1af0996ceSBarry Smith #include <petsc/private/matimpl.h> /*I "petscmat.h" I*/ 27807a1faSBarry Smith 3*cc1836a6SJunchao Zhang #include <../src/mat/impls/aij/seq/aij.h> 4*cc1836a6SJunchao Zhang #include <../src/mat/impls/aij/mpi/mpiaij.h> 5*cc1836a6SJunchao Zhang 6d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatSetBlockSizes_Default(Mat mat, PetscInt rbs, PetscInt cbs) 7d71ae5a4SJacob Faibussowitsch { 846533700Sstefano_zampini PetscFunctionBegin; 93ba16761SJacob Faibussowitsch if (!mat->preallocated) PetscFunctionReturn(PETSC_SUCCESS); 10aed4548fSBarry Smith PetscCheck(mat->rmap->bs <= 0 || mat->rmap->bs == rbs, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Cannot change row block size %" PetscInt_FMT " to %" PetscInt_FMT, mat->rmap->bs, rbs); 11aed4548fSBarry Smith PetscCheck(mat->cmap->bs <= 0 || mat->cmap->bs == cbs, PetscObjectComm((PetscObject)mat), PETSC_ERR_SUP, "Cannot change column block size %" PetscInt_FMT " to %" PetscInt_FMT, mat->cmap->bs, cbs); 123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1346533700Sstefano_zampini } 1446533700Sstefano_zampini 15d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatShift_Basic(Mat Y, PetscScalar a) 16d71ae5a4SJacob Faibussowitsch { 17*cc1836a6SJunchao Zhang PetscInt i, start, end, oldValA = 0, oldValB = 0; 187d68702bSBarry Smith PetscScalar alpha = a; 197d68702bSBarry Smith PetscBool prevoption; 20*cc1836a6SJunchao Zhang PetscBool isSeqAIJDerived, isMPIAIJDerived; // all classes sharing SEQAIJHEADER or MPIAIJHEADER 21*cc1836a6SJunchao Zhang Mat A = NULL, B = NULL; 227d68702bSBarry Smith 237d68702bSBarry Smith PetscFunctionBegin; 249566063dSJacob Faibussowitsch PetscCall(MatGetOption(Y, MAT_NO_OFF_PROC_ENTRIES, &prevoption)); 259566063dSJacob Faibussowitsch PetscCall(MatSetOption(Y, MAT_NO_OFF_PROC_ENTRIES, PETSC_TRUE)); 26*cc1836a6SJunchao Zhang PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)Y, &isSeqAIJDerived, MATSEQAIJ, MATSEQBAIJ, MATSEQSBAIJ, "")); 27*cc1836a6SJunchao Zhang PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)Y, &isMPIAIJDerived, MATMPIAIJ, MATMPIBAIJ, MATMPISBAIJ, "")); 28*cc1836a6SJunchao Zhang 29*cc1836a6SJunchao Zhang if (isSeqAIJDerived) A = Y; 30*cc1836a6SJunchao Zhang else if (isMPIAIJDerived) { 31*cc1836a6SJunchao Zhang Mat_MPIAIJ *mpiaij = (Mat_MPIAIJ *)Y->data; 32*cc1836a6SJunchao Zhang A = mpiaij->A; 33*cc1836a6SJunchao Zhang B = mpiaij->B; 34*cc1836a6SJunchao Zhang } 35*cc1836a6SJunchao Zhang 36*cc1836a6SJunchao Zhang if (A) { 37*cc1836a6SJunchao Zhang oldValA = ((Mat_SeqAIJ *)(A->data))->nonew; 38*cc1836a6SJunchao Zhang ((Mat_SeqAIJ *)(A->data))->nonew = 0; // so that new nonzero locations are allowed 39*cc1836a6SJunchao Zhang } 40*cc1836a6SJunchao Zhang if (B) { 41*cc1836a6SJunchao Zhang oldValB = ((Mat_SeqAIJ *)(B->data))->nonew; 42*cc1836a6SJunchao Zhang ((Mat_SeqAIJ *)(B->data))->nonew = 0; 43*cc1836a6SJunchao Zhang } 44*cc1836a6SJunchao Zhang 459566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(Y, &start, &end)); 467d68702bSBarry Smith for (i = start; i < end; i++) { 4748a46eb9SPierre Jolivet if (i < Y->cmap->N) PetscCall(MatSetValues(Y, 1, &i, 1, &i, &alpha, ADD_VALUES)); 48ab6153dcSStefano Zampini } 499566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(Y, MAT_FINAL_ASSEMBLY)); 509566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(Y, MAT_FINAL_ASSEMBLY)); 519566063dSJacob Faibussowitsch PetscCall(MatSetOption(Y, MAT_NO_OFF_PROC_ENTRIES, prevoption)); 52*cc1836a6SJunchao Zhang if (A) ((Mat_SeqAIJ *)(A->data))->nonew = oldValA; 53*cc1836a6SJunchao Zhang if (B) ((Mat_SeqAIJ *)(B->data))->nonew = oldValB; 543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 557d68702bSBarry Smith } 567d68702bSBarry Smith 5705869f15SSatish Balay /*@ 5869dd0797SLois Curfman McInnes MatCreate - Creates a matrix where the type is determined 5911a5261eSBarry Smith from either a call to `MatSetType()` or from the options database 602920cce0SJacob Faibussowitsch with a call to `MatSetFromOptions()`. 6183e1b59cSLois Curfman McInnes 62d083f849SBarry Smith Collective 63cb13003dSBarry Smith 64f69a0ea3SMatthew Knepley Input Parameter: 65f69a0ea3SMatthew Knepley . comm - MPI communicator 667807a1faSBarry Smith 677807a1faSBarry Smith Output Parameter: 68dc401e71SLois Curfman McInnes . A - the matrix 69e0b365e2SLois Curfman McInnes 70273d9f13SBarry Smith Options Database Keys: 7111a5261eSBarry Smith + -mat_type seqaij - `MATSEQAIJ` type, uses `MatCreateSeqAIJ()` 7211a5261eSBarry Smith . -mat_type mpiaij - `MATMPIAIJ` type, uses `MatCreateAIJ()` 7311a5261eSBarry Smith . -mat_type seqdense - `MATSEQDENSE`, uses `MatCreateSeqDense()` 7411a5261eSBarry Smith . -mat_type mpidense - `MATMPIDENSE` type, uses `MatCreateDense()` 7511a5261eSBarry Smith . -mat_type seqbaij - `MATSEQBAIJ` type, uses `MatCreateSeqBAIJ()` 7611a5261eSBarry Smith - -mat_type mpibaij - `MATMPIBAIJ` type, uses `MatCreateBAIJ()` 77e0b365e2SLois Curfman McInnes 782ef1f0ffSBarry Smith See the manpages for particular formats (e.g., `MATSEQAIJ`) 7983e1b59cSLois Curfman McInnes for additional format-specific options. 80e0b365e2SLois Curfman McInnes 81273d9f13SBarry Smith Level: beginner 82273d9f13SBarry Smith 832920cce0SJacob Faibussowitsch Notes: 842920cce0SJacob Faibussowitsch The default matrix type is `MATAIJ`, using the routines `MatCreateSeqAIJ()` or 852920cce0SJacob Faibussowitsch `MatCreateAIJ()` if you do not set a type in the options database. If you never call 862920cce0SJacob Faibussowitsch `MatSetType()` or `MatSetFromOptions()` it will generate an error when you try to use the 872920cce0SJacob Faibussowitsch matrix. 882920cce0SJacob Faibussowitsch 891cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatCreateSeqAIJ()`, `MatCreateAIJ()`, 90db781477SPatrick Sanan `MatCreateSeqDense()`, `MatCreateDense()`, 91db781477SPatrick Sanan `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, 92db781477SPatrick Sanan `MatCreateSeqSBAIJ()`, `MatCreateSBAIJ()`, 93db781477SPatrick Sanan `MatConvert()` 94273d9f13SBarry Smith @*/ 95d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreate(MPI_Comm comm, Mat *A) 96d71ae5a4SJacob Faibussowitsch { 97273d9f13SBarry Smith Mat B; 98273d9f13SBarry Smith 99273d9f13SBarry Smith PetscFunctionBegin; 1004f572ea9SToby Isaac PetscAssertPointer(A, 2); 10197f1f81fSBarry Smith 1020298fd71SBarry Smith *A = NULL; 1039566063dSJacob Faibussowitsch PetscCall(MatInitializePackage()); 1048ba1e511SMatthew Knepley 1059566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(B, MAT_CLASSID, "Mat", "Matrix", "Mat", comm, MatDestroy, MatView)); 1069566063dSJacob Faibussowitsch PetscCall(PetscLayoutCreate(comm, &B->rmap)); 1079566063dSJacob Faibussowitsch PetscCall(PetscLayoutCreate(comm, &B->cmap)); 1089566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(VECSTANDARD, &B->defaultvectype)); 1093faff063SStefano Zampini PetscCall(PetscStrallocpy(PETSCRANDER48, &B->defaultrandtype)); 11026fbe8dcSKarl Rupp 111b94d7dedSBarry Smith B->symmetric = PETSC_BOOL3_UNKNOWN; 112b94d7dedSBarry Smith B->hermitian = PETSC_BOOL3_UNKNOWN; 113b94d7dedSBarry Smith B->structurally_symmetric = PETSC_BOOL3_UNKNOWN; 114b94d7dedSBarry Smith B->spd = PETSC_BOOL3_UNKNOWN; 115b94d7dedSBarry Smith B->symmetry_eternal = PETSC_FALSE; 116b94d7dedSBarry Smith B->structural_symmetry_eternal = PETSC_FALSE; 117b94d7dedSBarry Smith 11894342113SStefano Zampini B->congruentlayouts = PETSC_DECIDE; 119273d9f13SBarry Smith B->preallocated = PETSC_FALSE; 1206f3d89d0SStefano Zampini #if defined(PETSC_HAVE_DEVICE) 1216f3d89d0SStefano Zampini B->boundtocpu = PETSC_TRUE; 1226f3d89d0SStefano Zampini #endif 123273d9f13SBarry Smith *A = B; 1243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 125273d9f13SBarry Smith } 126273d9f13SBarry Smith 12777433607SBarry Smith /*@C 12877433607SBarry Smith MatCreateFromOptions - Creates a matrix whose type is set from the options database 12977433607SBarry Smith 13077433607SBarry Smith Collective 13177433607SBarry Smith 13277433607SBarry Smith Input Parameters: 13377433607SBarry Smith + comm - MPI communicator 13477433607SBarry Smith . prefix - [optional] prefix for the options database 13577433607SBarry Smith . bs - the blocksize (commonly 1) 13677433607SBarry Smith . m - the local number of rows (or `PETSC_DECIDE`) 13777433607SBarry Smith . n - the local number of columns (or `PETSC_DECIDE` or `PETSC_DETERMINE`) 13877433607SBarry Smith . M - the global number of rows (or `PETSC_DETERMINE`) 13977433607SBarry Smith - N - the global number of columns (or `PETSC_DETERMINE`) 14077433607SBarry Smith 14177433607SBarry Smith Output Parameter: 14277433607SBarry Smith . A - the matrix 14377433607SBarry Smith 14477433607SBarry Smith Options Database Key: 14577433607SBarry Smith . -mat_type - see `MatType`, for example `aij`, `aijcusparse`, `baij`, `sbaij`, dense, defaults to `aij` 14677433607SBarry Smith 14777433607SBarry Smith Level: beginner 14877433607SBarry Smith 14977433607SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatCreateSeqAIJ()`, `MatCreateAIJ()`, 15077433607SBarry Smith `MatCreateSeqDense()`, `MatCreateDense()`, 15177433607SBarry Smith `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, 15277433607SBarry Smith `MatCreateSeqSBAIJ()`, `MatCreateSBAIJ()`, 15377433607SBarry Smith `MatConvert()`, `MatCreate()` 15477433607SBarry Smith @*/ 15577433607SBarry Smith PetscErrorCode MatCreateFromOptions(MPI_Comm comm, const char *prefix, PetscInt bs, PetscInt m, PetscInt n, PetscInt M, PetscInt N, Mat *A) 15677433607SBarry Smith { 15777433607SBarry Smith PetscFunctionBegin; 15877433607SBarry Smith PetscAssertPointer(A, 8); 15977433607SBarry Smith PetscCall(MatCreate(comm, A)); 16077433607SBarry Smith if (prefix) PetscCall(MatSetOptionsPrefix(*A, prefix)); 16177433607SBarry Smith PetscCall(MatSetBlockSize(*A, bs)); 16277433607SBarry Smith PetscCall(MatSetSizes(*A, m, n, M, N)); 16377433607SBarry Smith PetscCall(MatSetFromOptions(*A)); 16477433607SBarry Smith PetscFunctionReturn(PETSC_SUCCESS); 16577433607SBarry Smith } 16677433607SBarry Smith 167422a814eSBarry Smith /*@ 16811a5261eSBarry Smith MatSetErrorIfFailure - Causes `Mat` to generate an immediate error, for example a zero pivot, is detected. 169422a814eSBarry Smith 170c3339decSBarry Smith Logically Collective 171422a814eSBarry Smith 172422a814eSBarry Smith Input Parameters: 17311a5261eSBarry Smith + mat - matrix obtained from `MatCreate()` 17411a5261eSBarry Smith - flg - `PETSC_TRUE` indicates you want the error generated 175422a814eSBarry Smith 176422a814eSBarry Smith Level: advanced 177422a814eSBarry Smith 17811a5261eSBarry Smith Note: 17911a5261eSBarry 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 18011a5261eSBarry Smith or result in a `KSPConvergedReason` indicating the method did not converge. 18111a5261eSBarry Smith 1821cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `PCSetErrorIfFailure()`, `KSPConvergedReason`, `SNESConvergedReason` 183422a814eSBarry Smith @*/ 184d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetErrorIfFailure(Mat mat, PetscBool flg) 185d71ae5a4SJacob Faibussowitsch { 186422a814eSBarry Smith PetscFunctionBegin; 187422a814eSBarry Smith PetscValidHeaderSpecific(mat, MAT_CLASSID, 1); 188422a814eSBarry Smith PetscValidLogicalCollectiveBool(mat, flg, 2); 18984d44b13SHong Zhang mat->erroriffailure = flg; 1903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 191422a814eSBarry Smith } 192422a814eSBarry Smith 193f69a0ea3SMatthew Knepley /*@ 194f69a0ea3SMatthew Knepley MatSetSizes - Sets the local and global sizes, and checks to determine compatibility 195f69a0ea3SMatthew Knepley 196c3339decSBarry Smith Collective 197f69a0ea3SMatthew Knepley 198f69a0ea3SMatthew Knepley Input Parameters: 199f69a0ea3SMatthew Knepley + A - the matrix 20011a5261eSBarry Smith . m - number of local rows (or `PETSC_DECIDE`) 20111a5261eSBarry Smith . n - number of local columns (or `PETSC_DECIDE`) 20211a5261eSBarry Smith . M - number of global rows (or `PETSC_DETERMINE`) 20311a5261eSBarry Smith - N - number of global columns (or `PETSC_DETERMINE`) 204f69a0ea3SMatthew Knepley 2052fe279fdSBarry Smith Level: beginner 2062fe279fdSBarry Smith 207f69a0ea3SMatthew Knepley Notes: 2082ef1f0ffSBarry Smith `m` (`n`) and `M` (`N`) cannot be both `PETSC_DECIDE` 2092ef1f0ffSBarry Smith If one processor calls this with `M` (`N`) of `PETSC_DECIDE` then all processors must, otherwise the program will hang. 210f69a0ea3SMatthew Knepley 21111a5261eSBarry Smith If `PETSC_DECIDE` is not used for the arguments 'm' and 'n', then the 212f69a0ea3SMatthew Knepley user must ensure that they are chosen to be compatible with the 213f69a0ea3SMatthew Knepley vectors. To do this, one first considers the matrix-vector product 2142ef1f0ffSBarry Smith 'y = A x'. The `m` that is used in the above routine must match the 2152ef1f0ffSBarry Smith local size used in the vector creation routine `VecCreateMPI()` for 'y'. 2162ef1f0ffSBarry Smith Likewise, the `n` used must match that used as the local size in 21711a5261eSBarry Smith `VecCreateMPI()` for 'x'. 218f69a0ea3SMatthew Knepley 219f73d5cc4SBarry Smith You cannot change the sizes once they have been set. 220f73d5cc4SBarry Smith 22111a5261eSBarry Smith The sizes must be set before `MatSetUp()` or MatXXXSetPreallocation() is called. 222f73d5cc4SBarry Smith 2231cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatGetSize()`, `PetscSplitOwnership()` 224f69a0ea3SMatthew Knepley @*/ 225d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetSizes(Mat A, PetscInt m, PetscInt n, PetscInt M, PetscInt N) 226d71ae5a4SJacob Faibussowitsch { 227f69a0ea3SMatthew Knepley PetscFunctionBegin; 2280700a824SBarry Smith PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 229a69c7061SStefano Zampini PetscValidLogicalCollectiveInt(A, M, 4); 230a69c7061SStefano Zampini PetscValidLogicalCollectiveInt(A, N, 5); 231aed4548fSBarry 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); 232aed4548fSBarry 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); 2339371c9d4SSatish 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, 2349371c9d4SSatish Balay A->rmap->n, A->rmap->N); 2359371c9d4SSatish 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, 2369371c9d4SSatish Balay A->cmap->n, A->cmap->N); 237d0f46423SBarry Smith A->rmap->n = m; 238d0f46423SBarry Smith A->cmap->n = n; 23959cb773eSBarry Smith A->rmap->N = M > -1 ? M : A->rmap->N; 24059cb773eSBarry Smith A->cmap->N = N > -1 ? N : A->cmap->N; 2413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 242f69a0ea3SMatthew Knepley } 243f69a0ea3SMatthew Knepley 24405869f15SSatish Balay /*@ 245273d9f13SBarry Smith MatSetFromOptions - Creates a matrix where the type is determined 2462920cce0SJacob Faibussowitsch from the options database. 247273d9f13SBarry Smith 248c3339decSBarry Smith Collective 249273d9f13SBarry Smith 250273d9f13SBarry Smith Input Parameter: 251fe59aa6dSJacob Faibussowitsch . B - the matrix 252273d9f13SBarry Smith 253273d9f13SBarry Smith Options Database Keys: 25411a5261eSBarry Smith + -mat_type seqaij - `MATSEQAIJ` type, uses `MatCreateSeqAIJ()` 25511a5261eSBarry Smith . -mat_type mpiaij - `MATMPIAIJ` type, uses `MatCreateAIJ()` 25611a5261eSBarry Smith . -mat_type seqdense - `MATSEQDENSE` type, uses `MatCreateSeqDense()` 25711a5261eSBarry Smith . -mat_type mpidense - `MATMPIDENSE`, uses `MatCreateDense()` 25811a5261eSBarry Smith . -mat_type seqbaij - `MATSEQBAIJ`, uses `MatCreateSeqBAIJ()` 25911a5261eSBarry Smith - -mat_type mpibaij - `MATMPIBAIJ`, uses `MatCreateBAIJ()` 260273d9f13SBarry Smith 2612ef1f0ffSBarry Smith See the manpages for particular formats (e.g., `MATSEQAIJ`) 262273d9f13SBarry Smith for additional format-specific options. 263bd9ce289SLois Curfman McInnes 2641d69843bSLois Curfman McInnes Level: beginner 2651d69843bSLois Curfman McInnes 2662920cce0SJacob Faibussowitsch Notes: 2672920cce0SJacob Faibussowitsch Generates a parallel MPI matrix if the communicator has more than one processor. The default 2682920cce0SJacob Faibussowitsch matrix type is `MATAIJ`, using the routines `MatCreateSeqAIJ()` and `MatCreateAIJ()` if you 2692920cce0SJacob Faibussowitsch do not select a type in the options database. 2702920cce0SJacob Faibussowitsch 2711cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatCreateSeqAIJ()`, `MatCreateAIJ()`, 272db781477SPatrick Sanan `MatCreateSeqDense()`, `MatCreateDense()`, 273db781477SPatrick Sanan `MatCreateSeqBAIJ()`, `MatCreateBAIJ()`, 274db781477SPatrick Sanan `MatCreateSeqSBAIJ()`, `MatCreateSBAIJ()`, 275db781477SPatrick Sanan `MatConvert()` 2767807a1faSBarry Smith @*/ 277d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetFromOptions(Mat B) 278d71ae5a4SJacob Faibussowitsch { 279f3be49caSLisandro Dalcin const char *deft = MATAIJ; 280f3be49caSLisandro Dalcin char type[256]; 28169df5c0cSJed Brown PetscBool flg, set; 28216e04d98SRichard Tran Mills PetscInt bind_below = 0; 283dbb450caSBarry Smith 2843a40ed3dSBarry Smith PetscFunctionBegin; 2850700a824SBarry Smith PetscValidHeaderSpecific(B, MAT_CLASSID, 1); 286f3be49caSLisandro Dalcin 287d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)B); 288535b19f3SBarry Smith 289535b19f3SBarry Smith if (B->rmap->bs < 0) { 290535b19f3SBarry Smith PetscInt newbs = -1; 2919566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-mat_block_size", "Set the blocksize used to store the matrix", "MatSetBlockSize", newbs, &newbs, &flg)); 292535b19f3SBarry Smith if (flg) { 2939566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetBlockSize(B->rmap, newbs)); 2949566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetBlockSize(B->cmap, newbs)); 295535b19f3SBarry Smith } 296535b19f3SBarry Smith } 297535b19f3SBarry Smith 2989566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-mat_type", "Matrix type", "MatSetType", MatList, deft, type, 256, &flg)); 299273d9f13SBarry Smith if (flg) { 3009566063dSJacob Faibussowitsch PetscCall(MatSetType(B, type)); 301f3be49caSLisandro Dalcin } else if (!((PetscObject)B)->type_name) { 3029566063dSJacob Faibussowitsch PetscCall(MatSetType(B, deft)); 303273d9f13SBarry Smith } 304f3be49caSLisandro Dalcin 3059566063dSJacob Faibussowitsch PetscCall(PetscOptionsName("-mat_is_symmetric", "Checks if mat is symmetric on MatAssemblyEnd()", "MatIsSymmetric", &B->checksymmetryonassembly)); 3069566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-mat_is_symmetric", "Checks if mat is symmetric on MatAssemblyEnd()", "MatIsSymmetric", B->checksymmetrytol, &B->checksymmetrytol, NULL)); 3079566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-mat_null_space_test", "Checks if provided null space is correct in MatAssemblyEnd()", "MatSetNullSpaceTest", B->checknullspaceonassembly, &B->checknullspaceonassembly, NULL)); 3089566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-mat_error_if_failure", "Generate an error if an error occurs when factoring the matrix", "MatSetErrorIfFailure", B->erroriffailure, &B->erroriffailure, NULL)); 309840d65ccSBarry Smith 310dbbe0bcdSBarry Smith PetscTryTypeMethod(B, setfromoptions, PetscOptionsObject); 311f3be49caSLisandro Dalcin 31269df5c0cSJed Brown flg = PETSC_FALSE; 3139566063dSJacob 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)); 3149566063dSJacob Faibussowitsch if (set) PetscCall(MatSetOption(B, MAT_NEW_NONZERO_LOCATION_ERR, flg)); 31569df5c0cSJed Brown flg = PETSC_FALSE; 3169566063dSJacob 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)); 3179566063dSJacob Faibussowitsch if (set) PetscCall(MatSetOption(B, MAT_NEW_NONZERO_ALLOCATION_ERR, flg)); 318478db826SMatthew G. Knepley flg = PETSC_FALSE; 3199566063dSJacob 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)); 3209566063dSJacob Faibussowitsch if (set) PetscCall(MatSetOption(B, MAT_IGNORE_ZERO_ENTRIES, flg)); 32169df5c0cSJed Brown 3221a2c6b5cSJunchao Zhang flg = PETSC_FALSE; 3239566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-mat_form_explicit_transpose", "Hint to form an explicit transpose for operations like MatMultTranspose", "MatSetOption", flg, &flg, &set)); 3249566063dSJacob Faibussowitsch if (set) PetscCall(MatSetOption(B, MAT_FORM_EXPLICIT_TRANSPOSE, flg)); 3251a2c6b5cSJunchao Zhang 32616e04d98SRichard Tran Mills /* Bind to CPU if below a user-specified size threshold. 32716e04d98SRichard Tran Mills * This perhaps belongs in the options for the GPU Mat types, but MatBindToCPU() does nothing when called on non-GPU types, 32816e04d98SRichard Tran Mills * and putting it here makes is more maintainable than duplicating this for all. */ 3299566063dSJacob 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)); 33048a46eb9SPierre Jolivet if (flg && B->rmap->n < bind_below) PetscCall(MatBindToCPU(B, PETSC_TRUE)); 33116e04d98SRichard Tran Mills 3325d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 333dbbe0bcdSBarry Smith PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)B, PetscOptionsObject)); 334d0609cedSBarry Smith PetscOptionsEnd(); 3353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3367807a1faSBarry Smith } 3377807a1faSBarry Smith 338987010e7SBarry Smith /*@C 33911a5261eSBarry Smith MatXAIJSetPreallocation - set preallocation for serial and parallel `MATAIJ`, `MATBAIJ`, and `MATSBAIJ` matrices and their unassembled versions. 34063562e91SJed Brown 341c3339decSBarry Smith Collective 34263562e91SJed Brown 3434165533cSJose E. Roman Input Parameters: 34463562e91SJed Brown + A - matrix being preallocated 34563562e91SJed Brown . bs - block size 34641319c1dSStefano Zampini . dnnz - number of nonzero column blocks per block row of diagonal part of parallel matrix 34741319c1dSStefano Zampini . onnz - number of nonzero column blocks per block row of off-diagonal part of parallel matrix 34841319c1dSStefano Zampini . dnnzu - number of nonzero column blocks per block row of upper-triangular part of diagonal part of parallel matrix 34941319c1dSStefano Zampini - onnzu - number of nonzero column blocks per block row of upper-triangular part of off-diagonal part of parallel matrix 35063562e91SJed Brown 35163562e91SJed Brown Level: beginner 35263562e91SJed Brown 3531cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatSeqAIJSetPreallocation()`, `MatMPIAIJSetPreallocation()`, `MatSeqBAIJSetPreallocation()`, `MatMPIBAIJSetPreallocation()`, 3542fe279fdSBarry Smith `MatSeqSBAIJSetPreallocation()`, `MatMPISBAIJSetPreallocation()`, 355db781477SPatrick Sanan `PetscSplitOwnership()` 35663562e91SJed Brown @*/ 357d71ae5a4SJacob Faibussowitsch PetscErrorCode MatXAIJSetPreallocation(Mat A, PetscInt bs, const PetscInt dnnz[], const PetscInt onnz[], const PetscInt dnnzu[], const PetscInt onnzu[]) 358d71ae5a4SJacob Faibussowitsch { 35941319c1dSStefano Zampini PetscInt cbs; 36063562e91SJed Brown void (*aij)(void); 361e8bd9bafSStefano Zampini void (*is)(void); 362990279feSStefano Zampini void (*hyp)(void) = NULL; 36363562e91SJed Brown 36463562e91SJed Brown PetscFunctionBegin; 36541319c1dSStefano Zampini if (bs != PETSC_DECIDE) { /* don't mess with an already set block size */ 3669566063dSJacob Faibussowitsch PetscCall(MatSetBlockSize(A, bs)); 36741319c1dSStefano Zampini } 3689566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 3699566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 3709566063dSJacob Faibussowitsch PetscCall(MatGetBlockSizes(A, &bs, &cbs)); 37141319c1dSStefano Zampini /* these routines assumes bs == cbs, this should be checked somehow */ 3729566063dSJacob Faibussowitsch PetscCall(MatSeqBAIJSetPreallocation(A, bs, 0, dnnz)); 3739566063dSJacob Faibussowitsch PetscCall(MatMPIBAIJSetPreallocation(A, bs, 0, dnnz, 0, onnz)); 3749566063dSJacob Faibussowitsch PetscCall(MatSeqSBAIJSetPreallocation(A, bs, 0, dnnzu)); 3759566063dSJacob Faibussowitsch PetscCall(MatMPISBAIJSetPreallocation(A, bs, 0, dnnzu, 0, onnzu)); 37663562e91SJed Brown /* 377e8bd9bafSStefano 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 37863562e91SJed Brown good before going on with it. 37963562e91SJed Brown */ 3809566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatMPIAIJSetPreallocation_C", &aij)); 3819566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatISSetPreallocation_C", &is)); 382990279feSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 3839566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatHYPRESetPreallocation_C", &hyp)); 384990279feSStefano Zampini #endif 38548a46eb9SPierre Jolivet if (!aij && !is && !hyp) PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatSeqAIJSetPreallocation_C", &aij)); 386990279feSStefano Zampini if (aij || is || hyp) { 38741319c1dSStefano Zampini if (bs == cbs && bs == 1) { 3889566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(A, 0, dnnz)); 3899566063dSJacob Faibussowitsch PetscCall(MatMPIAIJSetPreallocation(A, 0, dnnz, 0, onnz)); 3909566063dSJacob Faibussowitsch PetscCall(MatISSetPreallocation(A, 0, dnnz, 0, onnz)); 391990279feSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 3929566063dSJacob Faibussowitsch PetscCall(MatHYPRESetPreallocation(A, 0, dnnz, 0, onnz)); 393990279feSStefano Zampini #endif 3943e5f4774SJed Brown } else { /* Convert block-row precallocation to scalar-row */ 39563562e91SJed Brown PetscInt i, m, *sdnnz, *sonnz; 3969566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(A, &m, NULL)); 3979566063dSJacob Faibussowitsch PetscCall(PetscMalloc2((!!dnnz) * m, &sdnnz, (!!onnz) * m, &sonnz)); 398dec54756SJed Brown for (i = 0; i < m; i++) { 39941319c1dSStefano Zampini if (dnnz) sdnnz[i] = dnnz[i / bs] * cbs; 40041319c1dSStefano Zampini if (onnz) sonnz[i] = onnz[i / bs] * cbs; 40163562e91SJed Brown } 4029566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(A, 0, dnnz ? sdnnz : NULL)); 4039566063dSJacob Faibussowitsch PetscCall(MatMPIAIJSetPreallocation(A, 0, dnnz ? sdnnz : NULL, 0, onnz ? sonnz : NULL)); 4049566063dSJacob Faibussowitsch PetscCall(MatISSetPreallocation(A, 0, dnnz ? sdnnz : NULL, 0, onnz ? sonnz : NULL)); 405990279feSStefano Zampini #if defined(PETSC_HAVE_HYPRE) 4069566063dSJacob Faibussowitsch PetscCall(MatHYPRESetPreallocation(A, 0, dnnz ? sdnnz : NULL, 0, onnz ? sonnz : NULL)); 407990279feSStefano Zampini #endif 4089566063dSJacob Faibussowitsch PetscCall(PetscFree2(sdnnz, sonnz)); 40963562e91SJed Brown } 41063562e91SJed Brown } 4113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 41263562e91SJed Brown } 41363562e91SJed Brown 414273d9f13SBarry Smith /* 415eb6b5d47SBarry Smith Merges some information from Cs header to A; the C object is then destroyed 416d0f46423SBarry Smith 417d0f46423SBarry Smith This is somewhat different from MatHeaderReplace() it would be nice to merge the code 418273d9f13SBarry Smith */ 419d71ae5a4SJacob Faibussowitsch PetscErrorCode MatHeaderMerge(Mat A, Mat *C) 420d71ae5a4SJacob Faibussowitsch { 421d44834fbSBarry Smith PetscInt refct; 42273107ff1SLisandro Dalcin PetscOps Abops; 42373107ff1SLisandro Dalcin struct _MatOps Aops; 4244768301cSVaclav Hapla char *mtype, *mname, *mprefix; 4254222ddf1SHong Zhang Mat_Product *product; 42633e6eea4SJose E. Roman Mat_Redundant *redundant; 427d4a972cbSStefano Zampini PetscObjectState state; 428273d9f13SBarry Smith 429273d9f13SBarry Smith PetscFunctionBegin; 4301dc04de0SStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 4311dc04de0SStefano Zampini PetscValidHeaderSpecific(*C, MAT_CLASSID, 2); 4323ba16761SJacob Faibussowitsch if (A == *C) PetscFunctionReturn(PETSC_SUCCESS); 4331dc04de0SStefano Zampini PetscCheckSameComm(A, 1, *C, 2); 434273d9f13SBarry Smith /* save the parts of A we need */ 43573107ff1SLisandro Dalcin Abops = ((PetscObject)A)->bops[0]; 43673107ff1SLisandro Dalcin Aops = A->ops[0]; 4377adad957SLisandro Dalcin refct = ((PetscObject)A)->refct; 4385c9eb25fSBarry Smith mtype = ((PetscObject)A)->type_name; 4395c9eb25fSBarry Smith mname = ((PetscObject)A)->name; 440d4a972cbSStefano Zampini state = ((PetscObject)A)->state; 4414768301cSVaclav Hapla mprefix = ((PetscObject)A)->prefix; 4424222ddf1SHong Zhang product = A->product; 44333e6eea4SJose E. Roman redundant = A->redundant; 44430735b05SKris Buschelman 4455c9eb25fSBarry Smith /* zero these so the destroy below does not free them */ 446f4259b30SLisandro Dalcin ((PetscObject)A)->type_name = NULL; 447f4259b30SLisandro Dalcin ((PetscObject)A)->name = NULL; 4485c9eb25fSBarry Smith 449dbbe0bcdSBarry Smith /* 450dbbe0bcdSBarry Smith free all the interior data structures from mat 451dbbe0bcdSBarry Smith cannot use PetscUseTypeMethod(A,destroy); because compiler 452dbbe0bcdSBarry Smith thinks it may print NULL type_name and name 453dbbe0bcdSBarry Smith */ 454dbbe0bcdSBarry Smith PetscTryTypeMethod(A, destroy); 4557c99f97cSSatish Balay 4569566063dSJacob Faibussowitsch PetscCall(PetscFree(A->defaultvectype)); 4573faff063SStefano Zampini PetscCall(PetscFree(A->defaultrandtype)); 4589566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&A->rmap)); 4599566063dSJacob Faibussowitsch PetscCall(PetscLayoutDestroy(&A->cmap)); 4609566063dSJacob Faibussowitsch PetscCall(PetscFunctionListDestroy(&((PetscObject)A)->qlist)); 4619566063dSJacob Faibussowitsch PetscCall(PetscObjectListDestroy(&((PetscObject)A)->olist)); 4629566063dSJacob Faibussowitsch PetscCall(PetscComposedQuantitiesDestroy((PetscObject)A)); 463273d9f13SBarry Smith 464273d9f13SBarry Smith /* copy C over to A */ 46526cc229bSBarry Smith PetscCall(PetscFree(A->factorprefix)); 4669566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(A, *C, sizeof(struct _p_Mat))); 467273d9f13SBarry Smith 468273d9f13SBarry Smith /* return the parts of A we saved */ 46973107ff1SLisandro Dalcin ((PetscObject)A)->bops[0] = Abops; 47073107ff1SLisandro Dalcin A->ops[0] = Aops; 4717adad957SLisandro Dalcin ((PetscObject)A)->refct = refct; 4727adad957SLisandro Dalcin ((PetscObject)A)->type_name = mtype; 4737adad957SLisandro Dalcin ((PetscObject)A)->name = mname; 4744768301cSVaclav Hapla ((PetscObject)A)->prefix = mprefix; 475d4a972cbSStefano Zampini ((PetscObject)A)->state = state + 1; 4764222ddf1SHong Zhang A->product = product; 47733e6eea4SJose E. Roman A->redundant = redundant; 478273d9f13SBarry Smith 4795c9eb25fSBarry Smith /* since these two are copied into A we do not want them destroyed in C */ 480f4259b30SLisandro Dalcin ((PetscObject)*C)->qlist = NULL; 481f4259b30SLisandro Dalcin ((PetscObject)*C)->olist = NULL; 48226fbe8dcSKarl Rupp 4839566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(C)); 4843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 485273d9f13SBarry Smith } 4868ab5b326SKris Buschelman /* 487eb6b5d47SBarry Smith Replace A's header with that of C; the C object is then destroyed 488d0f46423SBarry Smith 489eb6b5d47SBarry Smith This is essentially code moved from MatDestroy() 490eb6b5d47SBarry Smith 491eb6b5d47SBarry Smith This is somewhat different from MatHeaderMerge() it would be nice to merge the code 492b30237c6SBarry Smith 493b30237c6SBarry Smith Used in DM hence is declared PETSC_EXTERN 4948ab5b326SKris Buschelman */ 495d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode MatHeaderReplace(Mat A, Mat *C) 496d71ae5a4SJacob Faibussowitsch { 49727b31e29SJed Brown PetscInt refct; 498fefd9316SJose E. Roman PetscObjectState state; 49928be2f97SBarry Smith struct _p_Mat buffer; 50081fa06acSBarry Smith MatStencilInfo stencil; 5018ab5b326SKris Buschelman 5028ab5b326SKris Buschelman PetscFunctionBegin; 50327b31e29SJed Brown PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 50428be2f97SBarry Smith PetscValidHeaderSpecific(*C, MAT_CLASSID, 2); 5053ba16761SJacob Faibussowitsch if (A == *C) PetscFunctionReturn(PETSC_SUCCESS); 50628be2f97SBarry Smith PetscCheckSameComm(A, 1, *C, 2); 507aed4548fSBarry 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); 5086d7c1e57SBarry Smith 50928be2f97SBarry Smith /* swap C and A */ 51027b31e29SJed Brown refct = ((PetscObject)A)->refct; 511fefd9316SJose E. Roman state = ((PetscObject)A)->state; 51281fa06acSBarry Smith stencil = A->stencil; 5139566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(&buffer, A, sizeof(struct _p_Mat))); 5149566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(A, *C, sizeof(struct _p_Mat))); 5159566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(*C, &buffer, sizeof(struct _p_Mat))); 51627b31e29SJed Brown ((PetscObject)A)->refct = refct; 517fefd9316SJose E. Roman ((PetscObject)A)->state = state + 1; 51881fa06acSBarry Smith A->stencil = stencil; 51926fbe8dcSKarl Rupp 520c32d4117SBarry Smith ((PetscObject)*C)->refct = 1; 5219566063dSJacob Faibussowitsch PetscCall(MatShellSetOperation(*C, MATOP_DESTROY, (void (*)(void))NULL)); 5229566063dSJacob Faibussowitsch PetscCall(MatDestroy(C)); 5233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5248ab5b326SKris Buschelman } 525e7e92044SBarry Smith 526e7e92044SBarry Smith /*@ 527b470e4b4SRichard Tran Mills MatBindToCPU - marks a matrix to temporarily stay on the CPU and perform computations on the CPU 528e7e92044SBarry Smith 5292ef1f0ffSBarry Smith Logically Collective 5302216c58aSStefano Zampini 531e7e92044SBarry Smith Input Parameters: 532e7e92044SBarry Smith + A - the matrix 53311a5261eSBarry Smith - flg - bind to the CPU if value of `PETSC_TRUE` 534e7e92044SBarry Smith 53590ea27d8SSatish Balay Level: intermediate 5362216c58aSStefano Zampini 5371cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatBoundToCPU()` 538e7e92044SBarry Smith @*/ 539d71ae5a4SJacob Faibussowitsch PetscErrorCode MatBindToCPU(Mat A, PetscBool flg) 540d71ae5a4SJacob Faibussowitsch { 5417d871021SStefano Zampini PetscFunctionBegin; 5422ffa8ee7SStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 5432ffa8ee7SStefano Zampini PetscValidLogicalCollectiveBool(A, flg, 2); 5442216c58aSStefano Zampini #if defined(PETSC_HAVE_DEVICE) 5453ba16761SJacob Faibussowitsch if (A->boundtocpu == flg) PetscFunctionReturn(PETSC_SUCCESS); 546b470e4b4SRichard Tran Mills A->boundtocpu = flg; 547dbbe0bcdSBarry Smith PetscTryTypeMethod(A, bindtocpu, flg); 5482216c58aSStefano Zampini #endif 5493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5502216c58aSStefano Zampini } 5512216c58aSStefano Zampini 5522216c58aSStefano Zampini /*@ 5532216c58aSStefano Zampini MatBoundToCPU - query if a matrix is bound to the CPU 5542216c58aSStefano Zampini 5552216c58aSStefano Zampini Input Parameter: 5562216c58aSStefano Zampini . A - the matrix 5572216c58aSStefano Zampini 5582216c58aSStefano Zampini Output Parameter: 5592216c58aSStefano Zampini . flg - the logical flag 5602216c58aSStefano Zampini 5612216c58aSStefano Zampini Level: intermediate 5622216c58aSStefano Zampini 5631cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatBindToCPU()` 5642216c58aSStefano Zampini @*/ 565d71ae5a4SJacob Faibussowitsch PetscErrorCode MatBoundToCPU(Mat A, PetscBool *flg) 566d71ae5a4SJacob Faibussowitsch { 5672ffa8ee7SStefano Zampini PetscFunctionBegin; 5682ffa8ee7SStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 5694f572ea9SToby Isaac PetscAssertPointer(flg, 2); 5702216c58aSStefano Zampini #if defined(PETSC_HAVE_DEVICE) 5712216c58aSStefano Zampini *flg = A->boundtocpu; 5722216c58aSStefano Zampini #else 5732216c58aSStefano Zampini *flg = PETSC_TRUE; 5747d871021SStefano Zampini #endif 5753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 576e7e92044SBarry Smith } 5777e8381f9SStefano Zampini 578d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetValuesCOO_Basic(Mat A, const PetscScalar coo_v[], InsertMode imode) 579d71ae5a4SJacob Faibussowitsch { 5807e8381f9SStefano Zampini IS is_coo_i, is_coo_j; 5817e8381f9SStefano Zampini const PetscInt *coo_i, *coo_j; 5827e8381f9SStefano Zampini PetscInt n, n_i, n_j; 5837e8381f9SStefano Zampini PetscScalar zero = 0.; 5847e8381f9SStefano Zampini 5857e8381f9SStefano Zampini PetscFunctionBegin; 5869566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)A, "__PETSc_coo_i", (PetscObject *)&is_coo_i)); 5879566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)A, "__PETSc_coo_j", (PetscObject *)&is_coo_j)); 58828b400f6SJacob Faibussowitsch PetscCheck(is_coo_i, PetscObjectComm((PetscObject)A), PETSC_ERR_COR, "Missing coo_i IS"); 58928b400f6SJacob Faibussowitsch PetscCheck(is_coo_j, PetscObjectComm((PetscObject)A), PETSC_ERR_COR, "Missing coo_j IS"); 5909566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(is_coo_i, &n_i)); 5919566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(is_coo_j, &n_j)); 59208401ef6SPierre Jolivet PetscCheck(n_i == n_j, PETSC_COMM_SELF, PETSC_ERR_COR, "Wrong local size %" PetscInt_FMT " != %" PetscInt_FMT, n_i, n_j); 5939566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is_coo_i, &coo_i)); 5949566063dSJacob Faibussowitsch PetscCall(ISGetIndices(is_coo_j, &coo_j)); 59548a46eb9SPierre Jolivet if (imode != ADD_VALUES) PetscCall(MatZeroEntries(A)); 59648a46eb9SPierre 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)); 5979566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is_coo_i, &coo_i)); 5989566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(is_coo_j, &coo_j)); 5993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6007e8381f9SStefano Zampini } 6017e8381f9SStefano Zampini 6028063e3c8SPierre Jolivet PetscErrorCode MatSetPreallocationCOO_Basic(Mat A, PetscCount ncoo, PetscInt coo_i[], PetscInt coo_j[]) 603d71ae5a4SJacob Faibussowitsch { 6047e8381f9SStefano Zampini Mat preallocator; 6057e8381f9SStefano Zampini IS is_coo_i, is_coo_j; 6067e8381f9SStefano Zampini PetscScalar zero = 0.0; 6077e8381f9SStefano Zampini 6087e8381f9SStefano Zampini PetscFunctionBegin; 6099566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 6109566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 6119566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &preallocator)); 6129566063dSJacob Faibussowitsch PetscCall(MatSetType(preallocator, MATPREALLOCATOR)); 6139566063dSJacob Faibussowitsch PetscCall(MatSetSizes(preallocator, A->rmap->n, A->cmap->n, A->rmap->N, A->cmap->N)); 6149566063dSJacob Faibussowitsch PetscCall(MatSetLayouts(preallocator, A->rmap, A->cmap)); 6159566063dSJacob Faibussowitsch PetscCall(MatSetUp(preallocator)); 61648a46eb9SPierre Jolivet for (PetscCount n = 0; n < ncoo; n++) PetscCall(MatSetValue(preallocator, coo_i[n], coo_j[n], zero, INSERT_VALUES)); 6179566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(preallocator, MAT_FINAL_ASSEMBLY)); 6189566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(preallocator, MAT_FINAL_ASSEMBLY)); 6199566063dSJacob Faibussowitsch PetscCall(MatPreallocatorPreallocate(preallocator, PETSC_TRUE, A)); 6209566063dSJacob Faibussowitsch PetscCall(MatDestroy(&preallocator)); 6212c71b3e2SJacob 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); 6229566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, ncoo, coo_i, PETSC_COPY_VALUES, &is_coo_i)); 6239566063dSJacob Faibussowitsch PetscCall(ISCreateGeneral(PETSC_COMM_SELF, ncoo, coo_j, PETSC_COPY_VALUES, &is_coo_j)); 6249566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "__PETSc_coo_i", (PetscObject)is_coo_i)); 6259566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "__PETSc_coo_j", (PetscObject)is_coo_j)); 6269566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is_coo_i)); 6279566063dSJacob Faibussowitsch PetscCall(ISDestroy(&is_coo_j)); 6283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6297e8381f9SStefano Zampini } 6307e8381f9SStefano Zampini 63156856777SBarry Smith /*@C 632c3dd2894SJed Brown MatSetPreallocationCOO - set preallocation for matrices using a coordinate format of the entries with global indices 6337e8381f9SStefano Zampini 634c3339decSBarry Smith Collective 6357e8381f9SStefano Zampini 6364165533cSJose E. Roman Input Parameters: 6377e8381f9SStefano Zampini + A - matrix being preallocated 63842550becSJunchao Zhang . ncoo - number of entries 6397e8381f9SStefano Zampini . coo_i - row indices 6407e8381f9SStefano Zampini - coo_j - column indices 6417e8381f9SStefano Zampini 6427e8381f9SStefano Zampini Level: beginner 6437e8381f9SStefano Zampini 644394ed5ebSJunchao Zhang Notes: 6452ef1f0ffSBarry Smith The indices `coo_i` and `coo_j` may be modified within this function. The caller should not rely on them 646e8729f6fSJunchao Zhang having any specific value after this function returns. The arrays can be freed or reused immediately 647e8729f6fSJunchao Zhang after this function returns. 648e8729f6fSJunchao Zhang 64911a5261eSBarry Smith Entries can be repeated, see `MatSetValuesCOO()`. Entries with negative row or column indices are allowed 65011a5261eSBarry Smith but will be ignored. The corresponding entries in `MatSetValuesCOO()` will be ignored too. Remote entries 651d7547e51SJunchao Zhang are allowed and will be properly added or inserted to the matrix, unless the matrix option `MAT_IGNORE_OFF_PROC_ENTRIES` 65211a5261eSBarry 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. 6537e8381f9SStefano Zampini 654d7547e51SJunchao 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 655d7547e51SJunchao Zhang `MatCreateSeqAIJFromTriple()`. But that is not recommended for iterative applications. 656d7547e51SJunchao Zhang 6571cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatSetValuesCOO()`, `MatSeqAIJSetPreallocation()`, `MatMPIAIJSetPreallocation()`, `MatSeqBAIJSetPreallocation()`, 6582ef1f0ffSBarry Smith `MatMPIBAIJSetPreallocation()`, `MatSeqSBAIJSetPreallocation()`, `MatMPISBAIJSetPreallocation()`, `MatSetPreallocationCOOLocal()`, 6592ef1f0ffSBarry Smith `DMSetMatrixPreallocateSkip()`, `MatCreateSeqAIJFromTriple()` 6607e8381f9SStefano Zampini @*/ 661d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetPreallocationCOO(Mat A, PetscCount ncoo, PetscInt coo_i[], PetscInt coo_j[]) 662d71ae5a4SJacob Faibussowitsch { 6638063e3c8SPierre Jolivet PetscErrorCode (*f)(Mat, PetscCount, PetscInt[], PetscInt[]) = NULL; 6647e8381f9SStefano Zampini 6657e8381f9SStefano Zampini PetscFunctionBegin; 6667e8381f9SStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 6677e8381f9SStefano Zampini PetscValidType(A, 1); 6684f572ea9SToby Isaac if (ncoo) PetscAssertPointer(coo_i, 3); 6694f572ea9SToby Isaac if (ncoo) PetscAssertPointer(coo_j, 4); 6709566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 6719566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 6729566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatSetPreallocationCOO_C", &f)); 673cbc6b225SStefano Zampini 6749566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(MAT_PreallCOO, A, 0, 0, 0)); 6757e8381f9SStefano Zampini if (f) { 6769566063dSJacob Faibussowitsch PetscCall((*f)(A, ncoo, coo_i, coo_j)); 6777e8381f9SStefano Zampini } else { /* allow fallback, very slow */ 6789566063dSJacob Faibussowitsch PetscCall(MatSetPreallocationCOO_Basic(A, ncoo, coo_i, coo_j)); 6797e8381f9SStefano Zampini } 6809566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(MAT_PreallCOO, A, 0, 0, 0)); 6816834774dSStefano Zampini A->preallocated = PETSC_TRUE; 682cbc6b225SStefano Zampini A->nonzerostate++; 6833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6847e8381f9SStefano Zampini } 6857e8381f9SStefano Zampini 68656856777SBarry Smith /*@C 687c3dd2894SJed Brown MatSetPreallocationCOOLocal - set preallocation for matrices using a coordinate format of the entries with local indices 688c3dd2894SJed Brown 689c3339decSBarry Smith Collective 690c3dd2894SJed Brown 691c3dd2894SJed Brown Input Parameters: 692c3dd2894SJed Brown + A - matrix being preallocated 693c3dd2894SJed Brown . ncoo - number of entries 694c3dd2894SJed Brown . coo_i - row indices (local numbering; may be modified) 695c3dd2894SJed Brown - coo_j - column indices (local numbering; may be modified) 696c3dd2894SJed Brown 697c3dd2894SJed Brown Level: beginner 698c3dd2894SJed Brown 699c3dd2894SJed Brown Notes: 70011a5261eSBarry Smith The local indices are translated using the local to global mapping, thus `MatSetLocalToGlobalMapping()` must have been 70111a5261eSBarry Smith called prior to this function. For matrices created with `DMCreateMatrix()` the local to global mapping is often already provided. 702c3dd2894SJed Brown 7032ef1f0ffSBarry Smith The indices `coo_i` and `coo_j` may be modified within this function. They might be translated to corresponding global 704735d7f90SBarry Smith indices, but the caller should not rely on them having any specific value after this function returns. The arrays 705735d7f90SBarry Smith can be freed or reused immediately after this function returns. 706c3dd2894SJed Brown 70711a5261eSBarry Smith Entries can be repeated, see `MatSetValuesCOO()`. Entries with negative row or column indices are allowed 70811a5261eSBarry Smith but will be ignored. The corresponding entries in `MatSetValuesCOO()` will be ignored too. Remote entries 709394ed5ebSJunchao Zhang are allowed and will be properly added or inserted to the matrix. 710c3dd2894SJed Brown 7111cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatSetValuesCOO()`, `MatSeqAIJSetPreallocation()`, `MatMPIAIJSetPreallocation()`, `MatSeqBAIJSetPreallocation()`, 7122ef1f0ffSBarry Smith `MatMPIBAIJSetPreallocation()`, `MatSeqSBAIJSetPreallocation()`, `MatMPISBAIJSetPreallocation()`, `MatSetPreallocationCOO()`, 7132ef1f0ffSBarry Smith `DMSetMatrixPreallocateSkip()` 714c3dd2894SJed Brown @*/ 715d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetPreallocationCOOLocal(Mat A, PetscCount ncoo, PetscInt coo_i[], PetscInt coo_j[]) 716d71ae5a4SJacob Faibussowitsch { 7176834774dSStefano Zampini PetscErrorCode (*f)(Mat, PetscCount, PetscInt[], PetscInt[]) = NULL; 718c3dd2894SJed Brown 719c3dd2894SJed Brown PetscFunctionBegin; 720c3dd2894SJed Brown PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 721c3dd2894SJed Brown PetscValidType(A, 1); 7224f572ea9SToby Isaac if (ncoo) PetscAssertPointer(coo_i, 3); 7234f572ea9SToby Isaac if (ncoo) PetscAssertPointer(coo_j, 4); 7246834774dSStefano 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); 7259566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 7269566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 727cbc6b225SStefano Zampini 7289566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatSetPreallocationCOOLocal_C", &f)); 7296834774dSStefano Zampini if (f) { 7309566063dSJacob Faibussowitsch PetscCall((*f)(A, ncoo, coo_i, coo_j)); 731cbc6b225SStefano Zampini A->nonzerostate++; 7326834774dSStefano Zampini } else { 733cbc6b225SStefano Zampini ISLocalToGlobalMapping ltog_row, ltog_col; 7349566063dSJacob Faibussowitsch PetscCall(MatGetLocalToGlobalMapping(A, <og_row, <og_col)); 7359566063dSJacob Faibussowitsch if (ltog_row) PetscCall(ISLocalToGlobalMappingApply(ltog_row, ncoo, coo_i, coo_i)); 7369566063dSJacob Faibussowitsch if (ltog_col) PetscCall(ISLocalToGlobalMappingApply(ltog_col, ncoo, coo_j, coo_j)); 7379566063dSJacob Faibussowitsch PetscCall(MatSetPreallocationCOO(A, ncoo, coo_i, coo_j)); 7386834774dSStefano Zampini } 7396834774dSStefano Zampini A->preallocated = PETSC_TRUE; 7403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 741c3dd2894SJed Brown } 742c3dd2894SJed Brown 743c3dd2894SJed Brown /*@ 74411a5261eSBarry Smith MatSetValuesCOO - set values at once in a matrix preallocated using `MatSetPreallocationCOO()` 7457e8381f9SStefano Zampini 746c3339decSBarry Smith Collective 7477e8381f9SStefano Zampini 7484165533cSJose E. Roman Input Parameters: 7497e8381f9SStefano Zampini + A - matrix being preallocated 7502ef1f0ffSBarry Smith . coo_v - the matrix values (can be `NULL`) 7517e8381f9SStefano Zampini - imode - the insert mode 7527e8381f9SStefano Zampini 7537e8381f9SStefano Zampini Level: beginner 7547e8381f9SStefano Zampini 75511a5261eSBarry Smith Notes: 75611a5261eSBarry Smith The values must follow the order of the indices prescribed with `MatSetPreallocationCOO()` or `MatSetPreallocationCOOLocal()`. 75711a5261eSBarry Smith 7582ef1f0ffSBarry Smith When repeated entries are specified in the COO indices the `coo_v` values are first properly summed, regardless of the value of imode. 75911a5261eSBarry Smith The imode flag indicates if coo_v must be added to the current values of the matrix (`ADD_VALUES`) or overwritten (`INSERT_VALUES`). 76011a5261eSBarry Smith 76111a5261eSBarry Smith `MatAssemblyBegin()` and `MatAssemblyEnd()` do not need to be called after this routine. It automatically handles the assembly process. 7627e8381f9SStefano Zampini 7631cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatSetPreallocationCOO()`, `MatSetPreallocationCOOLocal()`, `InsertMode`, `INSERT_VALUES`, `ADD_VALUES` 7647e8381f9SStefano Zampini @*/ 765d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetValuesCOO(Mat A, const PetscScalar coo_v[], InsertMode imode) 766d71ae5a4SJacob Faibussowitsch { 7677e8381f9SStefano Zampini PetscErrorCode (*f)(Mat, const PetscScalar[], InsertMode) = NULL; 76835cef55dSJunchao Zhang PetscBool oldFlg; 7697e8381f9SStefano Zampini 7707e8381f9SStefano Zampini PetscFunctionBegin; 7717e8381f9SStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 7727e8381f9SStefano Zampini PetscValidType(A, 1); 7737e8381f9SStefano Zampini MatCheckPreallocated(A, 1); 774bfcc3627SStefano Zampini PetscValidLogicalCollectiveEnum(A, imode, 3); 7759566063dSJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatSetValuesCOO_C", &f)); 7769566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(MAT_SetVCOO, A, 0, 0, 0)); 7777e8381f9SStefano Zampini if (f) { 77835cef55dSJunchao Zhang PetscCall((*f)(A, coo_v, imode)); // all known COO implementations do not use MatStash. They do their own off-proc communication 77935cef55dSJunchao Zhang PetscCall(MatGetOption(A, MAT_NO_OFF_PROC_ENTRIES, &oldFlg)); 78035cef55dSJunchao Zhang PetscCall(MatSetOption(A, MAT_NO_OFF_PROC_ENTRIES, PETSC_TRUE)); // set A->nooffprocentries to avoid costly MatStash scatter in MatAssembly 78135cef55dSJunchao Zhang } else { 78235cef55dSJunchao Zhang PetscCall(MatSetValuesCOO_Basic(A, coo_v, imode)); // fall back to MatSetValues, which might use MatStash 7837e8381f9SStefano Zampini } 7849566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 7859566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 78635cef55dSJunchao Zhang if (f) PetscCall(MatSetOption(A, MAT_NO_OFF_PROC_ENTRIES, oldFlg)); 78735cef55dSJunchao Zhang PetscCall(PetscLogEventEnd(MAT_SetVCOO, A, 0, 0, 0)); 7883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7897e8381f9SStefano Zampini } 79065a9ecf2SRichard Tran Mills 79165a9ecf2SRichard Tran Mills /*@ 79265a9ecf2SRichard 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 79365a9ecf2SRichard Tran Mills 79465a9ecf2SRichard Tran Mills Input Parameters: 79565a9ecf2SRichard Tran Mills + A - the matrix 79665a9ecf2SRichard Tran Mills - flg - flag indicating whether the boundtocpu flag should be propagated 79765a9ecf2SRichard Tran Mills 79865a9ecf2SRichard Tran Mills Level: developer 79965a9ecf2SRichard Tran Mills 80065a9ecf2SRichard Tran Mills Notes: 8012fe279fdSBarry Smith If the value of flg is set to true, the following will occur 8022fe279fdSBarry Smith + `MatCreateSubMatrices()` and `MatCreateRedundantMatrix()` - bind created matrices to CPU if the input matrix is bound to the CPU. 8032fe279fdSBarry Smith - `MatCreateVecs()` - bind created vectors to CPU if the input matrix is bound to the CPU. 80465a9ecf2SRichard Tran Mills 80565a9ecf2SRichard Tran Mills The bindingpropagates flag itself is also propagated by the above routines. 80665a9ecf2SRichard Tran Mills 807fe59aa6dSJacob Faibussowitsch Developer Notes: 808aa624791SPierre Jolivet If the fine-scale `DMDA` has the `-dm_bind_below` option set to true, then `DMCreateInterpolationScale()` calls `MatSetBindingPropagates()` 80965a9ecf2SRichard Tran Mills on the restriction/interpolation operator to set the bindingpropagates flag to true. 81065a9ecf2SRichard Tran Mills 8111cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `VecSetBindingPropagates()`, `MatGetBindingPropagates()` 81265a9ecf2SRichard Tran Mills @*/ 813d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetBindingPropagates(Mat A, PetscBool flg) 814d71ae5a4SJacob Faibussowitsch { 81565a9ecf2SRichard Tran Mills PetscFunctionBegin; 81665a9ecf2SRichard Tran Mills PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 817d5e393b6SSuyash Tandon #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 81865a9ecf2SRichard Tran Mills A->bindingpropagates = flg; 81965a9ecf2SRichard Tran Mills #endif 8203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 82165a9ecf2SRichard Tran Mills } 822e9c74fd6SRichard Tran Mills 823e9c74fd6SRichard Tran Mills /*@ 824e9c74fd6SRichard 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 825e9c74fd6SRichard Tran Mills 826e9c74fd6SRichard Tran Mills Input Parameter: 827e9c74fd6SRichard Tran Mills . A - the matrix 828e9c74fd6SRichard Tran Mills 829e9c74fd6SRichard Tran Mills Output Parameter: 830e9c74fd6SRichard Tran Mills . flg - flag indicating whether the boundtocpu flag will be propagated 831e9c74fd6SRichard Tran Mills 832e9c74fd6SRichard Tran Mills Level: developer 833e9c74fd6SRichard Tran Mills 8341cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MatSetBindingPropagates()` 835e9c74fd6SRichard Tran Mills @*/ 836d71ae5a4SJacob Faibussowitsch PetscErrorCode MatGetBindingPropagates(Mat A, PetscBool *flg) 837d71ae5a4SJacob Faibussowitsch { 838e9c74fd6SRichard Tran Mills PetscFunctionBegin; 839e9c74fd6SRichard Tran Mills PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 8404f572ea9SToby Isaac PetscAssertPointer(flg, 2); 841d5e393b6SSuyash Tandon #if defined(PETSC_HAVE_VIENNACL) || defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 842e9c74fd6SRichard Tran Mills *flg = A->bindingpropagates; 843e9c74fd6SRichard Tran Mills #else 844e9c74fd6SRichard Tran Mills *flg = PETSC_FALSE; 845e9c74fd6SRichard Tran Mills #endif 8463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 847e9c74fd6SRichard Tran Mills } 848