使用Clang将OpenCL编译为PTX时未解决的extern?

时间:2015-12-03 09:54:53

标签: clang opencl llvm-clang

我正在按照this SO answer上的说明操作,但是当我尝试运行生成的PTX文件时,我在clBuild中收到了以下错误

ptxas fatal   : Unresolved extern function 'get_group_id'

在PTX文件中,对于我使用的每个OpenCL函数调用,我都有以下内容

.func  (.param .b64 func_retval0) get_group_id
(
        .param .b32 get_group_id_param_0
)
;

当我提供一个CL文件时,OpenCL运行时创建的PTX文件中不存在上述内容。相反,它有适当的特殊注册。

these instructions之后(针对不同的libclc库的链接)在LLVM IR到PTX编译期间给出了分段错误,并出现以下错误:

fatal error: error in backend: Cannot cast between two non-generic address spaces

这些说明是否仍然有效?还有其他我应该做的事吗?

我使用的是最新版本的libclc,Clang 3.7和Nvidia驱动程序352.39

1 个答案:

答案 0 :(得分:1)

问题是llvm不提供OpenCL设备代码库。然而,llvm提供了获取GPU线程ID的内在函数。现在你必须使用clang的内置函数编写自己的get_global_id等植入物,并使用nvptx目标将其编译为llvm bitcode。在将IR降低到PTX之前,使用llvm-link将设备库与已编译的OpenCL模块链接起来。

您将如何编写此类函数的示例:

#define __ptx_mad(a,b,c) ((a)*(b)+(c))

__attribute__((always_inline)) unsigned int get_global_id(unsigned int dimindx) { 
  switch (dimindx) { 
    case 0: return __ptx_mad(__nvvm_read_ptx_sreg_ntid_x(), __nvvm_read_ptx_sreg_ctaid_x(), __nvvm_read_ptx_sreg_tid_x()); 
    case 1: return __ptx_mad(__nvvm_read_ptx_sreg_ntid_y(), __nvvm_read_ptx_sreg_ctaid_y(), __nvvm_read_ptx_sreg_tid_y()); 
    case 2: return __ptx_mad(__nvvm_read_ptx_sreg_ntid_z(), __nvvm_read_ptx_sreg_ctaid_z(), __nvvm_read_ptx_sreg_tid_z()); 
    default: return 0; 
  } 
}