【发布时间】:2014-09-18 19:38:09
【问题描述】:
我正在尝试从设备阵列的一部分创建纹理 3d。
为此,我的步骤如下:
- malloc 设备阵列
- 写入设备数组
- 创建 CudaArray (3D)
- 将纹理绑定到 CudaArray
我这样做的方式不会产生编译器错误,但是当我运行 cuda-memcheck 时,当我尝试从纹理中获取数据时它失败了。
无效的全局读取大小为 8 .. 地址 0x10dfaf3a0 超出范围
这就是我猜测我声明纹理数组错误的原因。 这是我访问纹理的方式:
tex3D(NoiseTextures[i],x,y,z)
我执行上述步骤的方式:
1.Malloc 设备阵列
cudaMalloc((void **)&d_Noise, sqrSizeNoise*nNoise*sizeof(float));
2.写入设备数组
curandCreateGenerator(&gen,CURAND_RNG_PSEUDO_DEFAULT);
curandSetPseudoRandomGeneratorSeed(gen,Seed);
curandGenerateUniform(gen, d_Noise, sqrSizeNoise*nNoise);
curandDestroyGenerator(gen);
3+4.创建 Cuda Array 并将其绑定到纹理(我猜是这里的错误)
cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc<float>();//cudaCreateChannelDesc(32, 0, 0, 0, cudaChannelFormatKindFloat);
cudaArray *d_cuArr;
cudaMalloc3DArray(&d_cuArr, &channelDesc, make_cudaExtent(SizeNoise,SizeNoise,SizeNoise), 0);
cudaMemcpy3DParms copyParams = {0};
//Loop for every separated Noise Texture (nNoise = 4)
for(int i = 0; i < nNoise; i++){
//initialize the textures
NoiseTextures[i] = texture<float, 3, cudaReadModeElementType>(1,cudaFilterModeLinear,cudaAddressModeWrap,channelDesc);
//Array creation
//+(sqrSizeNoise*i) is to separate the created Noise Array into smaller parts with the size of SizeNoise^3
copyParams.srcPtr = make_cudaPitchedPtr(d_Noise+(sqrSizeNoise*i), SizeNoise*sizeof(float), SizeNoise, SizeNoise);
copyParams.dstArray = d_cuArr;
copyParams.extent = make_cudaExtent(SizeNoise,SizeNoise,SizeNoise);
copyParams.kind = cudaMemcpyDeviceToDevice;
checkCudaErrors(cudaMemcpy3D(©Params));
//Array creation End
//new Bind
// set texture parameters
NoiseTextures[i].normalized = true; // access with normalized texture coordinates
NoiseTextures[i].filterMode = cudaFilterModeLinear; // linear interpolation
NoiseTextures[i].addressMode[0] = cudaAddressModeWrap; // wrap texture coordinates
NoiseTextures[i].addressMode[1] = cudaAddressModeWrap;
NoiseTextures[i].addressMode[2] = cudaAddressModeWrap;
// bind array to 3D texture
checkCudaErrors(cudaBindTextureToArray(NoiseTextures[i], d_cuArr, channelDesc));
//end Bind
}
cudaFreeArray(d_cuArr);
我已将此代码 sn-p 粘贴到 Pastebin,以便使用颜色等更容易查看。 http://pastebin.com/SM3dYd38
我希望我清楚地描述了我的问题。如果不是请评论!
你能帮我解决这个问题吗? 感谢阅读,
赛瑞
编辑: 这是一个完整的代码,您可以在自己的机器上试用:
#include <helper_cuda.h>
#include <helper_functions.h>
#include <helper_cuda_gl.h>
#include <texture_types.h>
#include <cuda_runtime.h>
#include <curand.h>
static texture<float, 3, cudaReadModeElementType> NoiseTextures[4];//texture Array
float *d_NoiseTest;//Device Array with random floats
int SizeNoiseTest = 32;
int sqrSizeNoiseTest = 32768;
void CreateTexture();
__global__ void AccesTexture(texture<float, 3, cudaReadModeElementType>* NoiseTextures)
{
int test = tex3D(NoiseTextures[0],threadIdx.x,threadIdx.y,threadIdx.z);//by using this the error occurs
}
int
main(int argc, char **argv)
{
CreateTexture();
}
void CreateTexture()
{
//curand Random Generator (needs compiler link -lcurand)
curandGenerator_t gen;
cudaMalloc((void **)&d_NoiseTest, sqrSizeNoiseTest*4*sizeof(float));//Allocation of device Array
curandCreateGenerator(&gen,CURAND_RNG_PSEUDO_DEFAULT);
curandSetPseudoRandomGeneratorSeed(gen,1234ULL);
curandGenerateUniform(gen, d_NoiseTest, sqrSizeNoiseTest*4);//writing data to d_NoiseTest
curandDestroyGenerator(gen);
//cudaArray Descriptor
cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc<float>();
//cuda Array
cudaArray *d_cuArr;
cudaMalloc3DArray(&d_cuArr, &channelDesc, make_cudaExtent(SizeNoiseTest*sizeof(float),SizeNoiseTest,SizeNoiseTest), 0);
cudaMemcpy3DParms copyParams = {0};
//Loop for every separated Noise Texture (4 = 4)
for(int i = 0; i < 4; i++){
//initialize the textures
NoiseTextures[i] = texture<float, 3, cudaReadModeElementType>(1,cudaFilterModeLinear,cudaAddressModeWrap,channelDesc);
//Array creation
//+(sqrSizeNoise*i) is to separate the created Noise Array into smaller parts with the size of SizeNoise^3
copyParams.srcPtr = make_cudaPitchedPtr(d_NoiseTest+(sqrSizeNoiseTest*i), SizeNoiseTest*sizeof(float), SizeNoiseTest, SizeNoiseTest);
copyParams.dstArray = d_cuArr;
copyParams.extent = make_cudaExtent(SizeNoiseTest*sizeof(float),SizeNoiseTest,SizeNoiseTest);
copyParams.kind = cudaMemcpyDeviceToDevice;
checkCudaErrors(cudaMemcpy3D(©Params));
//Array creation End
//new Bind
// set texture parameters
NoiseTextures[i].normalized = true; // access with normalized texture coordinates
NoiseTextures[i].filterMode = cudaFilterModeLinear; // linear interpolation
NoiseTextures[i].addressMode[0] = cudaAddressModeWrap; // wrap texture coordinates
NoiseTextures[i].addressMode[1] = cudaAddressModeWrap;
NoiseTextures[i].addressMode[2] = cudaAddressModeWrap;
// bind array to 3D texture
checkCudaErrors(cudaBindTextureToArray(NoiseTextures[i], d_cuArr, channelDesc));
//end Bind
}
cudaFreeArray(d_cuArr);
AccesTexture<<<1,dim3(4,4,4)>>>(NoiseTextures);
}
您需要链接 -lcurand。并包括 CUDA-6.0/samples/common/inc
我现在在这段代码中遇到了另一个错误
code=11(cudaErrorInvalidValue) "cudaMemcpy3D(©Params)"
即使它与我的原始代码完全相同。 - 我开始完全糊涂了。 谢谢你的帮助
【问题讨论】:
-
1.提供一个简短的完整代码,有人可以复制、粘贴、编译和运行以查看错误。所以expects this。 2. 为什么要使用纹理数组?是否可以为每个子纹理使用带有偏移到该纹理的单个纹理?或者,你看过分层纹理吗? 3. 你打算使用什么 GPU?我问是因为纹理 objects 数组(cc3.0 和更高版本)可能可行,但存在问题/限制。
-
make_cudaExtent() 的第一个参数是以字节为单位的宽度,所以据我所知应该是
make_cudaExtent(SizeNoise*sizeof(float),SizeNoise,SizeNoise); -
感谢您处理我的问题! Robert Crovella:我创建了一个简短的完整代码 sn-p,因此您可以尝试一下。 FindError.cu : pastebin.com/viQYFGA7 我还编辑了原始帖子。 2.也许可以使用大纹理并偏移值,但我认为创建多个纹理会更容易,因为我想定期多次映射纹理。我认为 adressModeWrap 将是做到这一点的好方法。分层纹理不能是 3d 的,对吗?我的目标是 cc3.0,所以纹理对象可能是可能的。 Kamil Czerski:我试过了,但错误仍然出现。
-
您最好先让您的 3D 纹理代码为 single 普通(非数组)纹理工作。
dim3(32,32,32)不是任何当前 CUDA GPU 的有效线程块配置。无论前面的代码如何,您都不可能运行该内核。而且我们不会将纹理引用作为参数传递给内核。它是一个静态实体。你只是使用它。如果您先学习基本纹理,这可能是最好的。 -
@KamilCzerski 如果 cudaArray 参与
cudaMemcpy3D操作,则用于 3D 复制参数的范围不是以字节为单位,而是以元素为单位。参考documentation
标签: c++ c arrays cuda textures