В функции ядра CUDA, почему tex3D не может вернуть какое-либо значение?

Здесь у меня есть две разные версии моего кода.

Первая — это полная программа CUDA из CUDA SDK. В ядре tex3D работает хорошо.

Вторая версия более сложная, содержит множество функций OpenGL и текстур OpenGL. Его файл .cu такой же, как и первый. Однако я использую переменную cudaMalloc для получения значения из tex3D в той же функции ядра, я обнаружил, что функция tex3D ничего не возвращает. На самом деле две программы используют тот же способ создания 3D-текстуры, что и код ниже:

#define  SIZE_X 128 //numbers in elements
#define  SIZE_Y 128
#define  SIZE_Z 128
typedef float  VolumeType;
cudaExtent volumeSize = make_cudaExtent(SIZE_X, SIZE_Y, SIZE_Z); 

cudaArray *d_volumeArray = 0; //for tex
cudaArray *d_transferFuncArray; //for transferTex

texture<VolumeType, 3, cudaReadModeElementType> tex;         // 3D texture
texture<float4, 1, cudaReadModeElementType> transferTex; // 1D transfer function texture

//initialize the 3d texture "tex" with a 3D array "d_volumeArray"
cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc<VolumeType>();
cutilSafeCall( cudaMalloc3DArray(&d_volumeArray, &channelDesc, volumeSize) ); 

// set texture parameters
tex.normalized = true;                      // access with normalized texture coordinates
tex.filterMode = cudaFilterModeLinear;      // linear interpolation
tex.addressMode[0] = cudaAddressModeClamp;  // clamp texture coordinates
tex.addressMode[1] = cudaAddressModeClamp;
CUDA_SAFE_CALL(cudaBindTextureToArray(tex, d_volumeArray, channelDesc));// bind array to 3D texture

//get the real value for 3D texture "tex"
float *d_volumeMem;
cutilSafeCall(cudaMalloc((void**)&d_volumeMem, SIZE_X*SIZE_Y*SIZE_Z*sizeof(float)));

.....//assign value to d_volumeMem in GPU. I've already checked the d_volumeMem is valid

//copy d_volumeMem to 3DArray
cudaMemcpy3DParms copyParams = {0};
copyParams.srcPtr = make_cudaPitchedPtr((void*)d_volumeMem, SIZE_X*sizeof(VolumeType),   SIZE_X, SIZE_Y); 
copyParams.dstArray = d_volumeArray;
copyParams.extent = volumeSize;
copyParams.kin = cudaMemcpyDeviceToDevice;
cutilSafeCall( cudaMemcpy3D(&copyParams) ); 

Код ниже — это функция ядра, вызывающая tex3D. На самом деле это то же самое, что и ядро ​​VolumeRender CUDA SDK, то есть реализация ray-casting.

__global__ void d_render(....)
{
 ......//ray-casting progress

 float temp = tex3D(tex, pos1, pos2, pos3); 
 //pos1 pos2 pos3 is valid
 //Here actually I use a cudaMalloc variable "s" to store the temp
 //In the first version, s has different value for different position
 //In the second version, temp is 0 all the time

......//ray-casting progress
}

Я думаю, что этот код хорош, потому что большинство из них взяты из VolumeRender CUDA SDK и хорошо работают в моем коде первой версии.

Но я понятия не имею, почему во второй версии tex3D вдруг недействителен. Может быть, некоторые другие текстуры OpenGL имеют какие-то негативные эффекты?


person TonyLic    schedule 01.06.2012    source источник
comment
Кстати, при дальнейшей проверке я обнаружил, что tex3D всегда возвращает НОЛЬ.   -  person TonyLic    schedule 01.06.2012
comment
Я не вижу никакого кода ядра CUDA и вызовов tex3d() нигде в коде, который вы опубликовали.....   -  person talonmies    schedule 01.06.2012
comment
О, на самом деле код здесь — это способ создания и связывания 3D-текстуры. Ядро CUDA, использующее tex3D, вполне обычное, как и ядро ​​VolumeRender из CUDA SDK. Но чтобы было понятнее, я опубликую их прямо сейчас.   -  person TonyLic    schedule 01.06.2012
comment
Находятся ли pos1, pos2, pos3 между 0 и 1?   -  person geek    schedule 01.06.2012
comment
marina.k: Да, определенно, я использую переменную cudaMalloc для хранения pos1 pos2 pos3, все они между 0 и 1. На самом деле, я очень сомневаюсь, что причина в том, что во второй версии использование большого количества текстур в OpenGL может привести к отсутствию текстурной памяти для CUDA. Однако сообщения об ошибке нет. Является ли это возможным?   -  person TonyLic    schedule 01.06.2012
comment
Звучит подозрительно: cudaMalloc не сохраняет значения в памяти, а только выделяет их. Если вы вызываете только cudaMalloc, у вас будут неинициализированные данные.   -  person harrism    schedule 04.06.2012


Ответы (1)


На самом деле проблема в том, что я делаю привязку текстур до того, как выберу устройство CUDA. Таким образом, сначала вызов cudaChooseDevice и cudaSetGLDevice заставит все работать хорошо!

person TonyLic    schedule 07.06.2012