MPI_Gather分段故障 [英] MPI_Gather segmentation fault

查看:289
本文介绍了MPI_Gather分段故障的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这种并行高斯消元code。发生在调用任何 MPI_Gather 函数调用分段错误。我知道,如果内存不是为任何缓冲区正确分配这样的误差可能上升。但我看不到任何错误的内存管理code。

有人能帮助?

感谢。

注:
该计划从名为 input.txt的

的相同目录 .TXT 读取文件

code:

 的#include<&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&math.h中GT;
#包括mpi.h/ *无效print2dAddresses(双** array2d,诠释行,诠释COLS)
{
    INT I;    对于(i = 0; I<行;我++)
    {
        诠释J;        为(J = 0; J< COLS; J ++)
        {
            的printf(%D,及(array2d [I] [J]));
        }        的printf(\\ n);
    }    的printf(------------------------------------);
} * /双** newMatrix(INT行,诠释COLS)
{
    双*数据=(双*)malloc的(行* COLS *的sizeof(双));
    双**阵列=(双**)的malloc(行*的sizeof(双*));
    INT I;    对于(i = 0; I<行;我++)
        数组[我] =及(数据[COLS * I]);    返回数组;
}无效freeMatrix(双**垫)
{
    免费(垫[0]);    免费(垫);
}双** new2dArray(INT NROWS,诠释NCOLS)
{
    INT I;
    双** array2d;    array2d =(双**)的malloc(NROWS * sizeof的(双*));    对于(i = 0; I< NROWS;我++)
    {
        array2d [I] =(双*)malloc的(NCOLS *的sizeof(双));
    }    返回array2d;
}双* new1dArray(INT大小)
{
    回报(双*)malloc的(大小*的sizeof(双));
}无效free2dArray(双**​​ array2d,INT NROWS)
{
    INT I;    对于(i = 0; I< NROWS;我++)
    {
        免费(array2d [I]);
    }    免费(array2d);
}无效print2dArray(双**​​ array2d,诠释NROWS,诠释NCOLS)
{
    INT I,J;    对于(i = 0; I< NROWS;我++)
    {
        为(J = 0; J< NCOLS; J ++)
        {
            的printf(%LF,array2d [I] [J]);
        }        的printf(\\ n);
    }    的printf(---------------------- \\ n);
}无效print1dArray(双*数组,INT大小)
{
    INT I;    对于(i = 0; I<大小;我++)
    {
        的printf(%LF \\ n,数组[我]);
    }    的printf(---------------------- \\ n);
}无效read2dArray(FILE * FP,双** array2d,诠释NROWS,诠释NCOLS)
{
    INT I,J;    对于(i = 0; I< NROWS;我++)
    {
        为(J = 0; J< NCOLS; J ++)
        {
            的fscanf(FP,%LF,及(array2d [I] [J]));
        }
    }
}无效read1dArray(FILE * FP,双阵列*,诠释大小)
{
    INT I;    对于(i = 0; I<大小;我++)
    {
        的fscanf(FP,%LF,及(数组[I]));
    }
}无效readSymbols(字符*符号,诠释大小,FILE * FP)
{
    INT I;    对于(i = 0; I<大小;我++)
    {
        焦C ='\\ n';        而(C =='\\ n'| C ==''| C =='\\ T'| C =='\\ r')
            的fscanf(FP,%C,和C);        符号[I] = C;
    }
}无效printSolution(字符*符号,双* X,INT大小)
{
    INT I;    对于(i = 0; I<大小;我++)
    {
        的printf(%C =%LF \\ N,符号[I]中,x [I]);
    }
}双* copy_1d_array(双原*,诠释大小)
{
    双* copy_version;
    INT I;    copy_version =(双*)malloc的(大小*的sizeof(双));    对于(i = 0; I<大小;我++)
    {
        copy_version [I] = [i]原;
    }    返回copy_version;
}INT主(INT ARGC,字符** argv的)
{
    INT P,等级,I,J,K,L,MSIZE,rowsPerProcess,其余startingRow,DEST,rowCounter,remainingRows,neededProcesses;
    双** A * B,* X ** smallA,* currentRow,* smallB,currentB,** receivedA,* receivedB;
    字符*符号;
    MPI_Status状态;    MPI_INIT(安培; ARGC,&安培; argv的);
    MPI_Comm_size(MPI_COMM_WORLD,&放大器; P);
    MPI_Comm_rank(MPI_COMM_WORLD,&安培;等级);    如果(排名== 0)
    {
        FILE * FP;        FP = FOPEN(input.txt的,R);        的fscanf(FP,%D,&安培; MSIZE);        A = newMatrix(MSIZE,MSIZE);
        B = new1dArray(MSIZE);
        X = new1dArray(MSIZE);        符号=(字符*)malloc的(MSIZE *的sizeof(字符));        read2dArray(FP,A,MSIZE,MSIZE);
        read1dArray(FP,B,MSIZE);        readSymbols(符号,MSIZE,FP);
        FCLOSE(FP);        / * print2dArray(A,MSIZE,MSIZE);
        print1dArray(B,MSIZE); * /    }    MPI_Bcast(安培; MSIZE,1,MPI_INT,0,MPI_COMM_WORLD);
    对于(I = 0; I&≤(MSIZE - 1);我+ +)
    {
        INT maxIndex;
        双maxCoef,TMP,R;
        / *找出最大的行* /        如果(排名== 0)
        {
            maxIndex = I;
            maxCoef =晶圆厂(A [I] [I]);
            为(J = I + 1; J< MSIZE; J ++)
            {
                如果(晶圆厂(A [J] [I])GT; maxCoef)
                {
                    maxCoef = A [j]的[I]
                    maxIndex = j的;
                }
            }            / *交换当前行的最大行* /
            为(J = 0; J< MSIZE; J ++)
            {
                TMP = A [I] [J]。
                A [I] [J] = A [maxIndex] [J]。
                A [maxIndex] [J] = tmp目录;
            }            TMP = B [I];
            B〔Ⅰ〕= B [maxIndex];
            B〔maxIndex] = tmp目录;
            / * *消除/
            / *为(J = I + 1; J< MSIZE; J ++)
            {
                双R = A [j]的[I] / A [I] [I]                从j行减去R * i行
                对于(K = 1; K< MSIZE; k ++)
                {
                    A [J] [K] - = R * A [I] [K];
                }                B〔J] - = R * B [I]
            } * /            / *平行取消* /
            startingRow = I + 1;
            neededProcesses = P;            remainingRows = MSIZE - startingRow;            如果(remainingRows< neededProcesses)
            {
                neededProcesses = remainingRows;
            }            rowsPerProcess = remainingRows / neededProcesses;
            余数= remainingRows%neededProcesses;
        }        MPI_Bcast(安培; startingRow,1,MPI_INT,0,MPI_COMM_WORLD);
        MPI_Bcast(安培; rowsPerProcess,1,MPI_INT,0,MPI_COMM_WORLD);        如果(排名== 0)
        {
            currentRow = copy_1d_array(A [startingRow-1],MSIZE);
            currentB = B [startingRow-1];
        }
        其他
        {
            currentRow = new1dArray(MSIZE);
        }        MPI_Bcast(currentRow,MSIZE,MPI_DOUBLE,0,MPI_COMM_WORLD);
        MPI_Bcast(安培; currentB,1,MPI_DOUBLE,0,MPI_COMM_WORLD);        如果(排名== 0)
        {
            receivedA = newMatrix(remainingRows,MSIZE);
            receivedB = new1dArray(remainingRows);
        }
        smallA = newMatrix(rowsPerProcess,MSIZE);
        smallB = new1dArray(rowsPerProcess);        MPI_Scatter(及(A [startingRow] [0]),rowsPerProcess * MSIZE,MPI_DOUBLE,及(smallA [0] [0]),rowsPerProcess * MSIZE,MPI_DOUBLE,0,MPI_COMM_WORLD);        MPI_Scatter(及(B〔startingRow]),rowsPerProcess,MPI_DOUBLE,及(smallB [0]),rowsPerProcess,MPI_DOUBLE,0,MPI_COMM_WORLD);        为(J = 0; J< rowsPerProcess; J ++)
        {
            R = smallA [J] [startingRow-1] / currentRow [startingRow-1];            对于(K = 0; K< MSIZE; k ++)
            {
                smallA [J] [K] - = R * currentRow [K]
            }            smallB [J] - = R * currentB;
        }        MPI_Gather(及(smallA [0] [0]),rowsPerProcess * MSIZE,MPI_DOUBLE,及(receivedA [0] [0]),rowsPerProcess * MSIZE,MPI_DOUBLE,0,MPI_COMM_WORLD);        MPI_Gather(及(smallB [0]),rowsPerProcess,MPI_DOUBLE,及(receivedB [0]),rowsPerProcess,MPI_DOUBLE,0,MPI_COMM_WORLD);        freeMatrix(smallA);
        免费(smallB);        如果(排名== 0)
        {
            为(J = 0; J< remainingRows; J ++)
            {
                对于(K = 0; K< MSIZE; k ++)
                {
                    A [J + startingRow] [K] = receivedA [J] [K];
                }                B〔J + startingRow] = receivedB [J]。
            }
            免费(currentRow);
            freeMatrix(receivedA);
            免费(receivedB);
        }        如果(排名== 0)
        {
            如果(余数大于0)
            {
                为(J =(MSIZE - 余数); J< MSIZE; J ++)
                {
                    R = A [j]的[I] / A [I] [I]                    对于(K = 0; K< MSIZE; k ++)
                    {
                        A [J] [K] - = R * A [I] [K];
                    }                    B〔J] - = R * B [I]
                }
            }
        }    }    如果(排名== 0)
    {
        / *回代* /        为(ⅰ= MSIZE - 1; I> = 0;我 - )
        {
            X [I] = B [I];            为(J = MSIZE - 1; J>我; j--)
            {
                X [i] - = A [i] [j]的* X [J]。
            }            X [I] / = A [I] [I]
        }        的printf(解= \\ n);
        // print1dArray(X,MSIZE);        printSolution(符号中,x,MSIZE);        freeMatrix(A);
        免费(B);
        免费(X);
        免费(符号);
    }
    MPI_Finalize();
    返回0;
}

