LAM/MPI logo

LAM/MPI General User's Mailing List Archives

  |   Home   |   Download   |   Documentation   |   FAQ   |   all just in this list

From: Vo Kim Son (vks81_at_[hidden])
Date: 2003-06-02 08:58:46


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