Думаю, я разобрался с ответом. Если вы генерируете перемещаемый код устройства с помощью nv cc, либо nv cc необходимо связать объектные файлы, чтобы правильно обрабатывать связывание кода устройства, либо вам нужно сгенерировать отдельный объектный файл, выполнив nv cc для всех объектов файлы с перемещаемым кодом устройства с флагом --device-link. Этот дополнительный объектный файл затем может быть включен во все остальные объектные файлы для внешнего компоновщика.
Я адаптировал настройки из Может ли python distutils скомпилировать код CUDA? , добавив фиктивный файл ' файл link.cu 'до конца списка исходных файлов. Я также добавляю библиотеку cudadevrt и другой набор опций компилятора для шага связывания устройства cuda:
ext = Extension('mypythonextension',
sources=['python_wrapper.cpp', 'file_with_cuda_code.cu', 'link.cu'],
library_dirs=[CUDA['lib64']],
libraries=['cudart', 'cudadevrt'],
runtime_library_dirs=[CUDA['lib64']],
extra_compile_args={'gcc': [],
'nvcc': ['-arch=sm_70', '-rdc=true', '--compiler-options', "'-fPIC'"],
'nvcclink': ['-arch=sm_70', '--device-link', '--compiler-options', "'-fPIC'"]
},
include_dirs = [numpy_include, CUDA['include'], 'src'])
Затем эта функция обрабатывается следующим образом функцией, которая адаптирует вызовы компилятора:
def customize_compiler_for_nvcc(self):
self.src_extensions.append('.cu')
# track all the object files generated with cuda device code
self.cuda_object_files = []
super = self._compile
def _compile(obj, src, ext, cc_args, extra_postargs, pp_opts):
# generate a special object file that will contain linked in
# relocatable device code
if src == 'link.cu':
self.set_executable('compiler_so', CUDA['nvcc'])
postargs = extra_postargs['nvcclink']
cc_args = self.cuda_object_files[1:]
src = self.cuda_object_files[0]
elif os.path.splitext(src)[1] == '.cu':
self.set_executable('compiler_so', CUDA['nvcc'])
postargs = extra_postargs['nvcc']
self.cuda_object_files.append(obj)
else:
postargs = extra_postargs['gcc']
super(obj, src, ext, cc_args, postargs, pp_opts)
self.compiler_so = default_compiler_so
self._compile = _compile
Решение кажется немного хакерским sh из-за недостатка знаний distutils, но, похоже, оно работает. :)