diff --git a/.gitignore b/.gitignore index eb39fc4fc..e382eba34 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,9 @@ examples/nlm #data rnnlm/ptb-mikolov/ +# Python temporary files +*.pyc + # Compiled Object files *.slo *.lo diff --git a/CMakeLists.txt b/CMakeLists.txt index 79a4d54b3..6ea603853 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -41,6 +41,7 @@ function(find_mkl) endif() include_directories(${MKL_INCLUDE_DIR}) link_directories(${MKL_CORE_LIB_DIR} ${MKL_COMPILER_LIB_DIR}) + set(MKL_LINK_DIRS ${MKL_CORE_LIB_DIR} ${MKL_COMPILER_LIB_DIR} PARENT_SCOPE) # Keeping this for python build else() message(FATAL_ERROR "Failed to find MKL in path: ${MKL_ROOT} (Did you set MKL_ROOT properly?)") endif() diff --git a/doc/source/python.rst b/doc/source/python.rst index f8caee3a4..5a1940bb9 100644 --- a/doc/source/python.rst +++ b/doc/source/python.rst @@ -151,6 +151,25 @@ installation is likely to be working: from dynet import * model = Model() +Windows Support +------------------ +You can also use Python on Windows by following similar steps to the above. For simplicity, we recommend +using a Python distribution that already has Cython installed. The following has been tested to work: + +1) Install WinPython 2.7.10 (comes with Cython already installed). +2) Run CMake as above with ``-DPYTHON=/path/to/your/python.exe``. +3) Open a command prompt and set ``VS90COMNTOOLS`` to the path to your Visual Studio "Common7/Tools" directory. One easy way to do this is a command such as: + +:: + + set VS90COMNTOOLS=%VS140COMNTOOLS% + +4) Open dynet.sln from this command prompt and build the "Release" version of the solution. +5) Follow the rest of the instructions above for testing the build and installing it for other users + +Note, currently only the Release version works. + + GPU/MKL Support --------------- diff --git a/pyexamples/util.pyc b/pyexamples/util.pyc deleted file mode 100644 index 450ea3918..000000000 Binary files a/pyexamples/util.pyc and /dev/null differ diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 27c18e663..e37fc1e2c 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -1,4 +1,12 @@ +function(get_filename_components DEST ITEMS PART) + foreach(ITEM ${ITEMS}) + get_filename_component(ITEMPART "${ITEM}" ${PART}) + list(APPEND ${DEST} ${ITEMPART}) + endforeach() + list(REMOVE_DUPLICATES ${DEST}) + set(${DEST} ${${DEST}} PARENT_SCOPE) +endfunction() if(!PYTHON) find_program(PYTHON "python") @@ -14,8 +22,12 @@ if(PYTHON) ) if (WITH_CUDA_BACKEND) - message("--- CUDA:" ${CUDA_CUBLAS_LIBRARIES}) - get_filename_component(CUDA_CUBLAS_LIB ${CUDA_CUBLAS_LIBRARIES} PATH) + message("--- CUDA: CUBLAS: ${CUDA_CUBLAS_LIBRARIES} RT: ${CUDA_LIBRARIES}") + # Collect all of the library filenames and paths for setup.py + get_filename_components(CUDA_CUBLAS_DIRS "${CUDA_CUBLAS_LIBRARIES}" PATH) + get_filename_components(CUDA_CUBLAS_FILES "${CUDA_CUBLAS_LIBRARIES}" NAME) + get_filename_components(CUDA_RT_DIRS "${CUDA_LIBRARIES}" PATH) + get_filename_components(CUDA_RT_FILES "${CUDA_LIBRARIES}" NAME) endif() add_custom_target(copy) diff --git a/python/setup.py.in b/python/setup.py.in index f0abc3656..ece1b50d3 100644 --- a/python/setup.py.in +++ b/python/setup.py.in @@ -1,7 +1,25 @@ from setuptools import setup from setuptools.extension import Extension from Cython.Distutils import build_ext +import re +def appendCMakeList(list, var): + if var != "": + list.extend(var.split(';')) + +def appendCMakeLibList(list, var): + if var != "": + list.extend(map(stripLib, var.split(';'))) + +# Strip library prefixes and suffixes to prevent linker confusion +def stripLib(filename): + if filename.endswith(".lib"): + filename = re.sub(".lib$", "", filename) + elif filename.endswith(".so") or filename.endswith(".a"): + filename = re.sub("^lib", "", filename) + filename = re.sub(".so$", "", filename) + filename = re.sub(".a$", "", filename) + return filename # Remove the "-Wstrict-prototypes" compiler option, which isn't valid for C++. import distutils.sysconfig @@ -9,7 +27,36 @@ cfg_vars = distutils.sysconfig.get_config_vars() if "CFLAGS" in cfg_vars: cfg_vars["CFLAGS"] = cfg_vars["CFLAGS"].replace("-Wstrict-prototypes", "") -COMPILER_ARGS=["-std=c++11"] + +LIBRARIES=['dynet'] +LIBRARY_DIRS=["."] +GPULIBRARIES=['gdynet', 'dynetcuda'] +GPULIBRARY_DIRS=[] + +appendCMakeLibList(GPULIBRARIES, '${CUDA_CUBLAS_FILES}') +appendCMakeList(GPULIBRARY_DIRS, '${CUDA_CUBLAS_DIRS}') + +if "${MSVC}"=="1": + COMPILER_ARGS=["-DNOMINMAX", "/EHsc"] + DYNET_LIB_DIR="${PROJECT_BINARY_DIR}/dynet/Release/" + RUNTIME_LIB_DIRS=[] + # For MSVC, we compile dynet as a static lib, so we need to also link in the + # other libraries it depends on: + appendCMakeLibList(LIBRARIES, '${LIBS}') + appendCMakeLibList(GPULIBRARIES, '${LIBS}') + appendCMakeList(LIBRARY_DIRS, '${MKL_LINK_DIRS}') # Add the MKL dirs, if MKL is being used + appendCMakeLibList(GPULIBRARIES, '${CUDA_RT_FILES}') + appendCMakeList(GPULIBRARY_DIRS, '${CUDA_RT_DIRS}') + # Boost does auto-linking in MSVC, just point to the right directory: + appendCMakeList(LIBRARY_DIRS, '${Boost_LIBRARY_DIRS}') +else: + COMPILER_ARGS=["-std=c++11"] + DYNET_LIB_DIR="${PROJECT_BINARY_DIR}/dynet/" + RUNTIME_LIB_DIRS=[DYNET_LIB_DIR] + +LIBRARY_DIRS.append(DYNET_LIB_DIR) +GPULIBRARY_DIRS = LIBRARY_DIRS + GPULIBRARY_DIRS + import platform # in some OSX systems, the following extra flags are needed: @@ -24,11 +71,11 @@ ext_cpu = Extension( include_dirs=["${PROJECT_SOURCE_DIR}", # this is the location of the main dynet directory. "${EIGEN3_INCLUDE_DIR}", # this is the directory where eigen is saved. "${Boost_INCLUDE_DIR}"], # this is the directory where boost is. - libraries=['dynet'], # ditto - library_dirs=[".","${PROJECT_BINARY_DIR}/dynet/"], + libraries=LIBRARIES, # ditto + library_dirs=LIBRARY_DIRS, #extra_link_args=["-L/home/yogo/Vork/Research/dynet/dynet/build/dynet"], # if needed extra_compile_args=COMPILER_ARGS, - runtime_library_dirs=["${PROJECT_BINARY_DIR}/dynet/"], + runtime_library_dirs=RUNTIME_LIB_DIRS, ) ext_gpu = Extension( @@ -38,11 +85,11 @@ ext_gpu = Extension( include_dirs=["${PROJECT_SOURCE_DIR}", # this is the location of the main dynet directory. "${EIGEN3_INCLUDE_DIR}", # this is the directory where eigen is saved. "${Boost_INCLUDE_DIR}"], # this is the directory where boost is. - libraries=['gdynet','dynetcuda','cublas'], # ditto - library_dirs=[".","${PROJECT_BINARY_DIR}/dynet/","${CUDA_CUBLAS_LIB}"], + libraries=GPULIBRARIES, # ditto + library_dirs=GPULIBRARY_DIRS, #extra_link_args=["-L/home/yogo/Vork/Research/dynet/dynet/build/dynet"], # if needed extra_compile_args=COMPILER_ARGS, - runtime_library_dirs=["${PROJECT_BINARY_DIR}/dynet/"], + runtime_library_dirs=RUNTIME_LIB_DIRS, ) TARGET = [ext_cpu]