Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/60.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
使用copyin和copyout的OpenAcc错误_C_Pointers_Gpu_Buffer Overflow_Openacc - Fatal编程技术网

使用copyin和copyout的OpenAcc错误

使用copyin和copyout的OpenAcc错误,c,pointers,gpu,buffer-overflow,openacc,C,Pointers,Gpu,Buffer Overflow,Openacc,一般资料 注意:我对C、OpenAcc也是相当陌生的 您好,我正在尝试开发一个图像模糊程序,但首先我想看看是否可以并行化for循环和copyin/copyout我的值 我目前面临的问题是,当我尝试复制输入和复制输出我的数据和输出变量时。这个错误看起来是缓冲区溢出(我也用谷歌搜索了一下,人们都这么说),但我不确定该如何解决这个问题。我想我的指针有问题,但我不确定 提前非常感谢,如果您认为我遗漏了一些信息,请让我知道,我可以提供 问题: 我想确认错误到底是什么 我应该如何着手解决这个问题 任何我应该

一般资料

注意:我对C、OpenAcc也是相当陌生的

您好,我正在尝试开发一个图像模糊程序,但首先我想看看是否可以并行化for循环和copyin/copyout我的值

我目前面临的问题是,当我尝试复制输入和复制输出我的数据和输出变量时。这个错误看起来是缓冲区溢出(我也用谷歌搜索了一下,人们都这么说),但我不确定该如何解决这个问题。我想我的指针有问题,但我不确定

提前非常感谢,如果您认为我遗漏了一些信息,请让我知道,我可以提供

问题:

  • 我想确认错误到底是什么
  • 我应该如何着手解决这个问题
  • 任何我应该进一步研究的问题,以便我将来能够自己解决此类问题
  • 错误

    程序定义

    #包括
    #包括
    #包括
    #包括
    // ================================================
    //ppmFile.h
    // ================================================
    #包括
    typedef结构图像
    {
    整数宽度;
    内部高度;
    无符号字符*数据;
    }形象;
    图像*图像创建(整数宽度,
    内部高度);
    图像*图像读取(字符*文件名);
    无效图像写入(图像*图像,
    字符*文件名);
    int ImageWidth(图像*图像);
    int ImageHeight(图像*图像);
    无效图像清除(图像*图像,
    未签名的字符红色,
    无符号字符绿色,
    无符号字符(蓝色);
    无效图像设置像素(图像*图像,
    int x,
    INTY,
    陈英杰,
    无符号字符(val);
    无符号字符ImageGetPixel(图像*图像,
    int x,
    INTY,
    陈国强),;
    
    模糊滤波函数

    //================================================
    //模糊过滤器
    // ================================================
    void ProcessImageACC(图像**数据,整型过滤器,图像**输出){
    int行=(*数据)->高度;
    整数列=(*数据)->宽度;
    #pragma acc data copyin(行、列、筛选器列、(*data)->数据[0:row*col])copyout((*output)->数据[0:row*col])
    #pragma-acc核
    {
    #pragma acc环路独立
    对于(int j=0;j数据[j*行+i]=(*数据)->数据[j*行+i];
    }
    }
    }
    }
    
    主要功能

    //================================================
    //主程序
    // ================================================
    int main(int argc,char*argv[]){
    //用于处理的变量:
    图像*数据,*结果;
    int-dataSize;
    int filteradius=atoi(argv[1]);
    //==读取数据===
    数据=图像读取(argv[2]);
    //==向节点发送数据===
    //发送数据大小(字节)
    dataSize=sizeof(无符号字符)*数据->宽度*数据->高度*3;
    //==处理图像===
    //分配空间来存储结果
    结果=(图像*)malloc(sizeof(图像));
    结果->数据=(无符号字符*)malloc(数据大小);
    结果->宽度=数据->宽度;
    结果->高度=数据->高度;
    //将全部初始化为0
    对于(int i=0;i<(结果->宽度*结果->高度*3);i++){
    结果->数据[i]=0;
    }
    //应用过滤器
    ProcessImageACC(数据、过滤器和结果);
    //==保存回数据===
    ImageWrite(结果,argv[3]);
    返回0;
    }
    
    这里的问题是,除了数据数组之外,还需要复制输出和数据指针。从编译器的反馈消息中,您可以看到编译器隐式地将它们复制过来

    % pgcc -c image.c -ta=tesla:cc70 -Minfo=accel
    ProcessImageACC:
         46, Generating copyout(output->->data[:col*row])
             Generating copyin(data->->data[:col*row],col,filterRad,row)
         47, Generating implicit copyout(output[:1])
             Generating implicit copyin(data[:1])
         50, Loop is parallelizable
         52, Loop is parallelizable
             Accelerator kernel generated
             Generating Tesla code
             50, #pragma acc loop gang, vector(4) /* blockIdx.y threadIdx.y */
             52, #pragma acc loop gang, vector(32) /* blockIdx.x threadIdx.x */
    
    现在,您可以通过使用非结构化数据区域来创建数据和指针,然后将指针“附加”到数组(即,将设备指针的值填充到设备数据数组的地址)来实现这一点

    尽管更简单的选择是创建指向数据的临时数组,然后将数据复制到设备。这还将提高代码的性能(在GPU和CPU上),因为它消除了额外的间接寻址级别

    void ProcessImageACC(Image **data, int filterRad, Image **output) {
      int row = (*data)->height;
      int col = (*data)->width;
      unsigned char * ddata, * odata;
      odata = (*output)->data;
      ddata = (*data)->data;
    
      #pragma acc data copyin(ddata[0:row * col]) copyout(odata[0:row * col])
      #pragma acc kernels
      {
        #pragma acc loop independent
        for (int j = 0; j < row; j++) {
          #pragma acc loop independent
          for (int i = 0; i < col; i++) {
            odata[j * row + i] = ddata[j * row + i];
          }
        }
      }
    }
    
    void ProcessImageACC(图像**数据、整型过滤器、图像**输出){
    int行=(*数据)->高度;
    整数列=(*数据)->宽度;
    无符号字符*ddata,*odata;
    odata=(*输出)->数据;
    ddata=(*数据)->数据;
    #pragma acc数据复制输入(ddata[0:row*col])复制输出(odata[0:row*col])
    #pragma-acc核
    {
    #pragma acc环路独立
    对于(int j=0;j
    请注意,标量在默认情况下是firstprivate的,因此无需在data子句中添加row、col和filterRad变量

    // ================================================
    // The Blur Filter
    // ================================================
    
    void ProcessImageACC(Image **data, int filterRad, Image **output) {
      int row = (*data)->height;
      int col = (*data)->width;
    
      #pragma acc data copyin(row, col, filterRad, (*data)->data[0:row * col]) copyout((*output)->data[0:row * col])
      #pragma acc kernels
      {
        #pragma acc loop independent
        for (int j = 0; j < row; j++) {
          #pragma acc loop independent
          for (int i = 0; i < col; i++) {
            (*output)->data[j * row + i] = (*data)->data[j * row + i];
          }
        }
      }
    }
    
    // ================================================
    // Main Program
    // ================================================
    int main(int argc, char *argv[]) {
      // vars used for processing:
      Image *data, *result;
      int    dataSize;
      int    filterRadius = atoi(argv[1]);
    
      // ===read the data===
      data = ImageRead(argv[2]);
    
      // ===send data to nodes===
      // send data size in bytes
      dataSize = sizeof(unsigned char) * data->width * data->height * 3;
    
      // ===process the image===
      // allocate space to store result
      result         = (Image *)malloc(sizeof(Image));
      result->data   = (unsigned char *)malloc(dataSize);
      result->width  = data->width;
      result->height = data->height;
    
      // initialize all to 0
      for (int i = 0; i < (result->width * result->height * 3); i++) {
        result->data[i] = 0;
      }
    
      // apply the filter
      ProcessImageACC(&data, filterRadius, &result);
    
      // ===save the data back===
      ImageWrite(result, argv[3]);
    
      return 0;
    }
    
    % pgcc -c image.c -ta=tesla:cc70 -Minfo=accel
    ProcessImageACC:
         46, Generating copyout(output->->data[:col*row])
             Generating copyin(data->->data[:col*row],col,filterRad,row)
         47, Generating implicit copyout(output[:1])
             Generating implicit copyin(data[:1])
         50, Loop is parallelizable
         52, Loop is parallelizable
             Accelerator kernel generated
             Generating Tesla code
             50, #pragma acc loop gang, vector(4) /* blockIdx.y threadIdx.y */
             52, #pragma acc loop gang, vector(32) /* blockIdx.x threadIdx.x */
    
    void ProcessImageACC(Image **data, int filterRad, Image **output) {
      int row = (*data)->height;
      int col = (*data)->width;
      unsigned char * ddata, * odata;
      odata = (*output)->data;
      ddata = (*data)->data;
    
      #pragma acc data copyin(ddata[0:row * col]) copyout(odata[0:row * col])
      #pragma acc kernels
      {
        #pragma acc loop independent
        for (int j = 0; j < row; j++) {
          #pragma acc loop independent
          for (int i = 0; i < col; i++) {
            odata[j * row + i] = ddata[j * row + i];
          }
        }
      }
    }