int main(int argc, char * argv[]) { int X=atoi(argv[1]); int Y=X; double ** A=malloc2D(X,Y); int i,j,k; double l; struct timeval ts,tf; double total_time; init2D(A,X,Y); gettimeofday(&ts,NULL); for (k=0;k<X-1;k++) for (i=k+1;i<X;i++) { l=A[i][k]/A[k][k]; for (j=k;j<Y;j++) A[i][j]-=l*A[k][j]; } gettimeofday(&tf,NULL); total_time=(tf.tv_sec-ts.tv_sec)+(tf.tv_usec-ts.tv_usec)*0.000001; printf("LU-Serial\t%d\t%.3lf\n",X,total_time); char * filename="output_serial"; print2DFile(A,X,Y,filename); return 0; }
int main(int argc, char **argv){ int x = atoi(argv[1]); int y = x; double ** A = malloc2D(x, y); init2D(A, x, y); print2DFile(A, x, y, argv[2]); free2D(A, x, y); return 0; }
int main (int argc, char * argv[]) { int rank,size; MPI_Init(&argc,&argv); MPI_Comm_size(MPI_COMM_WORLD,&size); MPI_Comm_rank(MPI_COMM_WORLD,&rank); int X,Y,x,y,X_ext,i,j,k; double ** A, ** localA, l, *msg; X=atoi(argv[1]); Y=X; //Extend dimension X with ghost cells if X%size!=0 if (X%size!=0) X_ext=X+size-X%size; else X_ext=X; if (rank==0) { //Allocate and init matrix A A=malloc2D(X_ext,Y); init2D(A,X,Y); } //Local dimensions x,y x=X_ext/size; y=Y; //Allocate local matrix and scatter global matrix localA=malloc2D(x,y); double * idx; if (rank==0) idx=&A[0][0]; MPI_Scatter(idx,x*y,MPI_DOUBLE,&localA[0][0],x*y,MPI_DOUBLE,0,MPI_COMM_WORLD); if (rank==0) { free2D(A,X_ext,Y); } //Timers struct timeval ts,tf,comps,compf,comms,commf; double total_time=0,computation_time=0,communication_time=0; MPI_Barrier(MPI_COMM_WORLD); gettimeofday(&ts,NULL); /****************************************************************************** The matrix A is distributed in contiguous blocks to the local matrices localA You have to use point-to-point communication routines Don't forget to set the timers for computation and communication! ******************************************************************************/ //******************************************************************************** msg = malloc(y * sizeof(double)); int tag =55, dest, dif, srank; MPI_Status status; MPI_Request request; for(k = 0; k < X - 1; k++){ // if is owner_of_pivot_line(k) - x*rank <= k < x*(rank+1) if ( ( x*rank <= k ) && ( k < (x * (rank + 1)) ) ) { //pack_data(lA, send_buffer); memcpy(msg, localA[ k%x ], y * sizeof(double) ); //send_data_to_all for(dest=0;dest<size;dest++) { if ((dest==rank) || (dest<rank)) continue; gettimeofday(&comms,NULL); MPI_Send(msg,y,MPI_DOUBLE,dest,tag,MPI_COMM_WORLD); gettimeofday(&commf,NULL); communication_time+=commf.tv_sec-comms.tv_sec+(commf.tv_usec-comms.tv_usec)*0.000001; } } else { //receive_data_from_owner //unpack_data(receive_buffer, lA); srank = k / x; if ((rank<srank) || (rank==srank)) continue; gettimeofday(&comms,NULL); MPI_Recv(msg,y,MPI_DOUBLE,srank,tag,MPI_COMM_WORLD,&status); gettimeofday(&commf,NULL); communication_time+=commf.tv_sec-comms.tv_sec+(commf.tv_usec-comms.tv_usec)*0.000001; } //compute(k, lA); gettimeofday(&comps,NULL); if ( k < ( x * (rank + 1) - 1 ) ) { dif = ( x * (rank + 1) - 1 ) - k; if (dif > x) dif = x; for ( i = x - dif; i < x; i++ ) { l = localA[i][k] / msg[k]; for ( j=k; j<y; j++ ) localA[i][j] -= l * msg[j]; } } gettimeofday(&compf,NULL); computation_time+=compf.tv_sec-comps.tv_sec+(compf.tv_usec-comps.tv_usec)*0.000001; } free(msg); MPI_Barrier(MPI_COMM_WORLD); //******************************************************************************** gettimeofday(&tf,NULL); total_time=tf.tv_sec-ts.tv_sec+(tf.tv_usec-ts.tv_usec)*0.000001; //Gather local matrices back to the global matrix if (rank==0) { A=malloc2D(X_ext,Y); idx=&A[0][0]; } MPI_Gather(&localA[0][0],x*y,MPI_DOUBLE,idx,x*y,MPI_DOUBLE,0,MPI_COMM_WORLD); double avg_total,avg_comp,avg_comm,max_total,max_comp,max_comm; MPI_Reduce(&total_time,&max_total,1,MPI_DOUBLE,MPI_MAX,0,MPI_COMM_WORLD); MPI_Reduce(&computation_time,&max_comp,1,MPI_DOUBLE,MPI_MAX,0,MPI_COMM_WORLD); MPI_Reduce(&communication_time,&max_comm,1,MPI_DOUBLE,MPI_MAX,0,MPI_COMM_WORLD); MPI_Reduce(&total_time,&avg_total,1,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD); MPI_Reduce(&computation_time,&avg_comp,1,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD); MPI_Reduce(&communication_time,&avg_comm,1,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD); avg_total/=size; avg_comp/=size; avg_comm/=size; if (rank==0) { printf("LU-Block-p2p\tSize\t%d\tProcesses\t%d\n",X,size); printf("Max times:\tTotal\t%lf\tComp\t%lf\tComm\t%lf\n",max_total,max_comp,max_comm); printf("Avg times:\tTotal\t%lf\tComp\t%lf\tComm\t%lf\n",avg_total,avg_comp,avg_comm); } //Print triangular matrix U to file if (rank==0) { char * filename="output_block_p2p"; print2DFile(A,X,Y,filename); } MPI_Finalize(); return 0; }
int main (int argc, char * argv[]) { int rank,size; MPI_Init(&argc,&argv); MPI_Comm_size(MPI_COMM_WORLD,&size); MPI_Comm_rank(MPI_COMM_WORLD,&rank); int X,Y,x,y,X_ext,i; double **A, **localA; X=atoi(argv[1]); Y=X; //Extend dimension X with ghost cells if X%size!=0 if (X%size!=0) X_ext=X+size-X%size; else X_ext=X; if (rank==0) { //Allocate and init matrix A A=malloc2D(X_ext,Y); init2D(A,X,Y); } //Local dimensions x,y x=X_ext/size; y=Y; //Allocate local matrix and scatter global matrix localA=malloc2D(x,y); double * idx; for (i=0;i<x;i++) { if (rank==0) idx=&A[i*size][0]; MPI_Scatter(idx,Y,MPI_DOUBLE,&localA[i][0],y,MPI_DOUBLE,0,MPI_COMM_WORLD); } if (rank==0) free2D(A,X_ext,Y); //Timers struct timeval ts,tf,comps,compf,comms,commf; double total_time,computation_time,communication_time; MPI_Barrier(MPI_COMM_WORLD); gettimeofday(&ts,NULL); /****************************************************************************** The matrix A is distributed in a round-robin fashion to the local matrices localA You have to use point-to-point communication routines. Don't forget the timers for computation and communication! ******************************************************************************/ int line_index, line_owner; int k, start; double *k_row, *temp; MPI_Status status; temp = malloc(y * sizeof(*temp)); // k_row = malloc(y * sizeof(*k_row)); /* omoia me to allo cyclic, vriskoume ton line_owner */ for (k=0; k<y-1; k++){ line_owner = k % size; line_index = k / size; if (rank <= line_owner) start = k / size + 1; else start = k / size; if (rank == line_owner) k_row = localA[line_index]; else k_row = temp; /* set communication timer */ gettimeofday(&comms, NULL); /* COMM */ // if (rank != line_owner){ // if (rank == 0) // MPI_Recv( k_row, y, MPI_DOUBLE, size-1, MPI_ANY_SOURCE, MPI_COMM_WORLD, &status); // else // MPI_Recv( k_row, y, MPI_DOUBLE, rank-1, MPI_ANY_SOURCE, MPI_COMM_WORLD, &status); // } // // /* autos pou einai prin ton line_owner den prepei na steilei */ // if (rank != line_owner -1){ // /* o teleutaios prepei na steilei ston prwto, ektos an o prwtos einai o line_owner */ // if (rank == size-1) { // if (line_owner != 0) // MPI_Send( k_row, y, MPI_DOUBLE, 0, rank, MPI_COMM_WORLD); // } // else // MPI_Send(k_row, y, MPI_DOUBLE, rank+1, rank, MPI_COMM_WORLD); // } /* o line_owner stelnei se olous (ektos tou eautou tou) kai oloi oi alloi kanoun * receive */ if (rank == line_owner){ for (i=0; i<size; i++) if (i != line_owner) MPI_Send( k_row, y, MPI_DOUBLE, i, line_owner, MPI_COMM_WORLD); } else MPI_Recv(k_row, y, MPI_DOUBLE, line_owner, line_owner, MPI_COMM_WORLD, &status); /* stop communication timer */ gettimeofday(&commf, NULL); communication_time += commf.tv_sec - comms.tv_sec + (commf.tv_usec - comms.tv_usec)*0.000001; /* set computation timer */ gettimeofday(&comps, NULL); /* Compute */ go_to_work( localA, k_row, x, y, rank, start, k ); /* stop computation timer */ gettimeofday(&compf, NULL); computation_time += compf.tv_sec - comps.tv_sec + (compf.tv_usec - comps.tv_usec)*0.000001; } gettimeofday(&tf,NULL); total_time=tf.tv_sec-ts.tv_sec+(tf.tv_usec-ts.tv_usec)*0.000001; //Gather local matrices back to the global matrix if (rank==0) A=malloc2D(X_ext,Y); for (i=0;i<x;i++) { if (rank==0) idx=&A[i*size][0]; MPI_Gather(&localA[i][0],y,MPI_DOUBLE,idx,Y,MPI_DOUBLE,0,MPI_COMM_WORLD); } double avg_total,avg_comp,avg_comm,max_total,max_comp,max_comm; MPI_Reduce(&total_time,&max_total,1,MPI_DOUBLE,MPI_MAX,0,MPI_COMM_WORLD); MPI_Reduce(&computation_time,&max_comp,1,MPI_DOUBLE,MPI_MAX,0,MPI_COMM_WORLD); MPI_Reduce(&communication_time,&max_comm,1,MPI_DOUBLE,MPI_MAX,0,MPI_COMM_WORLD); MPI_Reduce(&total_time,&avg_total,1,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD); MPI_Reduce(&computation_time,&avg_comp,1,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD); MPI_Reduce(&communication_time,&avg_comm,1,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD); avg_total/=size; avg_comp/=size; avg_comm/=size; if (rank==0) { printf("LU-Cyclic-p2p\tSize\t%d\tProcesses\t%d\n",X,size); printf("Max times:\tTotal\t%lf\tComp\t%lf\tComm\t%lf\n",max_total,max_comp,max_comm); printf("Avg times:\tTotal\t%lf\tComp\t%lf\tComm\t%lf\n",avg_total,avg_comp,avg_comm); } //Print triangular matrix U to file if (rank==0) { char * filename="output_cyclic_p2p"; print2DFile(A,X,Y,filename); } MPI_Finalize(); return 0; }
int main (int argc, char * argv[]) { int rank,size; MPI_Init(&argc,&argv); MPI_Comm_size(MPI_COMM_WORLD,&size); MPI_Comm_rank(MPI_COMM_WORLD,&rank); int X,Y,x,y,X_ext, i; double ** A, ** localA; X=atoi(argv[1]); Y=X; //Extend dimension X with ghost cells if X%size!=0 if (X%size!=0) X_ext=X+size-X%size; else X_ext=X; if (rank==0) { //Allocate and init matrix A A=malloc2D(X_ext,Y); init2D(A,X,Y); } //Local dimensions x,y x=X_ext/size; y=Y; //Allocate local matrix and scatter global matrix localA=malloc2D(x,y); double * idx; if (rank==0) idx=&A[0][0]; MPI_Scatter(idx,x*y,MPI_DOUBLE,&localA[0][0],x*y,MPI_DOUBLE,0,MPI_COMM_WORLD); if (rank==0) { free2D(A,X_ext,Y); } //Timers struct timeval ts,tf,comps,compf,comms,commf; double total_time,computation_time,communication_time; MPI_Barrier(MPI_COMM_WORLD); gettimeofday(&ts,NULL); /****************************************************************************** The matrix A is distributed in contiguous blocks to the local matrices localA You have to use point-to-point communication routines Don't forget to set the timers for computation and communication! ******************************************************************************/ int line_index, line_owner; int k, start; MPI_Status status; double *k_row, *temp; temp = malloc(y * sizeof(*k_row)); for (k=0; k<y-1; k++){ start = 0; line_owner = k / x; line_index = k % x; if (rank == line_owner){ start = line_index+1; k_row = localA[line_index]; } else k_row = temp; /* set communication timer */ gettimeofday(&comms, NULL); /* o line_owner stelnei se olous (ektos tou eautou tou) kai oi alloi * kanoun receive th k_row */ if (rank == line_owner){ for (i=0; i<size; i++) if (i != line_owner) MPI_Send( k_row, y, MPI_DOUBLE, i, line_owner, MPI_COMM_WORLD); } else MPI_Recv(k_row, y, MPI_DOUBLE, line_owner, line_owner, MPI_COMM_WORLD, &status); /* stop communication timer */ gettimeofday(&commf, NULL); communication_time += commf.tv_sec - comms.tv_sec + (commf.tv_usec - comms.tv_usec)*0.000001; /* set computation timer */ gettimeofday(&comps, NULL); /* Compute */ go_to_work( localA, k_row, x, y, rank, line_owner, start, k ); /* stop computation timer */ gettimeofday(&compf, NULL); computation_time += compf.tv_sec - comps.tv_sec + (compf.tv_usec - comps.tv_usec)*0.000001; } gettimeofday(&tf,NULL); total_time=tf.tv_sec-ts.tv_sec+(tf.tv_usec-ts.tv_usec)*0.000001; //Gather local matrices back to the global matrix if (rank==0) { A=malloc2D(X_ext,Y); idx=&A[0][0]; } MPI_Gather(&localA[0][0],x*y,MPI_DOUBLE,idx,x*y,MPI_DOUBLE,0,MPI_COMM_WORLD); double avg_total,avg_comp,avg_comm,max_total,max_comp,max_comm; MPI_Reduce(&total_time,&max_total,1,MPI_DOUBLE,MPI_MAX,0,MPI_COMM_WORLD); MPI_Reduce(&computation_time,&max_comp,1,MPI_DOUBLE,MPI_MAX,0,MPI_COMM_WORLD); MPI_Reduce(&communication_time,&max_comm,1,MPI_DOUBLE,MPI_MAX,0,MPI_COMM_WORLD); MPI_Reduce(&total_time,&avg_total,1,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD); MPI_Reduce(&computation_time,&avg_comp,1,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD); MPI_Reduce(&communication_time,&avg_comm,1,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD); avg_total/=size; avg_comp/=size; avg_comm/=size; if (rank==0) { printf("LU-Block-p2p\tSize\t%d\tProcesses\t%d\n",X,size); printf("Max times:\tTotal\t%lf\tComp\t%lf\tComm\t%lf\n",max_total,max_comp,max_comm); printf("Avg times:\tTotal\t%lf\tComp\t%lf\tComm\t%lf\n",avg_total,avg_comp,avg_comm); } //Print triangular matrix U to file if (rank==0) { char * filename="output_block_p2p"; print2DFile(A,X,Y,filename); } MPI_Finalize(); return 0; }