如何解决 CUDA 中对 threadIdx.x、blockDim.x 和 blockIdx.x 的未定义引用错误?
Posted
技术标签:
【中文标题】如何解决 CUDA 中对 threadIdx.x、blockDim.x 和 blockIdx.x 的未定义引用错误?【英文标题】:How to resolve undefined reference errors to threadIdx.x, blockDim.x, and blockIdx.x in CUDA? 【发布时间】:2022-01-24 02:11:28 【问题描述】:我是一名在 CUDA 中研究并行列表排名算法的初学者。我不知道为什么在使用“nvcc ParallelListRanking.cu -o ParallelListRanking”进行编译时,会出现未定义的对 threadIdx.x、blockDim.x 和 blockIdx.x 的引用错误,并显示消息“ld 返回了退出 1 状态”。添加 #include "device_launch_parameters.h" 和 #include "cuda.h" 没有帮助。有什么想法可以解决这个问题?
#include<stdio.h>
#include <device_launch_parameters.h>
#include <cuda.h>
__global__ void set_up(unsigned long int n, unsigned long int *dS, unsigned long long int *dQR)
unsigned long int i = threadIdx.x + blockDim.x * blockIdx.x;
if (i < n)
dS[i] = i + 1;
dS[n-1] = 0;
if (dS[i] != 0)
dQR[i] = (dQR[i]%(1ull<<32)) + (1ull<<32) * 1ull;
else
dQR[i] = (dQR[i]%(1ull<<32)) + (1ull<<32) * 0ull;
dQR[i] = ((unsigned long long int) dS[i])%(1ull<<32) + (1ull<<32)*(dQR[i]/(1ull<<32));
__global__ void update(unsigned long int n, unsigned long long int *dQR)
unsigned long int i = threadIdx.x + blockDim.x * blockIdx.x;
if (i < n)
unsigned long int tempdQ = (unsigned long int) (dQR[i]%(1ull<<32));
unsigned long int tempdQQ = (unsigned long int) (dQR[tempdQ]%(1ull<<32));
if (tempdQ != 0 && tempdQQ != 0)
unsigned long long int tmpdQRQ = dQR[tempdQ];
unsigned long int tempdR = (unsigned long int) dQR[i]/(1ull<<32);
unsigned long long int tempdRQ = tmpdQRQ/(1ull<<32);
dQR[i] = ((unsigned long long int) tempdQQ)%(1ull<<32) + (((unsigned long long int) tempdR) + tempdRQ)*(1ull<<32);
tempdQ = tempdQQ;
tempdQQ = (unsigned long int) dQR[tempdQ]%(1ull<<32);
int main()
unsigned long int n = 1000;
unsigned long int *dS =(unsigned long int *) cudaMalloc((int **)n, sizeof(unsigned long int));
unsigned long long int *dQR = (unsigned long long int *) cudaMalloc((int **)n, sizeof(unsigned long long int));
unsigned long int i = threadIdx.x + blockDim.x * blockIdx.x;
set_up<<< 100, 100 >>>(n, dS, dQR);
for (int t = 1; t < n; t++)
update<<< 100, 100>>>(n, dQR);
printf("%lu", (unsigned long int) (dQR[i]%(1ull<<32)));
printf("\n");
printf("%lu", (unsigned long int) (dQR[i]/(1ull<<32)));
cudaFree(dQR);
cudaFree(dS);
return 0;
【问题讨论】:
【参考方案1】:你不能这样做:
unsigned long int i = threadIdx.x + blockDim.x * blockIdx.x;
在主机代码中(即main()
)。
这些变量仅在设备代码中自动定义(例如,用__global__
修饰的例程)。
从那时起,您的主机代码的其余部分不应依赖于像 threadIdx.x
这样的变量,因为它们没有在主机代码中定义并且在那里使用没有意义。
因此,只需完全删除该行(来自main()
),然后想出另一种方法来在您的主机代码中使用类似的索引。
您似乎使用它的唯一地方是在您的 printf
语句中,所以我猜如果您尝试打印出所有变量,您将需要在主机代码中进行循环:
for (int i = 0; i < n; i++)
printf("%lu", (unsigned long int) (dQR[i]%(1ull<<32)));
printf("\n");
printf("%lu", (unsigned long int) (dQR[i]/(1ull<<32)));
这是您报告的错误的近因,但是您的代码还有其他问题。
cudaMalloc
的用法不正确:
unsigned long int *dS =(unsigned long int *) cudaMalloc((int **)n, sizeof(unsigned long int));
你想做这样的事情:
cudaMallocManaged(&dS, sizeof(unsigned long int)*n);
同样适用于dQR
。 (我在这里从cudaMalloc
切换到cudaMallocManaged
的原因与您尝试从主机代码打印这些变量有关。)
您的代码可能还有其他问题。在尝试这样的事情之前,我建议您牢牢掌握如何在 CUDA 中编写一个适当、简单的矢量添加应用程序。
要基本掌握 CUDA,您可能需要学习一个简单的示例代码,例如 vectorAdd
,也可能需要学习 the introductory blogs 中的一个。
【讨论】:
以上是关于如何解决 CUDA 中对 threadIdx.x、blockDim.x 和 blockIdx.x 的未定义引用错误?的主要内容,如果未能解决你的问题,请参考以下文章
cuda 编 程 helloworld 打印 blockIdx和threadIdx.x threadIdx.y