Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/xamarin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
新的CUDA纹理对象--在2D情况下获取错误数据_Cuda_Textures_Gpu - Fatal编程技术网

新的CUDA纹理对象--在2D情况下获取错误数据

新的CUDA纹理对象--在2D情况下获取错误数据,cuda,textures,gpu,Cuda,Textures,Gpu,在CUDA 5.0中,NVIDIA添加了一个“纹理对象”(cudaTextureObject_t),使纹理更易于使用。以前,有必要将纹理定义为全局变量 我接着使用了cudaTextureObject\u t。它适用于1D情况。我尝试将该示例扩展到2D倾斜内存: #define WIDTH 6 #define HEIGHT 2 int width = WIDTH; int height = HEIGHT; float h_buffer[12] = {1,2,3,4,5,6,7,8,9,10,11

在CUDA 5.0中,NVIDIA添加了一个“纹理对象”(
cudaTextureObject_t
),使纹理更易于使用。以前,有必要将纹理定义为全局变量


我接着使用了
cudaTextureObject\u t
。它适用于1D情况。我尝试将该示例扩展到2D倾斜内存:

#define WIDTH 6
#define HEIGHT 2
int width = WIDTH; int height = HEIGHT;
float h_buffer[12] = {1,2,3,4,5,6,7,8,9,10,11,12};
float* d_buffer;
size_t pitch;
cudaMallocPitch(&d_buffer, &pitch, sizeof(float)*width, height);
cudaMemcpy2D(d_buffer, pitch, &h_buffer, sizeof(float)*width, sizeof(float)*width, height, cudaMemcpyHostToDevice);
printf("pitch = %d \n", pitch);

//CUDA 5 texture objects: https://developer.nvidia.com/content/cuda-pro-tip-kepler-texture-objects-improve-performance-and-flexibility
cudaResourceDesc resDesc;
memset(&resDesc, 0, sizeof(resDesc));
resDesc.resType = cudaResourceTypePitch2D;
resDesc.res.pitch2D.devPtr = d_buffer;
resDesc.res.pitch2D.pitchInBytes =  pitch;
resDesc.res.pitch2D.width = width;
resDesc.res.pitch2D.height = height;
resDesc.res.pitch2D.desc.f = cudaChannelFormatKindFloat;
resDesc.res.pitch2D.desc.x = 32; // bits per channel 
resDesc.res.pitch2D.desc.y = 32; 
cudaTextureDesc texDesc;
memset(&texDesc, 0, sizeof(texDesc));
texDesc.readMode = cudaReadModeElementType;
cudaTextureObject_t tex;
cudaCreateTextureObject(&tex, &resDesc, &texDesc, NULL);
为了查看数据是否确实可以通过纹理缓存访问,我在这个内核中打印了几个字节:

__global__ void printGpu_tex(cudaTextureObject_t tex) {
    int tidx = blockIdx.x * blockDim.x + threadIdx.x;
    int tidy = blockIdx.y * blockDim.y + threadIdx.y;
    if(tidx < WIDTH && tidy < HEIGHT){
        float x = tex2D<float>(tex, tidy, tidx);
        printf("tex2D<float>(tex, %d, %d) = %f \n", tidy, tidx, x);
    }
}
输出看起来不错(与纹理缓存版本不同):


关于纹理缓存版本可能出现的问题有什么想法吗?


下载:

  • (如上所述)

  • 您在
    resDesc.res.pitch2D.desc
    中的
    cudaChannelFormatDesc
    错误:
    y
    应该是
    0

    要设置
    FormatDesc
    右侧,请使用
    CreateChannelDesc()
    函数,如
    resDesc.res.pitch2D.desc=cudaCreateChannelDesc()而不是手动设置


    resDesc.res.pitch2D.desc.y=32
    float2
    纹理有效。

    除了
    cudaChannelFormatDesc
    ,代码中似乎有一个逻辑问题,这不是什么大问题,但如果不谨慎,可能会产生误导。如果你想遵循CUDA线程组织为块和网格,并安排包裹的方式(此外,如果你的代码与C++的“行主要”概念一致),最好考虑<代码> x <代码>作为最快变化的维度(类似于行专业)。由于您的代码显示
    y
    的变化速度快于
    x
    ,因此更合适的方法是切换代码中的索引:

    float x = tex2D<float>(tex, tidx, tidy);
    printf("tex2D<float>(tex, %d, %d) = %f \n", tidx, tidy, x);
    ...
    printf("d_buffer[%d][%d] = %f \n", tidx, tidy, x);
    
    float x=tex2D(tex,tidx,tidy);
    printf(“tex2D(tex,%d,%d)=%f\n”,tidx,tidy,x);
    ...
    printf(“d_缓冲区[%d][%d]=%f\n”,tidx,tidy,x);
    

    再次值得一提的是,这不是一个大问题,但同时可能会非常混乱,特别是当您想将此内核与代码的其他部分集成时。

    我猜部分问题在于
    cudamalocitch
    vs
    cudamalocarray
    。在旧的纹理缓存API中,
    cudamalocarray
    是典型的使用方式。但是,
    cudamalocarray
    需要一个
    cudaChannelFormatDesc
    ,它在新的
    cudaTextureObject\u t
    界面中似乎过时了。毫无理由地投票是一种不好的方式!!至少您可以留下一条注释来指出错误。通过这种方式,人们将了解为什么某些事情是错误的(知道某些事情是错误的是科学的一部分)。
    __global__ void printGpu_vanilla(float* d_buffer, int pitch) {
        int tidx = blockIdx.x * blockDim.x + threadIdx.x;
        int tidy = blockIdx.y * blockDim.y + threadIdx.y;
        if(tidx < WIDTH && tidy < HEIGHT){
            float x = d_buffer[tidy*pitch + tidx];
            printf("d_buffer[%d][%d] = %f \n", tidy, tidx, x);
        }
    }
    
    d_buffer[0][0] = 1.000000 
    d_buffer[0][2] = 2.000000 
    d_buffer[0][3] = 3.000000 
    d_buffer[0][4] = 4.000000 
    d_buffer[0][5] = 5.000000 
    d_buffer[0][5] = 6.000000 
    d_buffer[1][0] = 7.000000 
    d_buffer[1][6] = 8.000000 
    d_buffer[1][7] = 9.000000 
    d_buffer[1][8] = 10.000000 
    d_buffer[1][9] = 11.000000 
    d_buffer[1][5] = 12.000000 
    
    float x = tex2D<float>(tex, tidx, tidy);
    printf("tex2D<float>(tex, %d, %d) = %f \n", tidx, tidy, x);
    ...
    printf("d_buffer[%d][%d] = %f \n", tidx, tidy, x);