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 3411a5261eSBarry Smith with a call to `MatSetFromOptions()`. The default matrix type is 3511a5261eSBarry Smith `MATAIJ`, using the routines `MatCreateSeqAIJ()` or `MatCreateAIJ()` 367e5f4302SBarry Smith if you do not set a type in the options database. If you never 3711a5261eSBarry Smith call `MatSetType()` or `MatSetFromOptions()` it will generate an 38f8ab6608SSatish Balay error when you try to use the matrix. 3983e1b59cSLois Curfman McInnes 40d083f849SBarry Smith Collective 41cb13003dSBarry Smith 42f69a0ea3SMatthew Knepley Input Parameter: 43f69a0ea3SMatthew Knepley . comm - MPI communicator 447807a1faSBarry Smith 457807a1faSBarry Smith Output Parameter: 46dc401e71SLois Curfman McInnes . A - the matrix 47e0b365e2SLois Curfman McInnes 48273d9f13SBarry Smith Options Database Keys: 4911a5261eSBarry Smith + -mat_type seqaij - `MATSEQAIJ` type, uses `MatCreateSeqAIJ()` 5011a5261eSBarry Smith . -mat_type mpiaij - `MATMPIAIJ` type, uses `MatCreateAIJ()` 5111a5261eSBarry Smith . -mat_type seqdense - `MATSEQDENSE`, uses `MatCreateSeqDense()` 5211a5261eSBarry Smith . -mat_type mpidense - `MATMPIDENSE` type, uses `MatCreateDense()` 5311a5261eSBarry Smith . -mat_type seqbaij - `MATSEQBAIJ` type, uses `MatCreateSeqBAIJ()` 5411a5261eSBarry Smith - -mat_type mpibaij - `MATMPIBAIJ` type, uses `MatCreateBAIJ()` 55e0b365e2SLois Curfman McInnes 562ef1f0ffSBarry Smith See the manpages for particular formats (e.g., `MATSEQAIJ`) 5783e1b59cSLois Curfman McInnes for additional format-specific options. 58e0b365e2SLois Curfman McInnes 59273d9f13SBarry Smith Level: beginner 60273d9f13SBarry Smith 611cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatCreateSeqAIJ()`, `MatCreateAIJ()`, 62db781477SPatrick Sanan `MatCreateSeqDense()`, `MatCreateDense()`, 63db781477SPatrick Sanan `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, 64db781477SPatrick Sanan `MatCreateSeqSBAIJ()`, `MatCreateSBAIJ()`, 65db781477SPatrick Sanan `MatConvert()` 66273d9f13SBarry Smith @*/ 67d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreate(MPI_Comm comm, Mat *A) 68d71ae5a4SJacob Faibussowitsch { 69273d9f13SBarry Smith Mat B; 70273d9f13SBarry Smith 71273d9f13SBarry Smith PetscFunctionBegin; 72f69a0ea3SMatthew Knepley PetscValidPointer(A, 2); 7397f1f81fSBarry Smith 740298fd71SBarry Smith *A = NULL; 759566063dSJacob Faibussowitsch PetscCall(MatInitializePackage()); 768ba1e511SMatthew Knepley 779566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(B, MAT_CLASSID, "Mat", "Matrix", "Mat", comm, MatDestroy, MatView)); 789566063dSJacob Faibussowitsch PetscCall(PetscLayoutCreate(comm, &B->rmap)); 799566063dSJacob Faibussowitsch PetscCall(PetscLayoutCreate(comm, &B->cmap)); 809566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(VECSTANDARD, &B->defaultvectype)); 813faff063SStefano Zampini PetscCall(PetscStrallocpy(PETSCRANDER48, &B->defaultrandtype)); 8226fbe8dcSKarl Rupp 83b94d7dedSBarry Smith B->symmetric = PETSC_BOOL3_UNKNOWN; 84b94d7dedSBarry Smith B->hermitian = PETSC_BOOL3_UNKNOWN; 85b94d7dedSBarry Smith B->structurally_symmetric = PETSC_BOOL3_UNKNOWN; 86b94d7dedSBarry Smith B->spd = PETSC_BOOL3_UNKNOWN; 87b94d7dedSBarry Smith B->symmetry_eternal = PETSC_FALSE; 88b94d7dedSBarry Smith B->structural_symmetry_eternal = PETSC_FALSE; 89b94d7dedSBarry Smith 9094342113SStefano Zampini B->congruentlayouts = PETSC_DECIDE; 91273d9f13SBarry Smith B->preallocated = PETSC_FALSE; 926f3d89d0SStefano Zampini #if defined(PETSC_HAVE_DEVICE) 936f3d89d0SStefano Zampini B->boundtocpu = PETSC_TRUE; 946f3d89d0SStefano Zampini #endif 95273d9f13SBarry Smith *A = B; 963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 97273d9f13SBarry Smith } 98273d9f13SBarry Smith 99422a814eSBarry Smith /*@ 10011a5261eSBarry Smith MatSetErrorIfFailure - Causes `Mat` to generate an immediate error, for example a zero pivot, is detected. 101422a814eSBarry Smith 102c3339decSBarry Smith Logically Collective 103422a814eSBarry Smith 104422a814eSBarry Smith Input Parameters: 10511a5261eSBarry Smith + mat - matrix obtained from `MatCreate()` 10611a5261eSBarry Smith - flg - `PETSC_TRUE` indicates you want the error generated 107422a814eSBarry Smith 108422a814eSBarry Smith Level: advanced 109422a814eSBarry Smith 11011a5261eSBarry Smith Note: 11111a5261eSBarry 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 11211a5261eSBarry Smith or result in a `KSPConvergedReason` indicating the method did not converge. 11311a5261eSBarry Smith 1141cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `PCSetErrorIfFailure()`, `KSPConvergedReason`, `SNESConvergedReason` 115422a814eSBarry Smith @*/ 116d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetErrorIfFailure(Mat mat, PetscBool flg) 117d71ae5a4SJacob Faibussowitsch { 118422a814eSBarry Smith PetscFunctionBegin; 119422a814eSBarry Smith PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 120422a814eSBarry Smith PetscValidLogicalCollectiveBool(mat, flg, 2); 12184d44b13SHong Zhang mat->erroriffailure = flg; 1223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 123422a814eSBarry Smith } 124422a814eSBarry Smith 125f69a0ea3SMatthew Knepley /*@ 126f69a0ea3SMatthew Knepley MatSetSizes - Sets the local and global sizes, and checks to determine compatibility 127f69a0ea3SMatthew Knepley 128c3339decSBarry Smith Collective 129f69a0ea3SMatthew Knepley 130f69a0ea3SMatthew Knepley Input Parameters: 131f69a0ea3SMatthew Knepley + A - the matrix 13211a5261eSBarry Smith . m - number of local rows (or `PETSC_DECIDE`) 13311a5261eSBarry Smith . n - number of local columns (or `PETSC_DECIDE`) 13411a5261eSBarry Smith . M - number of global rows (or `PETSC_DETERMINE`) 13511a5261eSBarry Smith - N - number of global columns (or `PETSC_DETERMINE`) 136f69a0ea3SMatthew Knepley 1372fe279fdSBarry Smith Level: beginner 1382fe279fdSBarry Smith 139f69a0ea3SMatthew Knepley Notes: 1402ef1f0ffSBarry Smith `m` (`n`) and `M` (`N`) cannot be both `PETSC_DECIDE` 1412ef1f0ffSBarry Smith If one processor calls this with `M` (`N`) of `PETSC_DECIDE` then all processors must, otherwise the program will hang. 142f69a0ea3SMatthew Knepley 14311a5261eSBarry Smith If `PETSC_DECIDE` is not used for the arguments 'm' and 'n', then the 144f69a0ea3SMatthew Knepley user must ensure that they are chosen to be compatible with the 145f69a0ea3SMatthew Knepley vectors. To do this, one first considers the matrix-vector product 1462ef1f0ffSBarry Smith 'y = A x'. The `m` that is used in the above routine must match the 1472ef1f0ffSBarry Smith local size used in the vector creation routine `VecCreateMPI()` for 'y'. 1482ef1f0ffSBarry Smith Likewise, the `n` used must match that used as the local size in 14911a5261eSBarry Smith `VecCreateMPI()` for 'x'. 150f69a0ea3SMatthew Knepley 151f73d5cc4SBarry Smith You cannot change the sizes once they have been set. 152f73d5cc4SBarry Smith 15311a5261eSBarry Smith The sizes must be set before `MatSetUp()` or MatXXXSetPreallocation() is called. 154f73d5cc4SBarry Smith 1551cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatGetSize()`, `PetscSplitOwnership()` 156f69a0ea3SMatthew Knepley @*/ 157d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetSizes(Mat A, PetscInt m, PetscInt n, PetscInt M, PetscInt N) 158d71ae5a4SJacob Faibussowitsch { 159f69a0ea3SMatthew Knepley PetscFunctionBegin; 1600700a824SBarry Smith PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 161a69c7061SStefano Zampini PetscValidLogicalCollectiveInt(A, M, 4); 162a69c7061SStefano Zampini PetscValidLogicalCollectiveInt(A, N, 5); 163aed4548fSBarry 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); 164aed4548fSBarry 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); 1659371c9d4SSatish 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, 1669371c9d4SSatish Balay A->rmap->n, A->rmap->N); 1679371c9d4SSatish 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, 1689371c9d4SSatish Balay A->cmap->n, A->cmap->N); 169d0f46423SBarry Smith A->rmap->n = m; 170d0f46423SBarry Smith A->cmap->n = n; 17159cb773eSBarry Smith A->rmap->N = M > -1 ? M : A->rmap->N; 17259cb773eSBarry Smith A->cmap->N = N > -1 ? N : A->cmap->N; 1733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 174f69a0ea3SMatthew Knepley } 175f69a0ea3SMatthew Knepley 17605869f15SSatish Balay /*@ 177273d9f13SBarry Smith MatSetFromOptions - Creates a matrix where the type is determined 178273d9f13SBarry Smith from the options database. Generates a parallel MPI matrix if the 179273d9f13SBarry Smith communicator has more than one processor. The default matrix type is 18011a5261eSBarry Smith `MATAIJ`, using the routines `MatCreateSeqAIJ()` and `MatCreateAIJ()` if 1817e5f4302SBarry Smith you do not select a type in the options database. 182273d9f13SBarry Smith 183c3339decSBarry Smith Collective 184273d9f13SBarry Smith 185273d9f13SBarry Smith Input Parameter: 186273d9f13SBarry Smith . A - the matrix 187273d9f13SBarry Smith 188273d9f13SBarry Smith Options Database Keys: 18911a5261eSBarry Smith + -mat_type seqaij - `MATSEQAIJ` type, uses `MatCreateSeqAIJ()` 19011a5261eSBarry Smith . -mat_type mpiaij - `MATMPIAIJ` type, uses `MatCreateAIJ()` 19111a5261eSBarry Smith . -mat_type seqdense - `MATSEQDENSE` type, uses `MatCreateSeqDense()` 19211a5261eSBarry Smith . -mat_type mpidense - `MATMPIDENSE`, uses `MatCreateDense()` 19311a5261eSBarry Smith . -mat_type seqbaij - `MATSEQBAIJ`, uses `MatCreateSeqBAIJ()` 19411a5261eSBarry Smith - -mat_type mpibaij - `MATMPIBAIJ`, uses `MatCreateBAIJ()` 195273d9f13SBarry Smith 1962ef1f0ffSBarry Smith See the manpages for particular formats (e.g., `MATSEQAIJ`) 197273d9f13SBarry Smith for additional format-specific options. 198bd9ce289SLois Curfman McInnes 1991d69843bSLois Curfman McInnes Level: beginner 2001d69843bSLois Curfman McInnes 2011cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatCreateSeqAIJ()`, `MatCreateAIJ()`, 202db781477SPatrick Sanan `MatCreateSeqDense()`, `MatCreateDense()`, 203db781477SPatrick Sanan `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, 204db781477SPatrick Sanan `MatCreateSeqSBAIJ()`, `MatCreateSBAIJ()`, 205db781477SPatrick Sanan `MatConvert()` 2067807a1faSBarry Smith @*/ 207d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetFromOptions(Mat B) 208d71ae5a4SJacob Faibussowitsch { 209f3be49caSLisandro Dalcin const char *deft = MATAIJ; 210f3be49caSLisandro Dalcin char type[256]; 21169df5c0cSJed Brown PetscBool flg, set; 21216e04d98SRichard Tran Mills PetscInt bind_below = 0; 213dbb450caSBarry Smith 2143a40ed3dSBarry Smith PetscFunctionBegin; 2150700a824SBarry Smith PetscValidHeaderSpecific(B, MAT_CLASSID, 1); 216f3be49caSLisandro Dalcin 217d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)B); 218535b19f3SBarry Smith 219535b19f3SBarry Smith if (B->rmap->bs < 0) { 220535b19f3SBarry Smith PetscInt newbs = -1; 2219566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-mat_block_size", "Set the blocksize used to store the matrix", "MatSetBlockSize", newbs, &newbs, &flg)); 222535b19f3SBarry Smith if (flg) { 2239566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetBlockSize(B->rmap, newbs)); 2249566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetBlockSize(B->cmap, newbs)); 225535b19f3SBarry Smith } 226535b19f3SBarry Smith } 227535b19f3SBarry Smith 2289566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-mat_type", "Matrix type", "MatSetType", MatList, deft, type, 256, &flg)); 229273d9f13SBarry Smith if (flg) { 2309566063dSJacob Faibussowitsch PetscCall(MatSetType(B, type)); 231f3be49caSLisandro Dalcin } else if (!((PetscObject)B)->type_name) { 2329566063dSJacob Faibussowitsch PetscCall(MatSetType(B, deft)); 233273d9f13SBarry Smith } 234f3be49caSLisandro Dalcin 2359566063dSJacob Faibussowitsch PetscCall(PetscOptionsName("-mat_is_symmetric", "Checks if mat is symmetric on MatAssemblyEnd()", "MatIsSymmetric", &B->checksymmetryonassembly)); 2369566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-mat_is_symmetric", "Checks if mat is symmetric on MatAssemblyEnd()", "MatIsSymmetric", B->checksymmetrytol, &B->checksymmetrytol, NULL)); 2379566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-mat_null_space_test", "Checks if provided null space is correct in MatAssemblyEnd()", "MatSetNullSpaceTest", B->checknullspaceonassembly, &B->checknullspaceonassembly, NULL)); 2389566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-mat_error_if_failure", "Generate an error if an error occurs when factoring the matrix", "MatSetErrorIfFailure", B->erroriffailure, &B->erroriffailure, NULL)); 239840d65ccSBarry Smith 240dbbe0bcdSBarry Smith PetscTryTypeMethod(B, setfromoptions, PetscOptionsObject); 241f3be49caSLisandro Dalcin 24269df5c0cSJed Brown flg = PETSC_FALSE; 2439566063dSJacob 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)); 2449566063dSJacob Faibussowitsch if (set) PetscCall(MatSetOption(B, MAT_NEW_NONZERO_LOCATION_ERR, flg)); 24569df5c0cSJed Brown flg = PETSC_FALSE; 2469566063dSJacob 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)); 2479566063dSJacob Faibussowitsch if (set) PetscCall(MatSetOption(B, MAT_NEW_NONZERO_ALLOCATION_ERR, flg)); 248478db826SMatthew G. Knepley flg = PETSC_FALSE; 2499566063dSJacob 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)); 2509566063dSJacob Faibussowitsch if (set) PetscCall(MatSetOption(B, MAT_IGNORE_ZERO_ENTRIES, flg)); 25169df5c0cSJed Brown 2521a2c6b5cSJunchao Zhang flg = PETSC_FALSE; 2539566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-mat_form_explicit_transpose", "Hint to form an explicit transpose for operations like MatMultTranspose", "MatSetOption", flg, &flg, &set)); 2549566063dSJacob Faibussowitsch if (set) PetscCall(MatSetOption(B, MAT_FORM_EXPLICIT_TRANSPOSE, flg)); 2551a2c6b5cSJunchao Zhang 25616e04d98SRichard Tran Mills /* Bind to CPU if below a user-specified size threshold. 25716e04d98SRichard Tran Mills * This perhaps belongs in the options for the GPU Mat types, but MatBindToCPU() does nothing when called on non-GPU types, 25816e04d98SRichard Tran Mills * and putting it here makes is more maintainable than duplicating this for all. */ 2599566063dSJacob 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)); 26048a46eb9SPierre Jolivet if (flg && B->rmap->n < bind_below) PetscCall(MatBindToCPU(B, PETSC_TRUE)); 26116e04d98SRichard Tran Mills 2625d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 263dbbe0bcdSBarry Smith PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)B, PetscOptionsObject)); 264d0609cedSBarry Smith PetscOptionsEnd(); 2653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2667807a1faSBarry Smith } 2677807a1faSBarry Smith 268987010e7SBarry Smith /*@C 26911a5261eSBarry Smith MatXAIJSetPreallocation - set preallocation for serial and parallel `MATAIJ`, `MATBAIJ`, and `MATSBAIJ` matrices and their unassembled versions. 27063562e91SJed Brown 271c3339decSBarry Smith Collective 27263562e91SJed Brown 2734165533cSJose E. Roman Input Parameters: 27463562e91SJed Brown + A - matrix being preallocated 27563562e91SJed Brown . bs - block size 27641319c1dSStefano Zampini . dnnz - number of nonzero column blocks per block row of diagonal part of parallel matrix 27741319c1dSStefano Zampini . onnz - number of nonzero column blocks per block row of off-diagonal part of parallel matrix 27841319c1dSStefano Zampini . dnnzu - number of nonzero column blocks per block row of upper-triangular part of diagonal part of parallel matrix 27941319c1dSStefano Zampini - onnzu - number of nonzero column blocks per block row of upper-triangular part of off-diagonal part of parallel matrix 28063562e91SJed Brown 28163562e91SJed Brown Level: beginner 28263562e91SJed Brown 2831cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatSeqAIJSetPreallocation()`, `MatMPIAIJSetPreallocation()`, `MatSeqBAIJSetPreallocation()`, `MatMPIBAIJSetPreallocation()`, 2842fe279fdSBarry Smith `MatSeqSBAIJSetPreallocation()`, `MatMPISBAIJSetPreallocation()`, 285db781477SPatrick Sanan `PetscSplitOwnership()` 28663562e91SJed Brown @*/ 287d71ae5a4SJacob Faibussowitsch PetscErrorCode MatXAIJSetPreallocation(Mat A, PetscInt bs, const PetscInt dnnz[], const PetscInt onnz[], const PetscInt dnnzu[], const PetscInt onnzu[]) 288d71ae5a4SJacob Faibussowitsch { 28941319c1dSStefano Zampini PetscInt cbs; 29063562e91SJed Brown void (*aij)(void); 291e8bd9bafSStefano Zampini void (*is)(void); 292990279feSStefano Zampini void (*hyp)(void) = NULL; 29363562e91SJed Brown 29463562e91SJed Brown PetscFunctionBegin; 29541319c1dSStefano Zampini if (bs != PETSC_DECIDE) { /* don't mess with an already set block size */ 2969566063dSJacob Faibussowitsch PetscCall(MatSetBlockSize(A, bs)); 29741319c1dSStefano Zampini } 2989566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 2999566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 3009566063dSJacob Faibussowitsch PetscCall(MatGetBlockSizes(A, &bs, &cbs)); 30141319c1dSStefano Zampini /* these routines assumes bs == cbs, this should be checked somehow */ 3029566063dSJacob Faibussowitsch PetscCall(MatSeqBAIJSetPreallocation(A, bs, 0, dnnz)); 3039566063dSJacob Faibussowitsch PetscCall(MatMPIBAIJSetPreallocation(A, bs, 0, dnnz, 0, onnz)); 3049566063dSJacob Faibussowitsch PetscCall(MatSeqSBAIJSetPreallocation(A, bs, 0, dnnzu)); 3059566063dSJacob Faibussowitsch PetscCall(MatMPISBAIJSetPreallocation(A, bs, 0, dnnzu, 0, onnzu)); 30663562e91SJed Brown /* 307e8bd9bafSStefano 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 30863562e91SJed Brown good before going on with it. 30963562e91SJed Brown */ 3109566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatMPIAIJSetPreallocation_C", &aij)); 3119566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatISSetPreallocation_C", &is)); 312990279feSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 3139566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatHYPRESetPreallocation_C", &hyp)); 314990279feSStefano Zampini #endif 31548a46eb9SPierre Jolivet if (!aij && !is && !hyp) PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatSeqAIJSetPreallocation_C", &aij)); 316990279feSStefano Zampini if (aij || is || hyp) { 31741319c1dSStefano Zampini if (bs == cbs && bs == 1) { 3189566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(A, 0, dnnz)); 3199566063dSJacob Faibussowitsch PetscCall(MatMPIAIJSetPreallocation(A, 0, dnnz, 0, onnz)); 3209566063dSJacob Faibussowitsch PetscCall(MatISSetPreallocation(A, 0, dnnz, 0, onnz)); 321990279feSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 3229566063dSJacob Faibussowitsch PetscCall(MatHYPRESetPreallocation(A, 0, dnnz, 0, onnz)); 323990279feSStefano Zampini #endif 3243e5f4774SJed Brown } else { /* Convert block-row precallocation to scalar-row */ 32563562e91SJed Brown PetscInt i, m, *sdnnz, *sonnz; 3269566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(A, &m, NULL)); 3279566063dSJacob Faibussowitsch PetscCall(PetscMalloc2((!!dnnz) * m, &sdnnz, (!!onnz) * m, &sonnz)); 328dec54756SJed Brown for (i = 0; i < m; i++) { 32941319c1dSStefano Zampini if (dnnz) sdnnz[i] = dnnz[i / bs] * cbs; 33041319c1dSStefano Zampini if (onnz) sonnz[i] = onnz[i / bs] * cbs; 33163562e91SJed Brown } 3329566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(A, 0, dnnz ? sdnnz : NULL)); 3339566063dSJacob Faibussowitsch PetscCall(MatMPIAIJSetPreallocation(A, 0, dnnz ? sdnnz : NULL, 0, onnz ? sonnz : NULL)); 3349566063dSJacob Faibussowitsch PetscCall(MatISSetPreallocation(A, 0, dnnz ? sdnnz : NULL, 0, onnz ? sonnz : NULL)); 335990279feSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 3369566063dSJacob Faibussowitsch PetscCall(MatHYPRESetPreallocation(A, 0, dnnz ? sdnnz : NULL, 0, onnz ? sonnz : NULL)); 337990279feSStefano Zampini #endif 3389566063dSJacob Faibussowitsch PetscCall(PetscFree2(sdnnz, sonnz)); 33963562e91SJed Brown } 34063562e91SJed Brown } 3413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34263562e91SJed Brown } 34363562e91SJed Brown 344273d9f13SBarry Smith /* 345eb6b5d47SBarry Smith Merges some information from Cs header to A; the C object is then destroyed 346d0f46423SBarry Smith 347d0f46423SBarry Smith This is somewhat different from MatHeaderReplace() it would be nice to merge the code 348273d9f13SBarry Smith */ 349d71ae5a4SJacob Faibussowitsch PetscErrorCode MatHeaderMerge(Mat A, Mat *C) 350d71ae5a4SJacob Faibussowitsch { 351d44834fbSBarry Smith PetscInt refct; 35273107ff1SLisandro Dalcin PetscOps Abops; 35373107ff1SLisandro Dalcin struct _MatOps Aops; 3544768301cSVaclav Hapla char *mtype, *mname, *mprefix; 3554222ddf1SHong Zhang Mat_Product *product; 35633e6eea4SJose E. Roman Mat_Redundant *redundant; 357d4a972cbSStefano Zampini PetscObjectState state; 358273d9f13SBarry Smith 359273d9f13SBarry Smith PetscFunctionBegin; 3601dc04de0SStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3611dc04de0SStefano Zampini PetscValidHeaderSpecific(*C, MAT_CLASSID, 2); 3623ba16761SJacob Faibussowitsch if (A == *C) PetscFunctionReturn(PETSC_SUCCESS); 3631dc04de0SStefano Zampini PetscCheckSameComm(A, 1, *C, 2); 364273d9f13SBarry Smith /* save the parts of A we need */ 36573107ff1SLisandro Dalcin Abops = ((PetscObject)A)->bops[0]; 36673107ff1SLisandro Dalcin Aops = A->ops[0]; 3677adad957SLisandro Dalcin refct = ((PetscObject)A)->refct; 3685c9eb25fSBarry Smith mtype = ((PetscObject)A)->type_name; 3695c9eb25fSBarry Smith mname = ((PetscObject)A)->name; 370d4a972cbSStefano Zampini state = ((PetscObject)A)->state; 3714768301cSVaclav Hapla mprefix = ((PetscObject)A)->prefix; 3724222ddf1SHong Zhang product = A->product; 37333e6eea4SJose E. Roman redundant = A->redundant; 37430735b05SKris Buschelman 3755c9eb25fSBarry Smith /* zero these so the destroy below does not free them */ 376f4259b30SLisandro Dalcin ((PetscObject)A)->type_name = NULL; 377f4259b30SLisandro Dalcin ((PetscObject)A)->name = NULL; 3785c9eb25fSBarry Smith 379dbbe0bcdSBarry Smith /* 380dbbe0bcdSBarry Smith free all the interior data structures from mat 381dbbe0bcdSBarry Smith cannot use PetscUseTypeMethod(A,destroy); because compiler 382dbbe0bcdSBarry Smith thinks it may print NULL type_name and name 383dbbe0bcdSBarry Smith */ 384dbbe0bcdSBarry Smith PetscTryTypeMethod(A, destroy); 3857c99f97cSSatish Balay 3869566063dSJacob Faibussowitsch PetscCall(PetscFree(A->defaultvectype)); 3873faff063SStefano Zampini PetscCall(PetscFree(A->defaultrandtype)); 3889566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&A->rmap)); 3899566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&A->cmap)); 3909566063dSJacob Faibussowitsch PetscCall(PetscFunctionListDestroy(&((PetscObject)A)->qlist)); 3919566063dSJacob Faibussowitsch PetscCall(PetscObjectListDestroy(&((PetscObject)A)->olist)); 3929566063dSJacob Faibussowitsch PetscCall(PetscComposedQuantitiesDestroy((PetscObject)A)); 393273d9f13SBarry Smith 394273d9f13SBarry Smith /* copy C over to A */ 39526cc229bSBarry Smith PetscCall(PetscFree(A->factorprefix)); 3969566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(A, *C, sizeof(struct _p_Mat))); 397273d9f13SBarry Smith 398273d9f13SBarry Smith /* return the parts of A we saved */ 39973107ff1SLisandro Dalcin ((PetscObject)A)->bops[0] = Abops; 40073107ff1SLisandro Dalcin A->ops[0] = Aops; 4017adad957SLisandro Dalcin ((PetscObject)A)->refct = refct; 4027adad957SLisandro Dalcin ((PetscObject)A)->type_name = mtype; 4037adad957SLisandro Dalcin ((PetscObject)A)->name = mname; 4044768301cSVaclav Hapla ((PetscObject)A)->prefix = mprefix; 405d4a972cbSStefano Zampini ((PetscObject)A)->state = state + 1; 4064222ddf1SHong Zhang A->product = product; 40733e6eea4SJose E. Roman A->redundant = redundant; 408273d9f13SBarry Smith 4095c9eb25fSBarry Smith /* since these two are copied into A we do not want them destroyed in C */ 410f4259b30SLisandro Dalcin ((PetscObject)*C)->qlist = NULL; 411f4259b30SLisandro Dalcin ((PetscObject)*C)->olist = NULL; 41226fbe8dcSKarl Rupp 4139566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(C)); 4143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 415273d9f13SBarry Smith } 4168ab5b326SKris Buschelman /* 417eb6b5d47SBarry Smith Replace A's header with that of C; the C object is then destroyed 418d0f46423SBarry Smith 419eb6b5d47SBarry Smith This is essentially code moved from MatDestroy() 420eb6b5d47SBarry Smith 421eb6b5d47SBarry Smith This is somewhat different from MatHeaderMerge() it would be nice to merge the code 422b30237c6SBarry Smith 423b30237c6SBarry Smith Used in DM hence is declared PETSC_EXTERN 4248ab5b326SKris Buschelman */ 425d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode MatHeaderReplace(Mat A, Mat *C) 426d71ae5a4SJacob Faibussowitsch { 42727b31e29SJed Brown PetscInt refct; 428fefd9316SJose E. Roman PetscObjectState state; 42928be2f97SBarry Smith struct _p_Mat buffer; 43081fa06acSBarry Smith MatStencilInfo stencil; 4318ab5b326SKris Buschelman 4328ab5b326SKris Buschelman PetscFunctionBegin; 43327b31e29SJed Brown PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 43428be2f97SBarry Smith PetscValidHeaderSpecific(*C, MAT_CLASSID, 2); 4353ba16761SJacob Faibussowitsch if (A == *C) PetscFunctionReturn(PETSC_SUCCESS); 43628be2f97SBarry Smith PetscCheckSameComm(A, 1, *C, 2); 437aed4548fSBarry 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); 4386d7c1e57SBarry Smith 43928be2f97SBarry Smith /* swap C and A */ 44027b31e29SJed Brown refct = ((PetscObject)A)->refct; 441fefd9316SJose E. Roman state = ((PetscObject)A)->state; 44281fa06acSBarry Smith stencil = A->stencil; 4439566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(&buffer, A, sizeof(struct _p_Mat))); 4449566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(A, *C, sizeof(struct _p_Mat))); 4459566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(*C, &buffer, sizeof(struct _p_Mat))); 44627b31e29SJed Brown ((PetscObject)A)->refct = refct; 447fefd9316SJose E. Roman ((PetscObject)A)->state = state + 1; 44881fa06acSBarry Smith A->stencil = stencil; 44926fbe8dcSKarl Rupp 450c32d4117SBarry Smith ((PetscObject)*C)->refct = 1; 4519566063dSJacob Faibussowitsch PetscCall(MatShellSetOperation(*C, MATOP_DESTROY, (void (*)(void))NULL)); 4529566063dSJacob Faibussowitsch PetscCall(MatDestroy(C)); 4533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4548ab5b326SKris Buschelman } 455e7e92044SBarry Smith 456e7e92044SBarry Smith /*@ 457b470e4b4SRichard Tran Mills MatBindToCPU - marks a matrix to temporarily stay on the CPU and perform computations on the CPU 458e7e92044SBarry Smith 4592ef1f0ffSBarry Smith Logically Collective 4602216c58aSStefano Zampini 461e7e92044SBarry Smith Input Parameters: 462e7e92044SBarry Smith + A - the matrix 46311a5261eSBarry Smith - flg - bind to the CPU if value of `PETSC_TRUE` 464e7e92044SBarry Smith 46590ea27d8SSatish Balay Level: intermediate 4662216c58aSStefano Zampini 4671cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatBoundToCPU()` 468e7e92044SBarry Smith @*/ 469d71ae5a4SJacob Faibussowitsch PetscErrorCode MatBindToCPU(Mat A, PetscBool flg) 470d71ae5a4SJacob Faibussowitsch { 4717d871021SStefano Zampini PetscFunctionBegin; 4722ffa8ee7SStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 4732ffa8ee7SStefano Zampini PetscValidLogicalCollectiveBool(A, flg, 2); 4742216c58aSStefano Zampini #if defined(PETSC_HAVE_DEVICE) 4753ba16761SJacob Faibussowitsch if (A->boundtocpu == flg) PetscFunctionReturn(PETSC_SUCCESS); 476b470e4b4SRichard Tran Mills A->boundtocpu = flg; 477dbbe0bcdSBarry Smith PetscTryTypeMethod(A, bindtocpu, flg); 4782216c58aSStefano Zampini #endif 4793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4802216c58aSStefano Zampini } 4812216c58aSStefano Zampini 4822216c58aSStefano Zampini /*@ 4832216c58aSStefano Zampini MatBoundToCPU - query if a matrix is bound to the CPU 4842216c58aSStefano Zampini 4852216c58aSStefano Zampini Input Parameter: 4862216c58aSStefano Zampini . A - the matrix 4872216c58aSStefano Zampini 4882216c58aSStefano Zampini Output Parameter: 4892216c58aSStefano Zampini . flg - the logical flag 4902216c58aSStefano Zampini 4912216c58aSStefano Zampini Level: intermediate 4922216c58aSStefano Zampini 4931cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatBindToCPU()` 4942216c58aSStefano Zampini @*/ 495d71ae5a4SJacob Faibussowitsch PetscErrorCode MatBoundToCPU(Mat A, PetscBool *flg) 496d71ae5a4SJacob Faibussowitsch { 4972ffa8ee7SStefano Zampini PetscFunctionBegin; 4982ffa8ee7SStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 499dadcf809SJacob Faibussowitsch PetscValidBoolPointer(flg, 2); 5002216c58aSStefano Zampini #if defined(PETSC_HAVE_DEVICE) 5012216c58aSStefano Zampini *flg = A->boundtocpu; 5022216c58aSStefano Zampini #else 5032216c58aSStefano Zampini *flg = PETSC_TRUE; 5047d871021SStefano Zampini #endif 5053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 506e7e92044SBarry Smith } 5077e8381f9SStefano Zampini 508d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetValuesCOO_Basic(Mat A, const PetscScalar coo_v[], InsertMode imode) 509d71ae5a4SJacob Faibussowitsch { 5107e8381f9SStefano Zampini IS is_coo_i, is_coo_j; 5117e8381f9SStefano Zampini const PetscInt *coo_i, *coo_j; 5127e8381f9SStefano Zampini PetscInt n, n_i, n_j; 5137e8381f9SStefano Zampini PetscScalar zero = 0.; 5147e8381f9SStefano Zampini 5157e8381f9SStefano Zampini PetscFunctionBegin; 5169566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)A, "__PETSc_coo_i", (PetscObject *)&is_coo_i)); 5179566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)A, "__PETSc_coo_j", (PetscObject *)&is_coo_j)); 51828b400f6SJacob Faibussowitsch PetscCheck(is_coo_i, PetscObjectComm((PetscObject)A), PETSC_ERR_COR, "Missing coo_i IS"); 51928b400f6SJacob Faibussowitsch PetscCheck(is_coo_j, PetscObjectComm((PetscObject)A), PETSC_ERR_COR, "Missing coo_j IS"); 5209566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(is_coo_i, &n_i)); 5219566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(is_coo_j, &n_j)); 52208401ef6SPierre Jolivet PetscCheck(n_i == n_j, PETSC_COMM_SELF, PETSC_ERR_COR, "Wrong local size %" PetscInt_FMT " != %" PetscInt_FMT, n_i, n_j); 5239566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is_coo_i, &coo_i)); 5249566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is_coo_j, &coo_j)); 52548a46eb9SPierre Jolivet if (imode != ADD_VALUES) PetscCall(MatZeroEntries(A)); 52648a46eb9SPierre 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)); 5279566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is_coo_i, &coo_i)); 5289566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is_coo_j, &coo_j)); 5293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5307e8381f9SStefano Zampini } 5317e8381f9SStefano Zampini 532d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetPreallocationCOO_Basic(Mat A, PetscCount ncoo, const PetscInt coo_i[], const PetscInt coo_j[]) 533d71ae5a4SJacob Faibussowitsch { 5347e8381f9SStefano Zampini Mat preallocator; 5357e8381f9SStefano Zampini IS is_coo_i, is_coo_j; 5367e8381f9SStefano Zampini PetscScalar zero = 0.0; 5377e8381f9SStefano Zampini 5387e8381f9SStefano Zampini PetscFunctionBegin; 5399566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 5409566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 5419566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &preallocator)); 5429566063dSJacob Faibussowitsch PetscCall(MatSetType(preallocator, MATPREALLOCATOR)); 5439566063dSJacob Faibussowitsch PetscCall(MatSetSizes(preallocator, A->rmap->n, A->cmap->n, A->rmap->N, A->cmap->N)); 5449566063dSJacob Faibussowitsch PetscCall(MatSetLayouts(preallocator, A->rmap, A->cmap)); 5459566063dSJacob Faibussowitsch PetscCall(MatSetUp(preallocator)); 54648a46eb9SPierre Jolivet for (PetscCount n = 0; n < ncoo; n++) PetscCall(MatSetValue(preallocator, coo_i[n], coo_j[n], zero, INSERT_VALUES)); 5479566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(preallocator, MAT_FINAL_ASSEMBLY)); 5489566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(preallocator, MAT_FINAL_ASSEMBLY)); 5499566063dSJacob Faibussowitsch PetscCall(MatPreallocatorPreallocate(preallocator, PETSC_TRUE, A)); 5509566063dSJacob Faibussowitsch PetscCall(MatDestroy(&preallocator)); 5512c71b3e2SJacob 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); 5529566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, ncoo, coo_i, PETSC_COPY_VALUES, &is_coo_i)); 5539566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, ncoo, coo_j, PETSC_COPY_VALUES, &is_coo_j)); 5549566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "__PETSc_coo_i", (PetscObject)is_coo_i)); 5559566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "__PETSc_coo_j", (PetscObject)is_coo_j)); 5569566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is_coo_i)); 5579566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is_coo_j)); 5583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5597e8381f9SStefano Zampini } 5607e8381f9SStefano Zampini 56156856777SBarry Smith /*@C 562c3dd2894SJed Brown MatSetPreallocationCOO - set preallocation for matrices using a coordinate format of the entries with global indices 5637e8381f9SStefano Zampini 564c3339decSBarry Smith Collective 5657e8381f9SStefano Zampini 5664165533cSJose E. Roman Input Parameters: 5677e8381f9SStefano Zampini + A - matrix being preallocated 56842550becSJunchao Zhang . ncoo - number of entries 5697e8381f9SStefano Zampini . coo_i - row indices 5707e8381f9SStefano Zampini - coo_j - column indices 5717e8381f9SStefano Zampini 5727e8381f9SStefano Zampini Level: beginner 5737e8381f9SStefano Zampini 574394ed5ebSJunchao Zhang Notes: 5752ef1f0ffSBarry Smith The indices `coo_i` and `coo_j` may be modified within this function. The caller should not rely on them 576e8729f6fSJunchao Zhang having any specific value after this function returns. The arrays can be freed or reused immediately 577e8729f6fSJunchao Zhang after this function returns. 578e8729f6fSJunchao Zhang 57911a5261eSBarry Smith Entries can be repeated, see `MatSetValuesCOO()`. Entries with negative row or column indices are allowed 58011a5261eSBarry Smith but will be ignored. The corresponding entries in `MatSetValuesCOO()` will be ignored too. Remote entries 581d7547e51SJunchao Zhang are allowed and will be properly added or inserted to the matrix, unless the matrix option `MAT_IGNORE_OFF_PROC_ENTRIES` 58211a5261eSBarry 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. 5837e8381f9SStefano Zampini 584d7547e51SJunchao 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 585d7547e51SJunchao Zhang `MatCreateSeqAIJFromTriple()`. But that is not recommended for iterative applications. 586d7547e51SJunchao Zhang 5871cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatSetValuesCOO()`, `MatSeqAIJSetPreallocation()`, `MatMPIAIJSetPreallocation()`, `MatSeqBAIJSetPreallocation()`, 5882ef1f0ffSBarry Smith `MatMPIBAIJSetPreallocation()`, `MatSeqSBAIJSetPreallocation()`, `MatMPISBAIJSetPreallocation()`, `MatSetPreallocationCOOLocal()`, 5892ef1f0ffSBarry Smith `DMSetMatrixPreallocateSkip()`, `MatCreateSeqAIJFromTriple()` 5907e8381f9SStefano Zampini @*/ 591d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetPreallocationCOO(Mat A, PetscCount ncoo, PetscInt coo_i[], PetscInt coo_j[]) 592d71ae5a4SJacob Faibussowitsch { 59382a78a4eSJed Brown PetscErrorCode (*f)(Mat, PetscCount, const PetscInt[], const PetscInt[]) = NULL; 5947e8381f9SStefano Zampini 5957e8381f9SStefano Zampini PetscFunctionBegin; 5967e8381f9SStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 5977e8381f9SStefano Zampini PetscValidType(A, 1); 5987e8381f9SStefano Zampini if (ncoo) PetscValidIntPointer(coo_i, 3); 5997e8381f9SStefano Zampini if (ncoo) PetscValidIntPointer(coo_j, 4); 6009566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 6019566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 6029566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatSetPreallocationCOO_C", &f)); 603cbc6b225SStefano Zampini 6049566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(MAT_PreallCOO, A, 0, 0, 0)); 6057e8381f9SStefano Zampini if (f) { 6069566063dSJacob Faibussowitsch PetscCall((*f)(A, ncoo, coo_i, coo_j)); 6077e8381f9SStefano Zampini } else { /* allow fallback, very slow */ 6089566063dSJacob Faibussowitsch PetscCall(MatSetPreallocationCOO_Basic(A, ncoo, coo_i, coo_j)); 6097e8381f9SStefano Zampini } 6109566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(MAT_PreallCOO, A, 0, 0, 0)); 6116834774dSStefano Zampini A->preallocated = PETSC_TRUE; 612cbc6b225SStefano Zampini A->nonzerostate++; 6133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6147e8381f9SStefano Zampini } 6157e8381f9SStefano Zampini 61656856777SBarry Smith /*@C 617c3dd2894SJed Brown MatSetPreallocationCOOLocal - set preallocation for matrices using a coordinate format of the entries with local indices 618c3dd2894SJed Brown 619c3339decSBarry Smith Collective 620c3dd2894SJed Brown 621c3dd2894SJed Brown Input Parameters: 622c3dd2894SJed Brown + A - matrix being preallocated 623c3dd2894SJed Brown . ncoo - number of entries 624c3dd2894SJed Brown . coo_i - row indices (local numbering; may be modified) 625c3dd2894SJed Brown - coo_j - column indices (local numbering; may be modified) 626c3dd2894SJed Brown 627c3dd2894SJed Brown Level: beginner 628c3dd2894SJed Brown 629c3dd2894SJed Brown Notes: 63011a5261eSBarry Smith The local indices are translated using the local to global mapping, thus `MatSetLocalToGlobalMapping()` must have been 63111a5261eSBarry Smith called prior to this function. For matrices created with `DMCreateMatrix()` the local to global mapping is often already provided. 632c3dd2894SJed Brown 6332ef1f0ffSBarry Smith The indices `coo_i` and `coo_j` may be modified within this function. They might be translated to corresponding global 634735d7f90SBarry Smith indices, but the caller should not rely on them having any specific value after this function returns. The arrays 635735d7f90SBarry Smith can be freed or reused immediately after this function returns. 636c3dd2894SJed Brown 63711a5261eSBarry Smith Entries can be repeated, see `MatSetValuesCOO()`. Entries with negative row or column indices are allowed 63811a5261eSBarry Smith but will be ignored. The corresponding entries in `MatSetValuesCOO()` will be ignored too. Remote entries 639394ed5ebSJunchao Zhang are allowed and will be properly added or inserted to the matrix. 640c3dd2894SJed Brown 6411cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatSetValuesCOO()`, `MatSeqAIJSetPreallocation()`, `MatMPIAIJSetPreallocation()`, `MatSeqBAIJSetPreallocation()`, 6422ef1f0ffSBarry Smith `MatMPIBAIJSetPreallocation()`, `MatSeqSBAIJSetPreallocation()`, `MatMPISBAIJSetPreallocation()`, `MatSetPreallocationCOO()`, 6432ef1f0ffSBarry Smith `DMSetMatrixPreallocateSkip()` 644c3dd2894SJed Brown @*/ 645d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetPreallocationCOOLocal(Mat A, PetscCount ncoo, PetscInt coo_i[], PetscInt coo_j[]) 646d71ae5a4SJacob Faibussowitsch { 6476834774dSStefano Zampini PetscErrorCode (*f)(Mat, PetscCount, PetscInt[], PetscInt[]) = NULL; 648c3dd2894SJed Brown 649c3dd2894SJed Brown PetscFunctionBegin; 650c3dd2894SJed Brown PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 651c3dd2894SJed Brown PetscValidType(A, 1); 652c3dd2894SJed Brown if (ncoo) PetscValidIntPointer(coo_i, 3); 653c3dd2894SJed Brown if (ncoo) PetscValidIntPointer(coo_j, 4); 6546834774dSStefano 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); 6559566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 6569566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 657cbc6b225SStefano Zampini 6589566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatSetPreallocationCOOLocal_C", &f)); 6596834774dSStefano Zampini if (f) { 6609566063dSJacob Faibussowitsch PetscCall((*f)(A, ncoo, coo_i, coo_j)); 661cbc6b225SStefano Zampini A->nonzerostate++; 6626834774dSStefano Zampini } else { 663cbc6b225SStefano Zampini ISLocalToGlobalMapping ltog_row, ltog_col; 6649566063dSJacob Faibussowitsch PetscCall(MatGetLocalToGlobalMapping(A, <og_row, <og_col)); 6659566063dSJacob Faibussowitsch if (ltog_row) PetscCall(ISLocalToGlobalMappingApply(ltog_row, ncoo, coo_i, coo_i)); 6669566063dSJacob Faibussowitsch if (ltog_col) PetscCall(ISLocalToGlobalMappingApply(ltog_col, ncoo, coo_j, coo_j)); 6679566063dSJacob Faibussowitsch PetscCall(MatSetPreallocationCOO(A, ncoo, coo_i, coo_j)); 6686834774dSStefano Zampini } 6696834774dSStefano Zampini A->preallocated = PETSC_TRUE; 6703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 671c3dd2894SJed Brown } 672c3dd2894SJed Brown 673c3dd2894SJed Brown /*@ 67411a5261eSBarry Smith MatSetValuesCOO - set values at once in a matrix preallocated using `MatSetPreallocationCOO()` 6757e8381f9SStefano Zampini 676c3339decSBarry Smith Collective 6777e8381f9SStefano Zampini 6784165533cSJose E. Roman Input Parameters: 6797e8381f9SStefano Zampini + A - matrix being preallocated 6802ef1f0ffSBarry Smith . coo_v - the matrix values (can be `NULL`) 6817e8381f9SStefano Zampini - imode - the insert mode 6827e8381f9SStefano Zampini 6837e8381f9SStefano Zampini Level: beginner 6847e8381f9SStefano Zampini 68511a5261eSBarry Smith Notes: 68611a5261eSBarry Smith The values must follow the order of the indices prescribed with `MatSetPreallocationCOO()` or `MatSetPreallocationCOOLocal()`. 68711a5261eSBarry Smith 6882ef1f0ffSBarry Smith When repeated entries are specified in the COO indices the `coo_v` values are first properly summed, regardless of the value of imode. 68911a5261eSBarry Smith The imode flag indicates if coo_v must be added to the current values of the matrix (`ADD_VALUES`) or overwritten (`INSERT_VALUES`). 69011a5261eSBarry Smith 69111a5261eSBarry Smith `MatAssemblyBegin()` and `MatAssemblyEnd()` do not need to be called after this routine. It automatically handles the assembly process. 6927e8381f9SStefano Zampini 6931cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatSetPreallocationCOO()`, `MatSetPreallocationCOOLocal()`, `InsertMode`, `INSERT_VALUES`, `ADD_VALUES` 6947e8381f9SStefano Zampini @*/ 695d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetValuesCOO(Mat A, const PetscScalar coo_v[], InsertMode imode) 696d71ae5a4SJacob Faibussowitsch { 6977e8381f9SStefano Zampini PetscErrorCode (*f)(Mat, const PetscScalar[], InsertMode) = NULL; 698*35cef55dSJunchao Zhang PetscBool oldFlg; 6997e8381f9SStefano Zampini 7007e8381f9SStefano Zampini PetscFunctionBegin; 7017e8381f9SStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 7027e8381f9SStefano Zampini PetscValidType(A, 1); 7037e8381f9SStefano Zampini MatCheckPreallocated(A, 1); 704bfcc3627SStefano Zampini PetscValidLogicalCollectiveEnum(A, imode, 3); 7059566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatSetValuesCOO_C", &f)); 7069566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(MAT_SetVCOO, A, 0, 0, 0)); 7077e8381f9SStefano Zampini if (f) { 708*35cef55dSJunchao Zhang PetscCall((*f)(A, coo_v, imode)); // all known COO implementations do not use MatStash. They do their own off-proc communication 709*35cef55dSJunchao Zhang PetscCall(MatGetOption(A, MAT_NO_OFF_PROC_ENTRIES, &oldFlg)); 710*35cef55dSJunchao Zhang PetscCall(MatSetOption(A, MAT_NO_OFF_PROC_ENTRIES, PETSC_TRUE)); // set A->nooffprocentries to avoid costly MatStash scatter in MatAssembly 711*35cef55dSJunchao Zhang } else { 712*35cef55dSJunchao Zhang PetscCall(MatSetValuesCOO_Basic(A, coo_v, imode)); // fall back to MatSetValues, which might use MatStash 7137e8381f9SStefano Zampini } 7149566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 7159566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 716*35cef55dSJunchao Zhang if (f) PetscCall(MatSetOption(A, MAT_NO_OFF_PROC_ENTRIES, oldFlg)); 717*35cef55dSJunchao Zhang PetscCall(PetscLogEventEnd(MAT_SetVCOO, A, 0, 0, 0)); 7183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7197e8381f9SStefano Zampini } 72065a9ecf2SRichard Tran Mills 72165a9ecf2SRichard Tran Mills /*@ 72265a9ecf2SRichard 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 72365a9ecf2SRichard Tran Mills 72465a9ecf2SRichard Tran Mills Input Parameters: 72565a9ecf2SRichard Tran Mills + A - the matrix 72665a9ecf2SRichard Tran Mills - flg - flag indicating whether the boundtocpu flag should be propagated 72765a9ecf2SRichard Tran Mills 72865a9ecf2SRichard Tran Mills Level: developer 72965a9ecf2SRichard Tran Mills 73065a9ecf2SRichard Tran Mills Notes: 7312fe279fdSBarry Smith If the value of flg is set to true, the following will occur 7322fe279fdSBarry Smith + `MatCreateSubMatrices()` and `MatCreateRedundantMatrix()` - bind created matrices to CPU if the input matrix is bound to the CPU. 7332fe279fdSBarry Smith - `MatCreateVecs()` - bind created vectors to CPU if the input matrix is bound to the CPU. 73465a9ecf2SRichard Tran Mills 73565a9ecf2SRichard Tran Mills The bindingpropagates flag itself is also propagated by the above routines. 73665a9ecf2SRichard Tran Mills 73711a5261eSBarry Smith Developer Note: 738aa624791SPierre Jolivet If the fine-scale `DMDA` has the `-dm_bind_below` option set to true, then `DMCreateInterpolationScale()` calls `MatSetBindingPropagates()` 73965a9ecf2SRichard Tran Mills on the restriction/interpolation operator to set the bindingpropagates flag to true. 74065a9ecf2SRichard Tran Mills 7411cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `VecSetBindingPropagates()`, `MatGetBindingPropagates()` 74265a9ecf2SRichard Tran Mills @*/ 743d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetBindingPropagates(Mat A, PetscBool flg) 744d71ae5a4SJacob Faibussowitsch { 74565a9ecf2SRichard Tran Mills PetscFunctionBegin; 74665a9ecf2SRichard Tran Mills PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 747d5e393b6SSuyash Tandon #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 74865a9ecf2SRichard Tran Mills A->bindingpropagates = flg; 74965a9ecf2SRichard Tran Mills #endif 7503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 75165a9ecf2SRichard Tran Mills } 752e9c74fd6SRichard Tran Mills 753e9c74fd6SRichard Tran Mills /*@ 754e9c74fd6SRichard 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 755e9c74fd6SRichard Tran Mills 756e9c74fd6SRichard Tran Mills Input Parameter: 757e9c74fd6SRichard Tran Mills . A - the matrix 758e9c74fd6SRichard Tran Mills 759e9c74fd6SRichard Tran Mills Output Parameter: 760e9c74fd6SRichard Tran Mills . flg - flag indicating whether the boundtocpu flag will be propagated 761e9c74fd6SRichard Tran Mills 762e9c74fd6SRichard Tran Mills Level: developer 763e9c74fd6SRichard Tran Mills 7641cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatSetBindingPropagates()` 765e9c74fd6SRichard Tran Mills @*/ 766d71ae5a4SJacob Faibussowitsch PetscErrorCode MatGetBindingPropagates(Mat A, PetscBool *flg) 767d71ae5a4SJacob Faibussowitsch { 768e9c74fd6SRichard Tran Mills PetscFunctionBegin; 769e9c74fd6SRichard Tran Mills PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 770e9c74fd6SRichard Tran Mills PetscValidBoolPointer(flg, 2); 771d5e393b6SSuyash Tandon #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 772e9c74fd6SRichard Tran Mills *flg = A->bindingpropagates; 773e9c74fd6SRichard Tran Mills #else 774e9c74fd6SRichard Tran Mills *flg = PETSC_FALSE; 775e9c74fd6SRichard Tran Mills #endif 7763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 777e9c74fd6SRichard Tran Mills } 778