скомпилировать код cuda с перемещаемым кодом устройства через python distutils (для расширения python c) - PullRequest
1 голос
/ 03 февраля 2020

У меня есть некоторый код cuda, который использует кооперативные группы, поэтому для компиляции с nv cc требуется флаг -rdc = true. Я хотел бы вызвать код cuda из python, поэтому пишу интерфейс python с расширениями python c.

Поскольку я включаю код cuda, мне пришлось адаптировать мой setup.py, как описано в: Может ли python distutils скомпилировать код CUDA?

Это компилирует и устанавливает, но как только я импортирую свой код в python, происходит сбой. Удаление флага -rdc = true заставляет все работать, но вынуждает меня удалить любой код группы сотрудничества из ядер cuda (или получить ошибку 'cudaCGGetIntrinsicHandle unresolved' во время компиляции).

Можно ли как-нибудь адаптировать мой setup.py, чтобы он заработал? В качестве альтернативы, есть ли другой способ скомпилировать мое расширение c, которое позволяет использовать код cuda (с включенным флагом rd c)?

1 Ответ

1 голос
/ 05 февраля 2020

Думаю, я разобрался с ответом. Если вы генерируете перемещаемый код устройства с помощью 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, но, похоже, оно работает. :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...