加载由LLVM的NVPTX后端生成的PTX程序集时,我遇到了一个模糊的异常。 (我正在从ManagedCuda加载PTX - http://managedcuda.codeplex.com/)
ErrorNoBinaryForGPU: This indicates that there is no kernel image available that is suitable for the device. This can occur when a user specifies code generation options for a particular CUDA source file that do not include the corresponding device configuration.
这是模块的LLVM IR(由于它是由工具生成的,所以有点奇怪)
; ModuleID = 'Module'
target triple = "nvptx64-nvidia-cuda"
%testStruct = type { i32 }
define void @kernel(i32 addrspace(1)*) {
entry:
%1 = alloca %testStruct
store %testStruct zeroinitializer, %testStruct* %1
%2 = load %testStruct* %1
call void @structtest(%testStruct %2)
ret void
}
define void @structtest(%testStruct) {
entry:
ret void
}
!nvvm.annotations = !{!0}
!0 = metadata !{void (i32 addrspace(1)*)* @kernel, metadata !"kernel", i32 1}
这是最终的PTX
//
// Generated by LLVM NVPTX Back-End
//
.version 3.1
.target sm_20
.address_size 64
// .globl kernel
.visible .func structtest
(
.param .b0 structtest_param_0
)
;
.visible .entry kernel(
.param .u64 kernel_param_0
)
{
.local .align 8 .b8 __local_depot0[8];
.reg .b64 %SP;
.reg .b64 %SPL;
.reg .s32 %r<2>;
.reg .s64 %rl<2>;
mov.u64 %rl1, __local_depot0;
cvta.local.u64 %SP, %rl1;
mov.u32 %r1, 0;
st.u32 [%SP+0], %r1;
// Callseq Start 0
{
.reg .b32 temp_param_reg;
// <end>}
.param .align 4 .b8 param0[4];
st.param.b32 [param0+0], %r1;
call.uni
structtest,
(
param0
);
//{
}// Callseq End 0
ret;
}
// .globl structtest
.visible .func structtest(
.param .b0 structtest_param_0
)
{
ret;
}
我不知道如何阅读PTX,但我觉得问题与structtest函数定义中的.b0
.param .b0 structtest_param_0
位有关。
传递非结构值(如整数或指针)可以正常工作,.b0
。该功能的一部分在执行此操作时会读取.b32
或.b64
这样的内容。
将三元组更改为nvptx-nvidia-cuda(32位)不执行任何操作,以及包含/排除http://llvm.org/docs/NVPTXUsage.html中建议的数据布局
这是NVPTX后端的错误,还是我做错了什么?
更新
我正在查看这个 - http://llvm.org/docs/doxygen/html/NVPTXAsmPrinter_8cpp_source.html - 看起来好像类型正在落到行01568
,显然不是原始类型,Ty->getPrimitiveSizeInBits()
返回零。 (至少这是我的猜测,无论如何)
我是否需要添加一个特殊情况来检查它是否是一个结构,获取地址,生成参数byval
,然后取消引用该结构?这似乎是一个hacky解决方案,但我不确定如何解决它。
答案 0 :(得分:0)
您是否尝试从编译中获取错误消息缓冲区?在managedCuda中,这将是:
CudaContext ctx = new CudaContext();
CudaJitOptionCollection options = new CudaJitOptionCollection();
CudaJOErrorLogBuffer err = new CudaJOErrorLogBuffer(1024);
options.Add(err);
try
{
ctx.LoadModulePTX("test.ptx", options);
}
catch
{
options.UpdateValues();
MessageBox.Show(err.Value);
}
当我运行你的ptx时,它说:
ptxas application ptx input,第12行;致命:'。b0'附近的解析错误:语法错误
ptxas致命:由于错误导致Ptx装配中止“
用b0支持你的猜测。