int32_t impl_bHYPRE_IJParCSRMatrix_SetDiagOffdSizes( /* in */ bHYPRE_IJParCSRMatrix self, /* in rarray[local_nrows] */ int32_t* diag_sizes, /* in rarray[local_nrows] */ int32_t* offdiag_sizes, /* in */ int32_t local_nrows, /* out */ sidl_BaseInterface *_ex) { *_ex = 0; { /* DO-NOT-DELETE splicer.begin(bHYPRE.IJParCSRMatrix.SetDiagOffdSizes) */ /* Insert the implementation of the SetDiagOffdSizes method here... */ int ierr=0; struct bHYPRE_IJParCSRMatrix__data * data; HYPRE_IJMatrix ij_A; data = bHYPRE_IJParCSRMatrix__get_data( self ); ij_A = data -> ij_A; ierr = HYPRE_IJMatrixSetDiagOffdSizes( ij_A, diag_sizes, offdiag_sizes ); return( ierr ); /* DO-NOT-DELETE splicer.end(bHYPRE.IJParCSRMatrix.SetDiagOffdSizes) */ } }
HYPRE_Int hypre_ParaSailsBuildIJMatrix(hypre_ParaSails obj, HYPRE_IJMatrix *pij_A) { hypre_ParaSails_struct *internal = (hypre_ParaSails_struct *) obj; ParaSails *ps = internal->ps; Matrix *mat = internal->ps->M; HYPRE_Int *diag_sizes, *offdiag_sizes, local_row, i, j; HYPRE_Int size; HYPRE_Int *col_inds; HYPRE_Real *values; HYPRE_IJMatrixCreate( ps->comm, ps->beg_row, ps->end_row, ps->beg_row, ps->end_row, pij_A ); HYPRE_IJMatrixSetObjectType( *pij_A, HYPRE_PARCSR ); diag_sizes = hypre_CTAlloc(HYPRE_Int, ps->end_row - ps->beg_row + 1); offdiag_sizes = hypre_CTAlloc(HYPRE_Int, ps->end_row - ps->beg_row + 1); local_row = 0; for (i=ps->beg_row; i<= ps->end_row; i++) { MatrixGetRow(mat, local_row, &size, &col_inds, &values); NumberingLocalToGlobal(ps->numb, size, col_inds, col_inds); for (j=0; j < size; j++) { if (col_inds[j] < ps->beg_row || col_inds[j] > ps->end_row) offdiag_sizes[local_row]++; else diag_sizes[local_row]++; } local_row++; } HYPRE_IJMatrixSetDiagOffdSizes( *pij_A, (const HYPRE_Int *) diag_sizes, (const HYPRE_Int *) offdiag_sizes ); hypre_TFree(diag_sizes); hypre_TFree(offdiag_sizes); HYPRE_IJMatrixInitialize( *pij_A ); local_row = 0; for (i=ps->beg_row; i<= ps->end_row; i++) { MatrixGetRow(mat, local_row, &size, &col_inds, &values); HYPRE_IJMatrixSetValues( *pij_A, 1, &size, &i, (const HYPRE_Int *) col_inds, (const HYPRE_Real *) values ); NumberingGlobalToLocal(ps->numb, size, col_inds, col_inds); local_row++; } HYPRE_IJMatrixAssemble( *pij_A ); return hypre_error_flag; }
inline void numfact(unsigned int ncol, int* I, int* loc2glob, int* J, K* C) { static_assert(std::is_same<double, K>::value, "Hypre only supports double-precision floating-point real numbers"); static_assert(S == 'G', "Hypre only supports nonsymmetric matrices"); HYPRE_IJMatrixCreate(DMatrix::_communicator, loc2glob[0], loc2glob[1], loc2glob[0], loc2glob[1], &_A); HYPRE_IJMatrixSetObjectType(_A, HYPRE_PARCSR); HYPRE_IJMatrixSetRowSizes(_A, I + 1); _local = ncol; int* rows = new int[3 * _local](); int* diag_sizes = rows + _local; int* offdiag_sizes = diag_sizes + _local; rows[0] = I[0]; for(unsigned int i = 0; i < _local; ++i) { std::for_each(J + rows[0], J + rows[0] + I[i + 1], [&](int& j) { (j < loc2glob[0] || loc2glob[1] < j) ? ++offdiag_sizes[i] : ++diag_sizes[i]; }); rows[0] += I[i + 1]; } HYPRE_IJMatrixSetDiagOffdSizes(_A, diag_sizes, offdiag_sizes); HYPRE_IJMatrixSetMaxOffProcElmts(_A, 0); HYPRE_IJMatrixInitialize(_A); std::iota(rows, rows + _local, loc2glob[0]); HYPRE_IJMatrixSetValues(_A, _local, I + 1, rows, J, C); HYPRE_IJMatrixAssemble(_A); HYPRE_IJVectorCreate(DMatrix::_communicator, loc2glob[0], loc2glob[1], &_b); HYPRE_IJVectorSetObjectType(_b, HYPRE_PARCSR); HYPRE_IJVectorInitialize(_b); HYPRE_IJVectorCreate(DMatrix::_communicator, loc2glob[0], loc2glob[1], &_x); HYPRE_IJVectorSetObjectType(_x, HYPRE_PARCSR); HYPRE_IJVectorInitialize(_x); delete [] rows; delete [] I; delete [] loc2glob; HYPRE_BoomerAMGCreate(_strategy == 1 ? &_solver : &_precond); HYPRE_BoomerAMGSetCoarsenType(_strategy == 1 ? _solver : _precond, 6); /* Falgout coarsening */ HYPRE_BoomerAMGSetRelaxType(_strategy == 1 ? _solver : _precond, 6); /* G-S/Jacobi hybrid relaxation */ HYPRE_BoomerAMGSetNumSweeps(_strategy == 1 ? _solver : _precond, 1); /* sweeps on each level */ HYPRE_BoomerAMGSetMaxLevels(_strategy == 1 ? _solver : _precond, 10); /* maximum number of levels */ HYPRE_ParCSRMatrix parcsr_A; HYPRE_IJMatrixGetObject(_A, reinterpret_cast<void**>(&parcsr_A)); HYPRE_ParVector par_b; HYPRE_IJVectorGetObject(_b, reinterpret_cast<void**>(&par_b)); HYPRE_ParVector par_x; HYPRE_IJVectorGetObject(_x, reinterpret_cast<void**>(&par_x)); if(_strategy == 1) { HYPRE_BoomerAMGSetTol(_solver, 1.0e-8); HYPRE_BoomerAMGSetMaxIter(_solver, 1000); HYPRE_BoomerAMGSetPrintLevel(_solver, 1); HYPRE_BoomerAMGSetup(_solver, parcsr_A, nullptr, nullptr); } else { HYPRE_BoomerAMGSetTol(_precond, 0.0); HYPRE_BoomerAMGSetMaxIter(_precond, 1); HYPRE_BoomerAMGSetPrintLevel(_precond, 1); if(_strategy == 2) { HYPRE_ParCSRPCGCreate(DMatrix::_communicator, &_solver); HYPRE_PCGSetMaxIter(_solver, 500); HYPRE_PCGSetTol(_solver, 1.0e-8); HYPRE_PCGSetTwoNorm(_solver, 1); HYPRE_PCGSetPrintLevel(_solver, 1); HYPRE_PCGSetLogging(_solver, 1); HYPRE_PCGSetPrecond(_solver, reinterpret_cast<HYPRE_PtrToSolverFcn>(HYPRE_BoomerAMGSolve), reinterpret_cast<HYPRE_PtrToSolverFcn>(HYPRE_BoomerAMGSetup), _precond); HYPRE_ParCSRPCGSetup(_solver, parcsr_A, par_b, par_x); } else { HYPRE_ParCSRFlexGMRESCreate(DMatrix::_communicator, &_solver); HYPRE_FlexGMRESSetKDim(_solver, 50); HYPRE_FlexGMRESSetMaxIter(_solver, 500); HYPRE_FlexGMRESSetTol(_solver, 1.0e-8); HYPRE_FlexGMRESSetPrintLevel(_solver, 1); HYPRE_FlexGMRESSetLogging(_solver, 1); HYPRE_FlexGMRESSetPrecond(_solver, reinterpret_cast<HYPRE_PtrToSolverFcn>(HYPRE_BoomerAMGSolve), reinterpret_cast<HYPRE_PtrToSolverFcn>(HYPRE_BoomerAMGSetup), _precond); HYPRE_ParCSRFlexGMRESSetup(_solver, parcsr_A, par_b, par_x); } } }
HYPRE_Int AmgCGCGraphAssemble (hypre_ParCSRMatrix *S,HYPRE_Int *vertexrange,HYPRE_Int *CF_marker,HYPRE_Int *CF_marker_offd,HYPRE_Int coarsen_type, HYPRE_IJMatrix *ijG) /* assemble a graph representing the connections between the grids * ================================================================================================ * S : the strength matrix * vertexrange : the parallel layout of the candidate coarse grid vertices * CF_marker, CF_marker_offd : the coarse/fine markers * coarsen_type : the coarsening type * ijG : the created graph * ================================================================================================*/ { HYPRE_Int ierr=0; HYPRE_Int i,/* ii,*/ip,j,jj,m,n,p; HYPRE_Int mpisize,mpirank; HYPRE_Real weight; MPI_Comm comm = hypre_ParCSRMatrixComm(S); /* hypre_MPI_Status status; */ HYPRE_IJMatrix ijmatrix; hypre_CSRMatrix *S_diag = hypre_ParCSRMatrixDiag (S); hypre_CSRMatrix *S_offd = hypre_ParCSRMatrixOffd (S); /* HYPRE_Int *S_i = hypre_CSRMatrixI(S_diag); */ /* HYPRE_Int *S_j = hypre_CSRMatrixJ(S_diag); */ HYPRE_Int *S_offd_i = hypre_CSRMatrixI(S_offd); HYPRE_Int *S_offd_j = NULL; HYPRE_Int num_variables = hypre_CSRMatrixNumRows (S_diag); HYPRE_Int num_cols_offd = hypre_CSRMatrixNumCols (S_offd); HYPRE_Int *col_map_offd = hypre_ParCSRMatrixColMapOffd (S); HYPRE_Int pointrange_start,pointrange_end; HYPRE_Int *pointrange,*pointrange_nonlocal,*pointrange_strong=NULL; HYPRE_Int vertexrange_start,vertexrange_end; HYPRE_Int *vertexrange_strong= NULL; HYPRE_Int *vertexrange_nonlocal; HYPRE_Int num_recvs,num_recvs_strong; HYPRE_Int *recv_procs,*recv_procs_strong=NULL; HYPRE_Int /* *zeros,*rownz,*/*rownz_diag,*rownz_offd; HYPRE_Int nz; HYPRE_Int nlocal; HYPRE_Int one=1; hypre_ParCSRCommPkg *comm_pkg = hypre_ParCSRMatrixCommPkg (S); hypre_MPI_Comm_size (comm,&mpisize); hypre_MPI_Comm_rank (comm,&mpirank); /* determine neighbor processors */ num_recvs = hypre_ParCSRCommPkgNumRecvs (comm_pkg); recv_procs = hypre_ParCSRCommPkgRecvProcs (comm_pkg); pointrange = hypre_ParCSRMatrixRowStarts (S); pointrange_nonlocal = hypre_CTAlloc (HYPRE_Int, 2*num_recvs); vertexrange_nonlocal = hypre_CTAlloc (HYPRE_Int, 2*num_recvs); #ifdef HYPRE_NO_GLOBAL_PARTITION { HYPRE_Int num_sends = hypre_ParCSRCommPkgNumSends (comm_pkg); HYPRE_Int *send_procs = hypre_ParCSRCommPkgSendProcs (comm_pkg); HYPRE_Int *int_buf_data = hypre_CTAlloc (HYPRE_Int,4*num_sends); HYPRE_Int *int_buf_data2 = int_buf_data + 2*num_sends; hypre_MPI_Request *sendrequest,*recvrequest; nlocal = vertexrange[1] - vertexrange[0]; pointrange_start = pointrange[0]; pointrange_end = pointrange[1]; vertexrange_start = vertexrange[0]; vertexrange_end = vertexrange[1]; sendrequest = hypre_CTAlloc (hypre_MPI_Request,2*(num_sends+num_recvs)); recvrequest = sendrequest+2*num_sends; for (i=0;i<num_recvs;i++) { hypre_MPI_Irecv (pointrange_nonlocal+2*i,2,HYPRE_MPI_INT,recv_procs[i],tag_pointrange,comm,&recvrequest[2*i]); hypre_MPI_Irecv (vertexrange_nonlocal+2*i,2,HYPRE_MPI_INT,recv_procs[i],tag_vertexrange,comm,&recvrequest[2*i+1]); } for (i=0;i<num_sends;i++) { int_buf_data[2*i] = pointrange_start; int_buf_data[2*i+1] = pointrange_end; int_buf_data2[2*i] = vertexrange_start; int_buf_data2[2*i+1] = vertexrange_end; hypre_MPI_Isend (int_buf_data+2*i,2,HYPRE_MPI_INT,send_procs[i],tag_pointrange,comm,&sendrequest[2*i]); hypre_MPI_Isend (int_buf_data2+2*i,2,HYPRE_MPI_INT,send_procs[i],tag_vertexrange,comm,&sendrequest[2*i+1]); } hypre_MPI_Waitall (2*(num_sends+num_recvs),sendrequest,hypre_MPI_STATUSES_IGNORE); hypre_TFree (int_buf_data); hypre_TFree (sendrequest); } #else nlocal = vertexrange[mpirank+1] - vertexrange[mpirank]; pointrange_start = pointrange[mpirank]; pointrange_end = pointrange[mpirank+1]; vertexrange_start = vertexrange[mpirank]; vertexrange_end = vertexrange[mpirank+1]; for (i=0;i<num_recvs;i++) { pointrange_nonlocal[2*i] = pointrange[recv_procs[i]]; pointrange_nonlocal[2*i+1] = pointrange[recv_procs[i]+1]; vertexrange_nonlocal[2*i] = vertexrange[recv_procs[i]]; vertexrange_nonlocal[2*i+1] = vertexrange[recv_procs[i]+1]; } #endif /* now we have the array recv_procs. However, it may contain too many entries as it is inherited from A. We now have to determine the subset which contains only the strongly connected neighbors */ if (num_cols_offd) { S_offd_j = hypre_CSRMatrixJ(S_offd); recv_procs_strong = hypre_CTAlloc (HYPRE_Int,num_recvs); memset (recv_procs_strong,0,num_recvs*sizeof(HYPRE_Int)); /* don't forget to shorten the pointrange and vertexrange arrays accordingly */ pointrange_strong = hypre_CTAlloc (HYPRE_Int,2*num_recvs); memset (pointrange_strong,0,2*num_recvs*sizeof(HYPRE_Int)); vertexrange_strong = hypre_CTAlloc (HYPRE_Int,2*num_recvs); memset (vertexrange_strong,0,2*num_recvs*sizeof(HYPRE_Int)); for (i=0;i<num_variables;i++) for (j=S_offd_i[i];j<S_offd_i[i+1];j++) { jj = col_map_offd[S_offd_j[j]]; for (p=0;p<num_recvs;p++) /* S_offd_j is NOT sorted! */ if (jj >= pointrange_nonlocal[2*p] && jj < pointrange_nonlocal[2*p+1]) break; #if 0 hypre_printf ("Processor %d, remote point %d on processor %d\n",mpirank,jj,recv_procs[p]); #endif recv_procs_strong [p]=1; } for (p=0,num_recvs_strong=0;p<num_recvs;p++) { if (recv_procs_strong[p]) { recv_procs_strong[num_recvs_strong]=recv_procs[p]; pointrange_strong[2*num_recvs_strong] = pointrange_nonlocal[2*p]; pointrange_strong[2*num_recvs_strong+1] = pointrange_nonlocal[2*p+1]; vertexrange_strong[2*num_recvs_strong] = vertexrange_nonlocal[2*p]; vertexrange_strong[2*num_recvs_strong+1] = vertexrange_nonlocal[2*p+1]; num_recvs_strong++; } } } else num_recvs_strong=0; hypre_TFree (pointrange_nonlocal); hypre_TFree (vertexrange_nonlocal); rownz_diag = hypre_CTAlloc (HYPRE_Int,2*nlocal); rownz_offd = rownz_diag + nlocal; for (p=0,nz=0;p<num_recvs_strong;p++) { nz += vertexrange_strong[2*p+1]-vertexrange_strong[2*p]; } for (m=0;m<nlocal;m++) { rownz_diag[m]=nlocal-1; rownz_offd[m]=nz; } HYPRE_IJMatrixCreate(comm, vertexrange_start, vertexrange_end-1, vertexrange_start, vertexrange_end-1, &ijmatrix); HYPRE_IJMatrixSetObjectType(ijmatrix, HYPRE_PARCSR); HYPRE_IJMatrixSetDiagOffdSizes (ijmatrix, rownz_diag, rownz_offd); HYPRE_IJMatrixInitialize(ijmatrix); hypre_TFree (rownz_diag); /* initialize graph */ weight = -1; for (m=vertexrange_start;m<vertexrange_end;m++) { for (p=0;p<num_recvs_strong;p++) { for (n=vertexrange_strong[2*p];n<vertexrange_strong[2*p+1];n++) { ierr = HYPRE_IJMatrixAddToValues (ijmatrix,1,&one,&m,&n,&weight); #if 0 if (ierr) hypre_printf ("Processor %d: error %d while initializing graphs at (%d, %d)\n",mpirank,ierr,m,n); #endif } } } /* weight graph */ for (i=0;i<num_variables;i++) { for (j=S_offd_i[i];j<S_offd_i[i+1];j++) { jj = S_offd_j[j]; /* jj is not a global index!!! */ /* determine processor */ for (p=0;p<num_recvs_strong;p++) if (col_map_offd[jj] >= pointrange_strong[2*p] && col_map_offd[jj] < pointrange_strong[2*p+1]) break; ip=recv_procs_strong[p]; /* loop over all coarse grids constructed on this processor domain */ for (m=vertexrange_start;m<vertexrange_end;m++) { /* loop over all coarse grids constructed on neighbor processor domain */ for (n=vertexrange_strong[2*p];n<vertexrange_strong[2*p+1];n++) { /* coarse grid counting inside gridpartition->local/gridpartition->nonlocal starts with one while counting inside range starts with zero */ if (CF_marker[i]-1==m && CF_marker_offd[jj]-1==n) /* C-C-coupling */ weight = -1; else if ( (CF_marker[i]-1==m && (CF_marker_offd[jj]==0 || CF_marker_offd[jj]-1!=n) ) || ( (CF_marker[i]==0 || CF_marker[i]-1!=m) && CF_marker_offd[jj]-1==n ) ) /* C-F-coupling */ weight = 0; else weight = -8; /* F-F-coupling */ ierr = HYPRE_IJMatrixAddToValues (ijmatrix,1,&one,&m,&n,&weight); #if 0 if (ierr) hypre_printf ("Processor %d: error %d while adding %lf to entry (%d, %d)\n",mpirank,ierr,weight,m,n); #endif } } } } /* assemble */ HYPRE_IJMatrixAssemble (ijmatrix); /*if (num_recvs_strong) {*/ hypre_TFree (recv_procs_strong); hypre_TFree (pointrange_strong); hypre_TFree (vertexrange_strong); /*} */ *ijG = ijmatrix; return (ierr); }