简体   繁体   中英

C X11 Segmentation Fault in MandelBrot Set Application

I can't for the life of me find this seg fault. It keeps occurring on the slave processes as soon as I launch. I have already developed a standard application that works perfectly but have come across this issue when I tried to implement a zoom functionality.

Any help is greatly appreciated.

Part of my code:

int rank, processes, i, j, x, y;

MPI_Status status;
MPI_Init(&argc, &argv); 
MPI_Comm_size(MPI_COMM_WORLD, &processes); 
MPI_Comm_rank(MPI_COMM_WORLD, &rank);

Window win; // initialization for a window
GC gc; // graphics context
Display *display = NULL;
unsigned int width = X_RESN, height = Y_RESN; /* window size */
clock_t start, end, elapsed;

int changed = 1;

int* pixelChunk;
int** pixelSet;

if(rank==0)
{
    display = x11setup(&win, &gc, width, height);
    pixelSet = create2DArray(X_RESN, Y_RESN);

    int i;

    double pixelFactors[4];
    pixelFactors[0] = imin;
    pixelFactors[1] = imax;
    pixelFactors[2] = rmin;
    pixelFactors[3] = rmax;

    for(i = 1; i < processes - 1; i++)
    {
        MPI_Send(&pixelFactors, sizeof(double) * 4, MPI_DOUBLE, i, PIXEL_FACTORS, MPI_COMM_WORLD);
        assignTask(i);
    }
}
else
{
    pixelChunk = malloc(sizeof(int) * (Y_RESN+1));
}

// main loop
int running = 1; // loop variable
start = clock();
while(running) 
{
    if(rank==0) 
    {
        if(XPending(display)) 
        {
            XEvent ev;
            XNextEvent(display, &ev);
            switch(ev.type) 
            {               
                case ButtonPress:
                {
                    int xPos = ev.xbutton.x;
                    int yPos = ev.xbutton.y;

                    int xCenter = ((xPos / X_RESN) * (rmax - rmin)) + rmin;
                    int yCenter = ((yPos / Y_RESN) * (imax - imin)) + imin;

                    double xmin = xCenter - 2;
                    double xmax = xCenter + 2;
                    double ymin = yCenter - 2;
                    double ymax = yCenter + 2;

                    double pixelFactors[4];

                    if(ev.xbutton.button == 1) //Left click, zoom in
                    {
                        xmin += 0.1;
                        xmax -= 0.1;
                        ymin += 0.1;
                        ymax -= 0.1;
                    }
                    else if(ev.xbutton.button == 2) //Right click, zoom out
                    {
                        xmin -= 0.1;
                        xmax += 0.1;
                        ymin -= 0.1;
                        ymax += 0.1;
                    }

                    pixelFactors[0] = ymin;
                    pixelFactors[1] = ymax;
                    pixelFactors[2] = xmin;
                    pixelFactors[3] = xmax;

                    tasks = X_RESN-1;
                    changed = 1;

                    for(i = 1; i < processes - 1; i++)
                    {
                        MPI_Send(&pixelFactors, sizeof(double) * 4, MPI_DOUBLE, i, PIXEL_FACTORS, MPI_COMM_WORLD);
                        assignTask(i);
                    }
                }
            }
        }
    }
    else
    {
        //Calculate MandelBrot Set
        int taskNo;
        double pixelFactors[4];

        MPI_Recv(&pixelFactors, sizeof(double) * 4, MPI_DOUBLE, 0, PIXEL_FACTORS, MPI_COMM_WORLD, &status);
        MPI_Recv(&taskNo, sizeof(int), MPI_INT, 0, TASK_ASSIGNMENT, MPI_COMM_WORLD, &status);

        imin = pixelFactors[0];
        imax = pixelFactors[1];
        rmin = pixelFactors[2];
        rmax = pixelFactors[3];

        int x, y;
        complex c;

        double xPixelFactor = (rmax-rmin)/X_RESN;
        double yPixelFactor = (imax-imin)/Y_RESN;

        x = taskNo;

        if(changed == 1)
        {   
            for (y = 0; y < Y_RESN; y++)
            {
                complex imaginary;
                imaginary.real = 0;
                imaginary.imag = 1;
                c.real = rmin + (x * xPixelFactor);
                c.imag = (imin + (y * yPixelFactor)) * imaginary.imag;

                pixelChunk[y] = calculatePixel(c);
            }

            pixelChunk[Y_RESN] = taskNo;

            //SEND
            MPI_Send(&pixelChunk[0], Y_RESN+1, MPI_INT, 0, TASK_RESULT, MPI_COMM_WORLD);
        }

    }

    //RECEIVE
    if(rank == 0)
    {
        while(tasks > -1 || working > 0)
        {
            int* chunk = malloc(sizeof(int) * (Y_RESN+1));
            MPI_Recv(&chunk[0], Y_RESN+1, MPI_INT, MPI_ANY_SOURCE, TASK_RESULT, MPI_COMM_WORLD, &status);

            int process = status.MPI_SOURCE;
            int taskID = chunk[Y_RESN];
            working--;

            int k;

            for(k = 0; k < Y_RESN; k++)
            {
                pixelSet[taskID][k] = chunk[k];
            }   

            if(tasks > -1)
            {
                double pixelFactors[4];
                pixelFactors[0] = imin;
                pixelFactors[1] = imax;
                pixelFactors[2] = rmin;
                pixelFactors[3] = rmax;

                MPI_Send(&pixelFactors, sizeof(double) * 4, MPI_DOUBLE, process, PIXEL_FACTORS, MPI_COMM_WORLD);

                assignTask(process);
            }
        }
    }

Found it. Was to do with the way I was sending/receiving the array of doubles.

Changed it to MPI_Send(&pixelFactors[0], 4, MPI_DOUBLE, i, PIXEL_FACTORS, MPI_COMM_WORLD); and I stopped getting the segmentation fault.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM