使用cuda生成redheffer矩阵

时间:2016-02-17 03:35:22

标签: cuda gpu-programming

我有一项任务要求我使用Cuda在GPU上生成Redheffer矩阵。

A Redheffer matrix1 is a matrix where each entry a[i][j] is defined by  
a[i][j] =  
1 if j = 1,   
1 if j is divisible by i  
0 otherwise.

这是我的代码

    #define SIZE = 20000
    #define BLOCK_WIDTH 16

   /* Launch the CUDA kernel */
    int numBlocks = ceil(SIZE / BLOCK_WIDTH);
    dim3 dimGrid(BLOCK_WIDTH,BLOCK_WIDTH,1);
    dim3 dimBlock(numBlocks,numBlocks,1);
    redhefferMatrix<<<dimGrid, dimBlock>>>(d_M, SIZE);

我有代码来验证输出是否正确,当计算的矩阵元素值不正确时,它会返回错误消息。 当我运行我的程序时,我收到此错误。

GPU number 0 is assigned to this job
    Row 0 column 5000 is incorrect. Should be:1 Is actually: 0

我计算值的逻辑是

int Row= blockIdx.y*blockDim.y + threadIdx.y;
int Col= blockIdx.x*blockDim.x + threadIdx.x;
.
.
if(i < 20000 && j < 20000)
{   

    {

        if(j == 1 || j % i == 0)
            d_M[i*SIZE+ j] = 1;
        else
            d_M[i*SIZE+ j] = 0;
    }
}

有人可以告诉我哪里可能出错了。提前谢谢。

1 个答案:

答案 0 :(得分:2)

由于您还没有提供完整的代码,因此无法确定可能存在的所有问题。但是你对块和网格维度有误解(你已将它们颠倒过来):

#define SIZE = 20000
#define BLOCK_WIDTH 16

/* Launch the CUDA kernel */
int numBlocks = ceil(SIZE / BLOCK_WIDTH);
dim3 dimGrid(BLOCK_WIDTH,BLOCK_WIDTH,1);
dim3 dimBlock(numBlocks,numBlocks,1);
redhefferMatrix<<<dimGrid, dimBlock>>>(d_M, SIZE);

第一个内核配置参数应该是块数量的网格的维度(在这种情况下为x和y)。您的第一个内核配置参数是dimGrid,您已将其定义为dim3(BLOCK_WIDTH,BLOCK_WIDTH)数量,即16x16块。这不是你想要的,我不会想到,但实际上并非违法。

您的第二个内核配置参数应该是线程数量的的维度(在本例中为x和y)。您的第二个内核参数是dimBlocks,您已将其定义为dim3(20000/16, 20000/16)数量,即1250x1250个线程。这是非法的,因为CUDA线程块仅限于1024个线程的,即维度的乘积不能超过1024.

因此,您的内核启动是非法的,您的内核甚至没有运行。如果您使用proper cuda error checking和/或使用cuda-memcheck运行代码,您会发现这一点。

修复可能相当简单 - 反转您对这些配置参数的理解:

dim3 dimBlock(BLOCK_WIDTH,BLOCK_WIDTH,1);
dim3 dimGrid(numBlocks,numBlocks,1);

同样,我不能说这是唯一的问题,因为你没有展示我可以实际测试的完整代码(对于这样的问题,哪个SO expects。)

如果您进行了上述更改但事情仍然无效,我建议如下:

  1. 添加正确的cuda错误检查,并按照我的建议使用cuda-memcheck运行您的代码。

  2. 提供complete MCVE,即其他人可以复制,粘贴和运行的完整代码。还提供cuda-memcheck的输出和系统上的错误检查。

  3. 你应该在之前做上面的两件事情,你在SO上要求调试帮助。