输入文件:

  3
1 1 1
1 1 3
2 1 4
4
9
12
X
ÿ
ž


解决方案

这可能是这样的:及(receivedA [0] [0])上的进程,其中评级!= 0 。你索引尚未分配的数组。您可能需要创建另一个指针,像这样的:

 如果(排名== 0)
    {
        receivedA = newMatrix(remainingRows,MSIZE);
        recievedAHead =及(receivedA [0] [0]);
        receivedB = new1dArray(remainingRows);
    }
    其他{
        recievedAHead = NULL;
    }

和在MPI_Gather调用中使用 recievedAHead

I have this parallel Gaussian elimination code. A segmentation error happens upon calling either MPI_Gather function calls. I know such error may rise if memory is not allocated properly for either buffers. But I cannot see any wrong with the memory management code.

Can someone help?

Thanks.

Notes: The program reads from a .txt file in the same directory called input.txt.

Code:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "mpi.h"

/*void print2dAddresses(double** array2d, int rows, int cols)
{
    int i;

    for(i = 0; i < rows; i++)
    {
        int j;

        for(j = 0; j < cols; j++)
        {
            printf("%d ", &(array2d[i][j]));
        }

        printf("\n");
    }

    printf("------------------------------------");
}*/

double** newMatrix(int rows, int cols)
{
    double *data = (double*) malloc(rows * cols * sizeof(double));
    double **array= (double **)malloc(rows * sizeof(double*));
    int i;

    for (i=0; i<rows; i++)
        array[i] = &(data[cols*i]);

    return array;
}

