2017-05-31 43 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; 
} 
相關問題