2017-05-18 8 views
1

CUDAの入力データからいくつかの項目(すべてではない)を選択したいと考えています。 私の入力配列d_inサイズは(申し訳ありません、それが長い)である53 * 53です:CUDAで異なるサイズの入出力を扱う方法

$abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz 
z$abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxy 
yz$abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwx 
xyz$abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvw 
wxyz$abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuv 
vwxyz$abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstu 
uvwxyz$abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrst 
tuvwxyz$abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrs 
stuvwxyz$abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqr 
rstuvwxyz$abcdefghijklmnopqrstuvwxyzabcdefghijklmnopq 
qrstuvwxyz$abcdefghijklmnopqrstuvwxyzabcdefghijklmnop 
pqrstuvwxyz$abcdefghijklmnopqrstuvwxyzabcdefghijklmno 
opqrstuvwxyz$abcdefghijklmnopqrstuvwxyzabcdefghijklmn 
nopqrstuvwxyz$abcdefghijklmnopqrstuvwxyzabcdefghijklm 
mnopqrstuvwxyz$abcdefghijklmnopqrstuvwxyzabcdefghijkl 
lmnopqrstuvwxyz$abcdefghijklmnopqrstuvwxyzabcdefghijk 
klmnopqrstuvwxyz$abcdefghijklmnopqrstuvwxyzabcdefghij 
jklmnopqrstuvwxyz$abcdefghijklmnopqrstuvwxyzabcdefghi 
ijklmnopqrstuvwxyz$abcdefghijklmnopqrstuvwxyzabcdefgh 
hijklmnopqrstuvwxyz$abcdefghijklmnopqrstuvwxyzabcdefg 
ghijklmnopqrstuvwxyz$abcdefghijklmnopqrstuvwxyzabcdef 
fghijklmnopqrstuvwxyz$abcdefghijklmnopqrstuvwxyzabcde 
efghijklmnopqrstuvwxyz$abcdefghijklmnopqrstuvwxyzabcd 
defghijklmnopqrstuvwxyz$abcdefghijklmnopqrstuvwxyzabc 
cdefghijklmnopqrstuvwxyz$abcdefghijklmnopqrstuvwxyzab 
bcdefghijklmnopqrstuvwxyz$abcdefghijklmnopqrstuvwxyza 
abcdefghijklmnopqrstuvwxyz$abcdefghijklmnopqrstuvwxyz 
zabcdefghijklmnopqrstuvwxyz$abcdefghijklmnopqrstuvwxy 
yzabcdefghijklmnopqrstuvwxyz$abcdefghijklmnopqrstuvwx 
xyzabcdefghijklmnopqrstuvwxyz$abcdefghijklmnopqrstuvw 
wxyzabcdefghijklmnopqrstuvwxyz$abcdefghijklmnopqrstuv 
vwxyzabcdefghijklmnopqrstuvwxyz$abcdefghijklmnopqrstu 
uvwxyzabcdefghijklmnopqrstuvwxyz$abcdefghijklmnopqrst 
tuvwxyzabcdefghijklmnopqrstuvwxyz$abcdefghijklmnopqrs 
stuvwxyzabcdefghijklmnopqrstuvwxyz$abcdefghijklmnopqr 
rstuvwxyzabcdefghijklmnopqrstuvwxyz$abcdefghijklmnopq 
qrstuvwxyzabcdefghijklmnopqrstuvwxyz$abcdefghijklmnop 
pqrstuvwxyzabcdefghijklmnopqrstuvwxyz$abcdefghijklmno 
opqrstuvwxyzabcdefghijklmnopqrstuvwxyz$abcdefghijklmn 
nopqrstuvwxyzabcdefghijklmnopqrstuvwxyz$abcdefghijklm 
mnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz$abcdefghijkl 
lmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz$abcdefghijk 
klmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz$abcdefghij 
jklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz$abcdefghi 
ijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz$abcdefgh 
hijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz$abcdefg 
ghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz$abcdef 
fghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz$abcde 
efghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz$abcd 
defghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz$abc 
cdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz$ab 
bcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz$a 
abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz$ 

と私は私の出力d_outへの入力から各行の最後の項目を選択します。このようにして、出力サイズは53になります。ここに私のコードです。 preSortd_intempd_outの対処データについては、2つのポインタ用にメモリを割り当てて、カーネルを起動してください。

