int HYPRE_IJVectorGetLocalRange( HYPRE_IJVector vector, HYPRE_BigInt *jlower, HYPRE_BigInt *jupper ) { hypre_IJVector *vec = (hypre_IJVector *) vector; MPI_Comm comm; HYPRE_BigInt *partitioning; int my_id; if (!vec) { printf("Variable vec is NULL -- HYPRE_IJVectorGetObjectType\n"); hypre_error_in_arg(1); return hypre_error_flag; } comm = hypre_IJVectorComm(vec); partitioning = hypre_IJVectorPartitioning(vec); MPI_Comm_rank(comm, &my_id); #ifdef HYPRE_NO_GLOBAL_PARTITION *jlower = partitioning[0]; *jupper = partitioning[1]-1; #else *jlower = partitioning[my_id]; *jupper = partitioning[my_id+1]-1; #endif return hypre_error_flag; }
int HYPRE_IJVectorPrint( HYPRE_IJVector vector, const char *filename ) { MPI_Comm comm = hypre_IJVectorComm(vector); HYPRE_BigInt *partitioning; HYPRE_BigInt jlower, jupper, j; double value; int myid; char new_filename[255]; FILE *file; if (!vector) { printf("Variable vec is NULL -- HYPRE_IJVectorPrint\n"); hypre_error_in_arg(1); return hypre_error_flag; } MPI_Comm_rank(comm, &myid); sprintf(new_filename,"%s.%05d", filename, myid); if ((file = fopen(new_filename, "w")) == NULL) { printf("Error: can't open output file %s\n", new_filename); hypre_error_in_arg(2); return hypre_error_flag; } partitioning = hypre_IJVectorPartitioning(vector); #ifdef HYPRE_NO_GLOBAL_PARTITION jlower = partitioning[0]; jupper = partitioning[1] - 1; #else jlower = partitioning[myid]; jupper = partitioning[myid+1] - 1; #endif #ifdef HYPRE_LONG_LONG fprintf(file, "%lld %lld\n", jlower, jupper); #else fprintf(file, "%d %d\n", jlower, jupper); #endif for (j = jlower; j <= jupper; j++) { HYPRE_IJVectorGetValues(vector, 1, &j, &value); #ifdef HYPRE_LONG_LONG fprintf(file, "%lld %.14e\n", j, value); #else fprintf(file, "%d %.14e\n", j, value); #endif } fclose(file); return hypre_error_flag; }
/****************************************************************************** * * hypre_IJVectorInitializePar * * initializes ParVector of IJVectorPar * *****************************************************************************/ HYPRE_Int hypre_IJVectorInitializePar(hypre_IJVector *vector) { hypre_ParVector *par_vector = hypre_IJVectorObject(vector); hypre_AuxParVector *aux_vector = hypre_IJVectorTranslator(vector); HYPRE_Int *partitioning = hypre_ParVectorPartitioning(par_vector); hypre_Vector *local_vector = hypre_ParVectorLocalVector(par_vector); HYPRE_Int my_id; HYPRE_Int print_level = hypre_IJVectorPrintLevel(vector); MPI_Comm comm = hypre_IJVectorComm(vector); hypre_MPI_Comm_rank(comm,&my_id); if (!partitioning) { if (print_level) { hypre_printf("No ParVector partitioning for initialization -- "); hypre_printf("hypre_IJVectorInitializePar\n"); } hypre_error_in_arg(1); } #ifdef HYPRE_NO_GLOBAL_PARTITION hypre_VectorSize(local_vector) = partitioning[1] - partitioning[0]; #else hypre_VectorSize(local_vector) = partitioning[my_id+1] - partitioning[my_id]; #endif hypre_ParVectorInitialize(par_vector); if (!aux_vector) { hypre_AuxParVectorCreate(&aux_vector); hypre_IJVectorTranslator(vector) = aux_vector; } hypre_AuxParVectorInitialize(aux_vector); return hypre_error_flag; }
/****************************************************************************** * * hypre_IJVectorCreatePar * * creates ParVector if necessary, and leaves a pointer to it as the * hypre_IJVector object * *****************************************************************************/ int hypre_IJVectorCreatePar(hypre_IJVector *vector, HYPRE_BigInt *IJpartitioning) { MPI_Comm comm = hypre_IJVectorComm(vector); int num_procs, j; HYPRE_BigInt global_n, *partitioning, jmin; MPI_Comm_size(comm, &num_procs); #ifdef HYPRE_NO_GLOBAL_PARTITION jmin = hypre_IJVectorGlobalFirstRow(vector); global_n = hypre_IJVectorGlobalNumRows(vector); partitioning = hypre_CTAlloc(HYPRE_BigInt, 2); /* Shift to zero-based partitioning for ParVector object */ for (j = 0; j < 2; j++) partitioning[j] = IJpartitioning[j] - jmin; #else jmin = IJpartitioning[0]; global_n = IJpartitioning[num_procs] - jmin; partitioning = hypre_CTAlloc(HYPRE_BigInt, num_procs+1); /* Shift to zero-based partitioning for ParVector object */ for (j = 0; j < num_procs+1; j++) partitioning[j] = IJpartitioning[j] - jmin; #endif hypre_IJVectorObject(vector) = hypre_ParVectorCreate(comm, global_n, (HYPRE_BigInt *) partitioning); return hypre_error_flag; }
/****************************************************************************** * * hypre_IJVectorAddToValuesPar * * adds to a potentially noncontiguous set of IJVectorPar components * *****************************************************************************/ HYPRE_Int hypre_IJVectorAddToValuesPar(hypre_IJVector *vector, HYPRE_Int num_values, const HYPRE_Int *indices, const double *values ) { HYPRE_Int my_id; HYPRE_Int i, j, vec_start, vec_stop; double *data; HYPRE_Int print_level = hypre_IJVectorPrintLevel(vector); HYPRE_Int *IJpartitioning = hypre_IJVectorPartitioning(vector); hypre_ParVector *par_vector = hypre_IJVectorObject(vector); hypre_AuxParVector *aux_vector = hypre_IJVectorTranslator(vector); MPI_Comm comm = hypre_IJVectorComm(vector); hypre_Vector *local_vector = hypre_ParVectorLocalVector(par_vector); /* If no components are to be retrieved, perform no checking and return */ if (num_values < 1) return 0; hypre_MPI_Comm_rank(comm, &my_id); /* If par_vector == NULL or partitioning == NULL or local_vector == NULL let user know of catastrophe and exit */ if (!par_vector) { if (print_level) { hypre_printf("par_vector == NULL -- "); hypre_printf("hypre_IJVectorAddToValuesPar\n"); hypre_printf("**** Vector storage is either unallocated or orphaned ****\n"); } hypre_error_in_arg(1); } if (!IJpartitioning) { if (print_level) { hypre_printf("IJpartitioning == NULL -- "); hypre_printf("hypre_IJVectorAddToValuesPar\n"); hypre_printf("**** IJVector partitioning is either unallocated or orphaned ****\n"); } hypre_error_in_arg(1); } if (!local_vector) { if (print_level) { hypre_printf("local_vector == NULL -- "); hypre_printf("hypre_IJVectorAddToValuesPar\n"); hypre_printf("**** Vector local data is either unallocated or orphaned ****\n"); } hypre_error_in_arg(1); } #ifdef HYPRE_NO_GLOBAL_PARTITION vec_start = IJpartitioning[0]; vec_stop = IJpartitioning[1]-1; #else vec_start = IJpartitioning[my_id]; vec_stop = IJpartitioning[my_id+1]-1; #endif if (vec_start > vec_stop) { if (print_level) { hypre_printf("vec_start > vec_stop -- "); hypre_printf("hypre_IJVectorAddToValuesPar\n"); hypre_printf("**** This vector partitioning should not occur ****\n"); } hypre_error_in_arg(1); } /* Determine whether indices points to local indices only, and if not, store indices and values into auxiliary vector structure If indices == NULL, assume that num_values components are to be set in a block starting at vec_start. NOTE: If indices == NULL off processor values are ignored!!! */ /* if (indices) { for (i = 0; i < num_values; i++) { ierr += (indices[i] < vec_start); ierr += (indices[i] >= vec_stop); } } if (ierr) { hypre_printf("indices beyond local range -- "); hypre_printf("hypre_IJVectorAddToValuesPar\n"); hypre_printf("**** Indices specified are unusable ****\n"); exit(1); } */ data = hypre_VectorData(local_vector); if (indices) { HYPRE_Int current_num_elmts = hypre_AuxParVectorCurrentNumElmts(aux_vector); HYPRE_Int max_off_proc_elmts = hypre_AuxParVectorMaxOffProcElmts(aux_vector); HYPRE_Int *off_proc_i = hypre_AuxParVectorOffProcI(aux_vector); double *off_proc_data = hypre_AuxParVectorOffProcData(aux_vector); for (j = 0; j < num_values; j++) { i = indices[j]; if (i < vec_start || i > vec_stop) { /* if elements outside processor boundaries, store in off processor stash */ if (!max_off_proc_elmts) { max_off_proc_elmts = 100; hypre_AuxParVectorMaxOffProcElmts(aux_vector) = max_off_proc_elmts; hypre_AuxParVectorOffProcI(aux_vector) = hypre_CTAlloc(HYPRE_Int,max_off_proc_elmts); hypre_AuxParVectorOffProcData(aux_vector) = hypre_CTAlloc(double,max_off_proc_elmts); off_proc_i = hypre_AuxParVectorOffProcI(aux_vector); off_proc_data = hypre_AuxParVectorOffProcData(aux_vector); } else if (current_num_elmts + 1 > max_off_proc_elmts) { max_off_proc_elmts += 10; off_proc_i = hypre_TReAlloc(off_proc_i,HYPRE_Int,max_off_proc_elmts); off_proc_data = hypre_TReAlloc(off_proc_data,double, max_off_proc_elmts); hypre_AuxParVectorMaxOffProcElmts(aux_vector) = max_off_proc_elmts; hypre_AuxParVectorOffProcI(aux_vector) = off_proc_i; hypre_AuxParVectorOffProcData(aux_vector) = off_proc_data; } off_proc_i[current_num_elmts] = i; off_proc_data[current_num_elmts++] = values[j]; hypre_AuxParVectorCurrentNumElmts(aux_vector)=current_num_elmts; }
/****************************************************************************** * * hypre_IJVectorSetValuesPar * * sets a potentially noncontiguous set of components of an IJVectorPar * *****************************************************************************/ HYPRE_Int hypre_IJVectorSetValuesPar(hypre_IJVector *vector, HYPRE_Int num_values, const HYPRE_Int *indices, const double *values ) { HYPRE_Int my_id; HYPRE_Int i, j, vec_start, vec_stop; double *data; HYPRE_Int print_level = hypre_IJVectorPrintLevel(vector); HYPRE_Int *IJpartitioning = hypre_IJVectorPartitioning(vector); hypre_ParVector *par_vector = hypre_IJVectorObject(vector); hypre_AuxParVector *aux_vector = hypre_IJVectorTranslator(vector); MPI_Comm comm = hypre_IJVectorComm(vector); hypre_Vector *local_vector = hypre_ParVectorLocalVector(par_vector); /* If no components are to be set, perform no checking and return */ if (num_values < 1) return 0; hypre_MPI_Comm_rank(comm, &my_id); /* If par_vector == NULL or partitioning == NULL or local_vector == NULL let user know of catastrophe and exit */ if (!par_vector) { if (print_level) { hypre_printf("par_vector == NULL -- "); hypre_printf("hypre_IJVectorSetValuesPar\n"); hypre_printf("**** Vector storage is either unallocated or orphaned ****\n"); } hypre_error_in_arg(1); } if (!IJpartitioning) { if (print_level) { hypre_printf("IJpartitioning == NULL -- "); hypre_printf("hypre_IJVectorSetValuesPar\n"); hypre_printf("**** IJVector partitioning is either unallocated or orphaned ****\n"); } hypre_error_in_arg(1); } if (!local_vector) { if (print_level) { hypre_printf("local_vector == NULL -- "); hypre_printf("hypre_IJVectorSetValuesPar\n"); hypre_printf("**** Vector local data is either unallocated or orphaned ****\n"); } hypre_error_in_arg(1); } #ifdef HYPRE_NO_GLOBAL_PARTITION vec_start = IJpartitioning[0]; vec_stop = IJpartitioning[1]-1; #else vec_start = IJpartitioning[my_id]; vec_stop = IJpartitioning[my_id+1]-1; #endif if (vec_start > vec_stop) { if (print_level) { hypre_printf("vec_start > vec_stop -- "); hypre_printf("hypre_IJVectorSetValuesPar\n"); hypre_printf("**** This vector partitioning should not occur ****\n"); } hypre_error_in_arg(1); } /* Determine whether indices points to local indices only, and if not, store indices and values into auxiliary vector structure If indices == NULL, assume that num_values components are to be set in a block starting at vec_start. NOTE: If indices == NULL off processor values are ignored!!! */ data = hypre_VectorData(local_vector); if (indices) { HYPRE_Int current_num_elmts = hypre_AuxParVectorCurrentNumElmts(aux_vector); /*HYPRE_Int max_off_proc_elmts = hypre_AuxParVectorMaxOffProcElmts(aux_vector);*/ HYPRE_Int *off_proc_i = hypre_AuxParVectorOffProcI(aux_vector); /*double *off_proc_data = hypre_AuxParVectorOffProcData(aux_vector);*/ HYPRE_Int cancel_indx = hypre_AuxParVectorCancelIndx(aux_vector); HYPRE_Int ii; for (j = 0; j < num_values; j++) { i = indices[j]; if (i < vec_start || i > vec_stop) { for (ii = 0; ii < current_num_elmts; ii++) { if (i == off_proc_i[ii]) { off_proc_i[ii] = -1; cancel_indx++; } } hypre_AuxParVectorCancelIndx(aux_vector) = cancel_indx; } /* if elements outside processor boundaries, search for previous occurrences and cancel them */ /* if elements outside processor boundaries, store in off processor stash */ /*if (!max_off_proc_elmts) { max_off_proc_elmts = 100; hypre_AuxParVectorMaxOffProcElmts(aux_vector) = max_off_proc_elmts; hypre_AuxParVectorOffProcI(aux_vector) = hypre_CTAlloc(HYPRE_Int,max_off_proc_elmts); hypre_AuxParVectorOffProcData(aux_vector) = hypre_CTAlloc(double,max_off_proc_elmts); off_proc_i = hypre_AuxParVectorOffProcI(aux_vector); off_proc_data = hypre_AuxParVectorOffProcData(aux_vector); } else if (current_num_elmts + 1 > max_off_proc_elmts) { max_off_proc_elmts += 10; off_proc_i = hypre_TReAlloc(off_proc_i,HYPRE_Int,max_off_proc_elmts); off_proc_data = hypre_TReAlloc(off_proc_data,double, max_off_proc_elmts); hypre_AuxParVectorMaxOffProcElmts(aux_vector) = max_off_proc_elmts; hypre_AuxParVectorOffProcI(aux_vector) = off_proc_i; hypre_AuxParVectorOffProcData(aux_vector) = off_proc_data; } off_proc_i[current_num_elmts] = i; off_proc_data[current_num_elmts++] = values[j]; hypre_AuxParVectorCurrentNumElmts(aux_vector)=current_num_elmts; }*/ else /* local values are inserted into the vector */ { i -= vec_start; data[i] = values[j]; } } } else { if (num_values > vec_stop - vec_start + 1) { if (print_level) { hypre_printf("Warning! Indices beyond local range not identified!\n "); hypre_printf("Off processor values have been ignored!\n"); } num_values = vec_stop - vec_start +1; } for (j = 0; j < num_values; j++) data[j] = values[j]; } return hypre_error_flag; }
/****************************************************************************** * * hypre_IJVectorZeroValuesPar * * zeroes all local components of an IJVectorPar * *****************************************************************************/ HYPRE_Int hypre_IJVectorZeroValuesPar(hypre_IJVector *vector) { HYPRE_Int my_id; HYPRE_Int i, vec_start, vec_stop; double *data; hypre_ParVector *par_vector = hypre_IJVectorObject(vector); MPI_Comm comm = hypre_IJVectorComm(vector); HYPRE_Int *partitioning = hypre_ParVectorPartitioning(par_vector); hypre_Vector *local_vector = hypre_ParVectorLocalVector(par_vector); HYPRE_Int print_level = hypre_IJVectorPrintLevel(vector); hypre_MPI_Comm_rank(comm, &my_id); /* If par_vector == NULL or partitioning == NULL or local_vector == NULL let user know of catastrophe and exit */ if (!par_vector) { if (print_level) { hypre_printf("par_vector == NULL -- "); hypre_printf("hypre_IJVectorZeroValuesPar\n"); hypre_printf("**** Vector storage is either unallocated or orphaned ****\n"); } hypre_error_in_arg(1); } if (!partitioning) { if (print_level) { hypre_printf("partitioning == NULL -- "); hypre_printf("hypre_IJVectorZeroValuesPar\n"); hypre_printf("**** Vector partitioning is either unallocated or orphaned ****\n"); } hypre_error_in_arg(1); } if (!local_vector) { if (print_level) { hypre_printf("local_vector == NULL -- "); hypre_printf("hypre_IJVectorZeroValuesPar\n"); hypre_printf("**** Vector local data is either unallocated or orphaned ****\n"); } hypre_error_in_arg(1); } #ifdef HYPRE_NO_GLOBAL_PARTITION vec_start = partitioning[0]; vec_stop = partitioning[1]; #else vec_start = partitioning[my_id]; vec_stop = partitioning[my_id+1]; #endif if (vec_start > vec_stop) { if (print_level) { hypre_printf("vec_start > vec_stop -- "); hypre_printf("hypre_IJVectorZeroValuesPar\n"); hypre_printf("**** This vector partitioning should not occur ****\n"); } hypre_error_in_arg(1); } data = hypre_VectorData( local_vector ); for (i = 0; i < vec_stop - vec_start; i++) data[i] = 0.; return hypre_error_flag; }
int HYPRE_IJVectorCreate( MPI_Comm comm, HYPRE_BigInt jlower, HYPRE_BigInt jupper, HYPRE_IJVector *vector ) { hypre_IJVector *vec; int num_procs, my_id; HYPRE_BigInt *partitioning; #ifdef HYPRE_NO_GLOBAL_PARTITION HYPRE_BigInt row0, rowN; #else HYPRE_BigInt *recv_buf; HYPRE_BigInt *info; int i, i2; #endif vec = hypre_CTAlloc(hypre_IJVector, 1); if (!vec) { printf("Out of memory -- HYPRE_IJVectorCreate\n"); hypre_error(HYPRE_ERROR_MEMORY); return hypre_error_flag; } MPI_Comm_size(comm, &num_procs); MPI_Comm_rank(comm, &my_id); if (jlower > jupper+1 || jlower < 0) { hypre_error_in_arg(2); return hypre_error_flag; } if (jupper < -1) { hypre_error_in_arg(3); return hypre_error_flag; } #ifdef HYPRE_NO_GLOBAL_PARTITION partitioning = hypre_CTAlloc(HYPRE_BigInt, 2); partitioning[0] = jlower; partitioning[1] = jupper+1; /* now we need the global number of rows as well as the global first row index */ /* proc 0 has the first row */ if (my_id==0) { row0 = jlower; } MPI_Bcast(&row0, 1, MPI_HYPRE_BIG_INT, 0, comm); /* proc (num_procs-1) has the last row */ if (my_id == (num_procs-1)) { rowN = jupper; } MPI_Bcast(&rowN, 1, MPI_HYPRE_BIG_INT, num_procs-1, comm); hypre_IJVectorGlobalFirstRow(vec) = row0; hypre_IJVectorGlobalNumRows(vec) = rowN - row0 + 1; #else info = hypre_CTAlloc(HYPRE_BigInt,2); recv_buf = hypre_CTAlloc(HYPRE_BigInt, 2*num_procs); partitioning = hypre_CTAlloc(HYPRE_BigInt, num_procs+1); info[0] = jlower; info[1] = jupper; MPI_Allgather(info, 2, MPI_HYPRE_BIG_INT, recv_buf, 2, MPI_HYPRE_BIG_INT, comm); partitioning[0] = recv_buf[0]; for (i=0; i < num_procs-1; i++) { i2 = i+i; if (recv_buf[i2+1] != (recv_buf[i2+2]-1)) { printf("Inconsistent partitioning -- HYPRE_IJVectorCreate\n"); hypre_error(HYPRE_ERROR_GENERIC); return hypre_error_flag; } else partitioning[i+1] = recv_buf[i2+2]; } i2 = (num_procs-1)*2; partitioning[num_procs] = recv_buf[i2+1]+1; hypre_TFree(info); hypre_TFree(recv_buf); hypre_IJVectorGlobalFirstRow(vec) = partitioning[0]; hypre_IJVectorGlobalNumRows(vec)= partitioning[num_procs]-partitioning[0]; #endif hypre_IJVectorComm(vec) = comm; hypre_IJVectorPartitioning(vec) = partitioning; hypre_IJVectorObjectType(vec) = HYPRE_UNITIALIZED; hypre_IJVectorObject(vec) = NULL; hypre_IJVectorTranslator(vec) = NULL; *vector = (HYPRE_IJVector) vec; return hypre_error_flag; }