xref: /petsc/src/mat/impls/dense/seq/dense.c (revision 0ab4885dbfbd23084abc83d939d966cffb22897f)
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*/
8c6db04a5SJed Brown #include <petscblaslapack.h>
96a63e612SBarry Smith #include <../src/mat/impls/aij/seq/aij.h>
10b2573a8aSBarry Smith 
11d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSymmetrize_Private(Mat A, PetscBool hermitian)
12d71ae5a4SJacob Faibussowitsch {
138c178816SStefano Zampini   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
148c178816SStefano Zampini   PetscInt      j, k, n = A->rmap->n;
15ca15aa20SStefano Zampini   PetscScalar  *v;
168c178816SStefano Zampini 
178c178816SStefano Zampini   PetscFunctionBegin;
1808401ef6SPierre Jolivet   PetscCheck(A->rmap->n == A->cmap->n, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Cannot symmetrize a rectangular matrix");
199566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
208c178816SStefano Zampini   if (!hermitian) {
218c178816SStefano Zampini     for (k = 0; k < n; k++) {
22ad540459SPierre Jolivet       for (j = k; j < n; j++) v[j * mat->lda + k] = v[k * mat->lda + j];
238c178816SStefano Zampini     }
248c178816SStefano Zampini   } else {
258c178816SStefano Zampini     for (k = 0; k < n; k++) {
26ad540459SPierre Jolivet       for (j = k; j < n; j++) v[j * mat->lda + k] = PetscConj(v[k * mat->lda + j]);
278c178816SStefano Zampini     }
288c178816SStefano Zampini   }
299566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
308c178816SStefano Zampini   PetscFunctionReturn(0);
318c178816SStefano Zampini }
328c178816SStefano Zampini 
33d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode MatSeqDenseInvertFactors_Private(Mat A)
34d71ae5a4SJacob Faibussowitsch {
358c178816SStefano Zampini   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
368c178816SStefano Zampini   PetscBLASInt  info, n;
378c178816SStefano Zampini 
388c178816SStefano Zampini   PetscFunctionBegin;
398c178816SStefano Zampini   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
409566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
418c178816SStefano Zampini   if (A->factortype == MAT_FACTOR_LU) {
4228b400f6SJacob Faibussowitsch     PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present");
438c178816SStefano Zampini     if (!mat->fwork) {
448c178816SStefano Zampini       mat->lfwork = n;
459566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
468c178816SStefano Zampini     }
479566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
48792fecdfSBarry Smith     PetscCallBLAS("LAPACKgetri", LAPACKgetri_(&n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info));
499566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
509566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0));
518c178816SStefano Zampini   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
52b94d7dedSBarry Smith     if (A->spd == PETSC_BOOL3_TRUE) {
539566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
54792fecdfSBarry Smith       PetscCallBLAS("LAPACKpotri", LAPACKpotri_("L", &n, mat->v, &mat->lda, &info));
559566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
569566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_TRUE));
578c178816SStefano Zampini #if defined(PETSC_USE_COMPLEX)
58b94d7dedSBarry Smith     } else if (A->hermitian == PETSC_BOOL3_TRUE) {
5928b400f6SJacob Faibussowitsch       PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present");
6028b400f6SJacob Faibussowitsch       PetscCheck(mat->fwork, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Fwork not present");
619566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
62792fecdfSBarry Smith       PetscCallBLAS("LAPACKhetri", LAPACKhetri_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &info));
639566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
649566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_TRUE));
658c178816SStefano Zampini #endif
668c178816SStefano Zampini     } else { /* symmetric case */
6728b400f6SJacob Faibussowitsch       PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present");
6828b400f6SJacob Faibussowitsch       PetscCheck(mat->fwork, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Fwork not present");
699566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
70792fecdfSBarry Smith       PetscCallBLAS("LAPACKsytri", LAPACKsytri_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &info));
719566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
729566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_FALSE));
738c178816SStefano Zampini     }
7428b400f6SJacob Faibussowitsch     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad Inversion: zero pivot in row %" PetscInt_FMT, (PetscInt)info - 1);
759566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0));
768c178816SStefano Zampini   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Matrix must be factored to solve");
778c178816SStefano Zampini 
788c178816SStefano Zampini   A->ops->solve             = NULL;
798c178816SStefano Zampini   A->ops->matsolve          = NULL;
808c178816SStefano Zampini   A->ops->solvetranspose    = NULL;
818c178816SStefano Zampini   A->ops->matsolvetranspose = NULL;
828c178816SStefano Zampini   A->ops->solveadd          = NULL;
838c178816SStefano Zampini   A->ops->solvetransposeadd = NULL;
848c178816SStefano Zampini   A->factortype             = MAT_FACTOR_NONE;
859566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
868c178816SStefano Zampini   PetscFunctionReturn(0);
878c178816SStefano Zampini }
888c178816SStefano Zampini 
89d71ae5a4SJacob Faibussowitsch PetscErrorCode MatZeroRowsColumns_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b)
90d71ae5a4SJacob Faibussowitsch {
913f49a652SStefano Zampini   Mat_SeqDense      *l = (Mat_SeqDense *)A->data;
923f49a652SStefano Zampini   PetscInt           m = l->lda, n = A->cmap->n, r = A->rmap->n, i, j;
93ca15aa20SStefano Zampini   PetscScalar       *slot, *bb, *v;
943f49a652SStefano Zampini   const PetscScalar *xx;
953f49a652SStefano Zampini 
963f49a652SStefano Zampini   PetscFunctionBegin;
9776bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
983f49a652SStefano Zampini     for (i = 0; i < N; i++) {
9908401ef6SPierre Jolivet       PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed");
10008401ef6SPierre 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);
10108401ef6SPierre 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);
1023f49a652SStefano Zampini     }
10376bd3646SJed Brown   }
104ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
1053f49a652SStefano Zampini 
1063f49a652SStefano Zampini   /* fix right hand side if needed */
1073f49a652SStefano Zampini   if (x && b) {
1086c4d906cSStefano Zampini     Vec xt;
1096c4d906cSStefano Zampini 
11008401ef6SPierre Jolivet     PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices");
1119566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(x, &xt));
1129566063dSJacob Faibussowitsch     PetscCall(VecCopy(x, xt));
1139566063dSJacob Faibussowitsch     PetscCall(VecScale(xt, -1.0));
1149566063dSJacob Faibussowitsch     PetscCall(MatMultAdd(A, xt, b, b));
1159566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&xt));
1169566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(x, &xx));
1179566063dSJacob Faibussowitsch     PetscCall(VecGetArray(b, &bb));
1183f49a652SStefano Zampini     for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]];
1199566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(x, &xx));
1209566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(b, &bb));
1213f49a652SStefano Zampini   }
1223f49a652SStefano Zampini 
1239566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
1243f49a652SStefano Zampini   for (i = 0; i < N; i++) {
125ca15aa20SStefano Zampini     slot = v + rows[i] * m;
1269566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(slot, r));
1273f49a652SStefano Zampini   }
1283f49a652SStefano Zampini   for (i = 0; i < N; i++) {
129ca15aa20SStefano Zampini     slot = v + rows[i];
1309371c9d4SSatish Balay     for (j = 0; j < n; j++) {
1319371c9d4SSatish Balay       *slot = 0.0;
1329371c9d4SSatish Balay       slot += m;
1339371c9d4SSatish Balay     }
1343f49a652SStefano Zampini   }
1353f49a652SStefano Zampini   if (diag != 0.0) {
13608401ef6SPierre Jolivet     PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices");
1373f49a652SStefano Zampini     for (i = 0; i < N; i++) {
138ca15aa20SStefano Zampini       slot  = v + (m + 1) * rows[i];
1393f49a652SStefano Zampini       *slot = diag;
1403f49a652SStefano Zampini     }
1413f49a652SStefano Zampini   }
1429566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
1433f49a652SStefano Zampini   PetscFunctionReturn(0);
1443f49a652SStefano Zampini }
1453f49a652SStefano Zampini 
146d71ae5a4SJacob Faibussowitsch PetscErrorCode MatPtAPNumeric_SeqDense_SeqDense(Mat A, Mat P, Mat C)
147d71ae5a4SJacob Faibussowitsch {
148abc3b08eSStefano Zampini   Mat_SeqDense *c = (Mat_SeqDense *)(C->data);
149abc3b08eSStefano Zampini 
150abc3b08eSStefano Zampini   PetscFunctionBegin;
151ca15aa20SStefano Zampini   if (c->ptapwork) {
1529566063dSJacob Faibussowitsch     PetscCall((*C->ops->matmultnumeric)(A, P, c->ptapwork));
1539566063dSJacob Faibussowitsch     PetscCall((*C->ops->transposematmultnumeric)(P, c->ptapwork, C));
1544222ddf1SHong Zhang   } else SETERRQ(PetscObjectComm((PetscObject)C), PETSC_ERR_SUP, "Must call MatPtAPSymbolic_SeqDense_SeqDense() first");
155abc3b08eSStefano Zampini   PetscFunctionReturn(0);
156abc3b08eSStefano Zampini }
157abc3b08eSStefano Zampini 
158d71ae5a4SJacob Faibussowitsch PetscErrorCode MatPtAPSymbolic_SeqDense_SeqDense(Mat A, Mat P, PetscReal fill, Mat C)
159d71ae5a4SJacob Faibussowitsch {
160abc3b08eSStefano Zampini   Mat_SeqDense *c;
16147d993e7Ssuyashtn   PetscBool     cisdense = PETSC_FALSE;
162abc3b08eSStefano Zampini 
163abc3b08eSStefano Zampini   PetscFunctionBegin;
1649566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C, P->cmap->n, P->cmap->n, P->cmap->N, P->cmap->N));
16547d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA)
1669566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, ""));
16747d993e7Ssuyashtn #elif (PETSC_HAVE_HIP)
16847d993e7Ssuyashtn   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, ""));
16947d993e7Ssuyashtn #endif
17047d993e7Ssuyashtn 
1717a3c3d58SStefano Zampini   if (!cisdense) {
1727a3c3d58SStefano Zampini     PetscBool flg;
1737a3c3d58SStefano Zampini 
1749566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)P, ((PetscObject)A)->type_name, &flg));
1759566063dSJacob Faibussowitsch     PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE));
1767a3c3d58SStefano Zampini   }
1779566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
1784222ddf1SHong Zhang   c = (Mat_SeqDense *)C->data;
1799566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &c->ptapwork));
1809566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(c->ptapwork, A->rmap->n, P->cmap->n, A->rmap->N, P->cmap->N));
1819566063dSJacob Faibussowitsch   PetscCall(MatSetType(c->ptapwork, ((PetscObject)C)->type_name));
1829566063dSJacob Faibussowitsch   PetscCall(MatSetUp(c->ptapwork));
183abc3b08eSStefano Zampini   PetscFunctionReturn(0);
184abc3b08eSStefano Zampini }
185abc3b08eSStefano Zampini 
186d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat A, MatType newtype, MatReuse reuse, Mat *newmat)
187d71ae5a4SJacob Faibussowitsch {
188a13144ffSStefano Zampini   Mat              B = NULL;
189b49cda9fSStefano Zampini   Mat_SeqAIJ      *a = (Mat_SeqAIJ *)A->data;
190b49cda9fSStefano Zampini   Mat_SeqDense    *b;
191b49cda9fSStefano Zampini   PetscInt        *ai = a->i, *aj = a->j, m = A->rmap->N, n = A->cmap->N, i;
1922e5835c6SStefano Zampini   const MatScalar *av;
193a13144ffSStefano Zampini   PetscBool        isseqdense;
194b49cda9fSStefano Zampini 
195b49cda9fSStefano Zampini   PetscFunctionBegin;
196a13144ffSStefano Zampini   if (reuse == MAT_REUSE_MATRIX) {
1979566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)*newmat, MATSEQDENSE, &isseqdense));
19828b400f6SJacob Faibussowitsch     PetscCheck(isseqdense, PetscObjectComm((PetscObject)*newmat), PETSC_ERR_USER, "Cannot reuse matrix of type %s", ((PetscObject)(*newmat))->type_name);
199a13144ffSStefano Zampini   }
200a13144ffSStefano Zampini   if (reuse != MAT_REUSE_MATRIX) {
2019566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B));
2029566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(B, m, n, m, n));
2039566063dSJacob Faibussowitsch     PetscCall(MatSetType(B, MATSEQDENSE));
2049566063dSJacob Faibussowitsch     PetscCall(MatSeqDenseSetPreallocation(B, NULL));
205b49cda9fSStefano Zampini     b = (Mat_SeqDense *)(B->data);
206a13144ffSStefano Zampini   } else {
207a13144ffSStefano Zampini     b = (Mat_SeqDense *)((*newmat)->data);
2089566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(b->v, m * n));
209a13144ffSStefano Zampini   }
2109566063dSJacob Faibussowitsch   PetscCall(MatSeqAIJGetArrayRead(A, &av));
211b49cda9fSStefano Zampini   for (i = 0; i < m; i++) {
212b49cda9fSStefano Zampini     PetscInt j;
213b49cda9fSStefano Zampini     for (j = 0; j < ai[1] - ai[0]; j++) {
214b49cda9fSStefano Zampini       b->v[*aj * m + i] = *av;
215b49cda9fSStefano Zampini       aj++;
216b49cda9fSStefano Zampini       av++;
217b49cda9fSStefano Zampini     }
218b49cda9fSStefano Zampini     ai++;
219b49cda9fSStefano Zampini   }
2209566063dSJacob Faibussowitsch   PetscCall(MatSeqAIJRestoreArrayRead(A, &av));
221b49cda9fSStefano Zampini 
222511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
2239566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY));
2249566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY));
2259566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A, &B));
226b49cda9fSStefano Zampini   } else {
227a13144ffSStefano Zampini     if (B) *newmat = B;
2289566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(*newmat, MAT_FINAL_ASSEMBLY));
2299566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(*newmat, MAT_FINAL_ASSEMBLY));
230b49cda9fSStefano Zampini   }
231b49cda9fSStefano Zampini   PetscFunctionReturn(0);
232b49cda9fSStefano Zampini }
233b49cda9fSStefano Zampini 
234d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqDense_SeqAIJ(Mat A, MatType newtype, MatReuse reuse, Mat *newmat)
235d71ae5a4SJacob Faibussowitsch {
2366d4ec7b0SPierre Jolivet   Mat           B = NULL;
2376a63e612SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
2389399e1b8SMatthew G. Knepley   PetscInt      i, j;
2399399e1b8SMatthew G. Knepley   PetscInt     *rows, *nnz;
2409399e1b8SMatthew G. Knepley   MatScalar    *aa = a->v, *vals;
2416a63e612SBarry Smith 
2426a63e612SBarry Smith   PetscFunctionBegin;
2439566063dSJacob Faibussowitsch   PetscCall(PetscCalloc3(A->rmap->n, &rows, A->rmap->n, &nnz, A->rmap->n, &vals));
2446d4ec7b0SPierre Jolivet   if (reuse != MAT_REUSE_MATRIX) {
2459566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B));
2469566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(B, A->rmap->n, A->cmap->n, A->rmap->N, A->cmap->N));
2479566063dSJacob Faibussowitsch     PetscCall(MatSetType(B, MATSEQAIJ));
2489399e1b8SMatthew G. Knepley     for (j = 0; j < A->cmap->n; j++) {
2499371c9d4SSatish Balay       for (i = 0; i < A->rmap->n; i++)
2509371c9d4SSatish Balay         if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) ++nnz[i];
2516a63e612SBarry Smith       aa += a->lda;
2526a63e612SBarry Smith     }
2539566063dSJacob Faibussowitsch     PetscCall(MatSeqAIJSetPreallocation(B, PETSC_DETERMINE, nnz));
2546d4ec7b0SPierre Jolivet   } else B = *newmat;
2559399e1b8SMatthew G. Knepley   aa = a->v;
2569399e1b8SMatthew G. Knepley   for (j = 0; j < A->cmap->n; j++) {
2579399e1b8SMatthew G. Knepley     PetscInt numRows = 0;
2589371c9d4SSatish Balay     for (i = 0; i < A->rmap->n; i++)
2599371c9d4SSatish Balay       if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) {
2609371c9d4SSatish Balay         rows[numRows]   = i;
2619371c9d4SSatish Balay         vals[numRows++] = aa[i];
2629371c9d4SSatish Balay       }
2639566063dSJacob Faibussowitsch     PetscCall(MatSetValues(B, numRows, rows, 1, &j, vals, INSERT_VALUES));
2649399e1b8SMatthew G. Knepley     aa += a->lda;
2659399e1b8SMatthew G. Knepley   }
2669566063dSJacob Faibussowitsch   PetscCall(PetscFree3(rows, nnz, vals));
2679566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY));
2689566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY));
2696a63e612SBarry Smith 
270511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
2719566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A, &B));
2726d4ec7b0SPierre Jolivet   } else if (reuse != MAT_REUSE_MATRIX) *newmat = B;
2736a63e612SBarry Smith   PetscFunctionReturn(0);
2746a63e612SBarry Smith }
2756a63e612SBarry Smith 
276d71ae5a4SJacob Faibussowitsch PetscErrorCode MatAXPY_SeqDense(Mat Y, PetscScalar alpha, Mat X, MatStructure str)
277d71ae5a4SJacob Faibussowitsch {
2781987afe7SBarry Smith   Mat_SeqDense      *x = (Mat_SeqDense *)X->data, *y = (Mat_SeqDense *)Y->data;
279ca15aa20SStefano Zampini   const PetscScalar *xv;
280ca15aa20SStefano Zampini   PetscScalar       *yv;
28123fff9afSBarry Smith   PetscBLASInt       N, m, ldax = 0, lday = 0, one = 1;
2823a40ed3dSBarry Smith 
2833a40ed3dSBarry Smith   PetscFunctionBegin;
2849566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(X, &xv));
2859566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(Y, &yv));
2869566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(X->rmap->n * X->cmap->n, &N));
2879566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(X->rmap->n, &m));
2889566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(x->lda, &ldax));
2899566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(y->lda, &lday));
290a5ce6ee0Svictorle   if (ldax > m || lday > m) {
291ca15aa20SStefano Zampini     PetscInt j;
292ca15aa20SStefano Zampini 
29348a46eb9SPierre Jolivet     for (j = 0; j < X->cmap->n; j++) PetscCallBLAS("BLASaxpy", BLASaxpy_(&m, &alpha, xv + j * ldax, &one, yv + j * lday, &one));
294a5ce6ee0Svictorle   } else {
295792fecdfSBarry Smith     PetscCallBLAS("BLASaxpy", BLASaxpy_(&N, &alpha, xv, &one, yv, &one));
296a5ce6ee0Svictorle   }
2979566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(X, &xv));
2989566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(Y, &yv));
2999566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(PetscMax(2.0 * N - 1, 0)));
3003a40ed3dSBarry Smith   PetscFunctionReturn(0);
3011987afe7SBarry Smith }
3021987afe7SBarry Smith 
303d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetInfo_SeqDense(Mat A, MatInfoType flag, MatInfo *info)
304d71ae5a4SJacob Faibussowitsch {
305ca15aa20SStefano Zampini   PetscLogDouble N = A->rmap->n * A->cmap->n;
3063a40ed3dSBarry Smith 
3073a40ed3dSBarry Smith   PetscFunctionBegin;
3084e220ebcSLois Curfman McInnes   info->block_size        = 1.0;
309ca15aa20SStefano Zampini   info->nz_allocated      = N;
310ca15aa20SStefano Zampini   info->nz_used           = N;
311ca15aa20SStefano Zampini   info->nz_unneeded       = 0;
312ca15aa20SStefano Zampini   info->assemblies        = A->num_ass;
3134e220ebcSLois Curfman McInnes   info->mallocs           = 0;
3144dfa11a4SJacob Faibussowitsch   info->memory            = 0; /* REVIEW ME */
3154e220ebcSLois Curfman McInnes   info->fill_ratio_given  = 0;
3164e220ebcSLois Curfman McInnes   info->fill_ratio_needed = 0;
3174e220ebcSLois Curfman McInnes   info->factor_mallocs    = 0;
3183a40ed3dSBarry Smith   PetscFunctionReturn(0);
319289bc588SBarry Smith }
320289bc588SBarry Smith 
321d71ae5a4SJacob Faibussowitsch PetscErrorCode MatScale_SeqDense(Mat A, PetscScalar alpha)
322d71ae5a4SJacob Faibussowitsch {
323273d9f13SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
324ca15aa20SStefano Zampini   PetscScalar  *v;
32523fff9afSBarry Smith   PetscBLASInt  one = 1, j, nz, lda = 0;
32680cd9d93SLois Curfman McInnes 
3273a40ed3dSBarry Smith   PetscFunctionBegin;
3289566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
3299566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(a->lda, &lda));
330d0f46423SBarry Smith   if (lda > A->rmap->n) {
3319566063dSJacob Faibussowitsch     PetscCall(PetscBLASIntCast(A->rmap->n, &nz));
33248a46eb9SPierre Jolivet     for (j = 0; j < A->cmap->n; j++) PetscCallBLAS("BLASscal", BLASscal_(&nz, &alpha, v + j * lda, &one));
333a5ce6ee0Svictorle   } else {
3349566063dSJacob Faibussowitsch     PetscCall(PetscBLASIntCast(A->rmap->n * A->cmap->n, &nz));
335792fecdfSBarry Smith     PetscCallBLAS("BLASscal", BLASscal_(&nz, &alpha, v, &one));
336a5ce6ee0Svictorle   }
33704cbc005SJose E. Roman   PetscCall(PetscLogFlops(A->rmap->n * A->cmap->n));
3389566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
3393a40ed3dSBarry Smith   PetscFunctionReturn(0);
34080cd9d93SLois Curfman McInnes }
34180cd9d93SLois Curfman McInnes 
342d71ae5a4SJacob Faibussowitsch PetscErrorCode MatShift_SeqDense(Mat A, PetscScalar alpha)
343d71ae5a4SJacob Faibussowitsch {
3442f605a99SJose E. Roman   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
3452f605a99SJose E. Roman   PetscScalar  *v;
3462f605a99SJose E. Roman   PetscInt      j, k;
3472f605a99SJose E. Roman 
3482f605a99SJose E. Roman   PetscFunctionBegin;
3492f605a99SJose E. Roman   PetscCall(MatDenseGetArray(A, &v));
3502f605a99SJose E. Roman   k = PetscMin(A->rmap->n, A->cmap->n);
3512f605a99SJose E. Roman   for (j = 0; j < k; j++) v[j + j * a->lda] += alpha;
3522f605a99SJose E. Roman   PetscCall(PetscLogFlops(k));
3532f605a99SJose E. Roman   PetscCall(MatDenseRestoreArray(A, &v));
3542f605a99SJose E. Roman   PetscFunctionReturn(0);
3552f605a99SJose E. Roman }
3562f605a99SJose E. Roman 
357d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatIsHermitian_SeqDense(Mat A, PetscReal rtol, PetscBool *fl)
358d71ae5a4SJacob Faibussowitsch {
3591cbb95d3SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
360ca15aa20SStefano Zampini   PetscInt           i, j, m = A->rmap->n, N = a->lda;
361ca15aa20SStefano Zampini   const PetscScalar *v;
3621cbb95d3SBarry Smith 
3631cbb95d3SBarry Smith   PetscFunctionBegin;
3641cbb95d3SBarry Smith   *fl = PETSC_FALSE;
365d0f46423SBarry Smith   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
3669566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &v));
3671cbb95d3SBarry Smith   for (i = 0; i < m; i++) {
368ca15aa20SStefano Zampini     for (j = i; j < m; j++) {
369ad540459SPierre Jolivet       if (PetscAbsScalar(v[i + j * N] - PetscConj(v[j + i * N])) > rtol) goto restore;
3701cbb95d3SBarry Smith     }
371637a0070SStefano Zampini   }
3721cbb95d3SBarry Smith   *fl = PETSC_TRUE;
373637a0070SStefano Zampini restore:
3749566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &v));
375637a0070SStefano Zampini   PetscFunctionReturn(0);
376637a0070SStefano Zampini }
377637a0070SStefano Zampini 
378d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatIsSymmetric_SeqDense(Mat A, PetscReal rtol, PetscBool *fl)
379d71ae5a4SJacob Faibussowitsch {
380637a0070SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
381637a0070SStefano Zampini   PetscInt           i, j, m = A->rmap->n, N = a->lda;
382637a0070SStefano Zampini   const PetscScalar *v;
383637a0070SStefano Zampini 
384637a0070SStefano Zampini   PetscFunctionBegin;
385637a0070SStefano Zampini   *fl = PETSC_FALSE;
386637a0070SStefano Zampini   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
3879566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &v));
388637a0070SStefano Zampini   for (i = 0; i < m; i++) {
389637a0070SStefano Zampini     for (j = i; j < m; j++) {
390ad540459SPierre Jolivet       if (PetscAbsScalar(v[i + j * N] - v[j + i * N]) > rtol) goto restore;
391637a0070SStefano Zampini     }
392637a0070SStefano Zampini   }
393637a0070SStefano Zampini   *fl = PETSC_TRUE;
394637a0070SStefano Zampini restore:
3959566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &v));
3961cbb95d3SBarry Smith   PetscFunctionReturn(0);
3971cbb95d3SBarry Smith }
3981cbb95d3SBarry Smith 
399d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi, Mat A, MatDuplicateOption cpvalues)
400d71ae5a4SJacob Faibussowitsch {
401ca15aa20SStefano Zampini   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
40223fc5dcaSStefano Zampini   PetscInt      lda = (PetscInt)mat->lda, j, m, nlda = lda;
40375f6d85dSStefano Zampini   PetscBool     isdensecpu;
404b24902e0SBarry Smith 
405b24902e0SBarry Smith   PetscFunctionBegin;
4069566063dSJacob Faibussowitsch   PetscCall(PetscLayoutReference(A->rmap, &newi->rmap));
4079566063dSJacob Faibussowitsch   PetscCall(PetscLayoutReference(A->cmap, &newi->cmap));
40823fc5dcaSStefano Zampini   if (cpvalues == MAT_SHARE_NONZERO_PATTERN) { /* propagate LDA */
4099566063dSJacob Faibussowitsch     PetscCall(MatDenseSetLDA(newi, lda));
41023fc5dcaSStefano Zampini   }
4119566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)newi, MATSEQDENSE, &isdensecpu));
4129566063dSJacob Faibussowitsch   if (isdensecpu) PetscCall(MatSeqDenseSetPreallocation(newi, NULL));
413b24902e0SBarry Smith   if (cpvalues == MAT_COPY_VALUES) {
414ca15aa20SStefano Zampini     const PetscScalar *av;
415ca15aa20SStefano Zampini     PetscScalar       *v;
416ca15aa20SStefano Zampini 
4179566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A, &av));
4189566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayWrite(newi, &v));
4199566063dSJacob Faibussowitsch     PetscCall(MatDenseGetLDA(newi, &nlda));
420d0f46423SBarry Smith     m = A->rmap->n;
42123fc5dcaSStefano Zampini     if (lda > m || nlda > m) {
42248a46eb9SPierre Jolivet       for (j = 0; j < A->cmap->n; j++) PetscCall(PetscArraycpy(v + j * nlda, av + j * lda, m));
423b24902e0SBarry Smith     } else {
4249566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(v, av, A->rmap->n * A->cmap->n));
425b24902e0SBarry Smith     }
4269566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayWrite(newi, &v));
4279566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A, &av));
428b24902e0SBarry Smith   }
429b24902e0SBarry Smith   PetscFunctionReturn(0);
430b24902e0SBarry Smith }
431b24902e0SBarry Smith 
432d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDuplicate_SeqDense(Mat A, MatDuplicateOption cpvalues, Mat *newmat)
433d71ae5a4SJacob Faibussowitsch {
4343a40ed3dSBarry Smith   PetscFunctionBegin;
4359566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), newmat));
4369566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*newmat, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n));
4379566063dSJacob Faibussowitsch   PetscCall(MatSetType(*newmat, ((PetscObject)A)->type_name));
4389566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(*newmat, A, cpvalues));
439b24902e0SBarry Smith   PetscFunctionReturn(0);
440b24902e0SBarry Smith }
441b24902e0SBarry Smith 
442d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_LU(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T)
443d71ae5a4SJacob Faibussowitsch {
444c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
4454396437dSToby Isaac   PetscBLASInt  info;
44667e560aaSBarry Smith 
4473a40ed3dSBarry Smith   PetscFunctionBegin;
4489566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
449792fecdfSBarry Smith   PetscCallBLAS("LAPACKgetrs", LAPACKgetrs_(T ? "T" : "N", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info));
4509566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
45105fcb23eSStefano Zampini   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "GETRS - Bad solve %d", (int)info);
4529566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m)));
4534396437dSToby Isaac   PetscFunctionReturn(0);
4544396437dSToby Isaac }
4554396437dSToby Isaac 
4564396437dSToby Isaac static PetscErrorCode MatConjugate_SeqDense(Mat);
4574396437dSToby Isaac 
458d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_Cholesky(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T)
459d71ae5a4SJacob Faibussowitsch {
4604396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
4614396437dSToby Isaac   PetscBLASInt  info;
4624396437dSToby Isaac 
4634396437dSToby Isaac   PetscFunctionBegin;
464b94d7dedSBarry Smith   if (A->spd == PETSC_BOOL3_TRUE) {
4659566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A));
4669566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
467792fecdfSBarry Smith     PetscCallBLAS("LAPACKpotrs", LAPACKpotrs_("L", &m, &nrhs, mat->v, &mat->lda, x, &m, &info));
4689566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
46905fcb23eSStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "POTRS Bad solve %d", (int)info);
4709566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A));
471a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
472b94d7dedSBarry Smith   } else if (A->hermitian == PETSC_BOOL3_TRUE) {
4739566063dSJacob Faibussowitsch     if (T) PetscCall(MatConjugate_SeqDense(A));
4749566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
475792fecdfSBarry Smith     PetscCallBLAS("LAPACKhetrs", LAPACKhetrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info));
4769566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
47705fcb23eSStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "HETRS Bad solve %d", (int)info);
4789566063dSJacob Faibussowitsch     if (T) PetscCall(MatConjugate_SeqDense(A));
479a49dc2a2SStefano Zampini #endif
480a49dc2a2SStefano Zampini   } else { /* symmetric case */
4819566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
482792fecdfSBarry Smith     PetscCallBLAS("LAPACKsytrs", LAPACKsytrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info));
4839566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
48405fcb23eSStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "SYTRS Bad solve %d", (int)info);
485a49dc2a2SStefano Zampini   }
4869566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m)));
4874396437dSToby Isaac   PetscFunctionReturn(0);
4884396437dSToby Isaac }
48985e2c93fSHong Zhang 
490d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k)
491d71ae5a4SJacob Faibussowitsch {
4924396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
4934396437dSToby Isaac   PetscBLASInt  info;
4944396437dSToby Isaac   char          trans;
4954396437dSToby Isaac 
4964396437dSToby Isaac   PetscFunctionBegin;
4974905a7bcSToby Isaac   if (PetscDefined(USE_COMPLEX)) {
4984905a7bcSToby Isaac     trans = 'C';
4994905a7bcSToby Isaac   } else {
5004905a7bcSToby Isaac     trans = 'T';
5014905a7bcSToby Isaac   }
5029566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
50305fcb23eSStefano Zampini   { /* lwork depends on the number of right-hand sides */
50405fcb23eSStefano Zampini     PetscBLASInt nlfwork, lfwork = -1;
50505fcb23eSStefano Zampini     PetscScalar  fwork;
50605fcb23eSStefano Zampini 
507792fecdfSBarry Smith     PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info));
50805fcb23eSStefano Zampini     nlfwork = (PetscBLASInt)PetscRealPart(fwork);
50905fcb23eSStefano Zampini     if (nlfwork > mat->lfwork) {
51005fcb23eSStefano Zampini       mat->lfwork = nlfwork;
51105fcb23eSStefano Zampini       PetscCall(PetscFree(mat->fwork));
51205fcb23eSStefano Zampini       PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
51305fcb23eSStefano Zampini     }
51405fcb23eSStefano Zampini   }
515792fecdfSBarry Smith   PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info));
5169566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
51705fcb23eSStefano Zampini   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %d", (int)info);
5189566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
519792fecdfSBarry Smith   PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "N", "N", &mat->rank, &nrhs, mat->v, &mat->lda, x, &ldx, &info));
5209566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
52105fcb23eSStefano Zampini   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %d", (int)info);
5224905a7bcSToby Isaac   for (PetscInt j = 0; j < nrhs; j++) {
523ad540459SPierre Jolivet     for (PetscInt i = mat->rank; i < k; i++) x[j * ldx + i] = 0.;
5244905a7bcSToby Isaac   }
5259566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank))));
5264905a7bcSToby Isaac   PetscFunctionReturn(0);
5274905a7bcSToby Isaac }
5284905a7bcSToby Isaac 
529d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k)
530d71ae5a4SJacob Faibussowitsch {
5314396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
5324396437dSToby Isaac   PetscBLASInt  info;
5334396437dSToby Isaac 
5344396437dSToby Isaac   PetscFunctionBegin;
5354396437dSToby Isaac   if (A->rmap->n == A->cmap->n && mat->rank == A->rmap->n) {
5369566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
537792fecdfSBarry Smith     PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "T", "N", &m, &nrhs, mat->v, &mat->lda, x, &ldx, &info));
5389566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
53905fcb23eSStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %d", (int)info);
5409566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A));
54105fcb23eSStefano Zampini     { /* lwork depends on the number of right-hand sides */
54205fcb23eSStefano Zampini       PetscBLASInt nlfwork, lfwork = -1;
54305fcb23eSStefano Zampini       PetscScalar  fwork;
54405fcb23eSStefano Zampini 
545792fecdfSBarry Smith       PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info));
54605fcb23eSStefano Zampini       nlfwork = (PetscBLASInt)PetscRealPart(fwork);
54705fcb23eSStefano Zampini       if (nlfwork > mat->lfwork) {
54805fcb23eSStefano Zampini         mat->lfwork = nlfwork;
54905fcb23eSStefano Zampini         PetscCall(PetscFree(mat->fwork));
55005fcb23eSStefano Zampini         PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
55105fcb23eSStefano Zampini       }
55205fcb23eSStefano Zampini     }
5539566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
554792fecdfSBarry Smith     PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info));
5559566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
55605fcb23eSStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %d", (int)info);
5579566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A));
5584396437dSToby Isaac   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "QR factored matrix cannot be used for transpose solve");
5599566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank))));
5604396437dSToby Isaac   PetscFunctionReturn(0);
5614396437dSToby Isaac }
5624396437dSToby Isaac 
563d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_SetUp(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k)
564d71ae5a4SJacob Faibussowitsch {
5654396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
5664905a7bcSToby Isaac   PetscScalar  *y;
5674905a7bcSToby Isaac   PetscBLASInt  m = 0, k = 0;
5684905a7bcSToby Isaac 
5694905a7bcSToby Isaac   PetscFunctionBegin;
5709566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
5719566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &k));
5724905a7bcSToby Isaac   if (k < m) {
5739566063dSJacob Faibussowitsch     PetscCall(VecCopy(xx, mat->qrrhs));
5749566063dSJacob Faibussowitsch     PetscCall(VecGetArray(mat->qrrhs, &y));
5754905a7bcSToby Isaac   } else {
5769566063dSJacob Faibussowitsch     PetscCall(VecCopy(xx, yy));
5779566063dSJacob Faibussowitsch     PetscCall(VecGetArray(yy, &y));
5784905a7bcSToby Isaac   }
5794396437dSToby Isaac   *_y = y;
5804396437dSToby Isaac   *_k = k;
5814396437dSToby Isaac   *_m = m;
5824396437dSToby Isaac   PetscFunctionReturn(0);
5834396437dSToby Isaac }
5844396437dSToby Isaac 
585d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_TearDown(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k)
586d71ae5a4SJacob Faibussowitsch {
5874396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
58842e9364cSSatish Balay   PetscScalar  *y   = NULL;
5894396437dSToby Isaac   PetscBLASInt  m, k;
5904396437dSToby Isaac 
5914396437dSToby Isaac   PetscFunctionBegin;
5924396437dSToby Isaac   y   = *_y;
5934396437dSToby Isaac   *_y = NULL;
5944396437dSToby Isaac   k   = *_k;
5954396437dSToby Isaac   m   = *_m;
5964905a7bcSToby Isaac   if (k < m) {
5974905a7bcSToby Isaac     PetscScalar *yv;
5989566063dSJacob Faibussowitsch     PetscCall(VecGetArray(yy, &yv));
5999566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(yv, y, k));
6009566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(yy, &yv));
6019566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(mat->qrrhs, &y));
6024905a7bcSToby Isaac   } else {
6039566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(yy, &y));
6044905a7bcSToby Isaac   }
6054905a7bcSToby Isaac   PetscFunctionReturn(0);
6064905a7bcSToby Isaac }
6074905a7bcSToby Isaac 
608d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_LU(Mat A, Vec xx, Vec yy)
609d71ae5a4SJacob Faibussowitsch {
61042e9364cSSatish Balay   PetscScalar *y = NULL;
61142e9364cSSatish Balay   PetscBLASInt m = 0, k = 0;
6124396437dSToby Isaac 
6134396437dSToby Isaac   PetscFunctionBegin;
6149566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6159566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_FALSE));
6169566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6174396437dSToby Isaac   PetscFunctionReturn(0);
6184396437dSToby Isaac }
6194396437dSToby Isaac 
620d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_LU(Mat A, Vec xx, Vec yy)
621d71ae5a4SJacob Faibussowitsch {
62242e9364cSSatish Balay   PetscScalar *y = NULL;
62342e9364cSSatish Balay   PetscBLASInt m = 0, k = 0;
6244396437dSToby Isaac 
6254396437dSToby Isaac   PetscFunctionBegin;
6269566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6279566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_TRUE));
6289566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6294396437dSToby Isaac   PetscFunctionReturn(0);
6304396437dSToby Isaac }
6314396437dSToby Isaac 
632d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Cholesky(Mat A, Vec xx, Vec yy)
633d71ae5a4SJacob Faibussowitsch {
634e54beecaSStefano Zampini   PetscScalar *y = NULL;
635e54beecaSStefano Zampini   PetscBLASInt m = 0, k = 0;
6364396437dSToby Isaac 
6374396437dSToby Isaac   PetscFunctionBegin;
6389566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6399566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_FALSE));
6409566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6414396437dSToby Isaac   PetscFunctionReturn(0);
6424396437dSToby Isaac }
6434396437dSToby Isaac 
644d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_Cholesky(Mat A, Vec xx, Vec yy)
645d71ae5a4SJacob Faibussowitsch {
646e54beecaSStefano Zampini   PetscScalar *y = NULL;
647e54beecaSStefano Zampini   PetscBLASInt m = 0, k = 0;
6484396437dSToby Isaac 
6494396437dSToby Isaac   PetscFunctionBegin;
6509566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6519566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_TRUE));
6529566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6534396437dSToby Isaac   PetscFunctionReturn(0);
6544396437dSToby Isaac }
6554396437dSToby Isaac 
656d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_QR(Mat A, Vec xx, Vec yy)
657d71ae5a4SJacob Faibussowitsch {
658e54beecaSStefano Zampini   PetscScalar *y = NULL;
659e54beecaSStefano Zampini   PetscBLASInt m = 0, k = 0;
6604396437dSToby Isaac 
6614396437dSToby Isaac   PetscFunctionBegin;
6629566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6639566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k));
6649566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6654396437dSToby Isaac   PetscFunctionReturn(0);
6664396437dSToby Isaac }
6674396437dSToby Isaac 
668d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_QR(Mat A, Vec xx, Vec yy)
669d71ae5a4SJacob Faibussowitsch {
67042e9364cSSatish Balay   PetscScalar *y = NULL;
67142e9364cSSatish Balay   PetscBLASInt m = 0, k = 0;
6724396437dSToby Isaac 
6734396437dSToby Isaac   PetscFunctionBegin;
6749566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6759566063dSJacob Faibussowitsch   PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k));
6769566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6774396437dSToby Isaac   PetscFunctionReturn(0);
6784396437dSToby Isaac }
6794396437dSToby Isaac 
680d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_SetUp(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k)
681d71ae5a4SJacob Faibussowitsch {
6824905a7bcSToby Isaac   const PetscScalar *b;
6834396437dSToby Isaac   PetscScalar       *y;
684bf5a80bcSToby Isaac   PetscInt           n, _ldb, _ldx;
685bf5a80bcSToby Isaac   PetscBLASInt       nrhs = 0, m = 0, k = 0, ldb = 0, ldx = 0, ldy = 0;
6864905a7bcSToby Isaac 
6874905a7bcSToby Isaac   PetscFunctionBegin;
6889371c9d4SSatish Balay   *_ldy  = 0;
6899371c9d4SSatish Balay   *_m    = 0;
6909371c9d4SSatish Balay   *_nrhs = 0;
6919371c9d4SSatish Balay   *_k    = 0;
6929371c9d4SSatish Balay   *_y    = NULL;
6939566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
6949566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &k));
6959566063dSJacob Faibussowitsch   PetscCall(MatGetSize(B, NULL, &n));
6969566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(n, &nrhs));
6979566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(B, &_ldb));
6989566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldb, &ldb));
6999566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(X, &_ldx));
7009566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldx, &ldx));
701bf5a80bcSToby Isaac   if (ldx < m) {
7029566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(B, &b));
7039566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nrhs * m, &y));
704bf5a80bcSToby Isaac     if (ldb == m) {
7059566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(y, b, ldb * nrhs));
7064905a7bcSToby Isaac     } else {
70748a46eb9SPierre Jolivet       for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * m], &b[j * ldb], m));
7084905a7bcSToby Isaac     }
709bf5a80bcSToby Isaac     ldy = m;
7109566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(B, &b));
7114905a7bcSToby Isaac   } else {
712bf5a80bcSToby Isaac     if (ldb == ldx) {
7139566063dSJacob Faibussowitsch       PetscCall(MatCopy(B, X, SAME_NONZERO_PATTERN));
7149566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(X, &y));
7154905a7bcSToby Isaac     } else {
7169566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(X, &y));
7179566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArrayRead(B, &b));
71848a46eb9SPierre Jolivet       for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * ldx], &b[j * ldb], m));
7199566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArrayRead(B, &b));
7204905a7bcSToby Isaac     }
721bf5a80bcSToby Isaac     ldy = ldx;
7224905a7bcSToby Isaac   }
7234396437dSToby Isaac   *_y    = y;
724bf5a80bcSToby Isaac   *_ldy  = ldy;
7254396437dSToby Isaac   *_k    = k;
7264396437dSToby Isaac   *_m    = m;
7274396437dSToby Isaac   *_nrhs = nrhs;
7284396437dSToby Isaac   PetscFunctionReturn(0);
7294396437dSToby Isaac }
7304396437dSToby Isaac 
731d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_TearDown(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k)
732d71ae5a4SJacob Faibussowitsch {
7334396437dSToby Isaac   PetscScalar *y;
734bf5a80bcSToby Isaac   PetscInt     _ldx;
735bf5a80bcSToby Isaac   PetscBLASInt k, ldy, nrhs, ldx = 0;
7364396437dSToby Isaac 
7374396437dSToby Isaac   PetscFunctionBegin;
7384396437dSToby Isaac   y    = *_y;
7394396437dSToby Isaac   *_y  = NULL;
7404396437dSToby Isaac   k    = *_k;
741bf5a80bcSToby Isaac   ldy  = *_ldy;
7424396437dSToby Isaac   nrhs = *_nrhs;
7439566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(X, &_ldx));
7449566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldx, &ldx));
745bf5a80bcSToby Isaac   if (ldx != ldy) {
7464905a7bcSToby Isaac     PetscScalar *xv;
7479566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArray(X, &xv));
74848a46eb9SPierre Jolivet     for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&xv[j * ldx], &y[j * ldy], k));
7499566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(X, &xv));
7509566063dSJacob Faibussowitsch     PetscCall(PetscFree(y));
7514905a7bcSToby Isaac   } else {
7529566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(X, &y));
7534905a7bcSToby Isaac   }
75485e2c93fSHong Zhang   PetscFunctionReturn(0);
75585e2c93fSHong Zhang }
75685e2c93fSHong Zhang 
757d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_LU(Mat A, Mat B, Mat X)
758d71ae5a4SJacob Faibussowitsch {
7594396437dSToby Isaac   PetscScalar *y;
760bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7614396437dSToby Isaac 
7624396437dSToby Isaac   PetscFunctionBegin;
7639566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7649566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_FALSE));
7659566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7664396437dSToby Isaac   PetscFunctionReturn(0);
7674396437dSToby Isaac }
7684396437dSToby Isaac 
769d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_LU(Mat A, Mat B, Mat X)
770d71ae5a4SJacob Faibussowitsch {
7714396437dSToby Isaac   PetscScalar *y;
772bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7734396437dSToby Isaac 
7744396437dSToby Isaac   PetscFunctionBegin;
7759566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7769566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_TRUE));
7779566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7784396437dSToby Isaac   PetscFunctionReturn(0);
7794396437dSToby Isaac }
7804396437dSToby Isaac 
781d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_Cholesky(Mat A, Mat B, Mat X)
782d71ae5a4SJacob Faibussowitsch {
7834396437dSToby Isaac   PetscScalar *y;
784bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7854396437dSToby Isaac 
7864396437dSToby Isaac   PetscFunctionBegin;
7879566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7889566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_FALSE));
7899566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7904396437dSToby Isaac   PetscFunctionReturn(0);
7914396437dSToby Isaac }
7924396437dSToby Isaac 
793d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_Cholesky(Mat A, Mat B, Mat X)
794d71ae5a4SJacob Faibussowitsch {
7954396437dSToby Isaac   PetscScalar *y;
796bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7974396437dSToby Isaac 
7984396437dSToby Isaac   PetscFunctionBegin;
7999566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
8009566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_TRUE));
8019566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
8024396437dSToby Isaac   PetscFunctionReturn(0);
8034396437dSToby Isaac }
8044396437dSToby Isaac 
805d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_QR(Mat A, Mat B, Mat X)
806d71ae5a4SJacob Faibussowitsch {
8074396437dSToby Isaac   PetscScalar *y;
808bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
8094396437dSToby Isaac 
8104396437dSToby Isaac   PetscFunctionBegin;
8119566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
8129566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k));
8139566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
8144396437dSToby Isaac   PetscFunctionReturn(0);
8154396437dSToby Isaac }
8164396437dSToby Isaac 
817d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_QR(Mat A, Mat B, Mat X)
818d71ae5a4SJacob Faibussowitsch {
8194396437dSToby Isaac   PetscScalar *y;
820bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
8214396437dSToby Isaac 
8224396437dSToby Isaac   PetscFunctionBegin;
8239566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
8249566063dSJacob Faibussowitsch   PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k));
8259566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
8264396437dSToby Isaac   PetscFunctionReturn(0);
8274396437dSToby Isaac }
8284396437dSToby Isaac 
829db4efbfdSBarry Smith /* ---------------------------------------------------------------*/
830db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots,
831db4efbfdSBarry Smith    rather than put it in the Mat->row slot.*/
832d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLUFactor_SeqDense(Mat A, IS row, IS col, const MatFactorInfo *minfo)
833d71ae5a4SJacob Faibussowitsch {
834db4efbfdSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
835db4efbfdSBarry Smith   PetscBLASInt  n, m, info;
836db4efbfdSBarry Smith 
837db4efbfdSBarry Smith   PetscFunctionBegin;
8389566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
8399566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
8404dfa11a4SJacob Faibussowitsch   if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); }
841db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
8429566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
843792fecdfSBarry Smith   PetscCallBLAS("LAPACKgetrf", LAPACKgetrf_(&m, &n, mat->v, &mat->lda, mat->pivots, &info));
8449566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
8458e57ea43SSatish Balay 
84605fcb23eSStefano Zampini   PetscCheck(info >= 0, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to LU factorization %d", (int)info);
84705fcb23eSStefano Zampini   PetscCheck(info <= 0, PETSC_COMM_SELF, PETSC_ERR_MAT_LU_ZRPVT, "Bad LU factorization %d", (int)info);
8488208b9aeSStefano Zampini 
8494396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_LU;
8504396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_LU;
8514396437dSToby Isaac   A->ops->solvetranspose    = MatSolveTranspose_SeqDense_LU;
8524396437dSToby Isaac   A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_LU;
853d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_LU;
854db4efbfdSBarry Smith 
8559566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
8569566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype));
857f6224b95SHong Zhang 
8589566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops((2.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3));
859db4efbfdSBarry Smith   PetscFunctionReturn(0);
860db4efbfdSBarry Smith }
861db4efbfdSBarry Smith 
862d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy)
863d71ae5a4SJacob Faibussowitsch {
8644396437dSToby Isaac   MatFactorInfo info;
8654396437dSToby Isaac 
8664396437dSToby Isaac   PetscFunctionBegin;
8679566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES));
868dbbe0bcdSBarry Smith   PetscUseTypeMethod(fact, lufactor, NULL, NULL, &info);
8694396437dSToby Isaac   PetscFunctionReturn(0);
8704396437dSToby Isaac }
8714396437dSToby Isaac 
872d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, IS col, const MatFactorInfo *info)
873d71ae5a4SJacob Faibussowitsch {
8744396437dSToby Isaac   PetscFunctionBegin;
8754396437dSToby Isaac   fact->preallocated         = PETSC_TRUE;
8764396437dSToby Isaac   fact->assembled            = PETSC_TRUE;
8774396437dSToby Isaac   fact->ops->lufactornumeric = MatLUFactorNumeric_SeqDense;
8784396437dSToby Isaac   PetscFunctionReturn(0);
8794396437dSToby Isaac }
8804396437dSToby Isaac 
881a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */
882d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCholeskyFactor_SeqDense(Mat A, IS perm, const MatFactorInfo *factinfo)
883d71ae5a4SJacob Faibussowitsch {
884db4efbfdSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
885c5df96a5SBarry Smith   PetscBLASInt  info, n;
886db4efbfdSBarry Smith 
887db4efbfdSBarry Smith   PetscFunctionBegin;
8889566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
889db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
890b94d7dedSBarry Smith   if (A->spd == PETSC_BOOL3_TRUE) {
8919566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
892792fecdfSBarry Smith     PetscCallBLAS("LAPACKpotrf", LAPACKpotrf_("L", &n, mat->v, &mat->lda, &info));
8939566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
894a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
895b94d7dedSBarry Smith   } else if (A->hermitian == PETSC_BOOL3_TRUE) {
8964dfa11a4SJacob Faibussowitsch     if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); }
897a49dc2a2SStefano Zampini     if (!mat->fwork) {
898a49dc2a2SStefano Zampini       PetscScalar dummy;
899a49dc2a2SStefano Zampini 
900a49dc2a2SStefano Zampini       mat->lfwork = -1;
9019566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
902792fecdfSBarry Smith       PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info));
9039566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
904a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
9059566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
906a49dc2a2SStefano Zampini     }
9079566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
908792fecdfSBarry Smith     PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info));
9099566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
910a49dc2a2SStefano Zampini #endif
911a49dc2a2SStefano Zampini   } else { /* symmetric case */
9124dfa11a4SJacob Faibussowitsch     if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); }
913a49dc2a2SStefano Zampini     if (!mat->fwork) {
914a49dc2a2SStefano Zampini       PetscScalar dummy;
915a49dc2a2SStefano Zampini 
916a49dc2a2SStefano Zampini       mat->lfwork = -1;
9179566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
918792fecdfSBarry Smith       PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info));
9199566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
920a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
9219566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
922a49dc2a2SStefano Zampini     }
9239566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
924792fecdfSBarry Smith     PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info));
9259566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
926a49dc2a2SStefano Zampini   }
92728b400f6SJacob Faibussowitsch   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad factorization: zero pivot in row %" PetscInt_FMT, (PetscInt)info - 1);
9288208b9aeSStefano Zampini 
9294396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_Cholesky;
9304396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_Cholesky;
9314396437dSToby Isaac   A->ops->solvetranspose    = MatSolveTranspose_SeqDense_Cholesky;
9324396437dSToby Isaac   A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_Cholesky;
933d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_CHOLESKY;
9342205254eSKarl Rupp 
9359566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
9369566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype));
937f6224b95SHong Zhang 
9389566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0));
939db4efbfdSBarry Smith   PetscFunctionReturn(0);
940db4efbfdSBarry Smith }
941db4efbfdSBarry Smith 
942d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy)
943d71ae5a4SJacob Faibussowitsch {
944db4efbfdSBarry Smith   MatFactorInfo info;
945db4efbfdSBarry Smith 
946db4efbfdSBarry Smith   PetscFunctionBegin;
947db4efbfdSBarry Smith   info.fill = 1.0;
9482205254eSKarl Rupp 
9499566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES));
950dbbe0bcdSBarry Smith   PetscUseTypeMethod(fact, choleskyfactor, NULL, &info);
951db4efbfdSBarry Smith   PetscFunctionReturn(0);
952db4efbfdSBarry Smith }
953db4efbfdSBarry Smith 
954d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info)
955d71ae5a4SJacob Faibussowitsch {
956db4efbfdSBarry Smith   PetscFunctionBegin;
957c3ef05f6SHong Zhang   fact->assembled                  = PETSC_TRUE;
9581bbcc794SSatish Balay   fact->preallocated               = PETSC_TRUE;
959719d5645SBarry Smith   fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense;
960db4efbfdSBarry Smith   PetscFunctionReturn(0);
961db4efbfdSBarry Smith }
962db4efbfdSBarry Smith 
963d71ae5a4SJacob Faibussowitsch PetscErrorCode MatQRFactor_SeqDense(Mat A, IS col, const MatFactorInfo *minfo)
964d71ae5a4SJacob Faibussowitsch {
9654905a7bcSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
9664905a7bcSToby Isaac   PetscBLASInt  n, m, info, min, max;
9674905a7bcSToby Isaac 
9684905a7bcSToby Isaac   PetscFunctionBegin;
9699566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
9709566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
9714396437dSToby Isaac   max = PetscMax(m, n);
9724396437dSToby Isaac   min = PetscMin(m, n);
9734dfa11a4SJacob Faibussowitsch   if (!mat->tau) { PetscCall(PetscMalloc1(min, &mat->tau)); }
9744dfa11a4SJacob Faibussowitsch   if (!mat->pivots) { PetscCall(PetscMalloc1(n, &mat->pivots)); }
97548a46eb9SPierre Jolivet   if (!mat->qrrhs) PetscCall(MatCreateVecs(A, NULL, &(mat->qrrhs)));
9764905a7bcSToby Isaac   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
9774905a7bcSToby Isaac   if (!mat->fwork) {
9784905a7bcSToby Isaac     PetscScalar dummy;
9794905a7bcSToby Isaac 
9804905a7bcSToby Isaac     mat->lfwork = -1;
9819566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
982792fecdfSBarry Smith     PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, &dummy, &mat->lfwork, &info));
9839566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
9844905a7bcSToby Isaac     mat->lfwork = (PetscInt)PetscRealPart(dummy);
9859566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
9864905a7bcSToby Isaac   }
9879566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
988792fecdfSBarry Smith   PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, mat->fwork, &mat->lfwork, &info));
9899566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
99005fcb23eSStefano Zampini   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to QR factorization %d", (int)info);
9914905a7bcSToby 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
9924905a7bcSToby Isaac   mat->rank = min;
9934905a7bcSToby Isaac 
9944396437dSToby Isaac   A->ops->solve    = MatSolve_SeqDense_QR;
9954396437dSToby Isaac   A->ops->matsolve = MatMatSolve_SeqDense_QR;
9964905a7bcSToby Isaac   A->factortype    = MAT_FACTOR_QR;
9974905a7bcSToby Isaac   if (m == n) {
9984396437dSToby Isaac     A->ops->solvetranspose    = MatSolveTranspose_SeqDense_QR;
9994396437dSToby Isaac     A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_QR;
10004905a7bcSToby Isaac   }
10014905a7bcSToby Isaac 
10029566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
10039566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype));
10044905a7bcSToby Isaac 
10059566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0 * min * min * (max - min / 3.0)));
10064905a7bcSToby Isaac   PetscFunctionReturn(0);
10074905a7bcSToby Isaac }
10084905a7bcSToby Isaac 
1009d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatQRFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy)
1010d71ae5a4SJacob Faibussowitsch {
10114905a7bcSToby Isaac   MatFactorInfo info;
10124905a7bcSToby Isaac 
10134905a7bcSToby Isaac   PetscFunctionBegin;
10144905a7bcSToby Isaac   info.fill = 1.0;
10154905a7bcSToby Isaac 
10169566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES));
1017cac4c232SBarry Smith   PetscUseMethod(fact, "MatQRFactor_C", (Mat, IS, const MatFactorInfo *), (fact, NULL, &info));
10184905a7bcSToby Isaac   PetscFunctionReturn(0);
10194905a7bcSToby Isaac }
10204905a7bcSToby Isaac 
1021d71ae5a4SJacob Faibussowitsch PetscErrorCode MatQRFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info)
1022d71ae5a4SJacob Faibussowitsch {
10234905a7bcSToby Isaac   PetscFunctionBegin;
10244905a7bcSToby Isaac   fact->assembled    = PETSC_TRUE;
10254905a7bcSToby Isaac   fact->preallocated = PETSC_TRUE;
10269566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)fact, "MatQRFactorNumeric_C", MatQRFactorNumeric_SeqDense));
10274905a7bcSToby Isaac   PetscFunctionReturn(0);
10284905a7bcSToby Isaac }
10294905a7bcSToby Isaac 
1030ca15aa20SStefano Zampini /* uses LAPACK */
1031d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A, MatFactorType ftype, Mat *fact)
1032d71ae5a4SJacob Faibussowitsch {
1033db4efbfdSBarry Smith   PetscFunctionBegin;
10349566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), fact));
10359566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*fact, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n));
10369566063dSJacob Faibussowitsch   PetscCall(MatSetType(*fact, MATDENSE));
103766e17bc3SBarry Smith   (*fact)->trivialsymbolic = PETSC_TRUE;
10382a350339SBarry Smith   if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU) {
1039db4efbfdSBarry Smith     (*fact)->ops->lufactorsymbolic  = MatLUFactorSymbolic_SeqDense;
10402a350339SBarry Smith     (*fact)->ops->ilufactorsymbolic = MatLUFactorSymbolic_SeqDense;
1041bf5a80bcSToby Isaac   } else if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) {
1042db4efbfdSBarry Smith     (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense;
1043bf5a80bcSToby Isaac   } else if (ftype == MAT_FACTOR_QR) {
10449566063dSJacob Faibussowitsch     PetscCall(PetscObjectComposeFunction((PetscObject)(*fact), "MatQRFactorSymbolic_C", MatQRFactorSymbolic_SeqDense));
1045db4efbfdSBarry Smith   }
1046d5f3da31SBarry Smith   (*fact)->factortype = ftype;
104700c67f3bSHong Zhang 
10489566063dSJacob Faibussowitsch   PetscCall(PetscFree((*fact)->solvertype));
10499566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC, &(*fact)->solvertype));
10509566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_LU]));
10519566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ILU]));
10529566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_CHOLESKY]));
10539566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ICC]));
1054db4efbfdSBarry Smith   PetscFunctionReturn(0);
1055db4efbfdSBarry Smith }
1056db4efbfdSBarry Smith 
1057289bc588SBarry Smith /* ------------------------------------------------------------------*/
1058d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSOR_SeqDense(Mat A, Vec bb, PetscReal omega, MatSORType flag, PetscReal shift, PetscInt its, PetscInt lits, Vec xx)
1059d71ae5a4SJacob Faibussowitsch {
1060c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1061d9ca1df4SBarry Smith   PetscScalar       *x, *v = mat->v, zero = 0.0, xt;
1062d9ca1df4SBarry Smith   const PetscScalar *b;
1063d0f46423SBarry Smith   PetscInt           m = A->rmap->n, i;
106423fff9afSBarry Smith   PetscBLASInt       o = 1, bm = 0;
1065289bc588SBarry Smith 
10663a40ed3dSBarry Smith   PetscFunctionBegin;
106747d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
106808401ef6SPierre Jolivet   PetscCheck(A->offloadmask != PETSC_OFFLOAD_GPU, PETSC_COMM_SELF, PETSC_ERR_SUP, "Not implemented");
1069ca15aa20SStefano Zampini #endif
1070422a814eSBarry Smith   if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */
10719566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(m, &bm));
1072289bc588SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
10733bffc371SBarry Smith     /* this is a hack fix, should have another version without the second BLASdotu */
10749566063dSJacob Faibussowitsch     PetscCall(VecSet(xx, zero));
1075289bc588SBarry Smith   }
10769566063dSJacob Faibussowitsch   PetscCall(VecGetArray(xx, &x));
10779566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(bb, &b));
1078b965ef7fSBarry Smith   its = its * lits;
107908401ef6SPierre 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);
1080289bc588SBarry Smith   while (its--) {
1081fccaa45eSBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
1082289bc588SBarry Smith       for (i = 0; i < m; i++) {
1083792fecdfSBarry Smith         PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o));
108455a1b374SBarry Smith         x[i] = (1. - omega) * x[i] + omega * (xt + v[i + i * m] * x[i]) / (v[i + i * m] + shift);
1085289bc588SBarry Smith       }
1086289bc588SBarry Smith     }
1087fccaa45eSBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
1088289bc588SBarry Smith       for (i = m - 1; i >= 0; i--) {
1089792fecdfSBarry Smith         PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o));
109055a1b374SBarry Smith         x[i] = (1. - omega) * x[i] + omega * (xt + v[i + i * m] * x[i]) / (v[i + i * m] + shift);
1091289bc588SBarry Smith       }
1092289bc588SBarry Smith     }
1093289bc588SBarry Smith   }
10949566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(bb, &b));
10959566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(xx, &x));
10963a40ed3dSBarry Smith   PetscFunctionReturn(0);
1097289bc588SBarry Smith }
1098289bc588SBarry Smith 
1099289bc588SBarry Smith /* -----------------------------------------------------------------*/
1100d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultTranspose_SeqDense(Mat A, Vec xx, Vec yy)
1101d71ae5a4SJacob Faibussowitsch {
1102c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1103d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v, *x;
1104d9ca1df4SBarry Smith   PetscScalar       *y;
11050805154bSBarry Smith   PetscBLASInt       m, n, _One = 1;
1106ea709b57SSatish Balay   PetscScalar        _DOne = 1.0, _DZero = 0.0;
11073a40ed3dSBarry Smith 
11083a40ed3dSBarry Smith   PetscFunctionBegin;
11099566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
11109566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
11119566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx, &x));
11129566063dSJacob Faibussowitsch   PetscCall(VecGetArrayWrite(yy, &y));
11135ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
11145ac36cfcSBarry Smith     PetscBLASInt i;
11155ac36cfcSBarry Smith     for (i = 0; i < n; i++) y[i] = 0.0;
11165ac36cfcSBarry Smith   } else {
1117792fecdfSBarry Smith     PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v, &mat->lda, x, &_One, &_DZero, y, &_One));
11189566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n - A->cmap->n));
11195ac36cfcSBarry Smith   }
11209566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx, &x));
11219566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayWrite(yy, &y));
11223a40ed3dSBarry Smith   PetscFunctionReturn(0);
1123289bc588SBarry Smith }
1124800995b7SMatthew Knepley 
1125d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMult_SeqDense(Mat A, Vec xx, Vec yy)
1126d71ae5a4SJacob Faibussowitsch {
1127c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1128d9ca1df4SBarry Smith   PetscScalar       *y, _DOne = 1.0, _DZero = 0.0;
11290805154bSBarry Smith   PetscBLASInt       m, n, _One             = 1;
1130d9ca1df4SBarry Smith   const PetscScalar *v = mat->v, *x;
11313a40ed3dSBarry Smith 
11323a40ed3dSBarry Smith   PetscFunctionBegin;
11339566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
11349566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
11359566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx, &x));
11369566063dSJacob Faibussowitsch   PetscCall(VecGetArrayWrite(yy, &y));
11375ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
11385ac36cfcSBarry Smith     PetscBLASInt i;
11395ac36cfcSBarry Smith     for (i = 0; i < m; i++) y[i] = 0.0;
11405ac36cfcSBarry Smith   } else {
1141792fecdfSBarry Smith     PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DZero, y, &_One));
11429566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n - A->rmap->n));
11435ac36cfcSBarry Smith   }
11449566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx, &x));
11459566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayWrite(yy, &y));
11463a40ed3dSBarry Smith   PetscFunctionReturn(0);
1147289bc588SBarry Smith }
11486ee01492SSatish Balay 
1149d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy)
1150d71ae5a4SJacob Faibussowitsch {
1151c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1152d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v, *x;
1153d9ca1df4SBarry Smith   PetscScalar       *y, _DOne = 1.0;
11540805154bSBarry Smith   PetscBLASInt       m, n, _One = 1;
11553a40ed3dSBarry Smith 
11563a40ed3dSBarry Smith   PetscFunctionBegin;
11579566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
11589566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
11599566063dSJacob Faibussowitsch   PetscCall(VecCopy(zz, yy));
1160d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
11619566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx, &x));
11629566063dSJacob Faibussowitsch   PetscCall(VecGetArray(yy, &y));
1163792fecdfSBarry Smith   PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DOne, y, &_One));
11649566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx, &x));
11659566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(yy, &y));
11669566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n));
11673a40ed3dSBarry Smith   PetscFunctionReturn(0);
1168289bc588SBarry Smith }
11696ee01492SSatish Balay 
1170d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy)
1171d71ae5a4SJacob Faibussowitsch {
1172c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1173d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v, *x;
1174d9ca1df4SBarry Smith   PetscScalar       *y;
11750805154bSBarry Smith   PetscBLASInt       m, n, _One = 1;
117687828ca2SBarry Smith   PetscScalar        _DOne = 1.0;
11773a40ed3dSBarry Smith 
11783a40ed3dSBarry Smith   PetscFunctionBegin;
11799566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
11809566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
11819566063dSJacob Faibussowitsch   PetscCall(VecCopy(zz, yy));
1182d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
11839566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx, &x));
11849566063dSJacob Faibussowitsch   PetscCall(VecGetArray(yy, &y));
1185792fecdfSBarry Smith   PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DOne, y, &_One));
11869566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx, &x));
11879566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(yy, &y));
11889566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n));
11893a40ed3dSBarry Smith   PetscFunctionReturn(0);
1190289bc588SBarry Smith }
1191289bc588SBarry Smith 
1192289bc588SBarry Smith /* -----------------------------------------------------------------*/
1193d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals)
1194d71ae5a4SJacob Faibussowitsch {
1195c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
119613f74950SBarry Smith   PetscInt      i;
119767e560aaSBarry Smith 
11983a40ed3dSBarry Smith   PetscFunctionBegin;
1199d0f46423SBarry Smith   *ncols = A->cmap->n;
1200289bc588SBarry Smith   if (cols) {
12019566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(A->cmap->n, cols));
1202d0f46423SBarry Smith     for (i = 0; i < A->cmap->n; i++) (*cols)[i] = i;
1203289bc588SBarry Smith   }
1204289bc588SBarry Smith   if (vals) {
1205ca15aa20SStefano Zampini     const PetscScalar *v;
1206ca15aa20SStefano Zampini 
12079566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A, &v));
12089566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(A->cmap->n, vals));
1209ca15aa20SStefano Zampini     v += row;
12109371c9d4SSatish Balay     for (i = 0; i < A->cmap->n; i++) {
12119371c9d4SSatish Balay       (*vals)[i] = *v;
12129371c9d4SSatish Balay       v += mat->lda;
12139371c9d4SSatish Balay     }
12149566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A, &v));
1215289bc588SBarry Smith   }
12163a40ed3dSBarry Smith   PetscFunctionReturn(0);
1217289bc588SBarry Smith }
12186ee01492SSatish Balay 
1219d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRestoreRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals)
1220d71ae5a4SJacob Faibussowitsch {
1221606d414cSSatish Balay   PetscFunctionBegin;
1222cb4a9cd9SHong Zhang   if (ncols) *ncols = 0;
12239566063dSJacob Faibussowitsch   if (cols) PetscCall(PetscFree(*cols));
12249566063dSJacob Faibussowitsch   if (vals) PetscCall(PetscFree(*vals));
12253a40ed3dSBarry Smith   PetscFunctionReturn(0);
1226289bc588SBarry Smith }
1227289bc588SBarry Smith /* ----------------------------------------------------------------*/
1228d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], const PetscScalar v[], InsertMode addv)
1229d71ae5a4SJacob Faibussowitsch {
1230c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
1231ca15aa20SStefano Zampini   PetscScalar  *av;
123213f74950SBarry Smith   PetscInt      i, j, idx = 0;
123347d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
1234c70f7ee4SJunchao Zhang   PetscOffloadMask oldf;
1235ca15aa20SStefano Zampini #endif
1236d6dfbf8fSBarry Smith 
12373a40ed3dSBarry Smith   PetscFunctionBegin;
12389566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &av));
1239289bc588SBarry Smith   if (!mat->roworiented) {
1240dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1241289bc588SBarry Smith       for (j = 0; j < n; j++) {
12429371c9d4SSatish Balay         if (indexn[j] < 0) {
12439371c9d4SSatish Balay           idx += m;
12449371c9d4SSatish Balay           continue;
12459371c9d4SSatish Balay         }
12466bdcaf15SBarry 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);
1247289bc588SBarry Smith         for (i = 0; i < m; i++) {
12489371c9d4SSatish Balay           if (indexm[i] < 0) {
12499371c9d4SSatish Balay             idx++;
12509371c9d4SSatish Balay             continue;
12519371c9d4SSatish Balay           }
12526bdcaf15SBarry 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);
1253ca15aa20SStefano Zampini           av[indexn[j] * mat->lda + indexm[i]] = v[idx++];
1254289bc588SBarry Smith         }
1255289bc588SBarry Smith       }
12563a40ed3dSBarry Smith     } else {
1257289bc588SBarry Smith       for (j = 0; j < n; j++) {
12589371c9d4SSatish Balay         if (indexn[j] < 0) {
12599371c9d4SSatish Balay           idx += m;
12609371c9d4SSatish Balay           continue;
12619371c9d4SSatish Balay         }
12626bdcaf15SBarry 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);
1263289bc588SBarry Smith         for (i = 0; i < m; i++) {
12649371c9d4SSatish Balay           if (indexm[i] < 0) {
12659371c9d4SSatish Balay             idx++;
12669371c9d4SSatish Balay             continue;
12679371c9d4SSatish Balay           }
12686bdcaf15SBarry 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);
1269ca15aa20SStefano Zampini           av[indexn[j] * mat->lda + indexm[i]] += v[idx++];
1270289bc588SBarry Smith         }
1271289bc588SBarry Smith       }
1272289bc588SBarry Smith     }
12733a40ed3dSBarry Smith   } else {
1274dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1275e8d4e0b9SBarry Smith       for (i = 0; i < m; i++) {
12769371c9d4SSatish Balay         if (indexm[i] < 0) {
12779371c9d4SSatish Balay           idx += n;
12789371c9d4SSatish Balay           continue;
12799371c9d4SSatish Balay         }
12806bdcaf15SBarry 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);
1281e8d4e0b9SBarry Smith         for (j = 0; j < n; j++) {
12829371c9d4SSatish Balay           if (indexn[j] < 0) {
12839371c9d4SSatish Balay             idx++;
12849371c9d4SSatish Balay             continue;
12859371c9d4SSatish Balay           }
12866bdcaf15SBarry 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);
1287ca15aa20SStefano Zampini           av[indexn[j] * mat->lda + indexm[i]] = v[idx++];
1288e8d4e0b9SBarry Smith         }
1289e8d4e0b9SBarry Smith       }
12903a40ed3dSBarry Smith     } else {
1291289bc588SBarry Smith       for (i = 0; i < m; i++) {
12929371c9d4SSatish Balay         if (indexm[i] < 0) {
12939371c9d4SSatish Balay           idx += n;
12949371c9d4SSatish Balay           continue;
12959371c9d4SSatish Balay         }
12966bdcaf15SBarry 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);
1297289bc588SBarry Smith         for (j = 0; j < n; j++) {
12989371c9d4SSatish Balay           if (indexn[j] < 0) {
12999371c9d4SSatish Balay             idx++;
13009371c9d4SSatish Balay             continue;
13019371c9d4SSatish Balay           }
13026bdcaf15SBarry 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);
1303ca15aa20SStefano Zampini           av[indexn[j] * mat->lda + indexm[i]] += v[idx++];
1304289bc588SBarry Smith         }
1305289bc588SBarry Smith       }
1306289bc588SBarry Smith     }
1307e8d4e0b9SBarry Smith   }
1308ca15aa20SStefano Zampini   /* hack to prevent unneeded copy to the GPU while returning the array */
130947d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
1310c70f7ee4SJunchao Zhang   oldf           = A->offloadmask;
1311c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_GPU;
1312ca15aa20SStefano Zampini #endif
13139566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &av));
131447d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
1315c70f7ee4SJunchao Zhang   A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU);
1316ca15aa20SStefano Zampini #endif
13173a40ed3dSBarry Smith   PetscFunctionReturn(0);
1318289bc588SBarry Smith }
1319e8d4e0b9SBarry Smith 
1320d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], PetscScalar v[])
1321d71ae5a4SJacob Faibussowitsch {
1322ae80bb75SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1323ca15aa20SStefano Zampini   const PetscScalar *vv;
132413f74950SBarry Smith   PetscInt           i, j;
1325ae80bb75SLois Curfman McInnes 
13263a40ed3dSBarry Smith   PetscFunctionBegin;
13279566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &vv));
1328ae80bb75SLois Curfman McInnes   /* row-oriented output */
1329ae80bb75SLois Curfman McInnes   for (i = 0; i < m; i++) {
13309371c9d4SSatish Balay     if (indexm[i] < 0) {
13319371c9d4SSatish Balay       v += n;
13329371c9d4SSatish Balay       continue;
13339371c9d4SSatish Balay     }
133408401ef6SPierre 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);
1335ae80bb75SLois Curfman McInnes     for (j = 0; j < n; j++) {
13369371c9d4SSatish Balay       if (indexn[j] < 0) {
13379371c9d4SSatish Balay         v++;
13389371c9d4SSatish Balay         continue;
13399371c9d4SSatish Balay       }
134008401ef6SPierre 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);
1341ca15aa20SStefano Zampini       *v++ = vv[indexn[j] * mat->lda + indexm[i]];
1342ae80bb75SLois Curfman McInnes     }
1343ae80bb75SLois Curfman McInnes   }
13449566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &vv));
13453a40ed3dSBarry Smith   PetscFunctionReturn(0);
1346ae80bb75SLois Curfman McInnes }
1347ae80bb75SLois Curfman McInnes 
1348289bc588SBarry Smith /* -----------------------------------------------------------------*/
1349289bc588SBarry Smith 
1350d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_Dense_Binary(Mat mat, PetscViewer viewer)
1351d71ae5a4SJacob Faibussowitsch {
13528491ab44SLisandro Dalcin   PetscBool          skipHeader;
13538491ab44SLisandro Dalcin   PetscViewerFormat  format;
13548491ab44SLisandro Dalcin   PetscInt           header[4], M, N, m, lda, i, j, k;
13558491ab44SLisandro Dalcin   const PetscScalar *v;
13568491ab44SLisandro Dalcin   PetscScalar       *vwork;
1357aabbc4fbSShri Abhyankar 
1358aabbc4fbSShri Abhyankar   PetscFunctionBegin;
13599566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
13609566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader));
13619566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
13628491ab44SLisandro Dalcin   if (skipHeader) format = PETSC_VIEWER_NATIVE;
1363aabbc4fbSShri Abhyankar 
13649566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat, &M, &N));
13658491ab44SLisandro Dalcin 
13668491ab44SLisandro Dalcin   /* write matrix header */
13679371c9d4SSatish Balay   header[0] = MAT_FILE_CLASSID;
13689371c9d4SSatish Balay   header[1] = M;
13699371c9d4SSatish Balay   header[2] = N;
13708491ab44SLisandro Dalcin   header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M * N;
13719566063dSJacob Faibussowitsch   if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer, header, 4, PETSC_INT));
13728491ab44SLisandro Dalcin 
13739566063dSJacob Faibussowitsch   PetscCall(MatGetLocalSize(mat, &m, NULL));
13748491ab44SLisandro Dalcin   if (format != PETSC_VIEWER_NATIVE) {
13758491ab44SLisandro Dalcin     PetscInt nnz = m * N, *iwork;
13768491ab44SLisandro Dalcin     /* store row lengths for each row */
13779566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nnz, &iwork));
13788491ab44SLisandro Dalcin     for (i = 0; i < m; i++) iwork[i] = N;
13799566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT));
13808491ab44SLisandro Dalcin     /* store column indices (zero start index) */
13818491ab44SLisandro Dalcin     for (k = 0, i = 0; i < m; i++)
13829371c9d4SSatish Balay       for (j = 0; j < N; j++, k++) iwork[k] = j;
13839566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT));
13849566063dSJacob Faibussowitsch     PetscCall(PetscFree(iwork));
13858491ab44SLisandro Dalcin   }
13868491ab44SLisandro Dalcin   /* store matrix values as a dense matrix in row major order */
13879566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(m * N, &vwork));
13889566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(mat, &v));
13899566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(mat, &lda));
13908491ab44SLisandro Dalcin   for (k = 0, i = 0; i < m; i++)
13919371c9d4SSatish Balay     for (j = 0; j < N; j++, k++) vwork[k] = v[i + lda * j];
13929566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(mat, &v));
13939566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryWriteAll(viewer, vwork, m * N, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR));
13949566063dSJacob Faibussowitsch   PetscCall(PetscFree(vwork));
13958491ab44SLisandro Dalcin   PetscFunctionReturn(0);
13968491ab44SLisandro Dalcin }
13978491ab44SLisandro Dalcin 
1398d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLoad_Dense_Binary(Mat mat, PetscViewer viewer)
1399d71ae5a4SJacob Faibussowitsch {
14008491ab44SLisandro Dalcin   PetscBool    skipHeader;
14018491ab44SLisandro Dalcin   PetscInt     header[4], M, N, m, nz, lda, i, j, k;
14028491ab44SLisandro Dalcin   PetscInt     rows, cols;
14038491ab44SLisandro Dalcin   PetscScalar *v, *vwork;
14048491ab44SLisandro Dalcin 
14058491ab44SLisandro Dalcin   PetscFunctionBegin;
14069566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
14079566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader));
14088491ab44SLisandro Dalcin 
14098491ab44SLisandro Dalcin   if (!skipHeader) {
14109566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryRead(viewer, header, 4, NULL, PETSC_INT));
141108401ef6SPierre Jolivet     PetscCheck(header[0] == MAT_FILE_CLASSID, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Not a matrix object in file");
14129371c9d4SSatish Balay     M = header[1];
14139371c9d4SSatish Balay     N = header[2];
141408401ef6SPierre Jolivet     PetscCheck(M >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix row size (%" PetscInt_FMT ") in file is negative", M);
141508401ef6SPierre Jolivet     PetscCheck(N >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix column size (%" PetscInt_FMT ") in file is negative", N);
14168491ab44SLisandro Dalcin     nz = header[3];
1417aed4548fSBarry Smith     PetscCheck(nz == MATRIX_BINARY_FORMAT_DENSE || nz >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Unknown matrix format %" PetscInt_FMT " in file", nz);
1418aabbc4fbSShri Abhyankar   } else {
14199566063dSJacob Faibussowitsch     PetscCall(MatGetSize(mat, &M, &N));
1420aed4548fSBarry 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");
14218491ab44SLisandro Dalcin     nz = MATRIX_BINARY_FORMAT_DENSE;
1422e6324fbbSBarry Smith   }
1423aabbc4fbSShri Abhyankar 
14248491ab44SLisandro Dalcin   /* setup global sizes if not set */
14258491ab44SLisandro Dalcin   if (mat->rmap->N < 0) mat->rmap->N = M;
14268491ab44SLisandro Dalcin   if (mat->cmap->N < 0) mat->cmap->N = N;
14279566063dSJacob Faibussowitsch   PetscCall(MatSetUp(mat));
14288491ab44SLisandro Dalcin   /* check if global sizes are correct */
14299566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat, &rows, &cols));
1430aed4548fSBarry 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);
1431aabbc4fbSShri Abhyankar 
14329566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat, NULL, &N));
14339566063dSJacob Faibussowitsch   PetscCall(MatGetLocalSize(mat, &m, NULL));
14349566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(mat, &v));
14359566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(mat, &lda));
14368491ab44SLisandro Dalcin   if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense format */
14378491ab44SLisandro Dalcin     PetscInt nnz = m * N;
14388491ab44SLisandro Dalcin     /* read in matrix values */
14399566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nnz, &vwork));
14409566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR));
14418491ab44SLisandro Dalcin     /* store values in column major order */
14428491ab44SLisandro Dalcin     for (j = 0; j < N; j++)
14439371c9d4SSatish Balay       for (i = 0; i < m; i++) v[i + lda * j] = vwork[i * N + j];
14449566063dSJacob Faibussowitsch     PetscCall(PetscFree(vwork));
14458491ab44SLisandro Dalcin   } else { /* matrix in file is sparse format */
14468491ab44SLisandro Dalcin     PetscInt nnz = 0, *rlens, *icols;
14478491ab44SLisandro Dalcin     /* read in row lengths */
14489566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(m, &rlens));
14499566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer, rlens, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT));
14508491ab44SLisandro Dalcin     for (i = 0; i < m; i++) nnz += rlens[i];
14518491ab44SLisandro Dalcin     /* read in column indices and values */
14529566063dSJacob Faibussowitsch     PetscCall(PetscMalloc2(nnz, &icols, nnz, &vwork));
14539566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer, icols, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT));
14549566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR));
14558491ab44SLisandro Dalcin     /* store values in column major order */
14568491ab44SLisandro Dalcin     for (k = 0, i = 0; i < m; i++)
14579371c9d4SSatish Balay       for (j = 0; j < rlens[i]; j++, k++) v[i + lda * icols[k]] = vwork[k];
14589566063dSJacob Faibussowitsch     PetscCall(PetscFree(rlens));
14599566063dSJacob Faibussowitsch     PetscCall(PetscFree2(icols, vwork));
1460aabbc4fbSShri Abhyankar   }
14619566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(mat, &v));
14629566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY));
14639566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY));
1464aabbc4fbSShri Abhyankar   PetscFunctionReturn(0);
1465aabbc4fbSShri Abhyankar }
1466aabbc4fbSShri Abhyankar 
1467d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer)
1468d71ae5a4SJacob Faibussowitsch {
1469eb91f321SVaclav Hapla   PetscBool isbinary, ishdf5;
1470eb91f321SVaclav Hapla 
1471eb91f321SVaclav Hapla   PetscFunctionBegin;
1472eb91f321SVaclav Hapla   PetscValidHeaderSpecific(newMat, MAT_CLASSID, 1);
1473eb91f321SVaclav Hapla   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
1474eb91f321SVaclav Hapla   /* force binary viewer to load .info file if it has not yet done so */
14759566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
14769566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
14779566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5));
1478eb91f321SVaclav Hapla   if (isbinary) {
14799566063dSJacob Faibussowitsch     PetscCall(MatLoad_Dense_Binary(newMat, viewer));
1480eb91f321SVaclav Hapla   } else if (ishdf5) {
1481eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5)
14829566063dSJacob Faibussowitsch     PetscCall(MatLoad_Dense_HDF5(newMat, viewer));
1483eb91f321SVaclav Hapla #else
1484eb91f321SVaclav Hapla     SETERRQ(PetscObjectComm((PetscObject)newMat), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5");
1485eb91f321SVaclav Hapla #endif
1486eb91f321SVaclav Hapla   } else {
148798921bdaSJacob 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);
1488eb91f321SVaclav Hapla   }
1489eb91f321SVaclav Hapla   PetscFunctionReturn(0);
1490eb91f321SVaclav Hapla }
1491eb91f321SVaclav Hapla 
1492d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_ASCII(Mat A, PetscViewer viewer)
1493d71ae5a4SJacob Faibussowitsch {
1494932b0c3eSLois Curfman McInnes   Mat_SeqDense     *a = (Mat_SeqDense *)A->data;
149513f74950SBarry Smith   PetscInt          i, j;
14962dcb1b2aSMatthew Knepley   const char       *name;
1497ca15aa20SStefano Zampini   PetscScalar      *v, *av;
1498f3ef73ceSBarry Smith   PetscViewerFormat format;
14995f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX)
1500ace3abfcSBarry Smith   PetscBool allreal = PETSC_TRUE;
15015f481a85SSatish Balay #endif
1502932b0c3eSLois Curfman McInnes 
15033a40ed3dSBarry Smith   PetscFunctionBegin;
15049566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&av));
15059566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
1506456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
15073a40ed3dSBarry Smith     PetscFunctionReturn(0); /* do nothing for now */
1508fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
15099566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
1510d0f46423SBarry Smith     for (i = 0; i < A->rmap->n; i++) {
1511ca15aa20SStefano Zampini       v = av + i;
15129566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "row %" PetscInt_FMT ":", i));
1513d0f46423SBarry Smith       for (j = 0; j < A->cmap->n; j++) {
1514aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1515329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
15169566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g + %g i) ", j, (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v)));
1517329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
15189566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)PetscRealPart(*v)));
15196831982aSBarry Smith         }
152080cd9d93SLois Curfman McInnes #else
152148a46eb9SPierre Jolivet         if (*v) PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)*v));
152280cd9d93SLois Curfman McInnes #endif
15231b807ce4Svictorle         v += a->lda;
152480cd9d93SLois Curfman McInnes       }
15259566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
152680cd9d93SLois Curfman McInnes     }
15279566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
15283a40ed3dSBarry Smith   } else {
15299566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
1530aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
153147989497SBarry Smith     /* determine if matrix has all real values */
1532bcd8d3a4SJose E. Roman     for (j = 0; j < A->cmap->n; j++) {
1533bcd8d3a4SJose E. Roman       v = av + j * a->lda;
1534bcd8d3a4SJose E. Roman       for (i = 0; i < A->rmap->n; i++) {
15359371c9d4SSatish Balay         if (PetscImaginaryPart(v[i])) {
15369371c9d4SSatish Balay           allreal = PETSC_FALSE;
15379371c9d4SSatish Balay           break;
15389371c9d4SSatish Balay         }
153947989497SBarry Smith       }
1540bcd8d3a4SJose E. Roman     }
154147989497SBarry Smith #endif
1542fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
15439566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetName((PetscObject)A, &name));
15449566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%% Size = %" PetscInt_FMT " %" PetscInt_FMT " \n", A->rmap->n, A->cmap->n));
15459566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%s = zeros(%" PetscInt_FMT ",%" PetscInt_FMT ");\n", name, A->rmap->n, A->cmap->n));
15469566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%s = [\n", name));
1547ffac6cdbSBarry Smith     }
1548ffac6cdbSBarry Smith 
1549d0f46423SBarry Smith     for (i = 0; i < A->rmap->n; i++) {
1550ca15aa20SStefano Zampini       v = av + i;
1551d0f46423SBarry Smith       for (j = 0; j < A->cmap->n; j++) {
1552aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
155347989497SBarry Smith         if (allreal) {
15549566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)PetscRealPart(*v)));
155547989497SBarry Smith         } else {
15569566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e + %18.16ei ", (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v)));
155747989497SBarry Smith         }
1558289bc588SBarry Smith #else
15599566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)*v));
1560289bc588SBarry Smith #endif
15611b807ce4Svictorle         v += a->lda;
1562289bc588SBarry Smith       }
15639566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
1564289bc588SBarry Smith     }
156548a46eb9SPierre Jolivet     if (format == PETSC_VIEWER_ASCII_MATLAB) PetscCall(PetscViewerASCIIPrintf(viewer, "];\n"));
15669566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
1567da3a660dSBarry Smith   }
15689566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&av));
15699566063dSJacob Faibussowitsch   PetscCall(PetscViewerFlush(viewer));
15703a40ed3dSBarry Smith   PetscFunctionReturn(0);
1571289bc588SBarry Smith }
1572289bc588SBarry Smith 
15739804daf3SBarry Smith #include <petscdraw.h>
1574d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw, void *Aa)
1575d71ae5a4SJacob Faibussowitsch {
1576f1af5d2fSBarry Smith   Mat                A = (Mat)Aa;
1577383922c3SLisandro Dalcin   PetscInt           m = A->rmap->n, n = A->cmap->n, i, j;
1578383922c3SLisandro Dalcin   int                color = PETSC_DRAW_WHITE;
1579ca15aa20SStefano Zampini   const PetscScalar *v;
1580b0a32e0cSBarry Smith   PetscViewer        viewer;
1581b05fc000SLisandro Dalcin   PetscReal          xl, yl, xr, yr, x_l, x_r, y_l, y_r;
1582f3ef73ceSBarry Smith   PetscViewerFormat  format;
1583f1af5d2fSBarry Smith 
1584f1af5d2fSBarry Smith   PetscFunctionBegin;
15859566063dSJacob Faibussowitsch   PetscCall(PetscObjectQuery((PetscObject)A, "Zoomviewer", (PetscObject *)&viewer));
15869566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
15879566063dSJacob Faibussowitsch   PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr));
1588f1af5d2fSBarry Smith 
1589f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
15909566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &v));
1591fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
1592d0609cedSBarry Smith     PetscDrawCollectiveBegin(draw);
1593f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
1594f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
15959371c9d4SSatish Balay       x_l = j;
15969371c9d4SSatish Balay       x_r = x_l + 1.0;
1597f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1598f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1599f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1600ca15aa20SStefano Zampini         if (PetscRealPart(v[j * m + i]) > 0.) color = PETSC_DRAW_RED;
1601ca15aa20SStefano Zampini         else if (PetscRealPart(v[j * m + i]) < 0.) color = PETSC_DRAW_BLUE;
1602ca15aa20SStefano Zampini         else continue;
16039566063dSJacob Faibussowitsch         PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color));
1604f1af5d2fSBarry Smith       }
1605f1af5d2fSBarry Smith     }
1606d0609cedSBarry Smith     PetscDrawCollectiveEnd(draw);
1607f1af5d2fSBarry Smith   } else {
1608f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
1609f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
1610b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1611b05fc000SLisandro Dalcin     PetscDraw popup;
1612b05fc000SLisandro Dalcin 
1613f1af5d2fSBarry Smith     for (i = 0; i < m * n; i++) {
1614f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
1615f1af5d2fSBarry Smith     }
1616383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
16179566063dSJacob Faibussowitsch     PetscCall(PetscDrawGetPopup(draw, &popup));
16189566063dSJacob Faibussowitsch     PetscCall(PetscDrawScalePopup(popup, minv, maxv));
1619383922c3SLisandro Dalcin 
1620d0609cedSBarry Smith     PetscDrawCollectiveBegin(draw);
1621f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
1622f1af5d2fSBarry Smith       x_l = j;
1623f1af5d2fSBarry Smith       x_r = x_l + 1.0;
1624f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1625f1af5d2fSBarry Smith         y_l   = m - i - 1.0;
1626f1af5d2fSBarry Smith         y_r   = y_l + 1.0;
1627b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(v[j * m + i]), minv, maxv);
16289566063dSJacob Faibussowitsch         PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color));
1629f1af5d2fSBarry Smith       }
1630f1af5d2fSBarry Smith     }
1631d0609cedSBarry Smith     PetscDrawCollectiveEnd(draw);
1632f1af5d2fSBarry Smith   }
16339566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &v));
1634f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1635f1af5d2fSBarry Smith }
1636f1af5d2fSBarry Smith 
1637d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw(Mat A, PetscViewer viewer)
1638d71ae5a4SJacob Faibussowitsch {
1639b0a32e0cSBarry Smith   PetscDraw draw;
1640ace3abfcSBarry Smith   PetscBool isnull;
1641329f5518SBarry Smith   PetscReal xr, yr, xl, yl, h, w;
1642f1af5d2fSBarry Smith 
1643f1af5d2fSBarry Smith   PetscFunctionBegin;
16449566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
16459566063dSJacob Faibussowitsch   PetscCall(PetscDrawIsNull(draw, &isnull));
1646abc0a331SBarry Smith   if (isnull) PetscFunctionReturn(0);
1647f1af5d2fSBarry Smith 
16489371c9d4SSatish Balay   xr = A->cmap->n;
16499371c9d4SSatish Balay   yr = A->rmap->n;
16509371c9d4SSatish Balay   h  = yr / 10.0;
16519371c9d4SSatish Balay   w  = xr / 10.0;
16529371c9d4SSatish Balay   xr += w;
16539371c9d4SSatish Balay   yr += h;
16549371c9d4SSatish Balay   xl = -w;
16559371c9d4SSatish Balay   yl = -h;
16569566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetCoordinates(draw, xl, yl, xr, yr));
16579566063dSJacob Faibussowitsch   PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", (PetscObject)viewer));
16589566063dSJacob Faibussowitsch   PetscCall(PetscDrawZoom(draw, MatView_SeqDense_Draw_Zoom, A));
16599566063dSJacob Faibussowitsch   PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", NULL));
16609566063dSJacob Faibussowitsch   PetscCall(PetscDrawSave(draw));
1661f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1662f1af5d2fSBarry Smith }
1663f1af5d2fSBarry Smith 
1664d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_SeqDense(Mat A, PetscViewer viewer)
1665d71ae5a4SJacob Faibussowitsch {
1666ace3abfcSBarry Smith   PetscBool iascii, isbinary, isdraw;
1667932b0c3eSLois Curfman McInnes 
16683a40ed3dSBarry Smith   PetscFunctionBegin;
16699566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
16709566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
16719566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
16721baa6e33SBarry Smith   if (iascii) PetscCall(MatView_SeqDense_ASCII(A, viewer));
16731baa6e33SBarry Smith   else if (isbinary) PetscCall(MatView_Dense_Binary(A, viewer));
16741baa6e33SBarry Smith   else if (isdraw) PetscCall(MatView_SeqDense_Draw(A, viewer));
16753a40ed3dSBarry Smith   PetscFunctionReturn(0);
1676932b0c3eSLois Curfman McInnes }
1677289bc588SBarry Smith 
1678d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A, const PetscScalar *array)
1679d71ae5a4SJacob Faibussowitsch {
1680d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
1681d3042a70SBarry Smith 
1682d3042a70SBarry Smith   PetscFunctionBegin;
168328b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
168428b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
168528b400f6SJacob Faibussowitsch   PetscCheck(!a->unplacedarray, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreArray() first");
1686d3042a70SBarry Smith   a->unplacedarray       = a->v;
1687d3042a70SBarry Smith   a->unplaced_user_alloc = a->user_alloc;
1688d3042a70SBarry Smith   a->v                   = (PetscScalar *)array;
1689637a0070SStefano Zampini   a->user_alloc          = PETSC_TRUE;
169047d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
1691c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1692ca15aa20SStefano Zampini #endif
1693d3042a70SBarry Smith   PetscFunctionReturn(0);
1694d3042a70SBarry Smith }
1695d3042a70SBarry Smith 
1696d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseResetArray_SeqDense(Mat A)
1697d71ae5a4SJacob Faibussowitsch {
1698d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
1699d3042a70SBarry Smith 
1700d3042a70SBarry Smith   PetscFunctionBegin;
170128b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
170228b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
1703d3042a70SBarry Smith   a->v             = a->unplacedarray;
1704d3042a70SBarry Smith   a->user_alloc    = a->unplaced_user_alloc;
1705d3042a70SBarry Smith   a->unplacedarray = NULL;
170647d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
1707c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1708ca15aa20SStefano Zampini #endif
1709d3042a70SBarry Smith   PetscFunctionReturn(0);
1710d3042a70SBarry Smith }
1711d3042a70SBarry Smith 
1712d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A, const PetscScalar *array)
1713d71ae5a4SJacob Faibussowitsch {
1714d5ea218eSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
1715d5ea218eSStefano Zampini 
1716d5ea218eSStefano Zampini   PetscFunctionBegin;
171728b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
171828b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
17199566063dSJacob Faibussowitsch   if (!a->user_alloc) PetscCall(PetscFree(a->v));
1720d5ea218eSStefano Zampini   a->v          = (PetscScalar *)array;
1721d5ea218eSStefano Zampini   a->user_alloc = PETSC_FALSE;
172247d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
1723d5ea218eSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
1724d5ea218eSStefano Zampini #endif
1725d5ea218eSStefano Zampini   PetscFunctionReturn(0);
1726d5ea218eSStefano Zampini }
1727d5ea218eSStefano Zampini 
1728d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDestroy_SeqDense(Mat mat)
1729d71ae5a4SJacob Faibussowitsch {
1730ec8511deSBarry Smith   Mat_SeqDense *l = (Mat_SeqDense *)mat->data;
173190f02eecSBarry Smith 
17323a40ed3dSBarry Smith   PetscFunctionBegin;
1733aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1734c0aa6a63SJacob Faibussowitsch   PetscLogObjectState((PetscObject)mat, "Rows %" PetscInt_FMT " Cols %" PetscInt_FMT, mat->rmap->n, mat->cmap->n);
1735a5a9c739SBarry Smith #endif
17369566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(l->qrrhs)));
17379566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->tau));
17389566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->pivots));
17399566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->fwork));
17409566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&l->ptapwork));
17419566063dSJacob Faibussowitsch   if (!l->user_alloc) PetscCall(PetscFree(l->v));
17429566063dSJacob Faibussowitsch   if (!l->unplaced_user_alloc) PetscCall(PetscFree(l->unplacedarray));
174328b400f6SJacob Faibussowitsch   PetscCheck(!l->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
174428b400f6SJacob Faibussowitsch   PetscCheck(!l->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
17459566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&l->cvec));
17469566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&l->cmat));
17479566063dSJacob Faibussowitsch   PetscCall(PetscFree(mat->data));
1748dbd8c25aSHong Zhang 
17499566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)mat, NULL));
17509566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactor_C", NULL));
17512e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorSymbolic_C", NULL));
17522e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorNumeric_C", NULL));
17539566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetLDA_C", NULL));
17549566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseSetLDA_C", NULL));
17559566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArray_C", NULL));
17569566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArray_C", NULL));
17579566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDensePlaceArray_C", NULL));
17589566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseResetArray_C", NULL));
17599566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseReplaceArray_C", NULL));
17609566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayRead_C", NULL));
17619566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayRead_C", NULL));
17629566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayWrite_C", NULL));
17639566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayWrite_C", NULL));
17649566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqaij_C", NULL));
17658baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
17669566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_elemental_C", NULL));
17678baccfbdSHong Zhang #endif
1768d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
17699566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_scalapack_C", NULL));
1770d24d4204SJose E. Roman #endif
17712bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
17729566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensecuda_C", NULL));
17739566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", NULL));
17749566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdense_C", NULL));
17752e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensecuda_C", NULL));
17762bf066beSStefano Zampini #endif
177747d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP)
177847d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensehip_C", NULL));
177947d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensehip_seqdensehip_C", NULL));
178047d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensehip_seqdense_C", NULL));
178147d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensehip_C", NULL));
178247d993e7Ssuyashtn #endif
17839566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatSeqDenseSetPreallocation_C", NULL));
17849566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqaij_seqdense_C", NULL));
17859566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdense_C", NULL));
17869566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqbaij_seqdense_C", NULL));
17879566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqsbaij_seqdense_C", NULL));
178852c5f739Sprj- 
17899566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumn_C", NULL));
17909566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumn_C", NULL));
17919566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVec_C", NULL));
17929566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVec_C", NULL));
17939566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecRead_C", NULL));
17949566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecRead_C", NULL));
17959566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecWrite_C", NULL));
17969566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecWrite_C", NULL));
17979566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetSubMatrix_C", NULL));
17989566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreSubMatrix_C", NULL));
17993a40ed3dSBarry Smith   PetscFunctionReturn(0);
1800289bc588SBarry Smith }
1801289bc588SBarry Smith 
1802d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatTranspose_SeqDense(Mat A, MatReuse reuse, Mat *matout)
1803d71ae5a4SJacob Faibussowitsch {
1804c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
18056536e3caSStefano Zampini   PetscInt      k, j, m = A->rmap->n, M = mat->lda, n = A->cmap->n;
180687828ca2SBarry Smith   PetscScalar  *v, tmp;
180748b35521SBarry Smith 
18083a40ed3dSBarry Smith   PetscFunctionBegin;
18097fb60732SBarry Smith   if (reuse == MAT_REUSE_MATRIX) PetscCall(MatTransposeCheckNonzeroState_Private(A, *matout));
18106536e3caSStefano Zampini   if (reuse == MAT_INPLACE_MATRIX) {
18116536e3caSStefano Zampini     if (m == n) { /* in place transpose */
18129566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(A, &v));
1813d3e5ee88SLois Curfman McInnes       for (j = 0; j < m; j++) {
1814289bc588SBarry Smith         for (k = 0; k < j; k++) {
18151b807ce4Svictorle           tmp          = v[j + k * M];
18161b807ce4Svictorle           v[j + k * M] = v[k + j * M];
18171b807ce4Svictorle           v[k + j * M] = tmp;
1818289bc588SBarry Smith         }
1819289bc588SBarry Smith       }
18209566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArray(A, &v));
18216536e3caSStefano Zampini     } else { /* reuse memory, temporary allocates new memory */
18226536e3caSStefano Zampini       PetscScalar *v2;
18236536e3caSStefano Zampini       PetscLayout  tmplayout;
18246536e3caSStefano Zampini 
18259566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1((size_t)m * n, &v2));
18269566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(A, &v));
18276536e3caSStefano Zampini       for (j = 0; j < n; j++) {
18286536e3caSStefano Zampini         for (k = 0; k < m; k++) v2[j + (size_t)k * n] = v[k + (size_t)j * M];
18296536e3caSStefano Zampini       }
18309566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(v, v2, (size_t)m * n));
18319566063dSJacob Faibussowitsch       PetscCall(PetscFree(v2));
18329566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArray(A, &v));
18336536e3caSStefano Zampini       /* cleanup size dependent quantities */
18349566063dSJacob Faibussowitsch       PetscCall(VecDestroy(&mat->cvec));
18359566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&mat->cmat));
18369566063dSJacob Faibussowitsch       PetscCall(PetscFree(mat->pivots));
18379566063dSJacob Faibussowitsch       PetscCall(PetscFree(mat->fwork));
18389566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&mat->ptapwork));
18396536e3caSStefano Zampini       /* swap row/col layouts */
18406536e3caSStefano Zampini       mat->lda  = n;
18416536e3caSStefano Zampini       tmplayout = A->rmap;
18426536e3caSStefano Zampini       A->rmap   = A->cmap;
18436536e3caSStefano Zampini       A->cmap   = tmplayout;
18446536e3caSStefano Zampini     }
18453a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1846d3e5ee88SLois Curfman McInnes     Mat           tmat;
1847ec8511deSBarry Smith     Mat_SeqDense *tmatd;
184887828ca2SBarry Smith     PetscScalar  *v2;
1849af36a384SStefano Zampini     PetscInt      M2;
1850ea709b57SSatish Balay 
18516536e3caSStefano Zampini     if (reuse == MAT_INITIAL_MATRIX) {
18529566063dSJacob Faibussowitsch       PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &tmat));
18539566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(tmat, A->cmap->n, A->rmap->n, A->cmap->n, A->rmap->n));
18549566063dSJacob Faibussowitsch       PetscCall(MatSetType(tmat, ((PetscObject)A)->type_name));
18559566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSetPreallocation(tmat, NULL));
1856ca15aa20SStefano Zampini     } else tmat = *matout;
1857ca15aa20SStefano Zampini 
18589566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&v));
18599566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArray(tmat, &v2));
1860ec8511deSBarry Smith     tmatd = (Mat_SeqDense *)tmat->data;
1861ca15aa20SStefano Zampini     M2    = tmatd->lda;
1862d3e5ee88SLois Curfman McInnes     for (j = 0; j < n; j++) {
1863af36a384SStefano Zampini       for (k = 0; k < m; k++) v2[j + k * M2] = v[k + j * M];
1864d3e5ee88SLois Curfman McInnes     }
18659566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(tmat, &v2));
18669566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&v));
18679566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(tmat, MAT_FINAL_ASSEMBLY));
18689566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(tmat, MAT_FINAL_ASSEMBLY));
18696536e3caSStefano Zampini     *matout = tmat;
187048b35521SBarry Smith   }
18713a40ed3dSBarry Smith   PetscFunctionReturn(0);
1872289bc588SBarry Smith }
1873289bc588SBarry Smith 
1874d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatEqual_SeqDense(Mat A1, Mat A2, PetscBool *flg)
1875d71ae5a4SJacob Faibussowitsch {
1876c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat1 = (Mat_SeqDense *)A1->data;
1877c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat2 = (Mat_SeqDense *)A2->data;
1878ca15aa20SStefano Zampini   PetscInt           i;
1879ca15aa20SStefano Zampini   const PetscScalar *v1, *v2;
18809ea5d5aeSSatish Balay 
18813a40ed3dSBarry Smith   PetscFunctionBegin;
18829371c9d4SSatish Balay   if (A1->rmap->n != A2->rmap->n) {
18839371c9d4SSatish Balay     *flg = PETSC_FALSE;
18849371c9d4SSatish Balay     PetscFunctionReturn(0);
18859371c9d4SSatish Balay   }
18869371c9d4SSatish Balay   if (A1->cmap->n != A2->cmap->n) {
18879371c9d4SSatish Balay     *flg = PETSC_FALSE;
18889371c9d4SSatish Balay     PetscFunctionReturn(0);
18899371c9d4SSatish Balay   }
18909566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A1, &v1));
18919566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A2, &v2));
1892ca15aa20SStefano Zampini   for (i = 0; i < A1->cmap->n; i++) {
18939566063dSJacob Faibussowitsch     PetscCall(PetscArraycmp(v1, v2, A1->rmap->n, flg));
1894ca15aa20SStefano Zampini     if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
1895ca15aa20SStefano Zampini     v1 += mat1->lda;
1896ca15aa20SStefano Zampini     v2 += mat2->lda;
18971b807ce4Svictorle   }
18989566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A1, &v1));
18999566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A2, &v2));
190077c4ece6SBarry Smith   *flg = PETSC_TRUE;
19013a40ed3dSBarry Smith   PetscFunctionReturn(0);
1902289bc588SBarry Smith }
1903289bc588SBarry Smith 
1904d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetDiagonal_SeqDense(Mat A, Vec v)
1905d71ae5a4SJacob Faibussowitsch {
1906c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
190713f74950SBarry Smith   PetscInt           i, n, len;
1908ca15aa20SStefano Zampini   PetscScalar       *x;
1909ca15aa20SStefano Zampini   const PetscScalar *vv;
191044cd7ae7SLois Curfman McInnes 
19113a40ed3dSBarry Smith   PetscFunctionBegin;
19129566063dSJacob Faibussowitsch   PetscCall(VecGetSize(v, &n));
19139566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
1914d0f46423SBarry Smith   len = PetscMin(A->rmap->n, A->cmap->n);
19159566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &vv));
191608401ef6SPierre Jolivet   PetscCheck(n == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming mat and vec");
1917ad540459SPierre Jolivet   for (i = 0; i < len; i++) x[i] = vv[i * mat->lda + i];
19189566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &vv));
19199566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
19203a40ed3dSBarry Smith   PetscFunctionReturn(0);
1921289bc588SBarry Smith }
1922289bc588SBarry Smith 
1923d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDiagonalScale_SeqDense(Mat A, Vec ll, Vec rr)
1924d71ae5a4SJacob Faibussowitsch {
1925c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1926f1ceaac6SMatthew G. Knepley   const PetscScalar *l, *r;
1927ca15aa20SStefano Zampini   PetscScalar        x, *v, *vv;
1928d0f46423SBarry Smith   PetscInt           i, j, m = A->rmap->n, n = A->cmap->n;
192955659b69SBarry Smith 
19303a40ed3dSBarry Smith   PetscFunctionBegin;
19319566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &vv));
193228988994SBarry Smith   if (ll) {
19339566063dSJacob Faibussowitsch     PetscCall(VecGetSize(ll, &m));
19349566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ll, &l));
193508401ef6SPierre Jolivet     PetscCheck(m == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Left scaling vec wrong size");
1936da3a660dSBarry Smith     for (i = 0; i < m; i++) {
1937da3a660dSBarry Smith       x = l[i];
1938ca15aa20SStefano Zampini       v = vv + i;
19399371c9d4SSatish Balay       for (j = 0; j < n; j++) {
19409371c9d4SSatish Balay         (*v) *= x;
19419371c9d4SSatish Balay         v += mat->lda;
19429371c9d4SSatish Balay       }
1943da3a660dSBarry Smith     }
19449566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ll, &l));
19459566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0 * n * m));
1946da3a660dSBarry Smith   }
194728988994SBarry Smith   if (rr) {
19489566063dSJacob Faibussowitsch     PetscCall(VecGetSize(rr, &n));
19499566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(rr, &r));
195008401ef6SPierre Jolivet     PetscCheck(n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Right scaling vec wrong size");
1951da3a660dSBarry Smith     for (i = 0; i < n; i++) {
1952da3a660dSBarry Smith       x = r[i];
1953ca15aa20SStefano Zampini       v = vv + i * mat->lda;
19542205254eSKarl Rupp       for (j = 0; j < m; j++) (*v++) *= x;
1955da3a660dSBarry Smith     }
19569566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(rr, &r));
19579566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0 * n * m));
1958da3a660dSBarry Smith   }
19599566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &vv));
19603a40ed3dSBarry Smith   PetscFunctionReturn(0);
1961289bc588SBarry Smith }
1962289bc588SBarry Smith 
1963d71ae5a4SJacob Faibussowitsch PetscErrorCode MatNorm_SeqDense(Mat A, NormType type, PetscReal *nrm)
1964d71ae5a4SJacob Faibussowitsch {
1965c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
1966ca15aa20SStefano Zampini   PetscScalar  *v, *vv;
1967329f5518SBarry Smith   PetscReal     sum = 0.0;
196875f6d85dSStefano Zampini   PetscInt      lda, m = A->rmap->n, i, j;
196955659b69SBarry Smith 
19703a40ed3dSBarry Smith   PetscFunctionBegin;
19719566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&vv));
19729566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(A, &lda));
1973ca15aa20SStefano Zampini   v = vv;
1974289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1975a5ce6ee0Svictorle     if (lda > m) {
1976d0f46423SBarry Smith       for (j = 0; j < A->cmap->n; j++) {
1977ca15aa20SStefano Zampini         v = vv + j * lda;
1978a5ce6ee0Svictorle         for (i = 0; i < m; i++) {
19799371c9d4SSatish Balay           sum += PetscRealPart(PetscConj(*v) * (*v));
19809371c9d4SSatish Balay           v++;
1981a5ce6ee0Svictorle         }
1982a5ce6ee0Svictorle       }
1983a5ce6ee0Svictorle     } else {
1984570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1985570b7f6dSBarry Smith       PetscBLASInt one = 1, cnt = A->cmap->n * A->rmap->n;
1986792fecdfSBarry Smith       PetscCallBLAS("BLASnrm2", *nrm = BLASnrm2_(&cnt, v, &one));
1987570b7f6dSBarry Smith     }
1988570b7f6dSBarry Smith #else
1989d0f46423SBarry Smith       for (i = 0; i < A->cmap->n * A->rmap->n; i++) {
19909371c9d4SSatish Balay         sum += PetscRealPart(PetscConj(*v) * (*v));
19919371c9d4SSatish Balay         v++;
1992289bc588SBarry Smith       }
1993a5ce6ee0Svictorle     }
19948f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1995570b7f6dSBarry Smith #endif
19969566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0 * A->cmap->n * A->rmap->n));
19973a40ed3dSBarry Smith   } else if (type == NORM_1) {
1998064f8208SBarry Smith     *nrm = 0.0;
1999d0f46423SBarry Smith     for (j = 0; j < A->cmap->n; j++) {
2000ca15aa20SStefano Zampini       v   = vv + j * mat->lda;
2001289bc588SBarry Smith       sum = 0.0;
2002d0f46423SBarry Smith       for (i = 0; i < A->rmap->n; i++) {
20039371c9d4SSatish Balay         sum += PetscAbsScalar(*v);
20049371c9d4SSatish Balay         v++;
2005289bc588SBarry Smith       }
2006064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
2007289bc588SBarry Smith     }
20089566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n));
20093a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
2010064f8208SBarry Smith     *nrm = 0.0;
2011d0f46423SBarry Smith     for (j = 0; j < A->rmap->n; j++) {
2012ca15aa20SStefano Zampini       v   = vv + j;
2013289bc588SBarry Smith       sum = 0.0;
2014d0f46423SBarry Smith       for (i = 0; i < A->cmap->n; i++) {
20159371c9d4SSatish Balay         sum += PetscAbsScalar(*v);
20169371c9d4SSatish Balay         v += mat->lda;
2017289bc588SBarry Smith       }
2018064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
2019289bc588SBarry Smith     }
20209566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n));
2021e7e72b3dSBarry Smith   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "No two norm");
20229566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&vv));
20233a40ed3dSBarry Smith   PetscFunctionReturn(0);
2024289bc588SBarry Smith }
2025289bc588SBarry Smith 
2026d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetOption_SeqDense(Mat A, MatOption op, PetscBool flg)
2027d71ae5a4SJacob Faibussowitsch {
2028c0bbcb79SLois Curfman McInnes   Mat_SeqDense *aij = (Mat_SeqDense *)A->data;
202967e560aaSBarry Smith 
20303a40ed3dSBarry Smith   PetscFunctionBegin;
2031b5a2b587SKris Buschelman   switch (op) {
2032d71ae5a4SJacob Faibussowitsch   case MAT_ROW_ORIENTED:
2033d71ae5a4SJacob Faibussowitsch     aij->roworiented = flg;
2034d71ae5a4SJacob Faibussowitsch     break;
2035512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
2036b5a2b587SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
20373971808eSMatthew Knepley   case MAT_NEW_NONZERO_ALLOCATION_ERR:
20388c78258cSHong Zhang   case MAT_FORCE_DIAGONAL_ENTRIES:
203913fa8e87SLisandro Dalcin   case MAT_KEEP_NONZERO_PATTERN:
2040b5a2b587SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
2041b5a2b587SKris Buschelman   case MAT_USE_HASH_TABLE:
20420f8fb01aSBarry Smith   case MAT_IGNORE_ZERO_ENTRIES:
20435021d80fSJed Brown   case MAT_IGNORE_LOWER_TRIANGULAR:
2044d71ae5a4SJacob Faibussowitsch   case MAT_SORTED_FULL:
2045d71ae5a4SJacob Faibussowitsch     PetscCall(PetscInfo(A, "Option %s ignored\n", MatOptions[op]));
2046d71ae5a4SJacob Faibussowitsch     break;
20475021d80fSJed Brown   case MAT_SPD:
204877e54ba9SKris Buschelman   case MAT_SYMMETRIC:
204977e54ba9SKris Buschelman   case MAT_STRUCTURALLY_SYMMETRIC:
20509a4540c5SBarry Smith   case MAT_HERMITIAN:
20519a4540c5SBarry Smith   case MAT_SYMMETRY_ETERNAL:
2052b94d7dedSBarry Smith   case MAT_STRUCTURAL_SYMMETRY_ETERNAL:
2053d71ae5a4SJacob Faibussowitsch   case MAT_SPD_ETERNAL:
2054d71ae5a4SJacob Faibussowitsch     break;
2055d71ae5a4SJacob Faibussowitsch   default:
2056d71ae5a4SJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "unknown option %s", MatOptions[op]);
20573a40ed3dSBarry Smith   }
20583a40ed3dSBarry Smith   PetscFunctionReturn(0);
2059289bc588SBarry Smith }
2060289bc588SBarry Smith 
2061d71ae5a4SJacob Faibussowitsch PetscErrorCode MatZeroEntries_SeqDense(Mat A)
2062d71ae5a4SJacob Faibussowitsch {
2063ec8511deSBarry Smith   Mat_SeqDense *l   = (Mat_SeqDense *)A->data;
20643d8925e7SStefano Zampini   PetscInt      lda = l->lda, m = A->rmap->n, n = A->cmap->n, j;
2065ca15aa20SStefano Zampini   PetscScalar  *v;
20663a40ed3dSBarry Smith 
20673a40ed3dSBarry Smith   PetscFunctionBegin;
20689566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(A, &v));
2069a5ce6ee0Svictorle   if (lda > m) {
207048a46eb9SPierre Jolivet     for (j = 0; j < n; j++) PetscCall(PetscArrayzero(v + j * lda, m));
2071a5ce6ee0Svictorle   } else {
20729566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(v, PetscInt64Mult(m, n)));
2073a5ce6ee0Svictorle   }
20749566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(A, &v));
20753a40ed3dSBarry Smith   PetscFunctionReturn(0);
20766f0a148fSBarry Smith }
20776f0a148fSBarry Smith 
2078d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatZeroRows_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b)
2079d71ae5a4SJacob Faibussowitsch {
2080ec8511deSBarry Smith   Mat_SeqDense      *l = (Mat_SeqDense *)A->data;
2081b9679d65SBarry Smith   PetscInt           m = l->lda, n = A->cmap->n, i, j;
2082ca15aa20SStefano Zampini   PetscScalar       *slot, *bb, *v;
208397b48c8fSBarry Smith   const PetscScalar *xx;
208455659b69SBarry Smith 
20853a40ed3dSBarry Smith   PetscFunctionBegin;
208676bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
2087b9679d65SBarry Smith     for (i = 0; i < N; i++) {
208808401ef6SPierre Jolivet       PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed");
208908401ef6SPierre 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);
2090b9679d65SBarry Smith     }
209176bd3646SJed Brown   }
2092ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
2093b9679d65SBarry Smith 
209497b48c8fSBarry Smith   /* fix right hand side if needed */
209597b48c8fSBarry Smith   if (x && b) {
20969566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(x, &xx));
20979566063dSJacob Faibussowitsch     PetscCall(VecGetArray(b, &bb));
20982205254eSKarl Rupp     for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]];
20999566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(x, &xx));
21009566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(b, &bb));
210197b48c8fSBarry Smith   }
210297b48c8fSBarry Smith 
21039566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
21046f0a148fSBarry Smith   for (i = 0; i < N; i++) {
2105ca15aa20SStefano Zampini     slot = v + rows[i];
21069371c9d4SSatish Balay     for (j = 0; j < n; j++) {
21079371c9d4SSatish Balay       *slot = 0.0;
21089371c9d4SSatish Balay       slot += m;
21099371c9d4SSatish Balay     }
21106f0a148fSBarry Smith   }
2111f4df32b1SMatthew Knepley   if (diag != 0.0) {
211208401ef6SPierre Jolivet     PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices");
21136f0a148fSBarry Smith     for (i = 0; i < N; i++) {
2114ca15aa20SStefano Zampini       slot  = v + (m + 1) * rows[i];
2115f4df32b1SMatthew Knepley       *slot = diag;
21166f0a148fSBarry Smith     }
21176f0a148fSBarry Smith   }
21189566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
21193a40ed3dSBarry Smith   PetscFunctionReturn(0);
21206f0a148fSBarry Smith }
2121557bce09SLois Curfman McInnes 
2122d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A, PetscInt *lda)
2123d71ae5a4SJacob Faibussowitsch {
212449a6ff4bSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
212549a6ff4bSBarry Smith 
212649a6ff4bSBarry Smith   PetscFunctionBegin;
212749a6ff4bSBarry Smith   *lda = mat->lda;
212849a6ff4bSBarry Smith   PetscFunctionReturn(0);
212949a6ff4bSBarry Smith }
213049a6ff4bSBarry Smith 
2131d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArray_SeqDense(Mat A, PetscScalar **array)
2132d71ae5a4SJacob Faibussowitsch {
2133c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
21343a40ed3dSBarry Smith 
21353a40ed3dSBarry Smith   PetscFunctionBegin;
213628b400f6SJacob Faibussowitsch   PetscCheck(!mat->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
213764e87e97SBarry Smith   *array = mat->v;
21383a40ed3dSBarry Smith   PetscFunctionReturn(0);
213964e87e97SBarry Smith }
21400754003eSLois Curfman McInnes 
2141d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A, PetscScalar **array)
2142d71ae5a4SJacob Faibussowitsch {
21433a40ed3dSBarry Smith   PetscFunctionBegin;
214475f6d85dSStefano Zampini   if (array) *array = NULL;
21453a40ed3dSBarry Smith   PetscFunctionReturn(0);
2146ff14e315SSatish Balay }
21470754003eSLois Curfman McInnes 
21480f74d2c1SSatish Balay /*@
214911a5261eSBarry Smith    MatDenseGetLDA - gets the leading dimension of the array returned from `MatDenseGetArray()`
215049a6ff4bSBarry Smith 
2151ad16ce7aSStefano Zampini    Not collective
215249a6ff4bSBarry Smith 
215349a6ff4bSBarry Smith    Input Parameter:
215411a5261eSBarry Smith .  mat - a `MATDENSE` or `MATDENSECUDA` matrix
215549a6ff4bSBarry Smith 
215649a6ff4bSBarry Smith    Output Parameter:
215749a6ff4bSBarry Smith .   lda - the leading dimension
215849a6ff4bSBarry Smith 
215949a6ff4bSBarry Smith    Level: intermediate
216049a6ff4bSBarry Smith 
216111a5261eSBarry Smith .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseSetLDA()`
216249a6ff4bSBarry Smith @*/
2163d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetLDA(Mat A, PetscInt *lda)
2164d71ae5a4SJacob Faibussowitsch {
216549a6ff4bSBarry Smith   PetscFunctionBegin;
2166d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2167dadcf809SJacob Faibussowitsch   PetscValidIntPointer(lda, 2);
216875f6d85dSStefano Zampini   MatCheckPreallocated(A, 1);
2169cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetLDA_C", (Mat, PetscInt *), (A, lda));
217049a6ff4bSBarry Smith   PetscFunctionReturn(0);
217149a6ff4bSBarry Smith }
217249a6ff4bSBarry Smith 
21730f74d2c1SSatish Balay /*@
217411a5261eSBarry Smith    MatDenseSetLDA - Sets the leading dimension of the array used by the `MATDENSE` matrix
2175ad16ce7aSStefano Zampini 
2176ad16ce7aSStefano Zampini    Not collective
2177ad16ce7aSStefano Zampini 
2178d8d19677SJose E. Roman    Input Parameters:
217911a5261eSBarry Smith +  mat - a `MATDENSE` or `MATDENSECUDA` matrix
2180ad16ce7aSStefano Zampini -  lda - the leading dimension
2181ad16ce7aSStefano Zampini 
2182ad16ce7aSStefano Zampini    Level: intermediate
2183ad16ce7aSStefano Zampini 
218411a5261eSBarry Smith .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetLDA()`
2185ad16ce7aSStefano Zampini @*/
2186d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA(Mat A, PetscInt lda)
2187d71ae5a4SJacob Faibussowitsch {
2188ad16ce7aSStefano Zampini   PetscFunctionBegin;
2189ad16ce7aSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2190cac4c232SBarry Smith   PetscTryMethod(A, "MatDenseSetLDA_C", (Mat, PetscInt), (A, lda));
2191ad16ce7aSStefano Zampini   PetscFunctionReturn(0);
2192ad16ce7aSStefano Zampini }
2193ad16ce7aSStefano Zampini 
2194ad16ce7aSStefano Zampini /*@C
219511a5261eSBarry Smith    MatDenseGetArray - gives read-write access to the array where the data for a `MATDENSE` matrix is stored
219673a71a0fSBarry Smith 
2197c3339decSBarry Smith    Logically Collective
219873a71a0fSBarry Smith 
219973a71a0fSBarry Smith    Input Parameter:
22006947451fSStefano Zampini .  mat - a dense matrix
220173a71a0fSBarry Smith 
220273a71a0fSBarry Smith    Output Parameter:
220373a71a0fSBarry Smith .   array - pointer to the data
220473a71a0fSBarry Smith 
220573a71a0fSBarry Smith    Level: intermediate
220673a71a0fSBarry Smith 
2207*0ab4885dSBarry Smith    Fortran Note:
2208*0ab4885dSBarry Smith    `MatDenseGetArray()` Fortran binding is deprecated (since PETSc 3.19), use `MatDenseGetArrayF90()`
2209*0ab4885dSBarry Smith 
221011a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
221173a71a0fSBarry Smith @*/
2212d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArray(Mat A, PetscScalar **array)
2213d71ae5a4SJacob Faibussowitsch {
221473a71a0fSBarry Smith   PetscFunctionBegin;
2215d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2216d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2217cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array));
221873a71a0fSBarry Smith   PetscFunctionReturn(0);
221973a71a0fSBarry Smith }
222073a71a0fSBarry Smith 
2221dec5eb66SMatthew G Knepley /*@C
222211a5261eSBarry Smith    MatDenseRestoreArray - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArray()`
222373a71a0fSBarry Smith 
2224c3339decSBarry Smith    Logically Collective
22258572280aSBarry Smith 
22268572280aSBarry Smith    Input Parameters:
22276947451fSStefano Zampini +  mat - a dense matrix
2228742765d3SMatthew Knepley -  array - pointer to the data (may be NULL)
22298572280aSBarry Smith 
22308572280aSBarry Smith    Level: intermediate
22318572280aSBarry Smith 
2232*0ab4885dSBarry Smith    Fortran Note:
2233*0ab4885dSBarry Smith    `MatDenseRestoreArray()` Fortran binding is deprecated (since PETSc 3.19), use `MatDenseRestoreArrayF90()`
2234*0ab4885dSBarry Smith 
223511a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
22368572280aSBarry Smith @*/
2237d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArray(Mat A, PetscScalar **array)
2238d71ae5a4SJacob Faibussowitsch {
22398572280aSBarry Smith   PetscFunctionBegin;
2240d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2241d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2242cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array));
22439566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)A));
224447d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
2245637a0070SStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
2246637a0070SStefano Zampini #endif
22478572280aSBarry Smith   PetscFunctionReturn(0);
22488572280aSBarry Smith }
22498572280aSBarry Smith 
22508572280aSBarry Smith /*@C
225111a5261eSBarry Smith   MatDenseGetArrayRead - gives read-only access to the array where the data for a `MATDENSE`  matrix is stored
22528572280aSBarry Smith 
2253*0ab4885dSBarry Smith    Not Collective; No Fortran Support
22548572280aSBarry Smith 
22558572280aSBarry Smith    Input Parameter:
22566947451fSStefano Zampini .  mat - a dense matrix
22578572280aSBarry Smith 
22588572280aSBarry Smith    Output Parameter:
22598572280aSBarry Smith .   array - pointer to the data
22608572280aSBarry Smith 
22618572280aSBarry Smith    Level: intermediate
22628572280aSBarry Smith 
226311a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
22648572280aSBarry Smith @*/
2265d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArrayRead(Mat A, const PetscScalar **array)
2266d71ae5a4SJacob Faibussowitsch {
22678572280aSBarry Smith   PetscFunctionBegin;
2268d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2269d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2270cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, const PetscScalar **), (A, array));
22718572280aSBarry Smith   PetscFunctionReturn(0);
22728572280aSBarry Smith }
22738572280aSBarry Smith 
22748572280aSBarry Smith /*@C
227511a5261eSBarry Smith    MatDenseRestoreArrayRead - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayRead()`
22768572280aSBarry Smith 
2277*0ab4885dSBarry Smith    Not Collective; No Fortran Support
227873a71a0fSBarry Smith 
227973a71a0fSBarry Smith    Input Parameters:
22806947451fSStefano Zampini +  mat - a dense matrix
2281742765d3SMatthew Knepley -  array - pointer to the data (may be NULL)
228273a71a0fSBarry Smith 
228373a71a0fSBarry Smith    Level: intermediate
228473a71a0fSBarry Smith 
228511a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
228673a71a0fSBarry Smith @*/
2287d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArrayRead(Mat A, const PetscScalar **array)
2288d71ae5a4SJacob Faibussowitsch {
228973a71a0fSBarry Smith   PetscFunctionBegin;
2290d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2291d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2292cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, const PetscScalar **), (A, array));
229373a71a0fSBarry Smith   PetscFunctionReturn(0);
229473a71a0fSBarry Smith }
229573a71a0fSBarry Smith 
22966947451fSStefano Zampini /*@C
229711a5261eSBarry Smith    MatDenseGetArrayWrite - gives write-only access to the array where the data for a `MATDENSE` matrix is stored
22986947451fSStefano Zampini 
2299*0ab4885dSBarry Smith    Not Collective; No Fortran Support
23006947451fSStefano Zampini 
23016947451fSStefano Zampini    Input Parameter:
23026947451fSStefano Zampini .  mat - a dense matrix
23036947451fSStefano Zampini 
23046947451fSStefano Zampini    Output Parameter:
23056947451fSStefano Zampini .   array - pointer to the data
23066947451fSStefano Zampini 
23076947451fSStefano Zampini    Level: intermediate
23086947451fSStefano Zampini 
230911a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`
23106947451fSStefano Zampini @*/
2311d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArrayWrite(Mat A, PetscScalar **array)
2312d71ae5a4SJacob Faibussowitsch {
23136947451fSStefano Zampini   PetscFunctionBegin;
2314d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2315d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2316cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array));
23176947451fSStefano Zampini   PetscFunctionReturn(0);
23186947451fSStefano Zampini }
23196947451fSStefano Zampini 
23206947451fSStefano Zampini /*@C
232111a5261eSBarry Smith    MatDenseRestoreArrayWrite - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayWrite()`
23226947451fSStefano Zampini 
2323*0ab4885dSBarry Smith    Not Collective; No Fortran Support
23246947451fSStefano Zampini 
23256947451fSStefano Zampini    Input Parameters:
23266947451fSStefano Zampini +  mat - a dense matrix
2327742765d3SMatthew Knepley -  array - pointer to the data (may be NULL)
23286947451fSStefano Zampini 
23296947451fSStefano Zampini    Level: intermediate
23306947451fSStefano Zampini 
233111a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`
23326947451fSStefano Zampini @*/
2333d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArrayWrite(Mat A, PetscScalar **array)
2334d71ae5a4SJacob Faibussowitsch {
23356947451fSStefano Zampini   PetscFunctionBegin;
2336d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2337d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2338cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array));
23399566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)A));
234047d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
23416947451fSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
23426947451fSStefano Zampini #endif
23436947451fSStefano Zampini   PetscFunctionReturn(0);
23446947451fSStefano Zampini }
23456947451fSStefano Zampini 
2346d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A, IS isrow, IS iscol, MatReuse scall, Mat *B)
2347d71ae5a4SJacob Faibussowitsch {
2348c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense *)A->data;
2349bf5a80bcSToby Isaac   PetscInt        i, j, nrows, ncols, ldb;
23505d0c19d7SBarry Smith   const PetscInt *irow, *icol;
235187828ca2SBarry Smith   PetscScalar    *av, *bv, *v = mat->v;
23520754003eSLois Curfman McInnes   Mat             newmat;
23530754003eSLois Curfman McInnes 
23543a40ed3dSBarry Smith   PetscFunctionBegin;
23559566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(isrow, &irow));
23569566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(iscol, &icol));
23579566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(isrow, &nrows));
23589566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(iscol, &ncols));
23590754003eSLois Curfman McInnes 
2360182d2002SSatish Balay   /* Check submatrixcall */
2361182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
236213f74950SBarry Smith     PetscInt n_cols, n_rows;
23639566063dSJacob Faibussowitsch     PetscCall(MatGetSize(*B, &n_rows, &n_cols));
236421a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
2365f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
23669566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(*B, nrows, ncols, nrows, ncols));
236721a2c019SBarry Smith     }
2368182d2002SSatish Balay     newmat = *B;
2369182d2002SSatish Balay   } else {
23700754003eSLois Curfman McInnes     /* Create and fill new matrix */
23719566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &newmat));
23729566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(newmat, nrows, ncols, nrows, ncols));
23739566063dSJacob Faibussowitsch     PetscCall(MatSetType(newmat, ((PetscObject)A)->type_name));
23749566063dSJacob Faibussowitsch     PetscCall(MatSeqDenseSetPreallocation(newmat, NULL));
2375182d2002SSatish Balay   }
2376182d2002SSatish Balay 
2377182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
23789566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(newmat, &bv));
23799566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(newmat, &ldb));
2380182d2002SSatish Balay   for (i = 0; i < ncols; i++) {
23816de62eeeSBarry Smith     av = v + mat->lda * icol[i];
2382ca15aa20SStefano Zampini     for (j = 0; j < nrows; j++) bv[j] = av[irow[j]];
2383bf5a80bcSToby Isaac     bv += ldb;
23840754003eSLois Curfman McInnes   }
23859566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(newmat, &bv));
2386182d2002SSatish Balay 
2387182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
23889566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(newmat, MAT_FINAL_ASSEMBLY));
23899566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(newmat, MAT_FINAL_ASSEMBLY));
23900754003eSLois Curfman McInnes 
23910754003eSLois Curfman McInnes   /* Free work space */
23929566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(isrow, &irow));
23939566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(iscol, &icol));
2394182d2002SSatish Balay   *B = newmat;
23953a40ed3dSBarry Smith   PetscFunctionReturn(0);
23960754003eSLois Curfman McInnes }
23970754003eSLois Curfman McInnes 
2398d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A, PetscInt n, const IS irow[], const IS icol[], MatReuse scall, Mat *B[])
2399d71ae5a4SJacob Faibussowitsch {
240013f74950SBarry Smith   PetscInt i;
2401905e6a2fSBarry Smith 
24023a40ed3dSBarry Smith   PetscFunctionBegin;
240348a46eb9SPierre Jolivet   if (scall == MAT_INITIAL_MATRIX) PetscCall(PetscCalloc1(n, B));
2404905e6a2fSBarry Smith 
240548a46eb9SPierre Jolivet   for (i = 0; i < n; i++) PetscCall(MatCreateSubMatrix_SeqDense(A, irow[i], icol[i], scall, &(*B)[i]));
24063a40ed3dSBarry Smith   PetscFunctionReturn(0);
2407905e6a2fSBarry Smith }
2408905e6a2fSBarry Smith 
2409d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat, MatAssemblyType mode)
2410d71ae5a4SJacob Faibussowitsch {
2411c0aa2d19SHong Zhang   PetscFunctionBegin;
2412c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2413c0aa2d19SHong Zhang }
2414c0aa2d19SHong Zhang 
2415d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat, MatAssemblyType mode)
2416d71ae5a4SJacob Faibussowitsch {
2417c0aa2d19SHong Zhang   PetscFunctionBegin;
2418c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2419c0aa2d19SHong Zhang }
2420c0aa2d19SHong Zhang 
2421d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCopy_SeqDense(Mat A, Mat B, MatStructure str)
2422d71ae5a4SJacob Faibussowitsch {
24234b0e389bSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data;
2424ca15aa20SStefano Zampini   const PetscScalar *va;
2425ca15aa20SStefano Zampini   PetscScalar       *vb;
2426d0f46423SBarry Smith   PetscInt           lda1 = a->lda, lda2 = b->lda, m = A->rmap->n, n = A->cmap->n, j;
24273a40ed3dSBarry Smith 
24283a40ed3dSBarry Smith   PetscFunctionBegin;
242933f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
243033f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
24319566063dSJacob Faibussowitsch     PetscCall(MatCopy_Basic(A, B, str));
24323a40ed3dSBarry Smith     PetscFunctionReturn(0);
24333a40ed3dSBarry Smith   }
2434aed4548fSBarry Smith   PetscCheck(m == B->rmap->n && n == B->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "size(B) != size(A)");
24359566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &va));
24369566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(B, &vb));
2437a5ce6ee0Svictorle   if (lda1 > m || lda2 > m) {
243848a46eb9SPierre Jolivet     for (j = 0; j < n; j++) PetscCall(PetscArraycpy(vb + j * lda2, va + j * lda1, m));
2439a5ce6ee0Svictorle   } else {
24409566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(vb, va, A->rmap->n * A->cmap->n));
2441a5ce6ee0Svictorle   }
24429566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(B, &vb));
24439566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &va));
24449566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY));
24459566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY));
2446273d9f13SBarry Smith   PetscFunctionReturn(0);
2447273d9f13SBarry Smith }
2448273d9f13SBarry Smith 
2449d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetUp_SeqDense(Mat A)
2450d71ae5a4SJacob Faibussowitsch {
2451273d9f13SBarry Smith   PetscFunctionBegin;
24529566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(A->rmap));
24539566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(A->cmap));
245448a46eb9SPierre Jolivet   if (!A->preallocated) PetscCall(MatSeqDenseSetPreallocation(A, NULL));
24553a40ed3dSBarry Smith   PetscFunctionReturn(0);
24564b0e389bSBarry Smith }
24574b0e389bSBarry Smith 
2458d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatConjugate_SeqDense(Mat A)
2459d71ae5a4SJacob Faibussowitsch {
24604396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
246106c5243aSJose E. Roman   PetscInt      i, j;
24624396437dSToby Isaac   PetscInt      min = PetscMin(A->rmap->n, A->cmap->n);
2463ca15aa20SStefano Zampini   PetscScalar  *aa;
2464ba337c44SJed Brown 
2465ba337c44SJed Brown   PetscFunctionBegin;
24669566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &aa));
246706c5243aSJose E. Roman   for (j = 0; j < A->cmap->n; j++) {
246806c5243aSJose E. Roman     for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscConj(aa[i + j * mat->lda]);
246906c5243aSJose E. Roman   }
24709566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &aa));
24719371c9d4SSatish Balay   if (mat->tau)
24729371c9d4SSatish Balay     for (i = 0; i < min; i++) mat->tau[i] = PetscConj(mat->tau[i]);
2473ba337c44SJed Brown   PetscFunctionReturn(0);
2474ba337c44SJed Brown }
2475ba337c44SJed Brown 
2476d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRealPart_SeqDense(Mat A)
2477d71ae5a4SJacob Faibussowitsch {
247806c5243aSJose E. Roman   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
247906c5243aSJose E. Roman   PetscInt      i, j;
2480ca15aa20SStefano Zampini   PetscScalar  *aa;
2481ba337c44SJed Brown 
2482ba337c44SJed Brown   PetscFunctionBegin;
24839566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &aa));
248406c5243aSJose E. Roman   for (j = 0; j < A->cmap->n; j++) {
248506c5243aSJose E. Roman     for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscRealPart(aa[i + j * mat->lda]);
248606c5243aSJose E. Roman   }
24879566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &aa));
2488ba337c44SJed Brown   PetscFunctionReturn(0);
2489ba337c44SJed Brown }
2490ba337c44SJed Brown 
2491d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatImaginaryPart_SeqDense(Mat A)
2492d71ae5a4SJacob Faibussowitsch {
249306c5243aSJose E. Roman   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
249406c5243aSJose E. Roman   PetscInt      i, j;
2495ca15aa20SStefano Zampini   PetscScalar  *aa;
2496ba337c44SJed Brown 
2497ba337c44SJed Brown   PetscFunctionBegin;
24989566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &aa));
249906c5243aSJose E. Roman   for (j = 0; j < A->cmap->n; j++) {
250006c5243aSJose E. Roman     for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscImaginaryPart(aa[i + j * mat->lda]);
250106c5243aSJose E. Roman   }
25029566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &aa));
2503ba337c44SJed Brown   PetscFunctionReturn(0);
2504ba337c44SJed Brown }
2505284134d9SBarry Smith 
2506a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/
2507d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C)
2508d71ae5a4SJacob Faibussowitsch {
2509d0f46423SBarry Smith   PetscInt  m = A->rmap->n, n = B->cmap->n;
251047d993e7Ssuyashtn   PetscBool cisdense = PETSC_FALSE;
2511a9fe9ddaSSatish Balay 
2512ee16a9a1SHong Zhang   PetscFunctionBegin;
25139566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C, m, n, m, n));
251447d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA)
25159566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, ""));
251647d993e7Ssuyashtn #endif
251747d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP)
251847d993e7Ssuyashtn   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, ""));
251947d993e7Ssuyashtn #endif
25207a3c3d58SStefano Zampini   if (!cisdense) {
25217a3c3d58SStefano Zampini     PetscBool flg;
25227a3c3d58SStefano Zampini 
25239566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg));
25249566063dSJacob Faibussowitsch     PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE));
25257a3c3d58SStefano Zampini   }
25269566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
2527ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2528ee16a9a1SHong Zhang }
2529a9fe9ddaSSatish Balay 
2530d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C)
2531d71ae5a4SJacob Faibussowitsch {
25326718818eSStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data, *c = (Mat_SeqDense *)C->data;
25330805154bSBarry Smith   PetscBLASInt       m, n, k;
2534ca15aa20SStefano Zampini   const PetscScalar *av, *bv;
2535ca15aa20SStefano Zampini   PetscScalar       *cv;
2536a9fe9ddaSSatish Balay   PetscScalar        _DOne = 1.0, _DZero = 0.0;
2537a9fe9ddaSSatish Balay 
2538a9fe9ddaSSatish Balay   PetscFunctionBegin;
25399566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n, &m));
25409566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n, &n));
25419566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &k));
254249d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
25439566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &av));
25449566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B, &bv));
25459566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C, &cv));
2546792fecdfSBarry Smith   PetscCallBLAS("BLASgemm", BLASgemm_("N", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda));
25479566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1)));
25489566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &av));
25499566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B, &bv));
25509566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C, &cv));
2551a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2552a9fe9ddaSSatish Balay }
2553a9fe9ddaSSatish Balay 
2554d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C)
2555d71ae5a4SJacob Faibussowitsch {
255669f65d41SStefano Zampini   PetscInt  m = A->rmap->n, n = B->rmap->n;
255747d993e7Ssuyashtn   PetscBool cisdense = PETSC_FALSE;
255869f65d41SStefano Zampini 
255969f65d41SStefano Zampini   PetscFunctionBegin;
25609566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C, m, n, m, n));
256147d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA)
25629566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, ""));
256347d993e7Ssuyashtn #endif
256447d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP)
256547d993e7Ssuyashtn   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, ""));
256647d993e7Ssuyashtn #endif
25677a3c3d58SStefano Zampini   if (!cisdense) {
25687a3c3d58SStefano Zampini     PetscBool flg;
25697a3c3d58SStefano Zampini 
25709566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg));
25719566063dSJacob Faibussowitsch     PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE));
25727a3c3d58SStefano Zampini   }
25739566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
257469f65d41SStefano Zampini   PetscFunctionReturn(0);
257569f65d41SStefano Zampini }
257669f65d41SStefano Zampini 
2577d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C)
2578d71ae5a4SJacob Faibussowitsch {
257969f65d41SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
258069f65d41SStefano Zampini   Mat_SeqDense      *b = (Mat_SeqDense *)B->data;
258169f65d41SStefano Zampini   Mat_SeqDense      *c = (Mat_SeqDense *)C->data;
25826718818eSStefano Zampini   const PetscScalar *av, *bv;
25836718818eSStefano Zampini   PetscScalar       *cv;
258469f65d41SStefano Zampini   PetscBLASInt       m, n, k;
258569f65d41SStefano Zampini   PetscScalar        _DOne = 1.0, _DZero = 0.0;
258669f65d41SStefano Zampini 
258769f65d41SStefano Zampini   PetscFunctionBegin;
25889566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n, &m));
25899566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n, &n));
25909566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &k));
259149d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
25929566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &av));
25939566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B, &bv));
25949566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C, &cv));
2595792fecdfSBarry Smith   PetscCallBLAS("BLASgemm", BLASgemm_("N", "T", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda));
25969566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &av));
25979566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B, &bv));
25989566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C, &cv));
25999566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1)));
260069f65d41SStefano Zampini   PetscFunctionReturn(0);
260169f65d41SStefano Zampini }
260269f65d41SStefano Zampini 
2603d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C)
2604d71ae5a4SJacob Faibussowitsch {
2605d0f46423SBarry Smith   PetscInt  m = A->cmap->n, n = B->cmap->n;
260647d993e7Ssuyashtn   PetscBool cisdense = PETSC_FALSE;
2607a9fe9ddaSSatish Balay 
2608ee16a9a1SHong Zhang   PetscFunctionBegin;
26099566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C, m, n, m, n));
261047d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA)
26119566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, ""));
261247d993e7Ssuyashtn #endif
261347d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP)
261447d993e7Ssuyashtn   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, ""));
261547d993e7Ssuyashtn #endif
26167a3c3d58SStefano Zampini   if (!cisdense) {
26177a3c3d58SStefano Zampini     PetscBool flg;
26187a3c3d58SStefano Zampini 
26199566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg));
26209566063dSJacob Faibussowitsch     PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE));
26217a3c3d58SStefano Zampini   }
26229566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
2623ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2624ee16a9a1SHong Zhang }
2625a9fe9ddaSSatish Balay 
2626d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C)
2627d71ae5a4SJacob Faibussowitsch {
2628a9fe9ddaSSatish Balay   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
2629a9fe9ddaSSatish Balay   Mat_SeqDense      *b = (Mat_SeqDense *)B->data;
2630a9fe9ddaSSatish Balay   Mat_SeqDense      *c = (Mat_SeqDense *)C->data;
26316718818eSStefano Zampini   const PetscScalar *av, *bv;
26326718818eSStefano Zampini   PetscScalar       *cv;
26330805154bSBarry Smith   PetscBLASInt       m, n, k;
2634a9fe9ddaSSatish Balay   PetscScalar        _DOne = 1.0, _DZero = 0.0;
2635a9fe9ddaSSatish Balay 
2636a9fe9ddaSSatish Balay   PetscFunctionBegin;
26379566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n, &m));
26389566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n, &n));
26399566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &k));
264049d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
26419566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &av));
26429566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B, &bv));
26439566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C, &cv));
2644792fecdfSBarry Smith   PetscCallBLAS("BLASgemm", BLASgemm_("T", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda));
26459566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &av));
26469566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B, &bv));
26479566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C, &cv));
26489566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1)));
2649a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2650a9fe9ddaSSatish Balay }
2651985db425SBarry Smith 
26524222ddf1SHong Zhang /* ----------------------------------------------- */
2653d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C)
2654d71ae5a4SJacob Faibussowitsch {
26554222ddf1SHong Zhang   PetscFunctionBegin;
26564222ddf1SHong Zhang   C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense;
26574222ddf1SHong Zhang   C->ops->productsymbolic = MatProductSymbolic_AB;
26584222ddf1SHong Zhang   PetscFunctionReturn(0);
26594222ddf1SHong Zhang }
26604222ddf1SHong Zhang 
2661d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C)
2662d71ae5a4SJacob Faibussowitsch {
26634222ddf1SHong Zhang   PetscFunctionBegin;
26644222ddf1SHong Zhang   C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense;
26654222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_AtB;
26664222ddf1SHong Zhang   PetscFunctionReturn(0);
26674222ddf1SHong Zhang }
26684222ddf1SHong Zhang 
2669d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C)
2670d71ae5a4SJacob Faibussowitsch {
26714222ddf1SHong Zhang   PetscFunctionBegin;
26724222ddf1SHong Zhang   C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense;
26734222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_ABt;
26744222ddf1SHong Zhang   PetscFunctionReturn(0);
26754222ddf1SHong Zhang }
26764222ddf1SHong Zhang 
2677d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C)
2678d71ae5a4SJacob Faibussowitsch {
26794222ddf1SHong Zhang   Mat_Product *product = C->product;
26804222ddf1SHong Zhang 
26814222ddf1SHong Zhang   PetscFunctionBegin;
26824222ddf1SHong Zhang   switch (product->type) {
2683d71ae5a4SJacob Faibussowitsch   case MATPRODUCT_AB:
2684d71ae5a4SJacob Faibussowitsch     PetscCall(MatProductSetFromOptions_SeqDense_AB(C));
2685d71ae5a4SJacob Faibussowitsch     break;
2686d71ae5a4SJacob Faibussowitsch   case MATPRODUCT_AtB:
2687d71ae5a4SJacob Faibussowitsch     PetscCall(MatProductSetFromOptions_SeqDense_AtB(C));
2688d71ae5a4SJacob Faibussowitsch     break;
2689d71ae5a4SJacob Faibussowitsch   case MATPRODUCT_ABt:
2690d71ae5a4SJacob Faibussowitsch     PetscCall(MatProductSetFromOptions_SeqDense_ABt(C));
2691d71ae5a4SJacob Faibussowitsch     break;
2692d71ae5a4SJacob Faibussowitsch   default:
2693d71ae5a4SJacob Faibussowitsch     break;
26944222ddf1SHong Zhang   }
26954222ddf1SHong Zhang   PetscFunctionReturn(0);
26964222ddf1SHong Zhang }
26974222ddf1SHong Zhang /* ----------------------------------------------- */
26984222ddf1SHong Zhang 
2699d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMax_SeqDense(Mat A, Vec v, PetscInt idx[])
2700d71ae5a4SJacob Faibussowitsch {
2701985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
2702d0f46423SBarry Smith   PetscInt           i, j, m = A->rmap->n, n = A->cmap->n, p;
2703985db425SBarry Smith   PetscScalar       *x;
2704ca15aa20SStefano Zampini   const PetscScalar *aa;
2705985db425SBarry Smith 
2706985db425SBarry Smith   PetscFunctionBegin;
270728b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
27089566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
27099566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v, &p));
27109566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
271108401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector");
2712985db425SBarry Smith   for (i = 0; i < m; i++) {
27139371c9d4SSatish Balay     x[i] = aa[i];
27149371c9d4SSatish Balay     if (idx) idx[i] = 0;
2715985db425SBarry Smith     for (j = 1; j < n; j++) {
27169371c9d4SSatish Balay       if (PetscRealPart(x[i]) < PetscRealPart(aa[i + a->lda * j])) {
27179371c9d4SSatish Balay         x[i] = aa[i + a->lda * j];
27189371c9d4SSatish Balay         if (idx) idx[i] = j;
27199371c9d4SSatish Balay       }
2720985db425SBarry Smith     }
2721985db425SBarry Smith   }
27229566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
27239566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
2724985db425SBarry Smith   PetscFunctionReturn(0);
2725985db425SBarry Smith }
2726985db425SBarry Smith 
2727d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A, Vec v, PetscInt idx[])
2728d71ae5a4SJacob Faibussowitsch {
2729985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
2730d0f46423SBarry Smith   PetscInt           i, j, m = A->rmap->n, n = A->cmap->n, p;
2731985db425SBarry Smith   PetscScalar       *x;
2732985db425SBarry Smith   PetscReal          atmp;
2733ca15aa20SStefano Zampini   const PetscScalar *aa;
2734985db425SBarry Smith 
2735985db425SBarry Smith   PetscFunctionBegin;
273628b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
27379566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
27389566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v, &p));
27399566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
274008401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector");
2741985db425SBarry Smith   for (i = 0; i < m; i++) {
27429189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
2743985db425SBarry Smith     for (j = 1; j < n; j++) {
2744ca15aa20SStefano Zampini       atmp = PetscAbsScalar(aa[i + a->lda * j]);
27459371c9d4SSatish Balay       if (PetscAbsScalar(x[i]) < atmp) {
27469371c9d4SSatish Balay         x[i] = atmp;
27479371c9d4SSatish Balay         if (idx) idx[i] = j;
27489371c9d4SSatish Balay       }
2749985db425SBarry Smith     }
2750985db425SBarry Smith   }
27519566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
27529566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
2753985db425SBarry Smith   PetscFunctionReturn(0);
2754985db425SBarry Smith }
2755985db425SBarry Smith 
2756d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMin_SeqDense(Mat A, Vec v, PetscInt idx[])
2757d71ae5a4SJacob Faibussowitsch {
2758985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
2759d0f46423SBarry Smith   PetscInt           i, j, m = A->rmap->n, n = A->cmap->n, p;
2760985db425SBarry Smith   PetscScalar       *x;
2761ca15aa20SStefano Zampini   const PetscScalar *aa;
2762985db425SBarry Smith 
2763985db425SBarry Smith   PetscFunctionBegin;
276428b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
27659566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
27669566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
27679566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v, &p));
276808401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector");
2769985db425SBarry Smith   for (i = 0; i < m; i++) {
27709371c9d4SSatish Balay     x[i] = aa[i];
27719371c9d4SSatish Balay     if (idx) idx[i] = 0;
2772985db425SBarry Smith     for (j = 1; j < n; j++) {
27739371c9d4SSatish Balay       if (PetscRealPart(x[i]) > PetscRealPart(aa[i + a->lda * j])) {
27749371c9d4SSatish Balay         x[i] = aa[i + a->lda * j];
27759371c9d4SSatish Balay         if (idx) idx[i] = j;
27769371c9d4SSatish Balay       }
2777985db425SBarry Smith     }
2778985db425SBarry Smith   }
27799566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
27809566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
2781985db425SBarry Smith   PetscFunctionReturn(0);
2782985db425SBarry Smith }
2783985db425SBarry Smith 
2784d71ae5a4SJacob Faibussowitsch PetscErrorCode MatGetColumnVector_SeqDense(Mat A, Vec v, PetscInt col)
2785d71ae5a4SJacob Faibussowitsch {
27868d0534beSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
27878d0534beSBarry Smith   PetscScalar       *x;
2788ca15aa20SStefano Zampini   const PetscScalar *aa;
27898d0534beSBarry Smith 
27908d0534beSBarry Smith   PetscFunctionBegin;
279128b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
27929566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
27939566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
27949566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(x, aa + col * a->lda, A->rmap->n));
27959566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
27969566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
27978d0534beSBarry Smith   PetscFunctionReturn(0);
27988d0534beSBarry Smith }
27998d0534beSBarry Smith 
2800d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatGetColumnReductions_SeqDense(Mat A, PetscInt type, PetscReal *reductions)
2801d71ae5a4SJacob Faibussowitsch {
28020716a85fSBarry Smith   PetscInt           i, j, m, n;
28031683a169SBarry Smith   const PetscScalar *a;
28040716a85fSBarry Smith 
28050716a85fSBarry Smith   PetscFunctionBegin;
28069566063dSJacob Faibussowitsch   PetscCall(MatGetSize(A, &m, &n));
28079566063dSJacob Faibussowitsch   PetscCall(PetscArrayzero(reductions, n));
28089566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &a));
2809857cbf51SRichard Tran Mills   if (type == NORM_2) {
28100716a85fSBarry Smith     for (i = 0; i < n; i++) {
2811ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j] * a[j]);
28120716a85fSBarry Smith       a += m;
28130716a85fSBarry Smith     }
2814857cbf51SRichard Tran Mills   } else if (type == NORM_1) {
28150716a85fSBarry Smith     for (i = 0; i < n; i++) {
2816ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j]);
28170716a85fSBarry Smith       a += m;
28180716a85fSBarry Smith     }
2819857cbf51SRichard Tran Mills   } else if (type == NORM_INFINITY) {
28200716a85fSBarry Smith     for (i = 0; i < n; i++) {
2821ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] = PetscMax(PetscAbsScalar(a[j]), reductions[i]);
28220716a85fSBarry Smith       a += m;
28230716a85fSBarry Smith     }
2824857cbf51SRichard Tran Mills   } else if (type == REDUCTION_SUM_REALPART || type == REDUCTION_MEAN_REALPART) {
2825a873a8cdSSam Reynolds     for (i = 0; i < n; i++) {
2826ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] += PetscRealPart(a[j]);
2827a873a8cdSSam Reynolds       a += m;
2828a873a8cdSSam Reynolds     }
2829857cbf51SRichard Tran Mills   } else if (type == REDUCTION_SUM_IMAGINARYPART || type == REDUCTION_MEAN_IMAGINARYPART) {
2830857cbf51SRichard Tran Mills     for (i = 0; i < n; i++) {
2831ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] += PetscImaginaryPart(a[j]);
2832857cbf51SRichard Tran Mills       a += m;
2833857cbf51SRichard Tran Mills     }
2834857cbf51SRichard Tran Mills   } else SETERRQ(PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Unknown reduction type");
28359566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &a));
2836857cbf51SRichard Tran Mills   if (type == NORM_2) {
2837a873a8cdSSam Reynolds     for (i = 0; i < n; i++) reductions[i] = PetscSqrtReal(reductions[i]);
2838857cbf51SRichard Tran Mills   } else if (type == REDUCTION_MEAN_REALPART || type == REDUCTION_MEAN_IMAGINARYPART) {
2839a873a8cdSSam Reynolds     for (i = 0; i < n; i++) reductions[i] /= m;
28400716a85fSBarry Smith   }
28410716a85fSBarry Smith   PetscFunctionReturn(0);
28420716a85fSBarry Smith }
28430716a85fSBarry Smith 
2844d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetRandom_SeqDense(Mat x, PetscRandom rctx)
2845d71ae5a4SJacob Faibussowitsch {
284673a71a0fSBarry Smith   PetscScalar *a;
2847637a0070SStefano Zampini   PetscInt     lda, m, n, i, j;
284873a71a0fSBarry Smith 
284973a71a0fSBarry Smith   PetscFunctionBegin;
28509566063dSJacob Faibussowitsch   PetscCall(MatGetSize(x, &m, &n));
28519566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(x, &lda));
28523faff063SStefano Zampini   PetscCall(MatDenseGetArrayWrite(x, &a));
2853637a0070SStefano Zampini   for (j = 0; j < n; j++) {
285448a46eb9SPierre Jolivet     for (i = 0; i < m; i++) PetscCall(PetscRandomGetValue(rctx, a + j * lda + i));
285573a71a0fSBarry Smith   }
28563faff063SStefano Zampini   PetscCall(MatDenseRestoreArrayWrite(x, &a));
285773a71a0fSBarry Smith   PetscFunctionReturn(0);
285873a71a0fSBarry Smith }
285973a71a0fSBarry Smith 
2860d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A, PetscBool *missing, PetscInt *d)
2861d71ae5a4SJacob Faibussowitsch {
28623b49f96aSBarry Smith   PetscFunctionBegin;
28633b49f96aSBarry Smith   *missing = PETSC_FALSE;
28643b49f96aSBarry Smith   PetscFunctionReturn(0);
28653b49f96aSBarry Smith }
286673a71a0fSBarry Smith 
2867ca15aa20SStefano Zampini /* vals is not const */
2868d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A, PetscInt col, PetscScalar **vals)
2869d71ae5a4SJacob Faibussowitsch {
287086aefd0dSHong Zhang   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
2871ca15aa20SStefano Zampini   PetscScalar  *v;
287286aefd0dSHong Zhang 
287386aefd0dSHong Zhang   PetscFunctionBegin;
287428b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
28759566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
2876ca15aa20SStefano Zampini   *vals = v + col * a->lda;
28779566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
287886aefd0dSHong Zhang   PetscFunctionReturn(0);
287986aefd0dSHong Zhang }
288086aefd0dSHong Zhang 
2881d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A, PetscScalar **vals)
2882d71ae5a4SJacob Faibussowitsch {
288386aefd0dSHong Zhang   PetscFunctionBegin;
2884742765d3SMatthew Knepley   if (vals) *vals = NULL; /* user cannot accidentally use the array later */
288586aefd0dSHong Zhang   PetscFunctionReturn(0);
288686aefd0dSHong Zhang }
2887abc3b08eSStefano Zampini 
2888289bc588SBarry Smith /* -------------------------------------------------------------------*/
2889a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqDense,
2890905e6a2fSBarry Smith                                        MatGetRow_SeqDense,
2891905e6a2fSBarry Smith                                        MatRestoreRow_SeqDense,
2892905e6a2fSBarry Smith                                        MatMult_SeqDense,
289397304618SKris Buschelman                                        /*  4*/ MatMultAdd_SeqDense,
28947c922b88SBarry Smith                                        MatMultTranspose_SeqDense,
28957c922b88SBarry Smith                                        MatMultTransposeAdd_SeqDense,
2896f4259b30SLisandro Dalcin                                        NULL,
2897f4259b30SLisandro Dalcin                                        NULL,
2898f4259b30SLisandro Dalcin                                        NULL,
2899f4259b30SLisandro Dalcin                                        /* 10*/ NULL,
2900905e6a2fSBarry Smith                                        MatLUFactor_SeqDense,
2901905e6a2fSBarry Smith                                        MatCholeskyFactor_SeqDense,
290241f059aeSBarry Smith                                        MatSOR_SeqDense,
2903ec8511deSBarry Smith                                        MatTranspose_SeqDense,
290497304618SKris Buschelman                                        /* 15*/ MatGetInfo_SeqDense,
2905905e6a2fSBarry Smith                                        MatEqual_SeqDense,
2906905e6a2fSBarry Smith                                        MatGetDiagonal_SeqDense,
2907905e6a2fSBarry Smith                                        MatDiagonalScale_SeqDense,
2908905e6a2fSBarry Smith                                        MatNorm_SeqDense,
2909c0aa2d19SHong Zhang                                        /* 20*/ MatAssemblyBegin_SeqDense,
2910c0aa2d19SHong Zhang                                        MatAssemblyEnd_SeqDense,
2911905e6a2fSBarry Smith                                        MatSetOption_SeqDense,
2912905e6a2fSBarry Smith                                        MatZeroEntries_SeqDense,
2913d519adbfSMatthew Knepley                                        /* 24*/ MatZeroRows_SeqDense,
2914f4259b30SLisandro Dalcin                                        NULL,
2915f4259b30SLisandro Dalcin                                        NULL,
2916f4259b30SLisandro Dalcin                                        NULL,
2917f4259b30SLisandro Dalcin                                        NULL,
29184994cf47SJed Brown                                        /* 29*/ MatSetUp_SeqDense,
2919f4259b30SLisandro Dalcin                                        NULL,
2920f4259b30SLisandro Dalcin                                        NULL,
2921f4259b30SLisandro Dalcin                                        NULL,
2922f4259b30SLisandro Dalcin                                        NULL,
2923d519adbfSMatthew Knepley                                        /* 34*/ MatDuplicate_SeqDense,
2924f4259b30SLisandro Dalcin                                        NULL,
2925f4259b30SLisandro Dalcin                                        NULL,
2926f4259b30SLisandro Dalcin                                        NULL,
2927f4259b30SLisandro Dalcin                                        NULL,
2928d519adbfSMatthew Knepley                                        /* 39*/ MatAXPY_SeqDense,
29297dae84e0SHong Zhang                                        MatCreateSubMatrices_SeqDense,
2930f4259b30SLisandro Dalcin                                        NULL,
29314b0e389bSBarry Smith                                        MatGetValues_SeqDense,
2932a5ae1ecdSBarry Smith                                        MatCopy_SeqDense,
2933d519adbfSMatthew Knepley                                        /* 44*/ MatGetRowMax_SeqDense,
2934a5ae1ecdSBarry Smith                                        MatScale_SeqDense,
29352f605a99SJose E. Roman                                        MatShift_SeqDense,
2936f4259b30SLisandro Dalcin                                        NULL,
29373f49a652SStefano Zampini                                        MatZeroRowsColumns_SeqDense,
293873a71a0fSBarry Smith                                        /* 49*/ MatSetRandom_SeqDense,
2939f4259b30SLisandro Dalcin                                        NULL,
2940f4259b30SLisandro Dalcin                                        NULL,
2941f4259b30SLisandro Dalcin                                        NULL,
2942f4259b30SLisandro Dalcin                                        NULL,
2943f4259b30SLisandro Dalcin                                        /* 54*/ NULL,
2944f4259b30SLisandro Dalcin                                        NULL,
2945f4259b30SLisandro Dalcin                                        NULL,
2946f4259b30SLisandro Dalcin                                        NULL,
2947f4259b30SLisandro Dalcin                                        NULL,
2948023c16fcSToby Isaac                                        /* 59*/ MatCreateSubMatrix_SeqDense,
2949e03a110bSBarry Smith                                        MatDestroy_SeqDense,
2950e03a110bSBarry Smith                                        MatView_SeqDense,
2951f4259b30SLisandro Dalcin                                        NULL,
2952f4259b30SLisandro Dalcin                                        NULL,
2953f4259b30SLisandro Dalcin                                        /* 64*/ NULL,
2954f4259b30SLisandro Dalcin                                        NULL,
2955f4259b30SLisandro Dalcin                                        NULL,
2956f4259b30SLisandro Dalcin                                        NULL,
2957f4259b30SLisandro Dalcin                                        NULL,
2958d519adbfSMatthew Knepley                                        /* 69*/ MatGetRowMaxAbs_SeqDense,
2959f4259b30SLisandro Dalcin                                        NULL,
2960f4259b30SLisandro Dalcin                                        NULL,
2961f4259b30SLisandro Dalcin                                        NULL,
2962f4259b30SLisandro Dalcin                                        NULL,
2963f4259b30SLisandro Dalcin                                        /* 74*/ NULL,
2964f4259b30SLisandro Dalcin                                        NULL,
2965f4259b30SLisandro Dalcin                                        NULL,
2966f4259b30SLisandro Dalcin                                        NULL,
2967f4259b30SLisandro Dalcin                                        NULL,
2968f4259b30SLisandro Dalcin                                        /* 79*/ NULL,
2969f4259b30SLisandro Dalcin                                        NULL,
2970f4259b30SLisandro Dalcin                                        NULL,
2971f4259b30SLisandro Dalcin                                        NULL,
29725bba2384SShri Abhyankar                                        /* 83*/ MatLoad_SeqDense,
2973637a0070SStefano Zampini                                        MatIsSymmetric_SeqDense,
29741cbb95d3SBarry Smith                                        MatIsHermitian_SeqDense,
2975f4259b30SLisandro Dalcin                                        NULL,
2976f4259b30SLisandro Dalcin                                        NULL,
2977f4259b30SLisandro Dalcin                                        NULL,
2978f4259b30SLisandro Dalcin                                        /* 89*/ NULL,
2979f4259b30SLisandro Dalcin                                        NULL,
2980a9fe9ddaSSatish Balay                                        MatMatMultNumeric_SeqDense_SeqDense,
2981f4259b30SLisandro Dalcin                                        NULL,
2982f4259b30SLisandro Dalcin                                        NULL,
2983f4259b30SLisandro Dalcin                                        /* 94*/ NULL,
2984f4259b30SLisandro Dalcin                                        NULL,
2985f4259b30SLisandro Dalcin                                        NULL,
298669f65d41SStefano Zampini                                        MatMatTransposeMultNumeric_SeqDense_SeqDense,
2987f4259b30SLisandro Dalcin                                        NULL,
29884222ddf1SHong Zhang                                        /* 99*/ MatProductSetFromOptions_SeqDense,
2989f4259b30SLisandro Dalcin                                        NULL,
2990f4259b30SLisandro Dalcin                                        NULL,
2991ba337c44SJed Brown                                        MatConjugate_SeqDense,
2992f4259b30SLisandro Dalcin                                        NULL,
2993f4259b30SLisandro Dalcin                                        /*104*/ NULL,
2994ba337c44SJed Brown                                        MatRealPart_SeqDense,
2995ba337c44SJed Brown                                        MatImaginaryPart_SeqDense,
2996f4259b30SLisandro Dalcin                                        NULL,
2997f4259b30SLisandro Dalcin                                        NULL,
2998f4259b30SLisandro Dalcin                                        /*109*/ NULL,
2999f4259b30SLisandro Dalcin                                        NULL,
30008d0534beSBarry Smith                                        MatGetRowMin_SeqDense,
3001aabbc4fbSShri Abhyankar                                        MatGetColumnVector_SeqDense,
30023b49f96aSBarry Smith                                        MatMissingDiagonal_SeqDense,
3003f4259b30SLisandro Dalcin                                        /*114*/ NULL,
3004f4259b30SLisandro Dalcin                                        NULL,
3005f4259b30SLisandro Dalcin                                        NULL,
3006f4259b30SLisandro Dalcin                                        NULL,
3007f4259b30SLisandro Dalcin                                        NULL,
3008f4259b30SLisandro Dalcin                                        /*119*/ NULL,
3009f4259b30SLisandro Dalcin                                        NULL,
3010f4259b30SLisandro Dalcin                                        NULL,
3011f4259b30SLisandro Dalcin                                        NULL,
3012f4259b30SLisandro Dalcin                                        NULL,
3013f4259b30SLisandro Dalcin                                        /*124*/ NULL,
3014a873a8cdSSam Reynolds                                        MatGetColumnReductions_SeqDense,
3015f4259b30SLisandro Dalcin                                        NULL,
3016f4259b30SLisandro Dalcin                                        NULL,
3017f4259b30SLisandro Dalcin                                        NULL,
3018f4259b30SLisandro Dalcin                                        /*129*/ NULL,
3019f4259b30SLisandro Dalcin                                        NULL,
3020f4259b30SLisandro Dalcin                                        NULL,
302175648e8dSHong Zhang                                        MatTransposeMatMultNumeric_SeqDense_SeqDense,
3022f4259b30SLisandro Dalcin                                        NULL,
3023f4259b30SLisandro Dalcin                                        /*134*/ NULL,
3024f4259b30SLisandro Dalcin                                        NULL,
3025f4259b30SLisandro Dalcin                                        NULL,
3026f4259b30SLisandro Dalcin                                        NULL,
3027f4259b30SLisandro Dalcin                                        NULL,
3028f4259b30SLisandro Dalcin                                        /*139*/ NULL,
3029f4259b30SLisandro Dalcin                                        NULL,
3030f4259b30SLisandro Dalcin                                        NULL,
3031f4259b30SLisandro Dalcin                                        NULL,
3032f4259b30SLisandro Dalcin                                        NULL,
30334222ddf1SHong Zhang                                        MatCreateMPIMatConcatenateSeqMat_SeqDense,
3034f4259b30SLisandro Dalcin                                        /*145*/ NULL,
3035f4259b30SLisandro Dalcin                                        NULL,
303699a7f59eSMark Adams                                        NULL,
303799a7f59eSMark Adams                                        NULL,
30387fb60732SBarry Smith                                        NULL,
3039dec0b466SHong Zhang                                        /*150*/ NULL,
3040dec0b466SHong Zhang                                        NULL};
304190ace30eSBarry Smith 
30424b828684SBarry Smith /*@C
304311a5261eSBarry Smith    MatCreateSeqDense - Creates a `MATSEQDENSE` that
3044d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
3045d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
3046289bc588SBarry Smith 
3047d083f849SBarry Smith    Collective
3048db81eaa0SLois Curfman McInnes 
304920563c6bSBarry Smith    Input Parameters:
305011a5261eSBarry Smith +  comm - MPI communicator, set to `PETSC_COMM_SELF`
30510c775827SLois Curfman McInnes .  m - number of rows
305218f449edSLois Curfman McInnes .  n - number of columns
30530298fd71SBarry Smith -  data - optional location of matrix data in column major order.  Set data=NULL for PETSc
3054dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
305520563c6bSBarry Smith 
305620563c6bSBarry Smith    Output Parameter:
305744cd7ae7SLois Curfman McInnes .  A - the matrix
305820563c6bSBarry Smith 
305911a5261eSBarry Smith    Note:
306018f449edSLois Curfman McInnes    The data input variable is intended primarily for Fortran programmers
306118f449edSLois Curfman McInnes    who wish to allocate their own matrix memory space.  Most users should
30620298fd71SBarry Smith    set data=NULL.
306318f449edSLois Curfman McInnes 
3064027ccd11SLois Curfman McInnes    Level: intermediate
3065027ccd11SLois Curfman McInnes 
306611a5261eSBarry Smith .seealso: `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()`
306720563c6bSBarry Smith @*/
3068d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateSeqDense(MPI_Comm comm, PetscInt m, PetscInt n, PetscScalar *data, Mat *A)
3069d71ae5a4SJacob Faibussowitsch {
30703a40ed3dSBarry Smith   PetscFunctionBegin;
30719566063dSJacob Faibussowitsch   PetscCall(MatCreate(comm, A));
30729566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*A, m, n, m, n));
30739566063dSJacob Faibussowitsch   PetscCall(MatSetType(*A, MATSEQDENSE));
30749566063dSJacob Faibussowitsch   PetscCall(MatSeqDenseSetPreallocation(*A, data));
3075273d9f13SBarry Smith   PetscFunctionReturn(0);
3076273d9f13SBarry Smith }
3077273d9f13SBarry Smith 
3078273d9f13SBarry Smith /*@C
307911a5261eSBarry Smith    MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements of a `MATSEQDENSE` matrix
3080273d9f13SBarry Smith 
3081d083f849SBarry Smith    Collective
3082273d9f13SBarry Smith 
3083273d9f13SBarry Smith    Input Parameters:
30841c4f3114SJed Brown +  B - the matrix
30850298fd71SBarry Smith -  data - the array (or NULL)
3086273d9f13SBarry Smith 
308711a5261eSBarry Smith    Note:
3088273d9f13SBarry Smith    The data input variable is intended primarily for Fortran programmers
3089273d9f13SBarry Smith    who wish to allocate their own matrix memory space.  Most users should
3090284134d9SBarry Smith    need not call this routine.
3091273d9f13SBarry Smith 
3092273d9f13SBarry Smith    Level: intermediate
3093273d9f13SBarry Smith 
309411a5261eSBarry Smith .seealso: `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()`, `MatDenseSetLDA()`
3095273d9f13SBarry Smith @*/
3096d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation(Mat B, PetscScalar data[])
3097d71ae5a4SJacob Faibussowitsch {
3098a23d5eceSKris Buschelman   PetscFunctionBegin;
3099d5ea218eSStefano Zampini   PetscValidHeaderSpecific(B, MAT_CLASSID, 1);
3100cac4c232SBarry Smith   PetscTryMethod(B, "MatSeqDenseSetPreallocation_C", (Mat, PetscScalar[]), (B, data));
3101a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3102a23d5eceSKris Buschelman }
3103a23d5eceSKris Buschelman 
3104d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation_SeqDense(Mat B, PetscScalar *data)
3105d71ae5a4SJacob Faibussowitsch {
3106ad16ce7aSStefano Zampini   Mat_SeqDense *b = (Mat_SeqDense *)B->data;
3107273d9f13SBarry Smith 
3108273d9f13SBarry Smith   PetscFunctionBegin;
310928b400f6SJacob Faibussowitsch   PetscCheck(!b->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
3110273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
3111a868139aSShri Abhyankar 
31129566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(B->rmap));
31139566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(B->cmap));
311434ef9618SShri Abhyankar 
3115ad16ce7aSStefano Zampini   if (b->lda <= 0) b->lda = B->rmap->n;
311686d161a7SShri Abhyankar 
31179e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
31189566063dSJacob Faibussowitsch     if (!b->user_alloc) PetscCall(PetscFree(b->v));
31199566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1((size_t)b->lda * B->cmap->n, &b->v));
31202205254eSKarl Rupp 
31219e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
3122273d9f13SBarry Smith   } else { /* user-allocated storage */
31239566063dSJacob Faibussowitsch     if (!b->user_alloc) PetscCall(PetscFree(b->v));
3124273d9f13SBarry Smith     b->v          = data;
3125273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
3126273d9f13SBarry Smith   }
31270450473dSBarry Smith   B->assembled = PETSC_TRUE;
3128273d9f13SBarry Smith   PetscFunctionReturn(0);
3129273d9f13SBarry Smith }
3130273d9f13SBarry Smith 
313165b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
3132d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype, MatReuse reuse, Mat *newmat)
3133d71ae5a4SJacob Faibussowitsch {
3134d77f618aSHong Zhang   Mat                mat_elemental;
31351683a169SBarry Smith   const PetscScalar *array;
31361683a169SBarry Smith   PetscScalar       *v_colwise;
3137d77f618aSHong Zhang   PetscInt           M = A->rmap->N, N = A->cmap->N, i, j, k, *rows, *cols;
3138d77f618aSHong Zhang 
31398baccfbdSHong Zhang   PetscFunctionBegin;
31409566063dSJacob Faibussowitsch   PetscCall(PetscMalloc3(M * N, &v_colwise, M, &rows, N, &cols));
31419566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &array));
3142d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
3143d77f618aSHong Zhang   k = 0;
3144d77f618aSHong Zhang   for (j = 0; j < N; j++) {
3145d77f618aSHong Zhang     cols[j] = j;
3146ad540459SPierre Jolivet     for (i = 0; i < M; i++) v_colwise[j * M + i] = array[k++];
3147d77f618aSHong Zhang   }
3148ad540459SPierre Jolivet   for (i = 0; i < M; i++) rows[i] = i;
31499566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &array));
3150d77f618aSHong Zhang 
31519566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental));
31529566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(mat_elemental, PETSC_DECIDE, PETSC_DECIDE, M, N));
31539566063dSJacob Faibussowitsch   PetscCall(MatSetType(mat_elemental, MATELEMENTAL));
31549566063dSJacob Faibussowitsch   PetscCall(MatSetUp(mat_elemental));
3155d77f618aSHong Zhang 
3156d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
31579566063dSJacob Faibussowitsch   PetscCall(MatSetValues(mat_elemental, M, rows, N, cols, v_colwise, ADD_VALUES));
31589566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY));
31599566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY));
31609566063dSJacob Faibussowitsch   PetscCall(PetscFree3(v_colwise, rows, cols));
3161d77f618aSHong Zhang 
3162511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
31639566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A, &mat_elemental));
3164d77f618aSHong Zhang   } else {
3165d77f618aSHong Zhang     *newmat = mat_elemental;
3166d77f618aSHong Zhang   }
31678baccfbdSHong Zhang   PetscFunctionReturn(0);
31688baccfbdSHong Zhang }
316965b80a83SHong Zhang #endif
31708baccfbdSHong Zhang 
3171d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA_SeqDense(Mat B, PetscInt lda)
3172d71ae5a4SJacob Faibussowitsch {
31731b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense *)B->data;
31747422da62SJose E. Roman   PetscBool     data;
317521a2c019SBarry Smith 
31761b807ce4Svictorle   PetscFunctionBegin;
31777422da62SJose E. Roman   data = (PetscBool)((B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE);
3178aed4548fSBarry Smith   PetscCheck(b->user_alloc || !data || b->lda == lda, PETSC_COMM_SELF, PETSC_ERR_ORDER, "LDA cannot be changed after allocation of internal storage");
317908401ef6SPierre 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);
31801b807ce4Svictorle   b->lda = lda;
31811b807ce4Svictorle   PetscFunctionReturn(0);
31821b807ce4Svictorle }
31831b807ce4Svictorle 
3184d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm, Mat inmat, PetscInt n, MatReuse scall, Mat *outmat)
3185d71ae5a4SJacob Faibussowitsch {
3186d528f656SJakub Kruzik   PetscFunctionBegin;
31879566063dSJacob Faibussowitsch   PetscCall(MatCreateMPIMatConcatenateSeqMat_MPIDense(comm, inmat, n, scall, outmat));
3188d528f656SJakub Kruzik   PetscFunctionReturn(0);
3189d528f656SJakub Kruzik }
3190d528f656SJakub Kruzik 
3191d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A, PetscInt col, Vec *v)
3192d71ae5a4SJacob Faibussowitsch {
31936947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
31946947451fSStefano Zampini 
31956947451fSStefano Zampini   PetscFunctionBegin;
319628b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
319728b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
31984dfa11a4SJacob Faibussowitsch   if (!a->cvec) { PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec)); }
31996947451fSStefano Zampini   a->vecinuse = col + 1;
32009566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, (PetscScalar **)&a->ptrinuse));
32019566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda));
32026947451fSStefano Zampini   *v = a->cvec;
32036947451fSStefano Zampini   PetscFunctionReturn(0);
32046947451fSStefano Zampini }
32056947451fSStefano Zampini 
3206d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A, PetscInt col, Vec *v)
3207d71ae5a4SJacob Faibussowitsch {
32086947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
32096947451fSStefano Zampini 
32106947451fSStefano Zampini   PetscFunctionBegin;
321128b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first");
321228b400f6SJacob Faibussowitsch   PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector");
32136947451fSStefano Zampini   a->vecinuse = 0;
32149566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, (PetscScalar **)&a->ptrinuse));
32159566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
321675f6d85dSStefano Zampini   if (v) *v = NULL;
32176947451fSStefano Zampini   PetscFunctionReturn(0);
32186947451fSStefano Zampini }
32196947451fSStefano Zampini 
3220d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v)
3221d71ae5a4SJacob Faibussowitsch {
32226947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
32236947451fSStefano Zampini 
32246947451fSStefano Zampini   PetscFunctionBegin;
322528b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
322628b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
32274dfa11a4SJacob Faibussowitsch   if (!a->cvec) { PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec)); }
32286947451fSStefano Zampini   a->vecinuse = col + 1;
32299566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &a->ptrinuse));
32309566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda));
32319566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(a->cvec));
32326947451fSStefano Zampini   *v = a->cvec;
32336947451fSStefano Zampini   PetscFunctionReturn(0);
32346947451fSStefano Zampini }
32356947451fSStefano Zampini 
3236d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v)
3237d71ae5a4SJacob Faibussowitsch {
32386947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
32396947451fSStefano Zampini 
32406947451fSStefano Zampini   PetscFunctionBegin;
324128b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first");
324228b400f6SJacob Faibussowitsch   PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector");
32436947451fSStefano Zampini   a->vecinuse = 0;
32449566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &a->ptrinuse));
32459566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(a->cvec));
32469566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
324775f6d85dSStefano Zampini   if (v) *v = NULL;
32486947451fSStefano Zampini   PetscFunctionReturn(0);
32496947451fSStefano Zampini }
32506947451fSStefano Zampini 
3251d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v)
3252d71ae5a4SJacob Faibussowitsch {
32536947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
32546947451fSStefano Zampini 
32556947451fSStefano Zampini   PetscFunctionBegin;
325628b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
325728b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
32584dfa11a4SJacob Faibussowitsch   if (!a->cvec) { PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec)); }
32596947451fSStefano Zampini   a->vecinuse = col + 1;
32609566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(A, (PetscScalar **)&a->ptrinuse));
32619566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda));
32626947451fSStefano Zampini   *v = a->cvec;
32636947451fSStefano Zampini   PetscFunctionReturn(0);
32646947451fSStefano Zampini }
32656947451fSStefano Zampini 
3266d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v)
3267d71ae5a4SJacob Faibussowitsch {
32686947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
32696947451fSStefano Zampini 
32706947451fSStefano Zampini   PetscFunctionBegin;
327128b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first");
327228b400f6SJacob Faibussowitsch   PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector");
32736947451fSStefano Zampini   a->vecinuse = 0;
32749566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(A, (PetscScalar **)&a->ptrinuse));
32759566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
327675f6d85dSStefano Zampini   if (v) *v = NULL;
32776947451fSStefano Zampini   PetscFunctionReturn(0);
32786947451fSStefano Zampini }
32796947451fSStefano Zampini 
3280d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v)
3281d71ae5a4SJacob Faibussowitsch {
32825ea7661aSPierre Jolivet   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
32835ea7661aSPierre Jolivet 
32845ea7661aSPierre Jolivet   PetscFunctionBegin;
328528b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
328628b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
3287a2748737SPierre Jolivet   if (a->cmat && (cend - cbegin != a->cmat->cmap->N || rend - rbegin != a->cmat->rmap->N)) PetscCall(MatDestroy(&a->cmat));
32885ea7661aSPierre Jolivet   if (!a->cmat) {
3289a2748737SPierre Jolivet     PetscCall(MatCreateDense(PetscObjectComm((PetscObject)A), rend - rbegin, PETSC_DECIDE, rend - rbegin, cend - cbegin, a->v + rbegin + (size_t)cbegin * a->lda, &a->cmat));
32905ea7661aSPierre Jolivet   } else {
3291a2748737SPierre Jolivet     PetscCall(MatDensePlaceArray(a->cmat, a->v + rbegin + (size_t)cbegin * a->lda));
32925ea7661aSPierre Jolivet   }
32939566063dSJacob Faibussowitsch   PetscCall(MatDenseSetLDA(a->cmat, a->lda));
32945ea7661aSPierre Jolivet   a->matinuse = cbegin + 1;
32955ea7661aSPierre Jolivet   *v          = a->cmat;
329647d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
329775f6d85dSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
329875f6d85dSStefano Zampini #endif
32995ea7661aSPierre Jolivet   PetscFunctionReturn(0);
33005ea7661aSPierre Jolivet }
33015ea7661aSPierre Jolivet 
3302d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A, Mat *v)
3303d71ae5a4SJacob Faibussowitsch {
33045ea7661aSPierre Jolivet   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
33055ea7661aSPierre Jolivet 
33065ea7661aSPierre Jolivet   PetscFunctionBegin;
330728b400f6SJacob Faibussowitsch   PetscCheck(a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetSubMatrix() first");
330828b400f6SJacob Faibussowitsch   PetscCheck(a->cmat, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column matrix");
330908401ef6SPierre Jolivet   PetscCheck(*v == a->cmat, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not the matrix obtained from MatDenseGetSubMatrix()");
33105ea7661aSPierre Jolivet   a->matinuse = 0;
33119566063dSJacob Faibussowitsch   PetscCall(MatDenseResetArray(a->cmat));
3312742765d3SMatthew Knepley   if (v) *v = NULL;
331347d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
33143faff063SStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
33153faff063SStefano Zampini #endif
33165ea7661aSPierre Jolivet   PetscFunctionReturn(0);
33175ea7661aSPierre Jolivet }
33185ea7661aSPierre Jolivet 
33190bad9183SKris Buschelman /*MC
3320fafad747SKris Buschelman    MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices.
33210bad9183SKris Buschelman 
33220bad9183SKris Buschelman    Options Database Keys:
332311a5261eSBarry Smith . -mat_type seqdense - sets the matrix type to `MATSEQDENSE` during a call to `MatSetFromOptions()`
33240bad9183SKris Buschelman 
33250bad9183SKris Buschelman   Level: beginner
33260bad9183SKris Buschelman 
332711a5261eSBarry Smith .seealso: `MATSEQDENSE`, `MatCreateSeqDense()`
33280bad9183SKris Buschelman M*/
3329d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreate_SeqDense(Mat B)
3330d71ae5a4SJacob Faibussowitsch {
3331273d9f13SBarry Smith   Mat_SeqDense *b;
33327c334f02SBarry Smith   PetscMPIInt   size;
3333273d9f13SBarry Smith 
3334273d9f13SBarry Smith   PetscFunctionBegin;
33359566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)B), &size));
333608401ef6SPierre Jolivet   PetscCheck(size <= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Comm must be of size 1");
333755659b69SBarry Smith 
33384dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&b));
33399566063dSJacob Faibussowitsch   PetscCall(PetscMemcpy(B->ops, &MatOps_Values, sizeof(struct _MatOps)));
334044cd7ae7SLois Curfman McInnes   B->data = (void *)b;
334118f449edSLois Curfman McInnes 
3342273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
33434e220ebcSLois Curfman McInnes 
33449566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatQRFactor_C", MatQRFactor_SeqDense));
33459566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetLDA_C", MatDenseGetLDA_SeqDense));
33469566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseSetLDA_C", MatDenseSetLDA_SeqDense));
33479566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArray_C", MatDenseGetArray_SeqDense));
33489566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArray_C", MatDenseRestoreArray_SeqDense));
33499566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDensePlaceArray_C", MatDensePlaceArray_SeqDense));
33509566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseResetArray_C", MatDenseResetArray_SeqDense));
33519566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseReplaceArray_C", MatDenseReplaceArray_SeqDense));
33529566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayRead_C", MatDenseGetArray_SeqDense));
33539566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayRead_C", MatDenseRestoreArray_SeqDense));
33549566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayWrite_C", MatDenseGetArray_SeqDense));
33559566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayWrite_C", MatDenseRestoreArray_SeqDense));
33569566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqaij_C", MatConvert_SeqDense_SeqAIJ));
33578baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
33589566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_elemental_C", MatConvert_SeqDense_Elemental));
33598baccfbdSHong Zhang #endif
3360d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
33619566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_scalapack_C", MatConvert_Dense_ScaLAPACK));
3362d24d4204SJose E. Roman #endif
33632bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
33649566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensecuda_C", MatConvert_SeqDense_SeqDenseCUDA));
33659566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", MatProductSetFromOptions_SeqDense));
33669566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdense_C", MatProductSetFromOptions_SeqDense));
33679566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensecuda_C", MatProductSetFromOptions_SeqDense));
33682bf066beSStefano Zampini #endif
336947d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP)
337047d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensehip_C", MatConvert_SeqDense_SeqDenseHIP));
337147d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensehip_seqdensehip_C", MatProductSetFromOptions_SeqDense));
337247d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensehip_seqdense_C", MatProductSetFromOptions_SeqDense));
337347d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensehip_C", MatProductSetFromOptions_SeqDense));
337447d993e7Ssuyashtn #endif
33759566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSeqDenseSetPreallocation_C", MatSeqDenseSetPreallocation_SeqDense));
33769566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqaij_seqdense_C", MatProductSetFromOptions_SeqAIJ_SeqDense));
33779566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdense_C", MatProductSetFromOptions_SeqDense));
33789566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense));
33799566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqsbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense));
338096e6d5c4SRichard Tran Mills 
33819566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumn_C", MatDenseGetColumn_SeqDense));
33829566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumn_C", MatDenseRestoreColumn_SeqDense));
33839566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVec_C", MatDenseGetColumnVec_SeqDense));
33849566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVec_C", MatDenseRestoreColumnVec_SeqDense));
33859566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecRead_C", MatDenseGetColumnVecRead_SeqDense));
33869566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecRead_C", MatDenseRestoreColumnVecRead_SeqDense));
33879566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecWrite_C", MatDenseGetColumnVecWrite_SeqDense));
33889566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecWrite_C", MatDenseRestoreColumnVecWrite_SeqDense));
33899566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetSubMatrix_C", MatDenseGetSubMatrix_SeqDense));
33909566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreSubMatrix_C", MatDenseRestoreSubMatrix_SeqDense));
33919566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)B, MATSEQDENSE));
33923a40ed3dSBarry Smith   PetscFunctionReturn(0);
3393289bc588SBarry Smith }
339486aefd0dSHong Zhang 
339586aefd0dSHong Zhang /*@C
339611a5261eSBarry 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.
339786aefd0dSHong Zhang 
339886aefd0dSHong Zhang    Not Collective
339986aefd0dSHong Zhang 
34005ea7661aSPierre Jolivet    Input Parameters:
340111a5261eSBarry Smith +  mat - a `MATSEQDENSE` or `MATMPIDENSE` matrix
340286aefd0dSHong Zhang -  col - column index
340386aefd0dSHong Zhang 
340486aefd0dSHong Zhang    Output Parameter:
340586aefd0dSHong Zhang .  vals - pointer to the data
340686aefd0dSHong Zhang 
340786aefd0dSHong Zhang    Level: intermediate
340886aefd0dSHong Zhang 
340911a5261eSBarry Smith    Note:
341011a5261eSBarry Smith    Use `MatDenseGetColumnVec()` to get access to a column of a `MATDENSE` treated as a `Vec`
341111a5261eSBarry Smith 
341211a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreColumn()`, `MatDenseGetColumnVec()`
341386aefd0dSHong Zhang @*/
3414d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumn(Mat A, PetscInt col, PetscScalar **vals)
3415d71ae5a4SJacob Faibussowitsch {
341686aefd0dSHong Zhang   PetscFunctionBegin;
3417d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
3418d5ea218eSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
3419d5ea218eSStefano Zampini   PetscValidPointer(vals, 3);
3420cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumn_C", (Mat, PetscInt, PetscScalar **), (A, col, vals));
342186aefd0dSHong Zhang   PetscFunctionReturn(0);
342286aefd0dSHong Zhang }
342386aefd0dSHong Zhang 
342486aefd0dSHong Zhang /*@C
342511a5261eSBarry Smith    MatDenseRestoreColumn - returns access to a column of a `MATDENSE` matrix which is returned by `MatDenseGetColumn()`.
342686aefd0dSHong Zhang 
342786aefd0dSHong Zhang    Not Collective
342886aefd0dSHong Zhang 
3429742765d3SMatthew Knepley    Input Parameters:
343011a5261eSBarry Smith +  mat - a `MATSEQDENSE` or `MATMPIDENSE` matrix
3431742765d3SMatthew Knepley -  vals - pointer to the data (may be NULL)
343286aefd0dSHong Zhang 
343386aefd0dSHong Zhang    Level: intermediate
343486aefd0dSHong Zhang 
343511a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetColumn()`
343686aefd0dSHong Zhang @*/
3437d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumn(Mat A, PetscScalar **vals)
3438d71ae5a4SJacob Faibussowitsch {
343986aefd0dSHong Zhang   PetscFunctionBegin;
3440d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
3441d5ea218eSStefano Zampini   PetscValidPointer(vals, 2);
3442cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumn_C", (Mat, PetscScalar **), (A, vals));
344386aefd0dSHong Zhang   PetscFunctionReturn(0);
344486aefd0dSHong Zhang }
34456947451fSStefano Zampini 
34460f74d2c1SSatish Balay /*@
344711a5261eSBarry Smith    MatDenseGetColumnVec - Gives read-write access to a column of a `MATDENSE` matrix, represented as a `Vec`.
34486947451fSStefano Zampini 
34496947451fSStefano Zampini    Collective
34506947451fSStefano Zampini 
34515ea7661aSPierre Jolivet    Input Parameters:
345211a5261eSBarry Smith +  mat - the `Mat` object
34536947451fSStefano Zampini -  col - the column index
34546947451fSStefano Zampini 
34556947451fSStefano Zampini    Output Parameter:
34566947451fSStefano Zampini .  v - the vector
34576947451fSStefano Zampini 
34586947451fSStefano Zampini    Notes:
345911a5261eSBarry Smith      The vector is owned by PETSc. Users need to call `MatDenseRestoreColumnVec()` when the vector is no longer needed.
346011a5261eSBarry Smith 
346111a5261eSBarry Smith      Use `MatDenseGetColumnVecRead()` to obtain read-only access or `MatDenseGetColumnVecWrite()` for write-only access.
34626947451fSStefano Zampini 
34636947451fSStefano Zampini    Level: intermediate
34646947451fSStefano Zampini 
346547d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`, `MatDenseGetColumn()`
34666947451fSStefano Zampini @*/
3467d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec(Mat A, PetscInt col, Vec *v)
3468d71ae5a4SJacob Faibussowitsch {
34696947451fSStefano Zampini   PetscFunctionBegin;
34706947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
34716947451fSStefano Zampini   PetscValidType(A, 1);
34726947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
34736947451fSStefano Zampini   PetscValidPointer(v, 3);
347428b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
34752cf15c64SPierre 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);
3476cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v));
34776947451fSStefano Zampini   PetscFunctionReturn(0);
34786947451fSStefano Zampini }
34796947451fSStefano Zampini 
34800f74d2c1SSatish Balay /*@
34816947451fSStefano Zampini    MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVec().
34826947451fSStefano Zampini 
34836947451fSStefano Zampini    Collective
34846947451fSStefano Zampini 
34855ea7661aSPierre Jolivet    Input Parameters:
34866947451fSStefano Zampini +  mat - the Mat object
34876947451fSStefano Zampini .  col - the column index
3488742765d3SMatthew Knepley -  v - the Vec object (may be NULL)
34896947451fSStefano Zampini 
34906947451fSStefano Zampini    Level: intermediate
34916947451fSStefano Zampini 
349247d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
34936947451fSStefano Zampini @*/
3494d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec(Mat A, PetscInt col, Vec *v)
3495d71ae5a4SJacob Faibussowitsch {
34966947451fSStefano Zampini   PetscFunctionBegin;
34976947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
34986947451fSStefano Zampini   PetscValidType(A, 1);
34996947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
350008401ef6SPierre Jolivet   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
35012cf15c64SPierre 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);
3502cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v));
35036947451fSStefano Zampini   PetscFunctionReturn(0);
35046947451fSStefano Zampini }
35056947451fSStefano Zampini 
35060f74d2c1SSatish Balay /*@
35076947451fSStefano Zampini    MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a Vec.
35086947451fSStefano Zampini 
35096947451fSStefano Zampini    Collective
35106947451fSStefano Zampini 
35115ea7661aSPierre Jolivet    Input Parameters:
35126947451fSStefano Zampini +  mat - the Mat object
35136947451fSStefano Zampini -  col - the column index
35146947451fSStefano Zampini 
35156947451fSStefano Zampini    Output Parameter:
35166947451fSStefano Zampini .  v - the vector
35176947451fSStefano Zampini 
35186947451fSStefano Zampini    Notes:
35196947451fSStefano Zampini      The vector is owned by PETSc and users cannot modify it.
352011a5261eSBarry Smith 
35216947451fSStefano Zampini      Users need to call MatDenseRestoreColumnVecRead() when the vector is no longer needed.
352211a5261eSBarry Smith 
35236947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecWrite() for write-only access.
35246947451fSStefano Zampini 
35256947451fSStefano Zampini    Level: intermediate
35266947451fSStefano Zampini 
352747d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
35286947451fSStefano Zampini @*/
3529d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead(Mat A, PetscInt col, Vec *v)
3530d71ae5a4SJacob Faibussowitsch {
35316947451fSStefano Zampini   PetscFunctionBegin;
35326947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
35336947451fSStefano Zampini   PetscValidType(A, 1);
35346947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
35356947451fSStefano Zampini   PetscValidPointer(v, 3);
353628b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
35372cf15c64SPierre 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);
3538cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v));
35396947451fSStefano Zampini   PetscFunctionReturn(0);
35406947451fSStefano Zampini }
35416947451fSStefano Zampini 
35420f74d2c1SSatish Balay /*@
35436947451fSStefano Zampini    MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecRead().
35446947451fSStefano Zampini 
35456947451fSStefano Zampini    Collective
35466947451fSStefano Zampini 
35475ea7661aSPierre Jolivet    Input Parameters:
35486947451fSStefano Zampini +  mat - the Mat object
35496947451fSStefano Zampini .  col - the column index
3550742765d3SMatthew Knepley -  v - the Vec object (may be NULL)
35516947451fSStefano Zampini 
35526947451fSStefano Zampini    Level: intermediate
35536947451fSStefano Zampini 
355447d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecWrite()`
35556947451fSStefano Zampini @*/
3556d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead(Mat A, PetscInt col, Vec *v)
3557d71ae5a4SJacob Faibussowitsch {
35586947451fSStefano Zampini   PetscFunctionBegin;
35596947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
35606947451fSStefano Zampini   PetscValidType(A, 1);
35616947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
356208401ef6SPierre Jolivet   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
35632cf15c64SPierre 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);
3564cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v));
35656947451fSStefano Zampini   PetscFunctionReturn(0);
35666947451fSStefano Zampini }
35676947451fSStefano Zampini 
35680f74d2c1SSatish Balay /*@
35696947451fSStefano Zampini    MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a Vec.
35706947451fSStefano Zampini 
35716947451fSStefano Zampini    Collective
35726947451fSStefano Zampini 
35735ea7661aSPierre Jolivet    Input Parameters:
35746947451fSStefano Zampini +  mat - the Mat object
35756947451fSStefano Zampini -  col - the column index
35766947451fSStefano Zampini 
35776947451fSStefano Zampini    Output Parameter:
35786947451fSStefano Zampini .  v - the vector
35796947451fSStefano Zampini 
35806947451fSStefano Zampini    Notes:
35816947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVecWrite() when the vector is no longer needed.
358211a5261eSBarry Smith 
35836947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecRead() for read-only access.
35846947451fSStefano Zampini 
35856947451fSStefano Zampini    Level: intermediate
35866947451fSStefano Zampini 
358747d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
35886947451fSStefano Zampini @*/
3589d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite(Mat A, PetscInt col, Vec *v)
3590d71ae5a4SJacob Faibussowitsch {
35916947451fSStefano Zampini   PetscFunctionBegin;
35926947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
35936947451fSStefano Zampini   PetscValidType(A, 1);
35946947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
35956947451fSStefano Zampini   PetscValidPointer(v, 3);
359628b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
3597aed4548fSBarry 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);
3598cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v));
35996947451fSStefano Zampini   PetscFunctionReturn(0);
36006947451fSStefano Zampini }
36016947451fSStefano Zampini 
36020f74d2c1SSatish Balay /*@
36036947451fSStefano Zampini    MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecWrite().
36046947451fSStefano Zampini 
36056947451fSStefano Zampini    Collective
36066947451fSStefano Zampini 
36075ea7661aSPierre Jolivet    Input Parameters:
36086947451fSStefano Zampini +  mat - the Mat object
36096947451fSStefano Zampini .  col - the column index
3610742765d3SMatthew Knepley -  v - the Vec object (may be NULL)
36116947451fSStefano Zampini 
36126947451fSStefano Zampini    Level: intermediate
36136947451fSStefano Zampini 
361447d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`
36156947451fSStefano Zampini @*/
3616d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A, PetscInt col, Vec *v)
3617d71ae5a4SJacob Faibussowitsch {
36186947451fSStefano Zampini   PetscFunctionBegin;
36196947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
36206947451fSStefano Zampini   PetscValidType(A, 1);
36216947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
362208401ef6SPierre Jolivet   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
3623aed4548fSBarry 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);
3624cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v));
36256947451fSStefano Zampini   PetscFunctionReturn(0);
36266947451fSStefano Zampini }
36275ea7661aSPierre Jolivet 
36280f74d2c1SSatish Balay /*@
3629a2748737SPierre Jolivet    MatDenseGetSubMatrix - Gives access to a block of rows and columns of a dense matrix, represented as a Mat.
36305ea7661aSPierre Jolivet 
36315ea7661aSPierre Jolivet    Collective
36325ea7661aSPierre Jolivet 
36335ea7661aSPierre Jolivet    Input Parameters:
36345ea7661aSPierre Jolivet +  mat - the Mat object
3635a2748737SPierre Jolivet .  rbegin - the first global row index in the block (if PETSC_DECIDE, is 0)
3636a2748737SPierre Jolivet .  rend - the global row index past the last one in the block (if PETSC_DECIDE, is M)
3637a2748737SPierre Jolivet .  cbegin - the first global column index in the block (if PETSC_DECIDE, is 0)
3638a2748737SPierre Jolivet -  cend - the global column index past the last one in the block (if PETSC_DECIDE, is N)
36395ea7661aSPierre Jolivet 
36405ea7661aSPierre Jolivet    Output Parameter:
36415ea7661aSPierre Jolivet .  v - the matrix
36425ea7661aSPierre Jolivet 
36435ea7661aSPierre Jolivet    Notes:
36445ea7661aSPierre Jolivet      The matrix is owned by PETSc. Users need to call MatDenseRestoreSubMatrix() when the matrix is no longer needed.
364511a5261eSBarry Smith 
3646a2748737SPierre 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.
36475ea7661aSPierre Jolivet 
36485ea7661aSPierre Jolivet    Level: intermediate
36495ea7661aSPierre Jolivet 
365047d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreSubMatrix()`
36515ea7661aSPierre Jolivet @*/
3652d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v)
3653d71ae5a4SJacob Faibussowitsch {
36545ea7661aSPierre Jolivet   PetscFunctionBegin;
36555ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
36565ea7661aSPierre Jolivet   PetscValidType(A, 1);
3657a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, rbegin, 2);
3658a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, rend, 3);
3659a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, cbegin, 4);
3660a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, cend, 5);
3661a2748737SPierre Jolivet   PetscValidPointer(v, 6);
3662a2748737SPierre Jolivet   if (rbegin == PETSC_DECIDE) rbegin = 0;
3663a2748737SPierre Jolivet   if (rend == PETSC_DECIDE) rend = A->rmap->N;
3664a2748737SPierre Jolivet   if (cbegin == PETSC_DECIDE) cbegin = 0;
3665a2748737SPierre Jolivet   if (cend == PETSC_DECIDE) cend = A->cmap->N;
366628b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
3667a2748737SPierre 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);
3668a2748737SPierre 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);
3669a2748737SPierre 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);
3670a2748737SPierre 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);
3671a2748737SPierre Jolivet   PetscUseMethod(A, "MatDenseGetSubMatrix_C", (Mat, PetscInt, PetscInt, PetscInt, PetscInt, Mat *), (A, rbegin, rend, cbegin, cend, v));
36725ea7661aSPierre Jolivet   PetscFunctionReturn(0);
36735ea7661aSPierre Jolivet }
36745ea7661aSPierre Jolivet 
36750f74d2c1SSatish Balay /*@
36765ea7661aSPierre Jolivet    MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from MatDenseGetSubMatrix().
36775ea7661aSPierre Jolivet 
36785ea7661aSPierre Jolivet    Collective
36795ea7661aSPierre Jolivet 
36805ea7661aSPierre Jolivet    Input Parameters:
36815ea7661aSPierre Jolivet +  mat - the Mat object
3682742765d3SMatthew Knepley -  v - the Mat object (may be NULL)
36835ea7661aSPierre Jolivet 
36845ea7661aSPierre Jolivet    Level: intermediate
36855ea7661aSPierre Jolivet 
368647d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseGetSubMatrix()`
36875ea7661aSPierre Jolivet @*/
3688d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix(Mat A, Mat *v)
3689d71ae5a4SJacob Faibussowitsch {
36905ea7661aSPierre Jolivet   PetscFunctionBegin;
36915ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
36925ea7661aSPierre Jolivet   PetscValidType(A, 1);
36935ea7661aSPierre Jolivet   PetscValidPointer(v, 2);
3694cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreSubMatrix_C", (Mat, Mat *), (A, v));
36955ea7661aSPierre Jolivet   PetscFunctionReturn(0);
36965ea7661aSPierre Jolivet }
36978a9c020eSBarry Smith 
36988a9c020eSBarry Smith #include <petscblaslapack.h>
36998a9c020eSBarry Smith #include <petsc/private/kernels/blockinvert.h>
37008a9c020eSBarry Smith 
3701d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseInvert(Mat A)
3702d71ae5a4SJacob Faibussowitsch {
37038a9c020eSBarry Smith   Mat_SeqDense   *a              = (Mat_SeqDense *)A->data;
37048a9c020eSBarry Smith   PetscInt        bs             = A->rmap->n;
37058a9c020eSBarry Smith   MatScalar      *values         = a->v;
37068a9c020eSBarry Smith   const PetscReal shift          = 0.0;
37078a9c020eSBarry Smith   PetscBool       allowzeropivot = PetscNot(A->erroriffailure), zeropivotdetected = PETSC_FALSE;
37088a9c020eSBarry Smith 
37098a9c020eSBarry Smith   PetscFunctionBegin;
37108a9c020eSBarry Smith   /* factor and invert each block */
37118a9c020eSBarry Smith   switch (bs) {
3712d71ae5a4SJacob Faibussowitsch   case 1:
3713d71ae5a4SJacob Faibussowitsch     values[0] = (PetscScalar)1.0 / (values[0] + shift);
3714d71ae5a4SJacob Faibussowitsch     break;
37158a9c020eSBarry Smith   case 2:
37168a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_2(values, shift, allowzeropivot, &zeropivotdetected));
37178a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
37188a9c020eSBarry Smith     break;
37198a9c020eSBarry Smith   case 3:
37208a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_3(values, shift, allowzeropivot, &zeropivotdetected));
37218a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
37228a9c020eSBarry Smith     break;
37238a9c020eSBarry Smith   case 4:
37248a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_4(values, shift, allowzeropivot, &zeropivotdetected));
37258a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
37268a9c020eSBarry Smith     break;
37279371c9d4SSatish Balay   case 5: {
37288a9c020eSBarry Smith     PetscScalar work[25];
37298a9c020eSBarry Smith     PetscInt    ipvt[5];
37308a9c020eSBarry Smith 
37318a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_5(values, ipvt, work, shift, allowzeropivot, &zeropivotdetected));
37328a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
37339371c9d4SSatish Balay   } break;
37348a9c020eSBarry Smith   case 6:
37358a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_6(values, shift, allowzeropivot, &zeropivotdetected));
37368a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
37378a9c020eSBarry Smith     break;
37388a9c020eSBarry Smith   case 7:
37398a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_7(values, shift, allowzeropivot, &zeropivotdetected));
37408a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
37418a9c020eSBarry Smith     break;
37429371c9d4SSatish Balay   default: {
37438a9c020eSBarry Smith     PetscInt    *v_pivots, *IJ, j;
37448a9c020eSBarry Smith     PetscScalar *v_work;
37458a9c020eSBarry Smith 
37468a9c020eSBarry Smith     PetscCall(PetscMalloc3(bs, &v_work, bs, &v_pivots, bs, &IJ));
3747ad540459SPierre Jolivet     for (j = 0; j < bs; j++) IJ[j] = j;
37488a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A(bs, values, v_pivots, v_work, allowzeropivot, &zeropivotdetected));
37498a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
37508a9c020eSBarry Smith     PetscCall(PetscFree3(v_work, v_pivots, IJ));
37518a9c020eSBarry Smith   }
37528a9c020eSBarry Smith   }
37538a9c020eSBarry Smith   PetscFunctionReturn(0);
37548a9c020eSBarry Smith }
3755