2016-06-20 5 views
0

Ich habe die folgenden (vereinfacht) Code in meinem .cu DateiWie mit Struktur im Inneren Struktur in Cuda

typedef struct 
{ 
    int leg_id; 
    int contract_id; 
} CudaLeg; 

typedef struct 
{ 
    CudaLeg* legs; 
    int no_legs; 
} CudaPortfolio; 

extern "C" 
__global__ void kernel(CudaPortfolio* o_portfolios_cuda, const int no_portfolios) 
{ 
// fill o_portfolios_cuda with data 
} 

void cudaFunction(CudaPortfolio* o_portfolios, unsigned long long no_portfolios) 
{ 
    CudaPortfolio* o_portfolios_cuda; 
    cudaMalloc((void **)& o_portfolios_cuda, sizeof(CudaPortfolio) * no_portfolios); 

    kernel<<<32, 32>>>(o_portfolios_cuda, no_portfolios); 

    cudaMemcpy(o_portfolios, o_portfolios_cuda, sizeof(CudaPortfolio) * no_portfolios, cudaMemcpyDeviceToHost); 

    //printf below works 
    printf("CPU no legs strike output portfolio: %d\n", o_portfolios[0].no_legs); 
    //printf below crashes the program 
    printf("CPU Leg 1 multiplier output portfolio: %d\n", o_portfolios[0].legs[0].multiplier); 

    cudaFree(o_portfolios_cuda); 
} 

Die GPU ist eine GTX580, SM2.0 zu arbeiten. Die GPU kann mit o_portfolios_cuda arbeiten und sie mit Daten füllen und Berechnungen damit durchführen. Der erste Ausdruck von o_portfolios [0] .no_legs gibt die korrekte Funktion zurück. Aber wenn ich versuche, auf einige der Portfolios (o_portfolios [0] .legs [0] .multiplier) zuzugreifen, stürzt das Programm ab. Irgendwelche Ideen, wie ich das beheben kann? Vielen Dank.

@Robert Crovella Ich habe schon so etwas versucht, aber es hat nicht funktioniert. Ich versuchte es noch einmal und fügte hinzu

CudaLeg* o_portfolios_legs_cuda; 
    cudaMalloc((void **)& o_portfolios_legs_cuda, sizeof(CudaLeg)); 
    cudaMemcpy(o_portfolios_legs_cuda, o_portfolios->legs, sizeof(CudaLeg), cudaMemcpyHostToDevice); 
    cudaMemcpy(&(o_portfolios_cuda->legs), &o_portfolios_legs_cuda, sizeof(CudaLeg *), cudaMemcpyHostToDevice); 

Aber jetzt stürzt das Programm auf der dritten Linie, die ich gerade hinzugefügt (cudaMemcpy (o_portfolios_legs_cuda, ...)

@MarkoR Die CudaLeg Objekte haben keine feste Anzahl

.
+5

Dieses Thema wurde oft behandelt, es ist eine tiefe Kopie genannt, zum Beispiel [hier] (http://stackoverflow.com/questions/16024087/copy-an-object-to-device/16024373#) 16024373) –

+0

@RobertCrovella Danke für den Link. Ich habe es versucht, aber jetzt stürzt mein Programm auf dem ersten cudaMemcpy ab, das der Beitrag vorschlägt, hinzuzufügen. Ich habe meine Frage mit dem hinzugefügten Code geändert. Kannst du mir sagen, was ich falsch gemacht habe? Vielen Dank. –

Antwort

1

Sie den Raum für CudaPortfolio struct Zuteilung, die ein int und ein CudaLeg Zeiger hat. Aber Sie sind die Zuweisung nicht den Raum für das, was dass CudaLeg Punkte zu. Also, wenn Sie versuchen, darauf zuzugreifen, stürzt.

Wie es zu beheben: Wenn Sie o sind Nur 1 CudaLeg haben, können Sie den Zeiger fallen lassen und CudaLeg Bein innerhalb CudaPortfolio einfach haben. Wenn Sie eine feste Anzahl von CudaLeg-Objekten haben, können Sie zum Beispiel "CudaLeg [5] Beine" in CudaPortfolio haben. Wenn Sie keine feste Anzahl von CudaLeg-Objekten haben und diese so behalten möchten, wie sie gerade ist, müssen Sie für die Anzahl der Zweige zusätzliches malloc hinzufügen und jedem Portfolio zuweisen. Sehen Sie den Link, den Robert Crovella im Kommentar gepostet hat, um zu sehen, wie es gemacht wird.

0

Wenn Sie einen Zeiger legs kopieren und auf eine Gerätespeicheradresse zeigen, müssen Sie den Hostzeiger auch auf eine Hostadresse ändern, die die Hostkopie der ursprünglichen Gerätedaten speichert.