CUDA读取纹理内存出错

mbb_333 mbb_333 墨衍会员 · AI 创作全网分发 墨衍智能分发 通过墨衍一键同步至各平台 可同步平台 CSDN微信公众号微博知乎掘金百家号博客园抖音小红书 你的文章也可以这样分发 墨衍会员 ¥399起/年,写一次发全网 我也要 + 加入社区
如题,这个问题很让人困惑,我使用CUDA数组和cudaMallocPitch分配的一维数组都不好用,都出现乱码
我的kernel函数为:



texture<float, cudaTextureType2D, cudaReadModeElementType> texSrc;
__inline__ __global__ void convolutionRows_kernel( float *d_Dst, int imageH, int imageW)
{
int ix = __mul24(blockIdx.x, blockDim.x) + threadIdx.x;
int iy = __mul24(blockIdx.y, blockDim.y) + threadIdx.y;
while(ix < imageW && iy < imageH)
{
float fx = (float) ix + 0.5f;
float fy = (float) iy + 0.5f;
d_Dst[ix + __mul24(iy, imageW)] = tex2D(texSrc, fx, fy);
ix += blockDim.x;
iy += blockDim.y;
}
}







#1-- CUDA数组的使用是:
#1.1--下面的代码是绑定CUDA数组到texture及函数调用

static void convolutionRowsGPU(float* d_DstData, cudaArray* d_srcDataArray, cudaChannelFormatDesc floatTex, unsigned int imageHeight, unsigned int imageWidth)
{
dim3 myBlock(16, 12);
dim3 myGrid((imageWidth+(blockDim.x -1))/blockDim.x, (imageHeight +(blockDim.y -1))/ blockDim.y );
//#1-- bind array to texture
CUDA_SAFE_CALL( cudaBindTextureToArray(texSrc, d_srcDataArray, floatTex));
//#2 -- call kernel function for row convolution
convolutionRows_kernel <<< myGrid , myBlock >>>(d_DstData, imageHeight, imageWidth);
cudaGetLastErrorWrapper("convolutionRows_kernel");
//#3--unbind texture CUDA_SAFE_CALL(cudaUnbindTexture(texSrc));
}



#1.2--下面是CUDA数组相关的纹理使用

unsigned int imageHeight = 640;
unsigned int imageWidth = 480;
float* h_sorce2DImage_f = new float[ imageHeight * imageWidth ];
//分配CUDA数组并赋值
cudaArray* d_fDataArray;
cudaChannelFormatDesc floatTex = cudaCreateChannelDesc<float>();
cudaMallocArrayWrapper(&d_fDataArray, & floatTex, imageWidth, imageHeight);
//d_sorce2DImage_f 是定义的device端变量,大小为imageHeight * imageWidth *sizeof(float)
cudaMemcpyToArrayWrapper(d_fDataArray, 0, 0, d_sorce2DImage_f, imageSize * sizeof(float), cudaMemcpyDeviceToDevice);

//测试1,测试CUDA数组内容
cudaError_t myError = cudaMemcpy2DFromArray(h_sorce2DImage_f, imageWidth, d_fDataArray, 0, 0, imageWidth, imageHeight, cudaMemcpyDeviceToHost);
WiteDataToFile("filted1.txt", h_sorce2DImage_f, imageWidth, imageHeight);

//调用函数,主要是读取纹理内容
convolutionRowsGPU (d_sorce2DImage_f, d_fDataArray,floatTex, imageHeight, imageWidth);
//测试2,测试从纹理中读取的内容
cudaMemcpyWrapper(h_sorce2DImage_f, d_sorce2DImage_f, imageSize * sizeof(float), cudaMemcpyDeviceToHost);
WiteDataToFile("filted2.txt", h_sorce2DImage_f, imageWidth, imageHeight);

delete [] h_sorce2DImage_f ;


注:其中函数cudaMallocArrayWrapper(),cudaMemcpyToArrayWrapper(),cudaMemcpyWrapper()只是为了方便进行了封装,不过只是在调用对应CUDA的函数后加上宏 CUDA_SAFE_CALL ()而已。

#2--绑定cudaMallocPitch分配的线性内存到纹理内存的情况
这里面的原因是因为cudaMalloc分配的pitch不是2的倍数,在绑定内存时会出错。

#2.1--下面的代码是绑定cudaMallocPitch分配的线性内存到纹理内存及相关调用


static void convolutionRowsGPU(float* d_DstData, const float* d_bindLinearMem, unsigned int imageHeight, unsigned int imageWidth, size_t pitch)
{
dim3 myBlock(16, 12);
dim3 myGrid((imageWidth+(blockDim.x -1))/blockDim.x, (imageHeight +(blockDim.y -1))/ blockDim.y );
size_t offset;
//绑定纹理内存
cudaChannelFormatDesc chennelDesc = cudaCreateChannelDesc();
cudaBindTexture2D(&offset, texSrc, d_bindLinearMem, chennelDesc, imageWidth, imageHeight, pitch);
//调用核函数
convolutionRows_kernel <<<myGrid, myBlock>>(d_DstData, imageHeight, imageWidth);
cudaGetLastErrorWrapper("convolutionRows_kernel");
//解绑定
CUDA_SAFE_CALL(cudaUnbindTexture(texSrc));
}


