通过python distutils(用于python c扩展)使用可重定位设备代码编译cuda代码

2024-09-29 17:09:26 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一些使用协作组的cuda代码,因此需要使用nvcc编译-rdc=true标志。我想从python中调用cuda代码,因此我编写了一个带有python c扩展的python接口

因为我包含了cuda代码,所以我必须调整setup.py,如:Can python distutils compile CUDA code?

这是编译和安装的,但只要我用python导入代码,它就会出错。删除-rdc=true标志会使一切正常,但会迫使我从cuda内核中删除任何协作组代码(或在编译过程中出现“cudaggetintrinsichandle unresolved”错误)

我是否可以进一步调整setup.py以使其正常工作?或者,是否有其他方法来编译允许cuda代码的c扩展(启用rdc标志)


Tags: 代码pytrue标志setupcode内核can
1条回答
网友
1楼 · 发布于 2024-09-29 17:09:26

我想我找到了答案。如果您使用nvcc生成可重定位设备代码,则nvcc需要链接目标文件,以便正确处理设备代码链接,或者您需要通过在具有带“设备链接”标志的可重定位设备代码的所有目标文件上运行nvcc来生成单独的目标文件。然后,这个额外的对象文件可以包含在外部链接器的所有其他对象文件中

我从Can python distutils compile CUDA code?修改了设置,在源文件列表的末尾添加了一个伪'link.cu'文件。我还为cuda设备链接步骤添加了cudadevrt库和另一组编译器选项:

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

由于我缺乏区隔知识,这个解决方案感觉有点粗糙,但似乎有效。:)

相关问题 更多 >

    热门问题