C++ CUDA:为什么我的块维度不起作用?
C++ CUDA: Why aren't my block dimensions working?
我正在使用书中的示例来求解 4x4 矩阵乘法。然而,这本书只提供了内核代码,所以剩下的程序就交给我了。书中说要使用 2 的块宽度,但是我不能让它与 dim3 变量一起使用。这是内核:
__global__ void matmul_basic(float *c, float *a, float *b, unsigned int width)
{
printf("Width: %d\n", width);
printf("BlockDim.x: %d, BlockDim.y: %d, BlockDim.z: %d\n", blockDim.x, blockDim.y, blockDim.z);
printf("GridkDim.x: %d, GridDim.y: %d, GridDim.z: %d\n", gridDim.x, gridDim.y, gridDim.z);
printf("Blockidx.x: %d, Blockidx.y: %d, Blockidx.z: %d\n", blockIdx.x, blockIdx.y, blockIdx.z);
printf("threadIdx.x %d, threadIdx.y: %d, threadIdx.z: %d\n", threadIdx.x, threadIdx.y, threadIdx.z);
// Calculate the row index of the c element and a
int Row = blockIdx.y * blockDim.y + threadIdx.y;
// Calculate the column index of c and b
int Col = blockIdx.x * blockDim.x + threadIdx.x;
// Sense check
printf("Row: %d\tCol: %d\n", Row, Col);
if ((Row < width) && (Col < width)) {
float Pvalue = 0;
// each thread computes one element of the block sub-matrix
for (size_t k = 0; k < width; k++)
{
Pvalue += a[Row * width + k] * b[k * width + Col];
}
c[Row * width + Col] = Pvalue;
}
else {
printf("Dimensions out of bounds. Row: %d, Col: %d\n", Row, Col);
}
}
我知道打印语句过多,但我只是想验证尺寸。以下是函数调用中的维度:
dim3 dimGrid = (1, 1, 1);
dim3 dimBlock = (2, 2, 1);
matmul_basic <<<dimGrid, dimBlock>>> (d_c, d_a, d_b, width);
这应该是一个尺寸为 2x2 的线程块?
最后,这里是读数:
Width: 4
BlockDim.x: 1, BlockDim.y: 1, BlockDim.z: 1
GridkDim.x: 1, GridDim.y: 1, GridDim.z: 1
Blockidx.x: 0, Blockidx.y: 0, Blockidx.z: 0
threadIdx.x 0, threadIdx.y: 0, threadIdx.z: 0
Row: 0 Col: 0
Kernel Complete, transferring results...
20218 -1.07374e+08 -1.07374e+08 -1.07374e+08
-1.07374e+08 -1.07374e+08 -1.07374e+08 -1.07374e+08
-1.07374e+08 -1.07374e+08 -1.07374e+08 -1.07374e+08
-1.07374e+08 -1.07374e+08 -1.07374e+08 -1.07374e+08
所以它永远不会超过第一个线程,它认为块大小是 1x1x1?它也永远不会进入表示它超出矩阵维度的 else 语句。
我确定我在做一些愚蠢的事情,或者我误解了尺寸的工作原理。任何帮助将不胜感激。谢谢!
编辑:
从 printf 语句添加宽度初始化和读出:
初始化:
// Determine matrix dimensions
const int width = 4;
以上原始部分中的读数已被编辑为包括宽度。
it thinks the block size is 1x1x1?
是的。
Why aren't my block dimensions working?
因为这个:
dim3 dimBlock = (2, 2, 1);
并没有按照您的想法行事,这不是初始化 dim3
变量的正确方法。您可能想花一些时间思考表达式 (2,2,1)
在 C++ 中对 的计算结果。在引擎盖下,一个 dim3
变量是一个具有 3 个组件的 struct
。您不能在 C++ 中以这种方式设置 3 元素结构的所有 3 个组件。
无论如何,像这样调用构造函数来设置值的东西你会更幸运:
dim3 dimBlock(2, 2, 1);
或者这个,但不是:
dim3 dimBlock;
dimBlock.x = 2;
dimBlock.y = 2;
dimBlock.z = 1;
我还要指出,对于 4x4 问题,您的网格大小也不正确,但您可能会弄明白。
我正在使用书中的示例来求解 4x4 矩阵乘法。然而,这本书只提供了内核代码,所以剩下的程序就交给我了。书中说要使用 2 的块宽度,但是我不能让它与 dim3 变量一起使用。这是内核:
__global__ void matmul_basic(float *c, float *a, float *b, unsigned int width)
{
printf("Width: %d\n", width);
printf("BlockDim.x: %d, BlockDim.y: %d, BlockDim.z: %d\n", blockDim.x, blockDim.y, blockDim.z);
printf("GridkDim.x: %d, GridDim.y: %d, GridDim.z: %d\n", gridDim.x, gridDim.y, gridDim.z);
printf("Blockidx.x: %d, Blockidx.y: %d, Blockidx.z: %d\n", blockIdx.x, blockIdx.y, blockIdx.z);
printf("threadIdx.x %d, threadIdx.y: %d, threadIdx.z: %d\n", threadIdx.x, threadIdx.y, threadIdx.z);
// Calculate the row index of the c element and a
int Row = blockIdx.y * blockDim.y + threadIdx.y;
// Calculate the column index of c and b
int Col = blockIdx.x * blockDim.x + threadIdx.x;
// Sense check
printf("Row: %d\tCol: %d\n", Row, Col);
if ((Row < width) && (Col < width)) {
float Pvalue = 0;
// each thread computes one element of the block sub-matrix
for (size_t k = 0; k < width; k++)
{
Pvalue += a[Row * width + k] * b[k * width + Col];
}
c[Row * width + Col] = Pvalue;
}
else {
printf("Dimensions out of bounds. Row: %d, Col: %d\n", Row, Col);
}
}
我知道打印语句过多,但我只是想验证尺寸。以下是函数调用中的维度:
dim3 dimGrid = (1, 1, 1);
dim3 dimBlock = (2, 2, 1);
matmul_basic <<<dimGrid, dimBlock>>> (d_c, d_a, d_b, width);
这应该是一个尺寸为 2x2 的线程块? 最后,这里是读数:
Width: 4
BlockDim.x: 1, BlockDim.y: 1, BlockDim.z: 1
GridkDim.x: 1, GridDim.y: 1, GridDim.z: 1
Blockidx.x: 0, Blockidx.y: 0, Blockidx.z: 0
threadIdx.x 0, threadIdx.y: 0, threadIdx.z: 0
Row: 0 Col: 0
Kernel Complete, transferring results...
20218 -1.07374e+08 -1.07374e+08 -1.07374e+08
-1.07374e+08 -1.07374e+08 -1.07374e+08 -1.07374e+08
-1.07374e+08 -1.07374e+08 -1.07374e+08 -1.07374e+08
-1.07374e+08 -1.07374e+08 -1.07374e+08 -1.07374e+08
所以它永远不会超过第一个线程,它认为块大小是 1x1x1?它也永远不会进入表示它超出矩阵维度的 else 语句。
我确定我在做一些愚蠢的事情,或者我误解了尺寸的工作原理。任何帮助将不胜感激。谢谢!
编辑: 从 printf 语句添加宽度初始化和读出:
初始化:
// Determine matrix dimensions
const int width = 4;
以上原始部分中的读数已被编辑为包括宽度。
it thinks the block size is 1x1x1?
是的。
Why aren't my block dimensions working?
因为这个:
dim3 dimBlock = (2, 2, 1);
并没有按照您的想法行事,这不是初始化 dim3
变量的正确方法。您可能想花一些时间思考表达式 (2,2,1)
在 C++ 中对 的计算结果。在引擎盖下,一个 dim3
变量是一个具有 3 个组件的 struct
。您不能在 C++ 中以这种方式设置 3 元素结构的所有 3 个组件。
无论如何,像这样调用构造函数来设置值的东西你会更幸运:
dim3 dimBlock(2, 2, 1);
或者这个,但不是:
dim3 dimBlock;
dimBlock.x = 2;
dimBlock.y = 2;
dimBlock.z = 1;
我还要指出,对于 4x4 问题,您的网格大小也不正确,但您可能会弄明白。