我想将内核函数的参数作为结构给出,如
struct kernel_data {
double *A;
double *B;
double *C;
const int *A_dims;
const int *B_dims;
int C_dims[2];
};
出于此目的,我需要使用cudaMalloc()
初始化设备指针,但我怎么能初始化。这个函数的结构包括我想要通过的这些参数。或者我必须单独传递它们吗?
答案 0 :(得分:3)
只需将结构按值传递给内核,就像任何其他参数一样:
struct kernel_data args;
cudaMalloc(&(args.A), sizeof(double)*.....);
cudaMalloc(&(args.B), sizeof(double)*.....);
cudaMalloc(&(args.C), sizeof(double)*.....);
cudaMalloc(&(args.A_dims), sizeof(int)*.....);
cudaMalloc(&(args.B_dims), sizeof(int)*.....);
kernel<<<....>>>(args);
参数列表大小存在理论上的限制,从256字节到4Kb,取决于您使用的硬件,如果超过它,将args
结构复制到设备分配并将其作为指针,或将其复制到常量内存指针。
要从主机初始化阵列,只需使用标准的cudaMemcpy
调用:
cudaMemcpy(args.A, hostA, sizeof(double)*....., cudaMemcpyHostToDevice);
等
答案 1 :(得分:2)
您可以通过复制将此结构传递给内核。 请记住,传送到内核的参数总大小不得超过Fermi上4KB的前费米卡上的256B。
因此,您必须使用cudaMalloc来分配设备内存,而不是在结构中设置指向设备内存的指针。最后,您将结构通过副本传递给内核。
我强烈建议您避免在C ++代码中使用此struc。 而不是
struct kernel_data {
double *A;
double *B;
double *C;
const int *A_dims;
const int *B_dims;
int C_dims[2];
};
你应该做那样的事情
class DeviceData{
public:
DeviceData(...){//Do cudaMalloc here}
~DeviceData(...){//Do cudaFree here}
private:
double *_A;
int _dims;
};
此类将保存设备上可用的数据,并且它是异常安全的。 您可以实现一个可以传递给内核的包装器
class DeviceDataWrapper{
public:
__host__ DeviceDataWrapper(DeviceData& device):
_A(device._A),
_dims(device._dims)
{}
__forceinline__ __device__ double* data(){return _A;}
__forceinline__ __device__ int dims()const{return _dims;}
private:
double *_A;
int _dims;
}
然后以这种方式调用内核
__global__ void myKernel(DeviceDataWrapper a, DeviceDataWrapper b, DeviceData2Wrapper c){
//do something like a.data()[0] = 1;
}
DeviceData A,B;
DeviceData2 C;
myKernel<<< >>>(A,B,C);