メインプログラムに大文字の配列があり、チャンクでデバイス のメモリにコピーしています。私は自分のプログラムで約500,000のスレッドを実行し、各スレッドは2000個の文字にアクセスします。 だから私500,000 * 2000 = 1ギガバイトは、私のカーネルでコードCUDA:ホストからデバイスにchar配列をコピーした後、 "スタックオーバーフローまたはブレークポイントヒット"と指定されていない起動エラーが発生しました
err = cudaMemcpy (dev_database, adjusted_database[k], JOBS * 2000 * sizeof(char), cudaMemcpyHostToDevice);
if(err != cudaSuccess) { printf("CUDA error: %s\n", cudaGetErrorString(err)); exit(EXIT_FAILURE); }
で一度にバイト私も定義する3つのが配列
//__shared__ char dev_query[200];
__shared__ float dev_scores[200*5];
__shared__ int dev_index[26];
を共有し、
if(threadIdx.x == 0) {
//for(i = 0; i < 200; i++){ dev_query[i] = dev_query_constant[i]; }
for(i = 0; i < 200 * 5; i++){ dev_scores[i] = dev_scores_constant[i]; }
for(i = 0; i < 26; i++){ dev_index[i] = dev_index_constant[i]; }
}
__syncthreads();
でそれらを初期化し転送します
2行のコメントを付けてプログラムを実行した場合、カーネルは奇妙な の値を返す私はchar配列の第二のチャンクをコピーするとき、私は、エラー
CUDAのエラーを取得:未指定の打ち上げ失敗
を私はすべて上記のコードの行のコメントを解除した場合正常に動作します。私は アレイのチャンクを1GBの代わりに100MBのようにコピーすると、上記と同じエラーが発生する 6番目のチャンクに達するまでうまく動作します。
これは非常に奇妙な動作であり、なぜこのようなことが起こっているのか理解したいと思います。 そこにこれを引き起こしているバグがありますか?小さいチャンク(100MBなど)を転送し、他の のものを無視すると、 プログラムが正常に動作するため、それを特定するのは難しいです。また、共有変数 に関連する行のコメントを外すか、共有変数を定数に変更するとうまくいきます。 ご協力いただければ幸いです。ありがとう!
EDIT: ここは私のカーネルです。要約すると、私は、0とその長さの間のすべてのiのi番目の文字を比較することによって2つの文字列の類似度スコアを計算しています。 このコードは、上記のエラー を生成します。if(threadIdx.x == 0) {
の直後の行のコメントを解除しない限り、このコードは発生しません。または、もしあなたが の共有配列を定数1で置き換えると、うまくいきます。
__global__ void assign7(int jobs_todo, char* database, float* results, int flag) {
unsigned int id = threadIdx.x + blockIdx.x * blockDim.x;
if(id < jobs_todo) {
__shared__ char dev_query[200];
__shared__ float dev_pos_specific_scores[200*5];
__shared__ int dev_subst_index[26];
int j_, i, p, stop, k; //stop2;
float score=0, max=0;
char ch; //ch1, ch2;
if(threadIdx.x == 0) {
//for(i = 0; i < 51; i++){ dev_query[i] = dev_query_constant[i]; }
for(i = 0; i < 5 * 200; i++){ dev_pos_specific_scores[i] = dev_pos_specific_scores_constant[i]; }
for(i = 0; i < 26; i++){ dev_subst_index[i] = dev_subst_index_constant[i]; }
}
__syncthreads();
for(i = 1; i <= 2000 - 51; i += 1){
p = jobs_todo*(i-1);
score = 0;
stop = 51/1; stop = stop*1;
for(j_ = 1; j_ <= stop; j_ += 1){
k = (j_-1)*5;
ch = database[p + id];
score += dev_pos_specific_scores[k + dev_subst_index[ch - 'A']];
if(score < 0) score = 0;
if(score > max) max = score;
p += jobs_todo;
}
}
results[id] = max;
}
}
残りのカーネルは何をしていますか?再帰を使用していますか? – perreal
私は再帰を使用していません。残りのコードはforループです。私はこのコメントの後にここにいくつか投稿します。 – Ross
私の質問に私のカーネルコードがあります。私はchar配列をホストからデバイスメモリにコピーした後、私のメインプログラムからこれを呼び出します。 – Ross