#2.2--下面是 cudaMallocPitch分配的线性内存相关的纹理使用

unsigned int imageHeight = 640;
unsigned int imageWidth = 480;
float* h_sorce2DImage_f = new float[ imageHeight * imageWidth ];

//cudaMallocPitchWrapper分配内存,并赋值
float* d_linearGloabalMem;
size_t pitch;
cudaMallocPitchWrapper(((void**)& d_linearGloabalMem), &pitch, imageWidth * sizeof(float), imageHeight);
myError = cudaMemcpy2D(d_linearGloabalMem, pitch, d_sorce2DImage_f, imageWidth * sizeof(float), imageWidth * sizeof(float), imageHeight, cudaMemcpyDeviceToDevice);

//测试3,测试cudaMallocPitch()分配的内存内容
myError = cudaMemcpy2D(h_sorce2DImage_f, imageWidth * sizeof(float), d_linearGloabalMem, pitch, imageWidth * sizeof(float), imageHeight, cudaMemcpyDeviceToHost);
WiteDataToFile("filted3.txt", h_sorce2DImage_f, imageWidth, imageHeight);

//调用函数,主要是读取纹理内容
convolutionRowsGPU (d_sorce2DImage_f, d_linearGloabalMem, imageHeight, imageWidth, pitch);

//测试4,测试从纹理中读取的内容
cudaMemcpyWrapper(h_sorce2DImage_f, d_sorce2DImage_f, imageSize * sizeof(float), cudaMemcpyDeviceToHost);
WiteDataToFile("filted4.txt", h_sorce2DImage_f, imageWidth, imageHeight);
delete [] h_sorce2DImage_f ;


很令人感到意外的是测试1 和测试3都有正确的结果,但是测试2 和测试4都是乱码,这个我确实不解,有那个大牛帮忙分析下。

...全文

相关推荐

CUDA VS Wizard 2.0 beta

**内存层次**:CUDA提供了多种类型的内存,包括全局内存、共享内存、纹理内存和常量内存等,根据数据访问模式选择合适的内存类型能有效提升性能。4.

OpenHero

基于GPU的Harris图像特征提取.pdf

传统的方法依赖于人工水火弯板工艺,效率低下且易出错。随着三维测量技术的发展,视觉测量技术成为主流,特别是非接触式的主动视觉测量,如结构光法。

数据资源

CUDA编程实战:从GPU并行计算原理到环境部署与性能优化

GPU并行计算是现代高性能计算的核心技术之一,它通过成千上万的计算核心同时处理海量数据,突破了传统CPU串行处理的性能瓶颈。其原理基于单指令多数据流架构,特别适合处理矩阵运算等高度并行的任务,在人工智能、科学计算和大数据分析领域展现出巨大技术价值。CUDA作为英伟达推出的统一计算架构,通过网格、线程块和线程的三级抽象模型,为开发者提供了高效的GPU编程接口。在实际应用中,合理利用全局内存、共享内存和寄存器的层次结构,并优化内存访问模式,是提升程序性能的关键。本文以环境部署和性能调优为主线,结合Nsight性

weixin_30345577

CUDA并行计算在OCT医学影像处理中的实战应用与优化

并行计算作为高性能计算的核心技术,通过同时执行多个计算任务来大幅提升处理效率,其原理在于将大规模问题分解为可独立处理的子任务并分配到多个处理器上同时执行。在医学影像处理领域,这一技术价值尤为突出,能够将传统串行算法难以应对的海量数据计算时间从分钟级缩短至秒级。光学相干断层扫描(OCT)图像因其高分辨率特性,数据量庞大,处理流程中的去噪、分割等环节天然适合数据并行化。CUDA作为NVIDIA推出的并行计算平台,允许开发者利用GPU的数千个核心进行通用计算,通过编写核函数(Kernel)将计算密集型任务映射到海

weixin_34008933

GPU并行计算从入门到精通:核心架构、CUDA编程与性能优化全解析

并行计算是现代高性能计算的核心技术,其基本原理是通过同时执行多个计算任务来大幅提升处理速度。在硬件层面,GPU凭借其数千个流处理器核心和层次化的内存架构,成为处理大规模数据并行任务的理想平台。这一技术价值在于能够高效应对人工智能训练、科学模拟和图形渲染等对算力要求极高的场景。理解GPU的SM(流多处理器)、线程束调度以及全局内存与共享内存的差异,是进行有效编程和优化的基础。例如,在部署PyTorch进行大模型微调或解决GPU利用率低下问题时,掌握CUDA编程模型中的网格与线程块组织、内存合并访问以及使用Ns

weixin_33924312
评论 13
收藏 已收藏
分享
返回顶部
mbb_333
CUDA 591 成员 2,925 内容