def _compile_cu(self, sources, output_dir=None, macros=None, include_dirs=None, debug=0, extra_preargs=None, extra_postargs=None, depends=None): # Compile CUDA C files, mainly derived from UnixCCompiler._compile(). macros, objects, extra_postargs, pp_opts, _build = \ self._setup_compile(output_dir, macros, include_dirs, sources, depends, extra_postargs) compiler_so = build.get_nvcc_path() cc_args = self._get_cc_args(pp_opts, debug, extra_preargs) cuda_version = build.get_cuda_version() postargs = _nvcc_gencode_options(cuda_version) + ['-O2'] postargs += ['-Xcompiler', '/MD'] print('NVCC options:', postargs) for obj in objects: try: src, ext = _build[obj] except KeyError: continue try: self.spawn(compiler_so + cc_args + [src, '-o', obj] + postargs) except errors.DistutilsExecError as e: raise errors.CompileError(str(e)) return objects
def run(self): if build.get_nvcc_path() is not None: def wrap_new_compiler(func): def _wrap_new_compiler(*args, **kwargs): try: return func(*args, **kwargs) except errors.DistutilsPlatformError: if not sys.platform == 'win32': CCompiler = _UnixCCompiler else: CCompiler = _MSVCCompiler return CCompiler(None, kwargs['dry_run'], kwargs['force']) return _wrap_new_compiler ccompiler.new_compiler = wrap_new_compiler(ccompiler.new_compiler) # Intentionally causes DistutilsPlatformError in # ccompiler.new_compiler() function to hook. self.compiler = 'nvidia' if check_cython_version(): get_ext_modules(True) # convert Cython files to cpp files check_extensions(self.extensions) build_ext.build_ext.run(self)
def run(self): if (build.get_nvcc_path() is not None or build.get_hipcc_path() is not None): def wrap_new_compiler(func): def _wrap_new_compiler(*args, **kwargs): try: return func(*args, **kwargs) except errors.DistutilsPlatformError: if not PLATFORM_WIN32: CCompiler = _UnixCCompiler else: CCompiler = _MSVCCompiler return CCompiler(None, kwargs['dry_run'], kwargs['force']) return _wrap_new_compiler ccompiler.new_compiler = wrap_new_compiler(ccompiler.new_compiler) # Intentionally causes DistutilsPlatformError in # ccompiler.new_compiler() function to hook. self.compiler = 'nvidia' ext_modules = get_ext_modules(True) # get .pyx modules cythonize(ext_modules, cupy_setup_options) check_extensions(self.extensions) build_ext.build_ext.run(self)
def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): # For sources other than CUDA C ones, just call the super class method. if os.path.splitext(src)[1] != '.cu': return unixccompiler.UnixCCompiler._compile( self, obj, src, ext, cc_args, extra_postargs, pp_opts) if use_hip: return self._comiple_unix_hipcc(obj, src, ext, cc_args, extra_postargs, pp_opts) # For CUDA C source files, compile them with NVCC. _compiler_so = self.compiler_so try: nvcc_path = build.get_nvcc_path() base_opts = build.get_compiler_base_options() self.set_executable('compiler_so', nvcc_path) cuda_version = build.get_cuda_version() postargs = _nvcc_gencode_options(cuda_version) + [ '-O2', '--compiler-options="-fPIC"', '--std=c++11' ] print('NVCC options:', postargs) return unixccompiler.UnixCCompiler._compile( self, obj, src, ext, base_opts + cc_args, postargs, pp_opts) finally: self.compiler_so = _compiler_so
def _compile_unix_nvcc(self, obj, src, ext, cc_args, extra_postargs, pp_opts): # For CUDA C source files, compile them with NVCC. nvcc_path = build.get_nvcc_path() base_opts = build.get_compiler_base_options() compiler_so = nvcc_path cuda_version = build.get_cuda_version() postargs = _nvcc_gencode_options(cuda_version) + [ '-O2', '--compiler-options="-fPIC"', '--std=c++11'] print('NVCC options:', postargs) try: self.spawn(compiler_so + base_opts + cc_args + [src, '-o', obj] + postargs) except errors.DistutilsExecError as e: raise errors.CompileError(str(e))
def _comiple_unix_nvcc(self, obj, src, ext, cc_args, extra_postargs, pp_opts): # For CUDA C source files, compile them with NVCC. _compiler_so = self.compiler_so try: nvcc_path = build.get_nvcc_path() base_opts = build.get_compiler_base_options() self.set_executable('compiler_so', nvcc_path) cuda_version = build.get_cuda_version() postargs = _nvcc_gencode_options(cuda_version) + [ '-O2', '--compiler-options="-fPIC"', '--std=c++11'] print('NVCC options:', postargs) return unixccompiler.UnixCCompiler._compile( self, obj, src, ext, base_opts + cc_args, postargs, pp_opts) finally: self.compiler_so = _compiler_so
def run(self): if build.get_nvcc_path() is not None: def wrap_new_compiler(func): def _wrap_new_compiler(*args, **kwargs): try: return func(*args, **kwargs) except errors.DistutilsPlatformError: if not sys.platform == 'win32': CCompiler = _UnixCCompiler else: CCompiler = _MSVCCompiler return CCompiler( None, kwargs['dry_run'], kwargs['force']) return _wrap_new_compiler ccompiler.new_compiler = wrap_new_compiler(ccompiler.new_compiler) # Intentionally causes DistutilsPlatformError in # ccompiler.new_compiler() function to hook. self.compiler = 'nvidia' build_ext.build_ext.run(self)
def _compile_cu(self, sources, output_dir=None, macros=None, include_dirs=None, debug=0, extra_preargs=None, extra_postargs=None, depends=None): # Compile CUDA C files, mainly derived from UnixCCompiler._compile(). macros, objects, extra_postargs, pp_opts, _build = \ self._setup_compile(output_dir, macros, include_dirs, sources, depends, extra_postargs) compiler_so = build.get_nvcc_path() cc_args = self._get_cc_args(pp_opts, debug, extra_preargs) cuda_version = build.get_cuda_version() postargs = _nvcc_gencode_options(cuda_version) + ['-O2'] if cuda_version >= 11020: # MSVC 14.0 (2015) is deprecated for CUDA 11.2 but we need it # to build CuPy because some Python versions were built using it. # REF: https://wiki.python.org/moin/WindowsCompilers postargs += ['-allow-unsupported-compiler'] postargs += ['-Xcompiler', '/MD'] # This is to compile thrust with MSVC2015 if cuda_version >= 11020: postargs += ['--std=c++14'] num_threads = int(os.environ.get('CUPY_NUM_NVCC_THREADS', '2')) postargs += [f'-t{num_threads}'] print('NVCC options:', postargs) for obj in objects: try: src, ext = _build[obj] except KeyError: continue try: self.spawn(compiler_so + cc_args + [src, '-o', obj] + postargs) except errors.DistutilsExecError as e: raise errors.CompileError(str(e)) return objects
def _compile_unix_nvcc(self, obj, src, ext, cc_args, extra_postargs, pp_opts): # For CUDA C source files, compile them with NVCC. nvcc_path = build.get_nvcc_path() base_opts = build.get_compiler_base_options(nvcc_path) compiler_so = nvcc_path cuda_version = build.get_cuda_version() postargs = _nvcc_gencode_options(cuda_version) + [ '-O2', '--compiler-options="-fPIC"'] if cuda_version >= 11020: postargs += ['--std=c++14'] num_threads = int(os.environ.get('CUPY_NUM_NVCC_THREADS', '2')) postargs += [f'-t{num_threads}'] else: postargs += ['--std=c++11'] print('NVCC options:', postargs) try: self.spawn(compiler_so + base_opts + cc_args + [src, '-o', obj] + postargs) except errors.DistutilsExecError as e: raise errors.CompileError(str(e))
def preconfigure_modules(compiler, settings): """Returns a list of modules buildable in given environment and settings. For each module in MODULES list, this function checks if the module can be built in the current environment and reports it. Returns a list of module names available. """ nvcc_path = build.get_nvcc_path() summary = [ '', '************************************************************', '* CuPy Configuration Summary *', '************************************************************', '', 'Build Environment:', ' Include directories: {}'.format(str(settings['include_dirs'])), ' Library directories: {}'.format(str(settings['library_dirs'])), ' nvcc command : {}'.format( nvcc_path if nvcc_path else '(not found)'), '', 'Environment Variables:', ] for key in ['CFLAGS', 'LDFLAGS', 'LIBRARY_PATH', 'CUDA_PATH', 'NVTOOLSEXT_PATH', 'NVCC']: summary += [' {:<16}: {}'.format(key, os.environ.get(key, '(none)'))] summary += [ '', 'Modules:', ] ret = [] for module in MODULES: installed = False status = 'No' errmsg = [] print('') print('-------- Configuring Module: {} --------'.format( module['name'])) sys.stdout.flush() if not check_library(compiler, includes=module['include'], include_dirs=settings['include_dirs'], define_macros=settings['define_macros']): errmsg = ['Include files not found: %s' % module['include'], 'Check your CFLAGS environment variable.'] elif not check_library(compiler, libraries=module['libraries'], library_dirs=settings['library_dirs'], define_macros=settings['define_macros']): errmsg = ['Cannot link libraries: %s' % module['libraries'], 'Check your LDFLAGS environment variable.'] elif ('check_method' in module and not module['check_method'](compiler, settings)): # Fail on per-library condition check (version requirements etc.) installed = True errmsg = ['The library is installed but not supported.'] elif module['name'] == 'thrust' and nvcc_path is None: installed = True errmsg = ['nvcc command could not be found in PATH.', 'Check your PATH environment variable.'] else: installed = True status = 'Yes' ret.append(module['name']) if installed and 'version_method' in module: status += ' (version {})'.format(module['version_method'](True)) summary += [ ' {:<10}: {}'.format(module['name'], status) ] # If error message exists... if len(errmsg) != 0: summary += [' -> {}'.format(m) for m in errmsg] # Skip checking other modules when CUDA is unavailable. if module['name'] == 'cuda': break if len(ret) != len(MODULES): if 'cuda' in ret: lines = [ 'WARNING: Some modules could not be configured.', 'CuPy will be installed without these modules.', ] else: lines = [ 'ERROR: CUDA could not be found on your system.', ] summary += [ '', ] + lines + [ 'Please refer to the Installation Guide for details:', 'https://docs-cupy.chainer.org/en/stable/install.html', '', ] summary += [ '************************************************************', '', ] print('\n'.join(summary)) return ret
def preconfigure_modules(compiler, settings): """Returns a list of modules buildable in given environment and settings. For each module in MODULES list, this function checks if the module can be built in the current environment and reports it. Returns a list of module names available. """ nvcc_path = build.get_nvcc_path() hipcc_path = build.get_hipcc_path() summary = [ '', '************************************************************', '* CuPy Configuration Summary *', '************************************************************', '', 'Build Environment:', ' Include directories: {}'.format(str(settings['include_dirs'])), ' Library directories: {}'.format(str(settings['library_dirs'])), ' nvcc command : {}'.format( nvcc_path if nvcc_path else '(not found)'), ' hipcc command : {}'.format( hipcc_path if hipcc_path else '(not found)'), '', 'Environment Variables:', ] for key in [ 'CFLAGS', 'LDFLAGS', 'LIBRARY_PATH', 'CUDA_PATH', 'NVTOOLSEXT_PATH', 'NVCC', 'HIPCC', 'ROCM_HOME' ]: summary += [' {:<16}: {}'.format(key, os.environ.get(key, '(none)'))] summary += [ '', 'Modules:', ] ret = [] for module in MODULES: installed = False status = 'No' errmsg = [] if module['name'] == 'cutensor': cutensor_path = os.environ.get('CUTENSOR_PATH', '') inc_path = os.path.join(cutensor_path, 'include') if os.path.exists(inc_path): settings['include_dirs'].append(inc_path) cuda_version = build.get_cuda_version() cuda_major = str(cuda_version // 1000) cuda_major_minor = cuda_major + '.' + \ str((cuda_version // 10) % 100) for cuda_ver in (cuda_major_minor, cuda_major): lib_path = os.path.join(cutensor_path, 'lib', cuda_ver) if os.path.exists(lib_path): settings['library_dirs'].append(lib_path) break print('') print('-------- Configuring Module: {} --------'.format( module['name'])) sys.stdout.flush() if not check_library( compiler, includes=module['include'], include_dirs=settings['include_dirs'], define_macros=settings['define_macros'], extra_compile_args=settings['extra_compile_args']): errmsg = [ 'Include files not found: %s' % module['include'], 'Check your CFLAGS environment variable.' ] elif not check_library( compiler, libraries=module['libraries'], library_dirs=settings['library_dirs'], define_macros=settings['define_macros'], extra_compile_args=settings['extra_compile_args']): errmsg = [ 'Cannot link libraries: %s' % module['libraries'], 'Check your LDFLAGS environment variable.' ] elif ('check_method' in module and not module['check_method'](compiler, settings)): # Fail on per-library condition check (version requirements etc.) installed = True errmsg = ['The library is installed but not supported.'] elif (module['name'] in ('thrust', 'cub', 'random') and (nvcc_path is None and hipcc_path is None)): installed = True cmd = 'nvcc' if not use_hip else 'hipcc' errmsg = [ '{} command could not be found in PATH.'.format(cmd), 'Check your PATH environment variable.' ] else: installed = True status = 'Yes' ret.append(module['name']) if installed and 'version_method' in module: status += ' (version {})'.format(module['version_method'](True)) summary += [' {:<10}: {}'.format(module['name'], status)] # If error message exists... if len(errmsg) != 0: summary += [' -> {}'.format(m) for m in errmsg] # Skip checking other modules when CUDA is unavailable. if module['name'] == 'cuda': break # Get a list of the CC of the devices connected to this node if not use_hip: build.check_compute_capabilities(compiler, settings) if len(ret) != len(MODULES): if 'cuda' in ret: lines = [ 'WARNING: Some modules could not be configured.', 'CuPy will be installed without these modules.', ] else: lines = [ 'ERROR: CUDA could not be found on your system.', ] summary += [ '', ] + lines + [ 'Please refer to the Installation Guide for details:', 'https://docs.cupy.dev/en/stable/install.html', '', ] summary += [ '************************************************************', '', ] print('\n'.join(summary)) return ret, settings
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