1af0996ceSBarry Smith #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 27807a1faSBarry Smith 3d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatSetBlockSizes_Default(Mat mat, PetscInt rbs, PetscInt cbs) 4d71ae5a4SJacob Faibussowitsch { 546533700Sstefano_zampini PetscFunctionBegin; 63ba16761SJacob Faibussowitsch if (!mat->preallocated) PetscFunctionReturn(PETSC_SUCCESS); 7aed4548fSBarry 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); 8aed4548fSBarry 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); 93ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1046533700Sstefano_zampini } 1146533700Sstefano_zampini 12d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatShift_Basic(Mat Y, PetscScalar a) 13d71ae5a4SJacob Faibussowitsch { 147d68702bSBarry Smith PetscInt i, start, end; 157d68702bSBarry Smith PetscScalar alpha = a; 167d68702bSBarry Smith PetscBool prevoption; 177d68702bSBarry Smith 187d68702bSBarry Smith PetscFunctionBegin; 199566063dSJacob Faibussowitsch PetscCall(MatGetOption(Y, MAT_NO_OFF_PROC_ENTRIES, &prevoption)); 209566063dSJacob Faibussowitsch PetscCall(MatSetOption(Y, MAT_NO_OFF_PROC_ENTRIES, PETSC_TRUE)); 219566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(Y, &start, &end)); 227d68702bSBarry Smith for (i = start; i < end; i++) { 2348a46eb9SPierre Jolivet if (i < Y->cmap->N) PetscCall(MatSetValues(Y, 1, &i, 1, &i, &alpha, ADD_VALUES)); 24ab6153dcSStefano Zampini } 259566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(Y, MAT_FINAL_ASSEMBLY)); 269566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(Y, MAT_FINAL_ASSEMBLY)); 279566063dSJacob Faibussowitsch PetscCall(MatSetOption(Y, MAT_NO_OFF_PROC_ENTRIES, prevoption)); 283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 297d68702bSBarry Smith } 307d68702bSBarry Smith 3105869f15SSatish Balay /*@ 3269dd0797SLois Curfman McInnes MatCreate - Creates a matrix where the type is determined 3311a5261eSBarry Smith from either a call to `MatSetType()` or from the options database 342920cce0SJacob Faibussowitsch with a call to `MatSetFromOptions()`. 3583e1b59cSLois Curfman McInnes 36d083f849SBarry Smith Collective 37cb13003dSBarry Smith 38f69a0ea3SMatthew Knepley Input Parameter: 39f69a0ea3SMatthew Knepley . comm - MPI communicator 407807a1faSBarry Smith 417807a1faSBarry Smith Output Parameter: 42dc401e71SLois Curfman McInnes . A - the matrix 43e0b365e2SLois Curfman McInnes 44273d9f13SBarry Smith Options Database Keys: 4511a5261eSBarry Smith + -mat_type seqaij - `MATSEQAIJ` type, uses `MatCreateSeqAIJ()` 4611a5261eSBarry Smith . -mat_type mpiaij - `MATMPIAIJ` type, uses `MatCreateAIJ()` 4711a5261eSBarry Smith . -mat_type seqdense - `MATSEQDENSE`, uses `MatCreateSeqDense()` 4811a5261eSBarry Smith . -mat_type mpidense - `MATMPIDENSE` type, uses `MatCreateDense()` 4911a5261eSBarry Smith . -mat_type seqbaij - `MATSEQBAIJ` type, uses `MatCreateSeqBAIJ()` 5011a5261eSBarry Smith - -mat_type mpibaij - `MATMPIBAIJ` type, uses `MatCreateBAIJ()` 51e0b365e2SLois Curfman McInnes 522ef1f0ffSBarry Smith See the manpages for particular formats (e.g., `MATSEQAIJ`) 5383e1b59cSLois Curfman McInnes for additional format-specific options. 54e0b365e2SLois Curfman McInnes 55273d9f13SBarry Smith Level: beginner 56273d9f13SBarry Smith 572920cce0SJacob Faibussowitsch Notes: 582920cce0SJacob Faibussowitsch The default matrix type is `MATAIJ`, using the routines `MatCreateSeqAIJ()` or 592920cce0SJacob Faibussowitsch `MatCreateAIJ()` if you do not set a type in the options database. If you never call 602920cce0SJacob Faibussowitsch `MatSetType()` or `MatSetFromOptions()` it will generate an error when you try to use the 612920cce0SJacob Faibussowitsch matrix. 622920cce0SJacob Faibussowitsch 631cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatCreateSeqAIJ()`, `MatCreateAIJ()`, 64db781477SPatrick Sanan `MatCreateSeqDense()`, `MatCreateDense()`, 65db781477SPatrick Sanan `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, 66db781477SPatrick Sanan `MatCreateSeqSBAIJ()`, `MatCreateSBAIJ()`, 67db781477SPatrick Sanan `MatConvert()` 68273d9f13SBarry Smith @*/ 69d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreate(MPI_Comm comm, Mat *A) 70d71ae5a4SJacob Faibussowitsch { 71273d9f13SBarry Smith Mat B; 72273d9f13SBarry Smith 73273d9f13SBarry Smith PetscFunctionBegin; 744f572ea9SToby Isaac PetscAssertPointer(A, 2); 7597f1f81fSBarry Smith 760298fd71SBarry Smith *A = NULL; 779566063dSJacob Faibussowitsch PetscCall(MatInitializePackage()); 788ba1e511SMatthew Knepley 799566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(B, MAT_CLASSID, "Mat", "Matrix", "Mat", comm, MatDestroy, MatView)); 809566063dSJacob Faibussowitsch PetscCall(PetscLayoutCreate(comm, &B->rmap)); 819566063dSJacob Faibussowitsch PetscCall(PetscLayoutCreate(comm, &B->cmap)); 829566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(VECSTANDARD, &B->defaultvectype)); 833faff063SStefano Zampini PetscCall(PetscStrallocpy(PETSCRANDER48, &B->defaultrandtype)); 8426fbe8dcSKarl Rupp 85b94d7dedSBarry Smith B->symmetric = PETSC_BOOL3_UNKNOWN; 86b94d7dedSBarry Smith B->hermitian = PETSC_BOOL3_UNKNOWN; 87b94d7dedSBarry Smith B->structurally_symmetric = PETSC_BOOL3_UNKNOWN; 88b94d7dedSBarry Smith B->spd = PETSC_BOOL3_UNKNOWN; 89b94d7dedSBarry Smith B->symmetry_eternal = PETSC_FALSE; 90b94d7dedSBarry Smith B->structural_symmetry_eternal = PETSC_FALSE; 91b94d7dedSBarry Smith 9294342113SStefano Zampini B->congruentlayouts = PETSC_DECIDE; 93273d9f13SBarry Smith B->preallocated = PETSC_FALSE; 946f3d89d0SStefano Zampini #if defined(PETSC_HAVE_DEVICE) 956f3d89d0SStefano Zampini B->boundtocpu = PETSC_TRUE; 966f3d89d0SStefano Zampini #endif 97273d9f13SBarry Smith *A = B; 983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 99273d9f13SBarry Smith } 100273d9f13SBarry Smith 10177433607SBarry Smith /*@C 10277433607SBarry Smith MatCreateFromOptions - Creates a matrix whose type is set from the options database 10377433607SBarry Smith 10477433607SBarry Smith Collective 10577433607SBarry Smith 10677433607SBarry Smith Input Parameters: 10777433607SBarry Smith + comm - MPI communicator 10877433607SBarry Smith . prefix - [optional] prefix for the options database 10977433607SBarry Smith . bs - the blocksize (commonly 1) 11077433607SBarry Smith . m - the local number of rows (or `PETSC_DECIDE`) 11177433607SBarry Smith . n - the local number of columns (or `PETSC_DECIDE` or `PETSC_DETERMINE`) 11277433607SBarry Smith . M - the global number of rows (or `PETSC_DETERMINE`) 11377433607SBarry Smith - N - the global number of columns (or `PETSC_DETERMINE`) 11477433607SBarry Smith 11577433607SBarry Smith Output Parameter: 11677433607SBarry Smith . A - the matrix 11777433607SBarry Smith 11877433607SBarry Smith Options Database Key: 11977433607SBarry Smith . -mat_type - see `MatType`, for example `aij`, `aijcusparse`, `baij`, `sbaij`, dense, defaults to `aij` 12077433607SBarry Smith 12177433607SBarry Smith Level: beginner 12277433607SBarry Smith 12377433607SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatCreateSeqAIJ()`, `MatCreateAIJ()`, 12477433607SBarry Smith `MatCreateSeqDense()`, `MatCreateDense()`, 12577433607SBarry Smith `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, 12677433607SBarry Smith `MatCreateSeqSBAIJ()`, `MatCreateSBAIJ()`, 12777433607SBarry Smith `MatConvert()`, `MatCreate()` 12877433607SBarry Smith @*/ 12977433607SBarry Smith PetscErrorCode MatCreateFromOptions(MPI_Comm comm, const char *prefix, PetscInt bs, PetscInt m, PetscInt n, PetscInt M, PetscInt N, Mat *A) 13077433607SBarry Smith { 13177433607SBarry Smith PetscFunctionBegin; 13277433607SBarry Smith PetscAssertPointer(A, 8); 13377433607SBarry Smith PetscCall(MatCreate(comm, A)); 13477433607SBarry Smith if (prefix) PetscCall(MatSetOptionsPrefix(*A, prefix)); 13577433607SBarry Smith PetscCall(MatSetBlockSize(*A, bs)); 13677433607SBarry Smith PetscCall(MatSetSizes(*A, m, n, M, N)); 13777433607SBarry Smith PetscCall(MatSetFromOptions(*A)); 13877433607SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 13977433607SBarry Smith } 14077433607SBarry Smith 141422a814eSBarry Smith /*@ 14211a5261eSBarry Smith MatSetErrorIfFailure - Causes `Mat` to generate an immediate error, for example a zero pivot, is detected. 143422a814eSBarry Smith 144c3339decSBarry Smith Logically Collective 145422a814eSBarry Smith 146422a814eSBarry Smith Input Parameters: 14711a5261eSBarry Smith + mat - matrix obtained from `MatCreate()` 14811a5261eSBarry Smith - flg - `PETSC_TRUE` indicates you want the error generated 149422a814eSBarry Smith 150422a814eSBarry Smith Level: advanced 151422a814eSBarry Smith 15211a5261eSBarry Smith Note: 15311a5261eSBarry 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 15411a5261eSBarry Smith or result in a `KSPConvergedReason` indicating the method did not converge. 15511a5261eSBarry Smith 1561cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `PCSetErrorIfFailure()`, `KSPConvergedReason`, `SNESConvergedReason` 157422a814eSBarry Smith @*/ 158d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetErrorIfFailure(Mat mat, PetscBool flg) 159d71ae5a4SJacob Faibussowitsch { 160422a814eSBarry Smith PetscFunctionBegin; 161422a814eSBarry Smith PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 162422a814eSBarry Smith PetscValidLogicalCollectiveBool(mat, flg, 2); 16384d44b13SHong Zhang mat->erroriffailure = flg; 1643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 165422a814eSBarry Smith } 166422a814eSBarry Smith 167f69a0ea3SMatthew Knepley /*@ 168f69a0ea3SMatthew Knepley MatSetSizes - Sets the local and global sizes, and checks to determine compatibility 169f69a0ea3SMatthew Knepley 170c3339decSBarry Smith Collective 171f69a0ea3SMatthew Knepley 172f69a0ea3SMatthew Knepley Input Parameters: 173f69a0ea3SMatthew Knepley + A - the matrix 17411a5261eSBarry Smith . m - number of local rows (or `PETSC_DECIDE`) 17511a5261eSBarry Smith . n - number of local columns (or `PETSC_DECIDE`) 17611a5261eSBarry Smith . M - number of global rows (or `PETSC_DETERMINE`) 17711a5261eSBarry Smith - N - number of global columns (or `PETSC_DETERMINE`) 178f69a0ea3SMatthew Knepley 1792fe279fdSBarry Smith Level: beginner 1802fe279fdSBarry Smith 181f69a0ea3SMatthew Knepley Notes: 1822ef1f0ffSBarry Smith `m` (`n`) and `M` (`N`) cannot be both `PETSC_DECIDE` 1832ef1f0ffSBarry Smith If one processor calls this with `M` (`N`) of `PETSC_DECIDE` then all processors must, otherwise the program will hang. 184f69a0ea3SMatthew Knepley 18511a5261eSBarry Smith If `PETSC_DECIDE` is not used for the arguments 'm' and 'n', then the 186f69a0ea3SMatthew Knepley user must ensure that they are chosen to be compatible with the 187f69a0ea3SMatthew Knepley vectors. To do this, one first considers the matrix-vector product 1882ef1f0ffSBarry Smith 'y = A x'. The `m` that is used in the above routine must match the 1892ef1f0ffSBarry Smith local size used in the vector creation routine `VecCreateMPI()` for 'y'. 1902ef1f0ffSBarry Smith Likewise, the `n` used must match that used as the local size in 19111a5261eSBarry Smith `VecCreateMPI()` for 'x'. 192f69a0ea3SMatthew Knepley 193f73d5cc4SBarry Smith You cannot change the sizes once they have been set. 194f73d5cc4SBarry Smith 19511a5261eSBarry Smith The sizes must be set before `MatSetUp()` or MatXXXSetPreallocation() is called. 196f73d5cc4SBarry Smith 1971cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatGetSize()`, `PetscSplitOwnership()` 198f69a0ea3SMatthew Knepley @*/ 199d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetSizes(Mat A, PetscInt m, PetscInt n, PetscInt M, PetscInt N) 200d71ae5a4SJacob Faibussowitsch { 201f69a0ea3SMatthew Knepley PetscFunctionBegin; 2020700a824SBarry Smith PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 203a69c7061SStefano Zampini PetscValidLogicalCollectiveInt(A, M, 4); 204a69c7061SStefano Zampini PetscValidLogicalCollectiveInt(A, N, 5); 205aed4548fSBarry 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); 206aed4548fSBarry 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); 2079371c9d4SSatish 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, 2089371c9d4SSatish Balay A->rmap->n, A->rmap->N); 2099371c9d4SSatish 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, 2109371c9d4SSatish Balay A->cmap->n, A->cmap->N); 211d0f46423SBarry Smith A->rmap->n = m; 212d0f46423SBarry Smith A->cmap->n = n; 21359cb773eSBarry Smith A->rmap->N = M > -1 ? M : A->rmap->N; 21459cb773eSBarry Smith A->cmap->N = N > -1 ? N : A->cmap->N; 2153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 216f69a0ea3SMatthew Knepley } 217f69a0ea3SMatthew Knepley 21805869f15SSatish Balay /*@ 219273d9f13SBarry Smith MatSetFromOptions - Creates a matrix where the type is determined 2202920cce0SJacob Faibussowitsch from the options database. 221273d9f13SBarry Smith 222c3339decSBarry Smith Collective 223273d9f13SBarry Smith 224273d9f13SBarry Smith Input Parameter: 225fe59aa6dSJacob Faibussowitsch . B - the matrix 226273d9f13SBarry Smith 227273d9f13SBarry Smith Options Database Keys: 22811a5261eSBarry Smith + -mat_type seqaij - `MATSEQAIJ` type, uses `MatCreateSeqAIJ()` 22911a5261eSBarry Smith . -mat_type mpiaij - `MATMPIAIJ` type, uses `MatCreateAIJ()` 23011a5261eSBarry Smith . -mat_type seqdense - `MATSEQDENSE` type, uses `MatCreateSeqDense()` 23111a5261eSBarry Smith . -mat_type mpidense - `MATMPIDENSE`, uses `MatCreateDense()` 23211a5261eSBarry Smith . -mat_type seqbaij - `MATSEQBAIJ`, uses `MatCreateSeqBAIJ()` 23311a5261eSBarry Smith - -mat_type mpibaij - `MATMPIBAIJ`, uses `MatCreateBAIJ()` 234273d9f13SBarry Smith 2352ef1f0ffSBarry Smith See the manpages for particular formats (e.g., `MATSEQAIJ`) 236273d9f13SBarry Smith for additional format-specific options. 237bd9ce289SLois Curfman McInnes 2381d69843bSLois Curfman McInnes Level: beginner 2391d69843bSLois Curfman McInnes 2402920cce0SJacob Faibussowitsch Notes: 2412920cce0SJacob Faibussowitsch Generates a parallel MPI matrix if the communicator has more than one processor. The default 2422920cce0SJacob Faibussowitsch matrix type is `MATAIJ`, using the routines `MatCreateSeqAIJ()` and `MatCreateAIJ()` if you 2432920cce0SJacob Faibussowitsch do not select a type in the options database. 2442920cce0SJacob Faibussowitsch 2451cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatCreateSeqAIJ()`, `MatCreateAIJ()`, 246db781477SPatrick Sanan `MatCreateSeqDense()`, `MatCreateDense()`, 247db781477SPatrick Sanan `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, 248db781477SPatrick Sanan `MatCreateSeqSBAIJ()`, `MatCreateSBAIJ()`, 249db781477SPatrick Sanan `MatConvert()` 2507807a1faSBarry Smith @*/ 251d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetFromOptions(Mat B) 252d71ae5a4SJacob Faibussowitsch { 253f3be49caSLisandro Dalcin const char *deft = MATAIJ; 254f3be49caSLisandro Dalcin char type[256]; 25569df5c0cSJed Brown PetscBool flg, set; 25616e04d98SRichard Tran Mills PetscInt bind_below = 0; 257dbb450caSBarry Smith 2583a40ed3dSBarry Smith PetscFunctionBegin; 2590700a824SBarry Smith PetscValidHeaderSpecific(B, MAT_CLASSID, 1); 260f3be49caSLisandro Dalcin 261d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)B); 262535b19f3SBarry Smith 263535b19f3SBarry Smith if (B->rmap->bs < 0) { 264535b19f3SBarry Smith PetscInt newbs = -1; 2659566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-mat_block_size", "Set the blocksize used to store the matrix", "MatSetBlockSize", newbs, &newbs, &flg)); 266535b19f3SBarry Smith if (flg) { 2679566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetBlockSize(B->rmap, newbs)); 2689566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetBlockSize(B->cmap, newbs)); 269535b19f3SBarry Smith } 270535b19f3SBarry Smith } 271535b19f3SBarry Smith 2729566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-mat_type", "Matrix type", "MatSetType", MatList, deft, type, 256, &flg)); 273273d9f13SBarry Smith if (flg) { 2749566063dSJacob Faibussowitsch PetscCall(MatSetType(B, type)); 275f3be49caSLisandro Dalcin } else if (!((PetscObject)B)->type_name) { 2769566063dSJacob Faibussowitsch PetscCall(MatSetType(B, deft)); 277273d9f13SBarry Smith } 278f3be49caSLisandro Dalcin 2799566063dSJacob Faibussowitsch PetscCall(PetscOptionsName("-mat_is_symmetric", "Checks if mat is symmetric on MatAssemblyEnd()", "MatIsSymmetric", &B->checksymmetryonassembly)); 2809566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-mat_is_symmetric", "Checks if mat is symmetric on MatAssemblyEnd()", "MatIsSymmetric", B->checksymmetrytol, &B->checksymmetrytol, NULL)); 2819566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-mat_null_space_test", "Checks if provided null space is correct in MatAssemblyEnd()", "MatSetNullSpaceTest", B->checknullspaceonassembly, &B->checknullspaceonassembly, NULL)); 2829566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-mat_error_if_failure", "Generate an error if an error occurs when factoring the matrix", "MatSetErrorIfFailure", B->erroriffailure, &B->erroriffailure, NULL)); 283840d65ccSBarry Smith 284dbbe0bcdSBarry Smith PetscTryTypeMethod(B, setfromoptions, PetscOptionsObject); 285f3be49caSLisandro Dalcin 28669df5c0cSJed Brown flg = PETSC_FALSE; 2879566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-mat_new_nonzero_location_err", "Generate an error if new nonzeros are created in the matrix structure (useful to test preallocation)", "MatSetOption", flg, &flg, &set)); 2889566063dSJacob Faibussowitsch if (set) PetscCall(MatSetOption(B, MAT_NEW_NONZERO_LOCATION_ERR, flg)); 28969df5c0cSJed Brown flg = PETSC_FALSE; 2909566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-mat_new_nonzero_allocation_err", "Generate an error if new nonzeros are allocated in the matrix structure (useful to test preallocation)", "MatSetOption", flg, &flg, &set)); 2919566063dSJacob Faibussowitsch if (set) PetscCall(MatSetOption(B, MAT_NEW_NONZERO_ALLOCATION_ERR, flg)); 292478db826SMatthew G. Knepley flg = PETSC_FALSE; 2939566063dSJacob 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)); 2949566063dSJacob Faibussowitsch if (set) PetscCall(MatSetOption(B, MAT_IGNORE_ZERO_ENTRIES, flg)); 29569df5c0cSJed Brown 2961a2c6b5cSJunchao Zhang flg = PETSC_FALSE; 2979566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-mat_form_explicit_transpose", "Hint to form an explicit transpose for operations like MatMultTranspose", "MatSetOption", flg, &flg, &set)); 2989566063dSJacob Faibussowitsch if (set) PetscCall(MatSetOption(B, MAT_FORM_EXPLICIT_TRANSPOSE, flg)); 2991a2c6b5cSJunchao Zhang 30016e04d98SRichard Tran Mills /* Bind to CPU if below a user-specified size threshold. 30116e04d98SRichard Tran Mills * This perhaps belongs in the options for the GPU Mat types, but MatBindToCPU() does nothing when called on non-GPU types, 30216e04d98SRichard Tran Mills * and putting it here makes is more maintainable than duplicating this for all. */ 3039566063dSJacob 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)); 30448a46eb9SPierre Jolivet if (flg && B->rmap->n < bind_below) PetscCall(MatBindToCPU(B, PETSC_TRUE)); 30516e04d98SRichard Tran Mills 3065d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 307dbbe0bcdSBarry Smith PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)B, PetscOptionsObject)); 308d0609cedSBarry Smith PetscOptionsEnd(); 3093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3107807a1faSBarry Smith } 3117807a1faSBarry Smith 312987010e7SBarry Smith /*@C 31311a5261eSBarry Smith MatXAIJSetPreallocation - set preallocation for serial and parallel `MATAIJ`, `MATBAIJ`, and `MATSBAIJ` matrices and their unassembled versions. 31463562e91SJed Brown 315c3339decSBarry Smith Collective 31663562e91SJed Brown 3174165533cSJose E. Roman Input Parameters: 31863562e91SJed Brown + A - matrix being preallocated 31963562e91SJed Brown . bs - block size 32041319c1dSStefano Zampini . dnnz - number of nonzero column blocks per block row of diagonal part of parallel matrix 32141319c1dSStefano Zampini . onnz - number of nonzero column blocks per block row of off-diagonal part of parallel matrix 32241319c1dSStefano Zampini . dnnzu - number of nonzero column blocks per block row of upper-triangular part of diagonal part of parallel matrix 32341319c1dSStefano Zampini - onnzu - number of nonzero column blocks per block row of upper-triangular part of off-diagonal part of parallel matrix 32463562e91SJed Brown 32563562e91SJed Brown Level: beginner 32663562e91SJed Brown 3271cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatSeqAIJSetPreallocation()`, `MatMPIAIJSetPreallocation()`, `MatSeqBAIJSetPreallocation()`, `MatMPIBAIJSetPreallocation()`, 3282fe279fdSBarry Smith `MatSeqSBAIJSetPreallocation()`, `MatMPISBAIJSetPreallocation()`, 329db781477SPatrick Sanan `PetscSplitOwnership()` 33063562e91SJed Brown @*/ 331d71ae5a4SJacob Faibussowitsch PetscErrorCode MatXAIJSetPreallocation(Mat A, PetscInt bs, const PetscInt dnnz[], const PetscInt onnz[], const PetscInt dnnzu[], const PetscInt onnzu[]) 332d71ae5a4SJacob Faibussowitsch { 33341319c1dSStefano Zampini PetscInt cbs; 33463562e91SJed Brown void (*aij)(void); 335e8bd9bafSStefano Zampini void (*is)(void); 336990279feSStefano Zampini void (*hyp)(void) = NULL; 33763562e91SJed Brown 33863562e91SJed Brown PetscFunctionBegin; 33941319c1dSStefano Zampini if (bs != PETSC_DECIDE) { /* don't mess with an already set block size */ 3409566063dSJacob Faibussowitsch PetscCall(MatSetBlockSize(A, bs)); 34141319c1dSStefano Zampini } 3429566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 3439566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 3449566063dSJacob Faibussowitsch PetscCall(MatGetBlockSizes(A, &bs, &cbs)); 34541319c1dSStefano Zampini /* these routines assumes bs == cbs, this should be checked somehow */ 3469566063dSJacob Faibussowitsch PetscCall(MatSeqBAIJSetPreallocation(A, bs, 0, dnnz)); 3479566063dSJacob Faibussowitsch PetscCall(MatMPIBAIJSetPreallocation(A, bs, 0, dnnz, 0, onnz)); 3489566063dSJacob Faibussowitsch PetscCall(MatSeqSBAIJSetPreallocation(A, bs, 0, dnnzu)); 3499566063dSJacob Faibussowitsch PetscCall(MatMPISBAIJSetPreallocation(A, bs, 0, dnnzu, 0, onnzu)); 35063562e91SJed Brown /* 351e8bd9bafSStefano 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 35263562e91SJed Brown good before going on with it. 35363562e91SJed Brown */ 3549566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatMPIAIJSetPreallocation_C", &aij)); 3559566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatISSetPreallocation_C", &is)); 356990279feSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 3579566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatHYPRESetPreallocation_C", &hyp)); 358990279feSStefano Zampini #endif 35948a46eb9SPierre Jolivet if (!aij && !is && !hyp) PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatSeqAIJSetPreallocation_C", &aij)); 360990279feSStefano Zampini if (aij || is || hyp) { 36141319c1dSStefano Zampini if (bs == cbs && bs == 1) { 3629566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(A, 0, dnnz)); 3639566063dSJacob Faibussowitsch PetscCall(MatMPIAIJSetPreallocation(A, 0, dnnz, 0, onnz)); 3649566063dSJacob Faibussowitsch PetscCall(MatISSetPreallocation(A, 0, dnnz, 0, onnz)); 365990279feSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 3669566063dSJacob Faibussowitsch PetscCall(MatHYPRESetPreallocation(A, 0, dnnz, 0, onnz)); 367990279feSStefano Zampini #endif 3683e5f4774SJed Brown } else { /* Convert block-row precallocation to scalar-row */ 36963562e91SJed Brown PetscInt i, m, *sdnnz, *sonnz; 3709566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(A, &m, NULL)); 3719566063dSJacob Faibussowitsch PetscCall(PetscMalloc2((!!dnnz) * m, &sdnnz, (!!onnz) * m, &sonnz)); 372dec54756SJed Brown for (i = 0; i < m; i++) { 37341319c1dSStefano Zampini if (dnnz) sdnnz[i] = dnnz[i / bs] * cbs; 37441319c1dSStefano Zampini if (onnz) sonnz[i] = onnz[i / bs] * cbs; 37563562e91SJed Brown } 3769566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(A, 0, dnnz ? sdnnz : NULL)); 3779566063dSJacob Faibussowitsch PetscCall(MatMPIAIJSetPreallocation(A, 0, dnnz ? sdnnz : NULL, 0, onnz ? sonnz : NULL)); 3789566063dSJacob Faibussowitsch PetscCall(MatISSetPreallocation(A, 0, dnnz ? sdnnz : NULL, 0, onnz ? sonnz : NULL)); 379990279feSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 3809566063dSJacob Faibussowitsch PetscCall(MatHYPRESetPreallocation(A, 0, dnnz ? sdnnz : NULL, 0, onnz ? sonnz : NULL)); 381990279feSStefano Zampini #endif 3829566063dSJacob Faibussowitsch PetscCall(PetscFree2(sdnnz, sonnz)); 38363562e91SJed Brown } 38463562e91SJed Brown } 3853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38663562e91SJed Brown } 38763562e91SJed Brown 388273d9f13SBarry Smith /* 389eb6b5d47SBarry Smith Merges some information from Cs header to A; the C object is then destroyed 390d0f46423SBarry Smith 391d0f46423SBarry Smith This is somewhat different from MatHeaderReplace() it would be nice to merge the code 392273d9f13SBarry Smith */ 393d71ae5a4SJacob Faibussowitsch PetscErrorCode MatHeaderMerge(Mat A, Mat *C) 394d71ae5a4SJacob Faibussowitsch { 395d44834fbSBarry Smith PetscInt refct; 39673107ff1SLisandro Dalcin PetscOps Abops; 39773107ff1SLisandro Dalcin struct _MatOps Aops; 3984768301cSVaclav Hapla char *mtype, *mname, *mprefix; 3994222ddf1SHong Zhang Mat_Product *product; 40033e6eea4SJose E. Roman Mat_Redundant *redundant; 401d4a972cbSStefano Zampini PetscObjectState state; 402273d9f13SBarry Smith 403273d9f13SBarry Smith PetscFunctionBegin; 4041dc04de0SStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 4051dc04de0SStefano Zampini PetscValidHeaderSpecific(*C, MAT_CLASSID, 2); 4063ba16761SJacob Faibussowitsch if (A == *C) PetscFunctionReturn(PETSC_SUCCESS); 4071dc04de0SStefano Zampini PetscCheckSameComm(A, 1, *C, 2); 408273d9f13SBarry Smith /* save the parts of A we need */ 40973107ff1SLisandro Dalcin Abops = ((PetscObject)A)->bops[0]; 41073107ff1SLisandro Dalcin Aops = A->ops[0]; 4117adad957SLisandro Dalcin refct = ((PetscObject)A)->refct; 4125c9eb25fSBarry Smith mtype = ((PetscObject)A)->type_name; 4135c9eb25fSBarry Smith mname = ((PetscObject)A)->name; 414d4a972cbSStefano Zampini state = ((PetscObject)A)->state; 4154768301cSVaclav Hapla mprefix = ((PetscObject)A)->prefix; 4164222ddf1SHong Zhang product = A->product; 41733e6eea4SJose E. Roman redundant = A->redundant; 41830735b05SKris Buschelman 4195c9eb25fSBarry Smith /* zero these so the destroy below does not free them */ 420f4259b30SLisandro Dalcin ((PetscObject)A)->type_name = NULL; 421f4259b30SLisandro Dalcin ((PetscObject)A)->name = NULL; 4225c9eb25fSBarry Smith 423dbbe0bcdSBarry Smith /* 424dbbe0bcdSBarry Smith free all the interior data structures from mat 425dbbe0bcdSBarry Smith cannot use PetscUseTypeMethod(A,destroy); because compiler 426dbbe0bcdSBarry Smith thinks it may print NULL type_name and name 427dbbe0bcdSBarry Smith */ 428dbbe0bcdSBarry Smith PetscTryTypeMethod(A, destroy); 4297c99f97cSSatish Balay 4309566063dSJacob Faibussowitsch PetscCall(PetscFree(A->defaultvectype)); 4313faff063SStefano Zampini PetscCall(PetscFree(A->defaultrandtype)); 4329566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&A->rmap)); 4339566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&A->cmap)); 4349566063dSJacob Faibussowitsch PetscCall(PetscFunctionListDestroy(&((PetscObject)A)->qlist)); 4359566063dSJacob Faibussowitsch PetscCall(PetscObjectListDestroy(&((PetscObject)A)->olist)); 4369566063dSJacob Faibussowitsch PetscCall(PetscComposedQuantitiesDestroy((PetscObject)A)); 437273d9f13SBarry Smith 438273d9f13SBarry Smith /* copy C over to A */ 43926cc229bSBarry Smith PetscCall(PetscFree(A->factorprefix)); 4409566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(A, *C, sizeof(struct _p_Mat))); 441273d9f13SBarry Smith 442273d9f13SBarry Smith /* return the parts of A we saved */ 44373107ff1SLisandro Dalcin ((PetscObject)A)->bops[0] = Abops; 44473107ff1SLisandro Dalcin A->ops[0] = Aops; 4457adad957SLisandro Dalcin ((PetscObject)A)->refct = refct; 4467adad957SLisandro Dalcin ((PetscObject)A)->type_name = mtype; 4477adad957SLisandro Dalcin ((PetscObject)A)->name = mname; 4484768301cSVaclav Hapla ((PetscObject)A)->prefix = mprefix; 449d4a972cbSStefano Zampini ((PetscObject)A)->state = state + 1; 4504222ddf1SHong Zhang A->product = product; 45133e6eea4SJose E. Roman A->redundant = redundant; 452273d9f13SBarry Smith 4535c9eb25fSBarry Smith /* since these two are copied into A we do not want them destroyed in C */ 454f4259b30SLisandro Dalcin ((PetscObject)*C)->qlist = NULL; 455f4259b30SLisandro Dalcin ((PetscObject)*C)->olist = NULL; 45626fbe8dcSKarl Rupp 4579566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(C)); 4583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 459273d9f13SBarry Smith } 4608ab5b326SKris Buschelman /* 461eb6b5d47SBarry Smith Replace A's header with that of C; the C object is then destroyed 462d0f46423SBarry Smith 463eb6b5d47SBarry Smith This is essentially code moved from MatDestroy() 464eb6b5d47SBarry Smith 465eb6b5d47SBarry Smith This is somewhat different from MatHeaderMerge() it would be nice to merge the code 466b30237c6SBarry Smith 467b30237c6SBarry Smith Used in DM hence is declared PETSC_EXTERN 4688ab5b326SKris Buschelman */ 469d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode MatHeaderReplace(Mat A, Mat *C) 470d71ae5a4SJacob Faibussowitsch { 47127b31e29SJed Brown PetscInt refct; 472fefd9316SJose E. Roman PetscObjectState state; 47328be2f97SBarry Smith struct _p_Mat buffer; 47481fa06acSBarry Smith MatStencilInfo stencil; 4758ab5b326SKris Buschelman 4768ab5b326SKris Buschelman PetscFunctionBegin; 47727b31e29SJed Brown PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 47828be2f97SBarry Smith PetscValidHeaderSpecific(*C, MAT_CLASSID, 2); 4793ba16761SJacob Faibussowitsch if (A == *C) PetscFunctionReturn(PETSC_SUCCESS); 48028be2f97SBarry Smith PetscCheckSameComm(A, 1, *C, 2); 481aed4548fSBarry 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); 4826d7c1e57SBarry Smith 48328be2f97SBarry Smith /* swap C and A */ 48427b31e29SJed Brown refct = ((PetscObject)A)->refct; 485fefd9316SJose E. Roman state = ((PetscObject)A)->state; 48681fa06acSBarry Smith stencil = A->stencil; 4879566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(&buffer, A, sizeof(struct _p_Mat))); 4889566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(A, *C, sizeof(struct _p_Mat))); 4899566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(*C, &buffer, sizeof(struct _p_Mat))); 49027b31e29SJed Brown ((PetscObject)A)->refct = refct; 491fefd9316SJose E. Roman ((PetscObject)A)->state = state + 1; 49281fa06acSBarry Smith A->stencil = stencil; 49326fbe8dcSKarl Rupp 494c32d4117SBarry Smith ((PetscObject)*C)->refct = 1; 4959566063dSJacob Faibussowitsch PetscCall(MatShellSetOperation(*C, MATOP_DESTROY, (void (*)(void))NULL)); 4969566063dSJacob Faibussowitsch PetscCall(MatDestroy(C)); 4973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4988ab5b326SKris Buschelman } 499e7e92044SBarry Smith 500e7e92044SBarry Smith /*@ 501b470e4b4SRichard Tran Mills MatBindToCPU - marks a matrix to temporarily stay on the CPU and perform computations on the CPU 502e7e92044SBarry Smith 5032ef1f0ffSBarry Smith Logically Collective 5042216c58aSStefano Zampini 505e7e92044SBarry Smith Input Parameters: 506e7e92044SBarry Smith + A - the matrix 50711a5261eSBarry Smith - flg - bind to the CPU if value of `PETSC_TRUE` 508e7e92044SBarry Smith 50990ea27d8SSatish Balay Level: intermediate 5102216c58aSStefano Zampini 5111cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatBoundToCPU()` 512e7e92044SBarry Smith @*/ 513d71ae5a4SJacob Faibussowitsch PetscErrorCode MatBindToCPU(Mat A, PetscBool flg) 514d71ae5a4SJacob Faibussowitsch { 5157d871021SStefano Zampini PetscFunctionBegin; 5162ffa8ee7SStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 5172ffa8ee7SStefano Zampini PetscValidLogicalCollectiveBool(A, flg, 2); 5182216c58aSStefano Zampini #if defined(PETSC_HAVE_DEVICE) 5193ba16761SJacob Faibussowitsch if (A->boundtocpu == flg) PetscFunctionReturn(PETSC_SUCCESS); 520b470e4b4SRichard Tran Mills A->boundtocpu = flg; 521dbbe0bcdSBarry Smith PetscTryTypeMethod(A, bindtocpu, flg); 5222216c58aSStefano Zampini #endif 5233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5242216c58aSStefano Zampini } 5252216c58aSStefano Zampini 5262216c58aSStefano Zampini /*@ 5272216c58aSStefano Zampini MatBoundToCPU - query if a matrix is bound to the CPU 5282216c58aSStefano Zampini 5292216c58aSStefano Zampini Input Parameter: 5302216c58aSStefano Zampini . A - the matrix 5312216c58aSStefano Zampini 5322216c58aSStefano Zampini Output Parameter: 5332216c58aSStefano Zampini . flg - the logical flag 5342216c58aSStefano Zampini 5352216c58aSStefano Zampini Level: intermediate 5362216c58aSStefano Zampini 5371cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatBindToCPU()` 5382216c58aSStefano Zampini @*/ 539d71ae5a4SJacob Faibussowitsch PetscErrorCode MatBoundToCPU(Mat A, PetscBool *flg) 540d71ae5a4SJacob Faibussowitsch { 5412ffa8ee7SStefano Zampini PetscFunctionBegin; 5422ffa8ee7SStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 5434f572ea9SToby Isaac PetscAssertPointer(flg, 2); 5442216c58aSStefano Zampini #if defined(PETSC_HAVE_DEVICE) 5452216c58aSStefano Zampini *flg = A->boundtocpu; 5462216c58aSStefano Zampini #else 5472216c58aSStefano Zampini *flg = PETSC_TRUE; 5487d871021SStefano Zampini #endif 5493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 550e7e92044SBarry Smith } 5517e8381f9SStefano Zampini 552d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetValuesCOO_Basic(Mat A, const PetscScalar coo_v[], InsertMode imode) 553d71ae5a4SJacob Faibussowitsch { 5547e8381f9SStefano Zampini IS is_coo_i, is_coo_j; 5557e8381f9SStefano Zampini const PetscInt *coo_i, *coo_j; 5567e8381f9SStefano Zampini PetscInt n, n_i, n_j; 5577e8381f9SStefano Zampini PetscScalar zero = 0.; 5587e8381f9SStefano Zampini 5597e8381f9SStefano Zampini PetscFunctionBegin; 5609566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)A, "__PETSc_coo_i", (PetscObject *)&is_coo_i)); 5619566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)A, "__PETSc_coo_j", (PetscObject *)&is_coo_j)); 56228b400f6SJacob Faibussowitsch PetscCheck(is_coo_i, PetscObjectComm((PetscObject)A), PETSC_ERR_COR, "Missing coo_i IS"); 56328b400f6SJacob Faibussowitsch PetscCheck(is_coo_j, PetscObjectComm((PetscObject)A), PETSC_ERR_COR, "Missing coo_j IS"); 5649566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(is_coo_i, &n_i)); 5659566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(is_coo_j, &n_j)); 56608401ef6SPierre Jolivet PetscCheck(n_i == n_j, PETSC_COMM_SELF, PETSC_ERR_COR, "Wrong local size %" PetscInt_FMT " != %" PetscInt_FMT, n_i, n_j); 5679566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is_coo_i, &coo_i)); 5689566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is_coo_j, &coo_j)); 56948a46eb9SPierre Jolivet if (imode != ADD_VALUES) PetscCall(MatZeroEntries(A)); 57048a46eb9SPierre 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)); 5719566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is_coo_i, &coo_i)); 5729566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is_coo_j, &coo_j)); 5733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5747e8381f9SStefano Zampini } 5757e8381f9SStefano Zampini 576*8063e3c8SPierre Jolivet PetscErrorCode MatSetPreallocationCOO_Basic(Mat A, PetscCount ncoo, PetscInt coo_i[], PetscInt coo_j[]) 577d71ae5a4SJacob Faibussowitsch { 5787e8381f9SStefano Zampini Mat preallocator; 5797e8381f9SStefano Zampini IS is_coo_i, is_coo_j; 5807e8381f9SStefano Zampini PetscScalar zero = 0.0; 5817e8381f9SStefano Zampini 5827e8381f9SStefano Zampini PetscFunctionBegin; 5839566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 5849566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 5859566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &preallocator)); 5869566063dSJacob Faibussowitsch PetscCall(MatSetType(preallocator, MATPREALLOCATOR)); 5879566063dSJacob Faibussowitsch PetscCall(MatSetSizes(preallocator, A->rmap->n, A->cmap->n, A->rmap->N, A->cmap->N)); 5889566063dSJacob Faibussowitsch PetscCall(MatSetLayouts(preallocator, A->rmap, A->cmap)); 5899566063dSJacob Faibussowitsch PetscCall(MatSetUp(preallocator)); 59048a46eb9SPierre Jolivet for (PetscCount n = 0; n < ncoo; n++) PetscCall(MatSetValue(preallocator, coo_i[n], coo_j[n], zero, INSERT_VALUES)); 5919566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(preallocator, MAT_FINAL_ASSEMBLY)); 5929566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(preallocator, MAT_FINAL_ASSEMBLY)); 5939566063dSJacob Faibussowitsch PetscCall(MatPreallocatorPreallocate(preallocator, PETSC_TRUE, A)); 5949566063dSJacob Faibussowitsch PetscCall(MatDestroy(&preallocator)); 5952c71b3e2SJacob Faibussowitsch PetscCheck(ncoo <= PETSC_MAX_INT, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "ncoo %" PetscCount_FMT " overflowed PetscInt; configure --with-64-bit-indices or request support", ncoo); 5969566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, ncoo, coo_i, PETSC_COPY_VALUES, &is_coo_i)); 5979566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, ncoo, coo_j, PETSC_COPY_VALUES, &is_coo_j)); 5989566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "__PETSc_coo_i", (PetscObject)is_coo_i)); 5999566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "__PETSc_coo_j", (PetscObject)is_coo_j)); 6009566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is_coo_i)); 6019566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is_coo_j)); 6023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6037e8381f9SStefano Zampini } 6047e8381f9SStefano Zampini 60556856777SBarry Smith /*@C 606c3dd2894SJed Brown MatSetPreallocationCOO - set preallocation for matrices using a coordinate format of the entries with global indices 6077e8381f9SStefano Zampini 608c3339decSBarry Smith Collective 6097e8381f9SStefano Zampini 6104165533cSJose E. Roman Input Parameters: 6117e8381f9SStefano Zampini + A - matrix being preallocated 61242550becSJunchao Zhang . ncoo - number of entries 6137e8381f9SStefano Zampini . coo_i - row indices 6147e8381f9SStefano Zampini - coo_j - column indices 6157e8381f9SStefano Zampini 6167e8381f9SStefano Zampini Level: beginner 6177e8381f9SStefano Zampini 618394ed5ebSJunchao Zhang Notes: 6192ef1f0ffSBarry Smith The indices `coo_i` and `coo_j` may be modified within this function. The caller should not rely on them 620e8729f6fSJunchao Zhang having any specific value after this function returns. The arrays can be freed or reused immediately 621e8729f6fSJunchao Zhang after this function returns. 622e8729f6fSJunchao Zhang 62311a5261eSBarry Smith Entries can be repeated, see `MatSetValuesCOO()`. Entries with negative row or column indices are allowed 62411a5261eSBarry Smith but will be ignored. The corresponding entries in `MatSetValuesCOO()` will be ignored too. Remote entries 625d7547e51SJunchao Zhang are allowed and will be properly added or inserted to the matrix, unless the matrix option `MAT_IGNORE_OFF_PROC_ENTRIES` 62611a5261eSBarry 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. 6277e8381f9SStefano Zampini 628d7547e51SJunchao 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 629d7547e51SJunchao Zhang `MatCreateSeqAIJFromTriple()`. But that is not recommended for iterative applications. 630d7547e51SJunchao Zhang 6311cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatSetValuesCOO()`, `MatSeqAIJSetPreallocation()`, `MatMPIAIJSetPreallocation()`, `MatSeqBAIJSetPreallocation()`, 6322ef1f0ffSBarry Smith `MatMPIBAIJSetPreallocation()`, `MatSeqSBAIJSetPreallocation()`, `MatMPISBAIJSetPreallocation()`, `MatSetPreallocationCOOLocal()`, 6332ef1f0ffSBarry Smith `DMSetMatrixPreallocateSkip()`, `MatCreateSeqAIJFromTriple()` 6347e8381f9SStefano Zampini @*/ 635d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetPreallocationCOO(Mat A, PetscCount ncoo, PetscInt coo_i[], PetscInt coo_j[]) 636d71ae5a4SJacob Faibussowitsch { 637*8063e3c8SPierre Jolivet PetscErrorCode (*f)(Mat, PetscCount, PetscInt[], PetscInt[]) = NULL; 6387e8381f9SStefano Zampini 6397e8381f9SStefano Zampini PetscFunctionBegin; 6407e8381f9SStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 6417e8381f9SStefano Zampini PetscValidType(A, 1); 6424f572ea9SToby Isaac if (ncoo) PetscAssertPointer(coo_i, 3); 6434f572ea9SToby Isaac if (ncoo) PetscAssertPointer(coo_j, 4); 6449566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 6459566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 6469566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatSetPreallocationCOO_C", &f)); 647cbc6b225SStefano Zampini 6489566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(MAT_PreallCOO, A, 0, 0, 0)); 6497e8381f9SStefano Zampini if (f) { 6509566063dSJacob Faibussowitsch PetscCall((*f)(A, ncoo, coo_i, coo_j)); 6517e8381f9SStefano Zampini } else { /* allow fallback, very slow */ 6529566063dSJacob Faibussowitsch PetscCall(MatSetPreallocationCOO_Basic(A, ncoo, coo_i, coo_j)); 6537e8381f9SStefano Zampini } 6549566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(MAT_PreallCOO, A, 0, 0, 0)); 6556834774dSStefano Zampini A->preallocated = PETSC_TRUE; 656cbc6b225SStefano Zampini A->nonzerostate++; 6573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6587e8381f9SStefano Zampini } 6597e8381f9SStefano Zampini 66056856777SBarry Smith /*@C 661c3dd2894SJed Brown MatSetPreallocationCOOLocal - set preallocation for matrices using a coordinate format of the entries with local indices 662c3dd2894SJed Brown 663c3339decSBarry Smith Collective 664c3dd2894SJed Brown 665c3dd2894SJed Brown Input Parameters: 666c3dd2894SJed Brown + A - matrix being preallocated 667c3dd2894SJed Brown . ncoo - number of entries 668c3dd2894SJed Brown . coo_i - row indices (local numbering; may be modified) 669c3dd2894SJed Brown - coo_j - column indices (local numbering; may be modified) 670c3dd2894SJed Brown 671c3dd2894SJed Brown Level: beginner 672c3dd2894SJed Brown 673c3dd2894SJed Brown Notes: 67411a5261eSBarry Smith The local indices are translated using the local to global mapping, thus `MatSetLocalToGlobalMapping()` must have been 67511a5261eSBarry Smith called prior to this function. For matrices created with `DMCreateMatrix()` the local to global mapping is often already provided. 676c3dd2894SJed Brown 6772ef1f0ffSBarry Smith The indices `coo_i` and `coo_j` may be modified within this function. They might be translated to corresponding global 678735d7f90SBarry Smith indices, but the caller should not rely on them having any specific value after this function returns. The arrays 679735d7f90SBarry Smith can be freed or reused immediately after this function returns. 680c3dd2894SJed Brown 68111a5261eSBarry Smith Entries can be repeated, see `MatSetValuesCOO()`. Entries with negative row or column indices are allowed 68211a5261eSBarry Smith but will be ignored. The corresponding entries in `MatSetValuesCOO()` will be ignored too. Remote entries 683394ed5ebSJunchao Zhang are allowed and will be properly added or inserted to the matrix. 684c3dd2894SJed Brown 6851cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatSetValuesCOO()`, `MatSeqAIJSetPreallocation()`, `MatMPIAIJSetPreallocation()`, `MatSeqBAIJSetPreallocation()`, 6862ef1f0ffSBarry Smith `MatMPIBAIJSetPreallocation()`, `MatSeqSBAIJSetPreallocation()`, `MatMPISBAIJSetPreallocation()`, `MatSetPreallocationCOO()`, 6872ef1f0ffSBarry Smith `DMSetMatrixPreallocateSkip()` 688c3dd2894SJed Brown @*/ 689d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetPreallocationCOOLocal(Mat A, PetscCount ncoo, PetscInt coo_i[], PetscInt coo_j[]) 690d71ae5a4SJacob Faibussowitsch { 6916834774dSStefano Zampini PetscErrorCode (*f)(Mat, PetscCount, PetscInt[], PetscInt[]) = NULL; 692c3dd2894SJed Brown 693c3dd2894SJed Brown PetscFunctionBegin; 694c3dd2894SJed Brown PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 695c3dd2894SJed Brown PetscValidType(A, 1); 6964f572ea9SToby Isaac if (ncoo) PetscAssertPointer(coo_i, 3); 6974f572ea9SToby Isaac if (ncoo) PetscAssertPointer(coo_j, 4); 6986834774dSStefano Zampini PetscCheck(ncoo <= PETSC_MAX_INT, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "ncoo %" PetscCount_FMT " overflowed PetscInt; configure --with-64-bit-indices or request support", ncoo); 6999566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 7009566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 701cbc6b225SStefano Zampini 7029566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatSetPreallocationCOOLocal_C", &f)); 7036834774dSStefano Zampini if (f) { 7049566063dSJacob Faibussowitsch PetscCall((*f)(A, ncoo, coo_i, coo_j)); 705cbc6b225SStefano Zampini A->nonzerostate++; 7066834774dSStefano Zampini } else { 707cbc6b225SStefano Zampini ISLocalToGlobalMapping ltog_row, ltog_col; 7089566063dSJacob Faibussowitsch PetscCall(MatGetLocalToGlobalMapping(A, <og_row, <og_col)); 7099566063dSJacob Faibussowitsch if (ltog_row) PetscCall(ISLocalToGlobalMappingApply(ltog_row, ncoo, coo_i, coo_i)); 7109566063dSJacob Faibussowitsch if (ltog_col) PetscCall(ISLocalToGlobalMappingApply(ltog_col, ncoo, coo_j, coo_j)); 7119566063dSJacob Faibussowitsch PetscCall(MatSetPreallocationCOO(A, ncoo, coo_i, coo_j)); 7126834774dSStefano Zampini } 7136834774dSStefano Zampini A->preallocated = PETSC_TRUE; 7143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 715c3dd2894SJed Brown } 716c3dd2894SJed Brown 717c3dd2894SJed Brown /*@ 71811a5261eSBarry Smith MatSetValuesCOO - set values at once in a matrix preallocated using `MatSetPreallocationCOO()` 7197e8381f9SStefano Zampini 720c3339decSBarry Smith Collective 7217e8381f9SStefano Zampini 7224165533cSJose E. Roman Input Parameters: 7237e8381f9SStefano Zampini + A - matrix being preallocated 7242ef1f0ffSBarry Smith . coo_v - the matrix values (can be `NULL`) 7257e8381f9SStefano Zampini - imode - the insert mode 7267e8381f9SStefano Zampini 7277e8381f9SStefano Zampini Level: beginner 7287e8381f9SStefano Zampini 72911a5261eSBarry Smith Notes: 73011a5261eSBarry Smith The values must follow the order of the indices prescribed with `MatSetPreallocationCOO()` or `MatSetPreallocationCOOLocal()`. 73111a5261eSBarry Smith 7322ef1f0ffSBarry Smith When repeated entries are specified in the COO indices the `coo_v` values are first properly summed, regardless of the value of imode. 73311a5261eSBarry Smith The imode flag indicates if coo_v must be added to the current values of the matrix (`ADD_VALUES`) or overwritten (`INSERT_VALUES`). 73411a5261eSBarry Smith 73511a5261eSBarry Smith `MatAssemblyBegin()` and `MatAssemblyEnd()` do not need to be called after this routine. It automatically handles the assembly process. 7367e8381f9SStefano Zampini 7371cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatSetPreallocationCOO()`, `MatSetPreallocationCOOLocal()`, `InsertMode`, `INSERT_VALUES`, `ADD_VALUES` 7387e8381f9SStefano Zampini @*/ 739d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetValuesCOO(Mat A, const PetscScalar coo_v[], InsertMode imode) 740d71ae5a4SJacob Faibussowitsch { 7417e8381f9SStefano Zampini PetscErrorCode (*f)(Mat, const PetscScalar[], InsertMode) = NULL; 74235cef55dSJunchao Zhang PetscBool oldFlg; 7437e8381f9SStefano Zampini 7447e8381f9SStefano Zampini PetscFunctionBegin; 7457e8381f9SStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 7467e8381f9SStefano Zampini PetscValidType(A, 1); 7477e8381f9SStefano Zampini MatCheckPreallocated(A, 1); 748bfcc3627SStefano Zampini PetscValidLogicalCollectiveEnum(A, imode, 3); 7499566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatSetValuesCOO_C", &f)); 7509566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(MAT_SetVCOO, A, 0, 0, 0)); 7517e8381f9SStefano Zampini if (f) { 75235cef55dSJunchao Zhang PetscCall((*f)(A, coo_v, imode)); // all known COO implementations do not use MatStash. They do their own off-proc communication 75335cef55dSJunchao Zhang PetscCall(MatGetOption(A, MAT_NO_OFF_PROC_ENTRIES, &oldFlg)); 75435cef55dSJunchao Zhang PetscCall(MatSetOption(A, MAT_NO_OFF_PROC_ENTRIES, PETSC_TRUE)); // set A->nooffprocentries to avoid costly MatStash scatter in MatAssembly 75535cef55dSJunchao Zhang } else { 75635cef55dSJunchao Zhang PetscCall(MatSetValuesCOO_Basic(A, coo_v, imode)); // fall back to MatSetValues, which might use MatStash 7577e8381f9SStefano Zampini } 7589566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 7599566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 76035cef55dSJunchao Zhang if (f) PetscCall(MatSetOption(A, MAT_NO_OFF_PROC_ENTRIES, oldFlg)); 76135cef55dSJunchao Zhang PetscCall(PetscLogEventEnd(MAT_SetVCOO, A, 0, 0, 0)); 7623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7637e8381f9SStefano Zampini } 76465a9ecf2SRichard Tran Mills 76565a9ecf2SRichard Tran Mills /*@ 76665a9ecf2SRichard 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 76765a9ecf2SRichard Tran Mills 76865a9ecf2SRichard Tran Mills Input Parameters: 76965a9ecf2SRichard Tran Mills + A - the matrix 77065a9ecf2SRichard Tran Mills - flg - flag indicating whether the boundtocpu flag should be propagated 77165a9ecf2SRichard Tran Mills 77265a9ecf2SRichard Tran Mills Level: developer 77365a9ecf2SRichard Tran Mills 77465a9ecf2SRichard Tran Mills Notes: 7752fe279fdSBarry Smith If the value of flg is set to true, the following will occur 7762fe279fdSBarry Smith + `MatCreateSubMatrices()` and `MatCreateRedundantMatrix()` - bind created matrices to CPU if the input matrix is bound to the CPU. 7772fe279fdSBarry Smith - `MatCreateVecs()` - bind created vectors to CPU if the input matrix is bound to the CPU. 77865a9ecf2SRichard Tran Mills 77965a9ecf2SRichard Tran Mills The bindingpropagates flag itself is also propagated by the above routines. 78065a9ecf2SRichard Tran Mills 781fe59aa6dSJacob Faibussowitsch Developer Notes: 782aa624791SPierre Jolivet If the fine-scale `DMDA` has the `-dm_bind_below` option set to true, then `DMCreateInterpolationScale()` calls `MatSetBindingPropagates()` 78365a9ecf2SRichard Tran Mills on the restriction/interpolation operator to set the bindingpropagates flag to true. 78465a9ecf2SRichard Tran Mills 7851cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `VecSetBindingPropagates()`, `MatGetBindingPropagates()` 78665a9ecf2SRichard Tran Mills @*/ 787d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetBindingPropagates(Mat A, PetscBool flg) 788d71ae5a4SJacob Faibussowitsch { 78965a9ecf2SRichard Tran Mills PetscFunctionBegin; 79065a9ecf2SRichard Tran Mills PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 791d5e393b6SSuyash Tandon #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 79265a9ecf2SRichard Tran Mills A->bindingpropagates = flg; 79365a9ecf2SRichard Tran Mills #endif 7943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 79565a9ecf2SRichard Tran Mills } 796e9c74fd6SRichard Tran Mills 797e9c74fd6SRichard Tran Mills /*@ 798e9c74fd6SRichard 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 799e9c74fd6SRichard Tran Mills 800e9c74fd6SRichard Tran Mills Input Parameter: 801e9c74fd6SRichard Tran Mills . A - the matrix 802e9c74fd6SRichard Tran Mills 803e9c74fd6SRichard Tran Mills Output Parameter: 804e9c74fd6SRichard Tran Mills . flg - flag indicating whether the boundtocpu flag will be propagated 805e9c74fd6SRichard Tran Mills 806e9c74fd6SRichard Tran Mills Level: developer 807e9c74fd6SRichard Tran Mills 8081cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatSetBindingPropagates()` 809e9c74fd6SRichard Tran Mills @*/ 810d71ae5a4SJacob Faibussowitsch PetscErrorCode MatGetBindingPropagates(Mat A, PetscBool *flg) 811d71ae5a4SJacob Faibussowitsch { 812e9c74fd6SRichard Tran Mills PetscFunctionBegin; 813e9c74fd6SRichard Tran Mills PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8144f572ea9SToby Isaac PetscAssertPointer(flg, 2); 815d5e393b6SSuyash Tandon #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 816e9c74fd6SRichard Tran Mills *flg = A->bindingpropagates; 817e9c74fd6SRichard Tran Mills #else 818e9c74fd6SRichard Tran Mills *flg = PETSC_FALSE; 819e9c74fd6SRichard Tran Mills #endif 8203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 821e9c74fd6SRichard Tran Mills } 822