2016-08-03 3 views
0

私は2つの正方行列d_imgとd_templateを持っています。私はd_imgの領域(この場合は左上隅から)をc_taMemcpy2D()を使ってd_templateにコピーしようとしています。しかし、それは正しい範囲をコピーしていません。私がこれで見つけたほとんどの質問は、議論が間違っているためです。しかし、私はそれが正しいと確信しています。私はチェックしたが、cudaErrorsは発生していない。cudaMemcpy2Dが正しいデータをコピーしていない大きな行列からサブ行列を抽出する

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

そして、これが出力

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,} 
} 

なぜそれが最初の行のみを行うんでしょうか? また、TEMPLATE_DIMを32または96に変更すると、奇妙な行スキップパターンが表示されます。欠落しているパターンを表示するのに役立ちます。

答えて

2

使用するデバイスの割り当てが、cudaMallocPitchを使用して割り当てられたピッチ付き線形メモリであるため、デバイスとの間の転送にはcudaMemcpy2Dを使用する必要があります。あなたはcudaMemcpyを使用しており、デバイス上のピッチ付き線形メモリの間違った領域を使って転送しています。

あなたはこのような何かに操作のあなたの順序を変更する場合:

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

あなたはそれが期待するようなコードが動作することを見つける必要があります。

+0

これは機能します。ありがとう。私はそれを試みたと思ったが、デバイスの行列のピッチをホストのサイズ(つまり、IMG_DIM_BYTESではなくimgPitch、TEMPLATE_DIM_BYTESではなくtemplatePitch)として渡していた。それは間違った議論だった。 – WillJM

関連する問題