【问题标题】:Handling Image pointer to pointer in CUDA处理 CUDA 中指向指针的图像指针
【发布时间】:2014-06-05 22:56:30
【问题描述】:

我一直在尝试使用具有指向 2D 图像的双指针的 CUDA 代码(部分取自 Yuval Fisher 的 Fractal Image Compression)。在处理 this 中指向指针分配的指针后,我仍然收到分段错误错误以及 “警告:无法判断指针指向的内容,假设为全局内存空间” 警告。这是整个code。我也在这里发布如下:(我很抱歉复制发布的代码)

#include <cuda.h>
#include <stdio.h>
#include <stdlib.h>
#define hsize 256
#define vsize 256

#define IMAGE_TYPE unsigned char


__global__ void kernel(IMAGE_TYPE matrixin[][hsize], IMAGE_TYPE matrixout[][hsize]) {
int tid=threadIdx.x;
int bid=blockIdx.x;

matrixout[bid][tid]=matrixin[bid][tid];
}

int fatal(char* s) {
fprintf(stderr,"%s\n",s);
return 1;
}

#define matrix_allocate(matrix,hsize,vsize,TYPE) {\
    TYPE *imptr;\
    int _i;\
    matrix=(TYPE**)malloc((vsize)*sizeof(TYPE*));\
    imptr=(TYPE*)malloc((long)(hsize)*(long)(vsize)*sizeof(TYPE));\
    if(imptr==NULL)\
    fatal("\nNo memory in matrix allocate.");\
    for(_i=0;_i<vsize;++_i,imptr+=hsize)\
    matrix[_i] = imptr;\
}\


int main() {
typedef IMAGE_TYPE IMarray[vsize][hsize];
IMAGE_TYPE **hin_image,**hout_image;

IMarray *din_image,*dout_image;


//allocate host memory
matrix_allocate(hin_image,hsize,vsize,IMAGE_TYPE)
for(int i=0;i<vsize;i++)
    for(int j=0;j<hsize;j++)
        hin_image[i][j]='a';

matrix_allocate(hout_image,hsize,vsize,IMAGE_TYPE)


//allocate device memory

cudaMalloc((void**)&din_image,(vsize*hsize)*sizeof(IMAGE_TYPE));
cudaMalloc((void**)&dout_image,(vsize*hsize)*sizeof(IMAGE_TYPE));

cudaMemcpy(din_image,hin_image, (vsize*hsize)*sizeof(IMAGE_TYPE),cudaMemcpyHostToDevice);

dim3 threads(hsize,1,1);
dim3 blocks(vsize,1,1);

kernel<<<blocks,threads>>>(din_image,dout_image);

cudaMemcpy(hout_image,dout_image,(vsize*hsize)*sizeof(IMAGE_TYPE),cudaMemcpyDeviceToHost);

for(int i=0;i<10;i++) {
    printf("\n");
    for(int j=0;j<10;j++)
        printf("%c\t",hout_image[i][j]);
}
printf("\n");

cudaFree(din_image);
cudaFree(dout_image);

free(hin_image);
free(hout_image);

return 0;
}

我想知道内核函数内部图像的标准 2D 访问有什么问题。非常欢迎任何帮助。

【问题讨论】:

  • 你找错地方了。内核永远不会在主机代码中引起分段错误。我的猜测是你的主机内存管理以某种方式被破坏了,你正在用某处的缓冲区溢出来冲洗堆栈。我在不久的将来会看到 valgrind 和/或主机调试器............
  • 你的代码错了。知道dd_imageouthd_imageout 在GPU 上,为什么还要将hd_imageout 复制到dd_imageont。你没有正确释放hd_imageout 既没有hh_imageout 也没有hh_imagein...同样的事情[...]in ptr...我认为你不应该混合主机上的ptr和GPU上的ptr,你做错了..
  • 由于您在编译时就知道数组的维度(宽度),您可以使用一些typedefs 来允许您访问内核中的多维数组但只传递一个指针(@ 987654335@)。 This code 举个例子。
  • @RobertCrovella:非常感谢您的意见。我根据您在帖子中提供的链接修改了code。我收到错误“错误:“IMarray ”类型的参数与“unsigned char ()[256]”类型的参数不兼容。我认为这是由于内核参数不兼容调用。我在我的主要评论中编辑了代码以突出显示它。
  • 是的,你仍然没有理解发生了什么。我发布了一个带有编译和运行代码的答案。

标签: c pointers image-processing cuda fractals


【解决方案1】:

我不会尝试整理您的复杂矩阵分配方案。我建议的目的是让您可以将事情简化为简单的 1 行分配。

此外,我认为您并没有真正理解我给出的示例。这是一个 3D 示例,typedef 有 2 个下标。 2D 版本将具有带有单个下标的 typedef。

这真的与 CUDA 无关。它围绕着对 C 数组和指针的理解展开。

这些是我为使您的代码正常工作所做的主要更改:

#include <stdio.h>
#include <stdlib.h>
#define hsize 256
#define vsize 256

#define IMAGE_TYPE unsigned char


__global__ void kernel(IMAGE_TYPE matrixin[][hsize], IMAGE_TYPE matrixout[][hsize]) {
  int tid=threadIdx.x;
  int bid=blockIdx.x;

  matrixout[bid][tid]=matrixin[bid][tid];
}

int fatal(char* s) {
  fprintf(stderr,"%s\n",s);
  return 1;
}


int main() {
  typedef IMAGE_TYPE IMarray[hsize];
  IMarray *hin_image,*hout_image;

  IMarray *din_image,*dout_image;


//allocate host memory
  hin_image = (IMarray *)malloc(hsize*vsize*sizeof(IMAGE_TYPE));
  hout_image = (IMarray *)malloc(hsize*vsize*sizeof(IMAGE_TYPE));

  for(int i=0;i<vsize;i++)
    for(int j=0;j<hsize;j++)
        hin_image[i][j]='a';


//allocate device memory

  cudaMalloc((void**)&din_image,(vsize*hsize)*sizeof(IMAGE_TYPE));
  cudaMalloc((void**)&dout_image,(vsize*hsize)*sizeof(IMAGE_TYPE));
  cudaMemset(dout_image, 0, (vsize*hsize)*sizeof(IMAGE_TYPE));
  cudaMemcpy(din_image,hin_image, (vsize*hsize)*sizeof(IMAGE_TYPE),cudaMemcpyHostToDevice);

  dim3 threads(hsize,1,1);
  dim3 blocks(vsize,1,1);

  kernel<<<blocks,threads>>>(din_image,dout_image);

  cudaMemcpy(hout_image,dout_image,(vsize*hsize)*sizeof(IMAGE_TYPE),cudaMemcpyDeviceToHost);

  for(int i=0;i<10;i++) {
    printf("\n");
    for(int j=0;j<10;j++)
        printf("%c\t",hout_image[i][j]);
  }
  printf("\n");

  cudaFree(din_image);
  cudaFree(dout_image);

  free(hin_image);
  free(hout_image);

  return 0;
}

【讨论】:

  • 非常感谢。我同意我需要提高我的 C 技能。代码现在可以工作了。
猜你喜欢
  • 1970-01-01
  • 2016-12-23
  • 2011-09-08
  • 1970-01-01
  • 2011-08-04
  • 2021-08-14
  • 1970-01-01
  • 1970-01-01
  • 2011-07-18
相关资源
最近更新 更多