def check_cudnn_version(compiler, settings): try: out = build_and_run(compiler, ''' #include <cudnn.h> #include <stdio.h> int main(int argc, char* argv[]) { printf("%d", CUDNN_VERSION); return 0; } ''', include_dirs=settings['include_dirs']) except Exception as e: utils.print_warning('Cannot check cuDNN version\n{0}'.format(e)) return False cudnn_version = int(out) if not minimum_cudnn_version <= cudnn_version <= maximum_cudnn_version: min_major = minimum_cudnn_version // 1000 max_major = maximum_cudnn_version // 1000 utils.print_warning( 'Unsupported cuDNN version: %d' % cudnn_version, 'cuDNN v%d<= and <=v%d is required' % (min_major, max_major)) return False return True
def make_extensions(options, compiler): """Produce a list of Extension instances which passed to cythonize().""" no_cuda = options['no_cuda'] settings = build.get_compiler_setting() include_dirs = settings['include_dirs'] settings['include_dirs'] = [ x for x in include_dirs if path.exists(x)] settings['library_dirs'] = [ x for x in settings['library_dirs'] if path.exists(x)] if sys.platform != 'win32': settings['runtime_library_dirs'] = settings['library_dirs'] if sys.platform == 'darwin': settings.setdefault('extra_link_args', []).append( '-Wl,' + ','.join('-rpath,' + path for path in settings['library_dirs'])) if options['linetrace']: settings['define_macros'].append(('CYTHON_TRACE', '1')) settings['define_macros'].append(('CYTHON_TRACE_NOGIL', '1')) if no_cuda: settings['define_macros'].append(('CUPY_NO_CUDA', '1')) ret = [] for module in MODULES: print('Include directories:', settings['include_dirs']) print('Library directories:', settings['library_dirs']) if not no_cuda: if not check_library(compiler, includes=module['include'], include_dirs=settings['include_dirs']): utils.print_warning( 'Include files not found: %s' % module['include'], 'Skip installing %s support' % module['name'], 'Check your CPATH environment variable') continue if not check_library(compiler, libraries=module['libraries'], library_dirs=settings['library_dirs']): utils.print_warning( 'Cannot link libraries: %s' % module['libraries'], 'Skip installing %s support' % module['name'], 'Check your LIBRARY_PATH environment variable') continue if 'check_method' in module and \ not module['check_method'](compiler, settings): continue s = settings.copy() if not no_cuda: s['libraries'] = module['libraries'] ret.extend([ setuptools.Extension(f, [path.join(*f.split('.')) + '.pyx'], **s) for f in module['file']]) return ret
def make_extensions(options, compiler): """Produce a list of Extension instances which passed to cythonize().""" no_cuda = options["no_cuda"] settings = build.get_compiler_setting() include_dirs = settings["include_dirs"] settings["include_dirs"] = [x for x in include_dirs if path.exists(x)] settings["library_dirs"] = [x for x in settings["library_dirs"] if path.exists(x)] if sys.platform != "win32": settings["runtime_library_dirs"] = settings["library_dirs"] if sys.platform == "darwin": args = settings.setdefault("extra_link_args", []) args.append("-Wl," + ",".join("-rpath," + path for path in settings["library_dirs"])) # -rpath is only supported when targetting Mac OS X 10.5 or later args.append("-mmacosx-version-min=10.5") if options["linetrace"]: settings["define_macros"].append(("CYTHON_TRACE", "1")) settings["define_macros"].append(("CYTHON_TRACE_NOGIL", "1")) if no_cuda: settings["define_macros"].append(("CUPY_NO_CUDA", "1")) ret = [] for module in MODULES: print("Include directories:", settings["include_dirs"]) print("Library directories:", settings["library_dirs"]) if not no_cuda: if not check_library(compiler, includes=module["include"], include_dirs=settings["include_dirs"]): utils.print_warning( "Include files not found: %s" % module["include"], "Skip installing %s support" % module["name"], "Check your CPATH environment variable", ) continue if not check_library(compiler, libraries=module["libraries"], library_dirs=settings["library_dirs"]): utils.print_warning( "Cannot link libraries: %s" % module["libraries"], "Skip installing %s support" % module["name"], "Check your LIBRARY_PATH environment variable", ) continue if "check_method" in module and not module["check_method"](compiler, settings): continue s = settings.copy() if not no_cuda: s["libraries"] = module["libraries"] ret.extend([setuptools.Extension(f, [path.join(*f.split(".")) + ".pyx"], **s) for f in module["file"]]) return ret
def get_compiler_setting(): nvcc_path = utils.search_on_path(('nvcc', 'nvcc.exe')) cuda_path_default = None if nvcc_path is None: utils.print_warning('nvcc not in path.', 'Please set path to nvcc.') else: cuda_path_default = os.path.normpath( os.path.join(os.path.dirname(nvcc_path), '..')) cuda_path = os.environ.get('CUDA_PATH', '') # Nvidia default on Windows if len(cuda_path) > 0 and cuda_path != cuda_path_default: utils.print_warning( 'nvcc path != CUDA_PATH', 'nvcc path: %s' % cuda_path_default, 'CUDA_PATH: %s' % cuda_path) if not os.path.exists(cuda_path): cuda_path = cuda_path_default if not cuda_path and os.path.exists('/usr/local/cuda'): cuda_path = '/usr/local/cuda' include_dirs = [] library_dirs = [] define_macros = [] if cuda_path: include_dirs.append(os.path.join(cuda_path, 'include')) if sys.platform == 'win32': library_dirs.append(os.path.join(cuda_path, 'bin')) library_dirs.append(os.path.join(cuda_path, 'lib', 'x64')) else: library_dirs.append(os.path.join(cuda_path, 'lib64')) library_dirs.append(os.path.join(cuda_path, 'lib')) if sys.platform == 'darwin': library_dirs.append('/usr/local/cuda/lib') if sys.platform == 'win32': nvtoolsext_path = os.environ.get('NVTOOLSEXT_PATH', '') if os.path.exists(nvtoolsext_path): include_dirs.append(os.path.join(nvtoolsext_path, 'include')) library_dirs.append(os.path.join(nvtoolsext_path, 'lib', 'x64')) else: define_macros.append(('CUPY_NO_NVTX', '1')) return { 'include_dirs': include_dirs, 'library_dirs': library_dirs, 'define_macros': define_macros, 'language': 'c++', }
def check_nccl_version(compiler, settings): # NCCL does not provide version information. # It only check whether there is nccl.h. try: build_and_run(compiler, ''' #include <nccl.h> int main(int argc, char* argv[]) { return 0; } ''', include_dirs=settings['include_dirs']) except Exception as e: utils.print_warning('Cannot include NCCL\n{0}'.format(e)) return False return True
def check_cusparselt_version(compiler, settings): global _cusparselt_version try: out = build_and_run(compiler, ''' #include <cusparseLt.h> #include <stdio.h> #ifndef CUSPARSELT_VERSION #define CUSPARSELT_VERSION 0 #endif int main(int argc, char* argv[]) { printf("%d", CUSPARSELT_VERSION); return 0; } ''', include_dirs=settings['include_dirs']) except Exception as e: utils.print_warning('Cannot check cuSPARSELt version\n{0}'.format(e)) return False _cusparselt_version = int(out) return True
def check_cusolver_version(compiler, settings): # As an initial cusolver does not have cusolverGetProperty, # we use CUDA_VERSION instead. try: out = build_and_run(compiler, ''' #include <cuda.h> #include <stdio.h> int main(int argc, char* argv[]) { printf("%d", CUDA_VERSION); return 0; } ''', include_dirs=settings['include_dirs']) except Exception as e: utils.print_warning('Cannot check CUDA version', str(e)) return False cuda_version = int(out) if cuda_version < minimum_cusolver_cuda_version: return False return True
def check_jitify_version(compiler, settings): global _jitify_version try: cupy_jitify_include = _jitify_path # Unfortunately Jitify does not have any identifiable name (branch, # tag, etc), so we must use the commit here a = subprocess.run(' '.join(['git', 'rev-parse', '--short', 'HEAD']), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, cwd=cupy_jitify_include) if a.returncode == 0: out = a.stdout.decode()[:-1] # unlike elsewhere, out is a str here else: raise RuntimeError('Cannot determine Jitify version from git') except Exception as e: utils.print_warning('Cannot determine Jitify version\n{}'.format(e)) # 0: Jitify is not built (makes no sense), -1: built with unknown ver out = -1 _jitify_version = out settings['define_macros'].append(('CUPY_JITIFY_VERSION_CODE', _jitify_version)) return True # we always build Jitify
def check_cugraph_version(compiler, settings): global _cugraph_version try: build_and_run(compiler, ''' #include <stdio.h> #include <cugraph/raft/error.hpp> int main(int argc, char* argv[]) { return 0; } ''', include_dirs=settings['include_dirs']) except Exception as e: utils.print_warning('Cannot find cuGraph header files\n{0}'.format(e)) return False try: out = build_and_run(compiler, ''' #include <stdio.h> #include <cugraph/version_config.hpp> int main(int argc, char* argv[]) { printf("%d", CUGRAPH_VERSION_MAJOR * 10000 + CUGRAPH_VERSION_MINOR * 100 + CUGRAPH_VERSION_PATCH); return 0; } ''', include_dirs=settings['include_dirs']) except Exception as e: utils.print_warning( 'Cannot find cuGRAPH version information\n{0}'.format(e)) _cugraph_version = 0 return True _cugraph_version = int(out) return True
def check_nccl_version(compiler, settings): global _nccl_version # NCCL 1.x does not provide version information. try: out = build_and_run(compiler, ''' #ifndef CUPY_USE_HIP #include <nccl.h> #else #include <rccl.h> #endif #include <stdio.h> #ifdef NCCL_MAJOR #ifndef NCCL_VERSION_CODE # define NCCL_VERSION_CODE \ (NCCL_MAJOR * 1000 + NCCL_MINOR * 100 + NCCL_PATCH) #endif #else # define NCCL_VERSION_CODE 0 #endif int main() { printf("%d", NCCL_VERSION_CODE); return 0; } ''', include_dirs=settings['include_dirs'], define_macros=settings['define_macros']) except Exception as e: utils.print_warning('Cannot include NCCL\n{0}'.format(e)) return False _nccl_version = int(out) return True
def check_cudnn_version(compiler, settings): try: out = build_and_run(compiler, ''' #include <cudnn.h> #include <stdio.h> int main(int argc, char* argv[]) { printf("%d", CUDNN_VERSION); return 0; } ''', include_dirs=settings['include_dirs']) except Exception as e: utils.print_warning('Cannot check cuDNN version\n{0}'.format(e)) return False cudnn_version = int(out) if cudnn_version < minimum_cudnn_version: utils.print_warning( 'cuDNN version is too old: %d' % cudnn_version, 'cuDNN v2 or newer is required') return False return True
def check_nvtx(compiler, settings): if PLATFORM_WIN32: path = os.environ.get('NVTOOLSEXT_PATH', None) if path is None: utils.print_warning('NVTX unavailable: NVTOOLSEXT_PATH is not set') elif not os.path.exists(path): utils.print_warning( 'NVTX unavailable: NVTOOLSEXT_PATH is set but the directory ' 'does not exist') elif utils.search_on_path(['nvToolsExt64_1.dll']) is None: utils.print_warning( 'NVTX unavailable: nvToolsExt64_1.dll not found in PATH') else: return True return False return True
def check_cub_version(compiler, settings): global _cub_version global _cub_path # This is guaranteed to work for any CUB source because the search # precedence follows that of include paths. # - On CUDA, CUB < 1.9.9 does not provide version.cuh and would error out # - On ROCm, hipCUB has the same version as rocPRIM (as of ROCm 3.5.0) try: out = build_and_run(compiler, ''' #ifndef CUPY_USE_HIP #include <cub/version.cuh> #else #include <hipcub/hipcub_version.hpp> #endif #include <stdio.h> int main() { #ifndef CUPY_USE_HIP printf("%d", CUB_VERSION); #else printf("%d", HIPCUB_VERSION); #endif return 0; }''', include_dirs=settings['include_dirs'], define_macros=settings['define_macros']) except Exception as e: # could be in a git submodule? try: # CuPy's bundle cupy_cub_include = _cub_path a = subprocess.run(' '.join(['git', 'describe', '--tags']), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True, cwd=cupy_cub_include) if a.returncode == 0: tag = a.stdout.decode()[:-1] # CUB's tag convention changed after 1.8.0: "v1.9.0" -> "1.9.0" # In any case, we normalize it to be in line with CUB_VERSION if tag.startswith('v'): tag = tag[1:] tag = tag.split('.') out = int(tag[0]) * 100000 + int(tag[1]) * 100 try: out += int(tag[2]) except ValueError: # there're local commits so tag is like 1.8.0-1-gdcbb288f, # we add the number of commits to the version local_patch = tag[2].split('-') out += int(local_patch[0]) + int(local_patch[1]) else: raise RuntimeError('Cannot determine CUB version from git tag' '\n{0}'.format(e)) except Exception as e: utils.print_warning('Cannot determine CUB version\n{0}'.format(e)) # 0: CUB is not built (makes no sense), -1: built with unknown ver out = -1 _cub_version = int(out) settings['define_macros'].append(('CUPY_CUB_VERSION_CODE', _cub_version)) return True # we always build CUB
'thrust/sort.h', ], 'libraries': [ 'cudart', ], 'check_method': build.check_cuda_version, } ] if sys.platform == 'win32': mod_cuda = MODULES[0] mod_cuda['libraries'].remove('nvToolsExt') if utils.search_on_path(['nvToolsExt64_1.dll']) is None: mod_cuda['file'].remove('cupy.cuda.nvtx') mod_cuda['include'].remove('nvToolsExt.h') utils.print_warning('Cannot find nvToolsExt. nvtx was disabled.') else: mod_cuda['libraries'].append('nvToolsExt64_1') def ensure_module_file(file): if isinstance(file, tuple): return file else: return (file, []) def module_extension_name(file): return ensure_module_file(file)[0]
def make_extensions(options, compiler, use_cython): """Produce a list of Extension instances which passed to cythonize().""" no_cuda = options['no_cuda'] settings = build.get_compiler_setting() include_dirs = settings['include_dirs'] settings['include_dirs'] = [x for x in include_dirs if path.exists(x)] settings['library_dirs'] = [ x for x in settings['library_dirs'] if path.exists(x) ] if sys.platform != 'win32': settings['runtime_library_dirs'] = settings['library_dirs'] if sys.platform == 'darwin': args = settings.setdefault('extra_link_args', []) args.append('-Wl,' + ','.join('-rpath,' + p for p in settings['library_dirs'])) # -rpath is only supported when targetting Mac OS X 10.5 or later args.append('-mmacosx-version-min=10.5') # This is a workaround for Anaconda. # Anaconda installs libstdc++ from GCC 4.8 and it is not compatible # with GCC 5's new ABI. settings['define_macros'].append(('_GLIBCXX_USE_CXX11_ABI', '0')) # In the environment with CUDA 7.5 on Ubuntu 16.04, gcc5.3 does not # automatically deal with memcpy because string.h header file has # been changed. This is a workaround for that environment. # See details in the below discussions: # https://github.com/BVLC/caffe/issues/4046 # https://groups.google.com/forum/#!topic/theano-users/3ihQYiTRG4E settings['define_macros'].append(('_FORCE_INLINES', '1')) if options['linetrace']: settings['define_macros'].append(('CYTHON_TRACE', '1')) settings['define_macros'].append(('CYTHON_TRACE_NOGIL', '1')) if no_cuda: settings['define_macros'].append(('CUPY_NO_CUDA', '1')) ret = [] for module in MODULES: print('Include directories:', settings['include_dirs']) print('Library directories:', settings['library_dirs']) if not no_cuda: err = False if not check_library(compiler, includes=module['include'], include_dirs=settings['include_dirs']): utils.print_warning( 'Include files not found: %s' % module['include'], 'Skip installing %s support' % module['name'], 'Check your CFLAGS environment variable') err = True elif not check_library(compiler, libraries=module['libraries'], library_dirs=settings['library_dirs']): utils.print_warning( 'Cannot link libraries: %s' % module['libraries'], 'Skip installing %s support' % module['name'], 'Check your LDFLAGS environment variable') err = True elif ('check_method' in module and not module['check_method'](compiler, settings)): err = True if err: if module['name'] == 'cuda': raise Exception('Your CUDA environment is invalid. ' 'Please check above error log.') else: # Other modules are optional. They are skipped. continue s = settings.copy() if not no_cuda: s['libraries'] = module['libraries'] if module['name'] == 'cusolver': compile_args = s.setdefault('extra_compile_args', []) link_args = s.setdefault('extra_link_args', []) # openmp is required for cusolver if compiler.compiler_type == 'unix' and sys.platform != 'darwin': # In mac environment, openmp is not required. compile_args.append('-fopenmp') link_args.append('-fopenmp') elif compiler.compiler_type == 'msvc': compile_args.append('/openmp') if not no_cuda and module['name'] == 'thrust': if build.get_nvcc_path() is None: utils.print_warning('Cannot find nvcc in PATH.', 'Skip installing thrust support.') continue for f in module['file']: name = module_extension_name(f) sources = module_extension_sources(f, use_cython, no_cuda) extension = setuptools.Extension(name, sources, **s) ret.append(extension) return ret
def make_extensions(options, compiler, use_cython): """Produce a list of Extension instances which passed to cythonize().""" no_cuda = options['no_cuda'] settings = build.get_compiler_setting() include_dirs = settings['include_dirs'] settings['include_dirs'] = [ x for x in include_dirs if path.exists(x)] settings['library_dirs'] = [ x for x in settings['library_dirs'] if path.exists(x)] if sys.platform != 'win32': settings['runtime_library_dirs'] = settings['library_dirs'] if sys.platform == 'darwin': args = settings.setdefault('extra_link_args', []) args.append( '-Wl,' + ','.join('-rpath,' + p for p in settings['library_dirs'])) # -rpath is only supported when targetting Mac OS X 10.5 or later args.append('-mmacosx-version-min=10.5') # This is a workaround for Anaconda. # Anaconda installs libstdc++ from GCC 4.8 and it is not compatible # with GCC 5's new ABI. settings['define_macros'].append(('_GLIBCXX_USE_CXX11_ABI', '0')) if options['linetrace']: settings['define_macros'].append(('CYTHON_TRACE', '1')) settings['define_macros'].append(('CYTHON_TRACE_NOGIL', '1')) if no_cuda: settings['define_macros'].append(('CUPY_NO_CUDA', '1')) ret = [] ext = '.pyx' if use_cython else '.cpp' for module in MODULES: print('Include directories:', settings['include_dirs']) print('Library directories:', settings['library_dirs']) if not no_cuda: if not check_library(compiler, includes=module['include'], include_dirs=settings['include_dirs']): utils.print_warning( 'Include files not found: %s' % module['include'], 'Skip installing %s support' % module['name'], 'Check your CFLAGS environment variable') continue if not check_library(compiler, libraries=module['libraries'], library_dirs=settings['library_dirs']): utils.print_warning( 'Cannot link libraries: %s' % module['libraries'], 'Skip installing %s support' % module['name'], 'Check your LDFLAGS environment variable') continue if 'check_method' in module and \ not module['check_method'](compiler, settings): continue s = settings.copy() if not no_cuda: s['libraries'] = module['libraries'] ret.extend([ setuptools.Extension(f, [path.join(*f.split('.')) + ext], **s) for f in module['file']]) return ret
def test_print_warning(self): utils.print_warning('This is a test.')
def get_compiler_setting(use_hip): cuda_path = None rocm_path = None if use_hip: rocm_path = get_rocm_path() else: cuda_path = get_cuda_path() include_dirs = [] library_dirs = [] define_macros = [] extra_compile_args = [] if cuda_path: include_dirs.append(os.path.join(cuda_path, 'include')) if PLATFORM_WIN32: library_dirs.append(os.path.join(cuda_path, 'bin')) library_dirs.append(os.path.join(cuda_path, 'lib', 'x64')) else: library_dirs.append(os.path.join(cuda_path, 'lib64')) library_dirs.append(os.path.join(cuda_path, 'lib')) if rocm_path: include_dirs.append(os.path.join(rocm_path, 'include')) include_dirs.append(os.path.join(rocm_path, 'include', 'hip')) include_dirs.append(os.path.join(rocm_path, 'rocrand', 'include')) library_dirs.append(os.path.join(rocm_path, 'lib')) library_dirs.append(os.path.join(rocm_path, 'rocrand', 'lib')) if use_hip: extra_compile_args.append('-std=c++11') if PLATFORM_DARWIN: library_dirs.append('/usr/local/cuda/lib') if PLATFORM_WIN32: nvtoolsext_path = os.environ.get('NVTOOLSEXT_PATH', '') if os.path.exists(nvtoolsext_path): include_dirs.append(os.path.join(nvtoolsext_path, 'include')) library_dirs.append(os.path.join(nvtoolsext_path, 'lib', 'x64')) else: define_macros.append(('CUPY_NO_NVTX', '1')) # For CUB, we need the complex and CUB headers. The search precedence for # the latter is: # 1. built-in CUB (for CUDA 11+) # 2. CuPy's CUB bundle # Note that starting CuPy v8 we no longer use CUB_PATH # for <cupy/complex.cuh> cupy_header = os.path.join(os.path.dirname(os.path.realpath(__file__)), '../cupy/core/include') # TODO(leofang): remove this detection in CuPy v9 old_cub_path = os.environ.get('CUB_PATH', '') if old_cub_path: utils.print_warning( 'CUB_PATH is detected: ' + old_cub_path, 'It is no longer used by CuPy and will be ignored') if cuda_path: cuda_cub_path = os.path.join(cuda_path, 'include', 'cub') if not os.path.exists(cuda_cub_path): cuda_cub_path = None else: cuda_cub_path = None global _cub_path if cuda_cub_path: _cub_path = cuda_cub_path else: _cub_path = os.path.join(cupy_header, 'cupy', 'cub') include_dirs.insert(0, _cub_path) include_dirs.insert(1, cupy_header) return { 'include_dirs': include_dirs, 'library_dirs': library_dirs, 'define_macros': define_macros, 'language': 'c++', 'extra_compile_args': extra_compile_args, }
'cusolverDn.h', ], 'libraries': [ 'cusolver', ], 'check_method': build.check_cusolver_version, } ] if sys.platform == 'win32': mod_cuda = MODULES[0] mod_cuda['libraries'].remove('nvToolsExt') if utils.search_on_path(['nvToolsExt64_1.dll']) is None: mod_cuda['file'].remove('cupy.cuda.nvtx') mod_cuda['include'].remove('nvToolsExt.h') utils.print_warning( 'Cannot find nvToolsExt. nvtx was disabled.') else: mod_cuda['libraries'].append('nvToolsExt64_1') def check_readthedocs_environment(): return os.environ.get('READTHEDOCS', None) == 'True' def check_library(compiler, includes=(), libraries=(), include_dirs=(), library_dirs=()): source = ''.join(['#include <%s>\n' % header for header in includes]) source += 'int main(int argc, char* argv[]) {return 0;}' try: # We need to try to build a shared library because distutils