2017-05-31 46 views
0

我想并行化一个简单的mandelbrot c程序,但我得到这个错误,不包括acc例程信息。另外,我不确定是否应该将数据复制到并行部分。 PS我对并行编程相对来说比较新,所以任何有关学习它的建议都会很感激。OpenACC必须有常规信息错误

(警告编译时)

PGC-S-0155-Procedures called in a compute region must have acc routine information: fwrite (mandelbrot.c: 88) 
PGC-S-0155-Accelerator region ignored; see -Minfo messages (mandelbrot.c: 51) 
main: 
    51, Accelerator region ignored 
    88, Accelerator restriction: call to 'fwrite' with no acc routine information 
PGC/x86-64 Linux 16.10-0: compilation completed with severe errors 

这是我的代码:

#include <stdio.h> 
#include <math.h> 
int main() 
{ 
    /* screen (integer) coordinate */ 
    int iX,iY; 
    const int iXmax = 800; 
    const int iYmax = 800; 
    /* world (double) coordinate = parameter plane*/ 
    double Cx,Cy; 
    const double CxMin=-2.5; 
    const double CxMax=1.5; 
    const double CyMin=-2.0; 
    const double CyMax=2.0; 
    /* */ 
    double PixelWidth=(CxMax-CxMin)/iXmax; 
    double PixelHeight=(CyMax-CyMin)/iYmax; 
    /* color component (R or G or B) is coded from 0 to 255 */ 
    /* it is 24 bit color RGB file */ 
    const int MaxColorComponentValue=255; 
    FILE * fp; 
    char *filename="new1.ppm"; 
    char *comment="# ";/* comment should start with # */ 
    static unsigned char color[3]; 
    /* Z=Zx+Zy*i ; Z0 = 0 */ 
    double Zx, Zy; 
    double Zx2, Zy2; /* Zx2=Zx*Zx; Zy2=Zy*Zy */ 
    /* */ 
    int Iteration; 
    const int IterationMax=200; 
    /* bail-out value , radius of circle ; */ 
    const double EscapeRadius=2; 
    double ER2=EscapeRadius*EscapeRadius; 
    /*create new file,give it a name and open it in binary mode */ 
    fp= fopen(filename,"wb"); /* b - binary mode */ 
    /*write ASCII header to the file*/ 
    fprintf(fp,"P6\n %s\n %d\n %d\n %d\n",comment,iXmax,iYmax,MaxColorComponentValue); 
    /* compute and write image data bytes to the file*/ 
    #pragma acc parallel loop present(CyMin, iY, PixelHeight, iX, iXmax, CxMin, PixelWidth, Zx, Zy, Zx2, Zy2, Iteration, IterationMax) 
    for(iY=0;iY<iYmax;iY++) 
    { 
     Cy=CyMin + iY*PixelHeight; 
     if (fabs(Cy)< PixelHeight/2) Cy=0.0; /* Main antenna */ 
     #pragma acc loop 
     for(iX=0;iX<iXmax;iX++) 
     { 
      Cx=CxMin + iX*PixelWidth; 
      /* initial value of orbit = critical point Z= 0 */ 
      Zx=0.0; 
      Zy=0.0; 
      Zx2=Zx*Zx; 
      Zy2=Zy*Zy; 
      /* */ 
      #pragma acc loop 
      for (Iteration=0;Iteration<IterationMax && ((Zx2+Zy2)<ER2);Iteration++) 
      { 
       Zy=2*Zx*Zy + Cy; 
       Zx=Zx2-Zy2 +Cx; 
       Zx2=Zx*Zx; 
       Zy2=Zy*Zy; 
      }; 
      /* compute pixel color (24 bit = 3 bytes) */ 
      if (Iteration==IterationMax) 
      { /* interior of Mandelbrot set = black */ 
       color[0]=0; 
       color[1]=0; 
       color[2]=0; 
      } 
      else 
      { /* exterior of Mandelbrot set = white */ 
       color[0]=255; /* Red*/ 
       color[1]=255; /* Green */ 
       color[2]=255;/* Blue */ 
      }; 
      /*write color to the file*/ 
      fwrite(color,1,3,fp); 
     } 
    } 
    fclose(fp); 
    return 0; 
} 
+0

你为什么用“openmp”标签标记这个?这里没有OpenMP ... –

回答

0

当使用OpenACC的,平行的区域被卸载到一个设备,像GPU。 GPU设备通常无法访问整个系统或IO,并且实现了标准库的减少子集。 在你的情况下,fwrite函数调用不能被卸载到设备,因为你不能从加速器访问磁盘。 您可以在OpenMP中执行此操作,其中并行区域在CPU或MIC线程上执行,通常可以访问整个系统库。 acc例程 PGC建议的指令将允许您注释任何函数来创建它的设备版本。

