簡體   English   中英

通過 python distutils 使用可重定位設備代碼編譯 cuda 代碼(用於 python c 擴展)

[英]compile cuda code with relocatable device code through python distutils (for python c extension)

我有一些使用協作組的 cuda 代碼,因此需要 -rdc=true 標志才能使用 nvcc 進行編譯。 我想從 python 調用 cuda 代碼,所以我正在編寫一個帶有 python c 擴展的 python 接口。

因為我包含了 cuda 代碼,所以我不得不修改我的 setup.py,如: Can python distutils compile CUDA code?

這會編譯並安裝,但是一旦我在 python 中導入我的代碼,它就會出現段錯誤。 刪除 -rdc=true 標志使一切正常,但迫使我從 cuda 內核中刪除任何協作組代碼(或在編譯期間出現“cudaCGGetIntrinsicHandle unresolved”錯誤)。

我可以通過什么方式進一步調整我的 setup.py 以使其正常工作? 或者,是否有其他方法可以編譯我的 c 擴展,允許 cuda 代碼(打開 rdc 標志)?

想我有點想通了答案。 如果您使用 nvcc 生成可重定位設備代碼,則 nvcc 需要鏈接目標文件以便正確處理設備代碼鏈接,或者您需要通過在所有具有可重定位設備代碼的目標文件上運行 nvcc 來生成單獨的目標文件 ' --device-link' 標志。 然后可以將這個額外的目標文件與外部鏈接器的所有其他目標文件一起包含在內。

我從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

由於我缺乏 distutils 知識,該解決方案感覺有點黑客,但它似乎有效。 :)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM