0

単純な mandelbrot c プログラムを並列化しようとしていますが、acc ルーチン情報が含まれていないことに関係するこのエラーが発生します。また、並列セクションの内外でデータをコピーする必要があるかどうかもわかりません。PS私は並列プログラミングに比較的慣れていないので、学習に関するアドバイスをいただければ幸いです。

(コンパイル時の警告)

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;
}
4

2 に答える 2

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;
}
于 2017-05-31T17:14:04.650 に答える