2

由于您无法从GPU访问文件,因此您需要将结果捕获到数组,然后将其复制回主机,然后将结果输出到文件。

此外,“present”子句表示您已经将数据复制到设备,如果程序不存在,程序将中止。鉴于使用情况,我认为你的意思是使用“私人”,这表明该变量应该对执行级别是私人的。然而标量在OpenACC中默认是私有的,所以不需要手动私有化这些变量。如果你手动私有化一个变量,一定要把它放在正确的循环级别。例如,如果您在外部循环中对“Zx”进行了私有化,那么它将只对该循环级别专用。它将被内部循环的所有向量共享!同样,在这里,最好让编译器处理标量私有化,但要注意在少数情况下你必须手动对变量进行私有化。

以下是您的代码的更正版本。

#include <stdio.h> 
#include <math.h> 

int main() 
{ 
    /* screen (integer) coordinate */ 
    int iX,iY; 
    const int iXmax = 800; 
    const int iYmax = 800; 
    /* world (double) coordinate = parameter plane*/ 
    double Cx,Cy; 
    const double CxMin=-2.5; 
    const double CxMax=1.5; 
    const double CyMin=-2.0; 
    const double CyMax=2.0; 
    /* */ 
    double PixelWidth=(CxMax-CxMin)/iXmax; 
    double PixelHeight=(CyMax-CyMin)/iYmax; 
    /* color component (R or G or B) is coded from 0 to 255 */ 
    /* it is 24 bit color RGB file */ 
    const int MaxColorComponentValue=255; 
    FILE * fp; 
    char *filename="new1.ppm"; 
    char *comment="# ";/* comment should start with # */ 
    static unsigned char color[3]; 
    unsigned char red[iXmax][iYmax]; 
    unsigned char blue[iXmax][iYmax]; 
    unsigned char green[iXmax][iYmax]; 
    /* Z=Zx+Zy*i ; Z0 = 0 */ 
    double Zx, Zy; 
    double Zx2, Zy2; /* Zx2=Zx*Zx; Zy2=Zy*Zy */ 
    /* */ 
    int Iteration; 
    const int IterationMax=200; 
    /* bail-out value , radius of circle ; */ 
    const double EscapeRadius=2; 
    double ER2=EscapeRadius*EscapeRadius; 
    /*create new file,give it a name and open it in binary mode */ 
    fp= fopen(filename,"wb"); /* b - binary mode */ 
    /*write ASCII header to the file*/ 
    fprintf(fp,"P6\n %s\n %d\n %d\n %d\n",comment,iXmax,iYmax,MaxColorComponentValue); 
    /* compute and write image data bytes to the file*/ 
    #pragma acc parallel loop copyout(red,blue,green) 
    for(iY=0;iY<iYmax;iY++) 
    { 
     Cy=CyMin + iY*PixelHeight; 
     if (fabs(Cy)< PixelHeight/2) Cy=0.0; /* Main antenna */ 
     #pragma acc loop 
     for(iX=0;iX<iXmax;iX++) 
     { 
      Cx=CxMin + iX*PixelWidth; 
      /* initial value of orbit = critical point Z= 0 */ 
      Zx=0.0; 
      Zy=0.0; 
      Zx2=Zx*Zx; 
      Zy2=Zy*Zy; 
      /* */ 
      #pragma acc loop 
      for (Iteration=0;Iteration<IterationMax && ((Zx2+Zy2)<ER2);Iteration++) 
      { 
       Zy=2*Zx*Zy + Cy; 
       Zx=Zx2-Zy2 +Cx; 
       Zx2=Zx*Zx; 
       Zy2=Zy*Zy; 
      }; 
      /* compute pixel color (24 bit = 3 bytes) */ 
      if (Iteration==IterationMax) 
      { /* interior of Mandelbrot set = black */ 
       red[iX][iY]=0; 
       blue[iX][iY]=0; 
       green[iX][iY]=0; 
      } 
      else 
      { /* exterior of Mandelbrot set = white */ 
       red[iX][iY]=255; 
       blue[iX][iY]=255; 
       green[iX][iY]=255; 
      };   } 
    } 


    /*write color to the file*/ 
    for(iY=0;iY<iYmax;iY++) { 
     for(iX=0;iX<iXmax;iX++) { 
      color[0] = red[iX][iY]; 
      color[1] = blue[iX][iY]; 
      color[2] = green[iX][iY]; 
      fwrite(color,1,3,fp); 
     } 
    } 
    fclose(fp); 
    return 0; 
} 
相关问题