与CUDA、Clang和LLVM IR抗争,并获得:CUDA失败:';无效的设备功能';

与CUDA、Clang和LLVM IR抗争,并获得:CUDA失败:';无效的设备功能';,cuda,llvm,clang++,powerpc,Cuda,Llvm,Clang++,Powerpc,我正在尝试在配备V100 GPU、CUDA 10.1和LLVM 11(从源代码构建)的PowerPC系统(RHEL 7.6,无根访问)上使用LLVM传递优化CUDA代码。此外,我测试了CLAN,LLI,并选择了一个简单的C++代码,所有的工作都很好。 经过几天的搜索、阅读、尝试和错误,我成功地编译了一个简单的CUDA源代码。代码是著名的axpy: #包括 #定义cudaCheckError()\ {

我正在尝试在配备V100 GPU、CUDA 10.1和LLVM 11(从源代码构建)的PowerPC系统(RHEL 7.6,无根访问)上使用LLVM传递优化CUDA代码。此外,我测试了CLAN,LLI,并选择了一个简单的C++代码,所有的工作都很好。 经过几天的搜索、阅读、尝试和错误,我成功地编译了一个简单的CUDA源代码。代码是著名的axpy:

#包括
#定义cudaCheckError()\
{                                                            \
cudaError_t e=cudaGetLastError()\
如果(e!=cudaSuccess){\
printf(“Cuda故障%s:%d:'%s'\n'、\uuuuuu文件、\uuuuu行、\
cudaGetErrorString(e))\
退出(退出失败)\
}                                                          \
}
__全局无效axpy(浮点a、浮点*x、浮点*y){
y[threadIdx.x]=a*x[threadIdx.x];
}
int main(int argc,char*argv[]){
常数int kDataLen=4;
浮球a=2.0f;
浮动主机x[kDataLen]={1.0f,2.0f,3.0f,4.0f};
浮动主机y[kDataLen];
//将输入数据复制到设备。
浮动*装置x;
浮动*装置y;
Cudamaloc(&device_x,kDataLen*sizeof(float));
Cudamaloc(和设备y,kDataLen*sizeof(浮动));
cudaMemcpy(设备x、主机x、kDataLen*sizeof(浮动),
cudamemcpyhostodevice);
//启动内核。
axpy(a,设备x,设备y);
cudaCheckError();
//将输出数据复制到主机。
cudaDeviceSynchronize();
cudaMemcpy(主机y、设备y、kDataLen*sizeof(浮动),
cudaMemcpyDeviceToHost);
//打印结果。
对于(int i=0;istd::cout问题与PowerPC架构无关。我需要使用
-Xclang-fcuda include gpubinary-Xclang axpy.fatbin
fatbin
文件传递到主机端编译命令,以复制整个编译行为

以下是更正的生成文件:

BIN_FILE=axpy
SRC_FILE=$(BIN_FILE).cu

main: $(BIN_FILE)

# Host Side
$(BIN_FILE).ll: $(SRC_FILE) $(BIN_FILE).fatbin
    clang++ -stdlib=libc++ -Wall -Werror $(BIN_FILE).cu -march=ppc64le --cuda-host-only -relocatable-pch \
        -Xclang -fcuda-include-gpubinary -Xclang $(BIN_FILE).fatbin -S -g -c -emit-llvm

$(BIN_FILE).o: $(BIN_FILE).ll
    llc -march=ppc64le $(BIN_FILE).ll -o $(BIN_FILE).s
    clang++ -c -Wall $(BIN_FILE).s -o $(BIN_FILE).o

# GPU Side
$(BIN_FILE)-cuda-nvptx64-nvidia-cuda-sm_70.ll: $(SRC_FILE)
    clang++ -x cuda -stdlib=libc++ -Wall -Werror $(BIN_FILE).cu --cuda-device-only \
        --cuda-gpu-arch=sm_70 -S -g -emit-llvm

$(BIN_FILE).ptx: $(BIN_FILE)-cuda-nvptx64-nvidia-cuda-sm_70.ll
    llc -march=nvptx64 -mcpu=sm_70 -mattr=+ptx64 $(BIN_FILE)-cuda-nvptx64-nvidia-cuda-sm_70.ll -o $(BIN_FILE).ptx

$(BIN_FILE).ptx.o: $(BIN_FILE).ptx
    ptxas -m64 --gpu-name=sm_70 $(BIN_FILE).ptx -o $(BIN_FILE).ptx.o

$(BIN_FILE).fatbin: $(BIN_FILE).ptx.o
    fatbinary --64 --create $(BIN_FILE).fatbin --image=profile=sm_70,file=$(BIN_FILE).ptx.o \
        --image=profile=compute_70,file=$(BIN_FILE).ptx -link

$(BIN_FILE)_dlink.o: $(BIN_FILE).fatbin
    nvcc $(BIN_FILE).fatbin -gencode arch=compute_70,code=sm_70 \
        -dlink -o $(BIN_FILE)_dlink.o -lcudart -lcudart_static -lcudadevrt

# Link both object files together (either nvcc or clang works here):
$(BIN_FILE): $(BIN_FILE).o $(BIN_FILE)_dlink.o
    nvcc $(BIN_FILE).o $(BIN_FILE)_dlink.o -o $(BIN_FILE) -arch=sm_70 -lc++

图1包括fatbinary文件的创建步骤。

如果在生成的可执行文件中反汇编GPU有效负载,您会看到什么?我编辑了一个问题@talonmiesDumping the fatbin与dumping the final Executive不同,但如果我们接受相同的sm_70代码被链接,那么这可能是一个实习生编译器生成的所有样板安装代码实现都有问题,而不是您的代码。谢谢您的评论。您有改进编译器序列的建议吗?您是否怀疑有其他问题?此外,
nvdism axpy
抛出此错误:
nvdism fatal:axpy不是受支持的Elf文件
应该能够在主机可执行文件上使用cuobjdump并转储elf头文件或反汇编。我不使用clang编译CUDA,您使用的是我不熟悉的平台,因此我无法提供更具体的内容,抱歉。
BIN_FILE=axpy
SRC_FILE=$(BIN_FILE).cu

main: $(BIN_FILE)

# Host Side
$(BIN_FILE).ll: $(SRC_FILE) $(BIN_FILE).fatbin
    clang++ -stdlib=libc++ -Wall -Werror $(BIN_FILE).cu -march=ppc64le --cuda-host-only -relocatable-pch \
        -Xclang -fcuda-include-gpubinary -Xclang $(BIN_FILE).fatbin -S -g -c -emit-llvm

$(BIN_FILE).o: $(BIN_FILE).ll
    llc -march=ppc64le $(BIN_FILE).ll -o $(BIN_FILE).s
    clang++ -c -Wall $(BIN_FILE).s -o $(BIN_FILE).o

# GPU Side
$(BIN_FILE)-cuda-nvptx64-nvidia-cuda-sm_70.ll: $(SRC_FILE)
    clang++ -x cuda -stdlib=libc++ -Wall -Werror $(BIN_FILE).cu --cuda-device-only \
        --cuda-gpu-arch=sm_70 -S -g -emit-llvm

$(BIN_FILE).ptx: $(BIN_FILE)-cuda-nvptx64-nvidia-cuda-sm_70.ll
    llc -march=nvptx64 -mcpu=sm_70 -mattr=+ptx64 $(BIN_FILE)-cuda-nvptx64-nvidia-cuda-sm_70.ll -o $(BIN_FILE).ptx

$(BIN_FILE).ptx.o: $(BIN_FILE).ptx
    ptxas -m64 --gpu-name=sm_70 $(BIN_FILE).ptx -o $(BIN_FILE).ptx.o

$(BIN_FILE).fatbin: $(BIN_FILE).ptx.o
    fatbinary --64 --create $(BIN_FILE).fatbin --image=profile=sm_70,file=$(BIN_FILE).ptx.o \
        --image=profile=compute_70,file=$(BIN_FILE).ptx -link

$(BIN_FILE)_dlink.o: $(BIN_FILE).fatbin
    nvcc $(BIN_FILE).fatbin -gencode arch=compute_70,code=sm_70 \
        -dlink -o $(BIN_FILE)_dlink.o -lcudart -lcudart_static -lcudadevrt

# Link both object files together (either nvcc or clang works here):
$(BIN_FILE): $(BIN_FILE).o $(BIN_FILE)_dlink.o
    nvcc $(BIN_FILE).o $(BIN_FILE)_dlink.o -o $(BIN_FILE) -arch=sm_70 -lc++