void freeMatrix(double** mat)
{
    free(mat[0]);

    free(mat);
}

double** new2dArray(int nrows, int ncols)
{
    int i;
    double** array2d;

    array2d = (double**) malloc(nrows * sizeof(double*));

    for(i = 0; i < nrows; i++)
    {
        array2d[i] = (double*) malloc(ncols * sizeof(double));
    }

    return array2d;
}

double* new1dArray(int size)
{
    return (double*) malloc(size * sizeof(double));
}

void free2dArray(double** array2d, int nrows)
{
    int i;

    for(i = 0; i < nrows; i++)
    {
        free(array2d[i]);
    }

    free(array2d);
}

void print2dArray(double** array2d, int nrows, int ncols)
{
    int i, j;

    for(i = 0; i < nrows; i++)
    {
        for(j = 0; j < ncols; j++)
        {
            printf("%lf ", array2d[i][j]);
        }

        printf("\n");
    }

    printf("----------------------\n");
}

void print1dArray(double* array, int size)
{
    int i;

    for(i = 0; i < size; i++)
    {
        printf("%lf\n", array[i]);
    }

    printf("----------------------\n");
}

void read2dArray(FILE* fp, double** array2d, int nrows, int ncols)
{
    int i, j;

    for(i = 0; i < nrows; i++)
    {
        for(j = 0; j < ncols; j++)
        {
            fscanf(fp, "%lf", &(array2d[i][j]));
        }
    }
}

