Реализация метода Гаусса. Решения СЛАУ в системе MPI, страница 2

if(!rank){

inp=fopen("./input.txt","r");

fscanf(inp,"%i",&dim);

for(i=1;i<=size;i++)comp[i-1]=dim/size;

for(i=1;i<=dim%size;i++)comp[i-1]++;

/*Now we'll send dim and comp array to next processor*/

if(size>1){

MPI_Send(&dim,1,MPI_INT,1,tag,ring);


MPI_Send(comp,size,MPI_INT,1,tag,ring);

};

};

if(rank){

MPI_Recv(&dim,1,MPI_INT,sour,tag,ring,&st);

MPI_Recv(comp,size,MPI_INT,sour,tag,ring,&st);

if(rank<(size-1)){

MPI_Send(&dim,1,MPI_INT,dest,tag,ring);

MPI_Send(comp,size,MPI_INT,dest,tag,ring);

};

};

for(i=0;i<=size-1,comp[i]>0;i++);

size=i<size?i:size;

if(!comp[rank])exit(0);

A=(float *)malloc(sizeof(float)*(dim+1)*comp[rank]);

pr=dim;

for(i=0;i<rank;i++)pr-=comp[i];

res=(float *)malloc(sizeof(float)*pr);

if(!A||!res){printf("Can't allocate memory...\n");return 1;};

B=(float *)malloc((dim+1)*sizeof(float));

if(!rank){

for(i=1;i<=comp[rank];i++)for(j=1;j<=dim+1;j++)fscanf(inp,"%f",A+(i-1)*(dim+1)+j-1);

for(compID=1;compID<=size-1;compID++){

for(i=1;i<=comp[compID];i++){

for(j=1;j<=dim+1;j++)fscanf(inp,"%f",B+j-1);

MPI_Send(B,dim+1,MPI_FLOAT,compID,tag,ring);

};

};

if(fclose(inp))printf("Error closing file...\n");

time(tp1);

};

if(rank){

/*Now we'll recieve and send dim and comp array to next processor*/

for(i=1;i<=comp[rank];i++){

MPI_Recv(A+(i-1)*(dim+1),dim+1,MPI_FLOAT,0,tag,ring,&st);

};

};

/*Now all processors have their matrixes...*/

pr=0;

for(compID=0;compID<rank;compID++){

for(k=1;k<=comp[compID];k++){

MPI_Recv(B,dim-pr-k+2,MPI_FLOAT,compID,recvtag,ring,&st);

for(j=1;j<=comp[rank];j++)if(A[(j-1)*(dim+1)+pr+k-1]){

c=-A[(j-1)*(dim+1)+pr+k-1]/B[0];

for(j1=pr+k;j1<=dim+1;j1++)A[(j-1)*(dim+1)+j1-1]+=c*B[j1-pr-k];

};

};

pr+=comp[compID];

};

/*For each row...*/

for(i=1;i<=comp[rank];i++){

/*First , we'll send current string to other processors    and then we will calculate it.*/

for(k=rank+1;k<size;k++)MPI_Send(A+(dim+1)*(i-1)+i+pr-1,dim-i-pr+2,MPI_FLOAT,k,sendtag,ring);

for(j=i+1;j<=comp[rank];j++)if(A[(j-1)*(dim+1)+i+pr-1]){

c=-A[(j-1)*(dim+1)+i+pr-1]/A[(i-1)*(dim+1)+i+pr-1];

for(j1=i+pr;j1<=dim+1;j1++)A[(j-1)*(dim+1)+j1-1]+=c*A[(i-1)*(dim+1)+j1-1];

};

};

/*Result calculating*/

pr=0;

for(i=rank+1;i<=size-1;i++)pr+=comp[i];

if(rank<size-1)MPI_Recv(res+comp[rank],pr,MPI_FLOAT,rank+1,tag,ring,&st);

for(i=comp[rank];i>=1;i--){

res[i-1]=A[(i)*(dim+1)-1];

for(k=dim-pr+i-comp[rank]+1,k1=1;k<=dim;k1++,k++){

res[i-1]-=res[i-1+k1]*A[(i-1)*(dim+1)+k-1];

};

if(!A[(i-1)*(dim+1)+dim-pr+i-comp[rank]-1]){

printf("\nMatrix is null determined...\n");

exit(0);

};

res[i-1]/=A[(i-1)*(dim+1)+dim-pr+i-comp[rank]-1];

};

if(rank)MPI_Send(res,pr+comp[rank],MPI_FLOAT,rank-1,tag,ring);

if(!rank){

time(tp2);

time_=difftime(*tp2,*tp1);

printf("time=%f",time_);

if(!(outp=fopen("./output.txt","w"))){

printf("Couldn't open output file...\n");

exit(1);

};

fprintf(outp,"Result:\n");

for(i=1;i<=dim;i++)fprintf(outp,"%f ",res[i-1]);

fprintf(outp,"\nExecution time: %f\n",time_);

};

if(A)free(A);

if(comp)free(comp);

if(res)free(res);

if(B)free(B);

MPI_Finalize();

return 0;

};

II.  Программа 2

#include <mpi.h>

#include <time.h>

#include <stdio.h>

int main(int argc, char* argv[]){

int rank,i,j,j1,k,k1,pr,compID,size,sendtag=11,recvtag=11,nd=1,tag=11;

int     dims[1],per[1],reord=0,sour,dest,dim,*comp,counter,localnum;

float *A,*B, *res,c;

double time_;

time_t *tp1,*tp2;

MPI_Status st;

MPI_Comm ring;

MPI_Request req1,req2;

FILE *inp, *outp;

tp1=(time_t *)malloc(sizeof(time_t));

tp2=(time_t *)malloc(sizeof(time_t));

MPI_Init(&argc,&argv);

sendtag=recvtag=11;

MPI_Comm_size(MPI_COMM_WORLD,&size);

dims[0]=size;

per[0]=1;

MPI_Cart_create(MPI_COMM_WORLD,nd,dims,per,reord,&ring);

MPI_Comm_rank(ring, &rank);

MPI_Cart_shift(ring,0,1,&sour,&dest);

comp=(int *)malloc(size*sizeof(int));

if(!rank){

inp=fopen("./input.txt","r");

fscanf(inp,"%i",&dim);

for(i=0;i<size;i++)comp[i]=0;

for(i=1;i<=dim;i++)comp[(i-1)%size]++;

/*Now we'll send dim and comp array to next processor*/

if(size>1){

MPI_Send(&dim,1,MPI_INT,1,tag,ring);