Скопировать объект на устройство?

Могу ли я скопировать объект C++ на устройство?

скажи у меня есть:

class CudaClass
{
public:
int* data;
CudaClass(int x) {
    data = new int[1]; data[0] = x;
}
};

__global__ void useClass(CudaClass cudaClass)
{
    printf("%d" cudaClass.data[0]);
};


int main()
{
    CudaClass c(1);
}

Теперь, как мне скопировать "c" в память устройства и запустить ядро ​​"useClass"?

1 ответ

Решение

Да, вы можете скопировать объект на устройство для использования на устройстве. Когда объект имеет встроенные указатели на динамически распределенные области, процесс требует некоторых дополнительных шагов.

Смотрите мой ответ здесь для обсуждения того, что участвует. Этот ответ также имеет несколько примеров кодовых ответов, связанных с ним.

Кроме того, в вашем определении класса, если вы хотите, чтобы определенные функции могли использоваться на устройстве, вы должны соответствующим образом декорировать эти функции (т.е. __device__ __host__);

РЕДАКТИРОВАТЬ: В ответ на вопрос (теперь удален) вот самый простой пример кода, который я мог придумать на основе предоставленного кода:

#include <stdio.h>

class CudaClass
{
public:
int* data;
CudaClass(int x) {
    data = new int[1]; data[0] = x;
}
};

__global__ void useClass(CudaClass *cudaClass)
{
    printf("%d\n", cudaClass->data[0]);
};




int main()
{
    CudaClass c(1);
    // create class storage on device and copy top level class
    CudaClass *d_c;
    cudaMalloc((void **)&d_c, sizeof(CudaClass));
    cudaMemcpy(d_c, &c, sizeof(CudaClass), cudaMemcpyHostToDevice);
    // make an allocated region on device for use by pointer in class
    int *hostdata;
    cudaMalloc((void **)&hostdata, sizeof(int));
    cudaMemcpy(hostdata, c.data, sizeof(int), cudaMemcpyHostToDevice);
    // copy pointer to allocated device storage to device class
    cudaMemcpy(&(d_c->data), &hostdata, sizeof(int *), cudaMemcpyHostToDevice);
    useClass<<<1,1>>>(d_c);
    cudaDeviceSynchronize();
    return 0;
}

В интересах краткости / ясности я обошелся без обычной проверки ошибок cuda.

Отвечая на вопрос, вы не можете выделить хранилище непосредственно с хоста, используя указатель в классе на основе устройства. Это потому, что cudaMalloc ожидает обычное хранилище указателей на основе хоста, например то, что вы получаете:

int *hostdata;

cudaMalloc не может работать с указателем, чье хранилище уже находится на устройстве. Это не будет работать:

cudaMalloc(&(d_c->data), sizeof(int));

потому что это требует разыменования указателя устройства (d_c) в коде хоста, что недопустимо.

Другие вопросы по тегам