2013-10-16 82 views
0

我看过这个网站和其他人,并没有任何工作。我正在为我的具体情况发布一个问题。如何使用cudaMalloc/cudaMemcpy指向包含指针的结构的指针?

我有一堆矩阵,目标是使用内核让GPU对它们进行相同的操作。我很确定我可以让内核工作,但我无法使cudaMalloc/cudaMemcpy正常工作。

我有一个指向Matrix结构的指针,该结构有一个名为元素的成员,指向某些浮点数。我可以做所有的非cuda malloc就好了。

感谢您的任何/所有帮助。

代码:

typedef struct { 
    int width; 
    int height; 
    float* elements; 
} Matrix; 

int main void() { 
    int rows, cols, numMat = 2; // These are actually determined at run-time 
    Matrix* data = (Matrix*)malloc(numMat * sizeof(Matrix)); 

    // ... Successfully read from file into "data" ... 

    Matrix* d_data; 
    cudaMalloc(&d_data, numMat*sizeof(Matrix)); 
    for (int i=0; i<numMat; i++){ 
     // The next line doesn't work 
     cudaMalloc(&(d_data[i].elements), rows*cols*sizeof(float)); 

     // Don't know if this works 
     cudaMemcpy(d_data[i].elements, data[i].elements, rows*cols*sizeof(float)), cudaMemcpyHostToDevice); 
    } 

    // ... Do other things ... 
} 

谢谢!

+0

它不会以这种方式工作。你已经使用'cudaMalloc'分配了'd_data',并试图访问主机上的'd_data [i]',这是不可能的。 – sgarizvi

+0

更好的方法是使用'malloc'在主机上分配'd_data',然后使用'cudaMalloc'在设备上分配'd_data.elements'。目前还不清楚如何在设备代码中使用分配的结构。 – sgarizvi

+0

谢谢@ sgar91。但你在哪里说我试图访问d_data [i]? –

回答

5

你必须知道你的内存驻留在哪里。 malloc分配主机内存,cudaMalloc在设备上分配内存并返回指向该内存的指针。但是,该指针仅在设备功能中有效。

你想要可以achived为遵循什么:

typedef struct { 
    int width; 
    int height; 
    float* elements; 
} Matrix; 

int main void() { 
    int rows, cols, numMat = 2; // These are actually determined at run-time 
    Matrix* data = (Matrix*)malloc(numMat * sizeof(Matrix)); 

    // ... Successfully read from file into "data" ... 
    Matrix* h_data = (Matrix*)malloc(numMat * sizeof(Matrix)); 
    memcpy(h_data, data, numMat * sizeof(Matrix); 

    for (int i=0; i<numMat; i++){ 

     cudaMalloc(&(h_data[i].elements), rows*cols*sizeof(float)); 
     cudaMemcpy(h_data[i].elements, data[i].elements, rows*cols*sizeof(float)), cudaMemcpyHostToDevice); 

    }// matrix data is now on the gpu, now copy the "meta" data to gpu 
    Matrix* d_data; 
    cudaMalloc(&d_data, numMat*sizeof(Matrix)); 
    cudaMemcpy(d_data, h_data, numMat*sizeof(Matrix)); 
    // ... Do other things ... 
} 

为了把事情说清楚: Matrix* data包含主机上的数据。 Matrix* h_data包含一个指向设备内存的指针,它可以作为参数传递给内核。内存在GPU上。 Matrix* d_data在GPU上是完整的,可以像主机上的数据一样使用。

在内核代码,你卡恩

现在访问矩阵值,例如,

__global__ void doThings(Matrix* matrices) 
{ 
     matrices[i].elements[0] = 42; 
} 
+0

谢谢@kronos,我会试试这个。将“中间指针”“h_data”作为标准方法来实现这一点的想法是什么? –

+0

那要看情况。它代表主机代码中的开销,因为您必须将其他结构数据存储两次。这可能会导致错误。你可以做2件事:将设备指针打包到一个数组中,并将数组传递给内核(该数组也必须分配到设备内存中),或者向包含设备指针的结构添加一个字段。通过第二个选项,您可以在主机和设备端使用相同的结构,但通过元素和设备数据访问主机数据,可以通过d_elements进行说明。 –

+0

这非常有帮助。这让我想知道是否需要将所有东西全部放到设备上 - 如果我可以用主机指针调用内核来访问设备内存。再次感谢! –