Skip to content

Commit

Permalink
Add MGR restriction helper (#1037)
Browse files Browse the repository at this point in the history
Add hypre_MGRBuildRFromW for building classical restriction operators R = [-Wr  I] from an input matrix Wr
  • Loading branch information
victorapm authored Feb 1, 2024
1 parent 9be7307 commit b51f691
Show file tree
Hide file tree
Showing 4 changed files with 144 additions and 13 deletions.
5 changes: 4 additions & 1 deletion src/parcsr_ls/_hypre_parcsr_ls.h
Original file line number Diff line number Diff line change
Expand Up @@ -3701,7 +3701,7 @@ HYPRE_Int hypre_MGRGetNumIterations( void *mgr_vdata, HYPRE_Int *num_iterations
HYPRE_Int hypre_MGRGetFinalRelativeResidualNorm( void *mgr_vdata, HYPRE_Real *res_norm );
HYPRE_Int hypre_MGRGetCoarseGridConvergenceFactor( void *mgr_data, HYPRE_Real *conv_factor );

/* par_mgr.c */
/* par_mgr_interp.c */
HYPRE_Int hypre_MGRBuildInterp( hypre_ParCSRMatrix *A, hypre_ParCSRMatrix *A_FF,
hypre_ParCSRMatrix *A_FC, HYPRE_Int *CF_marker,
hypre_ParCSRMatrix *S, HYPRE_BigInt *num_cpts_global,
Expand Down Expand Up @@ -3740,6 +3740,9 @@ HYPRE_Int hypre_MGRGetAcfCPR( hypre_ParCSRMatrix *A, HYPRE_Int blk_size,
HYPRE_Int *c_marker, HYPRE_Int *f_marker,
hypre_ParCSRMatrix **A_CF_ptr );
HYPRE_Int hypre_MGRTruncateAcfCPR( hypre_ParCSRMatrix *A_CF, hypre_ParCSRMatrix **A_CF_new_ptr );
HYPRE_Int hypre_MGRBuildRFromW( HYPRE_Int *C_map, HYPRE_Int *F_map, HYPRE_BigInt *row_starts_R,
HYPRE_BigInt *col_starts_R, hypre_ParCSRMatrix *W,
hypre_ParCSRMatrix **R_ptr );

/* par_mgr_coarsen.c */
HYPRE_Int hypre_MGRCoarseParms( MPI_Comm comm, HYPRE_Int num_rows, hypre_IntArray *CF_marker,
Expand Down
11 changes: 0 additions & 11 deletions src/parcsr_ls/par_mgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,6 @@
//#include "dsuperlu.h"
//#endif

#if defined(HYPRE_USING_GPU)
void hypre_NoGPUSupport(char *option)
{
char msg[256];
hypre_sprintf(msg, "Error: Chosen %s option is not currently supported on GPU\n\n", option);
hypre_printf("%s ", msg);
// hypre_error_w_msg(1, msg);
hypre_MPI_Abort(hypre_MPI_COMM_WORLD, -1);
}
#endif

/* Need to define these hypre_lapack protos here instead of including _hypre_lapack.h to avoid conflicts with
* dsuperlu.h on some lapack functions. Alternative is to move superLU related functions to a separate file.
*/
Expand Down
136 changes: 136 additions & 0 deletions src/parcsr_ls/par_mgr_interp.c
Original file line number Diff line number Diff line change
Expand Up @@ -2375,3 +2375,139 @@ hypre_MGRTruncateAcfCPR(hypre_ParCSRMatrix *A_CF,

return hypre_error_flag;
}

/*--------------------------------------------------------------------------
* hypre_MGRBuildRFromWHost
*
* Constructs a classical restriction operator as R = [-W I].
*--------------------------------------------------------------------------*/

HYPRE_Int
hypre_MGRBuildRFromWHost(HYPRE_Int *C_map,
HYPRE_Int *F_map,
hypre_ParCSRMatrix *W,
hypre_ParCSRMatrix *R)
{
/* Input matrix variables */
hypre_CSRMatrix *W_diag = hypre_ParCSRMatrixDiag(W);
HYPRE_Int *W_diag_i = hypre_CSRMatrixI(W_diag);
HYPRE_Int *W_diag_j = hypre_CSRMatrixJ(W_diag);
HYPRE_Complex *W_diag_a = hypre_CSRMatrixData(W_diag);
HYPRE_Int W_diag_num_rows = hypre_CSRMatrixNumRows(W_diag);

/* Output matrix */
hypre_CSRMatrix *R_diag = hypre_ParCSRMatrixDiag(R);
HYPRE_Int *R_diag_i = hypre_CSRMatrixI(R_diag);
HYPRE_Int *R_diag_j = hypre_CSRMatrixJ(R_diag);
HYPRE_Complex *R_diag_a = hypre_CSRMatrixData(R_diag);

/* Local variables */
HYPRE_Int i, j, nnz_diag;
HYPRE_Real one = 1.0;

R_diag_i[0] = nnz_diag = 0;
for (i = 0; i < W_diag_num_rows; i++)
{
/* Set CF connections */
for (j = W_diag_i[i]; j < W_diag_i[i + 1]; j++)
{
R_diag_j[nnz_diag] = F_map[W_diag_j[j]];
R_diag_a[nnz_diag] = - W_diag_a[j];
nnz_diag++;
}

/* Set CC connection */
R_diag_j[nnz_diag] = C_map[i];
R_diag_a[nnz_diag] = one;
nnz_diag++;

/* Update row pointer */
R_diag_i[i + 1] = nnz_diag;
}

return hypre_error_flag;
}

/*--------------------------------------------------------------------------
* hypre_MGRBuildRFromW
*
* Constructs a classical restriction operator as R = [-W I].
*--------------------------------------------------------------------------*/

HYPRE_Int
hypre_MGRBuildRFromW(HYPRE_Int *C_map,
HYPRE_Int *F_map,
HYPRE_BigInt *row_starts_R,
HYPRE_BigInt *col_starts_R,
hypre_ParCSRMatrix *W,
hypre_ParCSRMatrix **R_ptr)
{
/* Input matrix variables */
MPI_Comm comm = hypre_ParCSRMatrixComm(W);
HYPRE_BigInt num_rows_W = hypre_ParCSRMatrixGlobalNumRows(W);
HYPRE_BigInt num_cols_W = hypre_ParCSRMatrixGlobalNumCols(W);
HYPRE_MemoryLocation memory_location_W = hypre_ParCSRMatrixMemoryLocation(W);

hypre_CSRMatrix *W_diag = hypre_ParCSRMatrixDiag(W);
HYPRE_Int W_diag_num_rows = hypre_CSRMatrixNumRows(W_diag);
HYPRE_Int W_diag_nnz = hypre_CSRMatrixNumNonzeros(W_diag);

hypre_CSRMatrix *W_offd = hypre_ParCSRMatrixOffd(W);
HYPRE_Int W_offd_num_cols = hypre_CSRMatrixNumCols(W_offd);
HYPRE_Int W_offd_nnz = hypre_CSRMatrixNumNonzeros(W_offd);

/* Output matrix */
hypre_ParCSRMatrix *R;
HYPRE_BigInt num_rows_R = num_rows_W;
HYPRE_BigInt num_cols_R = num_cols_W + num_rows_W;
HYPRE_Int num_nonzeros_diag = W_diag_nnz + W_diag_num_rows;
HYPRE_Int num_nonzeros_offd = W_offd_nnz;

/* Sanity checks */
if (W_offd_nnz > 0 || W_offd_num_cols > 0)
{
*R_ptr = NULL;

hypre_error_w_msg(HYPRE_ERROR_GENERIC, "Not implemented for matrices with nonzero offd");
return hypre_error_flag;
}

/*-----------------------------------------------------------------------
* Create and initialize output matrix
*-----------------------------------------------------------------------*/

R = hypre_ParCSRMatrixCreate(comm, num_rows_R, num_cols_R,
row_starts_R, col_starts_R, W_offd_num_cols,
num_nonzeros_diag, num_nonzeros_offd);
hypre_ParCSRMatrixInitialize_v2(R, memory_location_W);

/*-----------------------------------------------------------------------
* Fill matrix entries
*-----------------------------------------------------------------------*/

#if defined (HYPRE_USING_GPU)
HYPRE_ExecutionPolicy exec = hypre_GetExecPolicy1(memory_location_W);

if (exec == HYPRE_EXEC_DEVICE)
{
/* TODO (VPM): Implement hypre_MGRBuildRFromWDevice */
hypre_ParCSRMatrixMigrate(W, HYPRE_MEMORY_HOST);
hypre_ParCSRMatrixMigrate(R, HYPRE_MEMORY_HOST);
hypre_MGRBuildRFromWHost(C_map, F_map, W, R);
hypre_ParCSRMatrixMigrate(W, HYPRE_MEMORY_DEVICE);
hypre_ParCSRMatrixMigrate(R, HYPRE_MEMORY_DEVICE);
}
else
#endif
{
hypre_MGRBuildRFromWHost(C_map, F_map, W, R);
}

/* Setup communication package */
hypre_MatvecCommPkgCreate(R);

/* Set output pointer */
*R_ptr = R;

return hypre_error_flag;
}
5 changes: 4 additions & 1 deletion src/parcsr_ls/protos.h
Original file line number Diff line number Diff line change
Expand Up @@ -2248,7 +2248,7 @@ HYPRE_Int hypre_MGRGetNumIterations( void *mgr_vdata, HYPRE_Int *num_iterations
HYPRE_Int hypre_MGRGetFinalRelativeResidualNorm( void *mgr_vdata, HYPRE_Real *res_norm );
HYPRE_Int hypre_MGRGetCoarseGridConvergenceFactor( void *mgr_data, HYPRE_Real *conv_factor );

/* par_mgr.c */
/* par_mgr_interp.c */
HYPRE_Int hypre_MGRBuildInterp( hypre_ParCSRMatrix *A, hypre_ParCSRMatrix *A_FF,
hypre_ParCSRMatrix *A_FC, HYPRE_Int *CF_marker,
hypre_ParCSRMatrix *S, HYPRE_BigInt *num_cpts_global,
Expand Down Expand Up @@ -2287,6 +2287,9 @@ HYPRE_Int hypre_MGRGetAcfCPR( hypre_ParCSRMatrix *A, HYPRE_Int blk_size,
HYPRE_Int *c_marker, HYPRE_Int *f_marker,
hypre_ParCSRMatrix **A_CF_ptr );
HYPRE_Int hypre_MGRTruncateAcfCPR( hypre_ParCSRMatrix *A_CF, hypre_ParCSRMatrix **A_CF_new_ptr );
HYPRE_Int hypre_MGRBuildRFromW( HYPRE_Int *C_map, HYPRE_Int *F_map, HYPRE_BigInt *row_starts_R,
HYPRE_BigInt *col_starts_R, hypre_ParCSRMatrix *W,
hypre_ParCSRMatrix **R_ptr );

/* par_mgr_coarsen.c */
HYPRE_Int hypre_MGRCoarseParms( MPI_Comm comm, HYPRE_Int num_rows, hypre_IntArray *CF_marker,
Expand Down

0 comments on commit b51f691

Please sign in to comment.