Add vector resizing functions (#829)

This PR adds hypre_SeqVectorResize and hypre_ParVectorResize for resizing sequential and parallel vectors, respectively. This is useful for block-Krylov solvers/eigensolvers using BoomerAMG and multi-component vectors.
This commit is contained in:
Victor A. Paludetto Magri 2023-02-08 18:14:32 -05:00 committed by GitHub
parent ddc548f906
commit 67d3fe4532
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 116 additions and 14 deletions

View File

@ -51,6 +51,7 @@ hypre_BoomerAMGSolve( void *amg_vdata,
HYPRE_Int j;
HYPRE_Int Solve_err_flag;
HYPRE_Int num_procs, my_id;
HYPRE_Int num_vectors;
HYPRE_Real alpha = 1.0;
HYPRE_Real beta = -1.0;
HYPRE_Real cycle_op_count;
@ -70,6 +71,9 @@ hypre_BoomerAMGSolve( void *amg_vdata,
HYPRE_Real ieee_check = 0.;
hypre_ParVector *Vtemp;
hypre_ParVector *Rtemp;
hypre_ParVector *Ptemp;
hypre_ParVector *Ztemp;
hypre_ParVector *Residual;
HYPRE_ANNOTATE_FUNC_BEGIN;
@ -97,18 +101,38 @@ hypre_BoomerAMGSolve( void *amg_vdata,
block_mode = hypre_ParAMGDataBlockMode(amg_data);
A_block_array = hypre_ParAMGDataABlockArray(amg_data);
Vtemp = hypre_ParAMGDataVtemp(amg_data);
Rtemp = hypre_ParAMGDataRtemp(amg_data);
Ptemp = hypre_ParAMGDataPtemp(amg_data);
Ztemp = hypre_ParAMGDataZtemp(amg_data);
num_vectors = hypre_ParVectorNumVectors(f);
A_array[0] = A;
F_array[0] = f;
U_array[0] = u;
/* Verify that the number of vectors held by f and u match */
if (hypre_ParVectorNumVectors(f) != hypre_ParVectorNumVectors(u))
if (hypre_ParVectorNumVectors(f) !=
hypre_ParVectorNumVectors(u))
{
hypre_error_w_msg(HYPRE_ERROR_GENERIC, "Error: num_vectors for RHS and LHS do not match!\n");
return hypre_error_flag;
}
/* Update work vectors */
hypre_ParVectorResize(Vtemp, num_vectors);
hypre_ParVectorResize(Rtemp, num_vectors);
hypre_ParVectorResize(Ptemp, num_vectors);
hypre_ParVectorResize(Ztemp, num_vectors);
if (amg_logging > 1)
{
hypre_ParVectorResize(Residual, num_vectors);
}
for (j = 1; j < num_levels; j++)
{
hypre_ParVectorResize(F_array[j], num_vectors);
hypre_ParVectorResize(U_array[j], num_vectors);
}
/*-----------------------------------------------------------------------
* Write the solver parameters
*-----------------------------------------------------------------------*/
@ -139,7 +163,6 @@ hypre_BoomerAMGSolve( void *amg_vdata,
hypre_printf("\n\nAMG SOLUTION INFO:\n");
}
/*-----------------------------------------------------------------------
* Compute initial fine-grid residual and print
*-----------------------------------------------------------------------*/
@ -148,7 +171,7 @@ hypre_BoomerAMGSolve( void *amg_vdata,
{
if ( amg_logging > 1 )
{
hypre_ParVectorCopy(F_array[0], Residual );
hypre_ParVectorCopy(F_array[0], Residual);
if (tol > 0)
{
hypre_ParCSRMatrixMatvec(alpha, A_array[0], U_array[0], beta, Residual);

View File

@ -1199,6 +1199,7 @@ HYPRE_Int hypre_ParVectorSetDataOwner ( hypre_ParVector *vector, HYPRE_Int owns_
HYPRE_Int hypre_ParVectorSetLocalSize ( hypre_ParVector *vector, HYPRE_Int local_size );
HYPRE_Int hypre_ParVectorSetNumVectors ( hypre_ParVector *vector, HYPRE_Int num_vectors );
HYPRE_Int hypre_ParVectorSetComponent ( hypre_ParVector *vector, HYPRE_Int component );
HYPRE_Int hypre_ParVectorResize ( hypre_ParVector *vector, HYPRE_Int num_vectors );
hypre_ParVector *hypre_ParVectorRead ( MPI_Comm comm, const char *file_name );
HYPRE_Int hypre_ParVectorPrint ( hypre_ParVector *vector, const char *file_name );
HYPRE_Int hypre_ParVectorSetConstantValues ( hypre_ParVector *v, HYPRE_Complex value );

View File

@ -18,12 +18,12 @@ HYPRE_Int hypre_FillResponseParToVectorAll(void*, HYPRE_Int, HYPRE_Int, void*, M
/*--------------------------------------------------------------------------
* hypre_ParVectorCreate
*
* If create is called and partitioning is NOT null, then it is assumed that it
* is array of length 2 containing the start row of the calling processor
* followed by the start row of the next processor - AHB 6/05
*--------------------------------------------------------------------------*/
/* If create is called and partitioning is NOT null, then it is assumed that it
is array of length 2 containing the start row of the calling processor
followed by the start row of the next processor - AHB 6/05 */
hypre_ParVector *
hypre_ParVectorCreate( MPI_Comm comm,
HYPRE_BigInt global_size,
@ -212,6 +212,22 @@ hypre_ParVectorSetNumVectors( hypre_ParVector *vector,
}
#endif
/*--------------------------------------------------------------------------
* hypre_ParVectorResize
*--------------------------------------------------------------------------*/
HYPRE_Int
hypre_ParVectorResize( hypre_ParVector *vector,
HYPRE_Int num_vectors )
{
if (vector)
{
hypre_SeqVectorResize(hypre_ParVectorLocalVector(vector), num_vectors);
}
return hypre_error_flag;
}
/*--------------------------------------------------------------------------
* hypre_ParVectorRead
*--------------------------------------------------------------------------*/
@ -311,6 +327,10 @@ hypre_ParVectorSetConstantValues( hypre_ParVector *v,
return hypre_SeqVectorSetConstantValues(v_local, value);
}
/*--------------------------------------------------------------------------
* hypre_ParVectorSetZeros
*--------------------------------------------------------------------------*/
HYPRE_Int
hypre_ParVectorSetZeros( hypre_ParVector *v )
{
@ -354,7 +374,8 @@ hypre_ParVectorCopy( hypre_ParVector *x,
/*--------------------------------------------------------------------------
* hypre_ParVectorCloneShallow
* returns a complete copy of a hypre_ParVector x - a shallow copy, re-using
*
* Returns a complete copy of a hypre_ParVector x - a shallow copy, re-using
* the partitioning and data arrays of x
*--------------------------------------------------------------------------*/
@ -375,6 +396,10 @@ hypre_ParVectorCloneShallow( hypre_ParVector *x )
return y;
}
/*--------------------------------------------------------------------------
* hypre_ParVectorCloneDeep_v2
*--------------------------------------------------------------------------*/
hypre_ParVector *
hypre_ParVectorCloneDeep_v2( hypre_ParVector *x, HYPRE_MemoryLocation memory_location )
{
@ -391,6 +416,10 @@ hypre_ParVectorCloneDeep_v2( hypre_ParVector *x, HYPRE_MemoryLocation memory_loc
return y;
}
/*--------------------------------------------------------------------------
* hypre_ParVectorMigrate
*--------------------------------------------------------------------------*/
HYPRE_Int
hypre_ParVectorMigrate(hypre_ParVector *x, HYPRE_MemoryLocation memory_location)
{
@ -414,7 +443,6 @@ hypre_ParVectorMigrate(hypre_ParVector *x, HYPRE_MemoryLocation memory_location)
return hypre_error_flag;
}
/*--------------------------------------------------------------------------
* hypre_ParVectorScale
*--------------------------------------------------------------------------*/
@ -490,6 +518,7 @@ hypre_ParVectorInnerProd( hypre_ParVector *x,
/*--------------------------------------------------------------------------
* hypre_ParVectorElmdivpy
*
* y = y + x ./ b [MATLAB Notation]
*--------------------------------------------------------------------------*/
@ -507,6 +536,7 @@ hypre_ParVectorElmdivpy( hypre_ParVector *x,
/*--------------------------------------------------------------------------
* hypre_ParVectorElmdivpyMarked
*
* y[i] += x[i] / b[i] where marker[i] == marker_val
*--------------------------------------------------------------------------*/
@ -525,8 +555,9 @@ hypre_ParVectorElmdivpyMarked( hypre_ParVector *x,
}
/*--------------------------------------------------------------------------
* hypre_VectorToParVector:
* generates a ParVector from a Vector on proc 0 and distributes the pieces
* hypre_VectorToParVector
*
* Generates a ParVector from a Vector on proc 0 and distributes the pieces
* to the other procs in comm
*--------------------------------------------------------------------------*/
@ -648,8 +679,9 @@ hypre_VectorToParVector ( MPI_Comm comm,
}
/*--------------------------------------------------------------------------
* hypre_ParVectorToVectorAll:
* generates a Vector on every proc which has a piece of the data
* hypre_ParVectorToVectorAll
*
* Generates a Vector on every proc which has a piece of the data
* from a ParVector on several procs in comm,
* vec_starts needs to contain the partitioning across all procs in comm
*--------------------------------------------------------------------------*/

View File

@ -546,6 +546,7 @@ HYPRE_Int hypre_ParVectorSetDataOwner ( hypre_ParVector *vector, HYPRE_Int owns_
HYPRE_Int hypre_ParVectorSetLocalSize ( hypre_ParVector *vector, HYPRE_Int local_size );
HYPRE_Int hypre_ParVectorSetNumVectors ( hypre_ParVector *vector, HYPRE_Int num_vectors );
HYPRE_Int hypre_ParVectorSetComponent ( hypre_ParVector *vector, HYPRE_Int component );
HYPRE_Int hypre_ParVectorResize ( hypre_ParVector *vector, HYPRE_Int num_vectors );
hypre_ParVector *hypre_ParVectorRead ( MPI_Comm comm, const char *file_name );
HYPRE_Int hypre_ParVectorPrint ( hypre_ParVector *vector, const char *file_name );
HYPRE_Int hypre_ParVectorSetConstantValues ( hypre_ParVector *v, HYPRE_Complex value );

View File

@ -237,6 +237,7 @@ HYPRE_Int hypre_SeqVectorInitialize_v2( hypre_Vector *vector,
HYPRE_Int hypre_SeqVectorInitialize ( hypre_Vector *vector );
HYPRE_Int hypre_SeqVectorSetDataOwner ( hypre_Vector *vector, HYPRE_Int owns_data );
HYPRE_Int hypre_SeqVectorSetSize ( hypre_Vector *vector, HYPRE_Int size );
HYPRE_Int hypre_SeqVectorResize ( hypre_Vector *vector, HYPRE_Int num_vectors_in );
hypre_Vector *hypre_SeqVectorRead ( char *file_name );
HYPRE_Int hypre_SeqVectorPrint ( hypre_Vector *vector, char *file_name );
HYPRE_Int hypre_SeqVectorSetConstantValues ( hypre_Vector *v, HYPRE_Complex value );

View File

@ -509,6 +509,7 @@ HYPRE_Int hypre_SeqVectorInitialize_v2( hypre_Vector *vector,
HYPRE_Int hypre_SeqVectorInitialize ( hypre_Vector *vector );
HYPRE_Int hypre_SeqVectorSetDataOwner ( hypre_Vector *vector, HYPRE_Int owns_data );
HYPRE_Int hypre_SeqVectorSetSize ( hypre_Vector *vector, HYPRE_Int size );
HYPRE_Int hypre_SeqVectorResize ( hypre_Vector *vector, HYPRE_Int num_vectors_in );
hypre_Vector *hypre_SeqVectorRead ( char *file_name );
HYPRE_Int hypre_SeqVectorPrint ( hypre_Vector *vector, char *file_name );
HYPRE_Int hypre_SeqVectorSetConstantValues ( hypre_Vector *v, HYPRE_Complex value );

View File

@ -159,7 +159,50 @@ hypre_SeqVectorSetSize( hypre_Vector *vector,
}
/*--------------------------------------------------------------------------
* ReadVector
* hypre_SeqVectorResize
*
* Resize a sequential vector when changing its number of components.
*--------------------------------------------------------------------------*/
HYPRE_Int
hypre_SeqVectorResize( hypre_Vector *vector,
HYPRE_Int num_vectors_in )
{
HYPRE_Int method = hypre_VectorMultiVecStorageMethod(vector);
HYPRE_Int size = hypre_VectorSize(vector);
HYPRE_Int num_vectors = hypre_VectorNumVectors(vector);
HYPRE_Int total_size = num_vectors * size;
HYPRE_Int total_size_in = num_vectors_in * size;
/* Reallocate data array */
if (total_size_in > total_size)
{
hypre_VectorData(vector) = hypre_TReAlloc_v2(hypre_VectorData(vector),
HYPRE_Complex,
total_size,
HYPRE_Complex,
total_size_in,
hypre_VectorMemoryLocation(vector));
}
/* Update vector info */
hypre_VectorNumVectors(vector) = num_vectors_in;
if (method == 0)
{
hypre_VectorVectorStride(vector) = size;
hypre_VectorIndexStride(vector) = 1;
}
else if (method == 1)
{
hypre_VectorVectorStride(vector) = 1;
hypre_VectorIndexStride(vector) = num_vectors;
}
return hypre_error_flag;
}
/*--------------------------------------------------------------------------
* hypre_SeqVectorRead
*--------------------------------------------------------------------------*/
hypre_Vector *