void read1dArray(FILE* fp, double* array, int size)
{
    int i;

    for(i = 0; i < size; i++)
    {
        fscanf(fp, "%lf", &(array[i]));
    }
}

void readSymbols(char* symbols, int size, FILE* fp)
{
    int i;

    for(i = 0; i < size; i++)
    {
        char c = '\n';

        while(c == '\n' | c == ' ' | c == '\t' | c == '\r')
            fscanf(fp, "%c", &c);

        symbols[i] = c;
    }
}

void printSolution(char* symbols, double* x, int size)
{
    int i;

    for(i = 0; i < size; i++)
    {
        printf("%c = %lf\n", symbols[i], x[i]);
    }
}

double* copy_1d_array(double* original, int size)
{
    double* copy_version;
    int i;

    copy_version = (double*) malloc(size * sizeof(double));

    for(i = 0; i < size; i++)
    {
        copy_version[i] = original[i];
    }

    return copy_version;
}

int main(int argc, char** argv)
{
    int p, rank, i, j, k, l, msize, rowsPerProcess, remainder, startingRow, dest, rowCounter, remainingRows, neededProcesses;
    double **A, *b, *x, **smallA, *currentRow, *smallB, currentB, **receivedA, *receivedB;
    char *symbols;
    MPI_Status status;

    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &p);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    if(rank == 0)
    {
        FILE* fp;

        fp = fopen("input.txt", "r");

        fscanf(fp, "%d", &msize);

        A = newMatrix(msize, msize);
        b = new1dArray(msize);
        x = new1dArray(msize);

        symbols = (char*) malloc(msize * sizeof(char));

        read2dArray(fp, A, msize, msize);
        read1dArray(fp, b, msize);

        readSymbols(symbols, msize, fp);
        fclose(fp);

        /*print2dArray(A, msize, msize);
        print1dArray(b, msize);*/

    }

    MPI_Bcast(&msize, 1, MPI_INT, 0, MPI_COMM_WORLD);


    for(i = 0; i < (msize - 1); i++)
    {
        int maxIndex;
        double maxCoef, tmp, r;
        /*finding max row*/

        if(rank == 0)
        {
            maxIndex = i;
            maxCoef = fabs(A[i][i]);
            for(j = i + 1; j < msize; j++)
            {
                if(fabs(A[j][i]) > maxCoef)
                {
                    maxCoef = A[j][i];
                    maxIndex = j;
                }
            }

            /*swapping the current row with the max row*/
            for(j = 0; j < msize; j++)
            {
                tmp = A[i][j];
                A[i][j] = A[maxIndex][j];
                A[maxIndex][j] = tmp;
            }

            tmp = b[i];
            b[i] = b[maxIndex];
            b[maxIndex] = tmp;


            /*elimination*/
            /*for(j = i + 1; j < msize; j++)
            {
                double r = A[j][i] / A[i][i];

                subtracting r * row i from row j
                for(k = i; k < msize; k++)
                {
                    A[j][k] -= r * A[i][k];
                }

                b[j] -= r * b[i];
            }*/

            /*parallel elimination*/
            startingRow = i + 1;
            neededProcesses = p;

            remainingRows = msize - startingRow;

            if(remainingRows < neededProcesses)
            {
                neededProcesses = remainingRows;
            }

            rowsPerProcess = remainingRows / neededProcesses;
            remainder = remainingRows % neededProcesses;
        }

        MPI_Bcast(&startingRow, 1, MPI_INT, 0, MPI_COMM_WORLD);
        MPI_Bcast(&rowsPerProcess, 1, MPI_INT, 0, MPI_COMM_WORLD);

        if(rank == 0)
        {
            currentRow = copy_1d_array(A[startingRow-1], msize);
            currentB = b[startingRow-1];
        }
        else
        {
            currentRow = new1dArray(msize);
        }

        MPI_Bcast(currentRow, msize, MPI_DOUBLE, 0, MPI_COMM_WORLD);
        MPI_Bcast(&currentB, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);

        if(rank == 0)
        {
            receivedA = newMatrix(remainingRows, msize);
            receivedB = new1dArray(remainingRows);
        }
        smallA = newMatrix(rowsPerProcess, msize);
        smallB = new1dArray(rowsPerProcess);

        MPI_Scatter(&(A[startingRow][0]), rowsPerProcess*msize, MPI_DOUBLE, &(smallA[0][0]), rowsPerProcess*msize, MPI_DOUBLE, 0, MPI_COMM_WORLD);

        MPI_Scatter(&(b[startingRow]), rowsPerProcess, MPI_DOUBLE, &(smallB[0]), rowsPerProcess, MPI_DOUBLE, 0, MPI_COMM_WORLD);

        for(j = 0; j < rowsPerProcess; j++)
        {
            r = smallA[j][startingRow-1] / currentRow[startingRow-1];

            for(k = 0; k < msize; k++)
            {
                smallA[j][k] -= r * currentRow[k];
            }

            smallB[j] -= r * currentB;
        }

        MPI_Gather(&(smallA[0][0]), rowsPerProcess*msize, MPI_DOUBLE, &(receivedA[0][0]), rowsPerProcess*msize, MPI_DOUBLE, 0, MPI_COMM_WORLD);

        MPI_Gather(&(smallB[0]), rowsPerProcess, MPI_DOUBLE, &(receivedB[0]), rowsPerProcess, MPI_DOUBLE, 0, MPI_COMM_WORLD);

        freeMatrix(smallA);
        free(smallB);

        if(rank == 0)
        {
            for(j = 0; j < remainingRows; j++)
            {
                for(k = 0; k < msize; k++)
                {
                    A[j+startingRow][k] = receivedA[j][k];
                }

                b[j+startingRow] = receivedB[j];
            }
            free(currentRow);
            freeMatrix(receivedA);
            free(receivedB);
        }

        if(rank == 0)
        {
            if(remainder > 0)
            {
                for(j = (msize - remainder); j < msize; j++)
                {
                    r = A[j][i] / A[i][i];

                    for(k = 0; k < msize; k++)
                    {
                        A[j][k] -= r * A[i][k];
                    }

                    b[j] -= r * b[i];
                }
            }
        }

    }

    if(rank == 0)
    {
        /*backward substitution*/

        for(i = msize - 1; i >= 0; i--)
        {
            x[i] = b[i];

            for(j = msize - 1; j > i; j--)
            {
                x[i] -= A[i][j] * x[j];
            }

            x[i] /= A[i][i];
        }

        printf("solution = \n");
        //print1dArray(x, msize);

        printSolution(symbols, x, msize);

        freeMatrix(A);
        free(b);
        free(x);
        free(symbols);
    }


    MPI_Finalize();
    return 0;
}

Input File:

3
1 1 1
1 1 3
2 1 4
4
9
12
x
y
z

解决方案

It might be this: &(receivedA[0][0]) on processes where rank != 0. You're indexing an array that hasn't been allocated. You might have to create another pointer, like this:

    if(rank == 0)
    {
        receivedA = newMatrix(remainingRows, msize);
        recievedAHead = &(receivedA[0][0]);
        receivedB = new1dArray(remainingRows);
    }
    else {
        recievedAHead = NULL;
    }

and use recievedAHead in the MPI_Gather call.

这篇关于MPI_Gather分段故障的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