Modifications to support AddToValues and SetValues for off-processor
rows in a vector. This modification required adding the assumed partition object to the parallel vector data structure. Also added the hypre error checking where appropriate.
This commit is contained in:
parent
2c3344527d
commit
fd7a8823a5
@ -428,9 +428,8 @@ hypre_IJMatrixGetValuesParCSR( hypre_IJMatrix *matrix,
|
||||
|
||||
if (assemble_flag == 0)
|
||||
{
|
||||
hypre_error(HYPRE_ERROR_GENERIC);
|
||||
hypre_error_in_arg(1);
|
||||
printf("Error! Matrix not assembled yet! HYPRE_IJMatrixGetValues\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
#ifdef HYPRE_NO_GLOBAL_PARTITION
|
||||
@ -481,9 +480,8 @@ hypre_IJMatrixGetValuesParCSR( hypre_IJMatrix *matrix,
|
||||
offd_i[row_local+1]-offd_i[row_local];
|
||||
if (counter[i]+row_size > counter[nrows])
|
||||
{
|
||||
hypre_error(HYPRE_ERROR_MEMORY);
|
||||
hypre_error_in_arg(1);
|
||||
printf ("Error! Not enough memory! HYPRE_IJMatrixGetValues\n");
|
||||
exit(1);
|
||||
}
|
||||
if (ncols[i] < row_size)
|
||||
warning = 1;
|
||||
@ -645,9 +643,8 @@ hypre_IJMatrixSetValuesParCSR( hypre_IJMatrix *matrix,
|
||||
#endif
|
||||
if (nrows < 0)
|
||||
{
|
||||
hypre_error(HYPRE_ERROR_GENERIC);
|
||||
hypre_error_in_arg(2);
|
||||
printf("Error! nrows negative! HYPRE_IJMatrixSetValues\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (hypre_IJMatrixAssembleFlag(matrix))
|
||||
@ -695,7 +692,6 @@ hypre_IJMatrixSetValuesParCSR( hypre_IJMatrix *matrix,
|
||||
hypre_error(HYPRE_ERROR_GENERIC);
|
||||
printf (" row %d too long! \n", row);
|
||||
return hypre_error_flag;
|
||||
/* return -1; */
|
||||
}
|
||||
|
||||
pos_diag = diag_i[row_local];
|
||||
@ -717,7 +713,6 @@ hypre_IJMatrixSetValuesParCSR( hypre_IJMatrix *matrix,
|
||||
printf (" Error, element %d %d does not exist\n",
|
||||
row, cols[indx]);
|
||||
return hypre_error_flag;
|
||||
/* return -1; */
|
||||
}
|
||||
for (j=pos_offd; j < len_offd; j++)
|
||||
{
|
||||
@ -734,7 +729,6 @@ hypre_IJMatrixSetValuesParCSR( hypre_IJMatrix *matrix,
|
||||
printf (" Error, element %d %d does not exist\n",
|
||||
row, cols[indx]);
|
||||
return hypre_error_flag;
|
||||
/* return -1; */
|
||||
}
|
||||
not_found = 1;
|
||||
}
|
||||
@ -2726,7 +2720,7 @@ hypre_FillResponseIJOffProcValsDouble(void *p_recv_contact_buf,
|
||||
/*check to see if we need to allocate more space in send_proc_obj for vec starts*/
|
||||
if (send_proc_obj->length == send_proc_obj->storage_length)
|
||||
{
|
||||
send_proc_obj->storage_length +=20; /*add space for 10 more contact*/
|
||||
send_proc_obj->storage_length +=20; /*add space for 20 more contact*/
|
||||
send_proc_obj->vec_starts = hypre_TReAlloc(send_proc_obj->vec_starts,int,
|
||||
send_proc_obj->storage_length + 1);
|
||||
}
|
||||
|
||||
@ -46,14 +46,6 @@ hypre_IJVectorCreatePar(hypre_IJVector *vector, int *IJpartitioning)
|
||||
{
|
||||
MPI_Comm comm = hypre_IJVectorComm(vector);
|
||||
|
||||
#if 0
|
||||
if (par_vector)
|
||||
{
|
||||
printf("Creating a ParVector object will orphan an old one -- ");
|
||||
printf("hypreIJVectorCreatePar\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
int num_procs, jmin, global_n, *partitioning, j;
|
||||
MPI_Comm_size(comm, &num_procs);
|
||||
@ -84,7 +76,7 @@ hypre_IJVectorCreatePar(hypre_IJVector *vector, int *IJpartitioning)
|
||||
hypre_IJVectorObject(vector) = hypre_ParVectorCreate(comm,
|
||||
global_n, (int *) partitioning);
|
||||
|
||||
return 0;
|
||||
return hypre_error_flag;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
@ -114,7 +106,8 @@ hypre_IJVectorInitializePar(hypre_IJVector *vector)
|
||||
hypre_AuxParVector *aux_vector = hypre_IJVectorTranslator(vector);
|
||||
int *partitioning = hypre_ParVectorPartitioning(par_vector);
|
||||
hypre_Vector *local_vector = hypre_ParVectorLocalVector(par_vector);
|
||||
int my_id, ierr = 0;
|
||||
int my_id;
|
||||
|
||||
MPI_Comm comm = hypre_IJVectorComm(vector);
|
||||
|
||||
MPI_Comm_rank(comm,&my_id);
|
||||
@ -123,7 +116,7 @@ hypre_IJVectorInitializePar(hypre_IJVector *vector)
|
||||
{
|
||||
printf("No ParVector partitioning for initialization -- ");
|
||||
printf("hypre_IJVectorInitializePar\n");
|
||||
exit(1);
|
||||
hypre_error_in_arg(1);
|
||||
}
|
||||
|
||||
#ifdef HYPRE_NO_GLOBAL_PARTITION
|
||||
@ -135,16 +128,16 @@ hypre_IJVectorInitializePar(hypre_IJVector *vector)
|
||||
#endif
|
||||
|
||||
|
||||
ierr += hypre_ParVectorInitialize(par_vector);
|
||||
hypre_ParVectorInitialize(par_vector);
|
||||
|
||||
if (!aux_vector)
|
||||
{
|
||||
ierr = hypre_AuxParVectorCreate(&aux_vector);
|
||||
hypre_AuxParVectorCreate(&aux_vector);
|
||||
hypre_IJVectorTranslator(vector) = aux_vector;
|
||||
}
|
||||
ierr += hypre_AuxParVectorInitialize(aux_vector);
|
||||
hypre_AuxParVectorInitialize(aux_vector);
|
||||
|
||||
return ierr;
|
||||
return hypre_error_flag;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
@ -157,17 +150,17 @@ int
|
||||
hypre_IJVectorSetMaxOffProcElmtsPar(hypre_IJVector *vector,
|
||||
int max_off_proc_elmts)
|
||||
{
|
||||
int ierr = 0;
|
||||
|
||||
hypre_AuxParVector *aux_vector;
|
||||
|
||||
aux_vector = hypre_IJVectorTranslator(vector);
|
||||
if (!aux_vector)
|
||||
{
|
||||
ierr = hypre_AuxParVectorCreate(&aux_vector);
|
||||
hypre_AuxParVectorCreate(&aux_vector);
|
||||
hypre_IJVectorTranslator(vector) = aux_vector;
|
||||
}
|
||||
hypre_AuxParVectorMaxOffProcElmts(aux_vector) = max_off_proc_elmts;
|
||||
return ierr;
|
||||
return hypre_error_flag;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
@ -183,7 +176,6 @@ int
|
||||
hypre_IJVectorDistributePar(hypre_IJVector *vector,
|
||||
const int *vec_starts)
|
||||
{
|
||||
int ierr = 0;
|
||||
|
||||
hypre_ParVector *old_vector = hypre_IJVectorObject(vector);
|
||||
hypre_ParVector *par_vector;
|
||||
@ -193,7 +185,7 @@ hypre_IJVectorDistributePar(hypre_IJVector *vector,
|
||||
printf("old_vector == NULL -- ");
|
||||
printf("hypre_IJVectorDistributePar\n");
|
||||
printf("**** Vector storage is either unallocated or orphaned ****\n");
|
||||
exit(1);
|
||||
hypre_error_in_arg(1);
|
||||
}
|
||||
|
||||
par_vector = hypre_VectorToParVector(hypre_ParVectorComm(old_vector),
|
||||
@ -204,14 +196,14 @@ hypre_IJVectorDistributePar(hypre_IJVector *vector,
|
||||
printf("par_vector == NULL -- ");
|
||||
printf("hypre_IJVectorDistributePar\n");
|
||||
printf("**** Vector storage is unallocated ****\n");
|
||||
exit(1);
|
||||
hypre_error_in_arg(1);
|
||||
}
|
||||
|
||||
ierr = hypre_ParVectorDestroy(old_vector);
|
||||
hypre_ParVectorDestroy(old_vector);
|
||||
|
||||
hypre_IJVectorObject(vector) = par_vector;
|
||||
|
||||
return ierr;
|
||||
return hypre_error_flag;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
@ -224,7 +216,6 @@ hypre_IJVectorDistributePar(hypre_IJVector *vector,
|
||||
int
|
||||
hypre_IJVectorZeroValuesPar(hypre_IJVector *vector)
|
||||
{
|
||||
int ierr = 0;
|
||||
int my_id;
|
||||
int i, vec_start, vec_stop;
|
||||
double *data;
|
||||
@ -244,21 +235,21 @@ hypre_IJVectorZeroValuesPar(hypre_IJVector *vector)
|
||||
printf("par_vector == NULL -- ");
|
||||
printf("hypre_IJVectorZeroValuesPar\n");
|
||||
printf("**** Vector storage is either unallocated or orphaned ****\n");
|
||||
exit(1);
|
||||
hypre_error_in_arg(1);
|
||||
}
|
||||
if (!partitioning)
|
||||
{
|
||||
printf("partitioning == NULL -- ");
|
||||
printf("hypre_IJVectorZeroValuesPar\n");
|
||||
printf("**** Vector partitioning is either unallocated or orphaned ****\n");
|
||||
exit(1);
|
||||
hypre_error_in_arg(1);
|
||||
}
|
||||
if (!local_vector)
|
||||
{
|
||||
printf("local_vector == NULL -- ");
|
||||
printf("hypre_IJVectorZeroValuesPar\n");
|
||||
printf("**** Vector local data is either unallocated or orphaned ****\n");
|
||||
exit(1);
|
||||
hypre_error_in_arg(1);
|
||||
}
|
||||
|
||||
#ifdef HYPRE_NO_GLOBAL_PARTITION
|
||||
@ -275,14 +266,15 @@ hypre_IJVectorZeroValuesPar(hypre_IJVector *vector)
|
||||
printf("vec_start > vec_stop -- ");
|
||||
printf("hypre_IJVectorZeroValuesPar\n");
|
||||
printf("**** This vector partitioning should not occur ****\n");
|
||||
exit(1);
|
||||
hypre_error_in_arg(1);
|
||||
|
||||
}
|
||||
|
||||
data = hypre_VectorData( local_vector );
|
||||
for (i = 0; i < vec_stop - vec_start; i++)
|
||||
data[i] = 0.;
|
||||
|
||||
return ierr;
|
||||
return hypre_error_flag;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
@ -298,7 +290,7 @@ hypre_IJVectorSetValuesPar(hypre_IJVector *vector,
|
||||
const int *indices,
|
||||
const double *values )
|
||||
{
|
||||
int ierr = 0;
|
||||
|
||||
int my_id;
|
||||
int i, j, vec_start, vec_stop;
|
||||
double *data;
|
||||
@ -322,21 +314,21 @@ hypre_IJVectorSetValuesPar(hypre_IJVector *vector,
|
||||
printf("par_vector == NULL -- ");
|
||||
printf("hypre_IJVectorSetValuesPar\n");
|
||||
printf("**** Vector storage is either unallocated or orphaned ****\n");
|
||||
exit(1);
|
||||
hypre_error_in_arg(1);
|
||||
}
|
||||
if (!IJpartitioning)
|
||||
{
|
||||
printf("IJpartitioning == NULL -- ");
|
||||
printf("hypre_IJVectorSetValuesPar\n");
|
||||
printf("**** IJVector partitioning is either unallocated or orphaned ****\n");
|
||||
exit(1);
|
||||
hypre_error_in_arg(1);
|
||||
}
|
||||
if (!local_vector)
|
||||
{
|
||||
printf("local_vector == NULL -- ");
|
||||
printf("hypre_IJVectorSetValuesPar\n");
|
||||
printf("**** Vector local data is either unallocated or orphaned ****\n");
|
||||
exit(1);
|
||||
hypre_error_in_arg(1);
|
||||
}
|
||||
|
||||
#ifdef HYPRE_NO_GLOBAL_PARTITION
|
||||
@ -352,7 +344,7 @@ hypre_IJVectorSetValuesPar(hypre_IJVector *vector,
|
||||
printf("vec_start > vec_stop -- ");
|
||||
printf("hypre_IJVectorSetValuesPar\n");
|
||||
printf("**** This vector partitioning should not occur ****\n");
|
||||
exit(1);
|
||||
hypre_error_in_arg(1);
|
||||
}
|
||||
|
||||
/* Determine whether indices points to local indices only,
|
||||
@ -426,7 +418,7 @@ hypre_IJVectorSetValuesPar(hypre_IJVector *vector,
|
||||
data[j] = values[j];
|
||||
}
|
||||
|
||||
return ierr;
|
||||
return hypre_error_flag;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
@ -442,7 +434,6 @@ hypre_IJVectorAddToValuesPar(hypre_IJVector *vector,
|
||||
const int *indices,
|
||||
const double *values )
|
||||
{
|
||||
int ierr = 0;
|
||||
int my_id;
|
||||
int i, j, vec_start, vec_stop;
|
||||
double *data;
|
||||
@ -466,21 +457,21 @@ hypre_IJVectorAddToValuesPar(hypre_IJVector *vector,
|
||||
printf("par_vector == NULL -- ");
|
||||
printf("hypre_IJVectorAddToValuesPar\n");
|
||||
printf("**** Vector storage is either unallocated or orphaned ****\n");
|
||||
exit(1);
|
||||
hypre_error_in_arg(1);
|
||||
}
|
||||
if (!IJpartitioning)
|
||||
{
|
||||
printf("IJpartitioning == NULL -- ");
|
||||
printf("hypre_IJVectorAddToValuesPar\n");
|
||||
printf("**** IJVector partitioning is either unallocated or orphaned ****\n");
|
||||
exit(1);
|
||||
hypre_error_in_arg(1);
|
||||
}
|
||||
if (!local_vector)
|
||||
{
|
||||
printf("local_vector == NULL -- ");
|
||||
printf("hypre_IJVectorAddToValuesPar\n");
|
||||
printf("**** Vector local data is either unallocated or orphaned ****\n");
|
||||
exit(1);
|
||||
hypre_error_in_arg(1);
|
||||
}
|
||||
|
||||
#ifdef HYPRE_NO_GLOBAL_PARTITION
|
||||
@ -496,7 +487,7 @@ hypre_IJVectorAddToValuesPar(hypre_IJVector *vector,
|
||||
printf("vec_start > vec_stop -- ");
|
||||
printf("hypre_IJVectorAddToValuesPar\n");
|
||||
printf("**** This vector partitioning should not occur ****\n");
|
||||
exit(1);
|
||||
hypre_error_in_arg(1);
|
||||
}
|
||||
|
||||
/* Determine whether indices points to local indices only,
|
||||
@ -587,7 +578,7 @@ hypre_IJVectorAddToValuesPar(hypre_IJVector *vector,
|
||||
data[j] += values[j];
|
||||
}
|
||||
|
||||
return ierr;
|
||||
return hypre_error_flag;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
@ -611,21 +602,21 @@ hypre_IJVectorAssemblePar(hypre_IJVector *vector)
|
||||
printf("par_vector == NULL -- ");
|
||||
printf("hypre_IJVectorAssemblePar\n");
|
||||
printf("**** Vector storage is either unallocated or orphaned ****\n");
|
||||
exit(1);
|
||||
hypre_error_in_arg(1);
|
||||
}
|
||||
if (!IJpartitioning)
|
||||
{
|
||||
printf("IJpartitioning == NULL -- ");
|
||||
printf("hypre_IJVectorAssemblePar\n");
|
||||
printf("**** IJVector partitioning is either unallocated or orphaned ****\n");
|
||||
exit(1);
|
||||
hypre_error_in_arg(1);
|
||||
}
|
||||
if (!partitioning)
|
||||
{
|
||||
printf("partitioning == NULL -- ");
|
||||
printf("hypre_IJVectorAssemblePar\n");
|
||||
printf("**** ParVector partitioning is either unallocated or orphaned ****\n");
|
||||
exit(1);
|
||||
hypre_error_in_arg(1);
|
||||
}
|
||||
|
||||
if (aux_vector)
|
||||
@ -650,7 +641,7 @@ hypre_IJVectorAssemblePar(hypre_IJVector *vector)
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return hypre_error_flag;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
@ -666,10 +657,10 @@ hypre_IJVectorGetValuesPar(hypre_IJVector *vector,
|
||||
const int *indices,
|
||||
double *values )
|
||||
{
|
||||
int ierr = 0;
|
||||
int my_id;
|
||||
int i, j, vec_start, vec_stop;
|
||||
double *data;
|
||||
int ierr = 0;
|
||||
|
||||
int *IJpartitioning = hypre_IJVectorPartitioning(vector);
|
||||
hypre_ParVector *par_vector = hypre_IJVectorObject(vector);
|
||||
@ -689,21 +680,21 @@ hypre_IJVectorGetValuesPar(hypre_IJVector *vector,
|
||||
printf("par_vector == NULL -- ");
|
||||
printf("hypre_IJVectorGetValuesPar\n");
|
||||
printf("**** Vector storage is either unallocated or orphaned ****\n");
|
||||
exit(1);
|
||||
hypre_error_in_arg(1);
|
||||
}
|
||||
if (!IJpartitioning)
|
||||
{
|
||||
printf("IJpartitioning == NULL -- ");
|
||||
printf("hypre_IJVectorGetValuesPar\n");
|
||||
printf("**** IJVector partitioning is either unallocated or orphaned ****\n");
|
||||
exit(1);
|
||||
hypre_error_in_arg(1);
|
||||
}
|
||||
if (!local_vector)
|
||||
{
|
||||
printf("local_vector == NULL -- ");
|
||||
printf("hypre_IJVectorGetValuesPar\n");
|
||||
printf("**** Vector local data is either unallocated or orphaned ****\n");
|
||||
exit(1);
|
||||
hypre_error_in_arg(1);
|
||||
}
|
||||
|
||||
#ifdef HYPRE_NO_GLOBAL_PARTITION
|
||||
@ -719,7 +710,7 @@ hypre_IJVectorGetValuesPar(hypre_IJVector *vector,
|
||||
printf("vec_start > vec_stop -- ");
|
||||
printf("hypre_IJVectorGetValuesPar\n");
|
||||
printf("**** This vector partitioning should not occur ****\n");
|
||||
exit(1);
|
||||
hypre_error_in_arg(1);
|
||||
}
|
||||
|
||||
/* Determine whether indices points to local indices only,
|
||||
@ -741,7 +732,7 @@ hypre_IJVectorGetValuesPar(hypre_IJVector *vector,
|
||||
printf("indices beyond local range -- ");
|
||||
printf("hypre_IJVectorGetValuesPar\n");
|
||||
printf("**** Indices specified are unusable ****\n");
|
||||
exit(1);
|
||||
hypre_error_in_arg(3);
|
||||
}
|
||||
|
||||
data = hypre_VectorData(local_vector);
|
||||
@ -760,9 +751,21 @@ hypre_IJVectorGetValuesPar(hypre_IJVector *vector,
|
||||
values[j] = data[j];
|
||||
}
|
||||
|
||||
return ierr;
|
||||
return hypre_error_flag;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
||||
* hypre_IJVectorAssembleOffProcValsPar
|
||||
|
||||
* This is for handling set and get values calls to off-proc. entries -
|
||||
* it is called from assemble. There is an alternate version for
|
||||
* when the assumed partition is being used.
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef HYPRE_NO_GLOBAL_PARTITION
|
||||
|
||||
int
|
||||
hypre_IJVectorAssembleOffProcValsPar( hypre_IJVector *vector,
|
||||
int max_off_proc_elmts,
|
||||
@ -770,9 +773,8 @@ hypre_IJVectorAssembleOffProcValsPar( hypre_IJVector *vector,
|
||||
int *off_proc_i,
|
||||
double *off_proc_data)
|
||||
{
|
||||
int ierr = 0;
|
||||
MPI_Comm comm = hypre_IJMatrixComm(vector);
|
||||
hypre_ParVector *par_vector = hypre_IJMatrixObject(vector);
|
||||
MPI_Comm comm = hypre_IJVectorComm(vector);
|
||||
hypre_ParVector *par_vector = hypre_IJVectorObject(vector);
|
||||
MPI_Request *requests;
|
||||
MPI_Status *status;
|
||||
int i, j, j2, row;
|
||||
@ -993,5 +995,421 @@ hypre_IJVectorAssembleOffProcValsPar( hypre_IJVector *vector,
|
||||
hypre_TFree(recv_i);
|
||||
hypre_TFree(recv_data);
|
||||
|
||||
return ierr;
|
||||
return hypre_error_flag;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
|
||||
/* assumed partition version */
|
||||
|
||||
|
||||
int
|
||||
hypre_IJVectorAssembleOffProcValsPar( hypre_IJVector *vector,
|
||||
int max_off_proc_elmts,
|
||||
int current_num_elmts,
|
||||
int *off_proc_i,
|
||||
double *off_proc_data)
|
||||
{
|
||||
|
||||
int myid, global_num_rows;
|
||||
int i, j, in, k;
|
||||
int proc_id, last_proc, prev_id, tmp_id;
|
||||
int max_response_size;
|
||||
int ex_num_contacts = 0;
|
||||
int range_start, range_end;
|
||||
int storage;
|
||||
int indx;
|
||||
int row, num_ranges, row_count;
|
||||
int num_recvs;
|
||||
int counter, upper_bound;
|
||||
int num_real_procs;
|
||||
int first_index;
|
||||
|
||||
int *row_list=NULL;
|
||||
int *a_proc_id=NULL, *orig_order=NULL;
|
||||
int *real_proc_id = NULL, *us_real_proc_id = NULL;
|
||||
int *ex_contact_procs = NULL, *ex_contact_vec_starts = NULL;
|
||||
int *recv_starts=NULL;
|
||||
int *response_buf = NULL, *response_buf_starts=NULL;
|
||||
int *num_rows_per_proc = NULL;
|
||||
|
||||
double *ex_contact_buf=NULL;
|
||||
double *recv_data = NULL;
|
||||
double *vector_data;
|
||||
double value;
|
||||
|
||||
hypre_DataExchangeResponse response_obj1, response_obj2;
|
||||
hypre_ProcListElements send_proc_obj_d;
|
||||
|
||||
MPI_Comm comm = hypre_IJVectorComm(vector);
|
||||
hypre_ParVector *par_vector = hypre_IJVectorObject(vector);
|
||||
|
||||
hypre_IJAssumedPart *apart;
|
||||
|
||||
|
||||
MPI_Comm_rank(comm, &myid);
|
||||
|
||||
global_num_rows = hypre_ParVectorGlobalSize(par_vector);
|
||||
|
||||
/* verify that we have created the assumed partition */
|
||||
|
||||
if (hypre_ParVectorAssumedPartition(par_vector) == NULL)
|
||||
{
|
||||
hypre_ParVectorCreateAssumedPartition(par_vector);
|
||||
}
|
||||
apart = hypre_ParVectorAssumedPartition(par_vector);
|
||||
|
||||
|
||||
|
||||
/* get the assumed processor id for each row */
|
||||
a_proc_id = hypre_CTAlloc(int, current_num_elmts);
|
||||
orig_order = hypre_CTAlloc(int, current_num_elmts);
|
||||
real_proc_id = hypre_CTAlloc(int, current_num_elmts);
|
||||
row_list = hypre_CTAlloc(int, current_num_elmts);
|
||||
|
||||
if (current_num_elmts > 0)
|
||||
{
|
||||
for (i=0; i < current_num_elmts; i++)
|
||||
{
|
||||
row = off_proc_i[i];
|
||||
if (row < 0) row = -row-1;
|
||||
row_list[i] = row;
|
||||
hypre_GetAssumedPartitionProcFromRow (row, global_num_rows, &proc_id);
|
||||
a_proc_id[i] = proc_id;
|
||||
orig_order[i] = i;
|
||||
}
|
||||
|
||||
/* now we need to find the actual order of each row - sort on row -
|
||||
this will result in proc ids sorted also...*/
|
||||
|
||||
hypre_qsort3i(row_list, a_proc_id, orig_order, 0, current_num_elmts -1);
|
||||
|
||||
/* calculate the number of contacts */
|
||||
ex_num_contacts = 1;
|
||||
last_proc = a_proc_id[0];
|
||||
for (i=1; i < current_num_elmts; i++)
|
||||
{
|
||||
if (a_proc_id[i] > last_proc)
|
||||
{
|
||||
ex_num_contacts++;
|
||||
last_proc = a_proc_id[i];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* now we will go through a create a contact list - need to contact
|
||||
assumed processors and find out who the actual row owner is - we
|
||||
will contact with a range (2 numbers) */
|
||||
|
||||
|
||||
|
||||
|
||||
ex_contact_procs = hypre_CTAlloc(int, ex_num_contacts);
|
||||
ex_contact_vec_starts = hypre_CTAlloc(int, ex_num_contacts+1);
|
||||
ex_contact_buf = hypre_CTAlloc(double, ex_num_contacts*2);
|
||||
|
||||
|
||||
counter = 0;
|
||||
range_end = -1;
|
||||
for (i=0; i< current_num_elmts; i++)
|
||||
{
|
||||
if (row_list[i] > range_end)
|
||||
{
|
||||
/* assumed proc */
|
||||
proc_id = a_proc_id[i];
|
||||
|
||||
/* end of prev. range */
|
||||
if (counter > 0) ex_contact_buf[counter*2 - 1] = row_list[i-1];
|
||||
|
||||
/*start new range*/
|
||||
ex_contact_procs[counter] = proc_id;
|
||||
ex_contact_vec_starts[counter] = counter*2;
|
||||
ex_contact_buf[counter*2] = row_list[i];
|
||||
counter++;
|
||||
|
||||
hypre_GetAssumedPartitionRowRange(proc_id, global_num_rows,
|
||||
&range_start, &range_end);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*finish the starts*/
|
||||
ex_contact_vec_starts[counter] = counter*2;
|
||||
/*finish the last range*/
|
||||
if (counter > 0)
|
||||
ex_contact_buf[counter*2 - 1] = row_list[current_num_elmts - 1];
|
||||
|
||||
|
||||
|
||||
/*create response object - can use same fill response as used in the commpkg
|
||||
routine */
|
||||
response_obj1.fill_response = hypre_RangeFillResponseIJDetermineRecvProcs;
|
||||
response_obj1.data1 = apart; /* this is necessary so we can fill responses*/
|
||||
response_obj1.data2 = NULL;
|
||||
|
||||
max_response_size = 6; /* 6 means we can fit 3 ranges*/
|
||||
|
||||
|
||||
hypre_DataExchangeList(ex_num_contacts, ex_contact_procs,
|
||||
ex_contact_buf, ex_contact_vec_starts, sizeof(int),
|
||||
sizeof(int), &response_obj1, max_response_size, 4,
|
||||
comm, (void**) &response_buf, &response_buf_starts);
|
||||
|
||||
|
||||
/* now response_buf contains
|
||||
a proc_id followed by an upper bound for the range. */
|
||||
|
||||
|
||||
|
||||
hypre_TFree(ex_contact_procs);
|
||||
hypre_TFree(ex_contact_buf);
|
||||
hypre_TFree(ex_contact_vec_starts);
|
||||
|
||||
hypre_TFree(a_proc_id);
|
||||
|
||||
/* too low */
|
||||
|
||||
|
||||
/*how many ranges were returned?*/
|
||||
num_ranges = response_buf_starts[ex_num_contacts];
|
||||
num_ranges = num_ranges/2;
|
||||
|
||||
|
||||
prev_id = -1;
|
||||
j = 0;
|
||||
counter = 0;
|
||||
num_real_procs = 0;
|
||||
|
||||
|
||||
/* loop through ranges - create a list of actual processor ids*/
|
||||
for (i=0; i<num_ranges; i++)
|
||||
{
|
||||
upper_bound = response_buf[i*2+1];
|
||||
counter = 0;
|
||||
tmp_id = response_buf[i*2];
|
||||
|
||||
/* loop through row_list entries - counting how many are in the range */
|
||||
while (row_list[j] <= upper_bound && j < current_num_elmts)
|
||||
{
|
||||
real_proc_id[j] = tmp_id;
|
||||
j++;
|
||||
counter++;
|
||||
}
|
||||
if (counter > 0 && tmp_id != prev_id)
|
||||
{
|
||||
num_real_procs++;
|
||||
}
|
||||
prev_id = tmp_id;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* now we have the list of real procesors ids (real_proc_id) -
|
||||
and the number of distinct ones -
|
||||
so now we can set up data to be sent - we have int and double data.
|
||||
(row number and value) - we will convert everything to double*/
|
||||
|
||||
|
||||
/*first find out how many elements to send per proc - so we can do
|
||||
storage */
|
||||
|
||||
ex_contact_procs = hypre_CTAlloc(int, num_real_procs);
|
||||
num_rows_per_proc = hypre_CTAlloc(int, num_real_procs);
|
||||
|
||||
counter = 0;
|
||||
|
||||
if (num_real_procs > 0 )
|
||||
{
|
||||
ex_contact_procs[0] = real_proc_id[0];
|
||||
num_rows_per_proc[0] = 1;
|
||||
|
||||
for (i=1; i < current_num_elmts; i++) /* loop through real procs - these are sorted
|
||||
(row_list is sorted also)*/
|
||||
{
|
||||
if (real_proc_id[i] == ex_contact_procs[counter]) /* same processor */
|
||||
{
|
||||
num_rows_per_proc[counter] += 1; /*another row */
|
||||
}
|
||||
else /* new processor */
|
||||
{
|
||||
counter++;
|
||||
ex_contact_procs[counter] = real_proc_id[i];
|
||||
num_rows_per_proc[counter] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* calculate total storage and make vec_starts arrays */
|
||||
storage = 0;
|
||||
ex_contact_vec_starts = hypre_CTAlloc(int, num_real_procs + 1);
|
||||
ex_contact_vec_starts[0] = -1;
|
||||
|
||||
for (i=0; i < num_real_procs; i++)
|
||||
{
|
||||
storage += 1 + 2* num_rows_per_proc[i];
|
||||
ex_contact_vec_starts[i+1] = -storage-1; /* need negative for next loop */
|
||||
}
|
||||
|
||||
ex_contact_buf = hypre_CTAlloc (double, storage);
|
||||
|
||||
|
||||
|
||||
/* set up data to be sent to send procs */
|
||||
/* for each proc, ex_contact_buf_d contains #rows, row #, data, ect. */
|
||||
|
||||
|
||||
/* un-sort real_proc_id - we want to access data arrays in order */
|
||||
|
||||
us_real_proc_id = hypre_CTAlloc(int, current_num_elmts);
|
||||
for (i=0; i < current_num_elmts; i++)
|
||||
{
|
||||
us_real_proc_id[orig_order[i]] = real_proc_id[i];
|
||||
}
|
||||
hypre_TFree(real_proc_id);
|
||||
|
||||
|
||||
|
||||
prev_id = -1;
|
||||
for (i=0; i < current_num_elmts; i++)
|
||||
{
|
||||
proc_id = us_real_proc_id[i];
|
||||
row = off_proc_i[i]; /*can't use row list[i] - you loose the negative signs that
|
||||
differentiate add/set values */
|
||||
/* find position of this processor */
|
||||
indx = hypre_BinarySearch(ex_contact_procs, proc_id, num_real_procs);
|
||||
in = ex_contact_vec_starts[indx];
|
||||
|
||||
if (in < 0) /* first time for this processor - add the number of rows to the buffer */
|
||||
{
|
||||
in = -in - 1;
|
||||
ex_contact_buf[in++] = (double) num_rows_per_proc[indx];
|
||||
}
|
||||
|
||||
ex_contact_buf[in++] = (double) row;
|
||||
ex_contact_buf[in++] = off_proc_data[i]; /* value */
|
||||
|
||||
|
||||
/* increment the indexes to keep track of where we are - fix later */
|
||||
ex_contact_vec_starts[indx] = in;
|
||||
|
||||
}
|
||||
|
||||
/* some clean up */
|
||||
|
||||
hypre_TFree(response_buf);
|
||||
hypre_TFree(response_buf_starts);
|
||||
|
||||
hypre_TFree(us_real_proc_id);
|
||||
hypre_TFree(orig_order);
|
||||
hypre_TFree(row_list);
|
||||
hypre_TFree(num_rows_per_proc);
|
||||
|
||||
|
||||
for (i=num_real_procs; i > 0; i--)
|
||||
{
|
||||
ex_contact_vec_starts[i] = ex_contact_vec_starts[i-1];
|
||||
}
|
||||
|
||||
ex_contact_vec_starts[0] = 0;
|
||||
|
||||
|
||||
|
||||
/* now send the data */
|
||||
|
||||
/***********************************/
|
||||
/* now get the info in send_proc_obj_d */
|
||||
|
||||
|
||||
/* the response we expect is just a confirmation*/
|
||||
response_buf = NULL;
|
||||
response_buf_starts = NULL;
|
||||
|
||||
/*build the response object*/
|
||||
|
||||
/* use the send_proc_obj for the info kept from contacts */
|
||||
/*estimate inital storage allocation */
|
||||
|
||||
send_proc_obj_d.length = 0;
|
||||
send_proc_obj_d.storage_length = num_real_procs + 5;
|
||||
send_proc_obj_d.id = NULL; /* don't care who sent it to us */
|
||||
send_proc_obj_d.vec_starts = hypre_CTAlloc(int, send_proc_obj_d.storage_length + 1);
|
||||
send_proc_obj_d.vec_starts[0] = 0;
|
||||
send_proc_obj_d.element_storage_length = storage + 20;
|
||||
send_proc_obj_d.d_elements = hypre_CTAlloc(double, send_proc_obj_d.element_storage_length);
|
||||
|
||||
response_obj2.fill_response = hypre_FillResponseIJOffProcValsDouble;
|
||||
response_obj2.data1 = NULL;
|
||||
response_obj2.data2 = &send_proc_obj_d;
|
||||
|
||||
max_response_size = 0;
|
||||
|
||||
hypre_DataExchangeList(num_real_procs, ex_contact_procs,
|
||||
ex_contact_buf, ex_contact_vec_starts, sizeof(double),
|
||||
sizeof(int), &response_obj2, max_response_size, 5,
|
||||
comm, (void **) &response_buf, &response_buf_starts);
|
||||
|
||||
|
||||
|
||||
|
||||
/***********************************/
|
||||
|
||||
|
||||
hypre_TFree(response_buf);
|
||||
hypre_TFree(response_buf_starts);
|
||||
|
||||
hypre_TFree(ex_contact_procs);
|
||||
hypre_TFree(ex_contact_buf);
|
||||
hypre_TFree(ex_contact_vec_starts);
|
||||
|
||||
|
||||
/* Now we can unpack the send_proc_objects and either set or add to
|
||||
the vector data */
|
||||
|
||||
num_recvs = send_proc_obj_d.length;
|
||||
|
||||
/* alias */
|
||||
recv_data = send_proc_obj_d.d_elements;
|
||||
recv_starts = send_proc_obj_d.vec_starts;
|
||||
|
||||
vector_data = hypre_VectorData(hypre_ParVectorLocalVector(par_vector));
|
||||
first_index = hypre_ParVectorFirstIndex(par_vector);
|
||||
|
||||
|
||||
for (i=0; i < num_recvs; i++)
|
||||
{
|
||||
/* get the number of rows from the this recv */
|
||||
indx = recv_starts[i];
|
||||
row_count = (int) recv_data[indx++];
|
||||
|
||||
for (j=0; j < row_count; j++) /* for each row: unpack info */
|
||||
{
|
||||
|
||||
row = (int) recv_data[indx++]; /* row number*/
|
||||
value = recv_data[indx++];
|
||||
if (row < 0) /* add */
|
||||
{
|
||||
row = -row-1;
|
||||
k = row - first_index;
|
||||
vector_data[k] += value;
|
||||
}
|
||||
else /* set */
|
||||
{
|
||||
k = row - first_index;
|
||||
vector_data[k] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
hypre_TFree(send_proc_obj_d.d_elements);
|
||||
hypre_TFree(send_proc_obj_d.vec_starts);
|
||||
|
||||
|
||||
return hypre_error_flag;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Loading…
Reference in New Issue
Block a user