-
Notifications
You must be signed in to change notification settings - Fork 67
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
CUDA compilation moved to a more Pythonesque way
- Loading branch information
1 parent
4b56f88
commit 66b83f8
Showing
1 changed file
with
100 additions
and
81 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,124 +1,143 @@ | ||
#!/usr/bin/env python | ||
from setuptools import setup, Extension | ||
from setuptools.command.install import install | ||
from subprocess import call | ||
from setuptools.command.build_ext import build_ext | ||
import numpy | ||
import os | ||
import sys | ||
import platform | ||
|
||
# Path to CUDA on Linux and OS X | ||
cuda_dir = "/usr/local/cuda" | ||
# Path to CUDA library on Windows, 64 for 64 bit | ||
win_cuda_dir = "C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v7.5" | ||
|
||
def find_cuda(): | ||
if 'CUDAHOME' in os.environ: | ||
home = os.environ['CUDAHOME'] | ||
nvcc = os.path.join(home, 'bin', 'nvcc') | ||
else: | ||
nvcc = None | ||
for dir in os.environ['PATH'].split(os.pathsep): | ||
binpath = os.path.join(dir, 'nvcc') | ||
if os.path.exists(binpath): | ||
nvcc = os.path.abspath(binpath) | ||
if nvcc is None: | ||
raise EnvironmentError('The nvcc binary could not be located in ' | ||
'your $PATH. Either add it to your path, or' | ||
'set $CUDAHOME') | ||
home = os.path.dirname(os.path.dirname(nvcc)) | ||
libdir = "lib" | ||
arch = int(platform.architecture()[0][0:2]) | ||
if sys.platform.startswith('win'): | ||
os.path.join(libdir, "x"+str(arch)) | ||
elif arch == 64: | ||
libdir += "64" | ||
cudaconfig = {'home': home, 'nvcc': nvcc, | ||
'include': os.path.join(home, 'include'), | ||
'lib': os.path.join(home, libdir)} | ||
for k, v in cudaconfig.items(): | ||
if not os.path.exists(v): | ||
raise EnvironmentError('The CUDA %s path could not be located in ' | ||
'%s' % (k, v)) | ||
|
||
return cudaconfig | ||
|
||
try: | ||
CUDA = find_cuda() | ||
except EnvironmentError: | ||
CUDA = None | ||
print("Proceeding without CUDA") | ||
|
||
try: | ||
numpy_include = numpy.get_include() | ||
except AttributeError: | ||
numpy_include = numpy.get_numpy_include() | ||
|
||
arch = int(platform.architecture()[0][0:2]) | ||
cmdclass = {} | ||
if sys.platform.startswith('win') and os.path.exists(win_cuda_dir): | ||
somoclu_module = Extension('_somoclu_wrap', | ||
sources=['somoclu/somoclu_wrap.cxx'], | ||
extra_objects=[ | ||
'somoclu/src/denseCpuKernels.obj', | ||
'somoclu/src/sparseCpuKernels.obj', | ||
'somoclu/src/training.obj', | ||
'somoclu/src/mapDistanceFunctions.obj', | ||
'somoclu/src/uMatrix.obj', | ||
'somoclu/src/denseGpuKernels.cu.obj'], | ||
define_macros=[('CUDA', None)], | ||
library_dirs=[win_cuda_dir+"/lib/x"+str(arch)], | ||
libraries=['cudart', 'cublas'], | ||
include_dirs=[numpy_include]) | ||
elif os.path.exists(cuda_dir): | ||
class MyInstall(install): | ||
def customize_compiler_for_nvcc(self): | ||
'''This is a verbatim copy of the NVCC compiler extension from | ||
https://github.com/rmcgibbo/npcuda-example | ||
''' | ||
self.src_extensions.append('.cu') | ||
default_compiler_so = self.compiler_so | ||
super = self._compile | ||
|
||
def _compile(obj, src, ext, cc_args, extra_postargs, pp_opts): | ||
if os.path.splitext(src)[1] == '.cu': | ||
self.set_executable('compiler_so', CUDA['nvcc']) | ||
postargs = extra_postargs['nvcc'] | ||
else: | ||
postargs = extra_postargs['cc'] | ||
|
||
def run(self): | ||
os.chdir('somoclu') | ||
call(["./configure", "--without-mpi", "--with-cuda=" + cuda_dir]) | ||
call(["make", "lib"]) | ||
os.chdir('../') | ||
install.run(self) | ||
super(obj, src, ext, cc_args, postargs, pp_opts) | ||
self.compiler_so = default_compiler_so | ||
self._compile = _compile | ||
|
||
|
||
# run the customize_compiler | ||
class custom_build_ext(build_ext): | ||
def build_extensions(self): | ||
customize_compiler_for_nvcc(self.compiler) | ||
build_ext.build_extensions(self) | ||
|
||
if arch == 32: | ||
cuda_lib_dir = cuda_dir + "/lib" | ||
else: | ||
cuda_lib_dir = cuda_dir + "/lib64" | ||
somoclu_module = Extension('_somoclu_wrap', | ||
sources=['somoclu/somoclu_wrap.cxx'], | ||
extra_objects=[ | ||
'somoclu/src/denseCpuKernels.o', | ||
'somoclu/src/sparseCpuKernels.o', | ||
'somoclu/src/training.o', | ||
'somoclu/src/mapDistanceFunctions.o', | ||
'somoclu/src/uMatrix.o', | ||
'somoclu/src/denseGpuKernels.cu.co'], | ||
define_macros=[('CUDA', None)], | ||
library_dirs=[cuda_lib_dir], | ||
libraries=['gomp', 'cudart', 'cublas'], | ||
include_dirs=[numpy_include]) | ||
cmdclass = {'install': MyInstall} | ||
|
||
if sys.platform.startswith('win'): | ||
extra_compile_args = ['-openmp'] | ||
openmp = '' | ||
else: | ||
if sys.platform.startswith('win'): | ||
extra_compile_args = ['-openmp'] | ||
extra_link_args = [] | ||
extra_compile_args = ['-fopenmp'] | ||
if 'CC' in os.environ and 'clang-omp' in os.environ['CC']: | ||
openmp = 'iomp5' | ||
else: | ||
extra_compile_args = ['-fopenmp'] | ||
if 'CC' in os.environ and 'clang-omp' in os.environ['CC']: | ||
extra_link_args = [ | ||
'-liomp5' | ||
] | ||
else: | ||
extra_link_args = [ | ||
'-lgomp' | ||
] | ||
sources_files = ['somoclu/src/denseCpuKernels.cpp', | ||
'somoclu/src/sparseCpuKernels.cpp', | ||
'somoclu/src/mapDistanceFunctions.cpp', | ||
'somoclu/src/training.cpp', | ||
'somoclu/src/uMatrix.cpp', | ||
'somoclu/somoclu_wrap.cxx'] | ||
somoclu_module = Extension('_somoclu_wrap', | ||
sources=sources_files, | ||
include_dirs=[numpy_include, 'src'], | ||
extra_compile_args=extra_compile_args, | ||
extra_link_args=extra_link_args | ||
) | ||
openmp = 'gomp' | ||
sources_files = ['somoclu/src/denseCpuKernels.cpp', | ||
'somoclu/src/sparseCpuKernels.cpp', | ||
'somoclu/src/mapDistanceFunctions.cpp', | ||
'somoclu/src/training.cpp', | ||
'somoclu/src/uMatrix.cpp', | ||
'somoclu/src/denseGpuKernels.cu', | ||
'somoclu/somoclu_wrap.cxx'] | ||
somoclu_module = Extension('_somoclu_wrap', | ||
sources=sources_files, | ||
include_dirs=[numpy_include, 'src'], | ||
extra_compile_args={'cc': extra_compile_args, | ||
'nvcc': ['-use_fast_math', | ||
'--ptxas-options=-v', | ||
'-c', | ||
'--compiler-options', | ||
'-fPIC ' + | ||
extra_compile_args[0]]}, | ||
libraries=[openmp], | ||
) | ||
if CUDA is not None: | ||
somoclu_module.define_macros = [('CUDA', None)] | ||
somoclu_module.include_dirs.append(CUDA['include']) | ||
somoclu_module.library_dirs = [CUDA['lib']] | ||
somoclu_module.libraries += ['cudart', 'cublas'] | ||
somoclu_module.runtime_library_dirs = [CUDA['lib']] | ||
|
||
try: | ||
setup(name='somoclu', | ||
version='1.5.1', | ||
license='GPL3', | ||
author="peterwittek", | ||
author_email="xgdgsc@gmail.com", | ||
author_email="", | ||
maintainer="shichaogao", | ||
maintainer_email="xgdgsc@gmail.com", | ||
url="http://peterwittek.github.io/somoclu/", | ||
url="https://somoclu.readthedocs.org/", | ||
platforms=["unix", "windows"], | ||
description="Massively parallel implementation of self-organizing maps", | ||
ext_modules=[somoclu_module], | ||
py_modules=["somoclu"], | ||
packages=["somoclu"], | ||
install_requires=['numpy', 'matplotlib'], | ||
cmdclass=cmdclass | ||
cmdclass={'build_ext': custom_build_ext}, | ||
) | ||
except: | ||
setup(name='somoclu', | ||
version='1.5.1', | ||
license='GPL3', | ||
author="peterwittek", | ||
author_email="xgdgsc@gmail.com", | ||
author_email="", | ||
maintainer="shichaogao", | ||
maintainer_email="xgdgsc@gmail.com", | ||
url="http://peterwittek.github.io/somoclu/", | ||
url="https://somoclu.readthedocs.org/", | ||
platforms=["unix", "windows"], | ||
description="Massively parallel implementation of self-organizing maps", | ||
py_modules=["somoclu"], | ||
packages=["somoclu"], | ||
install_requires=['numpy', 'matplotlib'], | ||
cmdclass=cmdclass | ||
install_requires=['numpy', 'matplotlib'] | ||
) |