OpenACC must have routine information error

本小妞迷上赌 提交于 2019-12-25 09:22:08

问题


I am trying to parallelize a simple mandelbrot c program, yet I get this error that has to do with not including acc routine information. Also, I am not sure whether I should be copying data in and out of the parallel section. PS I am relatively new to parallel programming, so any advice with learning it would be appreciated.

(Warning when compiled)

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

Here is my code:

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

回答1:


Since you can't access a file from the GPU, you'll want to capture the results to arrays, copy them back to the host, and then output the results to a file.

Also, the "present" clause indicates that you've already copied the data over to the device and the program will abort if it's not there. Given the usage, I think you meant to use "private", which indicates that the variable should be private to the execution level. However scalars are private by default in OpenACC, so there's no need to manually privatize these variables. If you do manually privatize a variable, be sure to put it at the correct loop level. For example, if you privatize "Zx" on the outer loop, it will only private to that loop level. It would be shared by all the vectors of the inner loop! Again, here, it's best to just let the compiler handle privatizing the scalars, but just be mindful of where you privatize things in the few cases where you have to manually privatize variables.

Here's a corrected version of your code.

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



回答2:


When using OpenACC, the parallel regions are offloaded to a device, like a GPU. GPU devices normally don't have access to the entire system or the IO, and have a reduced subset of the standard library implemented. In your case, the fwrite function call cannot be offloaded to a device, since you cannot access the disk from the accelerator. You could do that in OpenMP, where parallel regions are executed on CPU or MIC threads, which typically have access to the entire system library. The acc routine directive that PGC is suggesting would allow you to annotate any function to create a device version of it.



来源:https://stackoverflow.com/questions/44274167/openacc-must-have-routine-information-error

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!