如何使用clang将OpenCL编译成ptx代码?
Clang3.0能够将OpenCL编译成ptx,并使用Nvidia的工具在GPU上启动ptx代码。我该怎么做?请具体说明。有关具体示例或更多详细步骤以及示例链接,请参阅。以下是如何使用Clang trunk(目前为3.4)和libclc执行此操作的简要指南。我假设您已经掌握了如何配置和编译LLVM和Clang的基本知识,所以我只列出了我使用的配置标志 square.cl:如何使用clang将OpenCL编译成ptx代码?,opencl,clang,Opencl,Clang,Clang3.0能够将OpenCL编译成ptx,并使用Nvidia的工具在GPU上启动ptx代码。我该怎么做?请具体说明。有关具体示例或更多详细步骤以及示例链接,请参阅。以下是如何使用Clang trunk(目前为3.4)和libclc执行此操作的简要指南。我假设您已经掌握了如何配置和编译LLVM和Clang的基本知识,所以我只列出了我使用的配置标志 square.cl: __kernel void vector_square(__global float4* input, __global
__kernel void vector_square(__global float4* input, __global float4* output) {
int i = get_global_id(0);
output[i] = input[i]*input[i];
}
../llvm-trunk/configure --prefix=$PWD/../install-trunk --enable-debug-runtime --enable-jit --enable-targets=x86,x86_64,nvptx
make install
./configure.py --with-llvm-config=$PWD/../install-trunk/bin/llvm-config
make
-#include "llvm/Function.h"
-#include "llvm/GlobalVariable.h"
-#include "llvm/LLVMContext.h"
-#include "llvm/Module.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/GlobalVariable.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/IR/Module.h"
clang -Dcl_clang_storage_class_specifiers -isystem libclc/generic/include -include clc/clc.h -target nvptx -xcl square.cl -emit-llvm -S -o square.ll
llvm-link libclc/nvptx--nvidiacl/lib/builtins.bc square.ll -o square.linked.bc
clang -target nvptx square.linked.bc -S -o square.nvptx.s
//
// Generated by LLVM NVPTX Back-End
//
.version 3.1
.target sm_20, texmode_independent
.address_size 32
// .globl vector_square
.entry vector_square(
.param .u32 .ptr .global .align 16 vector_square_param_0,
.param .u32 .ptr .global .align 16 vector_square_param_1
)
{
.reg .pred %p<396>;
.reg .s16 %rc<396>;
.reg .s16 %rs<396>;
.reg .s32 %r<396>;
.reg .s64 %rl<396>;
.reg .f32 %f<396>;
.reg .f64 %fl<396>;
ld.param.u32 %r0, [vector_square_param_0];
mov.u32 %r1, %ctaid.x;
ld.param.u32 %r2, [vector_square_param_1];
mov.u32 %r3, %ntid.x;
mov.u32 %r4, %tid.x;
mad.lo.s32 %r1, %r3, %r1, %r4;
shl.b32 %r1, %r1, 4;
add.s32 %r0, %r0, %r1;
ld.global.v4.f32 {%f0, %f1, %f2, %f3}, [%r0];
mul.f32 %f0, %f0, %f0;
mul.f32 %f1, %f1, %f1;
mul.f32 %f2, %f2, %f2;
mul.f32 %f3, %f3, %f3;
add.s32 %r0, %r2, %r1;
st.global.f32 [%r0+12], %f3;
st.global.f32 [%r0+8], %f2;
st.global.f32 [%r0+4], %f1;
st.global.f32 [%r0], %f0;
ret;
}
//
//由LLVM NVPTX后端生成
//
.3.1版
.目标sm_20,texmode_独立
.地址尺寸32
//.globl向量_平方
.输入向量_平方(
.param.u32.ptr.global.align 16矢量平方参数0,
.param.u32.ptr.global.align 16矢量平方参数1
)
{
.reg.pred%p;
.reg.s16%rc;
.reg.s16%rs;
.注册号s32%r;
.reg.s64%rl;
.reg.f32%f;
.reg.f64%fl;
ld.param.u32%r0,[vector_square_param_0];
mov.u32%r1,%ctaid.x;
ld.param.u32%r2[vector_square_param_1];
mov.u32%r3,%ntid.x;
mov.u32%r4,%tid.x;
mad.lo.s32%r1,%r3,%r1,%r4;
shl.b32%r1,%r1,4;
添加.s32%r0,%r0,%r1;
ld.global.v4.f32{%f0,%f1,%f2,%f3},[%r0];
mul.f32%f0,%f0,%f0;
mul.f32%f1,%f1,%f1;
mul.f32%f2,%f2,%f2;
mul.f32%f3,%f3,%f3;
add.s32%r0、%r2、%r1;
st.global.f32[%r0+12],%f3;
st.global.f32[%r0+8],%f2;
st.global.f32[%r0+4],%f1;
st.global.f32[%r0],%f0;
ret;
}
使用当前版本的llvm(3.4)、libclc和nvptx后端,编译过程略有改变
您必须明确告诉nvptx后端使用哪个驱动程序接口;您可以选择nvptx nvidia cuda或nvptx nvidia nvcl(适用于OpenCL)及其64位等价物nvptx64 nvidia cuda或nvptx64 nvidia nvcl
根据选择的接口,生成的.ptx代码略有不同。在为CUDA驱动程序API生成的汇编代码中,intrinsic.global和.ptr从入口函数中删除,但它们是OpenCL所必需的。我稍微修改了Mikael的编译步骤,以生成可在OpenCL主机上运行的代码:
clang -Dcl_clang_storage_class_specifiers -isystem libclc/generic/include -include clc/clc.h -target nvptx64-nvidia-nvcl -xcl test.cl -emit-llvm -S -o test.ll
llvm-link libclc/built_libs/nvptx64--nvidiacl.bc test.ll -o test.linked.bc
clang -target nvptx64-nvidia-nvcl test.linked.bc -S -o test.nvptx.s
博客链接不再有效。另外,如果我没记错的话,那是不推荐使用的信息。我只是简单地修复了博客链接。对我来说,我必须在第2步中切换两个输入以使其正确链接。资料来源: