xref: /petsc/src/binding/petsc4py/src/petsc4py/PETSc/petscmat.pxi (revision e8c0849ab8fe171bed529bea27238c9b402db591)
1cdef extern from * nogil:
2
3    ctypedef const char* PetscMatType "MatType"
4    PetscMatType MATSAME
5    PetscMatType MATMAIJ
6    PetscMatType   MATSEQMAIJ
7    PetscMatType   MATMPIMAIJ
8    PetscMatType MATKAIJ
9    PetscMatType   MATSEQKAIJ
10    PetscMatType   MATMPIKAIJ
11    PetscMatType MATIS
12    PetscMatType MATAIJ
13    PetscMatType   MATSEQAIJ
14    PetscMatType   MATMPIAIJ
15    PetscMatType     MATAIJCRL
16    PetscMatType       MATSEQAIJCRL
17    PetscMatType       MATMPIAIJCRL
18    PetscMatType     MATAIJCUSPARSE
19    PetscMatType       MATSEQAIJCUSPARSE
20    PetscMatType       MATMPIAIJCUSPARSE
21    PetscMatType     MATAIJVIENNACL
22    PetscMatType       MATSEQAIJVIENNACL
23    PetscMatType       MATMPIAIJVIENNACL
24    PetscMatType     MATAIJPERM
25    PetscMatType       MATSEQAIJPERM
26    PetscMatType       MATMPIAIJPERM
27    PetscMatType MATAIJSELL
28    PetscMatType   MATSEQAIJSELL
29    PetscMatType   MATMPIAIJSELL
30    PetscMatType MATAIJMKL
31    PetscMatType    MATSEQAIJMKL
32    PetscMatType    MATMPIAIJMKL
33    PetscMatType MATBAIJMKL
34    PetscMatType    MATSEQBAIJMKL
35    PetscMatType    MATMPIBAIJMKL
36    PetscMatType MATSHELL
37    PetscMatType MATDENSE
38    PetscMatType   MATSEQDENSE
39    PetscMatType   MATMPIDENSE
40    PetscMatType MATDENSECUDA
41    PetscMatType   MATSEQDENSECUDA
42    PetscMatType   MATMPIDENSECUDA
43    PetscMatType MATDENSEHIP
44    PetscMatType   MATSEQDENSEHIP
45    PetscMatType   MATMPIDENSEHIP
46    PetscMatType MATELEMENTAL
47    PetscMatType MATBAIJ
48    PetscMatType   MATSEQBAIJ
49    PetscMatType   MATMPIBAIJ
50    PetscMatType MATMPIADJ
51    PetscMatType MATSBAIJ
52    PetscMatType   MATSEQSBAIJ
53    PetscMatType   MATMPISBAIJ
54    PetscMatType MATMFFD
55    PetscMatType MATNORMAL
56    PetscMatType MATNORMALHERMITIAN
57    PetscMatType MATLRC
58    PetscMatType MATSCATTER
59    PetscMatType MATBLOCKMAT
60    PetscMatType MATCOMPOSITE
61    PetscMatType MATFFT
62    PetscMatType   MATFFTW
63    PetscMatType   MATSEQCUFFT
64    PetscMatType MATTRANSPOSEVIRTUAL
65    PetscMatType MATHERMITIANTRANSPOSEVIRTUAL
66    PetscMatType MATSCHURCOMPLEMENT
67    PetscMatType MATPYTHON
68    PetscMatType MATHYPRE
69    PetscMatType MATHYPRESTRUCT
70    PetscMatType MATHYPRESSTRUCT
71    PetscMatType MATSUBMATRIX
72    PetscMatType MATLOCALREF
73    PetscMatType MATNEST
74    PetscMatType MATPREALLOCATOR
75    PetscMatType MATSELL
76    PetscMatType MATSEQSELL
77    PetscMatType MATMPISELL
78    PetscMatType MATDUMMY
79    PetscMatType MATLMVM
80    PetscMatType MATLMVMDFP
81    PetscMatType MATLMVMDDFP
82    PetscMatType MATLMVMBFGS
83    PetscMatType MATLMVMDBFGS
84    PetscMatType MATLMVMDQN
85    PetscMatType MATLMVMSR1
86    PetscMatType MATLMVMBROYDEN
87    PetscMatType MATLMVMBADBROYDEN
88    PetscMatType MATLMVMSYMBROYDEN
89    PetscMatType MATLMVMSYMBADBROYDEN
90    PetscMatType MATLMVMDIAGBROYDEN
91    PetscMatType MATCONSTANTDIAGONAL
92    PetscMatType MATDIAGONAL
93    PetscMatType MATH2OPUS
94
95    ctypedef const char* PetscMatOrderingType "MatOrderingType"
96    PetscMatOrderingType MATORDERINGNATURAL
97    PetscMatOrderingType MATORDERINGND
98    PetscMatOrderingType MATORDERING1WD
99    PetscMatOrderingType MATORDERINGRCM
100    PetscMatOrderingType MATORDERINGQMD
101    PetscMatOrderingType MATORDERINGROWLENGTH
102    PetscMatOrderingType MATORDERINGWBM
103    PetscMatOrderingType MATORDERINGSPECTRAL
104    PetscMatOrderingType MATORDERINGAMD
105    PetscMatOrderingType MATORDERINGMETISND
106
107    ctypedef const char* PetscMatSolverType "MatSolverType"
108    PetscMatSolverType MATSOLVERSUPERLU
109    PetscMatSolverType MATSOLVERSUPERLU_DIST
110    PetscMatSolverType MATSOLVERSTRUMPACK
111    PetscMatSolverType MATSOLVERUMFPACK
112    PetscMatSolverType MATSOLVERCHOLMOD
113    PetscMatSolverType MATSOLVERKLU
114    PetscMatSolverType MATSOLVERELEMENTAL
115    PetscMatSolverType MATSOLVERSCALAPACK
116    PetscMatSolverType MATSOLVERESSL
117    PetscMatSolverType MATSOLVERLUSOL
118    PetscMatSolverType MATSOLVERMUMPS
119    PetscMatSolverType MATSOLVERMKL_PARDISO
120    PetscMatSolverType MATSOLVERMKL_CPARDISO
121    PetscMatSolverType MATSOLVERPASTIX
122    PetscMatSolverType MATSOLVERMATLAB
123    PetscMatSolverType MATSOLVERPETSC
124    PetscMatSolverType MATSOLVERBAS
125    PetscMatSolverType MATSOLVERCUSPARSE
126    PetscMatSolverType MATSOLVERCUDA
127    PetscMatSolverType MATSOLVERSPQR
128
129    ctypedef enum PetscMatReuse "MatReuse":
130        MAT_INITIAL_MATRIX
131        MAT_REUSE_MATRIX
132        MAT_IGNORE_MATRIX
133        MAT_INPLACE_MATRIX
134
135    ctypedef enum PetscMatDuplicateOption "MatDuplicateOption":
136        MAT_DO_NOT_COPY_VALUES
137        MAT_COPY_VALUES
138        MAT_SHARE_NONZERO_PATTERN
139
140    ctypedef enum PetscMatSORType "MatSORType":
141        SOR_FORWARD_SWEEP
142        SOR_BACKWARD_SWEEP
143        SOR_SYMMETRIC_SWEEP
144        SOR_LOCAL_FORWARD_SWEEP
145        SOR_LOCAL_BACKWARD_SWEEP
146        SOR_LOCAL_SYMMETRIC_SWEEP
147        SOR_ZERO_INITIAL_GUESS
148        SOR_EISENSTAT
149        SOR_APPLY_UPPER
150        SOR_APPLY_LOWER
151
152    ctypedef enum PetscMatProductType "MatProductType":
153        MATPRODUCT_UNSPECIFIED
154        MATPRODUCT_AB
155        MATPRODUCT_AtB
156        MATPRODUCT_ABt
157        MATPRODUCT_PtAP
158        MATPRODUCT_RARt
159        MATPRODUCT_ABC
160
161    ctypedef enum PetscMatAssemblyType "MatAssemblyType":
162        MAT_FLUSH_ASSEMBLY
163        MAT_FINAL_ASSEMBLY
164
165    ctypedef enum PetscMatInfoType "MatInfoType":
166        MAT_LOCAL
167        MAT_GLOBAL_MAX
168        MAT_GLOBAL_SUM
169
170    ctypedef enum  PetscMatStructure "MatStructure":
171        MAT_SAME_NONZERO_PATTERN      "SAME_NONZERO_PATTERN"
172        MAT_DIFFERENT_NONZERO_PATTERN "DIFFERENT_NONZERO_PATTERN"
173        MAT_SUBSET_NONZERO_PATTERN    "SUBSET_NONZERO_PATTERN"
174        MAT_UNKNOWN_NONZERO_PATTERN   "UNKNOWN_NONZERO_PATTERN"
175
176    ctypedef enum PetscMatOption "MatOption":
177        MAT_OPTION_MIN
178        MAT_UNUSED_NONZERO_LOCATION_ERR
179        MAT_ROW_ORIENTED
180        MAT_SYMMETRIC
181        MAT_STRUCTURALLY_SYMMETRIC
182        MAT_FORCE_DIAGONAL_ENTRIES
183        MAT_IGNORE_OFF_PROC_ENTRIES
184        MAT_USE_HASH_TABLE
185        MAT_KEEP_NONZERO_PATTERN
186        MAT_IGNORE_ZERO_ENTRIES
187        MAT_USE_INODES
188        MAT_HERMITIAN
189        MAT_SYMMETRY_ETERNAL
190        MAT_NEW_NONZERO_LOCATION_ERR
191        MAT_IGNORE_LOWER_TRIANGULAR
192        MAT_ERROR_LOWER_TRIANGULAR
193        MAT_GETROW_UPPERTRIANGULAR
194        MAT_SPD
195        MAT_NO_OFF_PROC_ZERO_ROWS
196        MAT_NO_OFF_PROC_ENTRIES
197        MAT_NEW_NONZERO_LOCATIONS
198        MAT_NEW_NONZERO_ALLOCATION_ERR
199        MAT_SUBSET_OFF_PROC_ENTRIES
200        MAT_SUBMAT_SINGLEIS
201        MAT_STRUCTURE_ONLY
202        MAT_SORTED_FULL
203        MAT_OPTION_MAX
204
205    ctypedef enum PetscMatOperation "MatOperation":
206        pass
207
208    PetscErrorCode MatView(PetscMat, PetscViewer)
209    PetscErrorCode MatDestroy(PetscMat*)
210    PetscErrorCode MatCreate(MPI_Comm, PetscMat*)
211    PetscErrorCode MatCreateDenseCUDA(MPI_Comm, PetscInt, PetscInt, PetscInt, PetscInt, PetscScalar[], PetscMat*)
212
213    PetscErrorCode MatCreateIS(MPI_Comm, PetscInt, PetscInt, PetscInt, PetscInt, PetscInt, PetscLGMap, PetscLGMap, PetscMat*)
214    PetscErrorCode MatISGetLocalMat(PetscMat, PetscMat*)
215
216    PetscErrorCode MatCreateScatter(MPI_Comm, PetscScatter, PetscMat*)
217    PetscErrorCode MatScatterSetVecScatter(PetscMat, PetscScatter)
218    PetscErrorCode MatScatterGetVecScatter(PetscMat, PetscScatter*)
219
220    PetscErrorCode MatCreateNormal(PetscMat, PetscMat*)
221    PetscErrorCode MatCreateTranspose(PetscMat, PetscMat*)
222    PetscErrorCode MatTransposeGetMat(PetscMat, PetscMat*)
223    PetscErrorCode MatCreateNormalHermitian(PetscMat, PetscMat*)
224    PetscErrorCode MatCreateHermitianTranspose(PetscMat, PetscMat*)
225    PetscErrorCode MatCreateLRC(PetscMat, PetscMat, PetscVec, PetscMat, PetscMat*)
226    PetscErrorCode MatCreateSubMatrixVirtual(PetscMat, PetscIS, PetscIS, PetscMat*)
227    PetscErrorCode MatCreateRedundantMatrix(PetscMat, PetscInt, MPI_Comm, PetscMatReuse, PetscMat*)
228    PetscErrorCode MatCreateNest(MPI_Comm, PetscInt, PetscIS[], PetscInt, PetscIS[], PetscMat[], PetscMat*)
229    PetscErrorCode MatCreateShell(MPI_Comm, PetscInt, PetscInt, PetscInt, PetscInt, void*, PetscMat*)
230    PetscErrorCode MatCreateH2OpusFromMat(PetscMat, PetscInt, const PetscReal[], PetscBool, PetscReal, PetscInt, PetscInt, PetscInt, PetscReal, PetscMat*)
231    PetscErrorCode MatCreateSeqAIJWithArrays(MPI_Comm, PetscInt, PetscInt, PetscInt[], PetscInt[], PetscScalar[], PetscMat*)
232    PetscErrorCode MatCreateMPIAIJWithArrays(MPI_Comm, PetscInt, PetscInt, PetscInt, PetscInt, PetscInt[], PetscInt[], PetscScalar[], PetscMat*)
233    PetscErrorCode MatCreateMPIAIJWithSplitArrays(MPI_Comm, PetscInt, PetscInt, PetscInt, PetscInt, PetscInt[], PetscInt[], PetscScalar[], PetscInt[], PetscInt[], PetscScalar[], PetscMat*)
234    PetscErrorCode MatCreateDiagonal(PetscVec, PetscMat*)
235    PetscErrorCode MatCreateConstantDiagonal(MPI_Comm, PetscInt, PetscInt, PetscInt, PetscInt, PetscScalar, PetscMat*)
236
237    PetscErrorCode MatSetSizes(PetscMat, PetscInt, PetscInt, PetscInt, PetscInt)
238    PetscErrorCode MatSetBlockSize(PetscMat, PetscInt)
239    PetscErrorCode MatSetBlockSizes(PetscMat, PetscInt, PetscInt)
240    PetscErrorCode MatSetVariableBlockSizes(PetscMat, PetscInt, PetscInt[])
241    PetscErrorCode MatSetType(PetscMat, PetscMatType)
242    PetscErrorCode MatSetVecType(PetscMat, PetscVecType)
243    PetscErrorCode MatGetVecType(PetscMat, PetscVecType*)
244    PetscErrorCode MatSetOption(PetscMat, PetscMatOption, PetscBool)
245    PetscErrorCode MatGetOption(PetscMat, PetscMatOption, PetscBool*)
246
247    enum: MAT_SKIP_ALLOCATION
248    PetscErrorCode MatSeqAIJSetPreallocation  (PetscMat, PetscInt, PetscInt[])
249    PetscErrorCode MatMPIAIJSetPreallocation  (PetscMat, PetscInt, PetscInt[], PetscInt, PetscInt[])
250    PetscErrorCode MatSeqBAIJSetPreallocation (PetscMat, PetscInt, PetscInt, PetscInt[])
251    PetscErrorCode MatMPIBAIJSetPreallocation (PetscMat, PetscInt, PetscInt, PetscInt[], PetscInt, PetscInt[])
252    PetscErrorCode MatSeqSBAIJSetPreallocation(PetscMat, PetscInt, PetscInt, PetscInt[])
253    PetscErrorCode MatMPISBAIJSetPreallocation(PetscMat, PetscInt, PetscInt, PetscInt[], PetscInt, PetscInt[])
254    PetscErrorCode MatSeqAIJSetPreallocationCSR  (PetscMat,         PetscInt[], PetscInt[], PetscScalar[])
255    PetscErrorCode MatMPIAIJSetPreallocationCSR  (PetscMat,         PetscInt[], PetscInt[], PetscScalar[])
256    PetscErrorCode MatSeqBAIJSetPreallocationCSR (PetscMat, PetscInt, PetscInt[], PetscInt[], PetscScalar[])
257    PetscErrorCode MatMPIBAIJSetPreallocationCSR (PetscMat, PetscInt, PetscInt[], PetscInt[], PetscScalar[])
258    PetscErrorCode MatSeqSBAIJSetPreallocationCSR(PetscMat, PetscInt, PetscInt[], PetscInt[], PetscScalar[])
259    PetscErrorCode MatMPISBAIJSetPreallocationCSR(PetscMat, PetscInt, PetscInt[], PetscInt[], PetscScalar[])
260    PetscErrorCode MatSeqDenseSetPreallocation(PetscMat, PetscScalar[])
261    PetscErrorCode MatMPIDenseSetPreallocation(PetscMat, PetscScalar[])
262    PetscErrorCode MatISSetPreallocation(PetscMat, PetscInt, PetscInt[], PetscInt, PetscInt[])
263    PetscErrorCode MatSetPreallocationCOO(PetscMat, PetscCount, PetscInt[], PetscInt[])
264    PetscErrorCode MatSetPreallocationCOOLocal(PetscMat, PetscCount, PetscInt[], PetscInt[])
265
266    PetscErrorCode MatSetOptionsPrefix(PetscMat, char[])
267    PetscErrorCode MatAppendOptionsPrefix(PetscMat, char[])
268    PetscErrorCode MatGetOptionsPrefix(PetscMat, char*[])
269    PetscErrorCode MatSetFromOptions(PetscMat)
270    PetscErrorCode MatSetUp(PetscMat)
271
272    PetscErrorCode MatGetType(PetscMat, PetscMatType*)
273    PetscErrorCode MatGetSize(PetscMat, PetscInt*, PetscInt*)
274    PetscErrorCode MatGetLocalSize(PetscMat, PetscInt*, PetscInt*)
275    PetscErrorCode MatGetBlockSize(PetscMat, PetscInt*)
276    PetscErrorCode MatGetBlockSizes(PetscMat, PetscInt*, PetscInt*)
277    PetscErrorCode MatGetOwnershipRange(PetscMat, PetscInt*, PetscInt*)
278    PetscErrorCode MatGetOwnershipRanges(PetscMat, const PetscInt*[])
279    PetscErrorCode MatGetOwnershipRangeColumn(PetscMat, PetscInt*, PetscInt*)
280    PetscErrorCode MatGetOwnershipRangesColumn(PetscMat, const PetscInt*[])
281    PetscErrorCode MatGetOwnershipIS(PetscMat, PetscIS*, PetscIS*)
282    PetscErrorCode MatNestGetISs(PetscMat, PetscIS*, PetscIS*)
283    PetscErrorCode MatNestGetLocalISs(PetscMat, PetscIS*, PetscIS*)
284    PetscErrorCode MatNestGetSize(PetscMat, PetscInt*, PetscInt*)
285    PetscErrorCode MatNestGetSubMat(PetscMat, PetscInt, PetscInt, PetscMat*)
286    PetscErrorCode MatNestSetVecType(PetscMat, PetscVecType)
287
288    PetscErrorCode MatEqual(PetscMat, PetscMat, PetscBool*)
289    PetscErrorCode MatLoad(PetscMat, PetscViewer)
290    PetscErrorCode MatDuplicate(PetscMat, PetscMatDuplicateOption, PetscMat*)
291    PetscErrorCode MatCopy(PetscMat, PetscMat, PetscMatStructure)
292    PetscErrorCode MatTranspose(PetscMat, PetscMatReuse, PetscMat*)
293    PetscErrorCode MatTransposeSetPrecursor(PetscMat, PetscMat)
294    PetscErrorCode MatHermitianTranspose(PetscMat, PetscMatReuse, PetscMat*)
295    PetscErrorCode MatConvert(PetscMat, PetscMatType, PetscMatReuse, PetscMat*)
296
297    PetscErrorCode MatIsSymmetric(PetscMat, PetscReal, PetscBool*)
298    PetscErrorCode MatIsStructurallySymmetric(PetscMat, PetscBool*)
299    PetscErrorCode MatIsHermitian(PetscMat, PetscReal, PetscBool*)
300    PetscErrorCode MatIsSymmetricKnown(PetscMat, PetscBool*, PetscBool*)
301    PetscErrorCode MatIsHermitianKnown(PetscMat, PetscBool*, PetscBool*)
302    PetscErrorCode MatIsTranspose(PetscMat, PetscMat, PetscReal, PetscBool*)
303    PetscErrorCode MatIsLinear(PetscMat, PetscInt, PetscBool*)
304
305    PetscErrorCode MatCreateVecs(PetscMat, PetscVec*, PetscVec*)
306
307    PetscErrorCode MatSetValue(PetscMat, PetscInt, PetscInt, PetscScalar, PetscInsertMode)
308    PetscErrorCode MatSetValues(PetscMat, PetscInt, const PetscInt[], PetscInt, const PetscInt[], const PetscScalar[], PetscInsertMode)
309    PetscErrorCode MatSetValuesBlocked(PetscMat, PetscInt, const PetscInt[], PetscInt, const PetscInt[], const PetscScalar[], PetscInsertMode)
310    PetscErrorCode MatSetValuesCOO(PetscMat, const PetscScalar[], PetscInsertMode)
311
312    PetscErrorCode MatSetLocalToGlobalMapping(PetscMat, PetscLGMap, PetscLGMap)
313    PetscErrorCode MatGetLocalToGlobalMapping(PetscMat, PetscLGMap*, PetscLGMap*)
314    PetscErrorCode MatSetValueLocal(PetscMat, PetscInt, PetscInt, PetscScalar, PetscInsertMode)
315    PetscErrorCode MatSetValuesLocal(PetscMat, PetscInt, const PetscInt[], PetscInt, const PetscInt[], const PetscScalar[], PetscInsertMode)
316    PetscErrorCode MatSetValuesBlockedLocal(PetscMat, PetscInt, const PetscInt[], PetscInt, const PetscInt[], const PetscScalar[], PetscInsertMode)
317
318    PetscErrorCode MatSetStencil(PetscMat, PetscInt, const PetscInt[], const PetscInt[], PetscInt)
319    ctypedef struct PetscMatStencil "MatStencil":
320        PetscInt k, j, i, c
321    PetscErrorCode MatSetValuesStencil(PetscMat, PetscInt, const PetscMatStencil[], PetscInt, const PetscMatStencil[], const PetscScalar[], PetscInsertMode)
322    PetscErrorCode MatSetValuesBlockedStencil(PetscMat, PetscInt, const PetscMatStencil[], PetscInt, const PetscMatStencil[], const PetscScalar[], PetscInsertMode)
323
324    PetscErrorCode MatGetValues(PetscMat, PetscInt, const PetscInt[], PetscInt, const PetscInt[], PetscScalar[])
325    PetscErrorCode MatGetRow(PetscMat, PetscInt, PetscInt*, const PetscInt*[], const PetscScalar*[])
326    PetscErrorCode MatRestoreRow(PetscMat, PetscInt, PetscInt*, const PetscInt*[], const PetscScalar*[])
327    PetscErrorCode MatGetRowIJ(PetscMat, PetscInt, PetscBool, PetscBool, PetscInt*, const PetscInt*[], const PetscInt*[], PetscBool*)
328    PetscErrorCode MatRestoreRowIJ(PetscMat, PetscInt, PetscBool, PetscBool, PetscInt*, const PetscInt*[], const PetscInt*[], PetscBool*)
329    PetscErrorCode MatGetColumnIJ(PetscMat, PetscInt, PetscBool, PetscBool, PetscInt*, const PetscInt*[], const PetscInt*[], PetscBool*)
330    PetscErrorCode MatRestoreColumnIJ(PetscMat, PetscInt, PetscBool, PetscBool, PetscInt*, const PetscInt*[], const PetscInt*[], PetscBool*)
331
332    PetscErrorCode MatZeroEntries(PetscMat)
333    PetscErrorCode MatStoreValues(PetscMat)
334    PetscErrorCode MatRetrieveValues(PetscMat)
335    PetscErrorCode MatAssemblyBegin(PetscMat, PetscMatAssemblyType)
336    PetscErrorCode MatAssemblyEnd(PetscMat, PetscMatAssemblyType)
337    PetscErrorCode MatAssembled(PetscMat, PetscBool*)
338
339    PetscErrorCode MatDiagonalSet(PetscMat, PetscVec, PetscInsertMode)
340    PetscErrorCode MatDiagonalScale(PetscMat, PetscVec, PetscVec)
341    PetscErrorCode MatScale(PetscMat, PetscScalar)
342    PetscErrorCode MatShift(PetscMat, PetscScalar)
343    PetscErrorCode MatFilter(PetscMat, PetscReal, PetscBool, PetscBool)
344    PetscErrorCode MatSetRandom(PetscMat, PetscRandom)
345    PetscErrorCode MatAXPY(PetscMat, PetscScalar, PetscMat, PetscMatStructure)
346    PetscErrorCode MatAYPX(PetscMat, PetscScalar, PetscMat, PetscMatStructure)
347    PetscErrorCode MatMatMult(PetscMat, PetscMat, PetscMatReuse, PetscReal, PetscMat*)
348    PetscErrorCode MatMatTransposeMult(PetscMat, PetscMat, PetscMatReuse, PetscReal, PetscMat*)
349    PetscErrorCode MatTransposeMatMult(PetscMat, PetscMat, PetscMatReuse, PetscReal, PetscMat*)
350
351    PetscErrorCode MatPtAP(PetscMat, PetscMat, PetscMatReuse, PetscReal, PetscMat*)
352    PetscErrorCode MatRARt(PetscMat, PetscMat, PetscMatReuse, PetscReal, PetscMat*)
353    PetscErrorCode MatMatMatMult(PetscMat, PetscMat, PetscMat, PetscMatReuse, PetscReal, PetscMat*)
354    PetscErrorCode MatSeqAIJKron(PetscMat, PetscMat, PetscMatReuse, PetscMat*)
355
356    PetscErrorCode MatInterpolate(PetscMat, PetscVec, PetscVec)
357    PetscErrorCode MatInterpolateAdd(PetscMat, PetscVec, PetscVec, PetscVec)
358    PetscErrorCode MatRestrict(PetscMat, PetscVec, PetscVec)
359
360    PetscErrorCode MatPermute(PetscMat, PetscIS, PetscIS, PetscMat*)
361    PetscErrorCode MatPermuteSparsify(PetscMat, PetscInt, PetscReal, PetscReal, PetscIS, PetscIS, PetscMat*)
362
363    PetscErrorCode MatMerge(MPI_Comm, PetscMat, PetscInt, PetscMatReuse, PetscMat*)
364    PetscErrorCode MatCreateSubMatrix(PetscMat, PetscIS, PetscIS, PetscMatReuse, PetscMat*)
365    PetscErrorCode MatCreateSubMatrices(PetscMat, PetscInt, PetscIS[], PetscIS[], PetscMatReuse, PetscMat*[])
366    PetscErrorCode MatIncreaseOverlap(PetscMat, PetscInt, PetscIS[], PetscInt)
367    PetscErrorCode MatGetDiagonalBlock(PetscMat, PetscMat*)
368    PetscErrorCode MatGetLocalSubMatrix(PetscMat, PetscIS, PetscIS, PetscMat*)
369    PetscErrorCode MatRestoreLocalSubMatrix(PetscMat, PetscIS, PetscIS, PetscMat*)
370    PetscErrorCode MatDestroyMatrices(PetscInt, PetscMat*[])
371    PetscErrorCode MatSchurComplementGetSubMatrices(PetscMat, PetscMat*, PetscMat*, PetscMat*, PetscMat*, PetscMat*)
372    PetscErrorCode MatCreateSchurComplement(PetscMat, PetscMat, PetscMat, PetscMat, PetscMat, PetscMat*)
373
374    PetscErrorCode MatConjugate(PetscMat)
375    PetscErrorCode MatRealPart(PetscMat)
376    PetscErrorCode MatImaginaryPart(PetscMat)
377
378    PetscErrorCode MatZeroRows(PetscMat, PetscInt, PetscInt[], PetscScalar, PetscVec, PetscVec)
379    PetscErrorCode MatZeroRowsLocal(PetscMat, PetscInt, PetscInt[], PetscScalar, PetscVec, PetscVec)
380    PetscErrorCode MatZeroRowsIS(PetscMat, PetscIS, PetscScalar, PetscVec, PetscVec)
381    PetscErrorCode MatZeroRowsLocalIS(PetscMat, PetscIS, PetscScalar, PetscVec, PetscVec)
382    PetscErrorCode MatFindZeroRows(PetscMat, PetscIS*)
383
384    PetscErrorCode MatZeroRowsColumns(PetscMat, PetscInt, PetscInt[], PetscScalar, PetscVec, PetscVec)
385    PetscErrorCode MatZeroRowsColumnsLocal(PetscMat, PetscInt, PetscInt[], PetscScalar, PetscVec, PetscVec)
386    PetscErrorCode MatZeroRowsColumnsIS(PetscMat, PetscIS, PetscScalar, PetscVec, PetscVec)
387    PetscErrorCode MatZeroRowsColumnsLocalIS(PetscMat, PetscIS, PetscScalar, PetscVec, PetscVec)
388    PetscErrorCode MatZeroRowsColumnsStencil(PetscMat, PetscInt, const PetscMatStencil[], PetscScalar, PetscVec, PetscVec)
389
390    PetscErrorCode MatGetDiagonal(PetscMat, PetscVec)
391    PetscErrorCode MatGetRowSum(PetscMat, PetscVec)
392    PetscErrorCode MatInvertBlockDiagonal(PetscMat, const PetscScalar**)
393    PetscErrorCode MatGetRowMax(PetscMat, PetscVec, PetscInt[])
394    PetscErrorCode MatGetRowMaxAbs(PetscMat, PetscVec, PetscInt[])
395    PetscErrorCode MatGetColumnVector(PetscMat, PetscVec, PetscInt)
396
397    PetscErrorCode MatNorm(PetscMat, PetscNormType, PetscReal*)
398
399    PetscErrorCode MatMult(PetscMat, PetscVec, PetscVec)
400    PetscErrorCode MatMultAdd(PetscMat, PetscVec, PetscVec, PetscVec)
401    PetscErrorCode MatMultTranspose(PetscMat, PetscVec, PetscVec)
402    PetscErrorCode MatMultTransposeAdd(PetscMat, PetscVec, PetscVec, PetscVec)
403
404    # FIXME: Why?
405    PetscErrorCode MatMultHermitian"MatMultHermitianTranspose"(PetscMat, PetscVec, PetscVec)
406    PetscErrorCode MatMultHermitianAdd"MatMultHermitianTransposeAdd"(PetscMat, PetscVec, PetscVec, PetscVec)
407
408    PetscErrorCode MatBindToCPU(PetscMat, PetscBool)
409    PetscErrorCode MatBoundToCPU(PetscMat, PetscBool*)
410
411    PetscErrorCode MatSOR(PetscMat, PetscVec, PetscReal, PetscMatSORType, PetscReal, PetscInt, PetscInt, PetscVec)
412
413    PetscErrorCode MatGetOrdering(PetscMat, PetscMatOrderingType, PetscIS*, PetscIS*)
414    PetscErrorCode MatReorderForNonzeroDiagonal(PetscMat, PetscReal, PetscIS, PetscIS)
415
416    PetscErrorCode MatISSetAllowRepeated(PetscMat, PetscBool)
417    PetscErrorCode MatISGetAllowRepeated(PetscMat, PetscBool*)
418    PetscErrorCode MatISFixLocalEmpty(PetscMat, PetscBool)
419    PetscErrorCode MatISGetLocalMat(PetscMat, PetscMat*)
420    PetscErrorCode MatISRestoreLocalMat(PetscMat, PetscMat*)
421    PetscErrorCode MatISSetLocalMat(PetscMat, PetscMat)
422
423    PetscErrorCode MatH2OpusOrthogonalize(PetscMat)
424    PetscErrorCode MatH2OpusCompress(PetscMat, PetscReal)
425    PetscErrorCode MatH2OpusLowRankUpdate(PetscMat, PetscMat, PetscMat, PetscScalar)
426
427    PetscErrorCode MatLMVMGetJ0(PetscMat, PetscMat*)
428    PetscErrorCode MatLMVMSetJ0(PetscMat, PetscMat)
429    PetscErrorCode MatLMVMGetJ0KSP(PetscMat, PetscKSP*)
430    PetscErrorCode MatLMVMSetJ0KSP(PetscMat, PetscKSP)
431    PetscErrorCode MatLMVMAllocate(PetscMat, PetscVec, PetscVec)
432    PetscErrorCode MatLMVMUpdate(PetscMat, PetscVec, PetscVec)
433    PetscErrorCode MatLMVMReset(PetscMat, PetscBool)
434
435    ctypedef enum PetscMatFactorShiftType "MatFactorShiftType":
436        MAT_SHIFT_NONE
437        MAT_SHIFT_NONZERO
438        MAT_SHIFT_POSITIVE_DEFINITE
439        MAT_SHIFT_INBLOCKS
440
441    ctypedef struct PetscMatFactorInfo "MatFactorInfo":
442        PetscReal fill
443        PetscReal levels, diagonal_fill
444        PetscReal usedt, dt, dtcol, dtcount
445        PetscReal zeropivot, pivotinblocks
446        PetscReal shifttype, shiftamount
447
448    ctypedef struct PetscMatInfo "MatInfo":
449        PetscLogDouble block_size
450        PetscLogDouble nz_allocated, nz_used, nz_unneeded
451        PetscLogDouble memory
452        PetscLogDouble assemblies
453        PetscLogDouble mallocs
454        PetscLogDouble fill_ratio_given, fill_ratio_needed
455        PetscLogDouble factor_mallocs
456
457    PetscErrorCode MatGetInfo(PetscMat, PetscMatInfoType, PetscMatInfo*)
458
459    PetscErrorCode MatFactorInfoInitialize(PetscMatFactorInfo*)
460
461    PetscErrorCode MatCholeskyFactor(PetscMat, PetscIS, PetscMatFactorInfo*)
462    PetscErrorCode MatCholeskyFactorSymbolic(PetscMat, PetscIS, PetscMatFactorInfo*, PetscMat*)
463    PetscErrorCode MatCholeskyFactorNumeric(PetscMat, PetscMatFactorInfo*, PetscMat*)
464    PetscErrorCode MatLUFactor(PetscMat, PetscIS, PetscIS, PetscMatFactorInfo*)
465    PetscErrorCode MatILUFactor(PetscMat, PetscIS, PetscIS, PetscMatFactorInfo*)
466    PetscErrorCode MatICCFactor(PetscMat, PetscIS, PetscMatFactorInfo*)
467    PetscErrorCode MatLUFactorSymbolic(PetscMat, PetscIS, PetscIS, PetscMatFactorInfo*, PetscMat*)
468    PetscErrorCode MatILUFactorSymbolic(PetscMat, PetscIS, PetscIS, PetscMatFactorInfo*, PetscMat*)
469    PetscErrorCode MatICCFactorSymbolic(PetscMat, PetscIS, PetscMatFactorInfo*, PetscMat*)
470    PetscErrorCode MatLUFactorNumeric(PetscMat, PetscMatFactorInfo*, PetscMat*)
471    PetscErrorCode MatILUDTFactor(PetscMat, PetscIS, PetscIS, PetscMatFactorInfo*, PetscMat*)
472    PetscErrorCode MatGetInertia(PetscMat, PetscInt*, PetscInt*, PetscInt*)
473    PetscErrorCode MatSetUnfactored(PetscMat)
474
475    PetscErrorCode MatLRCGetMats(PetscMat, PetscMat*, PetscMat*, PetscVec*, PetscMat*)
476    PetscErrorCode MatLRCSetMats(PetscMat, PetscMat, PetscMat, PetscVec, PetscMat)
477
478    PetscErrorCode MatMumpsSetIcntl(PetscMat, PetscInt, PetscInt)
479    PetscErrorCode MatMumpsGetIcntl(PetscMat, PetscInt, PetscInt*)
480    PetscErrorCode MatMumpsSetCntl(PetscMat, PetscInt, PetscReal)
481    PetscErrorCode MatMumpsGetCntl(PetscMat, PetscInt, PetscReal*)
482    PetscErrorCode MatMumpsGetInfo(PetscMat, PetscInt, PetscInt*)
483    PetscErrorCode MatMumpsGetInfog(PetscMat, PetscInt, PetscInt*)
484    PetscErrorCode MatMumpsGetRinfo(PetscMat, PetscInt, PetscReal*)
485    PetscErrorCode MatMumpsGetRinfog(PetscMat, PetscInt, PetscReal*)
486
487    PetscErrorCode MatForwardSolve(PetscMat, PetscVec, PetscVec)
488    PetscErrorCode MatBackwardSolve(PetscMat, PetscVec, PetscVec)
489    PetscErrorCode MatSolve(PetscMat, PetscVec, PetscVec)
490    PetscErrorCode MatSolveTranspose(PetscMat, PetscVec, PetscVec)
491    PetscErrorCode MatSolveAdd(PetscMat, PetscVec, PetscVec, PetscVec)
492    PetscErrorCode MatSolveTransposeAdd(PetscMat, PetscVec, PetscVec, PetscVec)
493    PetscErrorCode MatMatSolve(PetscMat, PetscMat, PetscMat)
494
495    PetscErrorCode MatComputeExplicitOperator(PetscMat, PetscMat*)
496    PetscErrorCode MatUseScaledForm(PetscMat, PetscBool)
497    PetscErrorCode MatScaleSystem(PetscMat, PetscVec, PetscVec)
498    PetscErrorCode MatUnScaleSystem(PetscMat, PetscVec, PetscVec)
499
500    PetscErrorCode MatDenseSetLDA(PetscMat, PetscInt)
501    PetscErrorCode MatDenseGetLDA(PetscMat, PetscInt*)
502    PetscErrorCode MatDenseGetLocalMatrix(PetscMat, PetscMat*)
503    PetscErrorCode MatDenseGetArray(PetscMat, PetscScalar*[])
504    PetscErrorCode MatDenseRestoreArray(PetscMat, PetscScalar*[])
505    PetscErrorCode MatDenseGetArrayWrite(PetscMat, PetscScalar*[])
506    PetscErrorCode MatDenseRestoreArrayWrite(PetscMat, PetscScalar*[])
507    PetscErrorCode MatDenseGetArrayRead(PetscMat, const PetscScalar*[])
508    PetscErrorCode MatDenseRestoreArrayRead(PetscMat, const PetscScalar*[])
509    PetscErrorCode MatDenseGetColumnVec(PetscMat, PetscInt, PetscVec*)
510    PetscErrorCode MatDenseRestoreColumnVec(PetscMat, PetscInt, PetscVec*)
511    PetscErrorCode MatDenseGetColumnVecRead(PetscMat, PetscInt, PetscVec*)
512    PetscErrorCode MatDenseRestoreColumnVecRead(PetscMat, PetscInt, PetscVec*)
513    PetscErrorCode MatDenseGetColumnVecWrite(PetscMat, PetscInt, PetscVec*)
514    PetscErrorCode MatDenseRestoreColumnVecWrite(PetscMat, PetscInt, PetscVec*)
515    PetscErrorCode MatDenseGetArrayWriteAndMemType(PetscMat, PetscScalar*[], PetscMemType*)
516    PetscErrorCode MatDenseRestoreArrayWriteAndMemType(PetscMat, PetscScalar*[])
517    PetscErrorCode MatDenseGetArrayReadAndMemType(PetscMat, const PetscScalar*[], PetscMemType*)
518    PetscErrorCode MatDenseRestoreArrayReadAndMemType(PetscMat, const PetscScalar*[])
519    PetscErrorCode MatDenseGetArrayAndMemType(PetscMat, PetscScalar*[], PetscMemType*)
520    PetscErrorCode MatDenseRestoreArrayAndMemType(PetscMat, PetscScalar*[])
521    PetscErrorCode MatDenseGetSubMatrix(PetscMat, PetscInt, PetscInt, PetscInt, PetscInt, PetscMat*)
522    PetscErrorCode MatDenseRestoreSubMatrix(PetscMat, PetscMat*)
523
524    PetscErrorCode MatProductGetType(PetscMat, PetscMatProductType*)
525    PetscErrorCode MatProductGetMats(PetscMat, PetscMat*, PetscMat*, PetscMat*)
526
527    PetscErrorCode MatPythonSetType(PetscMat, char[])
528    PetscErrorCode MatPythonGetType(PetscMat, char*[])
529
530    PetscErrorCode MatPreallocatorPreallocate(PetscMat, PetscBool, PetscMat)
531
532cdef extern from * nogil: # custom.h
533    PetscErrorCode MatGetCurrentMemType(PetscMat, PetscMemType*)
534    PetscErrorCode MatIsPreallocated(PetscMat, PetscBool*)
535    PetscErrorCode MatHasPreallocationAIJ(PetscMat, PetscBool*, PetscBool*, PetscBool*, PetscBool*)
536
537# -----------------------------------------------------------------------------
538
539cdef extern from * nogil:
540    PetscErrorCode MatNullSpaceDestroy(PetscNullSpace*)
541    PetscErrorCode MatNullSpaceView(PetscNullSpace, PetscViewer)
542    PetscErrorCode MatNullSpaceCreate(MPI_Comm, PetscBool, PetscInt, PetscVec[],
543                                      PetscNullSpace*)
544    PetscErrorCode MatNullSpaceCreateRigidBody(PetscVec, PetscNullSpace*)
545    PetscErrorCode MatNullSpaceGetVecs(PetscNullSpace, PetscBool*, PetscInt*, const PetscVec*[])
546    PetscErrorCode MatNullSpaceRemove(PetscNullSpace, PetscVec)
547    PetscErrorCode MatNullSpaceTest(PetscNullSpace, PetscMat, PetscBool*)
548
549    ctypedef PetscErrorCode MatNullSpaceFunction(PetscNullSpace,
550                                                 PetscVec,
551                                                 void*) except PETSC_ERR_PYTHON
552    PetscErrorCode MatNullSpaceSetFunction(PetscNullSpace, MatNullSpaceFunction*, void*)
553
554    PetscErrorCode MatSetNullSpace(PetscMat, PetscNullSpace)
555    PetscErrorCode MatGetNullSpace(PetscMat, PetscNullSpace*)
556    PetscErrorCode MatSetTransposeNullSpace(PetscMat, PetscNullSpace)
557    PetscErrorCode MatGetTransposeNullSpace(PetscMat, PetscNullSpace*)
558    PetscErrorCode MatSetNearNullSpace(PetscMat, PetscNullSpace)
559    PetscErrorCode MatGetNearNullSpace(PetscMat, PetscNullSpace*)
560
561cdef inline NullSpace ref_NullSpace(PetscNullSpace nsp):
562    cdef NullSpace ob = <NullSpace> NullSpace()
563    ob.nsp = nsp
564    CHKERR(PetscINCREF(ob.obj))
565    return ob
566
567cdef PetscErrorCode NullSpace_Function(
568    PetscNullSpace n,
569    PetscVec       v,
570    void           *ctx,
571   ) except PETSC_ERR_PYTHON with gil:
572    cdef NullSpace nsp = ref_NullSpace(n)
573    cdef Vec vec = ref_Vec(v)
574    (function, args, kargs) = nsp.get_attr('__function__')
575    function(nsp, vec, *args, **kargs)
576    return PETSC_SUCCESS
577
578# -----------------------------------------------------------------------------
579
580cdef inline Mat ref_Mat(PetscMat mat):
581    cdef Mat ob = <Mat> Mat()
582    ob.mat = mat
583    CHKERR(PetscINCREF(ob.obj))
584    return ob
585
586# -----------------------------------------------------------------------------
587
588# unary operations
589
590cdef Mat mat_pos(Mat self):
591    cdef Mat mat = type(self)()
592    CHKERR(MatDuplicate(self.mat, MAT_COPY_VALUES, &mat.mat))
593    return mat
594
595cdef Mat mat_neg(Mat self):
596    cdef Mat mat = <Mat> mat_pos(self)
597    CHKERR(MatScale(mat.mat, -1))
598    return mat
599
600# inplace binary operations
601
602cdef Mat mat_iadd(Mat self, other):
603    if isinstance(other, Mat):
604        self.axpy(1, other)
605    elif isinstance(other, (tuple, list)):
606        alpha, mat = other
607        self.axpy(alpha, mat)
608    elif isinstance(other, Vec):
609        self.setDiagonal(other, PETSC_ADD_VALUES)
610    else:
611        self.shift(other)
612    return self
613
614cdef Mat mat_isub(Mat self, other):
615    if isinstance(other, Mat):
616        self.axpy(-1, other)
617    elif isinstance(other, (tuple, list)):
618        alpha, mat = other
619        self.axpy(-alpha, mat)
620    elif isinstance(other, Vec):
621        diag = other.copy()
622        diag.scale(-1)
623        self.setDiagonal(diag, PETSC_ADD_VALUES)
624        diag.destroy()
625    else:
626        self.shift(-other)
627    return self
628
629cdef Mat mat_imul(Mat self, other):
630    if isinstance(other, (tuple, list)):
631        L, R = other
632        self.diagonalScale(L, R)
633    else:
634        self.scale(other)
635    return self
636
637cdef Mat mat_idiv(Mat self, other):
638    if isinstance(other, (tuple, list)):
639        L, R = other
640        if isinstance(L, Vec):
641            L = L.copy()
642            L.reciprocal()
643        if isinstance(R, Vec):
644            R = R.copy()
645            R.reciprocal()
646        self.diagonalScale(L, R)
647    else:
648        other = 1/other
649        self.scale(other)
650    return self
651
652# binary operations
653
654cdef Mat mat_add(Mat self, other):
655    return mat_iadd(mat_pos(self), other)
656
657cdef Mat mat_sub(Mat self, other):
658    return mat_isub(mat_pos(self), other)
659
660cdef Vec mat_mul_vec(Mat self, Vec other):
661    cdef Vec result = self.createVecLeft()
662    self.mult(other, result)
663    return result
664
665cdef Mat mat_mul_mat(Mat self, Mat other):
666    return self.matMult(other)
667
668cdef object mat_mul(Mat self, other):
669    if isinstance(other, Vec):
670        return mat_mul_vec(self, <Vec>other)
671    elif isinstance(other, Mat):
672        return mat_mul_mat(self, <Mat>other)
673    else:
674        return mat_imul(mat_pos(self), other)
675
676cdef Mat mat_div(Mat self, other):
677    return mat_idiv(mat_pos(self), other)
678
679cdef object mat_matmul(Mat self, other):
680    if isinstance(other, Vec):
681        return mat_mul_vec(self, <Vec>other)
682    if isinstance(other, Mat):
683        return mat_mul_mat(self, <Mat>other)
684    return NotImplemented
685
686# reflected binary operations
687
688cdef Mat mat_radd(Mat self, other):
689    return mat_add(self, other)
690
691cdef Mat mat_rsub(Mat self, other):
692    cdef Mat mat = <Mat> mat_sub(self, other)
693    mat.scale(-1)
694    return mat
695
696cdef Mat mat_rmul(Mat self, other):
697    return mat_mul(self, other)
698
699cdef Mat mat_rdiv(Mat self, other):
700    <void>self; <void>other # unused
701    return NotImplemented
702
703# -----------------------------------------------------------------------------
704
705cdef inline PetscMatStructure matstructure(object structure) \
706    except <PetscMatStructure>(-1):
707    if   structure is None:  return MAT_DIFFERENT_NONZERO_PATTERN
708    elif structure is False: return MAT_DIFFERENT_NONZERO_PATTERN
709    elif structure is True:  return MAT_SAME_NONZERO_PATTERN
710    else:                    return structure
711
712cdef inline PetscMatDuplicateOption matduplicateoption(object copy) \
713    except <PetscMatDuplicateOption>(-1):
714    if   copy is None:  return MAT_DO_NOT_COPY_VALUES
715    elif copy is False: return MAT_DO_NOT_COPY_VALUES
716    elif copy is True:  return MAT_COPY_VALUES
717    else:               return copy
718
719cdef inline PetscMatAssemblyType assemblytype(object assembly) \
720    except <PetscMatAssemblyType>(-1):
721    if   assembly is None:  return MAT_FINAL_ASSEMBLY
722    elif assembly is False: return MAT_FINAL_ASSEMBLY
723    elif assembly is True:  return MAT_FLUSH_ASSEMBLY
724    else:                   return assembly
725
726cdef inline PetscMatInfoType infotype(object info) \
727    except <PetscMatInfoType>(-1):
728    if   info is None: return MAT_GLOBAL_SUM
729    else:              return info
730
731# -----------------------------------------------------------------------------
732
733cdef inline PetscErrorCode Mat_Sizes(
734    object size, object bsize,
735    PetscInt *r, PetscInt *c,
736    PetscInt *m, PetscInt *n,
737    PetscInt *M, PetscInt *N,
738   ) except PETSC_ERR_PYTHON:
739    # unpack row and column sizes
740    cdef object rsize, csize
741    try:
742        rsize , csize = size
743    except (TypeError, ValueError):
744        rsize = csize = size
745    # unpack row and column block sizes
746    cdef object rbsize, cbsize
747    try:
748        rbsize , cbsize = bsize
749    except (TypeError, ValueError):
750        rbsize = cbsize = bsize
751    # split row and column sizes
752    Sys_Sizes(rsize, rbsize, r, m, M)
753    Sys_Sizes(csize, cbsize, c, n, N)
754    return PETSC_SUCCESS
755
756cdef inline PetscErrorCode Mat_Create(
757    PetscMatType mtype,
758    object comm,
759    object size,
760    object bsize,
761    PetscMat *A,
762   ) except PETSC_ERR_PYTHON:
763    # communicator
764    cdef MPI_Comm ccomm = def_Comm(comm, PETSC_COMM_DEFAULT)
765    # sizes and block sizes
766    cdef PetscInt rbs = 0, cbs = 0, m = 0, n = 0, M = 0, N = 0
767    Mat_Sizes(size, bsize, &rbs, &cbs, &m, &n, &M, &N)
768    if rbs == PETSC_DECIDE: rbs = 1
769    if cbs == PETSC_DECIDE: cbs = rbs
770    Sys_Layout(ccomm, rbs, &m, &M)
771    Sys_Layout(ccomm, cbs, &n, &N)
772    # create matrix and set sizes
773    cdef PetscMat mat = NULL
774    CHKERR(MatCreate(ccomm, &mat))
775    CHKERR(MatSetSizes(mat, m, n, M, N))
776    CHKERR(MatSetBlockSizes(mat, rbs, cbs))
777    CHKERR(MatSetType(mat, mtype))
778    A[0] = mat
779    return PETSC_SUCCESS
780
781cdef inline PetscErrorCode Mat_AllocAIJ_NNZ(PetscMat A, object NNZ) except PETSC_ERR_PYTHON:
782    #
783    cdef PetscBool aij=PETSC_FALSE, baij=PETSC_FALSE, sbaij=PETSC_FALSE, aijis=PETSC_FALSE
784    CHKERR(MatHasPreallocationAIJ(A, &aij, &baij, &sbaij, &aijis))
785    # local row size and block size
786    cdef PetscInt m=0, bs=1
787    CHKERR(MatGetLocalSize(A, &m, NULL))
788    if baij == PETSC_TRUE or sbaij == PETSC_TRUE:
789        CHKERR(MatGetBlockSize(A, &bs))
790        assert bs > 0, "block size not set"
791    # unpack NNZ argument
792    cdef object od_nnz, oo_nnz
793    try:
794        od_nnz, oo_nnz = NNZ
795    except (TypeError, ValueError):
796        od_nnz, oo_nnz = NNZ, None
797    # diagonal and off-diagonal number of nonzeros
798    cdef PetscInt d_nz=PETSC_DECIDE, d_n=0, *d_nnz=NULL
799    if od_nnz is not None:
800        od_nnz = iarray_i(od_nnz, &d_n, &d_nnz)
801        if   d_n == 0: d_nnz = NULL # just in case
802        elif d_n == 1: d_nz = d_nnz[0]; d_n=0; d_nnz = NULL
803    cdef PetscInt o_nz=PETSC_DECIDE, o_n=0, *o_nnz=NULL
804    if oo_nnz is not None:
805        oo_nnz = iarray_i(oo_nnz, &o_n, &o_nnz)
806        if   o_n == 0: o_nnz = NULL # just in case
807        elif o_n == 1: o_nz = o_nnz[0]; o_n=0; o_nnz = NULL
808    if m == PETSC_DECIDE:
809        if d_n > 1 and d_n*bs > m: m = d_n*bs
810        if o_n > 1 and o_n*bs > m: m = o_n*bs
811    # check array sizes
812    if d_n > 1 and d_n*bs != m: raise ValueError(
813        "size(d_nnz) is %d, expected %d" %
814        (toInt(d_n), toInt(m//bs)))
815    if o_n > 1 and o_n*bs != m: raise ValueError(
816        "size(o_nnz) is %d, expected %d" %
817        (toInt(o_n), toInt(m//bs)))
818    # preallocate
819    if aij == PETSC_TRUE:
820        CHKERR(MatSeqAIJSetPreallocation(A, d_nz, d_nnz))
821        CHKERR(MatMPIAIJSetPreallocation(A, d_nz, d_nnz, o_nz, o_nnz))
822    if baij == PETSC_TRUE:
823        CHKERR(MatSeqBAIJSetPreallocation(A, bs, d_nz, d_nnz))
824        CHKERR(MatMPIBAIJSetPreallocation(A, bs, d_nz, d_nnz, o_nz, o_nnz))
825    if sbaij == PETSC_TRUE:
826        CHKERR(MatSeqSBAIJSetPreallocation(A, bs, d_nz, d_nnz))
827        CHKERR(MatMPISBAIJSetPreallocation(A, bs, d_nz, d_nnz, o_nz, o_nnz))
828    if aijis == PETSC_TRUE:
829        CHKERR(MatISSetPreallocation(A, d_nz, d_nnz, o_nz, o_nnz))
830    return PETSC_SUCCESS
831
832cdef inline PetscErrorCode Mat_AllocAIJ_CSR(PetscMat A, object CSR) except PETSC_ERR_PYTHON:
833    #
834    cdef PetscBool aij=PETSC_FALSE, baij=PETSC_FALSE, sbaij=PETSC_FALSE, aijis=PETSC_FALSE
835    CHKERR(MatHasPreallocationAIJ(A, &aij, &baij, &sbaij, &aijis))
836    # local row size and block size
837    cdef PetscInt m=0, bs = 1
838    CHKERR(MatGetLocalSize(A, &m, NULL))
839    if baij == PETSC_TRUE or sbaij == PETSC_TRUE:
840        CHKERR(MatGetBlockSize(A, &bs))
841        assert bs > 0, "block size not set"
842    # unpack CSR argument
843    cdef object oi, oj, ov
844    try:
845        oi, oj, ov = CSR
846    except (TypeError, ValueError):
847        oi, oj = CSR; ov = None
848    # rows, cols, and values
849    cdef PetscInt ni=0, *i=NULL
850    cdef PetscInt nj=0, *j=NULL
851    cdef PetscInt nv=0
852    cdef PetscScalar *v=NULL
853    oi = iarray_i(oi, &ni, &i)
854    oj = iarray_i(oj, &nj, &j)
855    if ov is not None:
856        ov = iarray_s(ov, &nv, &v)
857    if m == PETSC_DECIDE: m = (ni-1)*bs
858    # check array sizes
859    if ((ni-1)*bs != m):
860        raise ValueError("size(I) is %d, expected %d" %
861                         (toInt(ni), toInt(m//bs+1)))
862    if (i[0] != 0):
863        raise ValueError("I[0] is %d, expected %d" %
864                         (toInt(i[0]), toInt(0)))
865    if (i[ni-1] != nj):
866        raise ValueError("size(J) is %d, expected %d" %
867                         (toInt(nj), toInt(i[ni-1])))
868    if v != NULL and (nj*bs*bs != nv):
869        raise ValueError("size(V) is %d, expected %d" %
870                         (toInt(nv), toInt(nj*bs*bs)))
871    # preallocate
872    if aij == PETSC_TRUE:
873        CHKERR(MatSeqAIJSetPreallocationCSR(A, i, j, v))
874        CHKERR(MatMPIAIJSetPreallocationCSR(A, i, j, v))
875    if baij == PETSC_TRUE:
876        CHKERR(MatSeqBAIJSetPreallocationCSR(A, bs, i, j, v))
877        CHKERR(MatMPIBAIJSetPreallocationCSR(A, bs, i, j, v))
878    if sbaij == PETSC_TRUE:
879        CHKERR(MatSeqSBAIJSetPreallocationCSR(A, bs, i, j, v))
880        CHKERR(MatMPISBAIJSetPreallocationCSR(A, bs, i, j, v))
881    return PETSC_SUCCESS
882
883cdef inline PetscErrorCode Mat_AllocAIJ(PetscMat A, object NNZ, object CSR) except PETSC_ERR_PYTHON:
884    if CSR is not None:
885        return Mat_AllocAIJ_CSR(A, CSR)
886    if NNZ is not None:
887        return Mat_AllocAIJ_NNZ(A, NNZ)
888    return PETSC_SUCCESS
889
890cdef inline object Mat_AllocDense(PetscMat A, object array):
891    cdef PetscInt m=0, N=0
892    CHKERR(MatGetLocalSize(A, &m, NULL))
893    CHKERR(MatGetSize(A, NULL, &N))
894    cdef PetscInt size=0
895    cdef PetscScalar *data=NULL
896    if array is not None:
897        array = ofarray_s(array, &size, &data)
898        if m*N != size: raise ValueError(
899            "size(array) is %d, expected %dx%d=%d" %
900            (toInt(size), toInt(m), toInt(N), toInt(m*N)))
901    CHKERR(MatSeqDenseSetPreallocation(A, data))
902    CHKERR(MatMPIDenseSetPreallocation(A, data))
903    return array
904
905# -----------------------------------------------------------------------------
906
907ctypedef PetscErrorCode MatSetValuesFcn(PetscMat,
908                                        PetscInt, const PetscInt*,
909                                        PetscInt, const PetscInt*,
910                                        const PetscScalar*, PetscInsertMode)
911
912cdef inline MatSetValuesFcn* matsetvalues_fcn(int blocked, int local):
913    cdef MatSetValuesFcn *setvalues = NULL
914    if blocked and local: setvalues = MatSetValuesBlockedLocal
915    elif blocked:         setvalues = MatSetValuesBlocked
916    elif local:           setvalues = MatSetValuesLocal
917    else:                 setvalues = MatSetValues
918    return setvalues
919
920cdef inline PetscErrorCode matsetvalues(PetscMat A,
921                                        object oi, object oj, object ov,
922                                        object oaddv, int blocked, int local) except PETSC_ERR_PYTHON:
923    # block size
924    cdef PetscInt rbs=1, cbs=1
925    if blocked: CHKERR(MatGetBlockSizes(A, &rbs, &cbs))
926    if rbs < 1: rbs = 1
927    if cbs < 1: cbs = 1
928    # rows, cols, and values
929    cdef PetscInt ni=0, *i=NULL
930    cdef PetscInt nj=0, *j=NULL
931    cdef PetscInt nv=0
932    cdef PetscScalar *v=NULL
933    oi = iarray_i(oi, &ni, &i)
934    oj = iarray_i(oj, &nj, &j)
935    ov = iarray_s(ov, &nv, &v)
936    if ni*nj*rbs*cbs != nv: raise ValueError(
937        "incompatible array sizes: ni=%d, nj=%d, nv=%d" %
938        (toInt(ni), toInt(nj), toInt(nv)))
939    # MatSetValuesXXX function and insert mode
940    cdef MatSetValuesFcn *setvalues = matsetvalues_fcn(blocked, local)
941    cdef PetscInsertMode addv = insertmode(oaddv)
942    # actual call
943    CHKERR(setvalues(A, ni, i, nj, j, v, addv))
944    return PETSC_SUCCESS
945
946cdef inline PetscErrorCode matsetvalues_rcv(PetscMat A,
947                                            object oi, object oj, object ov,
948                                            object oaddv,
949                                            int blocked, int local) except PETSC_ERR_PYTHON:
950    # block size
951    cdef PetscInt rbs=1, cbs=1
952    if blocked: CHKERR(MatGetBlockSizes(A, &rbs, &cbs))
953    if rbs < 1: rbs = 1
954    if cbs < 1: cbs = 1
955    # rows, cols, and values
956    cdef PetscInt ni=0, *i=NULL
957    cdef PetscInt nj=0, *j=NULL
958    cdef PetscInt nv=0
959    cdef PetscScalar *v=NULL
960    cdef ndarray ai = iarray_i(oi, &ni, &i)
961    cdef ndarray aj = iarray_i(oj, &nj, &j)
962    cdef ndarray av = iarray_s(ov, &nv, &v)
963    # check various dimensions
964    if PyArray_NDIM(ai) != 2: raise ValueError(
965        ("row indices must have two dimensions: "
966         "rows.ndim=%d") % (PyArray_NDIM(ai)))
967    elif not PyArray_ISCONTIGUOUS(ai): raise ValueError(
968        "expecting a C-contiguous array")
969    if PyArray_NDIM(aj) != 2: raise ValueError(
970        ("column indices must have two dimensions: "
971         "cols.ndim=%d") % (PyArray_NDIM(aj)))
972    elif not PyArray_ISCONTIGUOUS(aj): raise ValueError(
973        "expecting a C-contiguous array")
974    if PyArray_NDIM(av) < 2: raise ValueError(
975        ("values must have two or more dimensions: "
976         "vals.ndim=%d") % (PyArray_NDIM(av)))
977    elif not PyArray_ISCONTIGUOUS(av): raise ValueError(
978        "expecting a C-contiguous array")
979    # check various shapes
980    cdef Py_ssize_t nm = PyArray_DIM(ai, 0)
981    cdef Py_ssize_t si = PyArray_DIM(ai, 1)
982    cdef Py_ssize_t sj = PyArray_DIM(aj, 1)
983    cdef Py_ssize_t sv = PyArray_MultiplyList(PyArray_DIMS(av)+1, PyArray_NDIM(av)-1)
984    if ((nm != PyArray_DIM(aj, 0)) or
985        (nm != PyArray_DIM(av, 0)) or
986        (si*rbs * sj*cbs != sv)): raise ValueError(
987        ("input arrays have incompatible shapes: "
988         "rows.shape=%s, cols.shape=%s, vals.shape=%s") %
989        (ai.shape, aj.shape, av.shape))
990    # MatSetValuesXXX function and insert mode
991    cdef MatSetValuesFcn *setvalues = \
992        matsetvalues_fcn(blocked, local)
993    cdef PetscInsertMode addv = insertmode(oaddv)
994    # actual calls
995    cdef Py_ssize_t k=0
996    for k from 0 <= k < nm:
997        CHKERR(setvalues(A,
998                         <PetscInt>si, &i[k*si],
999                         <PetscInt>sj, &j[k*sj],
1000                         &v[k*sv], addv))
1001    return PETSC_SUCCESS
1002
1003cdef inline PetscErrorCode matsetvalues_ijv(PetscMat A,
1004                                            object oi, object oj, object ov,
1005                                            object oaddv,
1006                                            object om,
1007                                            int blocked, int local) except PETSC_ERR_PYTHON:
1008    # block size
1009    cdef PetscInt rbs=1, cbs=1
1010    if blocked: CHKERR(MatGetBlockSizes(A, &rbs, &cbs))
1011    if rbs < 1: rbs = 1
1012    if cbs < 1: cbs = 1
1013    # column pointers, column indices, and values
1014    cdef PetscInt ni=0, *i=NULL
1015    cdef PetscInt nj=0, *j=NULL
1016    cdef PetscInt nv=0
1017    cdef PetscScalar *v=NULL
1018    oi = iarray_i(oi, &ni, &i)
1019    oj = iarray_i(oj, &nj, &j)
1020    ov = iarray_s(ov, &nv, &v)
1021    # row indices
1022    cdef PetscInt nm=0, *m=NULL
1023    cdef PetscInt rs=0, re=ni-1
1024    if om is not None:
1025        om = iarray_i(om, &nm, &m)
1026    else:
1027        if not local:
1028            CHKERR(MatGetOwnershipRange(A, &rs, &re))
1029            rs //= rbs; re //= rbs
1030        nm = re - rs
1031    # check various sizes
1032    if (ni-1 != nm): raise ValueError(
1033        "size(I) is %d, expected %d" %
1034        (toInt(ni), toInt(nm+1)))
1035    if (i[0] != 0): raise ValueError(
1036        "I[0] is %d, expected %d" %
1037        (toInt(i[0]), 0))
1038    if (i[ni-1] != nj): raise ValueError(
1039        "size(J) is %d, expected %d" %
1040        (toInt(nj), toInt(i[ni-1])))
1041    if (nj*rbs*cbs != nv): raise ValueError(
1042        "size(V) is %d, expected %d" %
1043        (toInt(nv), toInt(nj*rbs*cbs)))
1044    # MatSetValuesXXX function and insert mode
1045    cdef MatSetValuesFcn *setvalues = \
1046        matsetvalues_fcn(blocked, local)
1047    cdef PetscInsertMode addv = insertmode(oaddv)
1048    # actual call
1049    cdef PetscInt k=0, c=0
1050    cdef PetscInt irow=0, ncol=0, *icol=NULL
1051    cdef PetscScalar *sval=NULL
1052    for k from 0 <= k < nm:
1053        irow = m[k] if m!=NULL else rs+k
1054        ncol = i[k+1] - i[k]
1055        icol = j + i[k]
1056        if blocked:
1057            sval = v + i[k]*rbs*cbs
1058            for c from 0 <= c < ncol:
1059                CHKERR(setvalues(A, 1, &irow, 1, &icol[c],
1060                                 &sval[c*rbs*cbs], addv))
1061        else:
1062            sval = v + i[k]
1063            CHKERR(setvalues(A, 1, &irow, ncol, icol, sval, addv))
1064    return PETSC_SUCCESS
1065
1066cdef inline PetscErrorCode matsetvalues_coo(PetscMat A,
1067                                            object ocoo_v,
1068                                            object oaddv) except PETSC_ERR_PYTHON:
1069    cdef PetscScalar *v = NULL
1070    cdef PetscInsertMode addv
1071
1072    ocoo_v = iarray_s(ocoo_v, NULL, &v)
1073    addv = insertmode(oaddv)
1074
1075    CHKERR(MatSetValuesCOO(A, v, addv))
1076    return PETSC_SUCCESS
1077
1078cdef inline PetscErrorCode matsetvalues_csr(PetscMat A,
1079                                            object oi, object oj, object ov,
1080                                            object oaddv,
1081                                            int blocked, int local) except PETSC_ERR_PYTHON:
1082    matsetvalues_ijv(A, oi, oj, ov, oaddv, None, blocked, local)
1083    return PETSC_SUCCESS
1084
1085cdef inline matgetvalues(PetscMat mat,
1086                         object orows, object ocols, object values):
1087    cdef PetscInt ni=0, nj=0, nv=0
1088    cdef PetscInt *i=NULL, *j=NULL
1089    cdef PetscScalar *v=NULL
1090    cdef ndarray rows = iarray_i(orows, &ni, &i)
1091    cdef ndarray cols = iarray_i(ocols, &nj, &j)
1092    if values is None:
1093        values = empty_s(ni*nj)
1094        values.shape = rows.shape + cols.shape
1095    values = oarray_s(values, &nv, &v)
1096    if (ni*nj != nv): raise ValueError(
1097        "incompatible array sizes: ni=%d, nj=%d, nv=%d" %
1098        (toInt(ni), toInt(nj), toInt(nv)))
1099    CHKERR(MatGetValues(mat, ni, i, nj, j, v))
1100    return values
1101
1102# -----------------------------------------------------------------------------
1103
1104cdef extern from * nogil: # custom.h
1105    PetscErrorCode MatFactorInfoDefaults(PetscBool, PetscBool, PetscMatFactorInfo*)
1106
1107cdef inline PetscMatFactorShiftType matfactorshifttype(object st) \
1108    except <PetscMatFactorShiftType>(-1):
1109    if isinstance(st, str):
1110        if st == "none": return MAT_SHIFT_NONE
1111        if st == "nonzero": return MAT_SHIFT_NONZERO
1112        if st == "positive_definite": return MAT_SHIFT_POSITIVE_DEFINITE
1113        if st == "inblocks": return MAT_SHIFT_INBLOCKS
1114        if st == "na": return MAT_SHIFT_NONZERO
1115        if st == "pd": return MAT_SHIFT_POSITIVE_DEFINITE
1116        else: raise ValueError("unknown shift type: %s" % st)
1117    return st
1118
1119cdef PetscErrorCode matfactorinfo(PetscBool inc, PetscBool chol, object opts,
1120                                  PetscMatFactorInfo *info) except PETSC_ERR_PYTHON:
1121    CHKERR(MatFactorInfoDefaults(inc, chol, info))
1122    if opts is None: return PETSC_SUCCESS
1123    cdef dict options = dict(opts)
1124    #
1125    cdef fill = options.pop('fill', None)
1126    if fill is not None:
1127        info.fill = asReal(fill)
1128    #
1129    cdef zeropivot = options.pop('zeropivot', None)
1130    if zeropivot is not None:
1131        info.zeropivot = asReal(zeropivot)
1132    #
1133    cdef levels = options.pop('levels', None)
1134    if levels is not None:
1135        info.levels  = <PetscReal>asInt(levels)
1136    cdef diagonal_fill = options.pop('diagonal_fill', None)
1137    if diagonal_fill is not None:
1138        info.diagonal_fill = <PetscReal>(<bint>diagonal_fill)
1139    #
1140    cdef dt = options.pop('dt', None)
1141    if dt is not None:
1142        info.usedt = <PetscReal>PETSC_TRUE
1143        info.dt = asReal(dt)
1144    cdef dtcol = options.pop('dtcol', None)
1145    if dtcol is not None:
1146        info.usedt = <PetscReal>PETSC_TRUE
1147        info.dtcol = asReal(dtcol)
1148    cdef dtcount = options.pop('dtcount', None)
1149    if dtcount is not None:
1150        info.usedt = <PetscReal>PETSC_TRUE
1151        info.dtcount = <PetscReal>asInt(dtcount)
1152    #
1153    cdef shifttype = options.pop('shifttype', None)
1154    if shifttype is not None:
1155        info.shifttype = <PetscReal>matfactorshifttype(shifttype)
1156    cdef shiftamount = options.pop('shiftamount', None)
1157    if shiftamount is not None:
1158        info.shiftamount = asReal(shiftamount)
1159    #
1160    if options:
1161        raise ValueError("unknown options: %s"
1162                         % list(options.keys()))
1163    return PETSC_SUCCESS
1164
1165# -----------------------------------------------------------------------------
1166
1167cdef object mat_getitem(Mat self, object ij):
1168    cdef PetscInt M=0, N=0
1169    rows, cols = ij
1170    if isinstance(rows, slice):
1171        CHKERR(MatGetSize(self.mat, &M, NULL))
1172        start, stop, stride = rows.indices(toInt(M))
1173        rows = arange(start, stop, stride)
1174    if isinstance(cols, slice):
1175        CHKERR(MatGetSize(self.mat, NULL, &N))
1176        start, stop, stride = cols.indices(toInt(N))
1177        cols = arange(start, stop, stride)
1178    return matgetvalues(self.mat, rows, cols, None)
1179
1180
1181cdef PetscErrorCode mat_setitem(Mat self, object ij, object v) except PETSC_ERR_PYTHON:
1182    cdef PetscInt M=0, N=0
1183    rows, cols = ij
1184    if isinstance(rows, slice):
1185        CHKERR(MatGetSize(self.mat, &M, NULL))
1186        start, stop, stride = rows.indices(toInt(M))
1187        rows = arange(start, stop, stride)
1188    if isinstance(cols, slice):
1189        CHKERR(MatGetSize(self.mat, NULL, &N))
1190        start, stop, stride = cols.indices(toInt(N))
1191        cols = arange(start, stop, stride)
1192    matsetvalues(self.mat, rows, cols, v, None, 0, 0)
1193    return PETSC_SUCCESS
1194
1195# -----------------------------------------------------------------------------
1196
1197cdef matsetvaluestencil(PetscMat A,
1198                        MatStencil r, MatStencil c, object value,
1199                        PetscInsertMode im, int blocked):
1200    # block size
1201    cdef PetscInt rbs=1, cbs=1
1202    if blocked: CHKERR(MatGetBlockSizes(A, &rbs, &cbs))
1203    if rbs < 1: rbs = 1
1204    if cbs < 1: cbs = 1
1205    # values
1206    cdef PetscInt    nv = 1
1207    cdef PetscScalar *v = NULL
1208    value = iarray_s(value, &nv, &v)
1209    if rbs*cbs != nv: raise ValueError(
1210        "incompatible array sizes: nv=%d" % toInt(nv))
1211    if blocked:
1212        CHKERR(MatSetValuesBlockedStencil(A,
1213                                          1, &r.stencil,
1214                                          1, &c.stencil,
1215                                          v, im))
1216    else:
1217        CHKERR(MatSetValuesStencil(A,
1218                                   1, &r.stencil,
1219                                   1, &c.stencil,
1220                                   v, im))
1221    return 0
1222
1223cdef mat_get_dlpack_ctx(Mat self):
1224    if 'dense' not in self.getType():
1225        raise NotImplementedError("Not for type {}".format(self.getType()))
1226    cdef object ctx0 = self.get_attr('__dltensor_ctx__')
1227    cdef PetscInt n = 0, m = 0, lda = 0
1228    cdef int64_t ndim = 2
1229    cdef int64_t* shape_arr = NULL
1230    cdef int64_t* strides_arr = NULL
1231    cdef object s1 = None
1232    cdef object s2 = None
1233    cdef PetscInt devId = 0
1234    cdef PetscMemType mtype = PETSC_MEMTYPE_HOST
1235    if ctx0 is None: # First time in, create a linear memory view
1236        s1 = oarray_p(empty_p(<PetscInt>ndim), NULL, <void**>&shape_arr)
1237        s2 = oarray_p(empty_p(<PetscInt>ndim), NULL, <void**>&strides_arr)
1238        CHKERR(MatGetSize(self.mat, NULL, &n))
1239        CHKERR(MatGetLocalSize(self.mat, &m, NULL))
1240        CHKERR(MatDenseGetLDA(self.mat, &lda))
1241        shape_arr[0] = <int64_t>m
1242        shape_arr[1] = <int64_t>n
1243        strides_arr[0] = 1
1244        strides_arr[1] = <int64_t>lda
1245    else:
1246        (_, _, ndim, s1, s2) = ctx0
1247
1248    devType_ = {PETSC_MEMTYPE_HOST : kDLCPU, PETSC_MEMTYPE_CUDA : kDLCUDA, PETSC_MEMTYPE_HIP : kDLROCM}
1249    CHKERR(MatGetCurrentMemType(self.mat, &mtype))
1250    dtype = devType_.get(mtype, kDLCPU)
1251    if dtype != kDLCPU:
1252        CHKERR(PetscObjectGetDeviceId(<PetscObject>self.mat, &devId))
1253    ctx0 = (dtype, devId, ndim, s1, s2)
1254    self.set_attr('__dltensor_ctx__', ctx0)
1255    return ctx0
1256
1257# -----------------------------------------------------------------------------
1258