【问题标题】:Why is z always zero in CUDA kernel为什么 CUDA 内核中的 z 总是为零
【发布时间】:2025-12-01 22:00:02
【问题描述】:

我正在使用 Cudafy 在 NVIDIA GPU 上进行一些计算。 (Quadro K1100M 功能 3.0,如果重要的话)

我的问题是,当我使用以下内容时

cudaGpu.Launch(new dim3(44,8,num), new dim(8, 8)).MyKernel...

为什么当我在内核中使用 GThread 实例时,我的 z 索引总是为零?

int z = thread.blockIdx.z * thread.blockDim.z + thread.threadIdx.z;

此外,如果我必须做类似的事情

cudaGpu.Launch(new dim3(44,8,num), new dim(8, 8, num)).MyKernel...

z 确实给出了不同的索引,但是由于每个块的线程数的限制,num 不能很大。关于如何解决这个问题的任何建议?

编辑

另一种表达方式。当块大小仅为 2D 时,我可以在内核中使用 thread.z(用于任何有用的东西)吗?

【问题讨论】:

  • 0 可能是默认值?您应该始终为您的“num”提供至少 1 的值。要处理每个块的线程数限制,只需增加块数(因此,更多块更少线程)。
  • num 只是表示它可以是任何东西,但我很肯定它 > 0。
  • 我对cudafy了解不多,但可能是在cuda允许gridDim.z维度之前设计的dot net和cuda之间的映射尚未更新并且不考虑z维度。这需要验证
  • 经过研究,我只发现了一个用户指出 CUDAfy 为他的设备报告错误 CC 的主题:cudafy1.rssing.com/chan-12112480/all_p2.html。可能正因为如此,它认为它*无法启动 3 维网格,尽管您的设备可以。

标签: c# cuda cudafy.net


【解决方案1】:

在所有当前支持的硬件上,CUDA 允许使用三维网格和三维块。在计算能力 1.x 设备(不再受支持)上,网格仅限于二维。

但是,CUDAfy 目前使用已弃用的运行时 API 函数来启动内核,并且仅静默使用 gridDim.x 和 gridDim.y,而不考虑 gridDim.z:

_cuda.Launch(function, gridSize.x, gridSize.y);

the function DoLaunch() in CudaGPU.cs 所示。

因此,虽然您可以在 CUDAfy 中指定三维网格,但在内核启动期间会忽略第三维。感谢 Florent 指出这一点!

【讨论】:

  • 这不太正确。三维网格在 CC>=2.0 的所有硬件上都支持(即在 CUDA 7 中支持的所有硬件)
  • 在备忘单中也有索引 3D 块网格的示例,但我从来没有 Nvidia GPU 支持 3D 块网格。 Nsight 总是报告说,根据 GPU,我可以每 1 个不同数量的线程块启动 65535 个 65535 个。
  • docs.nvidia.com/cuda/cuda-c-programming-guide/…。支持 65535 x 65535 x 65535 的网格,对于 CC>=3 的一维网格,支持 2^31-1
  • 如果你知道,为什么不考虑回答 smok 的问题呢?无论如何,我要编辑我的纠正。
  • @Taro,在 CUDAfy 代码中偷偷摸摸,似乎它正在使用 CUDA 运行时已弃用的 API,它只允许 2D 调用:cudafy.codeplex.com/SourceControl/latest#Cudafy/Cudafy.Host/… (DoLaunch)。仅使用 gridSize.x 和 gridSize.y。
最近更新 更多