【发布时间】:2011-09-22 01:51:33
【问题描述】:
我的 CUDA 内核似乎没有改变我传入的数组的值,这是相关的主机代码:
dim3 grid(numNets, N);
dim3 threads(1, 1, 1);
// allocate the arrays and jagged arrays on the device
alloc_dev_memory( state0, state1, d_state0, d_state1,
adjlist, d_adjlist, transfer, d_transfer,
indeg, d_indeg, d_N, d_K, d_S,
d_Spow, d_numNets );
// operate on the device memory
kernel<<< grid, threads >>>( d_state0, d_state1, d_adjlist, d_transfer, d_indeg,
d_N, d_K, d_S, d_Spow, d_numNets );
// copy the new states from the device to the host
cutilSafeCall( cudaMemcpy( state0, d_state0, ens_size*sizeof(int),
cudaMemcpyDeviceToHost ) );
// copy the new states from the array to the ensemble
for(int i=0; i < numNets; ++i)
nets[i]->set_state( state0 + N*i );
这里是被调用的内核代码:
// this dummy kernel just sets all the values to 0 for checking later.
__global__ void kernel( int * state0,
int * state1,
int ** adjlist,
luint ** transfer,
int * indeg,
int * d_N,
float * d_K,
int * d_S,
luint * d_Spow,
int * d_numNets )
{
int N = *d_N;
luint * Spow = d_Spow;
int tid = blockIdx.x*N + blockIdx.y;
state0[tid] = 0;
state1[tid] = 0;
for(int k=0; k < indeg[tid]; ++k) {
adjlist[tid][k] = 0;
}
for(int k=0; k < Spow[indeg[tid]]; ++k) {
transfer[tid][k] = 0;
}
}
然后,在使用 cudaMemcpy 将 state0 数组返回主机后,如果我循环通过 state0 并将所有值发送到标准输出,它们与初始值相同,即使我的内核被写入设置所有值归零。
预期的输出应该是state0的初始值:101111101011,然后是state0的最终值:(全为零)
此代码输出的示例运行:
101111101011
101111101011
Press ENTER to exit...
第二行应该全为零。为什么这个 CUDA 内核不影响 state0 数组?
【问题讨论】:
-
尝试使您的代码更小,并专注于您正在检查的一件事。只有在这工作之后再添加其他位。
-
显而易见的原因是内核从未运行,但根据您发布的内容绝对不可能说,因为大多数可能的故障点都没有显示,所有的常量代码中有未知值,并且您的错误检查不完整。
-
为什么内核不能运行?我在使用
cudaGetLastError()的内核调用之后添加了一行,但返回值为cudaSuccess。 -
@habitmelon: 事实上
cudaMemcpy返回cudaSuccess并没有说明内核是否曾经运行过。它没有运行的原因可能有很多——无效的指针、无效的执行配置...... -
numNets 和 N 的值可能会有所帮助。无论如何,请注意您在 state0 中使用偏移量 N 更新位置。