2016-08-03 32 views
0

Ich habe zwei quadratische Matrizen: d_img und d_template. Ich versuche eine Region von d_img (in diesem Fall von der oberen linken Ecke) in d_template mit cudaMemcpy2D() zu kopieren. Aber es kopiert nicht die richtigen Bereiche. Die meisten Fragen, die ich hier gefunden habe, sind, weil ein Argument falsch ist. Aber ich bin mir ziemlich sicher, dass ich das richtig verstanden habe. Ich habe überprüft und es sind keine cudaErrors aufgetreten.Extrahieren einer Sub-Matrix von einem größeren mit cudaMemcpy2D Kopieren nicht korrekte Daten

int const TEMPLATE_DIM = 10; 
int const OFFSET_DIM = 1; 
int const IMG_DIM = 2 * OFFSET_DIM + TEMPLATE_DIM; //12 
size_t const TEMPLATE_DIM_BYTES = TEMPLATE_DIM * sizeof(int); 
size_t const IMG_DIM_BYTES = IMG_DIM * sizeof(int); 

int main(){ 

    //Larger matrix 
    int h_img[IMG_DIM][IMG_DIM]; 
    int* d_img; 
    size_t imgPitch; 
    cudaMallocPitch(&d_img, &imgPitch, IMG_DIM_BYTES, IMG_DIM); 

    //Subset matrix 
    int h_template[TEMPLATE_DIM][TEMPLATE_DIM]; 
    int* d_template; 
    size_t templatePitch; 
    cudaMallocPitch(&d_template, &templatePitch, TEMPLATE_DIM_BYTES, TEMPLATE_DIM); 

    //populate h_img, copy to d_img 
    srand(time(NULL)+1); 
    for (int y = 0; y < IMG_DIM; ++y) 
     for (int x = 0; x < IMG_DIM; ++x) 
      h_img[y][x] = y*IMG_DIM+x; 
    cout << "h_img: \n"; printTemplateImg(h_img); 
    cudaMemcpy(d_img, h_img, IMG_DIM_BYTES*IMG_DIM, cudaMemcpyHostToDevice); 

    //copy subset of d_img to d_template 
    cudaMemcpy2D(d_template, templatePitch, d_img, imgPitch, TEMPLATE_DIM_BYTES, TEMPLATE_DIM, cudaMemcpyDeviceToDevice); 
    //copy d_template to h_template to view it. 
    cudaMemcpy(h_template, d_template, TEMPLATE_DIM_BYTES*TEMPLATE_DIM, cudaMemcpyDeviceToHost); 
    cudaDeviceSynchronize(); 
    cout << "h_template: \n"; printTemplate(h_template); 
} 

Und dies ist der Ausgang

h_img: 
{ 
{0,1,2,3,4,5,6,7,8,9,10,11,} 
{12,13,14,15,16,17,18,19,20,21,22,23,} 
{24,25,26,27,28,29,30,31,32,33,34,35,} 
{36,37,38,39,40,41,42,43,44,45,46,47,} 
{48,49,50,51,52,53,54,55,56,57,58,59,} 
{60,61,62,63,64,65,66,67,68,69,70,71,} 
{72,73,74,75,76,77,78,79,80,81,82,83,} 
{84,85,86,87,88,89,90,91,92,93,94,95,} 
{96,97,98,99,100,101,102,103,104,105,106,107,} 
{108,109,110,111,112,113,114,115,116,117,118,119,} 
{120,121,122,123,124,125,126,127,128,129,130,131,} 
{132,133,134,135,136,137,138,139,140,141,142,143,} 
} 
h_template: 
{ 
{0,1,2,3,4,5,6,7,8,9,} 
{0,0,0,0,0,0,0,0,0,0,} 
{0,0,0,0,0,0,0,0,0,0,} 
{0,0,0,0,0,0,0,0,0,0,} 
{0,0,0,0,0,0,0,0,0,0,} 
{0,0,0,0,0,0,0,0,0,0,} 
{0,0,0,0,0,0,0,0,0,0,} 
{0,0,0,0,0,0,0,0,0,0,} 
{0,0,0,0,0,0,0,0,0,0,} 
{0,0,0,0,0,0,0,0,0,0,} 
} 

Warum nur, dass es die erste Zeile tun? Wenn Sie TEMPLATE_DIM auf 32 oder 96 ändern, werden seltsame Zeilensprungmuster angezeigt, falls Sie ein Muster sehen, das mir fehlt.

Antwort

2

Da die Gerätezuordnungen, die Sie verwenden möchten, linearer linearer Speicher sind, der mit cudaMallocPitch zugewiesen wurde, müssen Sie cudaMemcpy2D verwenden, um zum und vom Gerät zu übertragen. Wie es ist verwenden Sie cudaMemcpy und übertragen mit den falschen Bereichen des linearen Speichers auf dem Gerät.

Wenn Sie Ihre Sequenz von Operationen zu so etwas wie dies zu ändern:

//populate h_img, copy to d_img 
// ... 
cudaMemcpy2D(d_img, imgPitch, h_img, IMG_DIM_BYTES, IMG_DIM_BYTES, IMG_DIM, cudaMemcpyHostToDevice); 

//copy subset of d_img to d_template 
cudaMemcpy2D(d_template, templatePitch, d_img, imgPitch, TEMPLATE_DIM_BYTES, TEMPLATE_DIM, cudaMemcpyDeviceToDevice); 
//copy d_template to h_template to view it. 
cudaMemcpy2D(h_template, TEMPLATE_DIM_BYTES, d_template, templatePitch, TEMPLATE_DIM_BYTES, TEMPLATE_DIM, cudaMemcpyDeviceToHost); 

sollten Sie feststellen, dass der Code funktioniert, wie Sie es erwarten.

+0

Es funktioniert! Vielen Dank. Ich dachte, ich hätte es versucht, aber ich habe die Tonhöhen der Gerätematrizen als Hostgröße übergeben (d. H. ImgPitch statt IMG_DIM_BYTES und templatePitch anstelle von TEMPLATE_DIM_BYTES). Es stellte sich heraus, dass es ein falsches Argument war. – WillJM