// dump out the dumpQuadElement void dumpQuadElement(const QuadElement *ptr) { if(ptr == NULL) { printf("null entry\n"); } else { int i,j; printf("m = %10.15f\n",ptr->m); printf("alpha = %5.8f\n",ptr->alpha); printf("beta': \n"); for(i=0;i<ptr->gvNum;i++) { const double temp = getMyMatrix(ptr->beta,ptr->gvNum,1,i,0); // const double temp = gsl_matrix_get(ptr->beta,i,0); printf("%5.8f ",temp); } printf("\n"); printf("gamma: \n"); for(i=0;i<ptr->gvNum;i++) { for(j=0;j<ptr->gvNum;j++) { const double temp = getMyMatrix(ptr->gamma,ptr->gvNum,ptr->gvNum,i,j); // const double temp = gsl_matrix_get(ptr->gamma,i,j); printf("%5.8f ",temp); } printf("\n"); } } }
double absMaxMyMatrix(const double *src, const int row, const int col) { double val; double ret; int i,j; ret = fabs(getMyMatrix(src,row,col,0,0)); for(i=0;i<row;i++) { for(j=0;j<col;j++) { val = fabs(getMyMatrix(src,row,col,i,j)); if(val > ret) ret = val; } } return ret; }
// the address of a and c or b and c can not be the same void mulMyMatrix(double *c,const double *a,const double *b, const int rowA,const int colA, const int rowB, const int colB) { int i,j,k,index; double sum,elementA,elementB; const int rowC = rowA; const int colC = colB; for(i=0;i<rowC;i++) { for(j=0;j<colC;j++) { sum = 0.0; for(k=0;k<colA;k++) { elementA = getMyMatrix(a,rowA,colA,i,k); elementB = getMyMatrix(b,rowB,colB,k,j); sum += elementA * elementB; } index = indexConvert(rowC,colC,i,j); c[index] = sum; } } }
static void paralellJacobi(struct calculation_arguments const* arguments, struct calculation_results *results, struct options const* options) { int rank, num_procs; MPI_Status status; MPI_Init(arguments->argc, arguments->argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &num_procs); if(rank == 0) calculateMatrices(arguments, num_procs); int i, j; /* local variables for loops */ int m1, m2; /* used as indices for old and new matrices */ double star; /* four times center value minus 4 neigh.b values */ double residuum; /* residuum of current iteration */ double maxresiduum; /* maximum residuum value of a slave in iteration */ int const N = arguments->N; double const h = arguments->h; double pih = 0.0; double fpisin = 0.0; int term_iteration = options->term_iteration; int sendRec_before = (rank - 1) % num_procs; int sendRec_after = rank + 1 % num_procs; m1 = 0; m2 = 1; if (options->inf_func == FUNC_FPISIN) { pih = PI * h; fpisin = 0.25 * TWO_PI_SQUARE * h * h; } while (term_iteration > 0) { double** Matrix_Out = getMyMatrix(arguments->start[rank], arguments->moveSize[rank], m1, arguments); double** Matrix_In = getMyMatrix(arguments->start[rank], arguments->moveSize[rank], m2, arguments); maxresiduum = 0; if ((rank % 2) == 0) { if (rank == 0) { /*TODO: Sendplätze überprüfen, Sendetypen überprüfen */ MPI_Send(&Matrix_In[arguments->moveSize[rank] - 1], 1, MPI_DOUBLE, sendRec_after, TAG_SEND, MPI_COMM_WORLD); MPI_Recv(&Matrix_In[arguments->moveSize[rank]], 1, MPI_DOUBLE,sendRec_after, TAG_RECV, MPI_COMM_WORLD, NULL); } else if (rank == num_procs -1) { MPI_Send(&Matrix_In[arguments->moveSize[rank] - 1], 1, MPI_DOUBLE, sendRec_before, TAG_SEND, MPI_COMM_WORLD); MPI_Recv(&Matrix_In[0], 1, MPI_DOUBLE, sendRec_before, TAG_RECV, MPI_COMM_WORLD, NULL); } else { MPI_Send(&Matrix_In[1], 1, MPI_DOUBLE, sendRec_before, TAG_SEND, MPI_COMM_WORLD); MPI_Send(&Matrix_In[arguments->moveSize[rank] - 1], 1, MPI_DOUBLE, sendRec_after, TAG_SEND, MPI_COMM_WORLD); MPI_Recv(&Matrix_In[0], 1, MPI_DOUBLE, sendRec_after, TAG_RECV, MPI_COMM_WORLD, NULL); MPI_Recv(&Matrix_In[arguments->moveSize[rank]], 1, MPI_DOUBLE, sendRec_before, TAG_RECV, MPI_COMM_WORLD, NULL); } } else { if (rank == num_procs - 1) { MPI_Recv(&Matrix_In[0], 1, MPI_DOUBLE, sendRec_before, TAG_RECV, MPI_COMM_WORLD, NULL); MPI_Send(&Matrix_In[arguments->moveSize[rank] - 1], 1, MPI_DOUBLE, sendRec_before, TAG_SEND, MPI_COMM_WORLD); } else { MPI_Recv(&Matrix_In[0], 1, MPI_DOUBLE, sendRec_after, TAG_RECV, MPI_COMM_WORLD, NULL); MPI_Recv(&Matrix_In[arguments->moveSize[rank]], 1, MPI_DOUBLE, sendRec_before, TAG_RECV, MPI_COMM_WORLD, NULL); MPI_Send(&Matrix_In[1], 1, MPI_DOUBLE, sendRec_before, TAG_SEND, MPI_COMM_WORLD); MPI_Send(&Matrix_In[arguments->moveSize[rank] - 1], 1, MPI_DOUBLE, sendRec_after, TAG_SEND, MPI_COMM_WORLD); } } /* over all rows */ for (i = 1; i < arguments->moveSize[rank]; i++) { double fpisin_i = 0.0; if (options->inf_func == FUNC_FPISIN) { fpisin_i = fpisin * sin(pih * (double)i); } /* over all columns */ for (j = 1; j < N; j++) { star = 0.25 * (Matrix_In[i-1][j] + Matrix_In[i][j-1] + Matrix_In[i][j+1] + Matrix_In[i+1][j]); if (options->inf_func == FUNC_FPISIN) { star += fpisin_i * sin(pih * (double)j); } if (options->termination == TERM_PREC || term_iteration == 1) { residuum = Matrix_In[i][j] - star; residuum = (residuum < 0) ? -residuum : residuum; maxresiduum = (residuum < maxresiduum) ? maxresiduum : residuum; } Matrix_Out[i][j] = star; } } results->stat_iteration++; results->stat_precision = maxresiduum; /* exchange m1 and m2 */ i = m1; m1 = m2; m2 = i; /* check for stopping calculation, depending on termination method */ if (options->termination == TERM_PREC) { if (maxresiduum < options->term_precision) { term_iteration = 0; } } else if (options->termination == TERM_ITER) { term_iteration--; } } DisplayMatrixMPI(arguments, results, options, rank, num_procs, arguments->start[rank], (arguments->moveSize[rank] + arguments->start[rank])); results->m = m2; }