/*#define DEBUG */ void distrib_msr_matrix(int *proc_config, int N_global, int *n_nonzeros, int *N_update, int **update, double **val, int **bindx, double **x, double **b, double **xexact) { int i, n_entries, N_columns, n_global_nonzeros; int ii, j, row, have_xexact = 0 ; int kk = 0; int max_ii = 0, max_jj = 0; int ione = 1; double value; double *cnt; int *pntr, *bindx1, *pntr1; double *val1, *b1, *x1, *xexact1; #ifdef DEBUG printf("Processor %d of %d entering distrib_matrix.\n", proc_config[AZ_node],proc_config[AZ_N_procs]) ; #endif /*************** Distribute global matrix to all processors ************/ if(proc_config[AZ_node] == 0) { if ((*xexact) != NULL) have_xexact = 1; #ifdef DEBUG printf("Broadcasting exact solution\n"); #endif } if(proc_config[AZ_N_procs] > 1) { AZ_broadcast((char *) &N_global, sizeof(int), proc_config, AZ_PACK); AZ_broadcast((char *) n_nonzeros, sizeof(int), proc_config, AZ_PACK); AZ_broadcast((char *) &have_xexact, sizeof(int), proc_config, AZ_PACK); AZ_broadcast(NULL, 0, proc_config, AZ_SEND); if(proc_config[AZ_node] != 0) { (*bindx) = (int *) calloc(*n_nonzeros+1,sizeof(int)) ; (*val) = (double *) calloc(*n_nonzeros+1,sizeof(double)) ; } AZ_broadcast((char *) (*bindx), sizeof(int) *(*n_nonzeros+1), proc_config, AZ_PACK); AZ_broadcast(NULL, 0, proc_config, AZ_SEND); AZ_broadcast((char *) (*val), sizeof(double)*(*n_nonzeros+1), proc_config, AZ_PACK); AZ_broadcast(NULL, 0, proc_config, AZ_SEND); #ifdef DEBUG printf("Processor %d of %d done with matrix broadcast.\n", proc_config[AZ_node],proc_config[AZ_N_procs]) ; #endif /* Set rhs and initialize guess */ if(proc_config[AZ_node] != 0) { (*b) = (double *) calloc(N_global,sizeof(double)) ; (*x) = (double *) calloc(N_global,sizeof(double)) ; if (have_xexact) (*xexact) = (double *) calloc(N_global,sizeof(double)) ; } AZ_broadcast((char *) (*x), sizeof(double)*(N_global), proc_config, AZ_PACK); AZ_broadcast((char *) (*b), sizeof(double)*(N_global), proc_config, AZ_PACK); if (have_xexact) AZ_broadcast((char *) (*xexact), sizeof(double)*(N_global), proc_config, AZ_PACK); AZ_broadcast(NULL, 0, proc_config, AZ_SEND); #ifdef DEBUG printf("Processor %d of %d done with rhs/guess broadcast.\n", proc_config[AZ_node],proc_config[AZ_N_procs]) ; #endif } /********************** Generate update map *************************/ AZ_read_update(N_update, update, proc_config, N_global, 1, AZ_linear) ; printf("Processor %d of %d has %d rows of %d total rows.\n", proc_config[AZ_node],proc_config[AZ_N_procs],*N_update,N_global) ; /*************** Construct local matrix from global matrix ************/ /* The local matrix is a copy of the rows assigned to this processor. It is stored in MSR format and still has global indices (AZ_transform will complete conversion to local indices. */ if(proc_config[AZ_N_procs] > 1) { n_global_nonzeros = *n_nonzeros; *n_nonzeros = *N_update; for (i=0; i<*N_update; i++) *n_nonzeros += (*bindx)[(*update)[i]+1] - (*bindx)[(*update)[i]]; printf("Processor %d of %d has %d nonzeros of %d total nonzeros.\n", proc_config[AZ_node],proc_config[AZ_N_procs], *n_nonzeros,n_global_nonzeros) ; #ifdef DEBUG { double sum1 = 0.0; for (i=0;i<N_global; i++) sum1 += (*b)[i]; printf("Processor %d of %d has sum of b = %12.4g.\n", proc_config[AZ_node],proc_config[AZ_N_procs],sum1) ; } #endif /* DEBUG */ /* Allocate memory for local matrix */ bindx1 = (int *) calloc(*n_nonzeros+1,sizeof(int)) ; val1 = (double *) calloc(*n_nonzeros+1,sizeof(double)) ; b1 = (double *) calloc(*N_update,sizeof(double)) ; x1 = (double *) calloc(*N_update,sizeof(double)) ; if (have_xexact) xexact1 = (double *) calloc(*N_update,sizeof(double)) ; bindx1[0] = *N_update+1; for (i=0; i<*N_update; i++) { row = (*update)[i]; b1[i] = (*b)[row]; x1[i] = (*x)[row]; if (have_xexact) xexact1[i] = (*xexact)[row]; val1[i] = (*val)[row]; bindx1[i+1] = bindx1[i]; #ifdef DEBUG printf("Proc %d of %d: Global row = %d: Local row = %d: b = %12.4g: x = %12.4g: bindx = %d: val = %12.4g \n", proc_config[AZ_node],proc_config[AZ_N_procs], row, i, b1[i], x1[i], bindx1[i], val1[i]) ; #endif for (j = (*bindx)[row]; j < (*bindx)[row+1]; j++) { val1[ bindx1 [i+1] ] = (*val)[j]; bindx1[bindx1 [i+1] ] = (*bindx)[j]; bindx1[i+1] ++; } } #ifdef DEBUG printf("Processor %d of %d done with extracting local operators.\n", proc_config[AZ_node],proc_config[AZ_N_procs]) ; if (have_xexact) { printf( "The residual using MSR format and exact solution on processor %d is %12.4g\n", proc_config[AZ_node], smsrres (*N_update, N_global, val1, bindx1, xexact1, (*xexact), b1)); } #endif /* Release memory for global matrix, rhs and solution */ free ((void *) (*val)); free ((void *) (*bindx)); free ((void *) (*b)); free ((void *) (*x)); if (have_xexact) free((void *) *xexact); /* Return local matrix through same pointers. */ *val = val1; *bindx = bindx1; *b = b1; *x = x1; if (have_xexact) *xexact = xexact1; }
void read_hb(char *data_file, int *N_global, int *n_nonzeros, double **val, int **bindx, double **x, double **b, double **bt, double **xexact) #undef DEBUG { FILE *in_file ; char Title[73], Key[9], Rhstype[4]; char Type[4] = "XXX\0"; char Ptrfmt[17], Indfmt[17], Valfmt[21], Rhsfmt[21]; int Ptrcrd, Indcrd, Valcrd, Rhscrd; int i, n_entries, N_columns, Nrhs; int ii, jj ; int kk = 0; int isym; int ione = 1; double value, res; double *cnt; int *pntr, *indx1, *pntr1; double *val1; in_file = fopen( data_file, "r"); if (in_file == NULL) { printf("Error: Cannot open file: %s\n",data_file); exit(1); } /* Get information about the array stored in the file specified in the */ /* argument list: */ printf("Reading matrix info from %s...\n",data_file); in_file = fopen( data_file, "r"); if (in_file == NULL) { printf("Error: Cannot open file: %s\n",data_file); exit(1); } readHB_header(in_file, Title, Key, Type, N_global, &N_columns, &n_entries, &Nrhs, Ptrfmt, Indfmt, Valfmt, Rhsfmt, &Ptrcrd, &Indcrd, &Valcrd, &Rhscrd, Rhstype); fclose(in_file); if (Nrhs < 0 ) Nrhs = 0; printf("***************************************************************\n"); printf("Matrix in file %s is %d x %d, \n",data_file, *N_global, N_columns); printf("with %d nonzeros with type %3s;\n", n_entries, Type); printf("***************************************************************\n"); printf("Title: %72s\n",Title); printf("***************************************************************\n"); /*Nrhs = 0; */ printf("%d right-hand-side(s) available.\n",Nrhs); if (Type[0] != 'R') perror("Can only handle real valued matrices"); isym = 0; if (Type[1] == 'S') { printf("Converting symmetric matrix to nonsymmetric storage\n"); n_entries = 2*n_entries - N_columns; isym = 1; } if (Type[2] != 'A') perror("Can only handle assembled matrices"); if (N_columns != *N_global) perror("Matrix dimensions must be the same"); *n_nonzeros = n_entries; /* Read the matrix information, generating the associated storage arrays */ printf("Reading the matrix from %s...\n",data_file); /* Allocate space. Note that we add extra storage in case of zero diagonals. This is necessary for conversion to MSR format. */ pntr = (int *) calloc(N_columns+1,sizeof(int)) ; *bindx = (int *) calloc(n_entries+N_columns+1,sizeof(int)) ; *val = (double *) calloc(n_entries+N_columns+1,sizeof(double)) ; readHB_mat_double(data_file, pntr, *bindx, *val); /* If a rhs is specified in the file, read one, generating the associate storage */ if (Nrhs > 0 && Rhstype[2] =='X') { printf("Reading right-hand-side vector(s) from %s...\n",data_file); *b = (double *) calloc(N_columns,sizeof(double)); readHB_aux_double(data_file, 'F', (*b)); printf("Reading exact solution vector(s) from %s...\n",data_file); *xexact = (double *) calloc(N_columns,sizeof(double)); readHB_aux_double(data_file, 'X', (*xexact)); } else { /* Set Xexact to a random vector */ printf("Setting random exact solution vector\n"); *xexact = (double *) calloc(N_columns,sizeof(double)); for (i=0;i<*N_global;i++) (*xexact)[i] = drand48(); /* Compute b to match xexact */ *b = (double *) calloc(N_columns,sizeof(double)) ; if ((*b) == NULL) perror("Error: Not enough space to create rhs"); scscmv (isym, 1, N_columns, N_columns, (*val), (*bindx), pntr, (*xexact), (*b)); } /* Compute residual using CSC format */ for (i = 0; i <= *N_global; i++) pntr[i]--; for (i = 0; i <= n_entries; i++) (*bindx)[i]--; res = scscres(isym, *N_global, *N_global, (*val), (*bindx), pntr, (*xexact), (*b)); printf( "The residual using CSC format and exact solution is %12.4g\n", res); for (i = 0; i <= *N_global; i++) pntr[i]++; for (i = 0; i <= n_entries; i++) (*bindx)[i]++; /* Set initial guess to zero */ *x = (double *) calloc((*N_global),sizeof(double)) ; if ((*x) == NULL) perror("Error: Not enough space to create guess"); /* Set RHS to a random vector, initial guess to zero */ for (i=0;i<*N_global;i++) (*x)[i] = 0.0; /* Allocate temporary space */ pntr1 = (int *) calloc(N_columns+1,sizeof(int)) ; indx1 = (int *) calloc(n_entries+N_columns+1,sizeof(int)) ; val1 = (double *) calloc(n_entries+N_columns+1,sizeof(double)) ; /* Convert in the following way: - CSC to CSR - CSR to MSR */ csrcsc_(N_global,&ione,&ione, *val,*bindx,pntr, val1,indx1,pntr1); /* Compute bt = A(trans)*xexact */ *bt = (double *) calloc(N_columns,sizeof(double)) ; scscmv (isym, 1, N_columns, N_columns, val1, indx1, pntr1, (*xexact), (*bt)); if (Type[1] == 'S') { int *indu; int ierr; indu = indx1+n_entries; /* Use end of bindx for workspace */ ssrcsr_(&N_columns, val1, indx1, pntr1, &n_entries, val1, indx1, pntr1, indu, &ierr); if (ierr !=0 ) { printf(" Error in converting from symmetric form\n IERR = %d\n",ierr); abort(); } } csrmsr_(N_global,val1,indx1,pntr1, *val,*bindx, *val,*bindx); /* Recompute number of nonzeros in case there were zero diagonals */ *n_nonzeros = (*bindx)[*N_global] - 2; /* Still in Fortran mode so -2 */ /* Finally, convert bindx vectors to zero base */ for (i=0;i<*n_nonzeros+1;i++) (*bindx)[i] -= 1; printf("The residual using MSR format and exact solution is %12.4g\n", smsrres (*N_global, *N_global, (*val), (*bindx), (*xexact), (*xexact), (*b))); /* Release unneeded space */ free((void *) val1); free((void *) indx1); free((void *) pntr1); free((void *) pntr); /* end read_hb */ }