2013-04-15 15 views
8

Czy mogę skopiować obiekt C++ do urządzenia?Skopiować obiekt na urządzenie?

powiedzieć mam:

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

Teraz jak mogę skopiować "c" do pamięci urządzenia i uruchomić jądro "useClass"?

Odpowiedz

14

Tak, można skopiować obiekt do urządzenia w celu użycia na urządzeniu. Gdy obiekt ma osadzone wskaźniki do dynamicznie przydzielanych regionów, proces wymaga dodatkowych kroków.

Zobacz dyskusję o tym, co się dzieje, pod numerem my answer here. Ta odpowiedź zawiera również kilka przykładowych odpowiedzi na kod, które są z nią powiązane.

Ponadto, w definicji klasy, jeśli chcesz, aby pewne funkcje były użyteczne w urządzeniu, należy odpowiednio udekorować te funkcje (tj. Prawdopodobnie z __device__ __host__);

EDIT: W odpowiedzi na pytanie (obecnie usunięty) Oto najprostszy przykładowy kod mogę wymyślić na podstawie kodu dostarczanego:

#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; 
} 

w interesie zwięzłości/jasności mam zrezygnowano ze zwykłego sprawdzania błędów Cudy.

Odpowiadając na pytanie, nie można przydzielić pamięci masowej bezpośrednio z hosta za pomocą wskaźnika w klasie opartej na urządzeniu. To dlatego cudaMalloc oczekuje zwykły hosta przechowywanie wskaźnik oparty, na przykład, co się z:

int *hostdata; 

cudaMalloc nie może pracować ze wskaźnikiem, który jest już na przechowywanie urządzenia. To nie będzie działać:

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

ponieważ wymaga dereferencji wskaźnik urządzenia (d_c) w kodzie gospodarza, co jest niedozwolone.

+0

ok jeszcze jedno pytanie: Widzę, że przydzielono trochę pamięci na urządzeniu, a następnie skopiuj wartość wskaźnika do tablicy wewnątrz obiektu. Dlaczego nie mogę przydzielić bezpośrednio do myobject.array zamiast używać "środkowej" zmiennej do przechowywania danych i skopiować jej wskaźnik do myobject.array? –

+0

Odpowiedziały na to pytanie z poprawką w mojej odpowiedzi. Wydaje mi się, że już odpowiedziałem na to pytanie w pytaniach zamieszczonych po jednej z połączonych odpowiedzi. –

+0

Dziękuję bardzo, bardzo jasne odpowiedź! Jeszcze jedno pytanie, jeśli mogę: Dlaczego nie mogę zrobić CudaMalloc ((void **) i danych, 100 * sizeof (int)) W konstruktorze zamiast danych = nowy int [100] ? Myślałem, że należy przydzielić urządzenie bezpośrednio, a nie na komputerze, a następnie skopiować na urządzenie. Pozdrowienia –

Powiązane problemy