Sì, è possibile copiare un oggetto sul dispositivo per l'utilizzo sul dispositivo. Quando l'oggetto ha dei puntatori incorporati alle regioni allocate dinamicamente, il processo richiede alcuni passaggi aggiuntivi.
Vedere my answer here per una discussione su ciò che è coinvolto. Questa risposta ha anche alcuni esempi di risposte al codice ad essa collegate.
Inoltre, nella definizione della classe, se si desidera che alcune funzioni siano utilizzabili sul dispositivo, è necessario decorare tali funzioni in modo appropriato (ad esempio, probabilmente con __device__ __host__
);
EDIT: In risposta a una domanda (ora cancellato) Ecco il codice di esempio più semplice che potevo venire con basato sul codice fornito:
#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;
}
Per motivi di brevità/chiarezza ho dispensato dal solito controllo degli errori di cuda.
Rispondendo alla domanda, non è possibile allocare la memoria direttamente dall'host utilizzando il puntatore nella classe basata sul dispositivo. Questo perché cudaMalloc si aspetta un normale stoccaggio puntatore basato su host, come ad esempio quello che si ottiene con:
int *hostdata;
cudaMalloc non può funzionare con un puntatore il cui stoccaggio è già sul dispositivo. Questo non funzionerà:
cudaMalloc(&(d_c->data), sizeof(int));
perché richiede dereferenziazione un puntatore dispositivo (d_c) in codici host, che non è consentito.
ok solo un'altra domanda: Quello che vedo è che si assegna un po 'di memoria sul dispositivo, quindi si copia il valore del puntatore nell'array all'interno dell'oggetto. Perché non posso allocare direttamente myobject.array invece di utilizzare una variabile "media" per contenere i dati e copiare il puntatore in myobject.array? –
Ha risposto a questa domanda con una modifica alla mia risposta. Credo di aver già affrontato questa domanda anche nelle domande postate dopo una delle risposte collegate. –
Grazie mille, risposta molto chiara! Un'altra domanda se posso: Perché non posso fare CudaMalloc ((void **) & data, 100 * sizeof (int)) Nel costruttore invece di data = new int [100] ? Ho pensato che dovrebbe allocare sul dispositivo direttamente anziché sull'host quindi copiare sul dispositivo. Cheers –