2013-12-10 2 views
5

Zum Beispiel zuteilen ich diese folgenden Hinweise:Wie kopiert man in CUDA ein Array von Gerätezeigern auf den Gerätespeicher?

float *data_1, *data_2, *data_3, *data_4; 

//Use malloc to allocate memory and fill out some data to these pointers 
...... 
//Filling complete 

float *data_d1,*data_d2,*data_d3,*data_d4; 

cudaMalloc((void **)&data_d1,size1); 
cudaMalloc((void **)&data_d2,size2); 
cudaMalloc((void **)&data_d3,size3); 
cudaMalloc((void **)&data_d4,size4); 

cudaMemcpy(data_d1,data_1,size1,cudaMemcpyHostToDevice); 
cudaMemcpy(data_d2,data_2,size2,cudaMemcpyHostToDevice); 
cudaMemcpy(data_d3,data_3,size3,cudaMemcpyHostToDevice); 
cudaMemcpy(data_d4,data_4,size4,cudaMemcpyHostToDevice); 

Danach sollte ich schon tun, um die genauen Daten als Host-Zeiger 4 Gerätezeiger enthält. Jetzt würde ich gerne diese Zeiger in ein Array von Zeigern speichern, wie folgend,

float *ptrs[4]; 

ptrs[0] = data_d1; 
ptrs[1] = data_d2; 
ptrs[2] = data_d3; 
ptrs[3] = data_d4; 

Jetzt würde ich dieses Array von Zeigern auf CUDA Kernel übertragen möchten. Ich weiß jedoch, dass, da ptrs [4] tatsächlich auf dem Host-Speicher ist, ich einen neuen Zeiger auf dem Gerät zuweisen muss. Also tat ich dies,

float **ptrs_d; 
size_t size = 4 * sizeof(float*); 
cudaMalloc((void ***)&ptrs_d,size); 
cudaMemcpy(ptrs_d,ptrs,size,cudaMemcpyHostToDevice); 

Und dann rufen Sie den Kernel:

kernel_test<<<dimGrid,dimBlock>>>(ptrs_d, ...); 
//Declaration should be 
//__global__ void kernel_test(float **ptrs_d, ...); 

Im kernel_test, Ladedaten in folgenden Syntax:

if (threadIdx.x < length_of_data_1d) 
{ 
    float element0 = (ptrs[0])[threadIdx.x]; 
} 

compilieren ist in Ordnung, aber beim Debuggen , es gibt einen Fehler der Zugriffsverletzung.

Vielleicht gibt es eine Menge Fehler in meinem Code. Aber ich möchte nur herausfinden, warum ich Device-Pointer nicht auf diese Weise übergeben kann und wie man auf sie zugreift, wenn es in CUDA erlaubt ist, ein Array von Device-Pointern an die Kernel-Funktion zu übergeben.

Also, wie soll ich dieses Problem beheben? Irgendwelche Vorschläge werden geschätzt. Danke im Voraus.

+2

Ich sehe keine offensichtlichen Probleme mit Ihrer Methode. Ich habe einen einfachen Code um das erstellt, was Sie gezeigt haben, und es scheint für mich richtig zu funktionieren, es ist [hier] (http://pastebin.com/n1S63xLb). Ihre Zugriffsverletzung kann einfach ein Array außerhalb der Grenzen sein, basierend auf der Länge Ihrer Daten und etwas Code, den Sie hier nicht gezeigt haben. Es hat möglicherweise nichts mit Ihrer grundlegenden Methode zum Kopieren eines Arrays von Gerätezeigern zu tun. Ich schlage vor, dass Sie einen vollständigen Code bereitstellen, der das Problem reproduziert, anstatt eine Sequenz von Auszügen. Das Problem liegt in etwas, das Sie hier nicht gezeigt haben. –

+0

Vielen Dank für Ihren Vorschlag. Ich habe ein paar Mal versucht, zu debuggen und habe schließlich gelernt, dass diese Methode tatsächlich anwendbar ist. Das wirkliche Problem scheint am ehesten das Problem außerhalb der Grenzen zu sein, wie Sie vorgeschlagen haben, und jetzt versuche ich herauszufinden. Nochmals vielen Dank für Ihre reaktionsschnelle Hilfe. –

+1

Sicherlich mit dem Debugger zu laufen sollte Ihnen erlauben, eine Vorstellung davon zu bekommen, was schief läuft. Wenn Sie Ihren Code mit "cuda-memcheck" ausführen, kann dies ebenfalls einleuchten. –

Antwort

2

Eine Möglichkeit besteht darin, einen void-Zeiger zuzuordnen, wie es CUDA als Standard erwartet. Wenn Sie es in Ihren Kernel übertragen, können Sie es in float** umwandeln. Ich tat es auf diese Weise:

void* ptrs_d = 0; 
cudaMalloc(&ptrs_d, 4*sizeof(float*)); 
cudaMemcpy(ptrs_d, ptrs, 4*sizeof(float*), cudaMemcpyHostToDevice); 
kernel_test<<<dimGrid, dimBlock>>>((float**)ptrs_d); 
+1

Welches Problem hat diese Adresse? –

+0

@robert Es ist eine Möglichkeit, ein Array von Zeigern in einen Cuda-Kernel zu übergeben. – hubs

+1

Es ist unnötig, von Float zu Void und zurück zu floaten, um das zu erreichen, was gefragt wird. Der Code, den ich in meinem Kommentar-Link angegeben habe, zeigt das. –

Verwandte Themen