MPI_Gather分段故障 [英] MPI_Gather segmentation fault
问题描述
我有这种并行高斯消元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(¤tB, 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屋!