1af0996ceSBarry Smith #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 27807a1faSBarry Smith 3cc1836a6SJunchao Zhang #include <../src/mat/impls/aij/seq/aij.h> 4cc1836a6SJunchao Zhang #include <../src/mat/impls/aij/mpi/mpiaij.h> 5cc1836a6SJunchao Zhang 69de2952eSStefano Zampini PetscErrorCode MatSetBlockSizes_Default(Mat mat, PetscInt rbs, PetscInt cbs) 7d71ae5a4SJacob Faibussowitsch { 846533700Sstefano_zampini PetscFunctionBegin; 93ba16761SJacob Faibussowitsch if (!mat->preallocated) PetscFunctionReturn(PETSC_SUCCESS); 10aed4548fSBarry Smith PetscCheck(mat->rmap->bs <= 0 || mat->rmap->bs == rbs, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Cannot change row block size %" PetscInt_FMT " to %" PetscInt_FMT, mat->rmap->bs, rbs); 11aed4548fSBarry Smith PetscCheck(mat->cmap->bs <= 0 || mat->cmap->bs == cbs, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Cannot change column block size %" PetscInt_FMT " to %" PetscInt_FMT, mat->cmap->bs, cbs); 123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1346533700Sstefano_zampini } 1446533700Sstefano_zampini 159de2952eSStefano Zampini PetscErrorCode MatShift_Basic(Mat Y, PetscScalar a) 16d71ae5a4SJacob Faibussowitsch { 17cc1836a6SJunchao Zhang PetscInt i, start, end, oldValA = 0, oldValB = 0; 187d68702bSBarry Smith PetscScalar alpha = a; 197d68702bSBarry Smith PetscBool prevoption; 20cc1836a6SJunchao Zhang PetscBool isSeqAIJDerived, isMPIAIJDerived; // all classes sharing SEQAIJHEADER or MPIAIJHEADER 21cc1836a6SJunchao Zhang Mat A = NULL, B = NULL; 227d68702bSBarry Smith 237d68702bSBarry Smith PetscFunctionBegin; 249566063dSJacob Faibussowitsch PetscCall(MatGetOption(Y, MAT_NO_OFF_PROC_ENTRIES, &prevoption)); 259566063dSJacob Faibussowitsch PetscCall(MatSetOption(Y, MAT_NO_OFF_PROC_ENTRIES, PETSC_TRUE)); 26cc1836a6SJunchao Zhang PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)Y, &isSeqAIJDerived, MATSEQAIJ, MATSEQBAIJ, MATSEQSBAIJ, "")); 27cc1836a6SJunchao Zhang PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)Y, &isMPIAIJDerived, MATMPIAIJ, MATMPIBAIJ, MATMPISBAIJ, "")); 28cc1836a6SJunchao Zhang 29cc1836a6SJunchao Zhang if (isSeqAIJDerived) A = Y; 30cc1836a6SJunchao Zhang else if (isMPIAIJDerived) { 31cc1836a6SJunchao Zhang Mat_MPIAIJ *mpiaij = (Mat_MPIAIJ *)Y->data; 32cc1836a6SJunchao Zhang A = mpiaij->A; 33cc1836a6SJunchao Zhang B = mpiaij->B; 34cc1836a6SJunchao Zhang } 35cc1836a6SJunchao Zhang 36cc1836a6SJunchao Zhang if (A) { 37f4f49eeaSPierre Jolivet oldValA = ((Mat_SeqAIJ *)A->data)->nonew; 38f4f49eeaSPierre Jolivet ((Mat_SeqAIJ *)A->data)->nonew = 0; // so that new nonzero locations are allowed 39cc1836a6SJunchao Zhang } 40cc1836a6SJunchao Zhang if (B) { 41f4f49eeaSPierre Jolivet oldValB = ((Mat_SeqAIJ *)B->data)->nonew; 42f4f49eeaSPierre Jolivet ((Mat_SeqAIJ *)B->data)->nonew = 0; 43cc1836a6SJunchao Zhang } 44cc1836a6SJunchao Zhang 459566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(Y, &start, &end)); 467d68702bSBarry Smith for (i = start; i < end; i++) { 4748a46eb9SPierre Jolivet if (i < Y->cmap->N) PetscCall(MatSetValues(Y, 1, &i, 1, &i, &alpha, ADD_VALUES)); 48ab6153dcSStefano Zampini } 499566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(Y, MAT_FINAL_ASSEMBLY)); 509566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(Y, MAT_FINAL_ASSEMBLY)); 519566063dSJacob Faibussowitsch PetscCall(MatSetOption(Y, MAT_NO_OFF_PROC_ENTRIES, prevoption)); 52f4f49eeaSPierre Jolivet if (A) ((Mat_SeqAIJ *)A->data)->nonew = oldValA; 53f4f49eeaSPierre Jolivet if (B) ((Mat_SeqAIJ *)B->data)->nonew = oldValB; 543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 557d68702bSBarry Smith } 567d68702bSBarry Smith 5705869f15SSatish Balay /*@ 5869dd0797SLois Curfman McInnes MatCreate - Creates a matrix where the type is determined 5911a5261eSBarry Smith from either a call to `MatSetType()` or from the options database 602920cce0SJacob Faibussowitsch with a call to `MatSetFromOptions()`. 6183e1b59cSLois Curfman McInnes 62d083f849SBarry Smith Collective 63cb13003dSBarry Smith 64f69a0ea3SMatthew Knepley Input Parameter: 65f69a0ea3SMatthew Knepley . comm - MPI communicator 667807a1faSBarry Smith 677807a1faSBarry Smith Output Parameter: 68dc401e71SLois Curfman McInnes . A - the matrix 69e0b365e2SLois Curfman McInnes 70273d9f13SBarry Smith Options Database Keys: 7111a5261eSBarry Smith + -mat_type seqaij - `MATSEQAIJ` type, uses `MatCreateSeqAIJ()` 7211a5261eSBarry Smith . -mat_type mpiaij - `MATMPIAIJ` type, uses `MatCreateAIJ()` 7311a5261eSBarry Smith . -mat_type seqdense - `MATSEQDENSE`, uses `MatCreateSeqDense()` 7411a5261eSBarry Smith . -mat_type mpidense - `MATMPIDENSE` type, uses `MatCreateDense()` 7511a5261eSBarry Smith . -mat_type seqbaij - `MATSEQBAIJ` type, uses `MatCreateSeqBAIJ()` 7611a5261eSBarry Smith - -mat_type mpibaij - `MATMPIBAIJ` type, uses `MatCreateBAIJ()` 77e0b365e2SLois Curfman McInnes 782ef1f0ffSBarry Smith See the manpages for particular formats (e.g., `MATSEQAIJ`) 7983e1b59cSLois Curfman McInnes for additional format-specific options. 80e0b365e2SLois Curfman McInnes 81273d9f13SBarry Smith Level: beginner 82273d9f13SBarry Smith 832920cce0SJacob Faibussowitsch Notes: 842920cce0SJacob Faibussowitsch The default matrix type is `MATAIJ`, using the routines `MatCreateSeqAIJ()` or 852920cce0SJacob Faibussowitsch `MatCreateAIJ()` if you do not set a type in the options database. If you never call 862920cce0SJacob Faibussowitsch `MatSetType()` or `MatSetFromOptions()` it will generate an error when you try to use the 872920cce0SJacob Faibussowitsch matrix. 882920cce0SJacob Faibussowitsch 891cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatCreateSeqAIJ()`, `MatCreateAIJ()`, 90db781477SPatrick Sanan `MatCreateSeqDense()`, `MatCreateDense()`, 91db781477SPatrick Sanan `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, 92db781477SPatrick Sanan `MatCreateSeqSBAIJ()`, `MatCreateSBAIJ()`, 93db781477SPatrick Sanan `MatConvert()` 94273d9f13SBarry Smith @*/ 95d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreate(MPI_Comm comm, Mat *A) 96d71ae5a4SJacob Faibussowitsch { 97273d9f13SBarry Smith Mat B; 98273d9f13SBarry Smith 99273d9f13SBarry Smith PetscFunctionBegin; 1004f572ea9SToby Isaac PetscAssertPointer(A, 2); 1019566063dSJacob Faibussowitsch PetscCall(MatInitializePackage()); 1028ba1e511SMatthew Knepley 1039566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(B, MAT_CLASSID, "Mat", "Matrix", "Mat", comm, MatDestroy, MatView)); 1049566063dSJacob Faibussowitsch PetscCall(PetscLayoutCreate(comm, &B->rmap)); 1059566063dSJacob Faibussowitsch PetscCall(PetscLayoutCreate(comm, &B->cmap)); 1069566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(VECSTANDARD, &B->defaultvectype)); 1073faff063SStefano Zampini PetscCall(PetscStrallocpy(PETSCRANDER48, &B->defaultrandtype)); 10826fbe8dcSKarl Rupp 109b94d7dedSBarry Smith B->symmetric = PETSC_BOOL3_UNKNOWN; 110b94d7dedSBarry Smith B->hermitian = PETSC_BOOL3_UNKNOWN; 111b94d7dedSBarry Smith B->structurally_symmetric = PETSC_BOOL3_UNKNOWN; 112b94d7dedSBarry Smith B->spd = PETSC_BOOL3_UNKNOWN; 113b94d7dedSBarry Smith B->symmetry_eternal = PETSC_FALSE; 114b94d7dedSBarry Smith B->structural_symmetry_eternal = PETSC_FALSE; 115b94d7dedSBarry Smith 11694342113SStefano Zampini B->congruentlayouts = PETSC_DECIDE; 117273d9f13SBarry Smith B->preallocated = PETSC_FALSE; 1186f3d89d0SStefano Zampini #if defined(PETSC_HAVE_DEVICE) 1196f3d89d0SStefano Zampini B->boundtocpu = PETSC_TRUE; 1206f3d89d0SStefano Zampini #endif 121273d9f13SBarry Smith *A = B; 1223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 123273d9f13SBarry Smith } 124273d9f13SBarry Smith 125cc4c1da9SBarry Smith /*@ 12677433607SBarry Smith MatCreateFromOptions - Creates a matrix whose type is set from the options database 12777433607SBarry Smith 12877433607SBarry Smith Collective 12977433607SBarry Smith 13077433607SBarry Smith Input Parameters: 13177433607SBarry Smith + comm - MPI communicator 13277433607SBarry Smith . prefix - [optional] prefix for the options database 13377433607SBarry Smith . bs - the blocksize (commonly 1) 13477433607SBarry Smith . m - the local number of rows (or `PETSC_DECIDE`) 13577433607SBarry Smith . n - the local number of columns (or `PETSC_DECIDE` or `PETSC_DETERMINE`) 13677433607SBarry Smith . M - the global number of rows (or `PETSC_DETERMINE`) 13777433607SBarry Smith - N - the global number of columns (or `PETSC_DETERMINE`) 13877433607SBarry Smith 13977433607SBarry Smith Output Parameter: 14077433607SBarry Smith . A - the matrix 14177433607SBarry Smith 14277433607SBarry Smith Options Database Key: 14377433607SBarry Smith . -mat_type - see `MatType`, for example `aij`, `aijcusparse`, `baij`, `sbaij`, dense, defaults to `aij` 14477433607SBarry Smith 14577433607SBarry Smith Level: beginner 14677433607SBarry Smith 14777433607SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatCreateSeqAIJ()`, `MatCreateAIJ()`, 14877433607SBarry Smith `MatCreateSeqDense()`, `MatCreateDense()`, 14977433607SBarry Smith `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, 15077433607SBarry Smith `MatCreateSeqSBAIJ()`, `MatCreateSBAIJ()`, 15177433607SBarry Smith `MatConvert()`, `MatCreate()` 15277433607SBarry Smith @*/ 15377433607SBarry Smith PetscErrorCode MatCreateFromOptions(MPI_Comm comm, const char *prefix, PetscInt bs, PetscInt m, PetscInt n, PetscInt M, PetscInt N, Mat *A) 15477433607SBarry Smith { 15577433607SBarry Smith PetscFunctionBegin; 15677433607SBarry Smith PetscAssertPointer(A, 8); 15777433607SBarry Smith PetscCall(MatCreate(comm, A)); 15877433607SBarry Smith if (prefix) PetscCall(MatSetOptionsPrefix(*A, prefix)); 15977433607SBarry Smith PetscCall(MatSetBlockSize(*A, bs)); 16077433607SBarry Smith PetscCall(MatSetSizes(*A, m, n, M, N)); 16177433607SBarry Smith PetscCall(MatSetFromOptions(*A)); 16277433607SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 16377433607SBarry Smith } 16477433607SBarry Smith 165422a814eSBarry Smith /*@ 16611a5261eSBarry Smith MatSetErrorIfFailure - Causes `Mat` to generate an immediate error, for example a zero pivot, is detected. 167422a814eSBarry Smith 168c3339decSBarry Smith Logically Collective 169422a814eSBarry Smith 170422a814eSBarry Smith Input Parameters: 17111a5261eSBarry Smith + mat - matrix obtained from `MatCreate()` 17211a5261eSBarry Smith - flg - `PETSC_TRUE` indicates you want the error generated 173422a814eSBarry Smith 174422a814eSBarry Smith Level: advanced 175422a814eSBarry Smith 17611a5261eSBarry Smith Note: 17711a5261eSBarry Smith If this flag is not set then the matrix operation will note the error and continue. The error may cause a later `PC` or `KSP` error 17811a5261eSBarry Smith or result in a `KSPConvergedReason` indicating the method did not converge. 17911a5261eSBarry Smith 1801cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `PCSetErrorIfFailure()`, `KSPConvergedReason`, `SNESConvergedReason` 181422a814eSBarry Smith @*/ 182d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetErrorIfFailure(Mat mat, PetscBool flg) 183d71ae5a4SJacob Faibussowitsch { 184422a814eSBarry Smith PetscFunctionBegin; 185422a814eSBarry Smith PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 186422a814eSBarry Smith PetscValidLogicalCollectiveBool(mat, flg, 2); 18784d44b13SHong Zhang mat->erroriffailure = flg; 1883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 189422a814eSBarry Smith } 190422a814eSBarry Smith 191f69a0ea3SMatthew Knepley /*@ 192f69a0ea3SMatthew Knepley MatSetSizes - Sets the local and global sizes, and checks to determine compatibility 193f69a0ea3SMatthew Knepley 194c3339decSBarry Smith Collective 195f69a0ea3SMatthew Knepley 196f69a0ea3SMatthew Knepley Input Parameters: 197f69a0ea3SMatthew Knepley + A - the matrix 19811a5261eSBarry Smith . m - number of local rows (or `PETSC_DECIDE`) 19911a5261eSBarry Smith . n - number of local columns (or `PETSC_DECIDE`) 20011a5261eSBarry Smith . M - number of global rows (or `PETSC_DETERMINE`) 20111a5261eSBarry Smith - N - number of global columns (or `PETSC_DETERMINE`) 202f69a0ea3SMatthew Knepley 2032fe279fdSBarry Smith Level: beginner 2042fe279fdSBarry Smith 205f69a0ea3SMatthew Knepley Notes: 2062ef1f0ffSBarry Smith `m` (`n`) and `M` (`N`) cannot be both `PETSC_DECIDE` 2072ef1f0ffSBarry Smith If one processor calls this with `M` (`N`) of `PETSC_DECIDE` then all processors must, otherwise the program will hang. 208f69a0ea3SMatthew Knepley 20911a5261eSBarry Smith If `PETSC_DECIDE` is not used for the arguments 'm' and 'n', then the 210f69a0ea3SMatthew Knepley user must ensure that they are chosen to be compatible with the 211f69a0ea3SMatthew Knepley vectors. To do this, one first considers the matrix-vector product 2122ef1f0ffSBarry Smith 'y = A x'. The `m` that is used in the above routine must match the 2132ef1f0ffSBarry Smith local size used in the vector creation routine `VecCreateMPI()` for 'y'. 2142ef1f0ffSBarry Smith Likewise, the `n` used must match that used as the local size in 21511a5261eSBarry Smith `VecCreateMPI()` for 'x'. 216f69a0ea3SMatthew Knepley 217727bdf9bSBarry Smith If `m` and `n` are not `PETSC_DECIDE`, then the values determine the `PetscLayout` of the matrix and the ranges returned by 218727bdf9bSBarry Smith `MatGetOwnershipRange()`, `MatGetOwnershipRanges()`, `MatGetOwnershipRangeColumn()`, and `MatGetOwnershipRangesColumn()`. 219727bdf9bSBarry Smith 220f73d5cc4SBarry Smith You cannot change the sizes once they have been set. 221f73d5cc4SBarry Smith 22211a5261eSBarry Smith The sizes must be set before `MatSetUp()` or MatXXXSetPreallocation() is called. 223f73d5cc4SBarry Smith 224727bdf9bSBarry Smith .seealso: [](ch_matrices), `Mat`, `MatGetSize()`, `PetscSplitOwnership()`, `MatGetOwnershipRange()`, `MatGetOwnershipRanges()`, 225727bdf9bSBarry Smith `MatGetOwnershipRangeColumn()`, `MatGetOwnershipRangesColumn()`, `PetscLayout`, `VecSetSizes()` 226f69a0ea3SMatthew Knepley @*/ 227d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetSizes(Mat A, PetscInt m, PetscInt n, PetscInt M, PetscInt N) 228d71ae5a4SJacob Faibussowitsch { 229f69a0ea3SMatthew Knepley PetscFunctionBegin; 2300700a824SBarry Smith PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 231a69c7061SStefano Zampini PetscValidLogicalCollectiveInt(A, M, 4); 232a69c7061SStefano Zampini PetscValidLogicalCollectiveInt(A, N, 5); 233aed4548fSBarry Smith PetscCheck(M <= 0 || m <= M, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Local row size %" PetscInt_FMT " cannot be larger than global row size %" PetscInt_FMT, m, M); 234aed4548fSBarry Smith PetscCheck(N <= 0 || n <= N, PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP, "Local column size %" PetscInt_FMT " cannot be larger than global column size %" PetscInt_FMT, n, N); 2359371c9d4SSatish Balay PetscCheck((A->rmap->n < 0 || A->rmap->N < 0) || (A->rmap->n == m && (M <= 0 || A->rmap->N == M)), PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot change/reset row sizes to %" PetscInt_FMT " local %" PetscInt_FMT " global after previously setting them to %" PetscInt_FMT " local %" PetscInt_FMT " global", m, M, 2369371c9d4SSatish Balay A->rmap->n, A->rmap->N); 2379371c9d4SSatish Balay PetscCheck((A->cmap->n < 0 || A->cmap->N < 0) || (A->cmap->n == n && (N <= 0 || A->cmap->N == N)), PETSC_COMM_SELF, PETSC_ERR_SUP, "Cannot change/reset column sizes to %" PetscInt_FMT " local %" PetscInt_FMT " global after previously setting them to %" PetscInt_FMT " local %" PetscInt_FMT " global", n, N, 2389371c9d4SSatish Balay A->cmap->n, A->cmap->N); 239d0f46423SBarry Smith A->rmap->n = m; 240d0f46423SBarry Smith A->cmap->n = n; 24159cb773eSBarry Smith A->rmap->N = M > -1 ? M : A->rmap->N; 24259cb773eSBarry Smith A->cmap->N = N > -1 ? N : A->cmap->N; 2433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 244f69a0ea3SMatthew Knepley } 245f69a0ea3SMatthew Knepley 24605869f15SSatish Balay /*@ 247273d9f13SBarry Smith MatSetFromOptions - Creates a matrix where the type is determined 2482920cce0SJacob Faibussowitsch from the options database. 249273d9f13SBarry Smith 250c3339decSBarry Smith Collective 251273d9f13SBarry Smith 252273d9f13SBarry Smith Input Parameter: 253fe59aa6dSJacob Faibussowitsch . B - the matrix 254273d9f13SBarry Smith 255273d9f13SBarry Smith Options Database Keys: 25611a5261eSBarry Smith + -mat_type seqaij - `MATSEQAIJ` type, uses `MatCreateSeqAIJ()` 25711a5261eSBarry Smith . -mat_type mpiaij - `MATMPIAIJ` type, uses `MatCreateAIJ()` 25811a5261eSBarry Smith . -mat_type seqdense - `MATSEQDENSE` type, uses `MatCreateSeqDense()` 25911a5261eSBarry Smith . -mat_type mpidense - `MATMPIDENSE`, uses `MatCreateDense()` 26011a5261eSBarry Smith . -mat_type seqbaij - `MATSEQBAIJ`, uses `MatCreateSeqBAIJ()` 26111a5261eSBarry Smith - -mat_type mpibaij - `MATMPIBAIJ`, uses `MatCreateBAIJ()` 262273d9f13SBarry Smith 2632ef1f0ffSBarry Smith See the manpages for particular formats (e.g., `MATSEQAIJ`) 264273d9f13SBarry Smith for additional format-specific options. 265bd9ce289SLois Curfman McInnes 2661d69843bSLois Curfman McInnes Level: beginner 2671d69843bSLois Curfman McInnes 2682920cce0SJacob Faibussowitsch Notes: 2692920cce0SJacob Faibussowitsch Generates a parallel MPI matrix if the communicator has more than one processor. The default 2702920cce0SJacob Faibussowitsch matrix type is `MATAIJ`, using the routines `MatCreateSeqAIJ()` and `MatCreateAIJ()` if you 2712920cce0SJacob Faibussowitsch do not select a type in the options database. 2722920cce0SJacob Faibussowitsch 2731cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatCreateSeqAIJ()`, `MatCreateAIJ()`, 274db781477SPatrick Sanan `MatCreateSeqDense()`, `MatCreateDense()`, 275db781477SPatrick Sanan `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, 276db781477SPatrick Sanan `MatCreateSeqSBAIJ()`, `MatCreateSBAIJ()`, 277db781477SPatrick Sanan `MatConvert()` 2787807a1faSBarry Smith @*/ 279d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetFromOptions(Mat B) 280d71ae5a4SJacob Faibussowitsch { 281f3be49caSLisandro Dalcin const char *deft = MATAIJ; 282f3be49caSLisandro Dalcin char type[256]; 28369df5c0cSJed Brown PetscBool flg, set; 28416e04d98SRichard Tran Mills PetscInt bind_below = 0; 285dbb450caSBarry Smith 2863a40ed3dSBarry Smith PetscFunctionBegin; 2870700a824SBarry Smith PetscValidHeaderSpecific(B, MAT_CLASSID, 1); 288f3be49caSLisandro Dalcin 289d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)B); 290535b19f3SBarry Smith 291535b19f3SBarry Smith if (B->rmap->bs < 0) { 292535b19f3SBarry Smith PetscInt newbs = -1; 2939566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-mat_block_size", "Set the blocksize used to store the matrix", "MatSetBlockSize", newbs, &newbs, &flg)); 294535b19f3SBarry Smith if (flg) { 2959566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetBlockSize(B->rmap, newbs)); 2969566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetBlockSize(B->cmap, newbs)); 297535b19f3SBarry Smith } 298535b19f3SBarry Smith } 299535b19f3SBarry Smith 3009566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-mat_type", "Matrix type", "MatSetType", MatList, deft, type, 256, &flg)); 301273d9f13SBarry Smith if (flg) { 3029566063dSJacob Faibussowitsch PetscCall(MatSetType(B, type)); 303f3be49caSLisandro Dalcin } else if (!((PetscObject)B)->type_name) { 3049566063dSJacob Faibussowitsch PetscCall(MatSetType(B, deft)); 305273d9f13SBarry Smith } 306f3be49caSLisandro Dalcin 3079566063dSJacob Faibussowitsch PetscCall(PetscOptionsName("-mat_is_symmetric", "Checks if mat is symmetric on MatAssemblyEnd()", "MatIsSymmetric", &B->checksymmetryonassembly)); 3089566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-mat_is_symmetric", "Checks if mat is symmetric on MatAssemblyEnd()", "MatIsSymmetric", B->checksymmetrytol, &B->checksymmetrytol, NULL)); 3099566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-mat_null_space_test", "Checks if provided null space is correct in MatAssemblyEnd()", "MatSetNullSpaceTest", B->checknullspaceonassembly, &B->checknullspaceonassembly, NULL)); 3109566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-mat_error_if_failure", "Generate an error if an error occurs when factoring the matrix", "MatSetErrorIfFailure", B->erroriffailure, &B->erroriffailure, NULL)); 311840d65ccSBarry Smith 312dbbe0bcdSBarry Smith PetscTryTypeMethod(B, setfromoptions, PetscOptionsObject); 313f3be49caSLisandro Dalcin 31469df5c0cSJed Brown flg = PETSC_FALSE; 315*0b4b7b1cSBarry Smith PetscCall(PetscOptionsBool("-mat_new_nonzero_location_err", "Generate an error if new nonzeros are created in the matrix nonzero structure (useful to test preallocation)", "MatSetOption", flg, &flg, &set)); 3169566063dSJacob Faibussowitsch if (set) PetscCall(MatSetOption(B, MAT_NEW_NONZERO_LOCATION_ERR, flg)); 31769df5c0cSJed Brown flg = PETSC_FALSE; 318*0b4b7b1cSBarry Smith PetscCall(PetscOptionsBool("-mat_new_nonzero_allocation_err", "Generate an error if new nonzeros are allocated in the matrix nonzero structure (useful to test preallocation)", "MatSetOption", flg, &flg, &set)); 3199566063dSJacob Faibussowitsch if (set) PetscCall(MatSetOption(B, MAT_NEW_NONZERO_ALLOCATION_ERR, flg)); 320478db826SMatthew G. Knepley flg = PETSC_FALSE; 3219566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-mat_ignore_zero_entries", "For AIJ/IS matrices this will stop zero values from creating a zero location in the matrix", "MatSetOption", flg, &flg, &set)); 3229566063dSJacob Faibussowitsch if (set) PetscCall(MatSetOption(B, MAT_IGNORE_ZERO_ENTRIES, flg)); 32369df5c0cSJed Brown 3241a2c6b5cSJunchao Zhang flg = PETSC_FALSE; 3259566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-mat_form_explicit_transpose", "Hint to form an explicit transpose for operations like MatMultTranspose", "MatSetOption", flg, &flg, &set)); 3269566063dSJacob Faibussowitsch if (set) PetscCall(MatSetOption(B, MAT_FORM_EXPLICIT_TRANSPOSE, flg)); 3271a2c6b5cSJunchao Zhang 32816e04d98SRichard Tran Mills /* Bind to CPU if below a user-specified size threshold. 32916e04d98SRichard Tran Mills * This perhaps belongs in the options for the GPU Mat types, but MatBindToCPU() does nothing when called on non-GPU types, 33016e04d98SRichard Tran Mills * and putting it here makes is more maintainable than duplicating this for all. */ 3319566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-mat_bind_below", "Set the size threshold (in local rows) below which the Mat is bound to the CPU", "MatBindToCPU", bind_below, &bind_below, &flg)); 33248a46eb9SPierre Jolivet if (flg && B->rmap->n < bind_below) PetscCall(MatBindToCPU(B, PETSC_TRUE)); 33316e04d98SRichard Tran Mills 3345d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 335dbbe0bcdSBarry Smith PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)B, PetscOptionsObject)); 336d0609cedSBarry Smith PetscOptionsEnd(); 3373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3387807a1faSBarry Smith } 3397807a1faSBarry Smith 3405d83a8b1SBarry Smith /*@ 34111a5261eSBarry Smith MatXAIJSetPreallocation - set preallocation for serial and parallel `MATAIJ`, `MATBAIJ`, and `MATSBAIJ` matrices and their unassembled versions. 34263562e91SJed Brown 343c3339decSBarry Smith Collective 34463562e91SJed Brown 3454165533cSJose E. Roman Input Parameters: 34663562e91SJed Brown + A - matrix being preallocated 34763562e91SJed Brown . bs - block size 34841319c1dSStefano Zampini . dnnz - number of nonzero column blocks per block row of diagonal part of parallel matrix 34941319c1dSStefano Zampini . onnz - number of nonzero column blocks per block row of off-diagonal part of parallel matrix 35041319c1dSStefano Zampini . dnnzu - number of nonzero column blocks per block row of upper-triangular part of diagonal part of parallel matrix 35141319c1dSStefano Zampini - onnzu - number of nonzero column blocks per block row of upper-triangular part of off-diagonal part of parallel matrix 35263562e91SJed Brown 35363562e91SJed Brown Level: beginner 35463562e91SJed Brown 3551cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatSeqAIJSetPreallocation()`, `MatMPIAIJSetPreallocation()`, `MatSeqBAIJSetPreallocation()`, `MatMPIBAIJSetPreallocation()`, 3562fe279fdSBarry Smith `MatSeqSBAIJSetPreallocation()`, `MatMPISBAIJSetPreallocation()`, 357db781477SPatrick Sanan `PetscSplitOwnership()` 35863562e91SJed Brown @*/ 359d71ae5a4SJacob Faibussowitsch PetscErrorCode MatXAIJSetPreallocation(Mat A, PetscInt bs, const PetscInt dnnz[], const PetscInt onnz[], const PetscInt dnnzu[], const PetscInt onnzu[]) 360d71ae5a4SJacob Faibussowitsch { 36141319c1dSStefano Zampini PetscInt cbs; 36263562e91SJed Brown void (*aij)(void); 363e8bd9bafSStefano Zampini void (*is)(void); 364990279feSStefano Zampini void (*hyp)(void) = NULL; 36563562e91SJed Brown 36663562e91SJed Brown PetscFunctionBegin; 36741319c1dSStefano Zampini if (bs != PETSC_DECIDE) { /* don't mess with an already set block size */ 3689566063dSJacob Faibussowitsch PetscCall(MatSetBlockSize(A, bs)); 36941319c1dSStefano Zampini } 3709566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 3719566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 3729566063dSJacob Faibussowitsch PetscCall(MatGetBlockSizes(A, &bs, &cbs)); 37341319c1dSStefano Zampini /* these routines assumes bs == cbs, this should be checked somehow */ 3749566063dSJacob Faibussowitsch PetscCall(MatSeqBAIJSetPreallocation(A, bs, 0, dnnz)); 3759566063dSJacob Faibussowitsch PetscCall(MatMPIBAIJSetPreallocation(A, bs, 0, dnnz, 0, onnz)); 3769566063dSJacob Faibussowitsch PetscCall(MatSeqSBAIJSetPreallocation(A, bs, 0, dnnzu)); 3779566063dSJacob Faibussowitsch PetscCall(MatMPISBAIJSetPreallocation(A, bs, 0, dnnzu, 0, onnzu)); 37863562e91SJed Brown /* 379e8bd9bafSStefano Zampini In general, we have to do extra work to preallocate for scalar (AIJ) or unassembled (IS) matrices so we check whether it will do any 38063562e91SJed Brown good before going on with it. 38163562e91SJed Brown */ 3829566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatMPIAIJSetPreallocation_C", &aij)); 3839566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatISSetPreallocation_C", &is)); 384990279feSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 3859566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatHYPRESetPreallocation_C", &hyp)); 386990279feSStefano Zampini #endif 38748a46eb9SPierre Jolivet if (!aij && !is && !hyp) PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatSeqAIJSetPreallocation_C", &aij)); 388990279feSStefano Zampini if (aij || is || hyp) { 38941319c1dSStefano Zampini if (bs == cbs && bs == 1) { 3909566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(A, 0, dnnz)); 3919566063dSJacob Faibussowitsch PetscCall(MatMPIAIJSetPreallocation(A, 0, dnnz, 0, onnz)); 3929566063dSJacob Faibussowitsch PetscCall(MatISSetPreallocation(A, 0, dnnz, 0, onnz)); 393990279feSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 3949566063dSJacob Faibussowitsch PetscCall(MatHYPRESetPreallocation(A, 0, dnnz, 0, onnz)); 395990279feSStefano Zampini #endif 3963e5f4774SJed Brown } else { /* Convert block-row precallocation to scalar-row */ 39763562e91SJed Brown PetscInt i, m, *sdnnz, *sonnz; 3989566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(A, &m, NULL)); 3999566063dSJacob Faibussowitsch PetscCall(PetscMalloc2((!!dnnz) * m, &sdnnz, (!!onnz) * m, &sonnz)); 400dec54756SJed Brown for (i = 0; i < m; i++) { 40141319c1dSStefano Zampini if (dnnz) sdnnz[i] = dnnz[i / bs] * cbs; 40241319c1dSStefano Zampini if (onnz) sonnz[i] = onnz[i / bs] * cbs; 40363562e91SJed Brown } 4049566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(A, 0, dnnz ? sdnnz : NULL)); 4059566063dSJacob Faibussowitsch PetscCall(MatMPIAIJSetPreallocation(A, 0, dnnz ? sdnnz : NULL, 0, onnz ? sonnz : NULL)); 4069566063dSJacob Faibussowitsch PetscCall(MatISSetPreallocation(A, 0, dnnz ? sdnnz : NULL, 0, onnz ? sonnz : NULL)); 407990279feSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 4089566063dSJacob Faibussowitsch PetscCall(MatHYPRESetPreallocation(A, 0, dnnz ? sdnnz : NULL, 0, onnz ? sonnz : NULL)); 409990279feSStefano Zampini #endif 4109566063dSJacob Faibussowitsch PetscCall(PetscFree2(sdnnz, sonnz)); 41163562e91SJed Brown } 41263562e91SJed Brown } 4133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 41463562e91SJed Brown } 41563562e91SJed Brown 41602218ef1SBarry Smith /*@C 41702218ef1SBarry Smith MatHeaderMerge - Merges some information from the header of `C` to `A`; the `C` object is then destroyed 418d0f46423SBarry Smith 41902218ef1SBarry Smith Collective, No Fortran Support 42002218ef1SBarry Smith 42102218ef1SBarry Smith Input Parameters: 42202218ef1SBarry Smith + A - a `Mat` being merged into 42302218ef1SBarry Smith - C - the `Mat` providing the merge information 42402218ef1SBarry Smith 42502218ef1SBarry Smith Level: developer 42602218ef1SBarry Smith 427f2e50d50SStefano Zampini Notes: 428f2e50d50SStefano Zampini `A` and `C` must be of the same type. 429f2e50d50SStefano Zampini The object list and query function list in `A` are retained, as well as the object name, and prefix. 430f2e50d50SStefano Zampini The object state of `A` is increased by 1. 431f2e50d50SStefano Zampini 43202218ef1SBarry Smith Developer Note: 43302218ef1SBarry Smith This is somewhat different from `MatHeaderReplace()`, it would be nice to merge the code 43402218ef1SBarry Smith 43502218ef1SBarry Smith .seealso: `Mat`, `MatHeaderReplace()` 43602218ef1SBarry Smith @*/ 437d71ae5a4SJacob Faibussowitsch PetscErrorCode MatHeaderMerge(Mat A, Mat *C) 438d71ae5a4SJacob Faibussowitsch { 439d44834fbSBarry Smith PetscInt refct; 44073107ff1SLisandro Dalcin PetscOps Abops; 44173107ff1SLisandro Dalcin struct _MatOps Aops; 4424768301cSVaclav Hapla char *mtype, *mname, *mprefix; 4434222ddf1SHong Zhang Mat_Product *product; 44433e6eea4SJose E. Roman Mat_Redundant *redundant; 445d4a972cbSStefano Zampini PetscObjectState state; 446f2e50d50SStefano Zampini PetscObjectList olist; 447f2e50d50SStefano Zampini PetscFunctionList qlist; 448273d9f13SBarry Smith 449273d9f13SBarry Smith PetscFunctionBegin; 4501dc04de0SStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 4511dc04de0SStefano Zampini PetscValidHeaderSpecific(*C, MAT_CLASSID, 2); 4523ba16761SJacob Faibussowitsch if (A == *C) PetscFunctionReturn(PETSC_SUCCESS); 453f2e50d50SStefano Zampini PetscCheckSameTypeAndComm(A, 1, *C, 2); 454273d9f13SBarry Smith /* save the parts of A we need */ 45573107ff1SLisandro Dalcin Abops = ((PetscObject)A)->bops[0]; 45673107ff1SLisandro Dalcin Aops = A->ops[0]; 4577adad957SLisandro Dalcin refct = ((PetscObject)A)->refct; 4585c9eb25fSBarry Smith mtype = ((PetscObject)A)->type_name; 4595c9eb25fSBarry Smith mname = ((PetscObject)A)->name; 460d4a972cbSStefano Zampini state = ((PetscObject)A)->state; 4614768301cSVaclav Hapla mprefix = ((PetscObject)A)->prefix; 4624222ddf1SHong Zhang product = A->product; 46333e6eea4SJose E. Roman redundant = A->redundant; 464f2e50d50SStefano Zampini qlist = ((PetscObject)A)->qlist; 465f2e50d50SStefano Zampini olist = ((PetscObject)A)->olist; 46630735b05SKris Buschelman 4675c9eb25fSBarry Smith /* zero these so the destroy below does not free them */ 468f4259b30SLisandro Dalcin ((PetscObject)A)->type_name = NULL; 469f4259b30SLisandro Dalcin ((PetscObject)A)->name = NULL; 470f2e50d50SStefano Zampini ((PetscObject)A)->qlist = NULL; 471f2e50d50SStefano Zampini ((PetscObject)A)->olist = NULL; 4725c9eb25fSBarry Smith 473dbbe0bcdSBarry Smith /* 474dbbe0bcdSBarry Smith free all the interior data structures from mat 475dbbe0bcdSBarry Smith cannot use PetscUseTypeMethod(A,destroy); because compiler 476dbbe0bcdSBarry Smith thinks it may print NULL type_name and name 477dbbe0bcdSBarry Smith */ 478dbbe0bcdSBarry Smith PetscTryTypeMethod(A, destroy); 4797c99f97cSSatish Balay 4809566063dSJacob Faibussowitsch PetscCall(PetscFree(A->defaultvectype)); 4813faff063SStefano Zampini PetscCall(PetscFree(A->defaultrandtype)); 4829566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&A->rmap)); 4839566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&A->cmap)); 4849566063dSJacob Faibussowitsch PetscCall(PetscComposedQuantitiesDestroy((PetscObject)A)); 485273d9f13SBarry Smith 486273d9f13SBarry Smith /* copy C over to A */ 48726cc229bSBarry Smith PetscCall(PetscFree(A->factorprefix)); 4889566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(A, *C, sizeof(struct _p_Mat))); 489273d9f13SBarry Smith 490273d9f13SBarry Smith /* return the parts of A we saved */ 49173107ff1SLisandro Dalcin ((PetscObject)A)->bops[0] = Abops; 49273107ff1SLisandro Dalcin A->ops[0] = Aops; 4937adad957SLisandro Dalcin ((PetscObject)A)->refct = refct; 4947adad957SLisandro Dalcin ((PetscObject)A)->type_name = mtype; 4957adad957SLisandro Dalcin ((PetscObject)A)->name = mname; 4964768301cSVaclav Hapla ((PetscObject)A)->prefix = mprefix; 497d4a972cbSStefano Zampini ((PetscObject)A)->state = state + 1; 4984222ddf1SHong Zhang A->product = product; 49933e6eea4SJose E. Roman A->redundant = redundant; 500273d9f13SBarry Smith 501f2e50d50SStefano Zampini /* Append the saved lists */ 502f2e50d50SStefano Zampini PetscCall(PetscFunctionListDuplicate(qlist, &((PetscObject)A)->qlist)); 503f2e50d50SStefano Zampini PetscCall(PetscObjectListDuplicate(olist, &((PetscObject)A)->olist)); 504f2e50d50SStefano Zampini PetscCall(PetscFunctionListDestroy(&qlist)); 505f2e50d50SStefano Zampini PetscCall(PetscObjectListDestroy(&olist)); 506f2e50d50SStefano Zampini 5075c9eb25fSBarry Smith /* since these two are copied into A we do not want them destroyed in C */ 508f4259b30SLisandro Dalcin ((PetscObject)*C)->qlist = NULL; 509f4259b30SLisandro Dalcin ((PetscObject)*C)->olist = NULL; 5109566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(C)); 5113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 512273d9f13SBarry Smith } 513d0f46423SBarry Smith 51402218ef1SBarry Smith /*@ 51502218ef1SBarry Smith MatHeaderReplace - Replaces the internal data of matrix `A` by the internal data of matrix `C` while deleting the outer wrapper of `C` 516eb6b5d47SBarry Smith 51702218ef1SBarry Smith Input Parameters: 51802218ef1SBarry Smith + A - a `Mat` whose internal data is to be replaced 51902218ef1SBarry Smith - C - the `Mat` providing new internal data for `A` 520b30237c6SBarry Smith 52102218ef1SBarry Smith Level: advanced 52202218ef1SBarry Smith 52302218ef1SBarry Smith Example Usage\: 52402218ef1SBarry Smith .vb 52502218ef1SBarry Smith Mat C; 52602218ef1SBarry Smith MatCreateSeqAIJWithArrays(..., &C); 52702218ef1SBarry Smith MatHeaderReplace(A, &C); 52802218ef1SBarry Smith // C has been destroyed and A contains the matrix entries of C 52902218ef1SBarry Smith .ve 53002218ef1SBarry Smith 53102218ef1SBarry Smith Note: 532*0b4b7b1cSBarry Smith This can be used inside a function provided to `SNESSetJacobian()`, `TSSetRHSJacobian()`, or `TSSetIJacobian()` in cases where the user code 533*0b4b7b1cSBarry Smith computes an entirely new sparse matrix (generally with a different matrix nonzero structure/pattern) for each Newton update. 534*0b4b7b1cSBarry Smith It is usually better to reuse the matrix nonzero structure of `A` instead of constructing an entirely new one. 53502218ef1SBarry Smith 53602218ef1SBarry Smith Developer Note: 53702218ef1SBarry Smith This is somewhat different from `MatHeaderMerge()` it would be nice to merge the code 53802218ef1SBarry Smith 53902218ef1SBarry Smith .seealso: `Mat`, `MatHeaderMerge()` 54002218ef1SBarry Smith @*/ 54102218ef1SBarry Smith PetscErrorCode MatHeaderReplace(Mat A, Mat *C) 542d71ae5a4SJacob Faibussowitsch { 54327b31e29SJed Brown PetscInt refct; 544fefd9316SJose E. Roman PetscObjectState state; 54528be2f97SBarry Smith struct _p_Mat buffer; 54681fa06acSBarry Smith MatStencilInfo stencil; 5478ab5b326SKris Buschelman 5488ab5b326SKris Buschelman PetscFunctionBegin; 54927b31e29SJed Brown PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 55028be2f97SBarry Smith PetscValidHeaderSpecific(*C, MAT_CLASSID, 2); 5513ba16761SJacob Faibussowitsch if (A == *C) PetscFunctionReturn(PETSC_SUCCESS); 55228be2f97SBarry Smith PetscCheckSameComm(A, 1, *C, 2); 553aed4548fSBarry Smith PetscCheck(((PetscObject)*C)->refct == 1, PetscObjectComm((PetscObject)C), PETSC_ERR_ARG_WRONGSTATE, "Object C has refct %" PetscInt_FMT " > 1, would leave hanging reference", ((PetscObject)*C)->refct); 5546d7c1e57SBarry Smith 55528be2f97SBarry Smith /* swap C and A */ 55627b31e29SJed Brown refct = ((PetscObject)A)->refct; 557fefd9316SJose E. Roman state = ((PetscObject)A)->state; 55881fa06acSBarry Smith stencil = A->stencil; 5599566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(&buffer, A, sizeof(struct _p_Mat))); 5609566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(A, *C, sizeof(struct _p_Mat))); 5619566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(*C, &buffer, sizeof(struct _p_Mat))); 56227b31e29SJed Brown ((PetscObject)A)->refct = refct; 563fefd9316SJose E. Roman ((PetscObject)A)->state = state + 1; 56481fa06acSBarry Smith A->stencil = stencil; 56526fbe8dcSKarl Rupp 566c32d4117SBarry Smith ((PetscObject)*C)->refct = 1; 5679566063dSJacob Faibussowitsch PetscCall(MatDestroy(C)); 5683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5698ab5b326SKris Buschelman } 570e7e92044SBarry Smith 571e7e92044SBarry Smith /*@ 572b470e4b4SRichard Tran Mills MatBindToCPU - marks a matrix to temporarily stay on the CPU and perform computations on the CPU 573e7e92044SBarry Smith 5742ef1f0ffSBarry Smith Logically Collective 5752216c58aSStefano Zampini 576e7e92044SBarry Smith Input Parameters: 577e7e92044SBarry Smith + A - the matrix 57811a5261eSBarry Smith - flg - bind to the CPU if value of `PETSC_TRUE` 579e7e92044SBarry Smith 58090ea27d8SSatish Balay Level: intermediate 5812216c58aSStefano Zampini 5821cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatBoundToCPU()` 583e7e92044SBarry Smith @*/ 584d71ae5a4SJacob Faibussowitsch PetscErrorCode MatBindToCPU(Mat A, PetscBool flg) 585d71ae5a4SJacob Faibussowitsch { 5867d871021SStefano Zampini PetscFunctionBegin; 5872ffa8ee7SStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 5882ffa8ee7SStefano Zampini PetscValidLogicalCollectiveBool(A, flg, 2); 5892216c58aSStefano Zampini #if defined(PETSC_HAVE_DEVICE) 5903ba16761SJacob Faibussowitsch if (A->boundtocpu == flg) PetscFunctionReturn(PETSC_SUCCESS); 591b470e4b4SRichard Tran Mills A->boundtocpu = flg; 592dbbe0bcdSBarry Smith PetscTryTypeMethod(A, bindtocpu, flg); 5932216c58aSStefano Zampini #endif 5943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5952216c58aSStefano Zampini } 5962216c58aSStefano Zampini 5972216c58aSStefano Zampini /*@ 5982216c58aSStefano Zampini MatBoundToCPU - query if a matrix is bound to the CPU 5992216c58aSStefano Zampini 6002216c58aSStefano Zampini Input Parameter: 6012216c58aSStefano Zampini . A - the matrix 6022216c58aSStefano Zampini 6032216c58aSStefano Zampini Output Parameter: 6042216c58aSStefano Zampini . flg - the logical flag 6052216c58aSStefano Zampini 6062216c58aSStefano Zampini Level: intermediate 6072216c58aSStefano Zampini 6081cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatBindToCPU()` 6092216c58aSStefano Zampini @*/ 610d71ae5a4SJacob Faibussowitsch PetscErrorCode MatBoundToCPU(Mat A, PetscBool *flg) 611d71ae5a4SJacob Faibussowitsch { 6122ffa8ee7SStefano Zampini PetscFunctionBegin; 6132ffa8ee7SStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 6144f572ea9SToby Isaac PetscAssertPointer(flg, 2); 6152216c58aSStefano Zampini #if defined(PETSC_HAVE_DEVICE) 6162216c58aSStefano Zampini *flg = A->boundtocpu; 6172216c58aSStefano Zampini #else 6182216c58aSStefano Zampini *flg = PETSC_TRUE; 6197d871021SStefano Zampini #endif 6203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 621e7e92044SBarry Smith } 6227e8381f9SStefano Zampini 623d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetValuesCOO_Basic(Mat A, const PetscScalar coo_v[], InsertMode imode) 624d71ae5a4SJacob Faibussowitsch { 6257e8381f9SStefano Zampini IS is_coo_i, is_coo_j; 6267e8381f9SStefano Zampini const PetscInt *coo_i, *coo_j; 6277e8381f9SStefano Zampini PetscInt n, n_i, n_j; 6287e8381f9SStefano Zampini PetscScalar zero = 0.; 6297e8381f9SStefano Zampini 6307e8381f9SStefano Zampini PetscFunctionBegin; 6319566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)A, "__PETSc_coo_i", (PetscObject *)&is_coo_i)); 6329566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)A, "__PETSc_coo_j", (PetscObject *)&is_coo_j)); 63328b400f6SJacob Faibussowitsch PetscCheck(is_coo_i, PetscObjectComm((PetscObject)A), PETSC_ERR_COR, "Missing coo_i IS"); 63428b400f6SJacob Faibussowitsch PetscCheck(is_coo_j, PetscObjectComm((PetscObject)A), PETSC_ERR_COR, "Missing coo_j IS"); 6359566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(is_coo_i, &n_i)); 6369566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(is_coo_j, &n_j)); 63708401ef6SPierre Jolivet PetscCheck(n_i == n_j, PETSC_COMM_SELF, PETSC_ERR_COR, "Wrong local size %" PetscInt_FMT " != %" PetscInt_FMT, n_i, n_j); 6389566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is_coo_i, &coo_i)); 6399566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is_coo_j, &coo_j)); 64048a46eb9SPierre Jolivet if (imode != ADD_VALUES) PetscCall(MatZeroEntries(A)); 64148a46eb9SPierre Jolivet for (n = 0; n < n_i; n++) PetscCall(MatSetValue(A, coo_i[n], coo_j[n], coo_v ? coo_v[n] : zero, ADD_VALUES)); 6429566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is_coo_i, &coo_i)); 6439566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is_coo_j, &coo_j)); 6443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6457e8381f9SStefano Zampini } 6467e8381f9SStefano Zampini 6478063e3c8SPierre Jolivet PetscErrorCode MatSetPreallocationCOO_Basic(Mat A, PetscCount ncoo, PetscInt coo_i[], PetscInt coo_j[]) 648d71ae5a4SJacob Faibussowitsch { 6497e8381f9SStefano Zampini Mat preallocator; 6507e8381f9SStefano Zampini IS is_coo_i, is_coo_j; 6517e8381f9SStefano Zampini PetscScalar zero = 0.0; 6527e8381f9SStefano Zampini 6537e8381f9SStefano Zampini PetscFunctionBegin; 6541690c2aeSBarry Smith PetscCheck(ncoo <= PETSC_INT_MAX, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "ncoo %" PetscCount_FMT " overflowed PetscInt; configure --with-64-bit-indices or request support", ncoo); 6559566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 6569566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 6579566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &preallocator)); 6589566063dSJacob Faibussowitsch PetscCall(MatSetType(preallocator, MATPREALLOCATOR)); 6599566063dSJacob Faibussowitsch PetscCall(MatSetSizes(preallocator, A->rmap->n, A->cmap->n, A->rmap->N, A->cmap->N)); 6609566063dSJacob Faibussowitsch PetscCall(MatSetLayouts(preallocator, A->rmap, A->cmap)); 6619566063dSJacob Faibussowitsch PetscCall(MatSetUp(preallocator)); 66248a46eb9SPierre Jolivet for (PetscCount n = 0; n < ncoo; n++) PetscCall(MatSetValue(preallocator, coo_i[n], coo_j[n], zero, INSERT_VALUES)); 6639566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(preallocator, MAT_FINAL_ASSEMBLY)); 6649566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(preallocator, MAT_FINAL_ASSEMBLY)); 6659566063dSJacob Faibussowitsch PetscCall(MatPreallocatorPreallocate(preallocator, PETSC_TRUE, A)); 6669566063dSJacob Faibussowitsch PetscCall(MatDestroy(&preallocator)); 6676497c311SBarry Smith PetscCall(ISCreateGeneral(PETSC_COMM_SELF, (PetscInt)ncoo, coo_i, PETSC_COPY_VALUES, &is_coo_i)); 6686497c311SBarry Smith PetscCall(ISCreateGeneral(PETSC_COMM_SELF, (PetscInt)ncoo, coo_j, PETSC_COPY_VALUES, &is_coo_j)); 6699566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "__PETSc_coo_i", (PetscObject)is_coo_i)); 6709566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "__PETSc_coo_j", (PetscObject)is_coo_j)); 6719566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is_coo_i)); 6729566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is_coo_j)); 6733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6747e8381f9SStefano Zampini } 6757e8381f9SStefano Zampini 67656856777SBarry Smith /*@C 677c3dd2894SJed Brown MatSetPreallocationCOO - set preallocation for matrices using a coordinate format of the entries with global indices 6787e8381f9SStefano Zampini 679c3339decSBarry Smith Collective 6807e8381f9SStefano Zampini 6814165533cSJose E. Roman Input Parameters: 6827e8381f9SStefano Zampini + A - matrix being preallocated 68342550becSJunchao Zhang . ncoo - number of entries 6847e8381f9SStefano Zampini . coo_i - row indices 6857e8381f9SStefano Zampini - coo_j - column indices 6867e8381f9SStefano Zampini 6877e8381f9SStefano Zampini Level: beginner 6887e8381f9SStefano Zampini 689394ed5ebSJunchao Zhang Notes: 690f13dfd9eSBarry Smith The indices within `coo_i` and `coo_j` may be modified within this function. The caller should not rely on them 691e8729f6fSJunchao Zhang having any specific value after this function returns. The arrays can be freed or reused immediately 692e8729f6fSJunchao Zhang after this function returns. 693e8729f6fSJunchao Zhang 69411a5261eSBarry Smith Entries can be repeated, see `MatSetValuesCOO()`. Entries with negative row or column indices are allowed 69511a5261eSBarry Smith but will be ignored. The corresponding entries in `MatSetValuesCOO()` will be ignored too. Remote entries 696d7547e51SJunchao Zhang are allowed and will be properly added or inserted to the matrix, unless the matrix option `MAT_IGNORE_OFF_PROC_ENTRIES` 69711a5261eSBarry Smith is set, in which case remote entries are ignored, or `MAT_NO_OFF_PROC_ENTRIES` is set, in which case an error will be generated. 6987e8381f9SStefano Zampini 699d7547e51SJunchao Zhang If you just want to create a sequential AIJ matrix (`MATSEQAIJ`), and your matrix entries in COO format are unique, you can also use 700d7547e51SJunchao Zhang `MatCreateSeqAIJFromTriple()`. But that is not recommended for iterative applications. 701d7547e51SJunchao Zhang 7021cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatSetValuesCOO()`, `MatSeqAIJSetPreallocation()`, `MatMPIAIJSetPreallocation()`, `MatSeqBAIJSetPreallocation()`, 7032ef1f0ffSBarry Smith `MatMPIBAIJSetPreallocation()`, `MatSeqSBAIJSetPreallocation()`, `MatMPISBAIJSetPreallocation()`, `MatSetPreallocationCOOLocal()`, 7042ef1f0ffSBarry Smith `DMSetMatrixPreallocateSkip()`, `MatCreateSeqAIJFromTriple()` 7057e8381f9SStefano Zampini @*/ 706d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetPreallocationCOO(Mat A, PetscCount ncoo, PetscInt coo_i[], PetscInt coo_j[]) 707d71ae5a4SJacob Faibussowitsch { 7088063e3c8SPierre Jolivet PetscErrorCode (*f)(Mat, PetscCount, PetscInt[], PetscInt[]) = NULL; 7097e8381f9SStefano Zampini 7107e8381f9SStefano Zampini PetscFunctionBegin; 7117e8381f9SStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 7127e8381f9SStefano Zampini PetscValidType(A, 1); 7134f572ea9SToby Isaac if (ncoo) PetscAssertPointer(coo_i, 3); 7144f572ea9SToby Isaac if (ncoo) PetscAssertPointer(coo_j, 4); 7159566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 7169566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 7179566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatSetPreallocationCOO_C", &f)); 718cbc6b225SStefano Zampini 7199566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(MAT_PreallCOO, A, 0, 0, 0)); 7207e8381f9SStefano Zampini if (f) { 7219566063dSJacob Faibussowitsch PetscCall((*f)(A, ncoo, coo_i, coo_j)); 7227e8381f9SStefano Zampini } else { /* allow fallback, very slow */ 7239566063dSJacob Faibussowitsch PetscCall(MatSetPreallocationCOO_Basic(A, ncoo, coo_i, coo_j)); 7247e8381f9SStefano Zampini } 7259566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(MAT_PreallCOO, A, 0, 0, 0)); 7266834774dSStefano Zampini A->preallocated = PETSC_TRUE; 727cbc6b225SStefano Zampini A->nonzerostate++; 7283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7297e8381f9SStefano Zampini } 7307e8381f9SStefano Zampini 73156856777SBarry Smith /*@C 732c3dd2894SJed Brown MatSetPreallocationCOOLocal - set preallocation for matrices using a coordinate format of the entries with local indices 733c3dd2894SJed Brown 734c3339decSBarry Smith Collective 735c3dd2894SJed Brown 736c3dd2894SJed Brown Input Parameters: 737c3dd2894SJed Brown + A - matrix being preallocated 738c3dd2894SJed Brown . ncoo - number of entries 739c3dd2894SJed Brown . coo_i - row indices (local numbering; may be modified) 740c3dd2894SJed Brown - coo_j - column indices (local numbering; may be modified) 741c3dd2894SJed Brown 742c3dd2894SJed Brown Level: beginner 743c3dd2894SJed Brown 744c3dd2894SJed Brown Notes: 74511a5261eSBarry Smith The local indices are translated using the local to global mapping, thus `MatSetLocalToGlobalMapping()` must have been 74611a5261eSBarry Smith called prior to this function. For matrices created with `DMCreateMatrix()` the local to global mapping is often already provided. 747c3dd2894SJed Brown 7482ef1f0ffSBarry Smith The indices `coo_i` and `coo_j` may be modified within this function. They might be translated to corresponding global 749735d7f90SBarry Smith indices, but the caller should not rely on them having any specific value after this function returns. The arrays 750735d7f90SBarry Smith can be freed or reused immediately after this function returns. 751c3dd2894SJed Brown 75211a5261eSBarry Smith Entries can be repeated, see `MatSetValuesCOO()`. Entries with negative row or column indices are allowed 75311a5261eSBarry Smith but will be ignored. The corresponding entries in `MatSetValuesCOO()` will be ignored too. Remote entries 754394ed5ebSJunchao Zhang are allowed and will be properly added or inserted to the matrix. 755c3dd2894SJed Brown 7561cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatSetValuesCOO()`, `MatSeqAIJSetPreallocation()`, `MatMPIAIJSetPreallocation()`, `MatSeqBAIJSetPreallocation()`, 7572ef1f0ffSBarry Smith `MatMPIBAIJSetPreallocation()`, `MatSeqSBAIJSetPreallocation()`, `MatMPISBAIJSetPreallocation()`, `MatSetPreallocationCOO()`, 7582ef1f0ffSBarry Smith `DMSetMatrixPreallocateSkip()` 759c3dd2894SJed Brown @*/ 760d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetPreallocationCOOLocal(Mat A, PetscCount ncoo, PetscInt coo_i[], PetscInt coo_j[]) 761d71ae5a4SJacob Faibussowitsch { 7626834774dSStefano Zampini PetscErrorCode (*f)(Mat, PetscCount, PetscInt[], PetscInt[]) = NULL; 763c3dd2894SJed Brown 764c3dd2894SJed Brown PetscFunctionBegin; 765c3dd2894SJed Brown PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 766c3dd2894SJed Brown PetscValidType(A, 1); 7674f572ea9SToby Isaac if (ncoo) PetscAssertPointer(coo_i, 3); 7684f572ea9SToby Isaac if (ncoo) PetscAssertPointer(coo_j, 4); 7691690c2aeSBarry Smith PetscCheck(ncoo <= PETSC_INT_MAX, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "ncoo %" PetscCount_FMT " overflowed PetscInt; configure --with-64-bit-indices or request support", ncoo); 7709566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 7719566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 772cbc6b225SStefano Zampini 7739566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatSetPreallocationCOOLocal_C", &f)); 7746834774dSStefano Zampini if (f) { 7759566063dSJacob Faibussowitsch PetscCall((*f)(A, ncoo, coo_i, coo_j)); 776cbc6b225SStefano Zampini A->nonzerostate++; 7776834774dSStefano Zampini } else { 778cbc6b225SStefano Zampini ISLocalToGlobalMapping ltog_row, ltog_col; 7796497c311SBarry Smith 7809566063dSJacob Faibussowitsch PetscCall(MatGetLocalToGlobalMapping(A, <og_row, <og_col)); 7816497c311SBarry Smith if (ltog_row) PetscCall(ISLocalToGlobalMappingApply(ltog_row, (PetscInt)ncoo, coo_i, coo_i)); 7826497c311SBarry Smith if (ltog_col) PetscCall(ISLocalToGlobalMappingApply(ltog_col, (PetscInt)ncoo, coo_j, coo_j)); 7839566063dSJacob Faibussowitsch PetscCall(MatSetPreallocationCOO(A, ncoo, coo_i, coo_j)); 7846834774dSStefano Zampini } 7856834774dSStefano Zampini A->preallocated = PETSC_TRUE; 7863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 787c3dd2894SJed Brown } 788c3dd2894SJed Brown 789c3dd2894SJed Brown /*@ 79011a5261eSBarry Smith MatSetValuesCOO - set values at once in a matrix preallocated using `MatSetPreallocationCOO()` 7917e8381f9SStefano Zampini 792c3339decSBarry Smith Collective 7937e8381f9SStefano Zampini 7944165533cSJose E. Roman Input Parameters: 7957e8381f9SStefano Zampini + A - matrix being preallocated 7962ef1f0ffSBarry Smith . coo_v - the matrix values (can be `NULL`) 7977e8381f9SStefano Zampini - imode - the insert mode 7987e8381f9SStefano Zampini 7997e8381f9SStefano Zampini Level: beginner 8007e8381f9SStefano Zampini 80111a5261eSBarry Smith Notes: 80211a5261eSBarry Smith The values must follow the order of the indices prescribed with `MatSetPreallocationCOO()` or `MatSetPreallocationCOOLocal()`. 80311a5261eSBarry Smith 8042ef1f0ffSBarry Smith When repeated entries are specified in the COO indices the `coo_v` values are first properly summed, regardless of the value of imode. 80511a5261eSBarry Smith The imode flag indicates if coo_v must be added to the current values of the matrix (`ADD_VALUES`) or overwritten (`INSERT_VALUES`). 80611a5261eSBarry Smith 80711a5261eSBarry Smith `MatAssemblyBegin()` and `MatAssemblyEnd()` do not need to be called after this routine. It automatically handles the assembly process. 8087e8381f9SStefano Zampini 8091cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatSetPreallocationCOO()`, `MatSetPreallocationCOOLocal()`, `InsertMode`, `INSERT_VALUES`, `ADD_VALUES` 8107e8381f9SStefano Zampini @*/ 811d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetValuesCOO(Mat A, const PetscScalar coo_v[], InsertMode imode) 812d71ae5a4SJacob Faibussowitsch { 8137e8381f9SStefano Zampini PetscErrorCode (*f)(Mat, const PetscScalar[], InsertMode) = NULL; 81435cef55dSJunchao Zhang PetscBool oldFlg; 8157e8381f9SStefano Zampini 8167e8381f9SStefano Zampini PetscFunctionBegin; 8177e8381f9SStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8187e8381f9SStefano Zampini PetscValidType(A, 1); 8197e8381f9SStefano Zampini MatCheckPreallocated(A, 1); 820bfcc3627SStefano Zampini PetscValidLogicalCollectiveEnum(A, imode, 3); 8219566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatSetValuesCOO_C", &f)); 8229566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(MAT_SetVCOO, A, 0, 0, 0)); 8237e8381f9SStefano Zampini if (f) { 82435cef55dSJunchao Zhang PetscCall((*f)(A, coo_v, imode)); // all known COO implementations do not use MatStash. They do their own off-proc communication 82535cef55dSJunchao Zhang PetscCall(MatGetOption(A, MAT_NO_OFF_PROC_ENTRIES, &oldFlg)); 82635cef55dSJunchao Zhang PetscCall(MatSetOption(A, MAT_NO_OFF_PROC_ENTRIES, PETSC_TRUE)); // set A->nooffprocentries to avoid costly MatStash scatter in MatAssembly 82735cef55dSJunchao Zhang } else { 82835cef55dSJunchao Zhang PetscCall(MatSetValuesCOO_Basic(A, coo_v, imode)); // fall back to MatSetValues, which might use MatStash 8297e8381f9SStefano Zampini } 8309566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 8319566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 83235cef55dSJunchao Zhang if (f) PetscCall(MatSetOption(A, MAT_NO_OFF_PROC_ENTRIES, oldFlg)); 83335cef55dSJunchao Zhang PetscCall(PetscLogEventEnd(MAT_SetVCOO, A, 0, 0, 0)); 8343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8357e8381f9SStefano Zampini } 83665a9ecf2SRichard Tran Mills 83765a9ecf2SRichard Tran Mills /*@ 83865a9ecf2SRichard Tran Mills MatSetBindingPropagates - Sets whether the state of being bound to the CPU for a GPU matrix type propagates to child and some other associated objects 83965a9ecf2SRichard Tran Mills 84065a9ecf2SRichard Tran Mills Input Parameters: 84165a9ecf2SRichard Tran Mills + A - the matrix 84265a9ecf2SRichard Tran Mills - flg - flag indicating whether the boundtocpu flag should be propagated 84365a9ecf2SRichard Tran Mills 84465a9ecf2SRichard Tran Mills Level: developer 84565a9ecf2SRichard Tran Mills 84665a9ecf2SRichard Tran Mills Notes: 8472fe279fdSBarry Smith If the value of flg is set to true, the following will occur 8482fe279fdSBarry Smith + `MatCreateSubMatrices()` and `MatCreateRedundantMatrix()` - bind created matrices to CPU if the input matrix is bound to the CPU. 8492fe279fdSBarry Smith - `MatCreateVecs()` - bind created vectors to CPU if the input matrix is bound to the CPU. 85065a9ecf2SRichard Tran Mills 85165a9ecf2SRichard Tran Mills The bindingpropagates flag itself is also propagated by the above routines. 85265a9ecf2SRichard Tran Mills 853fe59aa6dSJacob Faibussowitsch Developer Notes: 854aa624791SPierre Jolivet If the fine-scale `DMDA` has the `-dm_bind_below` option set to true, then `DMCreateInterpolationScale()` calls `MatSetBindingPropagates()` 85565a9ecf2SRichard Tran Mills on the restriction/interpolation operator to set the bindingpropagates flag to true. 85665a9ecf2SRichard Tran Mills 8571cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `VecSetBindingPropagates()`, `MatGetBindingPropagates()` 85865a9ecf2SRichard Tran Mills @*/ 859d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetBindingPropagates(Mat A, PetscBool flg) 860d71ae5a4SJacob Faibussowitsch { 86165a9ecf2SRichard Tran Mills PetscFunctionBegin; 86265a9ecf2SRichard Tran Mills PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 863d5e393b6SSuyash Tandon #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 86465a9ecf2SRichard Tran Mills A->bindingpropagates = flg; 86565a9ecf2SRichard Tran Mills #endif 8663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 86765a9ecf2SRichard Tran Mills } 868e9c74fd6SRichard Tran Mills 869e9c74fd6SRichard Tran Mills /*@ 870e9c74fd6SRichard Tran Mills MatGetBindingPropagates - Gets whether the state of being bound to the CPU for a GPU matrix type propagates to child and some other associated objects 871e9c74fd6SRichard Tran Mills 872e9c74fd6SRichard Tran Mills Input Parameter: 873e9c74fd6SRichard Tran Mills . A - the matrix 874e9c74fd6SRichard Tran Mills 875e9c74fd6SRichard Tran Mills Output Parameter: 876e9c74fd6SRichard Tran Mills . flg - flag indicating whether the boundtocpu flag will be propagated 877e9c74fd6SRichard Tran Mills 878e9c74fd6SRichard Tran Mills Level: developer 879e9c74fd6SRichard Tran Mills 8801cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatSetBindingPropagates()` 881e9c74fd6SRichard Tran Mills @*/ 882d71ae5a4SJacob Faibussowitsch PetscErrorCode MatGetBindingPropagates(Mat A, PetscBool *flg) 883d71ae5a4SJacob Faibussowitsch { 884e9c74fd6SRichard Tran Mills PetscFunctionBegin; 885e9c74fd6SRichard Tran Mills PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8864f572ea9SToby Isaac PetscAssertPointer(flg, 2); 887d5e393b6SSuyash Tandon #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 888e9c74fd6SRichard Tran Mills *flg = A->bindingpropagates; 889e9c74fd6SRichard Tran Mills #else 890e9c74fd6SRichard Tran Mills *flg = PETSC_FALSE; 891e9c74fd6SRichard Tran Mills #endif 8923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 893e9c74fd6SRichard Tran Mills } 894