簡體   English   中英

將內核函數的參數作為C ++結構傳遞?

[英]passing parameters of an kernel function as C++ struct?

我想將內核函數的參數作為給定的結構傳遞

struct kernel_data {
    double *A;
    double *B;
    double *C;
    const int *A_dims;
    const int *B_dims;
    int C_dims[2];
};

為此,我需要使用cudaMalloc()初始化設備指針,但如何進行初始化。 我打算通過包含這些參數的此函數構造這樣的結構。 還是我必須分別通過?

只需將結構按值傳遞給內核,就像使用其他任何參數一樣:

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);

等等

您可以通過復制到內核來傳遞此結構。 請記住,在Fermi之前的4KB的Fermi卡上,傳遞給內核的參數的總大小不得超過256B。

因此,您必須使用cudaMalloc來分配設備內存,而不是在結構中設置指向設備內存的指針。 最后,您通過復制將結構傳遞給內核。

我強烈建議您避免在C ++代碼中使用此結構。 代替

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);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM