2

テクスチャ オブジェクトを使用して PGM イメージ ピクセルにアクセスしています。私の望みは、テクスチャが指定された座標のピクセル値をフェッチすることです。境界外の場合は 0 です。

これは私のテクスチャの説明です:

unsigned char *device_input=NULL;
size_t input_pitch;
checkCudaErrors(cudaMallocPitch(&device_input, &input_pitch, sizeof(unsigned char)*IMAGE_WIDTH, IMAGE_HEIGHT));
checkCudaErrors(cudaMemcpy2D(device_input, input_pitch, image, sizeof(unsigned char)*IMAGE_WIDTH, sizeof(unsigned char)*IMAGE_WIDTH, IMAGE_HEIGHT, cudaMemcpyHostToDevice));

cudaResourceDesc resDesc;
memset(&resDesc, 0, sizeof(resDesc));
resDesc.resType = cudaResourceTypePitch2D;
resDesc.res.pitch2D.devPtr = device_input; // 
resDesc.res.pitch2D.pitchInBytes =  input_pitch;
resDesc.res.pitch2D.width = IMAGE_WIDTH;
resDesc.res.pitch2D.height = IMAGE_HEIGHT;
resDesc.res.pitch2D.desc = cudaCreateChannelDesc<unsigned char>();

cudaTextureDesc texDesc;
memset(&texDesc, 0, sizeof(texDesc));
texDesc.readMode = cudaReadModeElementType;
texDesc.normalizedCoords=false;
texDesc.addressMode[0]=cudaAddressModeBorder;
texDesc.addressMode[1]=cudaAddressModeBorder;

cudaTextureObject_t tex;
cudaCreateTextureObject(&tex, &resDesc, &texDesc, NULL);

ただし、カーネル内では:

tex2D<unsigned char>(tex_inputImage,-100,-100)

これは明らかに画像の境界の外側にあり、値 0 ではなく image[0,0] の値を返します。

同じことが言えます:

tex2D<unsigned char>(tex_inputImage,IMAGE_WIDTH+1,IMAGE_HEIGHT+1)

0 の代わりに image[IMAGE_WIDTH,IMAGE_HEIGHT] の値を返します。

正規化された座標を使用すると、cudaAddressModeBorder は期待どおりに機能することに注意してください。ただし、正規化された座標は使用したくありません。nvidia のプログラミング ガイド (ここ) によると、cudaAddressModeBorder は正規化されていない座標でサポートされています。

私は何か間違っていますか?

4

1 に答える 1

3

これが私自身の質問に対する答えです:

プログラムは、ドライバー バージョン 319.32 のマシンで実行されました。明らかに、ドライバーには、通常の座標を使用する場合とcudaAddressModeBorder同様に処理されるバグがありました (問題の詳細はこちら - 最後の 2 組の返信を確認してください)。cudaAddressModeClamp

このバグはバージョン 319.49 で修正されcudaAddressModeBorder、正規化された座標と正規化されていない座標の両方で期待どおりに動作します。

于 2013-09-21T03:52:19.867 に答える