Please help me debug the following MPI program !!!
This program resolve a set of equations using the
Gauss method . At each step in the progress reduce the
matrix , the program also find the max value of any
valid rows in the same column .
The program can work well with the following pairs of
(amount of processes , amount of unknowns ) :
(3,10) ; (2,4) ;
but an error SIGSEGV occur with the pairs below :
(2,10) ; (3,8) ; (3,4) ;
I don't know why , Would you please help me ?
Thank you very much .
Goodbye .
__________________________________
Do you Yahoo!?
Yahoo! Calendar - Free online calendar with sync to Outlook(TM).
http://calendar.yahoo.com
#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
int mymin , mymax , maxrank,localsize;
#define INPUTTAG 100
#define ERRORTAG 111
#define REDUCETAG 222
int main(int argc ,char ** argv)
{
int size,rank ;
int n,count;
char m;
char s[30];
int numcol,steptag;
int i ,j ,k,error,nsize;
double *b,*myvec,*x ;
double *reducevec;
double tmp,tmp1,tmp2;
double start,end , time;
int nextrow;
FILE *f;
MPI_Status status ;
MPI_Init(&argc, &argv) ;
MPI_Comm_size(MPI_COMM_WORLD,&size);
MPI_Comm_rank(MPI_COMM_WORLD,&rank) ;
start = MPI_Wtime();
////////////////////start input /////////////////////////////////////////
if (rank==0) {
printf("\n enter matrix file : ");
gets(s);
f=fopen(s,"r");
fscanf(f,"%d\n",&n);
}
MPI_Bcast(&n,1,MPI_INT,0,MPI_COMM_WORLD);
///////////////////////////////////////////
numcol = n + 1 ;
if(n < size) {
nsize = 1 ;
maxrank = n;
}
else {
if(n%size == 0)
nsize = n/size ;
else{
if(n%(size-1)==0)
nsize = n/(size-1) -1 ;
else
nsize = n/(size-1);
}
maxrank = size ;
}
mymin = rank * nsize;
if(rank== maxrank - 1){
mymax = n-1 ;
}
else
mymax = (rank + 1)*nsize - 1 ;
localsize = mymax - mymin + 1;
myvec = (double*) malloc (sizeof(double)*(numcol)*(localsize));
x = (double*) malloc(sizeof(double)*n);
reducevec = (double *) malloc(sizeof(double)*(numcol));
///////////////////////////////////////////////////////////
count = 0 ;
if (rank == 0) {
b = (double *)malloc(sizeof(double)*(nsize)*(numcol));
for(k=0; k < maxrank; k++ ) {
for(i=0;i<nsize;i++){
for(j=0;j<numcol;j++){
if(count<n*numcol){
if(k==0)
fscanf(f,"%lf ",myvec+i*numcol+j);
else if(k<maxrank-1)
fscanf(f,"%lf ",b+i*numcol+j);
}
count++;
}
fscanf(f,"\n",m);
}
if (k > 0){
if(k==maxrank-1){
for(i=0;i < n-nsize*k;i++){
for(j=0;j<numcol;j++){
fscanf(f,"%lf ",b+i*numcol+j);
}
fscanf(f,"\n",m);
}
MPI_Send (b, (n-nsize*k)*numcol, MPI_DOUBLE, k ,INPUTTAG,MPI_COMM_WORLD);
}
else
MPI_Send (b, nsize*numcol, MPI_DOUBLE, k ,INPUTTAG,MPI_COMM_WORLD);
}
}
fclose(f);
}
else {
MPI_Recv(myvec,localsize*numcol,MPI_DOUBLE,MPI_ANY_SOURCE,INPUTTAG,MPI_COMM_WORLD,&status);
}
printMT((double*)myvec,numcol*localsize,rank);
///////////////end input ///////////////////////
error =1 ;
for(steptag=0;(steptag<n-1)&&(error!=0) ; steptag++) {
if (error!=0)
error = takeRowtoReduce((double*)myvec,(double*)reducevec,steptag,rank,numcol,nsize);
if(error==0){
printf("\n Cannot compute the result");
break;
}
if((mymin <= steptag)&&(steptag <= mymax)) {
int firstrow = steptag - mymin ;
for(j=steptag;j<numcol;j++)
*(myvec + firstrow*numcol + j) = *(reducevec+j-steptag) ;
for(nextrow = firstrow + 1;nextrow < nsize - firstrow ;nextrow++){
tmp = *(myvec + nextrow*numcol + steptag);
for(i=steptag;i<numcol;i++) {
tmp1 = *(myvec + nextrow*numcol + i);
tmp2 = *(reducevec +i - steptag);//
*(myvec + nextrow*numcol + i) = tmp1 - tmp2*tmp;
}
}
}
if(steptag < mymin) {
for(nextrow = 0;nextrow < nsize; nextrow++){
tmp = *(myvec+nextrow*numcol + steptag);
for(i=steptag;i<numcol;i++) {
tmp1 = *(myvec + nextrow*numcol + i);
tmp2 = *(reducevec + i - steptag);//
*(myvec + nextrow*numcol + i) = tmp1 - tmp2*tmp;
}
}
}
}
/////////// compute vector X //////////////
if(error != 0) {
for(steptag=n-1;steptag>=0;steptag--) {
computeResult((double*) x,(double*) myvec,steptag,rank,numcol,nsize,size);
}
}
end = MPI_Wtime();
if(rank==0 ){
if( error != 0) {
printMT((double*) x, n,rank);
time = end - start ;
printf("total time = %lf ",time);
output((double*) x,n);
printf("\nfinish\n");
}
}
MPI_Finalize() ;
return 0 ;
}
void output(double *mt,int n)
{
int z;
FILE *f1;
double t;
f1=fopen("output.txt","w");
for (z=0;z<n;z++)
fprintf(f1,"%lf ",*(mt+z));
fclose(f1);
}
void printMT(double *mt,int n,int rank)
{
int z;
printf("\nMatrix at P%d is :\n",rank);
for(z=0;z<n;z++)
printf(" %lf ",*(mt+z));
printf("\n");
}
int takeRowtoReduce(double *vec , double *reducevec,int steptag,int rank,int numcol,int nsize) {
struct {
double value;
int index;
} in,out;
MPI_Status status;
int i , offset , outrank , startrow ,firstrow;
int result;
double tmp;
offset = numcol - steptag;
if(steptag > mymax) {
in.value = 0;
in.index = 0 ;
}
else {// find the max value a[anyrow,steptag] at all rows
if( (mymin <= steptag)&&(steptag <= mymax))
firstrow = steptag - mymin;
else
firstrow = 0 ;
in.value = fabs(*(vec + firstrow*numcol + steptag));
in.index = firstrow;
for(i= firstrow + 1; i < localsize - firstrow ; i++){
tmp = fabs(*(vec + i*numcol + steptag)) ;
if(in.value < tmp ) {
in.value = tmp;
in.index = i ;
}
}
}
in.index = in.index + rank*1000;
MPI_Allreduce(&in,&out,1,MPI_DOUBLE_INT,MPI_MAXLOC,MPI_COMM_WORLD);
outrank = out.index / 1000 ;
startrow = out.index % 1000 ;
result = 1 ;
if (out.value == 0 ){ // max value is 0
result = 0 ;
}
if(result!=0){
if (outrank == rank) {// broadcast its reduce vector
tmp = *(vec + startrow*numcol + steptag) ;
for(i=0;i<offset;i++)
*(reducevec+i) = *(vec + (startrow*numcol + steptag + i))/tmp ;
if(steptag < mymin) {// exchange the row with another process
MPI_Recv(vec + startrow*numcol + steptag ,offset,MPI_DOUBLE,MPI_ANY_SOURCE,REDUCETAG,MPI_COMM_WORLD,&status);
}
else if(steptag <= mymax) { // exchange two rows locally in one process
if(steptag != (mymin + startrow)){
firstrow = (steptag - mymin);
if(firstrow!=startrow)
for (i=0;i < offset;i++){
tmp = *(vec + firstrow*numcol + steptag + i);
*(vec + firstrow*numcol + steptag + i) = *(vec + startrow*numcol + steptag +i);
*(vec + startrow*numcol + steptag + i) = tmp ;
}
}
}
}
else if ((mymin <= steptag)&&(steptag <= mymax)) { // send vec to another process
startrow = steptag - mymin ;
MPI_Send(vec + startrow*numcol + steptag ,offset,MPI_DOUBLE,outrank,REDUCETAG,MPI_COMM_WORLD);
}
}
MPI_Bcast(reducevec,offset,MPI_DOUBLE,outrank,MPI_COMM_WORLD);
return result ;
}
void computeResult(double* x,double* myvec,int steptag,int rank,int numcol,int nsize,int size ) {
int i,fromrank ;
double xtmp,a,b ;
int startrow;
if ((mymin <= steptag)&&(steptag <= mymax)) {
startrow = steptag - mymin;
b = *(myvec + startrow*numcol + steptag + 1);
if(steptag==numcol - 2){
a = *(myvec + startrow*numcol + steptag );
*(x + steptag) = b/a;
}
else
*(x + steptag) = b;
}
if((size-1)*nsize <= steptag)
fromrank = size-1;
else
fromrank = steptag/nsize ;
MPI_Bcast(x+steptag,1,MPI_DOUBLE,fromrank,MPI_COMM_WORLD);
if( (mymin <= steptag)&&(steptag <= mymax)){
xtmp = *(x + steptag);
for(i = startrow-1;i >= 0 ;i--) {
b = *(myvec + i*numcol + steptag + 1) ;
a = *(myvec + i*numcol + steptag ) ;
*(myvec + i*numcol + steptag) = b - xtmp*a ;
}
}
else if(steptag > mymax ) {
xtmp = *(x + steptag);
startrow = 0;
for (startrow = 0 ; startrow < nsize;startrow++) {
b = *(myvec + startrow*numcol + steptag + 1) ;
a = *(myvec + startrow*numcol + steptag ) ;
*(myvec + startrow*numcol + steptag) = b - xtmp*a ;
}
}
}
4
1 0.42 0.54 0.66 0.3
0.66 0.44 0.22 1 0.9
0.42 1.0 0.32 0.44 0.5
0.54 0.32 1 0.22 0.7
10
-2.024530 1.135208 0.846189 -0.271381 1.771051 1.157960 0.090649 3.151160 1.408493 0.773691 -5.302483
0.857239 -1.118077 0.490264 -1.221701 6.031911 -0.630010 0.939003 3.051934 0.579917 0.208855 1.337996
2.092713 7.600295 1.189046 -1.322373 3.221575 2.735504 0.207433 0.003812 0.631443 -0.916171 0.615799
-10.010813 -0.486804 92.628807 0.980990 2.692443 -0.475376 -2.350698 -0.306476 0.667559 -0.392978 0.316192
0.206454 0.925361 -0.402298 6.287778 0.198187 0.405630 -0.898688 -3.095903 1.716450 -0.927849 0.264332
0.557622 0.094228 1.415498 140.539815 -0.942889 0.917398 0.398055 2.702932 0.775277 0.591983 -0.326074
-0.760311 0.921083 -15.718971 -7.931153 1.764149 0.074621 0.501187 0.699782 0.473534 0.417620 2.545153
-2.978310 1.417167 0.480011 1.249715 5.094546 0.868270 -5.405024 0.590570 1.744573 0.495044 0.848869
0.282653 16.287071 2.821385 -2.812988 0.587737 2.280645 1.111854 1.188632 0.066297 0.154230 2.496306
0.009217 0.128841 -3.382640 0.627323 1.745721 -1.783417 0.757032 1.689040 -3.754201 0.580597 -0.260530
|