cuda - CUDA 索引 blockDim.y 始终为 1
问题描述
我正在尝试用共享内存解决二维拉普拉斯方程。但是一件奇怪的事情是 blockDim.y 的值总是 1。有人可以帮我吗?
主机代码
checkCudaErrors(cudaMalloc((void**)&d_A, h*h * sizeof(float)));
checkCudaErrors(cudaMalloc((void**)&d_out, h*h * sizeof(float)));
checkCudaErrors(cudaMemcpy(d_A, A, h*h * sizeof(float), cudaMemcpyHostToDevice));
dim3 blockSize = (BLOCK_SIZE, BLOCK_SIZE);
dim3 gridSize = ((h+BLOCK_SIZE-1)/BLOCK_SIZE, (h + BLOCK_SIZE - 1) / BLOCK_SIZE);
LaplaceDifference << <gridSize, blockSize >> > (d_A, h, d_out);
checkCudaErrors(cudaMemcpy(B, d_out, h*h * sizeof(float), cudaMemcpyDeviceToHost));
内核代码
int idx = blockIdx.x*blockDim.x + threadIdx.x;
int idy = blockIdx.y*blockDim.y + threadIdx.y;
__shared__ float A_ds[BLOCK_SIZE + 2][BLOCK_SIZE + 2];
int n = 1;
//Load data in shared memory
int halo_index_left = (blockIdx.x - 1)*blockDim.x + threadIdx.x;
int halo_index_right = (blockIdx.x + 1)*blockDim.x + threadIdx.x;
int halo_index_up = (blockIdx.y - 1)*blockDim.y + threadIdx.y;
int halo_index_down = (blockIdx.y + 1)*blockDim.y + threadIdx.y;
A_ds[n + threadIdx.y][n + threadIdx.x] = A[idy * h +idx];
if (threadIdx.x >= blockDim.x - n) {
A_ds[threadIdx.y + n][threadIdx.x - (blockDim.x - n)] = (halo_index_left < 0) ? 0 : A[idy*h + halo_index_left];
}
if (threadIdx.x < n) {
A_ds[threadIdx.y + n][blockDim.x + n + threadIdx.x] = (halo_index_right >= h) ? 0 : A[idy*h + halo_index_right];
}
if (threadIdx.y >= blockDim.y - n) {
A_ds[threadIdx.y - (blockDim.y - n)][threadIdx.x+n] = (halo_index_up < 0) ? 0 : A[halo_index_up*h + idx];
}
if (threadIdx.y < n) {
A_ds[blockDim.y + n + threadIdx.y][threadIdx.x + n] = (halo_index_down >= h) ? 0 : A[halo_index_down*h + idx];
}
__syncthreads();
P[idy*h + idx] = 0.25*(A_ds[threadIdx.y + n - 1][threadIdx.x + n] + A_ds[threadIdx.y + n + 1][threadIdx.x + n] + A_ds[threadIdx.y + n][threadIdx.x + n - 1] + A_ds[threadIdx.y + n][threadIdx.x + n + 1]);
解决方案
(我花了很长时间寻找一个骗子,但找不到。)
dim3变量是在 CUDA 头文件中定义的特定数据类型vector_types.h
。
它提供了几个构造函数。以下是此变量的构造函数的几个有效用法:
dim3 grid(gx, gy, gz);
dim3 grid = dim3(gx, gy, gz);
你所展示的:
dim3 blockSize = (BLOCK_SIZE, BLOCK_SIZE);
不会按您期望的方式工作。
dim3
由于等号右侧没有任何用法,编译器将使用其他方法来处理那里的内容。这不是语法错误,因为从 C++ 语言的角度来看,在这种形式下使用括号和逗号都是合法的。
希望您了解括号在 C++ 中的工作原理。我不会尝试描述逗号运算符,您可以在此处和此处阅读有关它的内容。最终效果是编译器将对这两个表达式中的每一个进行求值(一个在逗号的左侧,一个在右侧),并且它会将整个表达式的值作为对右侧表达式的求值产生的值来求值。所以这:
(BLOCK_SIZE, BLOCK_SIZE)
变成这样:
BLOCK_SIZE
这显然是一个标量,而不是多维的。
当您将标量分配给 dim3 变量时:
dim3 blockSize = BLOCK_SIZE;
您最终会得到一个具有以下维度的 dim3 变量:
(BLOCK_SIZE, 1, 1)
修复您所拥有的一种方法如下:
dim3 blockSize = dim3(BLOCK_SIZE, BLOCK_SIZE);
^^^^
推荐阅读
- c# - C# Linq InvalidOperationException
- react-native - 使用 detox 打开本地通知时出错
- django - Favicon 未在 Django 中加载
- .net - 我应该使用哪个版本的 .NET Framework?
- flutter - 颤振上的任何小部件可以显示麦克风均衡器的视觉显示?
- android - 检索 blob 时 SQLite 数据库中的异常
- laravel - 如何将旧路由的http请求转发到保留http方法和查询的新路由
- python - 如何执行多个进程以异步计算值并在完成后收集结果?
- sql-server - 在 ASP 经典 SQL 查询中使用特殊字符
- python - Python。发生异常:IndexError。列表索引超出范围