//variables declared 
const int ARRAY_BYTES_IN = CAPACITY * sizeof(char); 
const int ARRAY_BYTES_ST = CAPACITY * CAPACITY * sizeof(char); 
const int CAPACITY = 53; 
char preSort[CAPACITY * CAPACITY]; 
char temp[CAPACITY]; 

void getLast(){ 
    //two pointers 
    char* d_in; 
    char* d_out; 

    //allocate gpu memory  
    cudaMalloc(&d_in, ARRAY_BYTES_ST); 
    cudaMalloc(&d_out, ARRAY_BYTES_IN); 

    //transfer input into gpu 
    cudaMemcpy(d_in, preSort, ARRAY_BYTES_ST, cudaMemcpyHostToDevice); 

    int size = CAPACITY*CAPACITY; 
    int blockSize = 1024; 
    int numbBlock = (size + blockSize - 1)/blockSize; 

    //Launch the kernel 
    DoGetLast<<<numbBlock, blockSize>>>(d_out, d_in); 

    //Copy back to the host 
    cudaMemcpy(temp, d_out, ARRAY_BYTES_IN, cudaMemcpyDeviceToHost); 

    cudaFree(d_in); 
    cudaFree(d_out); 
} 

GPUカーネルがメインで

__global__ void DoGetLast(char* d_out, char* d_in){ 

    int CAP = 53*53; 
    int idx = blockDim.x * blockIdx.x + threadIdx.x; 

    char f; 

    //get the output trmo the input, It's a 1-D array actually, so pick 
    //only one character through every 53 characters from d_in 

    if(idx % CAP == (CAP - 1)){ 
      f = d_in[idx]; 
      d_out[idx] = f; 
    } 
} 

ですが、私は唯一のgetLast()メソッドを呼び出すと、output.Iを示すためにループを使用すると、出力は次のようになります願っています:

zyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcba$ 

しかし、出力にはzという文字が1つしかありません。 誰でも自分のコードで問題を伝えることができますか?助けを捧げる?

+0

https://meta.stackoverflow.com/q/284236/681865 – talonmies

+0

申し訳ありませんが、私が編集しました質問は、これまでよりも良いことを願っています。 –

+2

カーネル内のコードを注意深く読んでください。 CAPの値を見てください。そして、なぜあなたは1つの出力値しか得られないのか自問してください。 [SO]は、些細な間違いを犯すサービスではありません。それを一つのように扱わないでください。 – talonmies

答えて

2

カーネルにエラーがあります。このようにカーネルを変更する必要があります。

__global__ void DoGetLast(char* d_out, char* d_in) 
{ 
    int CAP = 53; // not 53*53 
    int idx = blockDim.x * blockIdx.x + threadIdx.x; 
    if (idx < CAP * CAP) // d_in boundary check 
     if (idx % CAP == (CAP - 1)) { 
      char f = d_in[idx]; 
      d_out[idx/CAP] = f; // not d_out[idx] 
     } 
} 

あなたはproper CUDA error checking methodcuda-memcheckツールを使用してコードをチェックしていた場合、あなたはあなたのカーネルがメモリアクセスエラーを持っていることが知られているだろうし、あなたが自分で自分のコードで間違っていたものを発見した可能性があります。

(私はcuda-memcheckでコードを実行した場合、それはラインd_out[idx] = fInvalid __global__ write of size 1言います。)

また、あなたが起動numBlock * blockSizeスレッドのうち、唯一の53のスレッドがいくつかの操作を行うので、あなたのコードは、GPU使用率の劣悪レベルを持っていることに注意してください作業。残りの部分(52 * 53スレッド以上)は何もしません。

0

CUDAでは、出力サイズ以下のスレッドを作成することをお勧めします。あなたの場合は、53のスレッドしか作成しないでください。各スレッドを終了し、カーネルで今すぐ

int size = CAPACITY; 
int blockSize = 64; 
int numbBlock = (size + blockSize - 1)/blockSize; 

は、同様の行の最後の項目を選ぶ:

__global__ void DoGetLast(char* d_out, char* d_in){ 

    int idx = blockDim.x * blockIdx.x + threadIdx.x; 
    int CAP = 53; 

     if(idx >= CAP) 
     return; 

    d_out[idx] = d_in[idx*CAP]; 

} 
関連する問題