xref: /petsc/src/mat/impls/dense/seq/dense.c (revision cd3f9d89000eee1a8525330c324095837b9c0d60)
167e560aaSBarry Smith /*
267e560aaSBarry Smith      Defines the basic matrix operations for sequential dense.
347d993e7Ssuyashtn      Portions of this code are under:
447d993e7Ssuyashtn      Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved.
567e560aaSBarry Smith */
6289bc588SBarry Smith 
7dec5eb66SMatthew G Knepley #include <../src/mat/impls/dense/seq/dense.h> /*I "petscmat.h" I*/
8*cd3f9d89SJunchao Zhang #include <../src/mat/impls/dense/mpi/mpidense.h>
9c6db04a5SJed Brown #include <petscblaslapack.h>
106a63e612SBarry Smith #include <../src/mat/impls/aij/seq/aij.h>
11b2573a8aSBarry Smith 
12d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSymmetrize_Private(Mat A, PetscBool hermitian)
13d71ae5a4SJacob Faibussowitsch {
148c178816SStefano Zampini   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
158c178816SStefano Zampini   PetscInt      j, k, n = A->rmap->n;
16ca15aa20SStefano Zampini   PetscScalar  *v;
178c178816SStefano Zampini 
188c178816SStefano Zampini   PetscFunctionBegin;
1908401ef6SPierre Jolivet   PetscCheck(A->rmap->n == A->cmap->n, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Cannot symmetrize a rectangular matrix");
209566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
218c178816SStefano Zampini   if (!hermitian) {
228c178816SStefano Zampini     for (k = 0; k < n; k++) {
23ad540459SPierre Jolivet       for (j = k; j < n; j++) v[j * mat->lda + k] = v[k * mat->lda + j];
248c178816SStefano Zampini     }
258c178816SStefano Zampini   } else {
268c178816SStefano Zampini     for (k = 0; k < n; k++) {
27ad540459SPierre Jolivet       for (j = k; j < n; j++) v[j * mat->lda + k] = PetscConj(v[k * mat->lda + j]);
288c178816SStefano Zampini     }
298c178816SStefano Zampini   }
309566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
318c178816SStefano Zampini   PetscFunctionReturn(0);
328c178816SStefano Zampini }
338c178816SStefano Zampini 
34d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode MatSeqDenseInvertFactors_Private(Mat A)
35d71ae5a4SJacob Faibussowitsch {
368c178816SStefano Zampini   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
378c178816SStefano Zampini   PetscBLASInt  info, n;
388c178816SStefano Zampini 
398c178816SStefano Zampini   PetscFunctionBegin;
408c178816SStefano Zampini   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
419566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
428c178816SStefano Zampini   if (A->factortype == MAT_FACTOR_LU) {
4328b400f6SJacob Faibussowitsch     PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present");
448c178816SStefano Zampini     if (!mat->fwork) {
458c178816SStefano Zampini       mat->lfwork = n;
469566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
478c178816SStefano Zampini     }
489566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
49792fecdfSBarry Smith     PetscCallBLAS("LAPACKgetri", LAPACKgetri_(&n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info));
509566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
519566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0));
528c178816SStefano Zampini   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
53b94d7dedSBarry Smith     if (A->spd == PETSC_BOOL3_TRUE) {
549566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
55792fecdfSBarry Smith       PetscCallBLAS("LAPACKpotri", LAPACKpotri_("L", &n, mat->v, &mat->lda, &info));
569566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
579566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_TRUE));
588c178816SStefano Zampini #if defined(PETSC_USE_COMPLEX)
59b94d7dedSBarry Smith     } else if (A->hermitian == PETSC_BOOL3_TRUE) {
6028b400f6SJacob Faibussowitsch       PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present");
6128b400f6SJacob Faibussowitsch       PetscCheck(mat->fwork, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Fwork not present");
629566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
63792fecdfSBarry Smith       PetscCallBLAS("LAPACKhetri", LAPACKhetri_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &info));
649566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
659566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_TRUE));
668c178816SStefano Zampini #endif
678c178816SStefano Zampini     } else { /* symmetric case */
6828b400f6SJacob Faibussowitsch       PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present");
6928b400f6SJacob Faibussowitsch       PetscCheck(mat->fwork, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Fwork not present");
709566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
71792fecdfSBarry Smith       PetscCallBLAS("LAPACKsytri", LAPACKsytri_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &info));
729566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
739566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_FALSE));
748c178816SStefano Zampini     }
7528b400f6SJacob Faibussowitsch     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad Inversion: zero pivot in row %" PetscInt_FMT, (PetscInt)info - 1);
769566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0));
778c178816SStefano Zampini   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Matrix must be factored to solve");
788c178816SStefano Zampini 
798c178816SStefano Zampini   A->ops->solve             = NULL;
808c178816SStefano Zampini   A->ops->matsolve          = NULL;
818c178816SStefano Zampini   A->ops->solvetranspose    = NULL;
828c178816SStefano Zampini   A->ops->matsolvetranspose = NULL;
838c178816SStefano Zampini   A->ops->solveadd          = NULL;
848c178816SStefano Zampini   A->ops->solvetransposeadd = NULL;
858c178816SStefano Zampini   A->factortype             = MAT_FACTOR_NONE;
869566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
878c178816SStefano Zampini   PetscFunctionReturn(0);
888c178816SStefano Zampini }
898c178816SStefano Zampini 
90d71ae5a4SJacob Faibussowitsch PetscErrorCode MatZeroRowsColumns_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b)
91d71ae5a4SJacob Faibussowitsch {
923f49a652SStefano Zampini   Mat_SeqDense      *l = (Mat_SeqDense *)A->data;
933f49a652SStefano Zampini   PetscInt           m = l->lda, n = A->cmap->n, r = A->rmap->n, i, j;
94ca15aa20SStefano Zampini   PetscScalar       *slot, *bb, *v;
953f49a652SStefano Zampini   const PetscScalar *xx;
963f49a652SStefano Zampini 
973f49a652SStefano Zampini   PetscFunctionBegin;
9876bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
993f49a652SStefano Zampini     for (i = 0; i < N; i++) {
10008401ef6SPierre Jolivet       PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed");
10108401ef6SPierre Jolivet       PetscCheck(rows[i] < A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Row %" PetscInt_FMT " requested to be zeroed greater than or equal number of rows %" PetscInt_FMT, rows[i], A->rmap->n);
10208401ef6SPierre Jolivet       PetscCheck(rows[i] < A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Col %" PetscInt_FMT " requested to be zeroed greater than or equal number of cols %" PetscInt_FMT, rows[i], A->cmap->n);
1033f49a652SStefano Zampini     }
10476bd3646SJed Brown   }
105ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
1063f49a652SStefano Zampini 
1073f49a652SStefano Zampini   /* fix right hand side if needed */
1083f49a652SStefano Zampini   if (x && b) {
1096c4d906cSStefano Zampini     Vec xt;
1106c4d906cSStefano Zampini 
11108401ef6SPierre Jolivet     PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices");
1129566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(x, &xt));
1139566063dSJacob Faibussowitsch     PetscCall(VecCopy(x, xt));
1149566063dSJacob Faibussowitsch     PetscCall(VecScale(xt, -1.0));
1159566063dSJacob Faibussowitsch     PetscCall(MatMultAdd(A, xt, b, b));
1169566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&xt));
1179566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(x, &xx));
1189566063dSJacob Faibussowitsch     PetscCall(VecGetArray(b, &bb));
1193f49a652SStefano Zampini     for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]];
1209566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(x, &xx));
1219566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(b, &bb));
1223f49a652SStefano Zampini   }
1233f49a652SStefano Zampini 
1249566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
1253f49a652SStefano Zampini   for (i = 0; i < N; i++) {
126ca15aa20SStefano Zampini     slot = v + rows[i] * m;
1279566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(slot, r));
1283f49a652SStefano Zampini   }
1293f49a652SStefano Zampini   for (i = 0; i < N; i++) {
130ca15aa20SStefano Zampini     slot = v + rows[i];
1319371c9d4SSatish Balay     for (j = 0; j < n; j++) {
1329371c9d4SSatish Balay       *slot = 0.0;
1339371c9d4SSatish Balay       slot += m;
1349371c9d4SSatish Balay     }
1353f49a652SStefano Zampini   }
1363f49a652SStefano Zampini   if (diag != 0.0) {
13708401ef6SPierre Jolivet     PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices");
1383f49a652SStefano Zampini     for (i = 0; i < N; i++) {
139ca15aa20SStefano Zampini       slot  = v + (m + 1) * rows[i];
1403f49a652SStefano Zampini       *slot = diag;
1413f49a652SStefano Zampini     }
1423f49a652SStefano Zampini   }
1439566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
1443f49a652SStefano Zampini   PetscFunctionReturn(0);
1453f49a652SStefano Zampini }
1463f49a652SStefano Zampini 
147d71ae5a4SJacob Faibussowitsch PetscErrorCode MatPtAPNumeric_SeqDense_SeqDense(Mat A, Mat P, Mat C)
148d71ae5a4SJacob Faibussowitsch {
149abc3b08eSStefano Zampini   Mat_SeqDense *c = (Mat_SeqDense *)(C->data);
150abc3b08eSStefano Zampini 
151abc3b08eSStefano Zampini   PetscFunctionBegin;
152ca15aa20SStefano Zampini   if (c->ptapwork) {
1539566063dSJacob Faibussowitsch     PetscCall((*C->ops->matmultnumeric)(A, P, c->ptapwork));
1549566063dSJacob Faibussowitsch     PetscCall((*C->ops->transposematmultnumeric)(P, c->ptapwork, C));
1554222ddf1SHong Zhang   } else SETERRQ(PetscObjectComm((PetscObject)C), PETSC_ERR_SUP, "Must call MatPtAPSymbolic_SeqDense_SeqDense() first");
156abc3b08eSStefano Zampini   PetscFunctionReturn(0);
157abc3b08eSStefano Zampini }
158abc3b08eSStefano Zampini 
159d71ae5a4SJacob Faibussowitsch PetscErrorCode MatPtAPSymbolic_SeqDense_SeqDense(Mat A, Mat P, PetscReal fill, Mat C)
160d71ae5a4SJacob Faibussowitsch {
161abc3b08eSStefano Zampini   Mat_SeqDense *c;
16247d993e7Ssuyashtn   PetscBool     cisdense = PETSC_FALSE;
163abc3b08eSStefano Zampini 
164abc3b08eSStefano Zampini   PetscFunctionBegin;
1659566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C, P->cmap->n, P->cmap->n, P->cmap->N, P->cmap->N));
16647d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA)
1679566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, ""));
16847d993e7Ssuyashtn #elif (PETSC_HAVE_HIP)
16947d993e7Ssuyashtn   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, ""));
17047d993e7Ssuyashtn #endif
17147d993e7Ssuyashtn 
1727a3c3d58SStefano Zampini   if (!cisdense) {
1737a3c3d58SStefano Zampini     PetscBool flg;
1747a3c3d58SStefano Zampini 
1759566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)P, ((PetscObject)A)->type_name, &flg));
1769566063dSJacob Faibussowitsch     PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE));
1777a3c3d58SStefano Zampini   }
1789566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
1794222ddf1SHong Zhang   c = (Mat_SeqDense *)C->data;
1809566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &c->ptapwork));
1819566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(c->ptapwork, A->rmap->n, P->cmap->n, A->rmap->N, P->cmap->N));
1829566063dSJacob Faibussowitsch   PetscCall(MatSetType(c->ptapwork, ((PetscObject)C)->type_name));
1839566063dSJacob Faibussowitsch   PetscCall(MatSetUp(c->ptapwork));
184abc3b08eSStefano Zampini   PetscFunctionReturn(0);
185abc3b08eSStefano Zampini }
186abc3b08eSStefano Zampini 
187d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat A, MatType newtype, MatReuse reuse, Mat *newmat)
188d71ae5a4SJacob Faibussowitsch {
189a13144ffSStefano Zampini   Mat              B = NULL;
190b49cda9fSStefano Zampini   Mat_SeqAIJ      *a = (Mat_SeqAIJ *)A->data;
191b49cda9fSStefano Zampini   Mat_SeqDense    *b;
192b49cda9fSStefano Zampini   PetscInt        *ai = a->i, *aj = a->j, m = A->rmap->N, n = A->cmap->N, i;
1932e5835c6SStefano Zampini   const MatScalar *av;
194a13144ffSStefano Zampini   PetscBool        isseqdense;
195b49cda9fSStefano Zampini 
196b49cda9fSStefano Zampini   PetscFunctionBegin;
197a13144ffSStefano Zampini   if (reuse == MAT_REUSE_MATRIX) {
1989566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)*newmat, MATSEQDENSE, &isseqdense));
19928b400f6SJacob Faibussowitsch     PetscCheck(isseqdense, PetscObjectComm((PetscObject)*newmat), PETSC_ERR_USER, "Cannot reuse matrix of type %s", ((PetscObject)(*newmat))->type_name);
200a13144ffSStefano Zampini   }
201a13144ffSStefano Zampini   if (reuse != MAT_REUSE_MATRIX) {
2029566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B));
2039566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(B, m, n, m, n));
2049566063dSJacob Faibussowitsch     PetscCall(MatSetType(B, MATSEQDENSE));
2059566063dSJacob Faibussowitsch     PetscCall(MatSeqDenseSetPreallocation(B, NULL));
206b49cda9fSStefano Zampini     b = (Mat_SeqDense *)(B->data);
207a13144ffSStefano Zampini   } else {
208a13144ffSStefano Zampini     b = (Mat_SeqDense *)((*newmat)->data);
2099566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(b->v, m * n));
210a13144ffSStefano Zampini   }
2119566063dSJacob Faibussowitsch   PetscCall(MatSeqAIJGetArrayRead(A, &av));
212b49cda9fSStefano Zampini   for (i = 0; i < m; i++) {
213b49cda9fSStefano Zampini     PetscInt j;
214b49cda9fSStefano Zampini     for (j = 0; j < ai[1] - ai[0]; j++) {
215b49cda9fSStefano Zampini       b->v[*aj * m + i] = *av;
216b49cda9fSStefano Zampini       aj++;
217b49cda9fSStefano Zampini       av++;
218b49cda9fSStefano Zampini     }
219b49cda9fSStefano Zampini     ai++;
220b49cda9fSStefano Zampini   }
2219566063dSJacob Faibussowitsch   PetscCall(MatSeqAIJRestoreArrayRead(A, &av));
222b49cda9fSStefano Zampini 
223511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
2249566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY));
2259566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY));
2269566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A, &B));
227b49cda9fSStefano Zampini   } else {
228a13144ffSStefano Zampini     if (B) *newmat = B;
2299566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(*newmat, MAT_FINAL_ASSEMBLY));
2309566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(*newmat, MAT_FINAL_ASSEMBLY));
231b49cda9fSStefano Zampini   }
232b49cda9fSStefano Zampini   PetscFunctionReturn(0);
233b49cda9fSStefano Zampini }
234b49cda9fSStefano Zampini 
235d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqDense_SeqAIJ(Mat A, MatType newtype, MatReuse reuse, Mat *newmat)
236d71ae5a4SJacob Faibussowitsch {
2376d4ec7b0SPierre Jolivet   Mat           B = NULL;
2386a63e612SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
2399399e1b8SMatthew G. Knepley   PetscInt      i, j;
2409399e1b8SMatthew G. Knepley   PetscInt     *rows, *nnz;
2419399e1b8SMatthew G. Knepley   MatScalar    *aa = a->v, *vals;
2426a63e612SBarry Smith 
2436a63e612SBarry Smith   PetscFunctionBegin;
2449566063dSJacob Faibussowitsch   PetscCall(PetscCalloc3(A->rmap->n, &rows, A->rmap->n, &nnz, A->rmap->n, &vals));
2456d4ec7b0SPierre Jolivet   if (reuse != MAT_REUSE_MATRIX) {
2469566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B));
2479566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(B, A->rmap->n, A->cmap->n, A->rmap->N, A->cmap->N));
2489566063dSJacob Faibussowitsch     PetscCall(MatSetType(B, MATSEQAIJ));
2499399e1b8SMatthew G. Knepley     for (j = 0; j < A->cmap->n; j++) {
2509371c9d4SSatish Balay       for (i = 0; i < A->rmap->n; i++)
2519371c9d4SSatish Balay         if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) ++nnz[i];
2526a63e612SBarry Smith       aa += a->lda;
2536a63e612SBarry Smith     }
2549566063dSJacob Faibussowitsch     PetscCall(MatSeqAIJSetPreallocation(B, PETSC_DETERMINE, nnz));
2556d4ec7b0SPierre Jolivet   } else B = *newmat;
2569399e1b8SMatthew G. Knepley   aa = a->v;
2579399e1b8SMatthew G. Knepley   for (j = 0; j < A->cmap->n; j++) {
2589399e1b8SMatthew G. Knepley     PetscInt numRows = 0;
2599371c9d4SSatish Balay     for (i = 0; i < A->rmap->n; i++)
2609371c9d4SSatish Balay       if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) {
2619371c9d4SSatish Balay         rows[numRows]   = i;
2629371c9d4SSatish Balay         vals[numRows++] = aa[i];
2639371c9d4SSatish Balay       }
2649566063dSJacob Faibussowitsch     PetscCall(MatSetValues(B, numRows, rows, 1, &j, vals, INSERT_VALUES));
2659399e1b8SMatthew G. Knepley     aa += a->lda;
2669399e1b8SMatthew G. Knepley   }
2679566063dSJacob Faibussowitsch   PetscCall(PetscFree3(rows, nnz, vals));
2689566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY));
2699566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY));
2706a63e612SBarry Smith 
271511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
2729566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A, &B));
2736d4ec7b0SPierre Jolivet   } else if (reuse != MAT_REUSE_MATRIX) *newmat = B;
2746a63e612SBarry Smith   PetscFunctionReturn(0);
2756a63e612SBarry Smith }
2766a63e612SBarry Smith 
277d71ae5a4SJacob Faibussowitsch PetscErrorCode MatAXPY_SeqDense(Mat Y, PetscScalar alpha, Mat X, MatStructure str)
278d71ae5a4SJacob Faibussowitsch {
2791987afe7SBarry Smith   Mat_SeqDense      *x = (Mat_SeqDense *)X->data, *y = (Mat_SeqDense *)Y->data;
280ca15aa20SStefano Zampini   const PetscScalar *xv;
281ca15aa20SStefano Zampini   PetscScalar       *yv;
28223fff9afSBarry Smith   PetscBLASInt       N, m, ldax = 0, lday = 0, one = 1;
2833a40ed3dSBarry Smith 
2843a40ed3dSBarry Smith   PetscFunctionBegin;
2859566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(X, &xv));
2869566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(Y, &yv));
2879566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(X->rmap->n * X->cmap->n, &N));
2889566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(X->rmap->n, &m));
2899566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(x->lda, &ldax));
2909566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(y->lda, &lday));
291a5ce6ee0Svictorle   if (ldax > m || lday > m) {
292ca15aa20SStefano Zampini     PetscInt j;
293ca15aa20SStefano Zampini 
29448a46eb9SPierre Jolivet     for (j = 0; j < X->cmap->n; j++) PetscCallBLAS("BLASaxpy", BLASaxpy_(&m, &alpha, xv + j * ldax, &one, yv + j * lday, &one));
295a5ce6ee0Svictorle   } else {
296792fecdfSBarry Smith     PetscCallBLAS("BLASaxpy", BLASaxpy_(&N, &alpha, xv, &one, yv, &one));
297a5ce6ee0Svictorle   }
2989566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(X, &xv));
2999566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(Y, &yv));
3009566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(PetscMax(2.0 * N - 1, 0)));
3013a40ed3dSBarry Smith   PetscFunctionReturn(0);
3021987afe7SBarry Smith }
3031987afe7SBarry Smith 
304d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetInfo_SeqDense(Mat A, MatInfoType flag, MatInfo *info)
305d71ae5a4SJacob Faibussowitsch {
306ca15aa20SStefano Zampini   PetscLogDouble N = A->rmap->n * A->cmap->n;
3073a40ed3dSBarry Smith 
3083a40ed3dSBarry Smith   PetscFunctionBegin;
3094e220ebcSLois Curfman McInnes   info->block_size        = 1.0;
310ca15aa20SStefano Zampini   info->nz_allocated      = N;
311ca15aa20SStefano Zampini   info->nz_used           = N;
312ca15aa20SStefano Zampini   info->nz_unneeded       = 0;
313ca15aa20SStefano Zampini   info->assemblies        = A->num_ass;
3144e220ebcSLois Curfman McInnes   info->mallocs           = 0;
3154dfa11a4SJacob Faibussowitsch   info->memory            = 0; /* REVIEW ME */
3164e220ebcSLois Curfman McInnes   info->fill_ratio_given  = 0;
3174e220ebcSLois Curfman McInnes   info->fill_ratio_needed = 0;
3184e220ebcSLois Curfman McInnes   info->factor_mallocs    = 0;
3193a40ed3dSBarry Smith   PetscFunctionReturn(0);
320289bc588SBarry Smith }
321289bc588SBarry Smith 
322d71ae5a4SJacob Faibussowitsch PetscErrorCode MatScale_SeqDense(Mat A, PetscScalar alpha)
323d71ae5a4SJacob Faibussowitsch {
324273d9f13SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
325ca15aa20SStefano Zampini   PetscScalar  *v;
32623fff9afSBarry Smith   PetscBLASInt  one = 1, j, nz, lda = 0;
32780cd9d93SLois Curfman McInnes 
3283a40ed3dSBarry Smith   PetscFunctionBegin;
3299566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
3309566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(a->lda, &lda));
331d0f46423SBarry Smith   if (lda > A->rmap->n) {
3329566063dSJacob Faibussowitsch     PetscCall(PetscBLASIntCast(A->rmap->n, &nz));
33348a46eb9SPierre Jolivet     for (j = 0; j < A->cmap->n; j++) PetscCallBLAS("BLASscal", BLASscal_(&nz, &alpha, v + j * lda, &one));
334a5ce6ee0Svictorle   } else {
3359566063dSJacob Faibussowitsch     PetscCall(PetscBLASIntCast(A->rmap->n * A->cmap->n, &nz));
336792fecdfSBarry Smith     PetscCallBLAS("BLASscal", BLASscal_(&nz, &alpha, v, &one));
337a5ce6ee0Svictorle   }
33804cbc005SJose E. Roman   PetscCall(PetscLogFlops(A->rmap->n * A->cmap->n));
3399566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
3403a40ed3dSBarry Smith   PetscFunctionReturn(0);
34180cd9d93SLois Curfman McInnes }
34280cd9d93SLois Curfman McInnes 
343d71ae5a4SJacob Faibussowitsch PetscErrorCode MatShift_SeqDense(Mat A, PetscScalar alpha)
344d71ae5a4SJacob Faibussowitsch {
3452f605a99SJose E. Roman   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
3462f605a99SJose E. Roman   PetscScalar  *v;
3472f605a99SJose E. Roman   PetscInt      j, k;
3482f605a99SJose E. Roman 
3492f605a99SJose E. Roman   PetscFunctionBegin;
3502f605a99SJose E. Roman   PetscCall(MatDenseGetArray(A, &v));
3512f605a99SJose E. Roman   k = PetscMin(A->rmap->n, A->cmap->n);
3522f605a99SJose E. Roman   for (j = 0; j < k; j++) v[j + j * a->lda] += alpha;
3532f605a99SJose E. Roman   PetscCall(PetscLogFlops(k));
3542f605a99SJose E. Roman   PetscCall(MatDenseRestoreArray(A, &v));
3552f605a99SJose E. Roman   PetscFunctionReturn(0);
3562f605a99SJose E. Roman }
3572f605a99SJose E. Roman 
358d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatIsHermitian_SeqDense(Mat A, PetscReal rtol, PetscBool *fl)
359d71ae5a4SJacob Faibussowitsch {
3601cbb95d3SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
361ca15aa20SStefano Zampini   PetscInt           i, j, m = A->rmap->n, N = a->lda;
362ca15aa20SStefano Zampini   const PetscScalar *v;
3631cbb95d3SBarry Smith 
3641cbb95d3SBarry Smith   PetscFunctionBegin;
3651cbb95d3SBarry Smith   *fl = PETSC_FALSE;
366d0f46423SBarry Smith   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
3679566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &v));
3681cbb95d3SBarry Smith   for (i = 0; i < m; i++) {
369ca15aa20SStefano Zampini     for (j = i; j < m; j++) {
370ad540459SPierre Jolivet       if (PetscAbsScalar(v[i + j * N] - PetscConj(v[j + i * N])) > rtol) goto restore;
3711cbb95d3SBarry Smith     }
372637a0070SStefano Zampini   }
3731cbb95d3SBarry Smith   *fl = PETSC_TRUE;
374637a0070SStefano Zampini restore:
3759566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &v));
376637a0070SStefano Zampini   PetscFunctionReturn(0);
377637a0070SStefano Zampini }
378637a0070SStefano Zampini 
379d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatIsSymmetric_SeqDense(Mat A, PetscReal rtol, PetscBool *fl)
380d71ae5a4SJacob Faibussowitsch {
381637a0070SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
382637a0070SStefano Zampini   PetscInt           i, j, m = A->rmap->n, N = a->lda;
383637a0070SStefano Zampini   const PetscScalar *v;
384637a0070SStefano Zampini 
385637a0070SStefano Zampini   PetscFunctionBegin;
386637a0070SStefano Zampini   *fl = PETSC_FALSE;
387637a0070SStefano Zampini   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
3889566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &v));
389637a0070SStefano Zampini   for (i = 0; i < m; i++) {
390637a0070SStefano Zampini     for (j = i; j < m; j++) {
391ad540459SPierre Jolivet       if (PetscAbsScalar(v[i + j * N] - v[j + i * N]) > rtol) goto restore;
392637a0070SStefano Zampini     }
393637a0070SStefano Zampini   }
394637a0070SStefano Zampini   *fl = PETSC_TRUE;
395637a0070SStefano Zampini restore:
3969566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &v));
3971cbb95d3SBarry Smith   PetscFunctionReturn(0);
3981cbb95d3SBarry Smith }
3991cbb95d3SBarry Smith 
400d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi, Mat A, MatDuplicateOption cpvalues)
401d71ae5a4SJacob Faibussowitsch {
402ca15aa20SStefano Zampini   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
40323fc5dcaSStefano Zampini   PetscInt      lda = (PetscInt)mat->lda, j, m, nlda = lda;
40475f6d85dSStefano Zampini   PetscBool     isdensecpu;
405b24902e0SBarry Smith 
406b24902e0SBarry Smith   PetscFunctionBegin;
4079566063dSJacob Faibussowitsch   PetscCall(PetscLayoutReference(A->rmap, &newi->rmap));
4089566063dSJacob Faibussowitsch   PetscCall(PetscLayoutReference(A->cmap, &newi->cmap));
40923fc5dcaSStefano Zampini   if (cpvalues == MAT_SHARE_NONZERO_PATTERN) { /* propagate LDA */
4109566063dSJacob Faibussowitsch     PetscCall(MatDenseSetLDA(newi, lda));
41123fc5dcaSStefano Zampini   }
4129566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)newi, MATSEQDENSE, &isdensecpu));
4139566063dSJacob Faibussowitsch   if (isdensecpu) PetscCall(MatSeqDenseSetPreallocation(newi, NULL));
414b24902e0SBarry Smith   if (cpvalues == MAT_COPY_VALUES) {
415ca15aa20SStefano Zampini     const PetscScalar *av;
416ca15aa20SStefano Zampini     PetscScalar       *v;
417ca15aa20SStefano Zampini 
4189566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A, &av));
4199566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayWrite(newi, &v));
4209566063dSJacob Faibussowitsch     PetscCall(MatDenseGetLDA(newi, &nlda));
421d0f46423SBarry Smith     m = A->rmap->n;
42223fc5dcaSStefano Zampini     if (lda > m || nlda > m) {
42348a46eb9SPierre Jolivet       for (j = 0; j < A->cmap->n; j++) PetscCall(PetscArraycpy(v + j * nlda, av + j * lda, m));
424b24902e0SBarry Smith     } else {
4259566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(v, av, A->rmap->n * A->cmap->n));
426b24902e0SBarry Smith     }
4279566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayWrite(newi, &v));
4289566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A, &av));
429b24902e0SBarry Smith   }
430b24902e0SBarry Smith   PetscFunctionReturn(0);
431b24902e0SBarry Smith }
432b24902e0SBarry Smith 
433d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDuplicate_SeqDense(Mat A, MatDuplicateOption cpvalues, Mat *newmat)
434d71ae5a4SJacob Faibussowitsch {
4353a40ed3dSBarry Smith   PetscFunctionBegin;
4369566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), newmat));
4379566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*newmat, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n));
4389566063dSJacob Faibussowitsch   PetscCall(MatSetType(*newmat, ((PetscObject)A)->type_name));
4399566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(*newmat, A, cpvalues));
440b24902e0SBarry Smith   PetscFunctionReturn(0);
441b24902e0SBarry Smith }
442b24902e0SBarry Smith 
443d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_LU(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T)
444d71ae5a4SJacob Faibussowitsch {
445c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
4464396437dSToby Isaac   PetscBLASInt  info;
44767e560aaSBarry Smith 
4483a40ed3dSBarry Smith   PetscFunctionBegin;
4499566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
450792fecdfSBarry Smith   PetscCallBLAS("LAPACKgetrs", LAPACKgetrs_(T ? "T" : "N", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info));
4519566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
45205fcb23eSStefano Zampini   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "GETRS - Bad solve %d", (int)info);
4539566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m)));
4544396437dSToby Isaac   PetscFunctionReturn(0);
4554396437dSToby Isaac }
4564396437dSToby Isaac 
4574396437dSToby Isaac static PetscErrorCode MatConjugate_SeqDense(Mat);
4584396437dSToby Isaac 
459d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_Cholesky(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T)
460d71ae5a4SJacob Faibussowitsch {
4614396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
4624396437dSToby Isaac   PetscBLASInt  info;
4634396437dSToby Isaac 
4644396437dSToby Isaac   PetscFunctionBegin;
465b94d7dedSBarry Smith   if (A->spd == PETSC_BOOL3_TRUE) {
4669566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A));
4679566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
468792fecdfSBarry Smith     PetscCallBLAS("LAPACKpotrs", LAPACKpotrs_("L", &m, &nrhs, mat->v, &mat->lda, x, &m, &info));
4699566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
47005fcb23eSStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "POTRS Bad solve %d", (int)info);
4719566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A));
472a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
473b94d7dedSBarry Smith   } else if (A->hermitian == PETSC_BOOL3_TRUE) {
4749566063dSJacob Faibussowitsch     if (T) PetscCall(MatConjugate_SeqDense(A));
4759566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
476792fecdfSBarry Smith     PetscCallBLAS("LAPACKhetrs", LAPACKhetrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info));
4779566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
47805fcb23eSStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "HETRS Bad solve %d", (int)info);
4799566063dSJacob Faibussowitsch     if (T) PetscCall(MatConjugate_SeqDense(A));
480a49dc2a2SStefano Zampini #endif
481a49dc2a2SStefano Zampini   } else { /* symmetric case */
4829566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
483792fecdfSBarry Smith     PetscCallBLAS("LAPACKsytrs", LAPACKsytrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info));
4849566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
48505fcb23eSStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "SYTRS Bad solve %d", (int)info);
486a49dc2a2SStefano Zampini   }
4879566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m)));
4884396437dSToby Isaac   PetscFunctionReturn(0);
4894396437dSToby Isaac }
49085e2c93fSHong Zhang 
491d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k)
492d71ae5a4SJacob Faibussowitsch {
4934396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
4944396437dSToby Isaac   PetscBLASInt  info;
4954396437dSToby Isaac   char          trans;
4964396437dSToby Isaac 
4974396437dSToby Isaac   PetscFunctionBegin;
4984905a7bcSToby Isaac   if (PetscDefined(USE_COMPLEX)) {
4994905a7bcSToby Isaac     trans = 'C';
5004905a7bcSToby Isaac   } else {
5014905a7bcSToby Isaac     trans = 'T';
5024905a7bcSToby Isaac   }
5039566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
50405fcb23eSStefano Zampini   { /* lwork depends on the number of right-hand sides */
50505fcb23eSStefano Zampini     PetscBLASInt nlfwork, lfwork = -1;
50605fcb23eSStefano Zampini     PetscScalar  fwork;
50705fcb23eSStefano Zampini 
508792fecdfSBarry Smith     PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info));
50905fcb23eSStefano Zampini     nlfwork = (PetscBLASInt)PetscRealPart(fwork);
51005fcb23eSStefano Zampini     if (nlfwork > mat->lfwork) {
51105fcb23eSStefano Zampini       mat->lfwork = nlfwork;
51205fcb23eSStefano Zampini       PetscCall(PetscFree(mat->fwork));
51305fcb23eSStefano Zampini       PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
51405fcb23eSStefano Zampini     }
51505fcb23eSStefano Zampini   }
516792fecdfSBarry Smith   PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info));
5179566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
51805fcb23eSStefano Zampini   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %d", (int)info);
5199566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
520792fecdfSBarry Smith   PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "N", "N", &mat->rank, &nrhs, mat->v, &mat->lda, x, &ldx, &info));
5219566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
52205fcb23eSStefano Zampini   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %d", (int)info);
5234905a7bcSToby Isaac   for (PetscInt j = 0; j < nrhs; j++) {
524ad540459SPierre Jolivet     for (PetscInt i = mat->rank; i < k; i++) x[j * ldx + i] = 0.;
5254905a7bcSToby Isaac   }
5269566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank))));
5274905a7bcSToby Isaac   PetscFunctionReturn(0);
5284905a7bcSToby Isaac }
5294905a7bcSToby Isaac 
530d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k)
531d71ae5a4SJacob Faibussowitsch {
5324396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
5334396437dSToby Isaac   PetscBLASInt  info;
5344396437dSToby Isaac 
5354396437dSToby Isaac   PetscFunctionBegin;
5364396437dSToby Isaac   if (A->rmap->n == A->cmap->n && mat->rank == A->rmap->n) {
5379566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
538792fecdfSBarry Smith     PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "T", "N", &m, &nrhs, mat->v, &mat->lda, x, &ldx, &info));
5399566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
54005fcb23eSStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %d", (int)info);
5419566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A));
54205fcb23eSStefano Zampini     { /* lwork depends on the number of right-hand sides */
54305fcb23eSStefano Zampini       PetscBLASInt nlfwork, lfwork = -1;
54405fcb23eSStefano Zampini       PetscScalar  fwork;
54505fcb23eSStefano Zampini 
546792fecdfSBarry Smith       PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info));
54705fcb23eSStefano Zampini       nlfwork = (PetscBLASInt)PetscRealPart(fwork);
54805fcb23eSStefano Zampini       if (nlfwork > mat->lfwork) {
54905fcb23eSStefano Zampini         mat->lfwork = nlfwork;
55005fcb23eSStefano Zampini         PetscCall(PetscFree(mat->fwork));
55105fcb23eSStefano Zampini         PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
55205fcb23eSStefano Zampini       }
55305fcb23eSStefano Zampini     }
5549566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
555792fecdfSBarry Smith     PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info));
5569566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
55705fcb23eSStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %d", (int)info);
5589566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A));
5594396437dSToby Isaac   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "QR factored matrix cannot be used for transpose solve");
5609566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank))));
5614396437dSToby Isaac   PetscFunctionReturn(0);
5624396437dSToby Isaac }
5634396437dSToby Isaac 
564d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_SetUp(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k)
565d71ae5a4SJacob Faibussowitsch {
5664396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
5674905a7bcSToby Isaac   PetscScalar  *y;
5684905a7bcSToby Isaac   PetscBLASInt  m = 0, k = 0;
5694905a7bcSToby Isaac 
5704905a7bcSToby Isaac   PetscFunctionBegin;
5719566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
5729566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &k));
5734905a7bcSToby Isaac   if (k < m) {
5749566063dSJacob Faibussowitsch     PetscCall(VecCopy(xx, mat->qrrhs));
5759566063dSJacob Faibussowitsch     PetscCall(VecGetArray(mat->qrrhs, &y));
5764905a7bcSToby Isaac   } else {
5779566063dSJacob Faibussowitsch     PetscCall(VecCopy(xx, yy));
5789566063dSJacob Faibussowitsch     PetscCall(VecGetArray(yy, &y));
5794905a7bcSToby Isaac   }
5804396437dSToby Isaac   *_y = y;
5814396437dSToby Isaac   *_k = k;
5824396437dSToby Isaac   *_m = m;
5834396437dSToby Isaac   PetscFunctionReturn(0);
5844396437dSToby Isaac }
5854396437dSToby Isaac 
586d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_TearDown(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k)
587d71ae5a4SJacob Faibussowitsch {
5884396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
58942e9364cSSatish Balay   PetscScalar  *y   = NULL;
5904396437dSToby Isaac   PetscBLASInt  m, k;
5914396437dSToby Isaac 
5924396437dSToby Isaac   PetscFunctionBegin;
5934396437dSToby Isaac   y   = *_y;
5944396437dSToby Isaac   *_y = NULL;
5954396437dSToby Isaac   k   = *_k;
5964396437dSToby Isaac   m   = *_m;
5974905a7bcSToby Isaac   if (k < m) {
5984905a7bcSToby Isaac     PetscScalar *yv;
5999566063dSJacob Faibussowitsch     PetscCall(VecGetArray(yy, &yv));
6009566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(yv, y, k));
6019566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(yy, &yv));
6029566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(mat->qrrhs, &y));
6034905a7bcSToby Isaac   } else {
6049566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(yy, &y));
6054905a7bcSToby Isaac   }
6064905a7bcSToby Isaac   PetscFunctionReturn(0);
6074905a7bcSToby Isaac }
6084905a7bcSToby Isaac 
609d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_LU(Mat A, Vec xx, Vec yy)
610d71ae5a4SJacob Faibussowitsch {
61142e9364cSSatish Balay   PetscScalar *y = NULL;
61242e9364cSSatish Balay   PetscBLASInt m = 0, k = 0;
6134396437dSToby Isaac 
6144396437dSToby Isaac   PetscFunctionBegin;
6159566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6169566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_FALSE));
6179566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6184396437dSToby Isaac   PetscFunctionReturn(0);
6194396437dSToby Isaac }
6204396437dSToby Isaac 
621d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_LU(Mat A, Vec xx, Vec yy)
622d71ae5a4SJacob Faibussowitsch {
62342e9364cSSatish Balay   PetscScalar *y = NULL;
62442e9364cSSatish Balay   PetscBLASInt m = 0, k = 0;
6254396437dSToby Isaac 
6264396437dSToby Isaac   PetscFunctionBegin;
6279566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6289566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_TRUE));
6299566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6304396437dSToby Isaac   PetscFunctionReturn(0);
6314396437dSToby Isaac }
6324396437dSToby Isaac 
633d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Cholesky(Mat A, Vec xx, Vec yy)
634d71ae5a4SJacob Faibussowitsch {
635e54beecaSStefano Zampini   PetscScalar *y = NULL;
636e54beecaSStefano Zampini   PetscBLASInt m = 0, k = 0;
6374396437dSToby Isaac 
6384396437dSToby Isaac   PetscFunctionBegin;
6399566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6409566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_FALSE));
6419566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6424396437dSToby Isaac   PetscFunctionReturn(0);
6434396437dSToby Isaac }
6444396437dSToby Isaac 
645d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_Cholesky(Mat A, Vec xx, Vec yy)
646d71ae5a4SJacob Faibussowitsch {
647e54beecaSStefano Zampini   PetscScalar *y = NULL;
648e54beecaSStefano Zampini   PetscBLASInt m = 0, k = 0;
6494396437dSToby Isaac 
6504396437dSToby Isaac   PetscFunctionBegin;
6519566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6529566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_TRUE));
6539566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6544396437dSToby Isaac   PetscFunctionReturn(0);
6554396437dSToby Isaac }
6564396437dSToby Isaac 
657d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_QR(Mat A, Vec xx, Vec yy)
658d71ae5a4SJacob Faibussowitsch {
659e54beecaSStefano Zampini   PetscScalar *y = NULL;
660e54beecaSStefano Zampini   PetscBLASInt m = 0, k = 0;
6614396437dSToby Isaac 
6624396437dSToby Isaac   PetscFunctionBegin;
6639566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6649566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k));
6659566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6664396437dSToby Isaac   PetscFunctionReturn(0);
6674396437dSToby Isaac }
6684396437dSToby Isaac 
669d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_QR(Mat A, Vec xx, Vec yy)
670d71ae5a4SJacob Faibussowitsch {
67142e9364cSSatish Balay   PetscScalar *y = NULL;
67242e9364cSSatish Balay   PetscBLASInt m = 0, k = 0;
6734396437dSToby Isaac 
6744396437dSToby Isaac   PetscFunctionBegin;
6759566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6769566063dSJacob Faibussowitsch   PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k));
6779566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6784396437dSToby Isaac   PetscFunctionReturn(0);
6794396437dSToby Isaac }
6804396437dSToby Isaac 
681d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_SetUp(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k)
682d71ae5a4SJacob Faibussowitsch {
6834905a7bcSToby Isaac   const PetscScalar *b;
6844396437dSToby Isaac   PetscScalar       *y;
685bf5a80bcSToby Isaac   PetscInt           n, _ldb, _ldx;
686bf5a80bcSToby Isaac   PetscBLASInt       nrhs = 0, m = 0, k = 0, ldb = 0, ldx = 0, ldy = 0;
6874905a7bcSToby Isaac 
6884905a7bcSToby Isaac   PetscFunctionBegin;
6899371c9d4SSatish Balay   *_ldy  = 0;
6909371c9d4SSatish Balay   *_m    = 0;
6919371c9d4SSatish Balay   *_nrhs = 0;
6929371c9d4SSatish Balay   *_k    = 0;
6939371c9d4SSatish Balay   *_y    = NULL;
6949566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
6959566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &k));
6969566063dSJacob Faibussowitsch   PetscCall(MatGetSize(B, NULL, &n));
6979566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(n, &nrhs));
6989566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(B, &_ldb));
6999566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldb, &ldb));
7009566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(X, &_ldx));
7019566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldx, &ldx));
702bf5a80bcSToby Isaac   if (ldx < m) {
7039566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(B, &b));
7049566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nrhs * m, &y));
705bf5a80bcSToby Isaac     if (ldb == m) {
7069566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(y, b, ldb * nrhs));
7074905a7bcSToby Isaac     } else {
70848a46eb9SPierre Jolivet       for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * m], &b[j * ldb], m));
7094905a7bcSToby Isaac     }
710bf5a80bcSToby Isaac     ldy = m;
7119566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(B, &b));
7124905a7bcSToby Isaac   } else {
713bf5a80bcSToby Isaac     if (ldb == ldx) {
7149566063dSJacob Faibussowitsch       PetscCall(MatCopy(B, X, SAME_NONZERO_PATTERN));
7159566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(X, &y));
7164905a7bcSToby Isaac     } else {
7179566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(X, &y));
7189566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArrayRead(B, &b));
71948a46eb9SPierre Jolivet       for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * ldx], &b[j * ldb], m));
7209566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArrayRead(B, &b));
7214905a7bcSToby Isaac     }
722bf5a80bcSToby Isaac     ldy = ldx;
7234905a7bcSToby Isaac   }
7244396437dSToby Isaac   *_y    = y;
725bf5a80bcSToby Isaac   *_ldy  = ldy;
7264396437dSToby Isaac   *_k    = k;
7274396437dSToby Isaac   *_m    = m;
7284396437dSToby Isaac   *_nrhs = nrhs;
7294396437dSToby Isaac   PetscFunctionReturn(0);
7304396437dSToby Isaac }
7314396437dSToby Isaac 
732d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_TearDown(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k)
733d71ae5a4SJacob Faibussowitsch {
7344396437dSToby Isaac   PetscScalar *y;
735bf5a80bcSToby Isaac   PetscInt     _ldx;
736bf5a80bcSToby Isaac   PetscBLASInt k, ldy, nrhs, ldx = 0;
7374396437dSToby Isaac 
7384396437dSToby Isaac   PetscFunctionBegin;
7394396437dSToby Isaac   y    = *_y;
7404396437dSToby Isaac   *_y  = NULL;
7414396437dSToby Isaac   k    = *_k;
742bf5a80bcSToby Isaac   ldy  = *_ldy;
7434396437dSToby Isaac   nrhs = *_nrhs;
7449566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(X, &_ldx));
7459566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldx, &ldx));
746bf5a80bcSToby Isaac   if (ldx != ldy) {
7474905a7bcSToby Isaac     PetscScalar *xv;
7489566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArray(X, &xv));
74948a46eb9SPierre Jolivet     for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&xv[j * ldx], &y[j * ldy], k));
7509566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(X, &xv));
7519566063dSJacob Faibussowitsch     PetscCall(PetscFree(y));
7524905a7bcSToby Isaac   } else {
7539566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(X, &y));
7544905a7bcSToby Isaac   }
75585e2c93fSHong Zhang   PetscFunctionReturn(0);
75685e2c93fSHong Zhang }
75785e2c93fSHong Zhang 
758d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_LU(Mat A, Mat B, Mat X)
759d71ae5a4SJacob Faibussowitsch {
7604396437dSToby Isaac   PetscScalar *y;
761bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7624396437dSToby Isaac 
7634396437dSToby Isaac   PetscFunctionBegin;
7649566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7659566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_FALSE));
7669566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7674396437dSToby Isaac   PetscFunctionReturn(0);
7684396437dSToby Isaac }
7694396437dSToby Isaac 
770d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_LU(Mat A, Mat B, Mat X)
771d71ae5a4SJacob Faibussowitsch {
7724396437dSToby Isaac   PetscScalar *y;
773bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7744396437dSToby Isaac 
7754396437dSToby Isaac   PetscFunctionBegin;
7769566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7779566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_TRUE));
7789566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7794396437dSToby Isaac   PetscFunctionReturn(0);
7804396437dSToby Isaac }
7814396437dSToby Isaac 
782d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_Cholesky(Mat A, Mat B, Mat X)
783d71ae5a4SJacob Faibussowitsch {
7844396437dSToby Isaac   PetscScalar *y;
785bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7864396437dSToby Isaac 
7874396437dSToby Isaac   PetscFunctionBegin;
7889566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7899566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_FALSE));
7909566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7914396437dSToby Isaac   PetscFunctionReturn(0);
7924396437dSToby Isaac }
7934396437dSToby Isaac 
794d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_Cholesky(Mat A, Mat B, Mat X)
795d71ae5a4SJacob Faibussowitsch {
7964396437dSToby Isaac   PetscScalar *y;
797bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7984396437dSToby Isaac 
7994396437dSToby Isaac   PetscFunctionBegin;
8009566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
8019566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_TRUE));
8029566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
8034396437dSToby Isaac   PetscFunctionReturn(0);
8044396437dSToby Isaac }
8054396437dSToby Isaac 
806d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_QR(Mat A, Mat B, Mat X)
807d71ae5a4SJacob Faibussowitsch {
8084396437dSToby Isaac   PetscScalar *y;
809bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
8104396437dSToby Isaac 
8114396437dSToby Isaac   PetscFunctionBegin;
8129566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
8139566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k));
8149566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
8154396437dSToby Isaac   PetscFunctionReturn(0);
8164396437dSToby Isaac }
8174396437dSToby Isaac 
818d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_QR(Mat A, Mat B, Mat X)
819d71ae5a4SJacob Faibussowitsch {
8204396437dSToby Isaac   PetscScalar *y;
821bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
8224396437dSToby Isaac 
8234396437dSToby Isaac   PetscFunctionBegin;
8249566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
8259566063dSJacob Faibussowitsch   PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k));
8269566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
8274396437dSToby Isaac   PetscFunctionReturn(0);
8284396437dSToby Isaac }
8294396437dSToby Isaac 
830db4efbfdSBarry Smith /* ---------------------------------------------------------------*/
831db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots,
832db4efbfdSBarry Smith    rather than put it in the Mat->row slot.*/
833d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLUFactor_SeqDense(Mat A, IS row, IS col, const MatFactorInfo *minfo)
834d71ae5a4SJacob Faibussowitsch {
835db4efbfdSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
836db4efbfdSBarry Smith   PetscBLASInt  n, m, info;
837db4efbfdSBarry Smith 
838db4efbfdSBarry Smith   PetscFunctionBegin;
8399566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
8409566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
8414dfa11a4SJacob Faibussowitsch   if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); }
842db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
8439566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
844792fecdfSBarry Smith   PetscCallBLAS("LAPACKgetrf", LAPACKgetrf_(&m, &n, mat->v, &mat->lda, mat->pivots, &info));
8459566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
8468e57ea43SSatish Balay 
84705fcb23eSStefano Zampini   PetscCheck(info >= 0, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to LU factorization %d", (int)info);
84805fcb23eSStefano Zampini   PetscCheck(info <= 0, PETSC_COMM_SELF, PETSC_ERR_MAT_LU_ZRPVT, "Bad LU factorization %d", (int)info);
8498208b9aeSStefano Zampini 
8504396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_LU;
8514396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_LU;
8524396437dSToby Isaac   A->ops->solvetranspose    = MatSolveTranspose_SeqDense_LU;
8534396437dSToby Isaac   A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_LU;
854d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_LU;
855db4efbfdSBarry Smith 
8569566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
8579566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype));
858f6224b95SHong Zhang 
8599566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops((2.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3));
860db4efbfdSBarry Smith   PetscFunctionReturn(0);
861db4efbfdSBarry Smith }
862db4efbfdSBarry Smith 
863d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy)
864d71ae5a4SJacob Faibussowitsch {
8654396437dSToby Isaac   MatFactorInfo info;
8664396437dSToby Isaac 
8674396437dSToby Isaac   PetscFunctionBegin;
8689566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES));
869dbbe0bcdSBarry Smith   PetscUseTypeMethod(fact, lufactor, NULL, NULL, &info);
8704396437dSToby Isaac   PetscFunctionReturn(0);
8714396437dSToby Isaac }
8724396437dSToby Isaac 
873d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, IS col, const MatFactorInfo *info)
874d71ae5a4SJacob Faibussowitsch {
8754396437dSToby Isaac   PetscFunctionBegin;
8764396437dSToby Isaac   fact->preallocated         = PETSC_TRUE;
8774396437dSToby Isaac   fact->assembled            = PETSC_TRUE;
8784396437dSToby Isaac   fact->ops->lufactornumeric = MatLUFactorNumeric_SeqDense;
8794396437dSToby Isaac   PetscFunctionReturn(0);
8804396437dSToby Isaac }
8814396437dSToby Isaac 
882a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */
883d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCholeskyFactor_SeqDense(Mat A, IS perm, const MatFactorInfo *factinfo)
884d71ae5a4SJacob Faibussowitsch {
885db4efbfdSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
886c5df96a5SBarry Smith   PetscBLASInt  info, n;
887db4efbfdSBarry Smith 
888db4efbfdSBarry Smith   PetscFunctionBegin;
8899566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
890db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
891b94d7dedSBarry Smith   if (A->spd == PETSC_BOOL3_TRUE) {
8929566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
893792fecdfSBarry Smith     PetscCallBLAS("LAPACKpotrf", LAPACKpotrf_("L", &n, mat->v, &mat->lda, &info));
8949566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
895a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
896b94d7dedSBarry Smith   } else if (A->hermitian == PETSC_BOOL3_TRUE) {
8974dfa11a4SJacob Faibussowitsch     if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); }
898a49dc2a2SStefano Zampini     if (!mat->fwork) {
899a49dc2a2SStefano Zampini       PetscScalar dummy;
900a49dc2a2SStefano Zampini 
901a49dc2a2SStefano Zampini       mat->lfwork = -1;
9029566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
903792fecdfSBarry Smith       PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info));
9049566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
905a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
9069566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
907a49dc2a2SStefano Zampini     }
9089566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
909792fecdfSBarry Smith     PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info));
9109566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
911a49dc2a2SStefano Zampini #endif
912a49dc2a2SStefano Zampini   } else { /* symmetric case */
9134dfa11a4SJacob Faibussowitsch     if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); }
914a49dc2a2SStefano Zampini     if (!mat->fwork) {
915a49dc2a2SStefano Zampini       PetscScalar dummy;
916a49dc2a2SStefano Zampini 
917a49dc2a2SStefano Zampini       mat->lfwork = -1;
9189566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
919792fecdfSBarry Smith       PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info));
9209566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
921a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
9229566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
923a49dc2a2SStefano Zampini     }
9249566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
925792fecdfSBarry Smith     PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info));
9269566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
927a49dc2a2SStefano Zampini   }
92828b400f6SJacob Faibussowitsch   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad factorization: zero pivot in row %" PetscInt_FMT, (PetscInt)info - 1);
9298208b9aeSStefano Zampini 
9304396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_Cholesky;
9314396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_Cholesky;
9324396437dSToby Isaac   A->ops->solvetranspose    = MatSolveTranspose_SeqDense_Cholesky;
9334396437dSToby Isaac   A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_Cholesky;
934d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_CHOLESKY;
9352205254eSKarl Rupp 
9369566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
9379566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype));
938f6224b95SHong Zhang 
9399566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0));
940db4efbfdSBarry Smith   PetscFunctionReturn(0);
941db4efbfdSBarry Smith }
942db4efbfdSBarry Smith 
943d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy)
944d71ae5a4SJacob Faibussowitsch {
945db4efbfdSBarry Smith   MatFactorInfo info;
946db4efbfdSBarry Smith 
947db4efbfdSBarry Smith   PetscFunctionBegin;
948db4efbfdSBarry Smith   info.fill = 1.0;
9492205254eSKarl Rupp 
9509566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES));
951dbbe0bcdSBarry Smith   PetscUseTypeMethod(fact, choleskyfactor, NULL, &info);
952db4efbfdSBarry Smith   PetscFunctionReturn(0);
953db4efbfdSBarry Smith }
954db4efbfdSBarry Smith 
955d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info)
956d71ae5a4SJacob Faibussowitsch {
957db4efbfdSBarry Smith   PetscFunctionBegin;
958c3ef05f6SHong Zhang   fact->assembled                  = PETSC_TRUE;
9591bbcc794SSatish Balay   fact->preallocated               = PETSC_TRUE;
960719d5645SBarry Smith   fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense;
961db4efbfdSBarry Smith   PetscFunctionReturn(0);
962db4efbfdSBarry Smith }
963db4efbfdSBarry Smith 
964d71ae5a4SJacob Faibussowitsch PetscErrorCode MatQRFactor_SeqDense(Mat A, IS col, const MatFactorInfo *minfo)
965d71ae5a4SJacob Faibussowitsch {
9664905a7bcSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
9674905a7bcSToby Isaac   PetscBLASInt  n, m, info, min, max;
9684905a7bcSToby Isaac 
9694905a7bcSToby Isaac   PetscFunctionBegin;
9709566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
9719566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
9724396437dSToby Isaac   max = PetscMax(m, n);
9734396437dSToby Isaac   min = PetscMin(m, n);
9744dfa11a4SJacob Faibussowitsch   if (!mat->tau) { PetscCall(PetscMalloc1(min, &mat->tau)); }
9754dfa11a4SJacob Faibussowitsch   if (!mat->pivots) { PetscCall(PetscMalloc1(n, &mat->pivots)); }
97648a46eb9SPierre Jolivet   if (!mat->qrrhs) PetscCall(MatCreateVecs(A, NULL, &(mat->qrrhs)));
9774905a7bcSToby Isaac   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
9784905a7bcSToby Isaac   if (!mat->fwork) {
9794905a7bcSToby Isaac     PetscScalar dummy;
9804905a7bcSToby Isaac 
9814905a7bcSToby Isaac     mat->lfwork = -1;
9829566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
983792fecdfSBarry Smith     PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, &dummy, &mat->lfwork, &info));
9849566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
9854905a7bcSToby Isaac     mat->lfwork = (PetscInt)PetscRealPart(dummy);
9869566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
9874905a7bcSToby Isaac   }
9889566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
989792fecdfSBarry Smith   PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, mat->fwork, &mat->lfwork, &info));
9909566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
99105fcb23eSStefano Zampini   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to QR factorization %d", (int)info);
9924905a7bcSToby Isaac   // TODO: try to estimate rank or test for and use geqp3 for rank revealing QR.  For now just say rank is min of m and n
9934905a7bcSToby Isaac   mat->rank = min;
9944905a7bcSToby Isaac 
9954396437dSToby Isaac   A->ops->solve    = MatSolve_SeqDense_QR;
9964396437dSToby Isaac   A->ops->matsolve = MatMatSolve_SeqDense_QR;
9974905a7bcSToby Isaac   A->factortype    = MAT_FACTOR_QR;
9984905a7bcSToby Isaac   if (m == n) {
9994396437dSToby Isaac     A->ops->solvetranspose    = MatSolveTranspose_SeqDense_QR;
10004396437dSToby Isaac     A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_QR;
10014905a7bcSToby Isaac   }
10024905a7bcSToby Isaac 
10039566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
10049566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype));
10054905a7bcSToby Isaac 
10069566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0 * min * min * (max - min / 3.0)));
10074905a7bcSToby Isaac   PetscFunctionReturn(0);
10084905a7bcSToby Isaac }
10094905a7bcSToby Isaac 
1010d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatQRFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy)
1011d71ae5a4SJacob Faibussowitsch {
10124905a7bcSToby Isaac   MatFactorInfo info;
10134905a7bcSToby Isaac 
10144905a7bcSToby Isaac   PetscFunctionBegin;
10154905a7bcSToby Isaac   info.fill = 1.0;
10164905a7bcSToby Isaac 
10179566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES));
1018cac4c232SBarry Smith   PetscUseMethod(fact, "MatQRFactor_C", (Mat, IS, const MatFactorInfo *), (fact, NULL, &info));
10194905a7bcSToby Isaac   PetscFunctionReturn(0);
10204905a7bcSToby Isaac }
10214905a7bcSToby Isaac 
1022d71ae5a4SJacob Faibussowitsch PetscErrorCode MatQRFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info)
1023d71ae5a4SJacob Faibussowitsch {
10244905a7bcSToby Isaac   PetscFunctionBegin;
10254905a7bcSToby Isaac   fact->assembled    = PETSC_TRUE;
10264905a7bcSToby Isaac   fact->preallocated = PETSC_TRUE;
10279566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)fact, "MatQRFactorNumeric_C", MatQRFactorNumeric_SeqDense));
10284905a7bcSToby Isaac   PetscFunctionReturn(0);
10294905a7bcSToby Isaac }
10304905a7bcSToby Isaac 
1031ca15aa20SStefano Zampini /* uses LAPACK */
1032d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A, MatFactorType ftype, Mat *fact)
1033d71ae5a4SJacob Faibussowitsch {
1034db4efbfdSBarry Smith   PetscFunctionBegin;
10359566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), fact));
10369566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*fact, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n));
10379566063dSJacob Faibussowitsch   PetscCall(MatSetType(*fact, MATDENSE));
103866e17bc3SBarry Smith   (*fact)->trivialsymbolic = PETSC_TRUE;
10392a350339SBarry Smith   if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU) {
1040db4efbfdSBarry Smith     (*fact)->ops->lufactorsymbolic  = MatLUFactorSymbolic_SeqDense;
10412a350339SBarry Smith     (*fact)->ops->ilufactorsymbolic = MatLUFactorSymbolic_SeqDense;
1042bf5a80bcSToby Isaac   } else if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) {
1043db4efbfdSBarry Smith     (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense;
1044bf5a80bcSToby Isaac   } else if (ftype == MAT_FACTOR_QR) {
10459566063dSJacob Faibussowitsch     PetscCall(PetscObjectComposeFunction((PetscObject)(*fact), "MatQRFactorSymbolic_C", MatQRFactorSymbolic_SeqDense));
1046db4efbfdSBarry Smith   }
1047d5f3da31SBarry Smith   (*fact)->factortype = ftype;
104800c67f3bSHong Zhang 
10499566063dSJacob Faibussowitsch   PetscCall(PetscFree((*fact)->solvertype));
10509566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC, &(*fact)->solvertype));
10519566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_LU]));
10529566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ILU]));
10539566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_CHOLESKY]));
10549566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ICC]));
1055db4efbfdSBarry Smith   PetscFunctionReturn(0);
1056db4efbfdSBarry Smith }
1057db4efbfdSBarry Smith 
1058289bc588SBarry Smith /* ------------------------------------------------------------------*/
1059d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSOR_SeqDense(Mat A, Vec bb, PetscReal omega, MatSORType flag, PetscReal shift, PetscInt its, PetscInt lits, Vec xx)
1060d71ae5a4SJacob Faibussowitsch {
1061c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1062d9ca1df4SBarry Smith   PetscScalar       *x, *v = mat->v, zero = 0.0, xt;
1063d9ca1df4SBarry Smith   const PetscScalar *b;
1064d0f46423SBarry Smith   PetscInt           m = A->rmap->n, i;
106523fff9afSBarry Smith   PetscBLASInt       o = 1, bm = 0;
1066289bc588SBarry Smith 
10673a40ed3dSBarry Smith   PetscFunctionBegin;
106847d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
106908401ef6SPierre Jolivet   PetscCheck(A->offloadmask != PETSC_OFFLOAD_GPU, PETSC_COMM_SELF, PETSC_ERR_SUP, "Not implemented");
1070ca15aa20SStefano Zampini #endif
1071422a814eSBarry Smith   if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */
10729566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(m, &bm));
1073289bc588SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
10743bffc371SBarry Smith     /* this is a hack fix, should have another version without the second BLASdotu */
10759566063dSJacob Faibussowitsch     PetscCall(VecSet(xx, zero));
1076289bc588SBarry Smith   }
10779566063dSJacob Faibussowitsch   PetscCall(VecGetArray(xx, &x));
10789566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(bb, &b));
1079b965ef7fSBarry Smith   its = its * lits;
108008401ef6SPierre Jolivet   PetscCheck(its > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Relaxation requires global its %" PetscInt_FMT " and local its %" PetscInt_FMT " both positive", its, lits);
1081289bc588SBarry Smith   while (its--) {
1082fccaa45eSBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
1083289bc588SBarry Smith       for (i = 0; i < m; i++) {
1084792fecdfSBarry Smith         PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o));
108555a1b374SBarry Smith         x[i] = (1. - omega) * x[i] + omega * (xt + v[i + i * m] * x[i]) / (v[i + i * m] + shift);
1086289bc588SBarry Smith       }
1087289bc588SBarry Smith     }
1088fccaa45eSBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
1089289bc588SBarry Smith       for (i = m - 1; i >= 0; i--) {
1090792fecdfSBarry Smith         PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o));
109155a1b374SBarry Smith         x[i] = (1. - omega) * x[i] + omega * (xt + v[i + i * m] * x[i]) / (v[i + i * m] + shift);
1092289bc588SBarry Smith       }
1093289bc588SBarry Smith     }
1094289bc588SBarry Smith   }
10959566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(bb, &b));
10969566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(xx, &x));
10973a40ed3dSBarry Smith   PetscFunctionReturn(0);
1098289bc588SBarry Smith }
1099289bc588SBarry Smith 
1100289bc588SBarry Smith /* -----------------------------------------------------------------*/
1101d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultTranspose_SeqDense(Mat A, Vec xx, Vec yy)
1102d71ae5a4SJacob Faibussowitsch {
1103c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1104d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v, *x;
1105d9ca1df4SBarry Smith   PetscScalar       *y;
11060805154bSBarry Smith   PetscBLASInt       m, n, _One = 1;
1107ea709b57SSatish Balay   PetscScalar        _DOne = 1.0, _DZero = 0.0;
11083a40ed3dSBarry Smith 
11093a40ed3dSBarry Smith   PetscFunctionBegin;
11109566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
11119566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
11129566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx, &x));
11139566063dSJacob Faibussowitsch   PetscCall(VecGetArrayWrite(yy, &y));
11145ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
11155ac36cfcSBarry Smith     PetscBLASInt i;
11165ac36cfcSBarry Smith     for (i = 0; i < n; i++) y[i] = 0.0;
11175ac36cfcSBarry Smith   } else {
1118792fecdfSBarry Smith     PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v, &mat->lda, x, &_One, &_DZero, y, &_One));
11199566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n - A->cmap->n));
11205ac36cfcSBarry Smith   }
11219566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx, &x));
11229566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayWrite(yy, &y));
11233a40ed3dSBarry Smith   PetscFunctionReturn(0);
1124289bc588SBarry Smith }
1125800995b7SMatthew Knepley 
1126d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMult_SeqDense(Mat A, Vec xx, Vec yy)
1127d71ae5a4SJacob Faibussowitsch {
1128c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1129d9ca1df4SBarry Smith   PetscScalar       *y, _DOne = 1.0, _DZero = 0.0;
11300805154bSBarry Smith   PetscBLASInt       m, n, _One             = 1;
1131d9ca1df4SBarry Smith   const PetscScalar *v = mat->v, *x;
11323a40ed3dSBarry Smith 
11333a40ed3dSBarry Smith   PetscFunctionBegin;
11349566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
11359566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
11369566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx, &x));
11379566063dSJacob Faibussowitsch   PetscCall(VecGetArrayWrite(yy, &y));
11385ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
11395ac36cfcSBarry Smith     PetscBLASInt i;
11405ac36cfcSBarry Smith     for (i = 0; i < m; i++) y[i] = 0.0;
11415ac36cfcSBarry Smith   } else {
1142792fecdfSBarry Smith     PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DZero, y, &_One));
11439566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n - A->rmap->n));
11445ac36cfcSBarry Smith   }
11459566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx, &x));
11469566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayWrite(yy, &y));
11473a40ed3dSBarry Smith   PetscFunctionReturn(0);
1148289bc588SBarry Smith }
11496ee01492SSatish Balay 
1150d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy)
1151d71ae5a4SJacob Faibussowitsch {
1152c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1153d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v, *x;
1154d9ca1df4SBarry Smith   PetscScalar       *y, _DOne = 1.0;
11550805154bSBarry Smith   PetscBLASInt       m, n, _One = 1;
11563a40ed3dSBarry Smith 
11573a40ed3dSBarry Smith   PetscFunctionBegin;
11589566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
11599566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
11609566063dSJacob Faibussowitsch   PetscCall(VecCopy(zz, yy));
1161d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
11629566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx, &x));
11639566063dSJacob Faibussowitsch   PetscCall(VecGetArray(yy, &y));
1164792fecdfSBarry Smith   PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DOne, y, &_One));
11659566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx, &x));
11669566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(yy, &y));
11679566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n));
11683a40ed3dSBarry Smith   PetscFunctionReturn(0);
1169289bc588SBarry Smith }
11706ee01492SSatish Balay 
1171d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy)
1172d71ae5a4SJacob Faibussowitsch {
1173c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1174d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v, *x;
1175d9ca1df4SBarry Smith   PetscScalar       *y;
11760805154bSBarry Smith   PetscBLASInt       m, n, _One = 1;
117787828ca2SBarry Smith   PetscScalar        _DOne = 1.0;
11783a40ed3dSBarry Smith 
11793a40ed3dSBarry Smith   PetscFunctionBegin;
11809566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
11819566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
11829566063dSJacob Faibussowitsch   PetscCall(VecCopy(zz, yy));
1183d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
11849566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx, &x));
11859566063dSJacob Faibussowitsch   PetscCall(VecGetArray(yy, &y));
1186792fecdfSBarry Smith   PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DOne, y, &_One));
11879566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx, &x));
11889566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(yy, &y));
11899566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n));
11903a40ed3dSBarry Smith   PetscFunctionReturn(0);
1191289bc588SBarry Smith }
1192289bc588SBarry Smith 
1193289bc588SBarry Smith /* -----------------------------------------------------------------*/
1194d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals)
1195d71ae5a4SJacob Faibussowitsch {
1196c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
119713f74950SBarry Smith   PetscInt      i;
119867e560aaSBarry Smith 
11993a40ed3dSBarry Smith   PetscFunctionBegin;
1200d0f46423SBarry Smith   *ncols = A->cmap->n;
1201289bc588SBarry Smith   if (cols) {
12029566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(A->cmap->n, cols));
1203d0f46423SBarry Smith     for (i = 0; i < A->cmap->n; i++) (*cols)[i] = i;
1204289bc588SBarry Smith   }
1205289bc588SBarry Smith   if (vals) {
1206ca15aa20SStefano Zampini     const PetscScalar *v;
1207ca15aa20SStefano Zampini 
12089566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A, &v));
12099566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(A->cmap->n, vals));
1210ca15aa20SStefano Zampini     v += row;
12119371c9d4SSatish Balay     for (i = 0; i < A->cmap->n; i++) {
12129371c9d4SSatish Balay       (*vals)[i] = *v;
12139371c9d4SSatish Balay       v += mat->lda;
12149371c9d4SSatish Balay     }
12159566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A, &v));
1216289bc588SBarry Smith   }
12173a40ed3dSBarry Smith   PetscFunctionReturn(0);
1218289bc588SBarry Smith }
12196ee01492SSatish Balay 
1220d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRestoreRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals)
1221d71ae5a4SJacob Faibussowitsch {
1222606d414cSSatish Balay   PetscFunctionBegin;
1223cb4a9cd9SHong Zhang   if (ncols) *ncols = 0;
12249566063dSJacob Faibussowitsch   if (cols) PetscCall(PetscFree(*cols));
12259566063dSJacob Faibussowitsch   if (vals) PetscCall(PetscFree(*vals));
12263a40ed3dSBarry Smith   PetscFunctionReturn(0);
1227289bc588SBarry Smith }
1228289bc588SBarry Smith /* ----------------------------------------------------------------*/
1229d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], const PetscScalar v[], InsertMode addv)
1230d71ae5a4SJacob Faibussowitsch {
1231c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
1232ca15aa20SStefano Zampini   PetscScalar  *av;
123313f74950SBarry Smith   PetscInt      i, j, idx = 0;
123447d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
1235c70f7ee4SJunchao Zhang   PetscOffloadMask oldf;
1236ca15aa20SStefano Zampini #endif
1237d6dfbf8fSBarry Smith 
12383a40ed3dSBarry Smith   PetscFunctionBegin;
12399566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &av));
1240289bc588SBarry Smith   if (!mat->roworiented) {
1241dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1242289bc588SBarry Smith       for (j = 0; j < n; j++) {
12439371c9d4SSatish Balay         if (indexn[j] < 0) {
12449371c9d4SSatish Balay           idx += m;
12459371c9d4SSatish Balay           continue;
12469371c9d4SSatish Balay         }
12476bdcaf15SBarry Smith         PetscCheck(indexn[j] < A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Column too large: col %" PetscInt_FMT " max %" PetscInt_FMT, indexn[j], A->cmap->n - 1);
1248289bc588SBarry Smith         for (i = 0; i < m; i++) {
12499371c9d4SSatish Balay           if (indexm[i] < 0) {
12509371c9d4SSatish Balay             idx++;
12519371c9d4SSatish Balay             continue;
12529371c9d4SSatish Balay           }
12536bdcaf15SBarry Smith           PetscCheck(indexm[i] < A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Row too large: row %" PetscInt_FMT " max %" PetscInt_FMT, indexm[i], A->rmap->n - 1);
1254ca15aa20SStefano Zampini           av[indexn[j] * mat->lda + indexm[i]] = v[idx++];
1255289bc588SBarry Smith         }
1256289bc588SBarry Smith       }
12573a40ed3dSBarry Smith     } else {
1258289bc588SBarry Smith       for (j = 0; j < n; j++) {
12599371c9d4SSatish Balay         if (indexn[j] < 0) {
12609371c9d4SSatish Balay           idx += m;
12619371c9d4SSatish Balay           continue;
12629371c9d4SSatish Balay         }
12636bdcaf15SBarry Smith         PetscCheck(indexn[j] < A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Column too large: col %" PetscInt_FMT " max %" PetscInt_FMT, indexn[j], A->cmap->n - 1);
1264289bc588SBarry Smith         for (i = 0; i < m; i++) {
12659371c9d4SSatish Balay           if (indexm[i] < 0) {
12669371c9d4SSatish Balay             idx++;
12679371c9d4SSatish Balay             continue;
12689371c9d4SSatish Balay           }
12696bdcaf15SBarry Smith           PetscCheck(indexm[i] < A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Row too large: row %" PetscInt_FMT " max %" PetscInt_FMT, indexm[i], A->rmap->n - 1);
1270ca15aa20SStefano Zampini           av[indexn[j] * mat->lda + indexm[i]] += v[idx++];
1271289bc588SBarry Smith         }
1272289bc588SBarry Smith       }
1273289bc588SBarry Smith     }
12743a40ed3dSBarry Smith   } else {
1275dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1276e8d4e0b9SBarry Smith       for (i = 0; i < m; i++) {
12779371c9d4SSatish Balay         if (indexm[i] < 0) {
12789371c9d4SSatish Balay           idx += n;
12799371c9d4SSatish Balay           continue;
12809371c9d4SSatish Balay         }
12816bdcaf15SBarry Smith         PetscCheck(indexm[i] < A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Row too large: row %" PetscInt_FMT " max %" PetscInt_FMT, indexm[i], A->rmap->n - 1);
1282e8d4e0b9SBarry Smith         for (j = 0; j < n; j++) {
12839371c9d4SSatish Balay           if (indexn[j] < 0) {
12849371c9d4SSatish Balay             idx++;
12859371c9d4SSatish Balay             continue;
12869371c9d4SSatish Balay           }
12876bdcaf15SBarry Smith           PetscCheck(indexn[j] < A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Column too large: col %" PetscInt_FMT " max %" PetscInt_FMT, indexn[j], A->cmap->n - 1);
1288ca15aa20SStefano Zampini           av[indexn[j] * mat->lda + indexm[i]] = v[idx++];
1289e8d4e0b9SBarry Smith         }
1290e8d4e0b9SBarry Smith       }
12913a40ed3dSBarry Smith     } else {
1292289bc588SBarry Smith       for (i = 0; i < m; i++) {
12939371c9d4SSatish Balay         if (indexm[i] < 0) {
12949371c9d4SSatish Balay           idx += n;
12959371c9d4SSatish Balay           continue;
12969371c9d4SSatish Balay         }
12976bdcaf15SBarry Smith         PetscCheck(indexm[i] < A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Row too large: row %" PetscInt_FMT " max %" PetscInt_FMT, indexm[i], A->rmap->n - 1);
1298289bc588SBarry Smith         for (j = 0; j < n; j++) {
12999371c9d4SSatish Balay           if (indexn[j] < 0) {
13009371c9d4SSatish Balay             idx++;
13019371c9d4SSatish Balay             continue;
13029371c9d4SSatish Balay           }
13036bdcaf15SBarry Smith           PetscCheck(indexn[j] < A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Column too large: col %" PetscInt_FMT " max %" PetscInt_FMT, indexn[j], A->cmap->n - 1);
1304ca15aa20SStefano Zampini           av[indexn[j] * mat->lda + indexm[i]] += v[idx++];
1305289bc588SBarry Smith         }
1306289bc588SBarry Smith       }
1307289bc588SBarry Smith     }
1308e8d4e0b9SBarry Smith   }
1309ca15aa20SStefano Zampini   /* hack to prevent unneeded copy to the GPU while returning the array */
131047d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
1311c70f7ee4SJunchao Zhang   oldf           = A->offloadmask;
1312c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_GPU;
1313ca15aa20SStefano Zampini #endif
13149566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &av));
131547d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
1316c70f7ee4SJunchao Zhang   A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU);
1317ca15aa20SStefano Zampini #endif
13183a40ed3dSBarry Smith   PetscFunctionReturn(0);
1319289bc588SBarry Smith }
1320e8d4e0b9SBarry Smith 
1321d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], PetscScalar v[])
1322d71ae5a4SJacob Faibussowitsch {
1323ae80bb75SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1324ca15aa20SStefano Zampini   const PetscScalar *vv;
132513f74950SBarry Smith   PetscInt           i, j;
1326ae80bb75SLois Curfman McInnes 
13273a40ed3dSBarry Smith   PetscFunctionBegin;
13289566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &vv));
1329ae80bb75SLois Curfman McInnes   /* row-oriented output */
1330ae80bb75SLois Curfman McInnes   for (i = 0; i < m; i++) {
13319371c9d4SSatish Balay     if (indexm[i] < 0) {
13329371c9d4SSatish Balay       v += n;
13339371c9d4SSatish Balay       continue;
13349371c9d4SSatish Balay     }
133508401ef6SPierre Jolivet     PetscCheck(indexm[i] < A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Row %" PetscInt_FMT " requested larger than number rows %" PetscInt_FMT, indexm[i], A->rmap->n);
1336ae80bb75SLois Curfman McInnes     for (j = 0; j < n; j++) {
13379371c9d4SSatish Balay       if (indexn[j] < 0) {
13389371c9d4SSatish Balay         v++;
13399371c9d4SSatish Balay         continue;
13409371c9d4SSatish Balay       }
134108401ef6SPierre Jolivet       PetscCheck(indexn[j] < A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Column %" PetscInt_FMT " requested larger than number columns %" PetscInt_FMT, indexn[j], A->cmap->n);
1342ca15aa20SStefano Zampini       *v++ = vv[indexn[j] * mat->lda + indexm[i]];
1343ae80bb75SLois Curfman McInnes     }
1344ae80bb75SLois Curfman McInnes   }
13459566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &vv));
13463a40ed3dSBarry Smith   PetscFunctionReturn(0);
1347ae80bb75SLois Curfman McInnes }
1348ae80bb75SLois Curfman McInnes 
1349289bc588SBarry Smith /* -----------------------------------------------------------------*/
1350289bc588SBarry Smith 
1351d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_Dense_Binary(Mat mat, PetscViewer viewer)
1352d71ae5a4SJacob Faibussowitsch {
13538491ab44SLisandro Dalcin   PetscBool          skipHeader;
13548491ab44SLisandro Dalcin   PetscViewerFormat  format;
13558491ab44SLisandro Dalcin   PetscInt           header[4], M, N, m, lda, i, j, k;
13568491ab44SLisandro Dalcin   const PetscScalar *v;
13578491ab44SLisandro Dalcin   PetscScalar       *vwork;
1358aabbc4fbSShri Abhyankar 
1359aabbc4fbSShri Abhyankar   PetscFunctionBegin;
13609566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
13619566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader));
13629566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
13638491ab44SLisandro Dalcin   if (skipHeader) format = PETSC_VIEWER_NATIVE;
1364aabbc4fbSShri Abhyankar 
13659566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat, &M, &N));
13668491ab44SLisandro Dalcin 
13678491ab44SLisandro Dalcin   /* write matrix header */
13689371c9d4SSatish Balay   header[0] = MAT_FILE_CLASSID;
13699371c9d4SSatish Balay   header[1] = M;
13709371c9d4SSatish Balay   header[2] = N;
13718491ab44SLisandro Dalcin   header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M * N;
13729566063dSJacob Faibussowitsch   if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer, header, 4, PETSC_INT));
13738491ab44SLisandro Dalcin 
13749566063dSJacob Faibussowitsch   PetscCall(MatGetLocalSize(mat, &m, NULL));
13758491ab44SLisandro Dalcin   if (format != PETSC_VIEWER_NATIVE) {
13768491ab44SLisandro Dalcin     PetscInt nnz = m * N, *iwork;
13778491ab44SLisandro Dalcin     /* store row lengths for each row */
13789566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nnz, &iwork));
13798491ab44SLisandro Dalcin     for (i = 0; i < m; i++) iwork[i] = N;
13809566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT));
13818491ab44SLisandro Dalcin     /* store column indices (zero start index) */
13828491ab44SLisandro Dalcin     for (k = 0, i = 0; i < m; i++)
13839371c9d4SSatish Balay       for (j = 0; j < N; j++, k++) iwork[k] = j;
13849566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT));
13859566063dSJacob Faibussowitsch     PetscCall(PetscFree(iwork));
13868491ab44SLisandro Dalcin   }
13878491ab44SLisandro Dalcin   /* store matrix values as a dense matrix in row major order */
13889566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(m * N, &vwork));
13899566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(mat, &v));
13909566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(mat, &lda));
13918491ab44SLisandro Dalcin   for (k = 0, i = 0; i < m; i++)
13929371c9d4SSatish Balay     for (j = 0; j < N; j++, k++) vwork[k] = v[i + lda * j];
13939566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(mat, &v));
13949566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryWriteAll(viewer, vwork, m * N, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR));
13959566063dSJacob Faibussowitsch   PetscCall(PetscFree(vwork));
13968491ab44SLisandro Dalcin   PetscFunctionReturn(0);
13978491ab44SLisandro Dalcin }
13988491ab44SLisandro Dalcin 
1399d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLoad_Dense_Binary(Mat mat, PetscViewer viewer)
1400d71ae5a4SJacob Faibussowitsch {
14018491ab44SLisandro Dalcin   PetscBool    skipHeader;
14028491ab44SLisandro Dalcin   PetscInt     header[4], M, N, m, nz, lda, i, j, k;
14038491ab44SLisandro Dalcin   PetscInt     rows, cols;
14048491ab44SLisandro Dalcin   PetscScalar *v, *vwork;
14058491ab44SLisandro Dalcin 
14068491ab44SLisandro Dalcin   PetscFunctionBegin;
14079566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
14089566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader));
14098491ab44SLisandro Dalcin 
14108491ab44SLisandro Dalcin   if (!skipHeader) {
14119566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryRead(viewer, header, 4, NULL, PETSC_INT));
141208401ef6SPierre Jolivet     PetscCheck(header[0] == MAT_FILE_CLASSID, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Not a matrix object in file");
14139371c9d4SSatish Balay     M = header[1];
14149371c9d4SSatish Balay     N = header[2];
141508401ef6SPierre Jolivet     PetscCheck(M >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix row size (%" PetscInt_FMT ") in file is negative", M);
141608401ef6SPierre Jolivet     PetscCheck(N >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix column size (%" PetscInt_FMT ") in file is negative", N);
14178491ab44SLisandro Dalcin     nz = header[3];
1418aed4548fSBarry Smith     PetscCheck(nz == MATRIX_BINARY_FORMAT_DENSE || nz >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Unknown matrix format %" PetscInt_FMT " in file", nz);
1419aabbc4fbSShri Abhyankar   } else {
14209566063dSJacob Faibussowitsch     PetscCall(MatGetSize(mat, &M, &N));
1421aed4548fSBarry Smith     PetscCheck(M >= 0 && N >= 0, PETSC_COMM_SELF, PETSC_ERR_USER, "Matrix binary file header was skipped, thus the user must specify the global sizes of input matrix");
14228491ab44SLisandro Dalcin     nz = MATRIX_BINARY_FORMAT_DENSE;
1423e6324fbbSBarry Smith   }
1424aabbc4fbSShri Abhyankar 
14258491ab44SLisandro Dalcin   /* setup global sizes if not set */
14268491ab44SLisandro Dalcin   if (mat->rmap->N < 0) mat->rmap->N = M;
14278491ab44SLisandro Dalcin   if (mat->cmap->N < 0) mat->cmap->N = N;
14289566063dSJacob Faibussowitsch   PetscCall(MatSetUp(mat));
14298491ab44SLisandro Dalcin   /* check if global sizes are correct */
14309566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat, &rows, &cols));
1431aed4548fSBarry Smith   PetscCheck(M == rows && N == cols, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix in file of different sizes (%" PetscInt_FMT ", %" PetscInt_FMT ") than the input matrix (%" PetscInt_FMT ", %" PetscInt_FMT ")", M, N, rows, cols);
1432aabbc4fbSShri Abhyankar 
14339566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat, NULL, &N));
14349566063dSJacob Faibussowitsch   PetscCall(MatGetLocalSize(mat, &m, NULL));
14359566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(mat, &v));
14369566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(mat, &lda));
14378491ab44SLisandro Dalcin   if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense format */
14388491ab44SLisandro Dalcin     PetscInt nnz = m * N;
14398491ab44SLisandro Dalcin     /* read in matrix values */
14409566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nnz, &vwork));
14419566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR));
14428491ab44SLisandro Dalcin     /* store values in column major order */
14438491ab44SLisandro Dalcin     for (j = 0; j < N; j++)
14449371c9d4SSatish Balay       for (i = 0; i < m; i++) v[i + lda * j] = vwork[i * N + j];
14459566063dSJacob Faibussowitsch     PetscCall(PetscFree(vwork));
14468491ab44SLisandro Dalcin   } else { /* matrix in file is sparse format */
14478491ab44SLisandro Dalcin     PetscInt nnz = 0, *rlens, *icols;
14488491ab44SLisandro Dalcin     /* read in row lengths */
14499566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(m, &rlens));
14509566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer, rlens, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT));
14518491ab44SLisandro Dalcin     for (i = 0; i < m; i++) nnz += rlens[i];
14528491ab44SLisandro Dalcin     /* read in column indices and values */
14539566063dSJacob Faibussowitsch     PetscCall(PetscMalloc2(nnz, &icols, nnz, &vwork));
14549566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer, icols, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT));
14559566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR));
14568491ab44SLisandro Dalcin     /* store values in column major order */
14578491ab44SLisandro Dalcin     for (k = 0, i = 0; i < m; i++)
14589371c9d4SSatish Balay       for (j = 0; j < rlens[i]; j++, k++) v[i + lda * icols[k]] = vwork[k];
14599566063dSJacob Faibussowitsch     PetscCall(PetscFree(rlens));
14609566063dSJacob Faibussowitsch     PetscCall(PetscFree2(icols, vwork));
1461aabbc4fbSShri Abhyankar   }
14629566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(mat, &v));
14639566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY));
14649566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY));
1465aabbc4fbSShri Abhyankar   PetscFunctionReturn(0);
1466aabbc4fbSShri Abhyankar }
1467aabbc4fbSShri Abhyankar 
1468d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer)
1469d71ae5a4SJacob Faibussowitsch {
1470eb91f321SVaclav Hapla   PetscBool isbinary, ishdf5;
1471eb91f321SVaclav Hapla 
1472eb91f321SVaclav Hapla   PetscFunctionBegin;
1473eb91f321SVaclav Hapla   PetscValidHeaderSpecific(newMat, MAT_CLASSID, 1);
1474eb91f321SVaclav Hapla   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
1475eb91f321SVaclav Hapla   /* force binary viewer to load .info file if it has not yet done so */
14769566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
14779566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
14789566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5));
1479eb91f321SVaclav Hapla   if (isbinary) {
14809566063dSJacob Faibussowitsch     PetscCall(MatLoad_Dense_Binary(newMat, viewer));
1481eb91f321SVaclav Hapla   } else if (ishdf5) {
1482eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5)
14839566063dSJacob Faibussowitsch     PetscCall(MatLoad_Dense_HDF5(newMat, viewer));
1484eb91f321SVaclav Hapla #else
1485eb91f321SVaclav Hapla     SETERRQ(PetscObjectComm((PetscObject)newMat), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5");
1486eb91f321SVaclav Hapla #endif
1487eb91f321SVaclav Hapla   } else {
148898921bdaSJacob Faibussowitsch     SETERRQ(PetscObjectComm((PetscObject)newMat), PETSC_ERR_SUP, "Viewer type %s not yet supported for reading %s matrices", ((PetscObject)viewer)->type_name, ((PetscObject)newMat)->type_name);
1489eb91f321SVaclav Hapla   }
1490eb91f321SVaclav Hapla   PetscFunctionReturn(0);
1491eb91f321SVaclav Hapla }
1492eb91f321SVaclav Hapla 
1493d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_ASCII(Mat A, PetscViewer viewer)
1494d71ae5a4SJacob Faibussowitsch {
1495932b0c3eSLois Curfman McInnes   Mat_SeqDense     *a = (Mat_SeqDense *)A->data;
149613f74950SBarry Smith   PetscInt          i, j;
14972dcb1b2aSMatthew Knepley   const char       *name;
1498ca15aa20SStefano Zampini   PetscScalar      *v, *av;
1499f3ef73ceSBarry Smith   PetscViewerFormat format;
15005f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX)
1501ace3abfcSBarry Smith   PetscBool allreal = PETSC_TRUE;
15025f481a85SSatish Balay #endif
1503932b0c3eSLois Curfman McInnes 
15043a40ed3dSBarry Smith   PetscFunctionBegin;
15059566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&av));
15069566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
1507456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
15083a40ed3dSBarry Smith     PetscFunctionReturn(0); /* do nothing for now */
1509fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
15109566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
1511d0f46423SBarry Smith     for (i = 0; i < A->rmap->n; i++) {
1512ca15aa20SStefano Zampini       v = av + i;
15139566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "row %" PetscInt_FMT ":", i));
1514d0f46423SBarry Smith       for (j = 0; j < A->cmap->n; j++) {
1515aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1516329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
15179566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g + %g i) ", j, (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v)));
1518329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
15199566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)PetscRealPart(*v)));
15206831982aSBarry Smith         }
152180cd9d93SLois Curfman McInnes #else
152248a46eb9SPierre Jolivet         if (*v) PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)*v));
152380cd9d93SLois Curfman McInnes #endif
15241b807ce4Svictorle         v += a->lda;
152580cd9d93SLois Curfman McInnes       }
15269566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
152780cd9d93SLois Curfman McInnes     }
15289566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
15293a40ed3dSBarry Smith   } else {
15309566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
1531aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
153247989497SBarry Smith     /* determine if matrix has all real values */
1533bcd8d3a4SJose E. Roman     for (j = 0; j < A->cmap->n; j++) {
1534bcd8d3a4SJose E. Roman       v = av + j * a->lda;
1535bcd8d3a4SJose E. Roman       for (i = 0; i < A->rmap->n; i++) {
15369371c9d4SSatish Balay         if (PetscImaginaryPart(v[i])) {
15379371c9d4SSatish Balay           allreal = PETSC_FALSE;
15389371c9d4SSatish Balay           break;
15399371c9d4SSatish Balay         }
154047989497SBarry Smith       }
1541bcd8d3a4SJose E. Roman     }
154247989497SBarry Smith #endif
1543fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
15449566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetName((PetscObject)A, &name));
15459566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%% Size = %" PetscInt_FMT " %" PetscInt_FMT " \n", A->rmap->n, A->cmap->n));
15469566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%s = zeros(%" PetscInt_FMT ",%" PetscInt_FMT ");\n", name, A->rmap->n, A->cmap->n));
15479566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%s = [\n", name));
1548ffac6cdbSBarry Smith     }
1549ffac6cdbSBarry Smith 
1550d0f46423SBarry Smith     for (i = 0; i < A->rmap->n; i++) {
1551ca15aa20SStefano Zampini       v = av + i;
1552d0f46423SBarry Smith       for (j = 0; j < A->cmap->n; j++) {
1553aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
155447989497SBarry Smith         if (allreal) {
15559566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)PetscRealPart(*v)));
155647989497SBarry Smith         } else {
15579566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e + %18.16ei ", (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v)));
155847989497SBarry Smith         }
1559289bc588SBarry Smith #else
15609566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)*v));
1561289bc588SBarry Smith #endif
15621b807ce4Svictorle         v += a->lda;
1563289bc588SBarry Smith       }
15649566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
1565289bc588SBarry Smith     }
156648a46eb9SPierre Jolivet     if (format == PETSC_VIEWER_ASCII_MATLAB) PetscCall(PetscViewerASCIIPrintf(viewer, "];\n"));
15679566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
1568da3a660dSBarry Smith   }
15699566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&av));
15709566063dSJacob Faibussowitsch   PetscCall(PetscViewerFlush(viewer));
15713a40ed3dSBarry Smith   PetscFunctionReturn(0);
1572289bc588SBarry Smith }
1573289bc588SBarry Smith 
15749804daf3SBarry Smith #include <petscdraw.h>
1575d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw, void *Aa)
1576d71ae5a4SJacob Faibussowitsch {
1577f1af5d2fSBarry Smith   Mat                A = (Mat)Aa;
1578383922c3SLisandro Dalcin   PetscInt           m = A->rmap->n, n = A->cmap->n, i, j;
1579383922c3SLisandro Dalcin   int                color = PETSC_DRAW_WHITE;
1580ca15aa20SStefano Zampini   const PetscScalar *v;
1581b0a32e0cSBarry Smith   PetscViewer        viewer;
1582b05fc000SLisandro Dalcin   PetscReal          xl, yl, xr, yr, x_l, x_r, y_l, y_r;
1583f3ef73ceSBarry Smith   PetscViewerFormat  format;
1584f1af5d2fSBarry Smith 
1585f1af5d2fSBarry Smith   PetscFunctionBegin;
15869566063dSJacob Faibussowitsch   PetscCall(PetscObjectQuery((PetscObject)A, "Zoomviewer", (PetscObject *)&viewer));
15879566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
15889566063dSJacob Faibussowitsch   PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr));
1589f1af5d2fSBarry Smith 
1590f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
15919566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &v));
1592fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
1593d0609cedSBarry Smith     PetscDrawCollectiveBegin(draw);
1594f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
1595f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
15969371c9d4SSatish Balay       x_l = j;
15979371c9d4SSatish Balay       x_r = x_l + 1.0;
1598f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1599f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1600f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1601ca15aa20SStefano Zampini         if (PetscRealPart(v[j * m + i]) > 0.) color = PETSC_DRAW_RED;
1602ca15aa20SStefano Zampini         else if (PetscRealPart(v[j * m + i]) < 0.) color = PETSC_DRAW_BLUE;
1603ca15aa20SStefano Zampini         else continue;
16049566063dSJacob Faibussowitsch         PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color));
1605f1af5d2fSBarry Smith       }
1606f1af5d2fSBarry Smith     }
1607d0609cedSBarry Smith     PetscDrawCollectiveEnd(draw);
1608f1af5d2fSBarry Smith   } else {
1609f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
1610f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
1611b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1612b05fc000SLisandro Dalcin     PetscDraw popup;
1613b05fc000SLisandro Dalcin 
1614f1af5d2fSBarry Smith     for (i = 0; i < m * n; i++) {
1615f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
1616f1af5d2fSBarry Smith     }
1617383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
16189566063dSJacob Faibussowitsch     PetscCall(PetscDrawGetPopup(draw, &popup));
16199566063dSJacob Faibussowitsch     PetscCall(PetscDrawScalePopup(popup, minv, maxv));
1620383922c3SLisandro Dalcin 
1621d0609cedSBarry Smith     PetscDrawCollectiveBegin(draw);
1622f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
1623f1af5d2fSBarry Smith       x_l = j;
1624f1af5d2fSBarry Smith       x_r = x_l + 1.0;
1625f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1626f1af5d2fSBarry Smith         y_l   = m - i - 1.0;
1627f1af5d2fSBarry Smith         y_r   = y_l + 1.0;
1628b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(v[j * m + i]), minv, maxv);
16299566063dSJacob Faibussowitsch         PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color));
1630f1af5d2fSBarry Smith       }
1631f1af5d2fSBarry Smith     }
1632d0609cedSBarry Smith     PetscDrawCollectiveEnd(draw);
1633f1af5d2fSBarry Smith   }
16349566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &v));
1635f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1636f1af5d2fSBarry Smith }
1637f1af5d2fSBarry Smith 
1638d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw(Mat A, PetscViewer viewer)
1639d71ae5a4SJacob Faibussowitsch {
1640b0a32e0cSBarry Smith   PetscDraw draw;
1641ace3abfcSBarry Smith   PetscBool isnull;
1642329f5518SBarry Smith   PetscReal xr, yr, xl, yl, h, w;
1643f1af5d2fSBarry Smith 
1644f1af5d2fSBarry Smith   PetscFunctionBegin;
16459566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
16469566063dSJacob Faibussowitsch   PetscCall(PetscDrawIsNull(draw, &isnull));
1647abc0a331SBarry Smith   if (isnull) PetscFunctionReturn(0);
1648f1af5d2fSBarry Smith 
16499371c9d4SSatish Balay   xr = A->cmap->n;
16509371c9d4SSatish Balay   yr = A->rmap->n;
16519371c9d4SSatish Balay   h  = yr / 10.0;
16529371c9d4SSatish Balay   w  = xr / 10.0;
16539371c9d4SSatish Balay   xr += w;
16549371c9d4SSatish Balay   yr += h;
16559371c9d4SSatish Balay   xl = -w;
16569371c9d4SSatish Balay   yl = -h;
16579566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetCoordinates(draw, xl, yl, xr, yr));
16589566063dSJacob Faibussowitsch   PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", (PetscObject)viewer));
16599566063dSJacob Faibussowitsch   PetscCall(PetscDrawZoom(draw, MatView_SeqDense_Draw_Zoom, A));
16609566063dSJacob Faibussowitsch   PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", NULL));
16619566063dSJacob Faibussowitsch   PetscCall(PetscDrawSave(draw));
1662f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1663f1af5d2fSBarry Smith }
1664f1af5d2fSBarry Smith 
1665d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_SeqDense(Mat A, PetscViewer viewer)
1666d71ae5a4SJacob Faibussowitsch {
1667ace3abfcSBarry Smith   PetscBool iascii, isbinary, isdraw;
1668932b0c3eSLois Curfman McInnes 
16693a40ed3dSBarry Smith   PetscFunctionBegin;
16709566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
16719566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
16729566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
16731baa6e33SBarry Smith   if (iascii) PetscCall(MatView_SeqDense_ASCII(A, viewer));
16741baa6e33SBarry Smith   else if (isbinary) PetscCall(MatView_Dense_Binary(A, viewer));
16751baa6e33SBarry Smith   else if (isdraw) PetscCall(MatView_SeqDense_Draw(A, viewer));
16763a40ed3dSBarry Smith   PetscFunctionReturn(0);
1677932b0c3eSLois Curfman McInnes }
1678289bc588SBarry Smith 
1679d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A, const PetscScalar *array)
1680d71ae5a4SJacob Faibussowitsch {
1681d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
1682d3042a70SBarry Smith 
1683d3042a70SBarry Smith   PetscFunctionBegin;
168428b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
168528b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
168628b400f6SJacob Faibussowitsch   PetscCheck(!a->unplacedarray, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreArray() first");
1687d3042a70SBarry Smith   a->unplacedarray       = a->v;
1688d3042a70SBarry Smith   a->unplaced_user_alloc = a->user_alloc;
1689d3042a70SBarry Smith   a->v                   = (PetscScalar *)array;
1690637a0070SStefano Zampini   a->user_alloc          = PETSC_TRUE;
169147d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
1692c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1693ca15aa20SStefano Zampini #endif
1694d3042a70SBarry Smith   PetscFunctionReturn(0);
1695d3042a70SBarry Smith }
1696d3042a70SBarry Smith 
1697d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseResetArray_SeqDense(Mat A)
1698d71ae5a4SJacob Faibussowitsch {
1699d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
1700d3042a70SBarry Smith 
1701d3042a70SBarry Smith   PetscFunctionBegin;
170228b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
170328b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
1704d3042a70SBarry Smith   a->v             = a->unplacedarray;
1705d3042a70SBarry Smith   a->user_alloc    = a->unplaced_user_alloc;
1706d3042a70SBarry Smith   a->unplacedarray = NULL;
170747d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
1708c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1709ca15aa20SStefano Zampini #endif
1710d3042a70SBarry Smith   PetscFunctionReturn(0);
1711d3042a70SBarry Smith }
1712d3042a70SBarry Smith 
1713d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A, const PetscScalar *array)
1714d71ae5a4SJacob Faibussowitsch {
1715d5ea218eSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
1716d5ea218eSStefano Zampini 
1717d5ea218eSStefano Zampini   PetscFunctionBegin;
171828b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
171928b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
17209566063dSJacob Faibussowitsch   if (!a->user_alloc) PetscCall(PetscFree(a->v));
1721d5ea218eSStefano Zampini   a->v          = (PetscScalar *)array;
1722d5ea218eSStefano Zampini   a->user_alloc = PETSC_FALSE;
172347d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
1724d5ea218eSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
1725d5ea218eSStefano Zampini #endif
1726d5ea218eSStefano Zampini   PetscFunctionReturn(0);
1727d5ea218eSStefano Zampini }
1728d5ea218eSStefano Zampini 
1729d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDestroy_SeqDense(Mat mat)
1730d71ae5a4SJacob Faibussowitsch {
1731ec8511deSBarry Smith   Mat_SeqDense *l = (Mat_SeqDense *)mat->data;
173290f02eecSBarry Smith 
17333a40ed3dSBarry Smith   PetscFunctionBegin;
1734aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1735c0aa6a63SJacob Faibussowitsch   PetscLogObjectState((PetscObject)mat, "Rows %" PetscInt_FMT " Cols %" PetscInt_FMT, mat->rmap->n, mat->cmap->n);
1736a5a9c739SBarry Smith #endif
17379566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(l->qrrhs)));
17389566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->tau));
17399566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->pivots));
17409566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->fwork));
17419566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&l->ptapwork));
17429566063dSJacob Faibussowitsch   if (!l->user_alloc) PetscCall(PetscFree(l->v));
17439566063dSJacob Faibussowitsch   if (!l->unplaced_user_alloc) PetscCall(PetscFree(l->unplacedarray));
174428b400f6SJacob Faibussowitsch   PetscCheck(!l->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
174528b400f6SJacob Faibussowitsch   PetscCheck(!l->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
17469566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&l->cvec));
17479566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&l->cmat));
17489566063dSJacob Faibussowitsch   PetscCall(PetscFree(mat->data));
1749dbd8c25aSHong Zhang 
17509566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)mat, NULL));
17519566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactor_C", NULL));
17522e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorSymbolic_C", NULL));
17532e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorNumeric_C", NULL));
17549566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetLDA_C", NULL));
17559566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseSetLDA_C", NULL));
17569566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArray_C", NULL));
17579566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArray_C", NULL));
17589566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDensePlaceArray_C", NULL));
17599566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseResetArray_C", NULL));
17609566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseReplaceArray_C", NULL));
17619566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayRead_C", NULL));
17629566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayRead_C", NULL));
17639566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayWrite_C", NULL));
17649566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayWrite_C", NULL));
17659566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqaij_C", NULL));
17668baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
17679566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_elemental_C", NULL));
17688baccfbdSHong Zhang #endif
1769d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
17709566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_scalapack_C", NULL));
1771d24d4204SJose E. Roman #endif
17722bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
17739566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensecuda_C", NULL));
17749566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", NULL));
17759566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdense_C", NULL));
17762e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensecuda_C", NULL));
17772bf066beSStefano Zampini #endif
177847d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP)
177947d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensehip_C", NULL));
178047d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensehip_seqdensehip_C", NULL));
178147d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensehip_seqdense_C", NULL));
178247d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensehip_C", NULL));
178347d993e7Ssuyashtn #endif
17849566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatSeqDenseSetPreallocation_C", NULL));
17859566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqaij_seqdense_C", NULL));
17869566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdense_C", NULL));
17879566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqbaij_seqdense_C", NULL));
17889566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqsbaij_seqdense_C", NULL));
178952c5f739Sprj- 
17909566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumn_C", NULL));
17919566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumn_C", NULL));
17929566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVec_C", NULL));
17939566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVec_C", NULL));
17949566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecRead_C", NULL));
17959566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecRead_C", NULL));
17969566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecWrite_C", NULL));
17979566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecWrite_C", NULL));
17989566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetSubMatrix_C", NULL));
17999566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreSubMatrix_C", NULL));
18003a40ed3dSBarry Smith   PetscFunctionReturn(0);
1801289bc588SBarry Smith }
1802289bc588SBarry Smith 
1803d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatTranspose_SeqDense(Mat A, MatReuse reuse, Mat *matout)
1804d71ae5a4SJacob Faibussowitsch {
1805c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
18066536e3caSStefano Zampini   PetscInt      k, j, m = A->rmap->n, M = mat->lda, n = A->cmap->n;
180787828ca2SBarry Smith   PetscScalar  *v, tmp;
180848b35521SBarry Smith 
18093a40ed3dSBarry Smith   PetscFunctionBegin;
18107fb60732SBarry Smith   if (reuse == MAT_REUSE_MATRIX) PetscCall(MatTransposeCheckNonzeroState_Private(A, *matout));
18116536e3caSStefano Zampini   if (reuse == MAT_INPLACE_MATRIX) {
18126536e3caSStefano Zampini     if (m == n) { /* in place transpose */
18139566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(A, &v));
1814d3e5ee88SLois Curfman McInnes       for (j = 0; j < m; j++) {
1815289bc588SBarry Smith         for (k = 0; k < j; k++) {
18161b807ce4Svictorle           tmp          = v[j + k * M];
18171b807ce4Svictorle           v[j + k * M] = v[k + j * M];
18181b807ce4Svictorle           v[k + j * M] = tmp;
1819289bc588SBarry Smith         }
1820289bc588SBarry Smith       }
18219566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArray(A, &v));
18226536e3caSStefano Zampini     } else { /* reuse memory, temporary allocates new memory */
18236536e3caSStefano Zampini       PetscScalar *v2;
18246536e3caSStefano Zampini       PetscLayout  tmplayout;
18256536e3caSStefano Zampini 
18269566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1((size_t)m * n, &v2));
18279566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(A, &v));
18286536e3caSStefano Zampini       for (j = 0; j < n; j++) {
18296536e3caSStefano Zampini         for (k = 0; k < m; k++) v2[j + (size_t)k * n] = v[k + (size_t)j * M];
18306536e3caSStefano Zampini       }
18319566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(v, v2, (size_t)m * n));
18329566063dSJacob Faibussowitsch       PetscCall(PetscFree(v2));
18339566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArray(A, &v));
18346536e3caSStefano Zampini       /* cleanup size dependent quantities */
18359566063dSJacob Faibussowitsch       PetscCall(VecDestroy(&mat->cvec));
18369566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&mat->cmat));
18379566063dSJacob Faibussowitsch       PetscCall(PetscFree(mat->pivots));
18389566063dSJacob Faibussowitsch       PetscCall(PetscFree(mat->fwork));
18399566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&mat->ptapwork));
18406536e3caSStefano Zampini       /* swap row/col layouts */
18416536e3caSStefano Zampini       mat->lda  = n;
18426536e3caSStefano Zampini       tmplayout = A->rmap;
18436536e3caSStefano Zampini       A->rmap   = A->cmap;
18446536e3caSStefano Zampini       A->cmap   = tmplayout;
18456536e3caSStefano Zampini     }
18463a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1847d3e5ee88SLois Curfman McInnes     Mat           tmat;
1848ec8511deSBarry Smith     Mat_SeqDense *tmatd;
184987828ca2SBarry Smith     PetscScalar  *v2;
1850af36a384SStefano Zampini     PetscInt      M2;
1851ea709b57SSatish Balay 
18526536e3caSStefano Zampini     if (reuse == MAT_INITIAL_MATRIX) {
18539566063dSJacob Faibussowitsch       PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &tmat));
18549566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(tmat, A->cmap->n, A->rmap->n, A->cmap->n, A->rmap->n));
18559566063dSJacob Faibussowitsch       PetscCall(MatSetType(tmat, ((PetscObject)A)->type_name));
18569566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSetPreallocation(tmat, NULL));
1857ca15aa20SStefano Zampini     } else tmat = *matout;
1858ca15aa20SStefano Zampini 
18599566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&v));
18609566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArray(tmat, &v2));
1861ec8511deSBarry Smith     tmatd = (Mat_SeqDense *)tmat->data;
1862ca15aa20SStefano Zampini     M2    = tmatd->lda;
1863d3e5ee88SLois Curfman McInnes     for (j = 0; j < n; j++) {
1864af36a384SStefano Zampini       for (k = 0; k < m; k++) v2[j + k * M2] = v[k + j * M];
1865d3e5ee88SLois Curfman McInnes     }
18669566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(tmat, &v2));
18679566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&v));
18689566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(tmat, MAT_FINAL_ASSEMBLY));
18699566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(tmat, MAT_FINAL_ASSEMBLY));
18706536e3caSStefano Zampini     *matout = tmat;
187148b35521SBarry Smith   }
18723a40ed3dSBarry Smith   PetscFunctionReturn(0);
1873289bc588SBarry Smith }
1874289bc588SBarry Smith 
1875d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatEqual_SeqDense(Mat A1, Mat A2, PetscBool *flg)
1876d71ae5a4SJacob Faibussowitsch {
1877c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat1 = (Mat_SeqDense *)A1->data;
1878c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat2 = (Mat_SeqDense *)A2->data;
1879ca15aa20SStefano Zampini   PetscInt           i;
1880ca15aa20SStefano Zampini   const PetscScalar *v1, *v2;
18819ea5d5aeSSatish Balay 
18823a40ed3dSBarry Smith   PetscFunctionBegin;
18839371c9d4SSatish Balay   if (A1->rmap->n != A2->rmap->n) {
18849371c9d4SSatish Balay     *flg = PETSC_FALSE;
18859371c9d4SSatish Balay     PetscFunctionReturn(0);
18869371c9d4SSatish Balay   }
18879371c9d4SSatish Balay   if (A1->cmap->n != A2->cmap->n) {
18889371c9d4SSatish Balay     *flg = PETSC_FALSE;
18899371c9d4SSatish Balay     PetscFunctionReturn(0);
18909371c9d4SSatish Balay   }
18919566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A1, &v1));
18929566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A2, &v2));
1893ca15aa20SStefano Zampini   for (i = 0; i < A1->cmap->n; i++) {
18949566063dSJacob Faibussowitsch     PetscCall(PetscArraycmp(v1, v2, A1->rmap->n, flg));
1895ca15aa20SStefano Zampini     if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
1896ca15aa20SStefano Zampini     v1 += mat1->lda;
1897ca15aa20SStefano Zampini     v2 += mat2->lda;
18981b807ce4Svictorle   }
18999566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A1, &v1));
19009566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A2, &v2));
190177c4ece6SBarry Smith   *flg = PETSC_TRUE;
19023a40ed3dSBarry Smith   PetscFunctionReturn(0);
1903289bc588SBarry Smith }
1904289bc588SBarry Smith 
1905d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetDiagonal_SeqDense(Mat A, Vec v)
1906d71ae5a4SJacob Faibussowitsch {
1907c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
190813f74950SBarry Smith   PetscInt           i, n, len;
1909ca15aa20SStefano Zampini   PetscScalar       *x;
1910ca15aa20SStefano Zampini   const PetscScalar *vv;
191144cd7ae7SLois Curfman McInnes 
19123a40ed3dSBarry Smith   PetscFunctionBegin;
19139566063dSJacob Faibussowitsch   PetscCall(VecGetSize(v, &n));
19149566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
1915d0f46423SBarry Smith   len = PetscMin(A->rmap->n, A->cmap->n);
19169566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &vv));
191708401ef6SPierre Jolivet   PetscCheck(n == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming mat and vec");
1918ad540459SPierre Jolivet   for (i = 0; i < len; i++) x[i] = vv[i * mat->lda + i];
19199566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &vv));
19209566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
19213a40ed3dSBarry Smith   PetscFunctionReturn(0);
1922289bc588SBarry Smith }
1923289bc588SBarry Smith 
1924d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDiagonalScale_SeqDense(Mat A, Vec ll, Vec rr)
1925d71ae5a4SJacob Faibussowitsch {
1926c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1927f1ceaac6SMatthew G. Knepley   const PetscScalar *l, *r;
1928ca15aa20SStefano Zampini   PetscScalar        x, *v, *vv;
1929d0f46423SBarry Smith   PetscInt           i, j, m = A->rmap->n, n = A->cmap->n;
193055659b69SBarry Smith 
19313a40ed3dSBarry Smith   PetscFunctionBegin;
19329566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &vv));
193328988994SBarry Smith   if (ll) {
19349566063dSJacob Faibussowitsch     PetscCall(VecGetSize(ll, &m));
19359566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ll, &l));
193608401ef6SPierre Jolivet     PetscCheck(m == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Left scaling vec wrong size");
1937da3a660dSBarry Smith     for (i = 0; i < m; i++) {
1938da3a660dSBarry Smith       x = l[i];
1939ca15aa20SStefano Zampini       v = vv + i;
19409371c9d4SSatish Balay       for (j = 0; j < n; j++) {
19419371c9d4SSatish Balay         (*v) *= x;
19429371c9d4SSatish Balay         v += mat->lda;
19439371c9d4SSatish Balay       }
1944da3a660dSBarry Smith     }
19459566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ll, &l));
19469566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0 * n * m));
1947da3a660dSBarry Smith   }
194828988994SBarry Smith   if (rr) {
19499566063dSJacob Faibussowitsch     PetscCall(VecGetSize(rr, &n));
19509566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(rr, &r));
195108401ef6SPierre Jolivet     PetscCheck(n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Right scaling vec wrong size");
1952da3a660dSBarry Smith     for (i = 0; i < n; i++) {
1953da3a660dSBarry Smith       x = r[i];
1954ca15aa20SStefano Zampini       v = vv + i * mat->lda;
19552205254eSKarl Rupp       for (j = 0; j < m; j++) (*v++) *= x;
1956da3a660dSBarry Smith     }
19579566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(rr, &r));
19589566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0 * n * m));
1959da3a660dSBarry Smith   }
19609566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &vv));
19613a40ed3dSBarry Smith   PetscFunctionReturn(0);
1962289bc588SBarry Smith }
1963289bc588SBarry Smith 
1964d71ae5a4SJacob Faibussowitsch PetscErrorCode MatNorm_SeqDense(Mat A, NormType type, PetscReal *nrm)
1965d71ae5a4SJacob Faibussowitsch {
1966c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
1967ca15aa20SStefano Zampini   PetscScalar  *v, *vv;
1968329f5518SBarry Smith   PetscReal     sum = 0.0;
196975f6d85dSStefano Zampini   PetscInt      lda, m = A->rmap->n, i, j;
197055659b69SBarry Smith 
19713a40ed3dSBarry Smith   PetscFunctionBegin;
19729566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&vv));
19739566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(A, &lda));
1974ca15aa20SStefano Zampini   v = vv;
1975289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1976a5ce6ee0Svictorle     if (lda > m) {
1977d0f46423SBarry Smith       for (j = 0; j < A->cmap->n; j++) {
1978ca15aa20SStefano Zampini         v = vv + j * lda;
1979a5ce6ee0Svictorle         for (i = 0; i < m; i++) {
19809371c9d4SSatish Balay           sum += PetscRealPart(PetscConj(*v) * (*v));
19819371c9d4SSatish Balay           v++;
1982a5ce6ee0Svictorle         }
1983a5ce6ee0Svictorle       }
1984a5ce6ee0Svictorle     } else {
1985570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1986570b7f6dSBarry Smith       PetscBLASInt one = 1, cnt = A->cmap->n * A->rmap->n;
1987792fecdfSBarry Smith       PetscCallBLAS("BLASnrm2", *nrm = BLASnrm2_(&cnt, v, &one));
1988570b7f6dSBarry Smith     }
1989570b7f6dSBarry Smith #else
1990d0f46423SBarry Smith       for (i = 0; i < A->cmap->n * A->rmap->n; i++) {
19919371c9d4SSatish Balay         sum += PetscRealPart(PetscConj(*v) * (*v));
19929371c9d4SSatish Balay         v++;
1993289bc588SBarry Smith       }
1994a5ce6ee0Svictorle     }
19958f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1996570b7f6dSBarry Smith #endif
19979566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0 * A->cmap->n * A->rmap->n));
19983a40ed3dSBarry Smith   } else if (type == NORM_1) {
1999064f8208SBarry Smith     *nrm = 0.0;
2000d0f46423SBarry Smith     for (j = 0; j < A->cmap->n; j++) {
2001ca15aa20SStefano Zampini       v   = vv + j * mat->lda;
2002289bc588SBarry Smith       sum = 0.0;
2003d0f46423SBarry Smith       for (i = 0; i < A->rmap->n; i++) {
20049371c9d4SSatish Balay         sum += PetscAbsScalar(*v);
20059371c9d4SSatish Balay         v++;
2006289bc588SBarry Smith       }
2007064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
2008289bc588SBarry Smith     }
20099566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n));
20103a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
2011064f8208SBarry Smith     *nrm = 0.0;
2012d0f46423SBarry Smith     for (j = 0; j < A->rmap->n; j++) {
2013ca15aa20SStefano Zampini       v   = vv + j;
2014289bc588SBarry Smith       sum = 0.0;
2015d0f46423SBarry Smith       for (i = 0; i < A->cmap->n; i++) {
20169371c9d4SSatish Balay         sum += PetscAbsScalar(*v);
20179371c9d4SSatish Balay         v += mat->lda;
2018289bc588SBarry Smith       }
2019064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
2020289bc588SBarry Smith     }
20219566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n));
2022e7e72b3dSBarry Smith   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "No two norm");
20239566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&vv));
20243a40ed3dSBarry Smith   PetscFunctionReturn(0);
2025289bc588SBarry Smith }
2026289bc588SBarry Smith 
2027d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetOption_SeqDense(Mat A, MatOption op, PetscBool flg)
2028d71ae5a4SJacob Faibussowitsch {
2029c0bbcb79SLois Curfman McInnes   Mat_SeqDense *aij = (Mat_SeqDense *)A->data;
203067e560aaSBarry Smith 
20313a40ed3dSBarry Smith   PetscFunctionBegin;
2032b5a2b587SKris Buschelman   switch (op) {
2033d71ae5a4SJacob Faibussowitsch   case MAT_ROW_ORIENTED:
2034d71ae5a4SJacob Faibussowitsch     aij->roworiented = flg;
2035d71ae5a4SJacob Faibussowitsch     break;
2036512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
2037b5a2b587SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
20383971808eSMatthew Knepley   case MAT_NEW_NONZERO_ALLOCATION_ERR:
20398c78258cSHong Zhang   case MAT_FORCE_DIAGONAL_ENTRIES:
204013fa8e87SLisandro Dalcin   case MAT_KEEP_NONZERO_PATTERN:
2041b5a2b587SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
2042b5a2b587SKris Buschelman   case MAT_USE_HASH_TABLE:
20430f8fb01aSBarry Smith   case MAT_IGNORE_ZERO_ENTRIES:
20445021d80fSJed Brown   case MAT_IGNORE_LOWER_TRIANGULAR:
2045d71ae5a4SJacob Faibussowitsch   case MAT_SORTED_FULL:
2046d71ae5a4SJacob Faibussowitsch     PetscCall(PetscInfo(A, "Option %s ignored\n", MatOptions[op]));
2047d71ae5a4SJacob Faibussowitsch     break;
20485021d80fSJed Brown   case MAT_SPD:
204977e54ba9SKris Buschelman   case MAT_SYMMETRIC:
205077e54ba9SKris Buschelman   case MAT_STRUCTURALLY_SYMMETRIC:
20519a4540c5SBarry Smith   case MAT_HERMITIAN:
20529a4540c5SBarry Smith   case MAT_SYMMETRY_ETERNAL:
2053b94d7dedSBarry Smith   case MAT_STRUCTURAL_SYMMETRY_ETERNAL:
2054d71ae5a4SJacob Faibussowitsch   case MAT_SPD_ETERNAL:
2055d71ae5a4SJacob Faibussowitsch     break;
2056d71ae5a4SJacob Faibussowitsch   default:
2057d71ae5a4SJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "unknown option %s", MatOptions[op]);
20583a40ed3dSBarry Smith   }
20593a40ed3dSBarry Smith   PetscFunctionReturn(0);
2060289bc588SBarry Smith }
2061289bc588SBarry Smith 
2062d71ae5a4SJacob Faibussowitsch PetscErrorCode MatZeroEntries_SeqDense(Mat A)
2063d71ae5a4SJacob Faibussowitsch {
2064ec8511deSBarry Smith   Mat_SeqDense *l   = (Mat_SeqDense *)A->data;
20653d8925e7SStefano Zampini   PetscInt      lda = l->lda, m = A->rmap->n, n = A->cmap->n, j;
2066ca15aa20SStefano Zampini   PetscScalar  *v;
20673a40ed3dSBarry Smith 
20683a40ed3dSBarry Smith   PetscFunctionBegin;
20699566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(A, &v));
2070a5ce6ee0Svictorle   if (lda > m) {
207148a46eb9SPierre Jolivet     for (j = 0; j < n; j++) PetscCall(PetscArrayzero(v + j * lda, m));
2072a5ce6ee0Svictorle   } else {
20739566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(v, PetscInt64Mult(m, n)));
2074a5ce6ee0Svictorle   }
20759566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(A, &v));
20763a40ed3dSBarry Smith   PetscFunctionReturn(0);
20776f0a148fSBarry Smith }
20786f0a148fSBarry Smith 
2079d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatZeroRows_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b)
2080d71ae5a4SJacob Faibussowitsch {
2081ec8511deSBarry Smith   Mat_SeqDense      *l = (Mat_SeqDense *)A->data;
2082b9679d65SBarry Smith   PetscInt           m = l->lda, n = A->cmap->n, i, j;
2083ca15aa20SStefano Zampini   PetscScalar       *slot, *bb, *v;
208497b48c8fSBarry Smith   const PetscScalar *xx;
208555659b69SBarry Smith 
20863a40ed3dSBarry Smith   PetscFunctionBegin;
208776bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
2088b9679d65SBarry Smith     for (i = 0; i < N; i++) {
208908401ef6SPierre Jolivet       PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed");
209008401ef6SPierre Jolivet       PetscCheck(rows[i] < A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Row %" PetscInt_FMT " requested to be zeroed greater than or equal number of rows %" PetscInt_FMT, rows[i], A->rmap->n);
2091b9679d65SBarry Smith     }
209276bd3646SJed Brown   }
2093ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
2094b9679d65SBarry Smith 
209597b48c8fSBarry Smith   /* fix right hand side if needed */
209697b48c8fSBarry Smith   if (x && b) {
20979566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(x, &xx));
20989566063dSJacob Faibussowitsch     PetscCall(VecGetArray(b, &bb));
20992205254eSKarl Rupp     for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]];
21009566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(x, &xx));
21019566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(b, &bb));
210297b48c8fSBarry Smith   }
210397b48c8fSBarry Smith 
21049566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
21056f0a148fSBarry Smith   for (i = 0; i < N; i++) {
2106ca15aa20SStefano Zampini     slot = v + rows[i];
21079371c9d4SSatish Balay     for (j = 0; j < n; j++) {
21089371c9d4SSatish Balay       *slot = 0.0;
21099371c9d4SSatish Balay       slot += m;
21109371c9d4SSatish Balay     }
21116f0a148fSBarry Smith   }
2112f4df32b1SMatthew Knepley   if (diag != 0.0) {
211308401ef6SPierre Jolivet     PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices");
21146f0a148fSBarry Smith     for (i = 0; i < N; i++) {
2115ca15aa20SStefano Zampini       slot  = v + (m + 1) * rows[i];
2116f4df32b1SMatthew Knepley       *slot = diag;
21176f0a148fSBarry Smith     }
21186f0a148fSBarry Smith   }
21199566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
21203a40ed3dSBarry Smith   PetscFunctionReturn(0);
21216f0a148fSBarry Smith }
2122557bce09SLois Curfman McInnes 
2123d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A, PetscInt *lda)
2124d71ae5a4SJacob Faibussowitsch {
212549a6ff4bSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
212649a6ff4bSBarry Smith 
212749a6ff4bSBarry Smith   PetscFunctionBegin;
212849a6ff4bSBarry Smith   *lda = mat->lda;
212949a6ff4bSBarry Smith   PetscFunctionReturn(0);
213049a6ff4bSBarry Smith }
213149a6ff4bSBarry Smith 
2132d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArray_SeqDense(Mat A, PetscScalar **array)
2133d71ae5a4SJacob Faibussowitsch {
2134c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
21353a40ed3dSBarry Smith 
21363a40ed3dSBarry Smith   PetscFunctionBegin;
213728b400f6SJacob Faibussowitsch   PetscCheck(!mat->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
213864e87e97SBarry Smith   *array = mat->v;
21393a40ed3dSBarry Smith   PetscFunctionReturn(0);
214064e87e97SBarry Smith }
21410754003eSLois Curfman McInnes 
2142d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A, PetscScalar **array)
2143d71ae5a4SJacob Faibussowitsch {
21443a40ed3dSBarry Smith   PetscFunctionBegin;
214575f6d85dSStefano Zampini   if (array) *array = NULL;
21463a40ed3dSBarry Smith   PetscFunctionReturn(0);
2147ff14e315SSatish Balay }
21480754003eSLois Curfman McInnes 
21490f74d2c1SSatish Balay /*@
215011a5261eSBarry Smith    MatDenseGetLDA - gets the leading dimension of the array returned from `MatDenseGetArray()`
215149a6ff4bSBarry Smith 
2152ad16ce7aSStefano Zampini    Not collective
215349a6ff4bSBarry Smith 
215449a6ff4bSBarry Smith    Input Parameter:
215511a5261eSBarry Smith .  mat - a `MATDENSE` or `MATDENSECUDA` matrix
215649a6ff4bSBarry Smith 
215749a6ff4bSBarry Smith    Output Parameter:
215849a6ff4bSBarry Smith .   lda - the leading dimension
215949a6ff4bSBarry Smith 
216049a6ff4bSBarry Smith    Level: intermediate
216149a6ff4bSBarry Smith 
216211a5261eSBarry Smith .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseSetLDA()`
216349a6ff4bSBarry Smith @*/
2164d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetLDA(Mat A, PetscInt *lda)
2165d71ae5a4SJacob Faibussowitsch {
216649a6ff4bSBarry Smith   PetscFunctionBegin;
2167d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2168dadcf809SJacob Faibussowitsch   PetscValidIntPointer(lda, 2);
216975f6d85dSStefano Zampini   MatCheckPreallocated(A, 1);
2170cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetLDA_C", (Mat, PetscInt *), (A, lda));
217149a6ff4bSBarry Smith   PetscFunctionReturn(0);
217249a6ff4bSBarry Smith }
217349a6ff4bSBarry Smith 
21740f74d2c1SSatish Balay /*@
217511a5261eSBarry Smith    MatDenseSetLDA - Sets the leading dimension of the array used by the `MATDENSE` matrix
2176ad16ce7aSStefano Zampini 
2177ad16ce7aSStefano Zampini    Not collective
2178ad16ce7aSStefano Zampini 
2179d8d19677SJose E. Roman    Input Parameters:
218011a5261eSBarry Smith +  mat - a `MATDENSE` or `MATDENSECUDA` matrix
2181ad16ce7aSStefano Zampini -  lda - the leading dimension
2182ad16ce7aSStefano Zampini 
2183ad16ce7aSStefano Zampini    Level: intermediate
2184ad16ce7aSStefano Zampini 
218511a5261eSBarry Smith .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetLDA()`
2186ad16ce7aSStefano Zampini @*/
2187d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA(Mat A, PetscInt lda)
2188d71ae5a4SJacob Faibussowitsch {
2189ad16ce7aSStefano Zampini   PetscFunctionBegin;
2190ad16ce7aSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2191cac4c232SBarry Smith   PetscTryMethod(A, "MatDenseSetLDA_C", (Mat, PetscInt), (A, lda));
2192ad16ce7aSStefano Zampini   PetscFunctionReturn(0);
2193ad16ce7aSStefano Zampini }
2194ad16ce7aSStefano Zampini 
2195ad16ce7aSStefano Zampini /*@C
219611a5261eSBarry Smith    MatDenseGetArray - gives read-write access to the array where the data for a `MATDENSE` matrix is stored
219773a71a0fSBarry Smith 
2198c3339decSBarry Smith    Logically Collective
219973a71a0fSBarry Smith 
220073a71a0fSBarry Smith    Input Parameter:
22016947451fSStefano Zampini .  mat - a dense matrix
220273a71a0fSBarry Smith 
220373a71a0fSBarry Smith    Output Parameter:
220473a71a0fSBarry Smith .   array - pointer to the data
220573a71a0fSBarry Smith 
220673a71a0fSBarry Smith    Level: intermediate
220773a71a0fSBarry Smith 
22080ab4885dSBarry Smith    Fortran Note:
22090ab4885dSBarry Smith    `MatDenseGetArray()` Fortran binding is deprecated (since PETSc 3.19), use `MatDenseGetArrayF90()`
22100ab4885dSBarry Smith 
221111a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
221273a71a0fSBarry Smith @*/
2213d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArray(Mat A, PetscScalar **array)
2214d71ae5a4SJacob Faibussowitsch {
221573a71a0fSBarry Smith   PetscFunctionBegin;
2216d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2217d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2218cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array));
221973a71a0fSBarry Smith   PetscFunctionReturn(0);
222073a71a0fSBarry Smith }
222173a71a0fSBarry Smith 
2222dec5eb66SMatthew G Knepley /*@C
222311a5261eSBarry Smith    MatDenseRestoreArray - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArray()`
222473a71a0fSBarry Smith 
2225c3339decSBarry Smith    Logically Collective
22268572280aSBarry Smith 
22278572280aSBarry Smith    Input Parameters:
22286947451fSStefano Zampini +  mat - a dense matrix
2229742765d3SMatthew Knepley -  array - pointer to the data (may be NULL)
22308572280aSBarry Smith 
22318572280aSBarry Smith    Level: intermediate
22328572280aSBarry Smith 
22330ab4885dSBarry Smith    Fortran Note:
22340ab4885dSBarry Smith    `MatDenseRestoreArray()` Fortran binding is deprecated (since PETSc 3.19), use `MatDenseRestoreArrayF90()`
22350ab4885dSBarry Smith 
223611a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
22378572280aSBarry Smith @*/
2238d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArray(Mat A, PetscScalar **array)
2239d71ae5a4SJacob Faibussowitsch {
22408572280aSBarry Smith   PetscFunctionBegin;
2241d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2242d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2243cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array));
22449566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)A));
224547d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
2246637a0070SStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
2247637a0070SStefano Zampini #endif
22488572280aSBarry Smith   PetscFunctionReturn(0);
22498572280aSBarry Smith }
22508572280aSBarry Smith 
22518572280aSBarry Smith /*@C
225211a5261eSBarry Smith   MatDenseGetArrayRead - gives read-only access to the array where the data for a `MATDENSE`  matrix is stored
22538572280aSBarry Smith 
22540ab4885dSBarry Smith    Not Collective; No Fortran Support
22558572280aSBarry Smith 
22568572280aSBarry Smith    Input Parameter:
22576947451fSStefano Zampini .  mat - a dense matrix
22588572280aSBarry Smith 
22598572280aSBarry Smith    Output Parameter:
22608572280aSBarry Smith .   array - pointer to the data
22618572280aSBarry Smith 
22628572280aSBarry Smith    Level: intermediate
22638572280aSBarry Smith 
226411a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
22658572280aSBarry Smith @*/
2266d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArrayRead(Mat A, const PetscScalar **array)
2267d71ae5a4SJacob Faibussowitsch {
22688572280aSBarry Smith   PetscFunctionBegin;
2269d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2270d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2271cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, const PetscScalar **), (A, array));
22728572280aSBarry Smith   PetscFunctionReturn(0);
22738572280aSBarry Smith }
22748572280aSBarry Smith 
22758572280aSBarry Smith /*@C
227611a5261eSBarry Smith    MatDenseRestoreArrayRead - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayRead()`
22778572280aSBarry Smith 
22780ab4885dSBarry Smith    Not Collective; No Fortran Support
227973a71a0fSBarry Smith 
228073a71a0fSBarry Smith    Input Parameters:
22816947451fSStefano Zampini +  mat - a dense matrix
2282742765d3SMatthew Knepley -  array - pointer to the data (may be NULL)
228373a71a0fSBarry Smith 
228473a71a0fSBarry Smith    Level: intermediate
228573a71a0fSBarry Smith 
228611a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
228773a71a0fSBarry Smith @*/
2288d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArrayRead(Mat A, const PetscScalar **array)
2289d71ae5a4SJacob Faibussowitsch {
229073a71a0fSBarry Smith   PetscFunctionBegin;
2291d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2292d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2293cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, const PetscScalar **), (A, array));
229473a71a0fSBarry Smith   PetscFunctionReturn(0);
229573a71a0fSBarry Smith }
229673a71a0fSBarry Smith 
22976947451fSStefano Zampini /*@C
229811a5261eSBarry Smith    MatDenseGetArrayWrite - gives write-only access to the array where the data for a `MATDENSE` matrix is stored
22996947451fSStefano Zampini 
23000ab4885dSBarry Smith    Not Collective; No Fortran Support
23016947451fSStefano Zampini 
23026947451fSStefano Zampini    Input Parameter:
23036947451fSStefano Zampini .  mat - a dense matrix
23046947451fSStefano Zampini 
23056947451fSStefano Zampini    Output Parameter:
23066947451fSStefano Zampini .   array - pointer to the data
23076947451fSStefano Zampini 
23086947451fSStefano Zampini    Level: intermediate
23096947451fSStefano Zampini 
231011a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`
23116947451fSStefano Zampini @*/
2312d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArrayWrite(Mat A, PetscScalar **array)
2313d71ae5a4SJacob Faibussowitsch {
23146947451fSStefano Zampini   PetscFunctionBegin;
2315d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2316d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2317cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array));
23186947451fSStefano Zampini   PetscFunctionReturn(0);
23196947451fSStefano Zampini }
23206947451fSStefano Zampini 
23216947451fSStefano Zampini /*@C
232211a5261eSBarry Smith    MatDenseRestoreArrayWrite - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayWrite()`
23236947451fSStefano Zampini 
23240ab4885dSBarry Smith    Not Collective; No Fortran Support
23256947451fSStefano Zampini 
23266947451fSStefano Zampini    Input Parameters:
23276947451fSStefano Zampini +  mat - a dense matrix
2328742765d3SMatthew Knepley -  array - pointer to the data (may be NULL)
23296947451fSStefano Zampini 
23306947451fSStefano Zampini    Level: intermediate
23316947451fSStefano Zampini 
233211a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`
23336947451fSStefano Zampini @*/
2334d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArrayWrite(Mat A, PetscScalar **array)
2335d71ae5a4SJacob Faibussowitsch {
23366947451fSStefano Zampini   PetscFunctionBegin;
2337d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2338d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2339cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array));
23409566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)A));
234147d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
23426947451fSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
23436947451fSStefano Zampini #endif
23446947451fSStefano Zampini   PetscFunctionReturn(0);
23456947451fSStefano Zampini }
23466947451fSStefano Zampini 
2347*cd3f9d89SJunchao Zhang /*@C
2348*cd3f9d89SJunchao Zhang    MatDenseGetArrayAndMemType - gives read-write access to the array where the data for a `MATDENSE` matrix is stored
2349*cd3f9d89SJunchao Zhang 
2350*cd3f9d89SJunchao Zhang    Logically Collective
2351*cd3f9d89SJunchao Zhang 
2352*cd3f9d89SJunchao Zhang    Input Parameter:
2353*cd3f9d89SJunchao Zhang .  mat - a dense matrix
2354*cd3f9d89SJunchao Zhang 
2355*cd3f9d89SJunchao Zhang    Output Parameters:
2356*cd3f9d89SJunchao Zhang +  array - pointer to the data
2357*cd3f9d89SJunchao Zhang -  mtype - memory type of the returned pointer
2358*cd3f9d89SJunchao Zhang 
2359*cd3f9d89SJunchao Zhang    Notes:
2360*cd3f9d89SJunchao Zhang    If the matrix is of a device type such as MATDENSECUDA, MATDENSEHIP, etc., unless it is currently bound to CPU,
2361*cd3f9d89SJunchao Zhang    an array on device is always returned and is guaranteed to contain the matrix's latest data.
2362*cd3f9d89SJunchao Zhang 
2363*cd3f9d89SJunchao Zhang    Level: intermediate
2364*cd3f9d89SJunchao Zhang 
2365*cd3f9d89SJunchao Zhang .seealso: `MATDENSE`, `MatDenseRestoreArrayAndMemType()`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArrayWriteAndMemType()`, `MatDenseGetArrayRead()`,
2366*cd3f9d89SJunchao Zhang    `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()`
2367*cd3f9d89SJunchao Zhang @*/
2368*cd3f9d89SJunchao Zhang PetscErrorCode MatDenseGetArrayAndMemType(Mat A, PetscScalar **array, PetscMemType *mtype)
2369*cd3f9d89SJunchao Zhang {
2370*cd3f9d89SJunchao Zhang   PetscBool isMPI;
2371*cd3f9d89SJunchao Zhang 
2372*cd3f9d89SJunchao Zhang   PetscFunctionBegin;
2373*cd3f9d89SJunchao Zhang   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2374*cd3f9d89SJunchao Zhang   PetscValidPointer(array, 2);
2375*cd3f9d89SJunchao Zhang   PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI));
2376*cd3f9d89SJunchao Zhang   if (isMPI) {
2377*cd3f9d89SJunchao Zhang     /* Dispatch here so that the code can be reused for all subclasses of MATDENSE */
2378*cd3f9d89SJunchao Zhang     PetscCall(MatDenseGetArrayAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype));
2379*cd3f9d89SJunchao Zhang   } else {
2380*cd3f9d89SJunchao Zhang     PetscErrorCode (*fptr)(Mat, PetscScalar **, PetscMemType *);
2381*cd3f9d89SJunchao Zhang     PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayAndMemType_C", &fptr);
2382*cd3f9d89SJunchao Zhang     if (fptr) {
2383*cd3f9d89SJunchao Zhang       PetscCall((*fptr)(A, array, mtype));
2384*cd3f9d89SJunchao Zhang     } else {
2385*cd3f9d89SJunchao Zhang       PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array));
2386*cd3f9d89SJunchao Zhang       if (mtype) *mtype = PETSC_MEMTYPE_HOST;
2387*cd3f9d89SJunchao Zhang     }
2388*cd3f9d89SJunchao Zhang   }
2389*cd3f9d89SJunchao Zhang   PetscFunctionReturn(0);
2390*cd3f9d89SJunchao Zhang }
2391*cd3f9d89SJunchao Zhang 
2392*cd3f9d89SJunchao Zhang /*@C
2393*cd3f9d89SJunchao Zhang    MatDenseRestoreArrayAndMemType - returns access to the array that is obtained by `MatDenseGetArrayAndMemType()`
2394*cd3f9d89SJunchao Zhang 
2395*cd3f9d89SJunchao Zhang    Logically Collective
2396*cd3f9d89SJunchao Zhang 
2397*cd3f9d89SJunchao Zhang    Input Parameters:
2398*cd3f9d89SJunchao Zhang +  mat - a dense matrix
2399*cd3f9d89SJunchao Zhang -  array - pointer to the data
2400*cd3f9d89SJunchao Zhang 
2401*cd3f9d89SJunchao Zhang    Level: intermediate
2402*cd3f9d89SJunchao Zhang 
2403*cd3f9d89SJunchao Zhang .seealso: `MATDENSE`, `MatDenseGetArrayAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
2404*cd3f9d89SJunchao Zhang @*/
2405*cd3f9d89SJunchao Zhang PetscErrorCode MatDenseRestoreArrayAndMemType(Mat A, PetscScalar **array)
2406*cd3f9d89SJunchao Zhang {
2407*cd3f9d89SJunchao Zhang   PetscBool isMPI;
2408*cd3f9d89SJunchao Zhang 
2409*cd3f9d89SJunchao Zhang   PetscFunctionBegin;
2410*cd3f9d89SJunchao Zhang   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2411*cd3f9d89SJunchao Zhang   PetscValidPointer(array, 2);
2412*cd3f9d89SJunchao Zhang   PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI));
2413*cd3f9d89SJunchao Zhang   if (isMPI) {
2414*cd3f9d89SJunchao Zhang     PetscCall(MatDenseRestoreArrayAndMemType(((Mat_MPIDense *)A->data)->A, array));
2415*cd3f9d89SJunchao Zhang   } else {
2416*cd3f9d89SJunchao Zhang     PetscErrorCode (*fptr)(Mat, PetscScalar **);
2417*cd3f9d89SJunchao Zhang     PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayAndMemType_C", &fptr);
2418*cd3f9d89SJunchao Zhang     if (fptr) {
2419*cd3f9d89SJunchao Zhang       PetscCall((*fptr)(A, array));
2420*cd3f9d89SJunchao Zhang     } else {
2421*cd3f9d89SJunchao Zhang       PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array));
2422*cd3f9d89SJunchao Zhang     }
2423*cd3f9d89SJunchao Zhang     *array = NULL;
2424*cd3f9d89SJunchao Zhang   }
2425*cd3f9d89SJunchao Zhang   PetscCall(PetscObjectStateIncrease((PetscObject)A));
2426*cd3f9d89SJunchao Zhang   PetscFunctionReturn(0);
2427*cd3f9d89SJunchao Zhang }
2428*cd3f9d89SJunchao Zhang 
2429*cd3f9d89SJunchao Zhang /*@C
2430*cd3f9d89SJunchao Zhang    MatDenseGetArrayReadAndMemType - gives read-only access to the array where the data for a `MATDENSE` matrix is stored
2431*cd3f9d89SJunchao Zhang 
2432*cd3f9d89SJunchao Zhang    Logically Collective
2433*cd3f9d89SJunchao Zhang 
2434*cd3f9d89SJunchao Zhang    Input Parameter:
2435*cd3f9d89SJunchao Zhang .  mat - a dense matrix
2436*cd3f9d89SJunchao Zhang 
2437*cd3f9d89SJunchao Zhang    Output Parameters:
2438*cd3f9d89SJunchao Zhang +  array - pointer to the data
2439*cd3f9d89SJunchao Zhang -  mtype - memory type of the returned pointer
2440*cd3f9d89SJunchao Zhang 
2441*cd3f9d89SJunchao Zhang    Notes:
2442*cd3f9d89SJunchao Zhang    If the matrix is of a device type such as MATDENSECUDA, MATDENSEHIP, etc., unless it is currently bound to CPU,
2443*cd3f9d89SJunchao Zhang    an array on device is always returned and is guaranteed to contain the matrix's latest data.
2444*cd3f9d89SJunchao Zhang 
2445*cd3f9d89SJunchao Zhang    Level: intermediate
2446*cd3f9d89SJunchao Zhang 
2447*cd3f9d89SJunchao Zhang .seealso: `MATDENSE`, `MatDenseRestoreArrayReadAndMemType()`, `MatDenseGetArrayWriteAndMemType()`,
2448*cd3f9d89SJunchao Zhang    `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()`
2449*cd3f9d89SJunchao Zhang @*/
2450*cd3f9d89SJunchao Zhang PetscErrorCode MatDenseGetArrayReadAndMemType(Mat A, const PetscScalar **array, PetscMemType *mtype)
2451*cd3f9d89SJunchao Zhang {
2452*cd3f9d89SJunchao Zhang   PetscBool isMPI;
2453*cd3f9d89SJunchao Zhang 
2454*cd3f9d89SJunchao Zhang   PetscFunctionBegin;
2455*cd3f9d89SJunchao Zhang   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2456*cd3f9d89SJunchao Zhang   PetscValidPointer(array, 2);
2457*cd3f9d89SJunchao Zhang   PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI));
2458*cd3f9d89SJunchao Zhang   if (isMPI) { /* Dispatch here so that the code can be reused for all subclasses of MATDENSE */
2459*cd3f9d89SJunchao Zhang     PetscCall(MatDenseGetArrayReadAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype));
2460*cd3f9d89SJunchao Zhang   } else {
2461*cd3f9d89SJunchao Zhang     PetscErrorCode (*fptr)(Mat, const PetscScalar **, PetscMemType *);
2462*cd3f9d89SJunchao Zhang     PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayReadAndMemType_C", &fptr);
2463*cd3f9d89SJunchao Zhang     if (fptr) {
2464*cd3f9d89SJunchao Zhang       PetscCall((*fptr)(A, array, mtype));
2465*cd3f9d89SJunchao Zhang     } else {
2466*cd3f9d89SJunchao Zhang       PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, const PetscScalar **), (A, array));
2467*cd3f9d89SJunchao Zhang       if (mtype) *mtype = PETSC_MEMTYPE_HOST;
2468*cd3f9d89SJunchao Zhang     }
2469*cd3f9d89SJunchao Zhang   }
2470*cd3f9d89SJunchao Zhang   PetscFunctionReturn(0);
2471*cd3f9d89SJunchao Zhang }
2472*cd3f9d89SJunchao Zhang 
2473*cd3f9d89SJunchao Zhang /*@C
2474*cd3f9d89SJunchao Zhang    MatDenseRestoreArrayReadAndMemType - returns access to the array that is obtained by `MatDenseGetArrayReadAndMemType()`
2475*cd3f9d89SJunchao Zhang 
2476*cd3f9d89SJunchao Zhang    Logically Collective
2477*cd3f9d89SJunchao Zhang 
2478*cd3f9d89SJunchao Zhang    Input Parameters:
2479*cd3f9d89SJunchao Zhang +  mat - a dense matrix
2480*cd3f9d89SJunchao Zhang -  array - pointer to the data
2481*cd3f9d89SJunchao Zhang 
2482*cd3f9d89SJunchao Zhang    Level: intermediate
2483*cd3f9d89SJunchao Zhang 
2484*cd3f9d89SJunchao Zhang .seealso: `MATDENSE`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
2485*cd3f9d89SJunchao Zhang @*/
2486*cd3f9d89SJunchao Zhang PetscErrorCode MatDenseRestoreArrayReadAndMemType(Mat A, const PetscScalar **array)
2487*cd3f9d89SJunchao Zhang {
2488*cd3f9d89SJunchao Zhang   PetscBool isMPI;
2489*cd3f9d89SJunchao Zhang 
2490*cd3f9d89SJunchao Zhang   PetscFunctionBegin;
2491*cd3f9d89SJunchao Zhang   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2492*cd3f9d89SJunchao Zhang   PetscValidPointer(array, 2);
2493*cd3f9d89SJunchao Zhang   PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI));
2494*cd3f9d89SJunchao Zhang   if (isMPI) {
2495*cd3f9d89SJunchao Zhang     PetscCall(MatDenseRestoreArrayReadAndMemType(((Mat_MPIDense *)A->data)->A, array));
2496*cd3f9d89SJunchao Zhang   } else {
2497*cd3f9d89SJunchao Zhang     PetscErrorCode (*fptr)(Mat, const PetscScalar **);
2498*cd3f9d89SJunchao Zhang     PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayReadAndMemType_C", &fptr);
2499*cd3f9d89SJunchao Zhang     if (fptr) {
2500*cd3f9d89SJunchao Zhang       PetscCall((*fptr)(A, array));
2501*cd3f9d89SJunchao Zhang     } else {
2502*cd3f9d89SJunchao Zhang       PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, const PetscScalar **), (A, array));
2503*cd3f9d89SJunchao Zhang     }
2504*cd3f9d89SJunchao Zhang     *array = NULL;
2505*cd3f9d89SJunchao Zhang   }
2506*cd3f9d89SJunchao Zhang   PetscFunctionReturn(0);
2507*cd3f9d89SJunchao Zhang }
2508*cd3f9d89SJunchao Zhang 
2509*cd3f9d89SJunchao Zhang /*@C
2510*cd3f9d89SJunchao Zhang    MatDenseGetArrayWriteAndMemType - gives write-only access to the array where the data for a `MATDENSE` matrix is stored
2511*cd3f9d89SJunchao Zhang 
2512*cd3f9d89SJunchao Zhang    Logically Collective
2513*cd3f9d89SJunchao Zhang 
2514*cd3f9d89SJunchao Zhang    Input Parameter:
2515*cd3f9d89SJunchao Zhang .  mat - a dense matrix
2516*cd3f9d89SJunchao Zhang 
2517*cd3f9d89SJunchao Zhang    Output Parameters:
2518*cd3f9d89SJunchao Zhang +  array - pointer to the data
2519*cd3f9d89SJunchao Zhang -  mtype - memory type of the returned pointer
2520*cd3f9d89SJunchao Zhang 
2521*cd3f9d89SJunchao Zhang    Notes:
2522*cd3f9d89SJunchao Zhang    If the matrix is of a device type such as MATDENSECUDA, MATDENSEHIP, etc., unless it is currently bound to CPU,
2523*cd3f9d89SJunchao Zhang    an array on device is always returned and is guaranteed to contain the matrix's latest data.
2524*cd3f9d89SJunchao Zhang 
2525*cd3f9d89SJunchao Zhang    Level: intermediate
2526*cd3f9d89SJunchao Zhang 
2527*cd3f9d89SJunchao Zhang .seealso: `MATDENSE`, `MatDenseRestoreArrayWriteAndMemType()`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArrayRead()`,
2528*cd3f9d89SJunchao Zhang   `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`,  `MatSeqAIJGetCSRAndMemType()`
2529*cd3f9d89SJunchao Zhang @*/
2530*cd3f9d89SJunchao Zhang PetscErrorCode MatDenseGetArrayWriteAndMemType(Mat A, PetscScalar **array, PetscMemType *mtype)
2531*cd3f9d89SJunchao Zhang {
2532*cd3f9d89SJunchao Zhang   PetscBool isMPI;
2533*cd3f9d89SJunchao Zhang 
2534*cd3f9d89SJunchao Zhang   PetscFunctionBegin;
2535*cd3f9d89SJunchao Zhang   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2536*cd3f9d89SJunchao Zhang   PetscValidPointer(array, 2);
2537*cd3f9d89SJunchao Zhang   PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI));
2538*cd3f9d89SJunchao Zhang   if (isMPI) {
2539*cd3f9d89SJunchao Zhang     PetscCall(MatDenseGetArrayWriteAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype));
2540*cd3f9d89SJunchao Zhang   } else {
2541*cd3f9d89SJunchao Zhang     PetscErrorCode (*fptr)(Mat, PetscScalar **, PetscMemType *);
2542*cd3f9d89SJunchao Zhang     PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayWriteAndMemType_C", &fptr);
2543*cd3f9d89SJunchao Zhang     if (fptr) {
2544*cd3f9d89SJunchao Zhang       PetscCall((*fptr)(A, array, mtype));
2545*cd3f9d89SJunchao Zhang     } else {
2546*cd3f9d89SJunchao Zhang       PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array));
2547*cd3f9d89SJunchao Zhang       if (mtype) *mtype = PETSC_MEMTYPE_HOST;
2548*cd3f9d89SJunchao Zhang     }
2549*cd3f9d89SJunchao Zhang   }
2550*cd3f9d89SJunchao Zhang   PetscFunctionReturn(0);
2551*cd3f9d89SJunchao Zhang }
2552*cd3f9d89SJunchao Zhang 
2553*cd3f9d89SJunchao Zhang /*@C
2554*cd3f9d89SJunchao Zhang    MatDenseRestoreArrayWriteAndMemType - returns access to the array that is obtained by `MatDenseGetArrayReadAndMemType()`
2555*cd3f9d89SJunchao Zhang 
2556*cd3f9d89SJunchao Zhang    Logically Collective
2557*cd3f9d89SJunchao Zhang 
2558*cd3f9d89SJunchao Zhang    Input Parameters:
2559*cd3f9d89SJunchao Zhang +  mat - a dense matrix
2560*cd3f9d89SJunchao Zhang -  array - pointer to the data
2561*cd3f9d89SJunchao Zhang 
2562*cd3f9d89SJunchao Zhang    Level: intermediate
2563*cd3f9d89SJunchao Zhang 
2564*cd3f9d89SJunchao Zhang .seealso: `MATDENSE`, `MatDenseGetArrayWriteAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
2565*cd3f9d89SJunchao Zhang @*/
2566*cd3f9d89SJunchao Zhang PetscErrorCode MatDenseRestoreArrayWriteAndMemType(Mat A, PetscScalar **array)
2567*cd3f9d89SJunchao Zhang {
2568*cd3f9d89SJunchao Zhang   PetscBool isMPI;
2569*cd3f9d89SJunchao Zhang 
2570*cd3f9d89SJunchao Zhang   PetscFunctionBegin;
2571*cd3f9d89SJunchao Zhang   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2572*cd3f9d89SJunchao Zhang   PetscValidPointer(array, 2);
2573*cd3f9d89SJunchao Zhang   PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI));
2574*cd3f9d89SJunchao Zhang   if (isMPI) {
2575*cd3f9d89SJunchao Zhang     PetscCall(MatDenseRestoreArrayWriteAndMemType(((Mat_MPIDense *)A->data)->A, array));
2576*cd3f9d89SJunchao Zhang   } else {
2577*cd3f9d89SJunchao Zhang     PetscErrorCode (*fptr)(Mat, PetscScalar **);
2578*cd3f9d89SJunchao Zhang     PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayWriteAndMemType_C", &fptr);
2579*cd3f9d89SJunchao Zhang     if (fptr) {
2580*cd3f9d89SJunchao Zhang       PetscCall((*fptr)(A, array));
2581*cd3f9d89SJunchao Zhang     } else {
2582*cd3f9d89SJunchao Zhang       PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array));
2583*cd3f9d89SJunchao Zhang     }
2584*cd3f9d89SJunchao Zhang     *array = NULL;
2585*cd3f9d89SJunchao Zhang   }
2586*cd3f9d89SJunchao Zhang   PetscCall(PetscObjectStateIncrease((PetscObject)A));
2587*cd3f9d89SJunchao Zhang   PetscFunctionReturn(0);
2588*cd3f9d89SJunchao Zhang }
2589*cd3f9d89SJunchao Zhang 
2590d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A, IS isrow, IS iscol, MatReuse scall, Mat *B)
2591d71ae5a4SJacob Faibussowitsch {
2592c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense *)A->data;
2593bf5a80bcSToby Isaac   PetscInt        i, j, nrows, ncols, ldb;
25945d0c19d7SBarry Smith   const PetscInt *irow, *icol;
259587828ca2SBarry Smith   PetscScalar    *av, *bv, *v = mat->v;
25960754003eSLois Curfman McInnes   Mat             newmat;
25970754003eSLois Curfman McInnes 
25983a40ed3dSBarry Smith   PetscFunctionBegin;
25999566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(isrow, &irow));
26009566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(iscol, &icol));
26019566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(isrow, &nrows));
26029566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(iscol, &ncols));
26030754003eSLois Curfman McInnes 
2604182d2002SSatish Balay   /* Check submatrixcall */
2605182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
260613f74950SBarry Smith     PetscInt n_cols, n_rows;
26079566063dSJacob Faibussowitsch     PetscCall(MatGetSize(*B, &n_rows, &n_cols));
260821a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
2609f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
26109566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(*B, nrows, ncols, nrows, ncols));
261121a2c019SBarry Smith     }
2612182d2002SSatish Balay     newmat = *B;
2613182d2002SSatish Balay   } else {
26140754003eSLois Curfman McInnes     /* Create and fill new matrix */
26159566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &newmat));
26169566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(newmat, nrows, ncols, nrows, ncols));
26179566063dSJacob Faibussowitsch     PetscCall(MatSetType(newmat, ((PetscObject)A)->type_name));
26189566063dSJacob Faibussowitsch     PetscCall(MatSeqDenseSetPreallocation(newmat, NULL));
2619182d2002SSatish Balay   }
2620182d2002SSatish Balay 
2621182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
26229566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(newmat, &bv));
26239566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(newmat, &ldb));
2624182d2002SSatish Balay   for (i = 0; i < ncols; i++) {
26256de62eeeSBarry Smith     av = v + mat->lda * icol[i];
2626ca15aa20SStefano Zampini     for (j = 0; j < nrows; j++) bv[j] = av[irow[j]];
2627bf5a80bcSToby Isaac     bv += ldb;
26280754003eSLois Curfman McInnes   }
26299566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(newmat, &bv));
2630182d2002SSatish Balay 
2631182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
26329566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(newmat, MAT_FINAL_ASSEMBLY));
26339566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(newmat, MAT_FINAL_ASSEMBLY));
26340754003eSLois Curfman McInnes 
26350754003eSLois Curfman McInnes   /* Free work space */
26369566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(isrow, &irow));
26379566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(iscol, &icol));
2638182d2002SSatish Balay   *B = newmat;
26393a40ed3dSBarry Smith   PetscFunctionReturn(0);
26400754003eSLois Curfman McInnes }
26410754003eSLois Curfman McInnes 
2642d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A, PetscInt n, const IS irow[], const IS icol[], MatReuse scall, Mat *B[])
2643d71ae5a4SJacob Faibussowitsch {
264413f74950SBarry Smith   PetscInt i;
2645905e6a2fSBarry Smith 
26463a40ed3dSBarry Smith   PetscFunctionBegin;
264748a46eb9SPierre Jolivet   if (scall == MAT_INITIAL_MATRIX) PetscCall(PetscCalloc1(n, B));
2648905e6a2fSBarry Smith 
264948a46eb9SPierre Jolivet   for (i = 0; i < n; i++) PetscCall(MatCreateSubMatrix_SeqDense(A, irow[i], icol[i], scall, &(*B)[i]));
26503a40ed3dSBarry Smith   PetscFunctionReturn(0);
2651905e6a2fSBarry Smith }
2652905e6a2fSBarry Smith 
2653d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat, MatAssemblyType mode)
2654d71ae5a4SJacob Faibussowitsch {
2655c0aa2d19SHong Zhang   PetscFunctionBegin;
2656c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2657c0aa2d19SHong Zhang }
2658c0aa2d19SHong Zhang 
2659d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat, MatAssemblyType mode)
2660d71ae5a4SJacob Faibussowitsch {
2661c0aa2d19SHong Zhang   PetscFunctionBegin;
2662c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2663c0aa2d19SHong Zhang }
2664c0aa2d19SHong Zhang 
2665d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCopy_SeqDense(Mat A, Mat B, MatStructure str)
2666d71ae5a4SJacob Faibussowitsch {
26674b0e389bSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data;
2668ca15aa20SStefano Zampini   const PetscScalar *va;
2669ca15aa20SStefano Zampini   PetscScalar       *vb;
2670d0f46423SBarry Smith   PetscInt           lda1 = a->lda, lda2 = b->lda, m = A->rmap->n, n = A->cmap->n, j;
26713a40ed3dSBarry Smith 
26723a40ed3dSBarry Smith   PetscFunctionBegin;
267333f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
267433f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
26759566063dSJacob Faibussowitsch     PetscCall(MatCopy_Basic(A, B, str));
26763a40ed3dSBarry Smith     PetscFunctionReturn(0);
26773a40ed3dSBarry Smith   }
2678aed4548fSBarry Smith   PetscCheck(m == B->rmap->n && n == B->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "size(B) != size(A)");
26799566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &va));
26809566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(B, &vb));
2681a5ce6ee0Svictorle   if (lda1 > m || lda2 > m) {
268248a46eb9SPierre Jolivet     for (j = 0; j < n; j++) PetscCall(PetscArraycpy(vb + j * lda2, va + j * lda1, m));
2683a5ce6ee0Svictorle   } else {
26849566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(vb, va, A->rmap->n * A->cmap->n));
2685a5ce6ee0Svictorle   }
26869566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(B, &vb));
26879566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &va));
26889566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY));
26899566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY));
2690273d9f13SBarry Smith   PetscFunctionReturn(0);
2691273d9f13SBarry Smith }
2692273d9f13SBarry Smith 
2693d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetUp_SeqDense(Mat A)
2694d71ae5a4SJacob Faibussowitsch {
2695273d9f13SBarry Smith   PetscFunctionBegin;
26969566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(A->rmap));
26979566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(A->cmap));
269848a46eb9SPierre Jolivet   if (!A->preallocated) PetscCall(MatSeqDenseSetPreallocation(A, NULL));
26993a40ed3dSBarry Smith   PetscFunctionReturn(0);
27004b0e389bSBarry Smith }
27014b0e389bSBarry Smith 
2702d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatConjugate_SeqDense(Mat A)
2703d71ae5a4SJacob Faibussowitsch {
27044396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
270506c5243aSJose E. Roman   PetscInt      i, j;
27064396437dSToby Isaac   PetscInt      min = PetscMin(A->rmap->n, A->cmap->n);
2707ca15aa20SStefano Zampini   PetscScalar  *aa;
2708ba337c44SJed Brown 
2709ba337c44SJed Brown   PetscFunctionBegin;
27109566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &aa));
271106c5243aSJose E. Roman   for (j = 0; j < A->cmap->n; j++) {
271206c5243aSJose E. Roman     for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscConj(aa[i + j * mat->lda]);
271306c5243aSJose E. Roman   }
27149566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &aa));
27159371c9d4SSatish Balay   if (mat->tau)
27169371c9d4SSatish Balay     for (i = 0; i < min; i++) mat->tau[i] = PetscConj(mat->tau[i]);
2717ba337c44SJed Brown   PetscFunctionReturn(0);
2718ba337c44SJed Brown }
2719ba337c44SJed Brown 
2720d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRealPart_SeqDense(Mat A)
2721d71ae5a4SJacob Faibussowitsch {
272206c5243aSJose E. Roman   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
272306c5243aSJose E. Roman   PetscInt      i, j;
2724ca15aa20SStefano Zampini   PetscScalar  *aa;
2725ba337c44SJed Brown 
2726ba337c44SJed Brown   PetscFunctionBegin;
27279566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &aa));
272806c5243aSJose E. Roman   for (j = 0; j < A->cmap->n; j++) {
272906c5243aSJose E. Roman     for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscRealPart(aa[i + j * mat->lda]);
273006c5243aSJose E. Roman   }
27319566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &aa));
2732ba337c44SJed Brown   PetscFunctionReturn(0);
2733ba337c44SJed Brown }
2734ba337c44SJed Brown 
2735d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatImaginaryPart_SeqDense(Mat A)
2736d71ae5a4SJacob Faibussowitsch {
273706c5243aSJose E. Roman   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
273806c5243aSJose E. Roman   PetscInt      i, j;
2739ca15aa20SStefano Zampini   PetscScalar  *aa;
2740ba337c44SJed Brown 
2741ba337c44SJed Brown   PetscFunctionBegin;
27429566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &aa));
274306c5243aSJose E. Roman   for (j = 0; j < A->cmap->n; j++) {
274406c5243aSJose E. Roman     for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscImaginaryPart(aa[i + j * mat->lda]);
274506c5243aSJose E. Roman   }
27469566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &aa));
2747ba337c44SJed Brown   PetscFunctionReturn(0);
2748ba337c44SJed Brown }
2749284134d9SBarry Smith 
2750a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/
2751d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C)
2752d71ae5a4SJacob Faibussowitsch {
2753d0f46423SBarry Smith   PetscInt  m = A->rmap->n, n = B->cmap->n;
275447d993e7Ssuyashtn   PetscBool cisdense = PETSC_FALSE;
2755a9fe9ddaSSatish Balay 
2756ee16a9a1SHong Zhang   PetscFunctionBegin;
27579566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C, m, n, m, n));
275847d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA)
27599566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, ""));
276047d993e7Ssuyashtn #endif
276147d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP)
276247d993e7Ssuyashtn   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, ""));
276347d993e7Ssuyashtn #endif
27647a3c3d58SStefano Zampini   if (!cisdense) {
27657a3c3d58SStefano Zampini     PetscBool flg;
27667a3c3d58SStefano Zampini 
27679566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg));
27689566063dSJacob Faibussowitsch     PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE));
27697a3c3d58SStefano Zampini   }
27709566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
2771ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2772ee16a9a1SHong Zhang }
2773a9fe9ddaSSatish Balay 
2774d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C)
2775d71ae5a4SJacob Faibussowitsch {
27766718818eSStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data, *c = (Mat_SeqDense *)C->data;
27770805154bSBarry Smith   PetscBLASInt       m, n, k;
2778ca15aa20SStefano Zampini   const PetscScalar *av, *bv;
2779ca15aa20SStefano Zampini   PetscScalar       *cv;
2780a9fe9ddaSSatish Balay   PetscScalar        _DOne = 1.0, _DZero = 0.0;
2781a9fe9ddaSSatish Balay 
2782a9fe9ddaSSatish Balay   PetscFunctionBegin;
27839566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n, &m));
27849566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n, &n));
27859566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &k));
278649d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
27879566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &av));
27889566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B, &bv));
27899566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C, &cv));
2790792fecdfSBarry Smith   PetscCallBLAS("BLASgemm", BLASgemm_("N", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda));
27919566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1)));
27929566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &av));
27939566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B, &bv));
27949566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C, &cv));
2795a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2796a9fe9ddaSSatish Balay }
2797a9fe9ddaSSatish Balay 
2798d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C)
2799d71ae5a4SJacob Faibussowitsch {
280069f65d41SStefano Zampini   PetscInt  m = A->rmap->n, n = B->rmap->n;
280147d993e7Ssuyashtn   PetscBool cisdense = PETSC_FALSE;
280269f65d41SStefano Zampini 
280369f65d41SStefano Zampini   PetscFunctionBegin;
28049566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C, m, n, m, n));
280547d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA)
28069566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, ""));
280747d993e7Ssuyashtn #endif
280847d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP)
280947d993e7Ssuyashtn   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, ""));
281047d993e7Ssuyashtn #endif
28117a3c3d58SStefano Zampini   if (!cisdense) {
28127a3c3d58SStefano Zampini     PetscBool flg;
28137a3c3d58SStefano Zampini 
28149566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg));
28159566063dSJacob Faibussowitsch     PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE));
28167a3c3d58SStefano Zampini   }
28179566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
281869f65d41SStefano Zampini   PetscFunctionReturn(0);
281969f65d41SStefano Zampini }
282069f65d41SStefano Zampini 
2821d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C)
2822d71ae5a4SJacob Faibussowitsch {
282369f65d41SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
282469f65d41SStefano Zampini   Mat_SeqDense      *b = (Mat_SeqDense *)B->data;
282569f65d41SStefano Zampini   Mat_SeqDense      *c = (Mat_SeqDense *)C->data;
28266718818eSStefano Zampini   const PetscScalar *av, *bv;
28276718818eSStefano Zampini   PetscScalar       *cv;
282869f65d41SStefano Zampini   PetscBLASInt       m, n, k;
282969f65d41SStefano Zampini   PetscScalar        _DOne = 1.0, _DZero = 0.0;
283069f65d41SStefano Zampini 
283169f65d41SStefano Zampini   PetscFunctionBegin;
28329566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n, &m));
28339566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n, &n));
28349566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &k));
283549d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
28369566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &av));
28379566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B, &bv));
28389566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C, &cv));
2839792fecdfSBarry Smith   PetscCallBLAS("BLASgemm", BLASgemm_("N", "T", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda));
28409566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &av));
28419566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B, &bv));
28429566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C, &cv));
28439566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1)));
284469f65d41SStefano Zampini   PetscFunctionReturn(0);
284569f65d41SStefano Zampini }
284669f65d41SStefano Zampini 
2847d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C)
2848d71ae5a4SJacob Faibussowitsch {
2849d0f46423SBarry Smith   PetscInt  m = A->cmap->n, n = B->cmap->n;
285047d993e7Ssuyashtn   PetscBool cisdense = PETSC_FALSE;
2851a9fe9ddaSSatish Balay 
2852ee16a9a1SHong Zhang   PetscFunctionBegin;
28539566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C, m, n, m, n));
285447d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA)
28559566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, ""));
285647d993e7Ssuyashtn #endif
285747d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP)
285847d993e7Ssuyashtn   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, ""));
285947d993e7Ssuyashtn #endif
28607a3c3d58SStefano Zampini   if (!cisdense) {
28617a3c3d58SStefano Zampini     PetscBool flg;
28627a3c3d58SStefano Zampini 
28639566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg));
28649566063dSJacob Faibussowitsch     PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE));
28657a3c3d58SStefano Zampini   }
28669566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
2867ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2868ee16a9a1SHong Zhang }
2869a9fe9ddaSSatish Balay 
2870d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C)
2871d71ae5a4SJacob Faibussowitsch {
2872a9fe9ddaSSatish Balay   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
2873a9fe9ddaSSatish Balay   Mat_SeqDense      *b = (Mat_SeqDense *)B->data;
2874a9fe9ddaSSatish Balay   Mat_SeqDense      *c = (Mat_SeqDense *)C->data;
28756718818eSStefano Zampini   const PetscScalar *av, *bv;
28766718818eSStefano Zampini   PetscScalar       *cv;
28770805154bSBarry Smith   PetscBLASInt       m, n, k;
2878a9fe9ddaSSatish Balay   PetscScalar        _DOne = 1.0, _DZero = 0.0;
2879a9fe9ddaSSatish Balay 
2880a9fe9ddaSSatish Balay   PetscFunctionBegin;
28819566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n, &m));
28829566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n, &n));
28839566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &k));
288449d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
28859566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &av));
28869566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B, &bv));
28879566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C, &cv));
2888792fecdfSBarry Smith   PetscCallBLAS("BLASgemm", BLASgemm_("T", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda));
28899566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &av));
28909566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B, &bv));
28919566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C, &cv));
28929566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1)));
2893a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2894a9fe9ddaSSatish Balay }
2895985db425SBarry Smith 
28964222ddf1SHong Zhang /* ----------------------------------------------- */
2897d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C)
2898d71ae5a4SJacob Faibussowitsch {
28994222ddf1SHong Zhang   PetscFunctionBegin;
29004222ddf1SHong Zhang   C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense;
29014222ddf1SHong Zhang   C->ops->productsymbolic = MatProductSymbolic_AB;
29024222ddf1SHong Zhang   PetscFunctionReturn(0);
29034222ddf1SHong Zhang }
29044222ddf1SHong Zhang 
2905d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C)
2906d71ae5a4SJacob Faibussowitsch {
29074222ddf1SHong Zhang   PetscFunctionBegin;
29084222ddf1SHong Zhang   C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense;
29094222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_AtB;
29104222ddf1SHong Zhang   PetscFunctionReturn(0);
29114222ddf1SHong Zhang }
29124222ddf1SHong Zhang 
2913d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C)
2914d71ae5a4SJacob Faibussowitsch {
29154222ddf1SHong Zhang   PetscFunctionBegin;
29164222ddf1SHong Zhang   C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense;
29174222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_ABt;
29184222ddf1SHong Zhang   PetscFunctionReturn(0);
29194222ddf1SHong Zhang }
29204222ddf1SHong Zhang 
2921d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C)
2922d71ae5a4SJacob Faibussowitsch {
29234222ddf1SHong Zhang   Mat_Product *product = C->product;
29244222ddf1SHong Zhang 
29254222ddf1SHong Zhang   PetscFunctionBegin;
29264222ddf1SHong Zhang   switch (product->type) {
2927d71ae5a4SJacob Faibussowitsch   case MATPRODUCT_AB:
2928d71ae5a4SJacob Faibussowitsch     PetscCall(MatProductSetFromOptions_SeqDense_AB(C));
2929d71ae5a4SJacob Faibussowitsch     break;
2930d71ae5a4SJacob Faibussowitsch   case MATPRODUCT_AtB:
2931d71ae5a4SJacob Faibussowitsch     PetscCall(MatProductSetFromOptions_SeqDense_AtB(C));
2932d71ae5a4SJacob Faibussowitsch     break;
2933d71ae5a4SJacob Faibussowitsch   case MATPRODUCT_ABt:
2934d71ae5a4SJacob Faibussowitsch     PetscCall(MatProductSetFromOptions_SeqDense_ABt(C));
2935d71ae5a4SJacob Faibussowitsch     break;
2936d71ae5a4SJacob Faibussowitsch   default:
2937d71ae5a4SJacob Faibussowitsch     break;
29384222ddf1SHong Zhang   }
29394222ddf1SHong Zhang   PetscFunctionReturn(0);
29404222ddf1SHong Zhang }
29414222ddf1SHong Zhang /* ----------------------------------------------- */
29424222ddf1SHong Zhang 
2943d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMax_SeqDense(Mat A, Vec v, PetscInt idx[])
2944d71ae5a4SJacob Faibussowitsch {
2945985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
2946d0f46423SBarry Smith   PetscInt           i, j, m = A->rmap->n, n = A->cmap->n, p;
2947985db425SBarry Smith   PetscScalar       *x;
2948ca15aa20SStefano Zampini   const PetscScalar *aa;
2949985db425SBarry Smith 
2950985db425SBarry Smith   PetscFunctionBegin;
295128b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
29529566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
29539566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v, &p));
29549566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
295508401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector");
2956985db425SBarry Smith   for (i = 0; i < m; i++) {
29579371c9d4SSatish Balay     x[i] = aa[i];
29589371c9d4SSatish Balay     if (idx) idx[i] = 0;
2959985db425SBarry Smith     for (j = 1; j < n; j++) {
29609371c9d4SSatish Balay       if (PetscRealPart(x[i]) < PetscRealPart(aa[i + a->lda * j])) {
29619371c9d4SSatish Balay         x[i] = aa[i + a->lda * j];
29629371c9d4SSatish Balay         if (idx) idx[i] = j;
29639371c9d4SSatish Balay       }
2964985db425SBarry Smith     }
2965985db425SBarry Smith   }
29669566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
29679566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
2968985db425SBarry Smith   PetscFunctionReturn(0);
2969985db425SBarry Smith }
2970985db425SBarry Smith 
2971d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A, Vec v, PetscInt idx[])
2972d71ae5a4SJacob Faibussowitsch {
2973985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
2974d0f46423SBarry Smith   PetscInt           i, j, m = A->rmap->n, n = A->cmap->n, p;
2975985db425SBarry Smith   PetscScalar       *x;
2976985db425SBarry Smith   PetscReal          atmp;
2977ca15aa20SStefano Zampini   const PetscScalar *aa;
2978985db425SBarry Smith 
2979985db425SBarry Smith   PetscFunctionBegin;
298028b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
29819566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
29829566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v, &p));
29839566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
298408401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector");
2985985db425SBarry Smith   for (i = 0; i < m; i++) {
29869189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
2987985db425SBarry Smith     for (j = 1; j < n; j++) {
2988ca15aa20SStefano Zampini       atmp = PetscAbsScalar(aa[i + a->lda * j]);
29899371c9d4SSatish Balay       if (PetscAbsScalar(x[i]) < atmp) {
29909371c9d4SSatish Balay         x[i] = atmp;
29919371c9d4SSatish Balay         if (idx) idx[i] = j;
29929371c9d4SSatish Balay       }
2993985db425SBarry Smith     }
2994985db425SBarry Smith   }
29959566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
29969566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
2997985db425SBarry Smith   PetscFunctionReturn(0);
2998985db425SBarry Smith }
2999985db425SBarry Smith 
3000d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMin_SeqDense(Mat A, Vec v, PetscInt idx[])
3001d71ae5a4SJacob Faibussowitsch {
3002985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
3003d0f46423SBarry Smith   PetscInt           i, j, m = A->rmap->n, n = A->cmap->n, p;
3004985db425SBarry Smith   PetscScalar       *x;
3005ca15aa20SStefano Zampini   const PetscScalar *aa;
3006985db425SBarry Smith 
3007985db425SBarry Smith   PetscFunctionBegin;
300828b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
30099566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
30109566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
30119566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v, &p));
301208401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector");
3013985db425SBarry Smith   for (i = 0; i < m; i++) {
30149371c9d4SSatish Balay     x[i] = aa[i];
30159371c9d4SSatish Balay     if (idx) idx[i] = 0;
3016985db425SBarry Smith     for (j = 1; j < n; j++) {
30179371c9d4SSatish Balay       if (PetscRealPart(x[i]) > PetscRealPart(aa[i + a->lda * j])) {
30189371c9d4SSatish Balay         x[i] = aa[i + a->lda * j];
30199371c9d4SSatish Balay         if (idx) idx[i] = j;
30209371c9d4SSatish Balay       }
3021985db425SBarry Smith     }
3022985db425SBarry Smith   }
30239566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
30249566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
3025985db425SBarry Smith   PetscFunctionReturn(0);
3026985db425SBarry Smith }
3027985db425SBarry Smith 
3028d71ae5a4SJacob Faibussowitsch PetscErrorCode MatGetColumnVector_SeqDense(Mat A, Vec v, PetscInt col)
3029d71ae5a4SJacob Faibussowitsch {
30308d0534beSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
30318d0534beSBarry Smith   PetscScalar       *x;
3032ca15aa20SStefano Zampini   const PetscScalar *aa;
30338d0534beSBarry Smith 
30348d0534beSBarry Smith   PetscFunctionBegin;
303528b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
30369566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
30379566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
30389566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(x, aa + col * a->lda, A->rmap->n));
30399566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
30409566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
30418d0534beSBarry Smith   PetscFunctionReturn(0);
30428d0534beSBarry Smith }
30438d0534beSBarry Smith 
3044d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatGetColumnReductions_SeqDense(Mat A, PetscInt type, PetscReal *reductions)
3045d71ae5a4SJacob Faibussowitsch {
30460716a85fSBarry Smith   PetscInt           i, j, m, n;
30471683a169SBarry Smith   const PetscScalar *a;
30480716a85fSBarry Smith 
30490716a85fSBarry Smith   PetscFunctionBegin;
30509566063dSJacob Faibussowitsch   PetscCall(MatGetSize(A, &m, &n));
30519566063dSJacob Faibussowitsch   PetscCall(PetscArrayzero(reductions, n));
30529566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &a));
3053857cbf51SRichard Tran Mills   if (type == NORM_2) {
30540716a85fSBarry Smith     for (i = 0; i < n; i++) {
3055ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j] * a[j]);
30560716a85fSBarry Smith       a += m;
30570716a85fSBarry Smith     }
3058857cbf51SRichard Tran Mills   } else if (type == NORM_1) {
30590716a85fSBarry Smith     for (i = 0; i < n; i++) {
3060ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j]);
30610716a85fSBarry Smith       a += m;
30620716a85fSBarry Smith     }
3063857cbf51SRichard Tran Mills   } else if (type == NORM_INFINITY) {
30640716a85fSBarry Smith     for (i = 0; i < n; i++) {
3065ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] = PetscMax(PetscAbsScalar(a[j]), reductions[i]);
30660716a85fSBarry Smith       a += m;
30670716a85fSBarry Smith     }
3068857cbf51SRichard Tran Mills   } else if (type == REDUCTION_SUM_REALPART || type == REDUCTION_MEAN_REALPART) {
3069a873a8cdSSam Reynolds     for (i = 0; i < n; i++) {
3070ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] += PetscRealPart(a[j]);
3071a873a8cdSSam Reynolds       a += m;
3072a873a8cdSSam Reynolds     }
3073857cbf51SRichard Tran Mills   } else if (type == REDUCTION_SUM_IMAGINARYPART || type == REDUCTION_MEAN_IMAGINARYPART) {
3074857cbf51SRichard Tran Mills     for (i = 0; i < n; i++) {
3075ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] += PetscImaginaryPart(a[j]);
3076857cbf51SRichard Tran Mills       a += m;
3077857cbf51SRichard Tran Mills     }
3078857cbf51SRichard Tran Mills   } else SETERRQ(PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Unknown reduction type");
30799566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &a));
3080857cbf51SRichard Tran Mills   if (type == NORM_2) {
3081a873a8cdSSam Reynolds     for (i = 0; i < n; i++) reductions[i] = PetscSqrtReal(reductions[i]);
3082857cbf51SRichard Tran Mills   } else if (type == REDUCTION_MEAN_REALPART || type == REDUCTION_MEAN_IMAGINARYPART) {
3083a873a8cdSSam Reynolds     for (i = 0; i < n; i++) reductions[i] /= m;
30840716a85fSBarry Smith   }
30850716a85fSBarry Smith   PetscFunctionReturn(0);
30860716a85fSBarry Smith }
30870716a85fSBarry Smith 
3088d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetRandom_SeqDense(Mat x, PetscRandom rctx)
3089d71ae5a4SJacob Faibussowitsch {
309073a71a0fSBarry Smith   PetscScalar *a;
3091637a0070SStefano Zampini   PetscInt     lda, m, n, i, j;
309273a71a0fSBarry Smith 
309373a71a0fSBarry Smith   PetscFunctionBegin;
30949566063dSJacob Faibussowitsch   PetscCall(MatGetSize(x, &m, &n));
30959566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(x, &lda));
30963faff063SStefano Zampini   PetscCall(MatDenseGetArrayWrite(x, &a));
3097637a0070SStefano Zampini   for (j = 0; j < n; j++) {
309848a46eb9SPierre Jolivet     for (i = 0; i < m; i++) PetscCall(PetscRandomGetValue(rctx, a + j * lda + i));
309973a71a0fSBarry Smith   }
31003faff063SStefano Zampini   PetscCall(MatDenseRestoreArrayWrite(x, &a));
310173a71a0fSBarry Smith   PetscFunctionReturn(0);
310273a71a0fSBarry Smith }
310373a71a0fSBarry Smith 
3104d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A, PetscBool *missing, PetscInt *d)
3105d71ae5a4SJacob Faibussowitsch {
31063b49f96aSBarry Smith   PetscFunctionBegin;
31073b49f96aSBarry Smith   *missing = PETSC_FALSE;
31083b49f96aSBarry Smith   PetscFunctionReturn(0);
31093b49f96aSBarry Smith }
311073a71a0fSBarry Smith 
3111ca15aa20SStefano Zampini /* vals is not const */
3112d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A, PetscInt col, PetscScalar **vals)
3113d71ae5a4SJacob Faibussowitsch {
311486aefd0dSHong Zhang   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
3115ca15aa20SStefano Zampini   PetscScalar  *v;
311686aefd0dSHong Zhang 
311786aefd0dSHong Zhang   PetscFunctionBegin;
311828b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
31199566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
3120ca15aa20SStefano Zampini   *vals = v + col * a->lda;
31219566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
312286aefd0dSHong Zhang   PetscFunctionReturn(0);
312386aefd0dSHong Zhang }
312486aefd0dSHong Zhang 
3125d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A, PetscScalar **vals)
3126d71ae5a4SJacob Faibussowitsch {
312786aefd0dSHong Zhang   PetscFunctionBegin;
3128742765d3SMatthew Knepley   if (vals) *vals = NULL; /* user cannot accidentally use the array later */
312986aefd0dSHong Zhang   PetscFunctionReturn(0);
313086aefd0dSHong Zhang }
3131abc3b08eSStefano Zampini 
3132289bc588SBarry Smith /* -------------------------------------------------------------------*/
3133a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqDense,
3134905e6a2fSBarry Smith                                        MatGetRow_SeqDense,
3135905e6a2fSBarry Smith                                        MatRestoreRow_SeqDense,
3136905e6a2fSBarry Smith                                        MatMult_SeqDense,
313797304618SKris Buschelman                                        /*  4*/ MatMultAdd_SeqDense,
31387c922b88SBarry Smith                                        MatMultTranspose_SeqDense,
31397c922b88SBarry Smith                                        MatMultTransposeAdd_SeqDense,
3140f4259b30SLisandro Dalcin                                        NULL,
3141f4259b30SLisandro Dalcin                                        NULL,
3142f4259b30SLisandro Dalcin                                        NULL,
3143f4259b30SLisandro Dalcin                                        /* 10*/ NULL,
3144905e6a2fSBarry Smith                                        MatLUFactor_SeqDense,
3145905e6a2fSBarry Smith                                        MatCholeskyFactor_SeqDense,
314641f059aeSBarry Smith                                        MatSOR_SeqDense,
3147ec8511deSBarry Smith                                        MatTranspose_SeqDense,
314897304618SKris Buschelman                                        /* 15*/ MatGetInfo_SeqDense,
3149905e6a2fSBarry Smith                                        MatEqual_SeqDense,
3150905e6a2fSBarry Smith                                        MatGetDiagonal_SeqDense,
3151905e6a2fSBarry Smith                                        MatDiagonalScale_SeqDense,
3152905e6a2fSBarry Smith                                        MatNorm_SeqDense,
3153c0aa2d19SHong Zhang                                        /* 20*/ MatAssemblyBegin_SeqDense,
3154c0aa2d19SHong Zhang                                        MatAssemblyEnd_SeqDense,
3155905e6a2fSBarry Smith                                        MatSetOption_SeqDense,
3156905e6a2fSBarry Smith                                        MatZeroEntries_SeqDense,
3157d519adbfSMatthew Knepley                                        /* 24*/ MatZeroRows_SeqDense,
3158f4259b30SLisandro Dalcin                                        NULL,
3159f4259b30SLisandro Dalcin                                        NULL,
3160f4259b30SLisandro Dalcin                                        NULL,
3161f4259b30SLisandro Dalcin                                        NULL,
31624994cf47SJed Brown                                        /* 29*/ MatSetUp_SeqDense,
3163f4259b30SLisandro Dalcin                                        NULL,
3164f4259b30SLisandro Dalcin                                        NULL,
3165f4259b30SLisandro Dalcin                                        NULL,
3166f4259b30SLisandro Dalcin                                        NULL,
3167d519adbfSMatthew Knepley                                        /* 34*/ MatDuplicate_SeqDense,
3168f4259b30SLisandro Dalcin                                        NULL,
3169f4259b30SLisandro Dalcin                                        NULL,
3170f4259b30SLisandro Dalcin                                        NULL,
3171f4259b30SLisandro Dalcin                                        NULL,
3172d519adbfSMatthew Knepley                                        /* 39*/ MatAXPY_SeqDense,
31737dae84e0SHong Zhang                                        MatCreateSubMatrices_SeqDense,
3174f4259b30SLisandro Dalcin                                        NULL,
31754b0e389bSBarry Smith                                        MatGetValues_SeqDense,
3176a5ae1ecdSBarry Smith                                        MatCopy_SeqDense,
3177d519adbfSMatthew Knepley                                        /* 44*/ MatGetRowMax_SeqDense,
3178a5ae1ecdSBarry Smith                                        MatScale_SeqDense,
31792f605a99SJose E. Roman                                        MatShift_SeqDense,
3180f4259b30SLisandro Dalcin                                        NULL,
31813f49a652SStefano Zampini                                        MatZeroRowsColumns_SeqDense,
318273a71a0fSBarry Smith                                        /* 49*/ MatSetRandom_SeqDense,
3183f4259b30SLisandro Dalcin                                        NULL,
3184f4259b30SLisandro Dalcin                                        NULL,
3185f4259b30SLisandro Dalcin                                        NULL,
3186f4259b30SLisandro Dalcin                                        NULL,
3187f4259b30SLisandro Dalcin                                        /* 54*/ NULL,
3188f4259b30SLisandro Dalcin                                        NULL,
3189f4259b30SLisandro Dalcin                                        NULL,
3190f4259b30SLisandro Dalcin                                        NULL,
3191f4259b30SLisandro Dalcin                                        NULL,
3192023c16fcSToby Isaac                                        /* 59*/ MatCreateSubMatrix_SeqDense,
3193e03a110bSBarry Smith                                        MatDestroy_SeqDense,
3194e03a110bSBarry Smith                                        MatView_SeqDense,
3195f4259b30SLisandro Dalcin                                        NULL,
3196f4259b30SLisandro Dalcin                                        NULL,
3197f4259b30SLisandro Dalcin                                        /* 64*/ NULL,
3198f4259b30SLisandro Dalcin                                        NULL,
3199f4259b30SLisandro Dalcin                                        NULL,
3200f4259b30SLisandro Dalcin                                        NULL,
3201f4259b30SLisandro Dalcin                                        NULL,
3202d519adbfSMatthew Knepley                                        /* 69*/ MatGetRowMaxAbs_SeqDense,
3203f4259b30SLisandro Dalcin                                        NULL,
3204f4259b30SLisandro Dalcin                                        NULL,
3205f4259b30SLisandro Dalcin                                        NULL,
3206f4259b30SLisandro Dalcin                                        NULL,
3207f4259b30SLisandro Dalcin                                        /* 74*/ NULL,
3208f4259b30SLisandro Dalcin                                        NULL,
3209f4259b30SLisandro Dalcin                                        NULL,
3210f4259b30SLisandro Dalcin                                        NULL,
3211f4259b30SLisandro Dalcin                                        NULL,
3212f4259b30SLisandro Dalcin                                        /* 79*/ NULL,
3213f4259b30SLisandro Dalcin                                        NULL,
3214f4259b30SLisandro Dalcin                                        NULL,
3215f4259b30SLisandro Dalcin                                        NULL,
32165bba2384SShri Abhyankar                                        /* 83*/ MatLoad_SeqDense,
3217637a0070SStefano Zampini                                        MatIsSymmetric_SeqDense,
32181cbb95d3SBarry Smith                                        MatIsHermitian_SeqDense,
3219f4259b30SLisandro Dalcin                                        NULL,
3220f4259b30SLisandro Dalcin                                        NULL,
3221f4259b30SLisandro Dalcin                                        NULL,
3222f4259b30SLisandro Dalcin                                        /* 89*/ NULL,
3223f4259b30SLisandro Dalcin                                        NULL,
3224a9fe9ddaSSatish Balay                                        MatMatMultNumeric_SeqDense_SeqDense,
3225f4259b30SLisandro Dalcin                                        NULL,
3226f4259b30SLisandro Dalcin                                        NULL,
3227f4259b30SLisandro Dalcin                                        /* 94*/ NULL,
3228f4259b30SLisandro Dalcin                                        NULL,
3229f4259b30SLisandro Dalcin                                        NULL,
323069f65d41SStefano Zampini                                        MatMatTransposeMultNumeric_SeqDense_SeqDense,
3231f4259b30SLisandro Dalcin                                        NULL,
32324222ddf1SHong Zhang                                        /* 99*/ MatProductSetFromOptions_SeqDense,
3233f4259b30SLisandro Dalcin                                        NULL,
3234f4259b30SLisandro Dalcin                                        NULL,
3235ba337c44SJed Brown                                        MatConjugate_SeqDense,
3236f4259b30SLisandro Dalcin                                        NULL,
3237f4259b30SLisandro Dalcin                                        /*104*/ NULL,
3238ba337c44SJed Brown                                        MatRealPart_SeqDense,
3239ba337c44SJed Brown                                        MatImaginaryPart_SeqDense,
3240f4259b30SLisandro Dalcin                                        NULL,
3241f4259b30SLisandro Dalcin                                        NULL,
3242f4259b30SLisandro Dalcin                                        /*109*/ NULL,
3243f4259b30SLisandro Dalcin                                        NULL,
32448d0534beSBarry Smith                                        MatGetRowMin_SeqDense,
3245aabbc4fbSShri Abhyankar                                        MatGetColumnVector_SeqDense,
32463b49f96aSBarry Smith                                        MatMissingDiagonal_SeqDense,
3247f4259b30SLisandro Dalcin                                        /*114*/ NULL,
3248f4259b30SLisandro Dalcin                                        NULL,
3249f4259b30SLisandro Dalcin                                        NULL,
3250f4259b30SLisandro Dalcin                                        NULL,
3251f4259b30SLisandro Dalcin                                        NULL,
3252f4259b30SLisandro Dalcin                                        /*119*/ NULL,
3253f4259b30SLisandro Dalcin                                        NULL,
3254f4259b30SLisandro Dalcin                                        NULL,
3255f4259b30SLisandro Dalcin                                        NULL,
3256f4259b30SLisandro Dalcin                                        NULL,
3257f4259b30SLisandro Dalcin                                        /*124*/ NULL,
3258a873a8cdSSam Reynolds                                        MatGetColumnReductions_SeqDense,
3259f4259b30SLisandro Dalcin                                        NULL,
3260f4259b30SLisandro Dalcin                                        NULL,
3261f4259b30SLisandro Dalcin                                        NULL,
3262f4259b30SLisandro Dalcin                                        /*129*/ NULL,
3263f4259b30SLisandro Dalcin                                        NULL,
3264f4259b30SLisandro Dalcin                                        NULL,
326575648e8dSHong Zhang                                        MatTransposeMatMultNumeric_SeqDense_SeqDense,
3266f4259b30SLisandro Dalcin                                        NULL,
3267f4259b30SLisandro Dalcin                                        /*134*/ NULL,
3268f4259b30SLisandro Dalcin                                        NULL,
3269f4259b30SLisandro Dalcin                                        NULL,
3270f4259b30SLisandro Dalcin                                        NULL,
3271f4259b30SLisandro Dalcin                                        NULL,
3272f4259b30SLisandro Dalcin                                        /*139*/ NULL,
3273f4259b30SLisandro Dalcin                                        NULL,
3274f4259b30SLisandro Dalcin                                        NULL,
3275f4259b30SLisandro Dalcin                                        NULL,
3276f4259b30SLisandro Dalcin                                        NULL,
32774222ddf1SHong Zhang                                        MatCreateMPIMatConcatenateSeqMat_SeqDense,
3278f4259b30SLisandro Dalcin                                        /*145*/ NULL,
3279f4259b30SLisandro Dalcin                                        NULL,
328099a7f59eSMark Adams                                        NULL,
328199a7f59eSMark Adams                                        NULL,
32827fb60732SBarry Smith                                        NULL,
3283dec0b466SHong Zhang                                        /*150*/ NULL,
3284dec0b466SHong Zhang                                        NULL};
328590ace30eSBarry Smith 
32864b828684SBarry Smith /*@C
328711a5261eSBarry Smith    MatCreateSeqDense - Creates a `MATSEQDENSE` that
3288d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
3289d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
3290289bc588SBarry Smith 
3291d083f849SBarry Smith    Collective
3292db81eaa0SLois Curfman McInnes 
329320563c6bSBarry Smith    Input Parameters:
329411a5261eSBarry Smith +  comm - MPI communicator, set to `PETSC_COMM_SELF`
32950c775827SLois Curfman McInnes .  m - number of rows
329618f449edSLois Curfman McInnes .  n - number of columns
32970298fd71SBarry Smith -  data - optional location of matrix data in column major order.  Set data=NULL for PETSc
3298dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
329920563c6bSBarry Smith 
330020563c6bSBarry Smith    Output Parameter:
330144cd7ae7SLois Curfman McInnes .  A - the matrix
330220563c6bSBarry Smith 
330311a5261eSBarry Smith    Note:
330418f449edSLois Curfman McInnes    The data input variable is intended primarily for Fortran programmers
330518f449edSLois Curfman McInnes    who wish to allocate their own matrix memory space.  Most users should
33060298fd71SBarry Smith    set data=NULL.
330718f449edSLois Curfman McInnes 
3308027ccd11SLois Curfman McInnes    Level: intermediate
3309027ccd11SLois Curfman McInnes 
331011a5261eSBarry Smith .seealso: `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()`
331120563c6bSBarry Smith @*/
3312d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateSeqDense(MPI_Comm comm, PetscInt m, PetscInt n, PetscScalar *data, Mat *A)
3313d71ae5a4SJacob Faibussowitsch {
33143a40ed3dSBarry Smith   PetscFunctionBegin;
33159566063dSJacob Faibussowitsch   PetscCall(MatCreate(comm, A));
33169566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*A, m, n, m, n));
33179566063dSJacob Faibussowitsch   PetscCall(MatSetType(*A, MATSEQDENSE));
33189566063dSJacob Faibussowitsch   PetscCall(MatSeqDenseSetPreallocation(*A, data));
3319273d9f13SBarry Smith   PetscFunctionReturn(0);
3320273d9f13SBarry Smith }
3321273d9f13SBarry Smith 
3322273d9f13SBarry Smith /*@C
332311a5261eSBarry Smith    MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements of a `MATSEQDENSE` matrix
3324273d9f13SBarry Smith 
3325d083f849SBarry Smith    Collective
3326273d9f13SBarry Smith 
3327273d9f13SBarry Smith    Input Parameters:
33281c4f3114SJed Brown +  B - the matrix
33290298fd71SBarry Smith -  data - the array (or NULL)
3330273d9f13SBarry Smith 
333111a5261eSBarry Smith    Note:
3332273d9f13SBarry Smith    The data input variable is intended primarily for Fortran programmers
3333273d9f13SBarry Smith    who wish to allocate their own matrix memory space.  Most users should
3334284134d9SBarry Smith    need not call this routine.
3335273d9f13SBarry Smith 
3336273d9f13SBarry Smith    Level: intermediate
3337273d9f13SBarry Smith 
333811a5261eSBarry Smith .seealso: `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()`, `MatDenseSetLDA()`
3339273d9f13SBarry Smith @*/
3340d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation(Mat B, PetscScalar data[])
3341d71ae5a4SJacob Faibussowitsch {
3342a23d5eceSKris Buschelman   PetscFunctionBegin;
3343d5ea218eSStefano Zampini   PetscValidHeaderSpecific(B, MAT_CLASSID, 1);
3344cac4c232SBarry Smith   PetscTryMethod(B, "MatSeqDenseSetPreallocation_C", (Mat, PetscScalar[]), (B, data));
3345a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3346a23d5eceSKris Buschelman }
3347a23d5eceSKris Buschelman 
3348d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation_SeqDense(Mat B, PetscScalar *data)
3349d71ae5a4SJacob Faibussowitsch {
3350ad16ce7aSStefano Zampini   Mat_SeqDense *b = (Mat_SeqDense *)B->data;
3351273d9f13SBarry Smith 
3352273d9f13SBarry Smith   PetscFunctionBegin;
335328b400f6SJacob Faibussowitsch   PetscCheck(!b->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
3354273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
3355a868139aSShri Abhyankar 
33569566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(B->rmap));
33579566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(B->cmap));
335834ef9618SShri Abhyankar 
3359ad16ce7aSStefano Zampini   if (b->lda <= 0) b->lda = B->rmap->n;
336086d161a7SShri Abhyankar 
33619e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
33629566063dSJacob Faibussowitsch     if (!b->user_alloc) PetscCall(PetscFree(b->v));
33639566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1((size_t)b->lda * B->cmap->n, &b->v));
33642205254eSKarl Rupp 
33659e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
3366273d9f13SBarry Smith   } else { /* user-allocated storage */
33679566063dSJacob Faibussowitsch     if (!b->user_alloc) PetscCall(PetscFree(b->v));
3368273d9f13SBarry Smith     b->v          = data;
3369273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
3370273d9f13SBarry Smith   }
33710450473dSBarry Smith   B->assembled = PETSC_TRUE;
3372273d9f13SBarry Smith   PetscFunctionReturn(0);
3373273d9f13SBarry Smith }
3374273d9f13SBarry Smith 
337565b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
3376d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype, MatReuse reuse, Mat *newmat)
3377d71ae5a4SJacob Faibussowitsch {
3378d77f618aSHong Zhang   Mat                mat_elemental;
33791683a169SBarry Smith   const PetscScalar *array;
33801683a169SBarry Smith   PetscScalar       *v_colwise;
3381d77f618aSHong Zhang   PetscInt           M = A->rmap->N, N = A->cmap->N, i, j, k, *rows, *cols;
3382d77f618aSHong Zhang 
33838baccfbdSHong Zhang   PetscFunctionBegin;
33849566063dSJacob Faibussowitsch   PetscCall(PetscMalloc3(M * N, &v_colwise, M, &rows, N, &cols));
33859566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &array));
3386d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
3387d77f618aSHong Zhang   k = 0;
3388d77f618aSHong Zhang   for (j = 0; j < N; j++) {
3389d77f618aSHong Zhang     cols[j] = j;
3390ad540459SPierre Jolivet     for (i = 0; i < M; i++) v_colwise[j * M + i] = array[k++];
3391d77f618aSHong Zhang   }
3392ad540459SPierre Jolivet   for (i = 0; i < M; i++) rows[i] = i;
33939566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &array));
3394d77f618aSHong Zhang 
33959566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental));
33969566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(mat_elemental, PETSC_DECIDE, PETSC_DECIDE, M, N));
33979566063dSJacob Faibussowitsch   PetscCall(MatSetType(mat_elemental, MATELEMENTAL));
33989566063dSJacob Faibussowitsch   PetscCall(MatSetUp(mat_elemental));
3399d77f618aSHong Zhang 
3400d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
34019566063dSJacob Faibussowitsch   PetscCall(MatSetValues(mat_elemental, M, rows, N, cols, v_colwise, ADD_VALUES));
34029566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY));
34039566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY));
34049566063dSJacob Faibussowitsch   PetscCall(PetscFree3(v_colwise, rows, cols));
3405d77f618aSHong Zhang 
3406511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
34079566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A, &mat_elemental));
3408d77f618aSHong Zhang   } else {
3409d77f618aSHong Zhang     *newmat = mat_elemental;
3410d77f618aSHong Zhang   }
34118baccfbdSHong Zhang   PetscFunctionReturn(0);
34128baccfbdSHong Zhang }
341365b80a83SHong Zhang #endif
34148baccfbdSHong Zhang 
3415d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA_SeqDense(Mat B, PetscInt lda)
3416d71ae5a4SJacob Faibussowitsch {
34171b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense *)B->data;
34187422da62SJose E. Roman   PetscBool     data;
341921a2c019SBarry Smith 
34201b807ce4Svictorle   PetscFunctionBegin;
34217422da62SJose E. Roman   data = (PetscBool)((B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE);
3422aed4548fSBarry Smith   PetscCheck(b->user_alloc || !data || b->lda == lda, PETSC_COMM_SELF, PETSC_ERR_ORDER, "LDA cannot be changed after allocation of internal storage");
342308401ef6SPierre Jolivet   PetscCheck(lda >= B->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "LDA %" PetscInt_FMT " must be at least matrix dimension %" PetscInt_FMT, lda, B->rmap->n);
34241b807ce4Svictorle   b->lda = lda;
34251b807ce4Svictorle   PetscFunctionReturn(0);
34261b807ce4Svictorle }
34271b807ce4Svictorle 
3428d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm, Mat inmat, PetscInt n, MatReuse scall, Mat *outmat)
3429d71ae5a4SJacob Faibussowitsch {
3430d528f656SJakub Kruzik   PetscFunctionBegin;
34319566063dSJacob Faibussowitsch   PetscCall(MatCreateMPIMatConcatenateSeqMat_MPIDense(comm, inmat, n, scall, outmat));
3432d528f656SJakub Kruzik   PetscFunctionReturn(0);
3433d528f656SJakub Kruzik }
3434d528f656SJakub Kruzik 
3435d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A, PetscInt col, Vec *v)
3436d71ae5a4SJacob Faibussowitsch {
34376947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
34386947451fSStefano Zampini 
34396947451fSStefano Zampini   PetscFunctionBegin;
344028b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
344128b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
34424dfa11a4SJacob Faibussowitsch   if (!a->cvec) { PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec)); }
34436947451fSStefano Zampini   a->vecinuse = col + 1;
34449566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, (PetscScalar **)&a->ptrinuse));
34459566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda));
34466947451fSStefano Zampini   *v = a->cvec;
34476947451fSStefano Zampini   PetscFunctionReturn(0);
34486947451fSStefano Zampini }
34496947451fSStefano Zampini 
3450d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A, PetscInt col, Vec *v)
3451d71ae5a4SJacob Faibussowitsch {
34526947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
34536947451fSStefano Zampini 
34546947451fSStefano Zampini   PetscFunctionBegin;
345528b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first");
345628b400f6SJacob Faibussowitsch   PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector");
34576947451fSStefano Zampini   a->vecinuse = 0;
34589566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, (PetscScalar **)&a->ptrinuse));
34599566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
346075f6d85dSStefano Zampini   if (v) *v = NULL;
34616947451fSStefano Zampini   PetscFunctionReturn(0);
34626947451fSStefano Zampini }
34636947451fSStefano Zampini 
3464d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v)
3465d71ae5a4SJacob Faibussowitsch {
34666947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
34676947451fSStefano Zampini 
34686947451fSStefano Zampini   PetscFunctionBegin;
346928b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
347028b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
34714dfa11a4SJacob Faibussowitsch   if (!a->cvec) { PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec)); }
34726947451fSStefano Zampini   a->vecinuse = col + 1;
34739566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &a->ptrinuse));
34749566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda));
34759566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(a->cvec));
34766947451fSStefano Zampini   *v = a->cvec;
34776947451fSStefano Zampini   PetscFunctionReturn(0);
34786947451fSStefano Zampini }
34796947451fSStefano Zampini 
3480d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v)
3481d71ae5a4SJacob Faibussowitsch {
34826947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
34836947451fSStefano Zampini 
34846947451fSStefano Zampini   PetscFunctionBegin;
348528b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first");
348628b400f6SJacob Faibussowitsch   PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector");
34876947451fSStefano Zampini   a->vecinuse = 0;
34889566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &a->ptrinuse));
34899566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(a->cvec));
34909566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
349175f6d85dSStefano Zampini   if (v) *v = NULL;
34926947451fSStefano Zampini   PetscFunctionReturn(0);
34936947451fSStefano Zampini }
34946947451fSStefano Zampini 
3495d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v)
3496d71ae5a4SJacob Faibussowitsch {
34976947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
34986947451fSStefano Zampini 
34996947451fSStefano Zampini   PetscFunctionBegin;
350028b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
350128b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
35024dfa11a4SJacob Faibussowitsch   if (!a->cvec) { PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec)); }
35036947451fSStefano Zampini   a->vecinuse = col + 1;
35049566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(A, (PetscScalar **)&a->ptrinuse));
35059566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda));
35066947451fSStefano Zampini   *v = a->cvec;
35076947451fSStefano Zampini   PetscFunctionReturn(0);
35086947451fSStefano Zampini }
35096947451fSStefano Zampini 
3510d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v)
3511d71ae5a4SJacob Faibussowitsch {
35126947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
35136947451fSStefano Zampini 
35146947451fSStefano Zampini   PetscFunctionBegin;
351528b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first");
351628b400f6SJacob Faibussowitsch   PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector");
35176947451fSStefano Zampini   a->vecinuse = 0;
35189566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(A, (PetscScalar **)&a->ptrinuse));
35199566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
352075f6d85dSStefano Zampini   if (v) *v = NULL;
35216947451fSStefano Zampini   PetscFunctionReturn(0);
35226947451fSStefano Zampini }
35236947451fSStefano Zampini 
3524d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v)
3525d71ae5a4SJacob Faibussowitsch {
35265ea7661aSPierre Jolivet   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
35275ea7661aSPierre Jolivet 
35285ea7661aSPierre Jolivet   PetscFunctionBegin;
352928b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
353028b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
3531a2748737SPierre Jolivet   if (a->cmat && (cend - cbegin != a->cmat->cmap->N || rend - rbegin != a->cmat->rmap->N)) PetscCall(MatDestroy(&a->cmat));
35325ea7661aSPierre Jolivet   if (!a->cmat) {
3533a2748737SPierre Jolivet     PetscCall(MatCreateDense(PetscObjectComm((PetscObject)A), rend - rbegin, PETSC_DECIDE, rend - rbegin, cend - cbegin, a->v + rbegin + (size_t)cbegin * a->lda, &a->cmat));
35345ea7661aSPierre Jolivet   } else {
3535a2748737SPierre Jolivet     PetscCall(MatDensePlaceArray(a->cmat, a->v + rbegin + (size_t)cbegin * a->lda));
35365ea7661aSPierre Jolivet   }
35379566063dSJacob Faibussowitsch   PetscCall(MatDenseSetLDA(a->cmat, a->lda));
35385ea7661aSPierre Jolivet   a->matinuse = cbegin + 1;
35395ea7661aSPierre Jolivet   *v          = a->cmat;
354047d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
354175f6d85dSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
354275f6d85dSStefano Zampini #endif
35435ea7661aSPierre Jolivet   PetscFunctionReturn(0);
35445ea7661aSPierre Jolivet }
35455ea7661aSPierre Jolivet 
3546d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A, Mat *v)
3547d71ae5a4SJacob Faibussowitsch {
35485ea7661aSPierre Jolivet   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
35495ea7661aSPierre Jolivet 
35505ea7661aSPierre Jolivet   PetscFunctionBegin;
355128b400f6SJacob Faibussowitsch   PetscCheck(a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetSubMatrix() first");
355228b400f6SJacob Faibussowitsch   PetscCheck(a->cmat, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column matrix");
355308401ef6SPierre Jolivet   PetscCheck(*v == a->cmat, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not the matrix obtained from MatDenseGetSubMatrix()");
35545ea7661aSPierre Jolivet   a->matinuse = 0;
35559566063dSJacob Faibussowitsch   PetscCall(MatDenseResetArray(a->cmat));
3556742765d3SMatthew Knepley   if (v) *v = NULL;
355747d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
35583faff063SStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
35593faff063SStefano Zampini #endif
35605ea7661aSPierre Jolivet   PetscFunctionReturn(0);
35615ea7661aSPierre Jolivet }
35625ea7661aSPierre Jolivet 
35630bad9183SKris Buschelman /*MC
3564fafad747SKris Buschelman    MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices.
35650bad9183SKris Buschelman 
35660bad9183SKris Buschelman    Options Database Keys:
356711a5261eSBarry Smith . -mat_type seqdense - sets the matrix type to `MATSEQDENSE` during a call to `MatSetFromOptions()`
35680bad9183SKris Buschelman 
35690bad9183SKris Buschelman   Level: beginner
35700bad9183SKris Buschelman 
357111a5261eSBarry Smith .seealso: `MATSEQDENSE`, `MatCreateSeqDense()`
35720bad9183SKris Buschelman M*/
3573d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreate_SeqDense(Mat B)
3574d71ae5a4SJacob Faibussowitsch {
3575273d9f13SBarry Smith   Mat_SeqDense *b;
35767c334f02SBarry Smith   PetscMPIInt   size;
3577273d9f13SBarry Smith 
3578273d9f13SBarry Smith   PetscFunctionBegin;
35799566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)B), &size));
358008401ef6SPierre Jolivet   PetscCheck(size <= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Comm must be of size 1");
358155659b69SBarry Smith 
35824dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&b));
35839566063dSJacob Faibussowitsch   PetscCall(PetscMemcpy(B->ops, &MatOps_Values, sizeof(struct _MatOps)));
358444cd7ae7SLois Curfman McInnes   B->data = (void *)b;
358518f449edSLois Curfman McInnes 
3586273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
35874e220ebcSLois Curfman McInnes 
35889566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatQRFactor_C", MatQRFactor_SeqDense));
35899566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetLDA_C", MatDenseGetLDA_SeqDense));
35909566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseSetLDA_C", MatDenseSetLDA_SeqDense));
35919566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArray_C", MatDenseGetArray_SeqDense));
35929566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArray_C", MatDenseRestoreArray_SeqDense));
35939566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDensePlaceArray_C", MatDensePlaceArray_SeqDense));
35949566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseResetArray_C", MatDenseResetArray_SeqDense));
35959566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseReplaceArray_C", MatDenseReplaceArray_SeqDense));
35969566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayRead_C", MatDenseGetArray_SeqDense));
35979566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayRead_C", MatDenseRestoreArray_SeqDense));
35989566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayWrite_C", MatDenseGetArray_SeqDense));
35999566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayWrite_C", MatDenseRestoreArray_SeqDense));
36009566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqaij_C", MatConvert_SeqDense_SeqAIJ));
36018baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
36029566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_elemental_C", MatConvert_SeqDense_Elemental));
36038baccfbdSHong Zhang #endif
3604d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
36059566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_scalapack_C", MatConvert_Dense_ScaLAPACK));
3606d24d4204SJose E. Roman #endif
36072bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
36089566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensecuda_C", MatConvert_SeqDense_SeqDenseCUDA));
36099566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", MatProductSetFromOptions_SeqDense));
36109566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdense_C", MatProductSetFromOptions_SeqDense));
36119566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensecuda_C", MatProductSetFromOptions_SeqDense));
36122bf066beSStefano Zampini #endif
361347d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP)
361447d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensehip_C", MatConvert_SeqDense_SeqDenseHIP));
361547d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensehip_seqdensehip_C", MatProductSetFromOptions_SeqDense));
361647d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensehip_seqdense_C", MatProductSetFromOptions_SeqDense));
361747d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensehip_C", MatProductSetFromOptions_SeqDense));
361847d993e7Ssuyashtn #endif
36199566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSeqDenseSetPreallocation_C", MatSeqDenseSetPreallocation_SeqDense));
36209566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqaij_seqdense_C", MatProductSetFromOptions_SeqAIJ_SeqDense));
36219566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdense_C", MatProductSetFromOptions_SeqDense));
36229566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense));
36239566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqsbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense));
362496e6d5c4SRichard Tran Mills 
36259566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumn_C", MatDenseGetColumn_SeqDense));
36269566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumn_C", MatDenseRestoreColumn_SeqDense));
36279566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVec_C", MatDenseGetColumnVec_SeqDense));
36289566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVec_C", MatDenseRestoreColumnVec_SeqDense));
36299566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecRead_C", MatDenseGetColumnVecRead_SeqDense));
36309566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecRead_C", MatDenseRestoreColumnVecRead_SeqDense));
36319566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecWrite_C", MatDenseGetColumnVecWrite_SeqDense));
36329566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecWrite_C", MatDenseRestoreColumnVecWrite_SeqDense));
36339566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetSubMatrix_C", MatDenseGetSubMatrix_SeqDense));
36349566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreSubMatrix_C", MatDenseRestoreSubMatrix_SeqDense));
36359566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)B, MATSEQDENSE));
36363a40ed3dSBarry Smith   PetscFunctionReturn(0);
3637289bc588SBarry Smith }
363886aefd0dSHong Zhang 
363986aefd0dSHong Zhang /*@C
364011a5261eSBarry Smith    MatDenseGetColumn - gives access to a column of a dense matrix. This is only the local part of the column. You MUST call `MatDenseRestoreColumn()` to avoid memory bleeding.
364186aefd0dSHong Zhang 
364286aefd0dSHong Zhang    Not Collective
364386aefd0dSHong Zhang 
36445ea7661aSPierre Jolivet    Input Parameters:
364511a5261eSBarry Smith +  mat - a `MATSEQDENSE` or `MATMPIDENSE` matrix
364686aefd0dSHong Zhang -  col - column index
364786aefd0dSHong Zhang 
364886aefd0dSHong Zhang    Output Parameter:
364986aefd0dSHong Zhang .  vals - pointer to the data
365086aefd0dSHong Zhang 
365186aefd0dSHong Zhang    Level: intermediate
365286aefd0dSHong Zhang 
365311a5261eSBarry Smith    Note:
365411a5261eSBarry Smith    Use `MatDenseGetColumnVec()` to get access to a column of a `MATDENSE` treated as a `Vec`
365511a5261eSBarry Smith 
365611a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreColumn()`, `MatDenseGetColumnVec()`
365786aefd0dSHong Zhang @*/
3658d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumn(Mat A, PetscInt col, PetscScalar **vals)
3659d71ae5a4SJacob Faibussowitsch {
366086aefd0dSHong Zhang   PetscFunctionBegin;
3661d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
3662d5ea218eSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
3663d5ea218eSStefano Zampini   PetscValidPointer(vals, 3);
3664cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumn_C", (Mat, PetscInt, PetscScalar **), (A, col, vals));
366586aefd0dSHong Zhang   PetscFunctionReturn(0);
366686aefd0dSHong Zhang }
366786aefd0dSHong Zhang 
366886aefd0dSHong Zhang /*@C
366911a5261eSBarry Smith    MatDenseRestoreColumn - returns access to a column of a `MATDENSE` matrix which is returned by `MatDenseGetColumn()`.
367086aefd0dSHong Zhang 
367186aefd0dSHong Zhang    Not Collective
367286aefd0dSHong Zhang 
3673742765d3SMatthew Knepley    Input Parameters:
367411a5261eSBarry Smith +  mat - a `MATSEQDENSE` or `MATMPIDENSE` matrix
3675742765d3SMatthew Knepley -  vals - pointer to the data (may be NULL)
367686aefd0dSHong Zhang 
367786aefd0dSHong Zhang    Level: intermediate
367886aefd0dSHong Zhang 
367911a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetColumn()`
368086aefd0dSHong Zhang @*/
3681d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumn(Mat A, PetscScalar **vals)
3682d71ae5a4SJacob Faibussowitsch {
368386aefd0dSHong Zhang   PetscFunctionBegin;
3684d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
3685d5ea218eSStefano Zampini   PetscValidPointer(vals, 2);
3686cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumn_C", (Mat, PetscScalar **), (A, vals));
368786aefd0dSHong Zhang   PetscFunctionReturn(0);
368886aefd0dSHong Zhang }
36896947451fSStefano Zampini 
36900f74d2c1SSatish Balay /*@
369111a5261eSBarry Smith    MatDenseGetColumnVec - Gives read-write access to a column of a `MATDENSE` matrix, represented as a `Vec`.
36926947451fSStefano Zampini 
36936947451fSStefano Zampini    Collective
36946947451fSStefano Zampini 
36955ea7661aSPierre Jolivet    Input Parameters:
369611a5261eSBarry Smith +  mat - the `Mat` object
36976947451fSStefano Zampini -  col - the column index
36986947451fSStefano Zampini 
36996947451fSStefano Zampini    Output Parameter:
37006947451fSStefano Zampini .  v - the vector
37016947451fSStefano Zampini 
37026947451fSStefano Zampini    Notes:
370311a5261eSBarry Smith      The vector is owned by PETSc. Users need to call `MatDenseRestoreColumnVec()` when the vector is no longer needed.
370411a5261eSBarry Smith 
370511a5261eSBarry Smith      Use `MatDenseGetColumnVecRead()` to obtain read-only access or `MatDenseGetColumnVecWrite()` for write-only access.
37066947451fSStefano Zampini 
37076947451fSStefano Zampini    Level: intermediate
37086947451fSStefano Zampini 
370947d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`, `MatDenseGetColumn()`
37106947451fSStefano Zampini @*/
3711d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec(Mat A, PetscInt col, Vec *v)
3712d71ae5a4SJacob Faibussowitsch {
37136947451fSStefano Zampini   PetscFunctionBegin;
37146947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
37156947451fSStefano Zampini   PetscValidType(A, 1);
37166947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
37176947451fSStefano Zampini   PetscValidPointer(v, 3);
371828b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
37192cf15c64SPierre Jolivet   PetscCheck(col >= 0 && col < A->cmap->N, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")", col, A->cmap->N);
3720cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v));
37216947451fSStefano Zampini   PetscFunctionReturn(0);
37226947451fSStefano Zampini }
37236947451fSStefano Zampini 
37240f74d2c1SSatish Balay /*@
37256947451fSStefano Zampini    MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVec().
37266947451fSStefano Zampini 
37276947451fSStefano Zampini    Collective
37286947451fSStefano Zampini 
37295ea7661aSPierre Jolivet    Input Parameters:
37306947451fSStefano Zampini +  mat - the Mat object
37316947451fSStefano Zampini .  col - the column index
3732742765d3SMatthew Knepley -  v - the Vec object (may be NULL)
37336947451fSStefano Zampini 
37346947451fSStefano Zampini    Level: intermediate
37356947451fSStefano Zampini 
373647d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
37376947451fSStefano Zampini @*/
3738d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec(Mat A, PetscInt col, Vec *v)
3739d71ae5a4SJacob Faibussowitsch {
37406947451fSStefano Zampini   PetscFunctionBegin;
37416947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
37426947451fSStefano Zampini   PetscValidType(A, 1);
37436947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
374408401ef6SPierre Jolivet   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
37452cf15c64SPierre Jolivet   PetscCheck(col >= 0 && col < A->cmap->N, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")", col, A->cmap->N);
3746cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v));
37476947451fSStefano Zampini   PetscFunctionReturn(0);
37486947451fSStefano Zampini }
37496947451fSStefano Zampini 
37500f74d2c1SSatish Balay /*@
37516947451fSStefano Zampini    MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a Vec.
37526947451fSStefano Zampini 
37536947451fSStefano Zampini    Collective
37546947451fSStefano Zampini 
37555ea7661aSPierre Jolivet    Input Parameters:
37566947451fSStefano Zampini +  mat - the Mat object
37576947451fSStefano Zampini -  col - the column index
37586947451fSStefano Zampini 
37596947451fSStefano Zampini    Output Parameter:
37606947451fSStefano Zampini .  v - the vector
37616947451fSStefano Zampini 
37626947451fSStefano Zampini    Notes:
37636947451fSStefano Zampini      The vector is owned by PETSc and users cannot modify it.
376411a5261eSBarry Smith 
37656947451fSStefano Zampini      Users need to call MatDenseRestoreColumnVecRead() when the vector is no longer needed.
376611a5261eSBarry Smith 
37676947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecWrite() for write-only access.
37686947451fSStefano Zampini 
37696947451fSStefano Zampini    Level: intermediate
37706947451fSStefano Zampini 
377147d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
37726947451fSStefano Zampini @*/
3773d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead(Mat A, PetscInt col, Vec *v)
3774d71ae5a4SJacob Faibussowitsch {
37756947451fSStefano Zampini   PetscFunctionBegin;
37766947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
37776947451fSStefano Zampini   PetscValidType(A, 1);
37786947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
37796947451fSStefano Zampini   PetscValidPointer(v, 3);
378028b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
37812cf15c64SPierre Jolivet   PetscCheck(col >= 0 && col < A->cmap->N, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")", col, A->cmap->N);
3782cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v));
37836947451fSStefano Zampini   PetscFunctionReturn(0);
37846947451fSStefano Zampini }
37856947451fSStefano Zampini 
37860f74d2c1SSatish Balay /*@
37876947451fSStefano Zampini    MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecRead().
37886947451fSStefano Zampini 
37896947451fSStefano Zampini    Collective
37906947451fSStefano Zampini 
37915ea7661aSPierre Jolivet    Input Parameters:
37926947451fSStefano Zampini +  mat - the Mat object
37936947451fSStefano Zampini .  col - the column index
3794742765d3SMatthew Knepley -  v - the Vec object (may be NULL)
37956947451fSStefano Zampini 
37966947451fSStefano Zampini    Level: intermediate
37976947451fSStefano Zampini 
379847d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecWrite()`
37996947451fSStefano Zampini @*/
3800d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead(Mat A, PetscInt col, Vec *v)
3801d71ae5a4SJacob Faibussowitsch {
38026947451fSStefano Zampini   PetscFunctionBegin;
38036947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
38046947451fSStefano Zampini   PetscValidType(A, 1);
38056947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
380608401ef6SPierre Jolivet   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
38072cf15c64SPierre Jolivet   PetscCheck(col >= 0 && col < A->cmap->N, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")", col, A->cmap->N);
3808cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v));
38096947451fSStefano Zampini   PetscFunctionReturn(0);
38106947451fSStefano Zampini }
38116947451fSStefano Zampini 
38120f74d2c1SSatish Balay /*@
38136947451fSStefano Zampini    MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a Vec.
38146947451fSStefano Zampini 
38156947451fSStefano Zampini    Collective
38166947451fSStefano Zampini 
38175ea7661aSPierre Jolivet    Input Parameters:
38186947451fSStefano Zampini +  mat - the Mat object
38196947451fSStefano Zampini -  col - the column index
38206947451fSStefano Zampini 
38216947451fSStefano Zampini    Output Parameter:
38226947451fSStefano Zampini .  v - the vector
38236947451fSStefano Zampini 
38246947451fSStefano Zampini    Notes:
38256947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVecWrite() when the vector is no longer needed.
382611a5261eSBarry Smith 
38276947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecRead() for read-only access.
38286947451fSStefano Zampini 
38296947451fSStefano Zampini    Level: intermediate
38306947451fSStefano Zampini 
383147d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
38326947451fSStefano Zampini @*/
3833d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite(Mat A, PetscInt col, Vec *v)
3834d71ae5a4SJacob Faibussowitsch {
38356947451fSStefano Zampini   PetscFunctionBegin;
38366947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
38376947451fSStefano Zampini   PetscValidType(A, 1);
38386947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
38396947451fSStefano Zampini   PetscValidPointer(v, 3);
384028b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
3841aed4548fSBarry Smith   PetscCheck(col >= 0 && col < A->cmap->N, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")", col, A->cmap->N);
3842cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v));
38436947451fSStefano Zampini   PetscFunctionReturn(0);
38446947451fSStefano Zampini }
38456947451fSStefano Zampini 
38460f74d2c1SSatish Balay /*@
38476947451fSStefano Zampini    MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecWrite().
38486947451fSStefano Zampini 
38496947451fSStefano Zampini    Collective
38506947451fSStefano Zampini 
38515ea7661aSPierre Jolivet    Input Parameters:
38526947451fSStefano Zampini +  mat - the Mat object
38536947451fSStefano Zampini .  col - the column index
3854742765d3SMatthew Knepley -  v - the Vec object (may be NULL)
38556947451fSStefano Zampini 
38566947451fSStefano Zampini    Level: intermediate
38576947451fSStefano Zampini 
385847d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`
38596947451fSStefano Zampini @*/
3860d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A, PetscInt col, Vec *v)
3861d71ae5a4SJacob Faibussowitsch {
38626947451fSStefano Zampini   PetscFunctionBegin;
38636947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
38646947451fSStefano Zampini   PetscValidType(A, 1);
38656947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
386608401ef6SPierre Jolivet   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
3867aed4548fSBarry Smith   PetscCheck(col >= 0 && col < A->cmap->N, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")", col, A->cmap->N);
3868cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v));
38696947451fSStefano Zampini   PetscFunctionReturn(0);
38706947451fSStefano Zampini }
38715ea7661aSPierre Jolivet 
38720f74d2c1SSatish Balay /*@
3873a2748737SPierre Jolivet    MatDenseGetSubMatrix - Gives access to a block of rows and columns of a dense matrix, represented as a Mat.
38745ea7661aSPierre Jolivet 
38755ea7661aSPierre Jolivet    Collective
38765ea7661aSPierre Jolivet 
38775ea7661aSPierre Jolivet    Input Parameters:
38785ea7661aSPierre Jolivet +  mat - the Mat object
3879a2748737SPierre Jolivet .  rbegin - the first global row index in the block (if PETSC_DECIDE, is 0)
3880a2748737SPierre Jolivet .  rend - the global row index past the last one in the block (if PETSC_DECIDE, is M)
3881a2748737SPierre Jolivet .  cbegin - the first global column index in the block (if PETSC_DECIDE, is 0)
3882a2748737SPierre Jolivet -  cend - the global column index past the last one in the block (if PETSC_DECIDE, is N)
38835ea7661aSPierre Jolivet 
38845ea7661aSPierre Jolivet    Output Parameter:
38855ea7661aSPierre Jolivet .  v - the matrix
38865ea7661aSPierre Jolivet 
38875ea7661aSPierre Jolivet    Notes:
38885ea7661aSPierre Jolivet      The matrix is owned by PETSc. Users need to call MatDenseRestoreSubMatrix() when the matrix is no longer needed.
388911a5261eSBarry Smith 
3890a2748737SPierre Jolivet      The output matrix is not redistributed by PETSc, so depending on the values of rbegin and rend, some processes may have no local rows.
38915ea7661aSPierre Jolivet 
38925ea7661aSPierre Jolivet    Level: intermediate
38935ea7661aSPierre Jolivet 
389447d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreSubMatrix()`
38955ea7661aSPierre Jolivet @*/
3896d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v)
3897d71ae5a4SJacob Faibussowitsch {
38985ea7661aSPierre Jolivet   PetscFunctionBegin;
38995ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
39005ea7661aSPierre Jolivet   PetscValidType(A, 1);
3901a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, rbegin, 2);
3902a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, rend, 3);
3903a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, cbegin, 4);
3904a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, cend, 5);
3905a2748737SPierre Jolivet   PetscValidPointer(v, 6);
3906a2748737SPierre Jolivet   if (rbegin == PETSC_DECIDE) rbegin = 0;
3907a2748737SPierre Jolivet   if (rend == PETSC_DECIDE) rend = A->rmap->N;
3908a2748737SPierre Jolivet   if (cbegin == PETSC_DECIDE) cbegin = 0;
3909a2748737SPierre Jolivet   if (cend == PETSC_DECIDE) cend = A->cmap->N;
391028b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
3911a2748737SPierre Jolivet   PetscCheck(rbegin >= 0 && rbegin <= A->rmap->N, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Invalid rbegin %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT "]", rbegin, A->rmap->N);
3912a2748737SPierre Jolivet   PetscCheck(rend >= rbegin && rend <= A->rmap->N, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Invalid rend %" PetscInt_FMT ", should be in [%" PetscInt_FMT ",%" PetscInt_FMT "]", rend, rbegin, A->rmap->N);
3913a2748737SPierre Jolivet   PetscCheck(cbegin >= 0 && cbegin <= A->cmap->N, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Invalid cbegin %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT "]", cbegin, A->cmap->N);
3914a2748737SPierre Jolivet   PetscCheck(cend >= cbegin && cend <= A->cmap->N, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Invalid cend %" PetscInt_FMT ", should be in [%" PetscInt_FMT ",%" PetscInt_FMT "]", cend, cbegin, A->cmap->N);
3915a2748737SPierre Jolivet   PetscUseMethod(A, "MatDenseGetSubMatrix_C", (Mat, PetscInt, PetscInt, PetscInt, PetscInt, Mat *), (A, rbegin, rend, cbegin, cend, v));
39165ea7661aSPierre Jolivet   PetscFunctionReturn(0);
39175ea7661aSPierre Jolivet }
39185ea7661aSPierre Jolivet 
39190f74d2c1SSatish Balay /*@
39205ea7661aSPierre Jolivet    MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from MatDenseGetSubMatrix().
39215ea7661aSPierre Jolivet 
39225ea7661aSPierre Jolivet    Collective
39235ea7661aSPierre Jolivet 
39245ea7661aSPierre Jolivet    Input Parameters:
39255ea7661aSPierre Jolivet +  mat - the Mat object
3926742765d3SMatthew Knepley -  v - the Mat object (may be NULL)
39275ea7661aSPierre Jolivet 
39285ea7661aSPierre Jolivet    Level: intermediate
39295ea7661aSPierre Jolivet 
393047d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseGetSubMatrix()`
39315ea7661aSPierre Jolivet @*/
3932d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix(Mat A, Mat *v)
3933d71ae5a4SJacob Faibussowitsch {
39345ea7661aSPierre Jolivet   PetscFunctionBegin;
39355ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
39365ea7661aSPierre Jolivet   PetscValidType(A, 1);
39375ea7661aSPierre Jolivet   PetscValidPointer(v, 2);
3938cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreSubMatrix_C", (Mat, Mat *), (A, v));
39395ea7661aSPierre Jolivet   PetscFunctionReturn(0);
39405ea7661aSPierre Jolivet }
39418a9c020eSBarry Smith 
39428a9c020eSBarry Smith #include <petscblaslapack.h>
39438a9c020eSBarry Smith #include <petsc/private/kernels/blockinvert.h>
39448a9c020eSBarry Smith 
3945d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseInvert(Mat A)
3946d71ae5a4SJacob Faibussowitsch {
39478a9c020eSBarry Smith   Mat_SeqDense   *a              = (Mat_SeqDense *)A->data;
39488a9c020eSBarry Smith   PetscInt        bs             = A->rmap->n;
39498a9c020eSBarry Smith   MatScalar      *values         = a->v;
39508a9c020eSBarry Smith   const PetscReal shift          = 0.0;
39518a9c020eSBarry Smith   PetscBool       allowzeropivot = PetscNot(A->erroriffailure), zeropivotdetected = PETSC_FALSE;
39528a9c020eSBarry Smith 
39538a9c020eSBarry Smith   PetscFunctionBegin;
39548a9c020eSBarry Smith   /* factor and invert each block */
39558a9c020eSBarry Smith   switch (bs) {
3956d71ae5a4SJacob Faibussowitsch   case 1:
3957d71ae5a4SJacob Faibussowitsch     values[0] = (PetscScalar)1.0 / (values[0] + shift);
3958d71ae5a4SJacob Faibussowitsch     break;
39598a9c020eSBarry Smith   case 2:
39608a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_2(values, shift, allowzeropivot, &zeropivotdetected));
39618a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
39628a9c020eSBarry Smith     break;
39638a9c020eSBarry Smith   case 3:
39648a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_3(values, shift, allowzeropivot, &zeropivotdetected));
39658a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
39668a9c020eSBarry Smith     break;
39678a9c020eSBarry Smith   case 4:
39688a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_4(values, shift, allowzeropivot, &zeropivotdetected));
39698a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
39708a9c020eSBarry Smith     break;
39719371c9d4SSatish Balay   case 5: {
39728a9c020eSBarry Smith     PetscScalar work[25];
39738a9c020eSBarry Smith     PetscInt    ipvt[5];
39748a9c020eSBarry Smith 
39758a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_5(values, ipvt, work, shift, allowzeropivot, &zeropivotdetected));
39768a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
39779371c9d4SSatish Balay   } break;
39788a9c020eSBarry Smith   case 6:
39798a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_6(values, shift, allowzeropivot, &zeropivotdetected));
39808a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
39818a9c020eSBarry Smith     break;
39828a9c020eSBarry Smith   case 7:
39838a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_7(values, shift, allowzeropivot, &zeropivotdetected));
39848a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
39858a9c020eSBarry Smith     break;
39869371c9d4SSatish Balay   default: {
39878a9c020eSBarry Smith     PetscInt    *v_pivots, *IJ, j;
39888a9c020eSBarry Smith     PetscScalar *v_work;
39898a9c020eSBarry Smith 
39908a9c020eSBarry Smith     PetscCall(PetscMalloc3(bs, &v_work, bs, &v_pivots, bs, &IJ));
3991ad540459SPierre Jolivet     for (j = 0; j < bs; j++) IJ[j] = j;
39928a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A(bs, values, v_pivots, v_work, allowzeropivot, &zeropivotdetected));
39938a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
39948a9c020eSBarry Smith     PetscCall(PetscFree3(v_work, v_pivots, IJ));
39958a9c020eSBarry Smith   }
39968a9c020eSBarry Smith   }
39978a9c020eSBarry Smith   PetscFunctionReturn(0);
39988a9c020eSBarry Smith }
3999