【发布时间】:2020-03-24 21:42:18
【问题描述】:
我以为我知道如何编写一些干净的 cuda 代码。直到我尝试制作一个简单的模板类并在一个简单的内核中使用它。 这几天我一直在解决问题。我访问过的每一个线程都让我觉得自己更愚蠢。
为了检查错误,我使用了这个
这是我的类.h:
#pragma once
template <typename T>
class MyArray
{
public:
const int size;
T *data;
__host__ MyArray(int size); //gpuErrchk(cudaMalloc(&data, size * sizeof(T)));
__device__ __host__ T GetValue(int); //return data[i]
__device__ __host__ void SetValue(T, int); //data[i] = val;
__device__ __host__ T& operator()(int); //return data[i];
~MyArray(); //gpuErrchk(cudaFree(data));
};
template class MyArray<double>;
class.cu 的相关内容在 cmets 中。如果您认为整个事情是相关的,我很乐意添加它。
现在是主要课程:
__global__ void test(MyArray<double> array, double *data, int size)
{
int j = threadIdx.x;
//array.SetValue(1, j); //doesn't work
//array(j) = 1; //doesn't work
//array.data[j] = 1; //doesn't work
data[j] = 1; //This does work !
printf("Reach this code\n");
}
}
int main(int argc, char **argv)
{
MyArray x(20);
test<<<1, 20>>>(x, x.data, 20);
gpuErrchk(cudaPeekAtLastError());
gpuErrchk(cudaDeviceSynchronize());
}
当我说“不起作用”时,我的意思是程序停在那里(在到达 printf 之前)而不输出任何错误。另外,我从cudaDeviceSynchronize 和cudaFree 都收到以下错误:
遇到非法内存访问
我无法理解的是,内存管理应该没有问题,因为将数组直接发送到内核可以正常工作。那么为什么当我发送课程并尝试访问课程数据时它不起作用?当我的代码明显遇到错误时,为什么我没有收到任何警告或错误消息?
这是nvcc --version的输出
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2017 NVIDIA Corporation
Built on Fri_Nov__3_21:07:56_CDT_2017
Cuda compilation tools, release 9.1, V9.1.85
【问题讨论】:
-
我现在无法测试它,但我建议不要将 MyArray
作为参考,而是按值。看到这个问题:stackoverflow.com/questions/8302506/parameters-to-cuda-kernels -
此用例不支持通过引用传递
-
x在主机内存中,您无法从 GPU 访问主机内存中的对象。请注意,data成员不能在主机上使用,因为底层内存是在设备上分配的。我会推荐更多关于主机和设备内存的阅读。 -
@DevonCornwall:这种情况下传值也会失败
-
您需要在主机上创建 x,在构造函数或其他函数中分配 GPU 上的 T* 数据。然后使用 cudaMemcpy() 将 x 从主机复制到 GPU,然后将其发送到内核以使其工作。您遇到的错误与作为模板的类无关。