xref: /petsc/src/mat/impls/dense/seq/dense.c (revision dec0b4665a36c357901b00de474573dbc58fdd79)
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 
219711a5261eSBarry Smith    Logically Collective on A
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 
220711a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
220873a71a0fSBarry Smith @*/
2209d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArray(Mat A, PetscScalar **array)
2210d71ae5a4SJacob Faibussowitsch {
221173a71a0fSBarry Smith   PetscFunctionBegin;
2212d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2213d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2214cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array));
221573a71a0fSBarry Smith   PetscFunctionReturn(0);
221673a71a0fSBarry Smith }
221773a71a0fSBarry Smith 
2218dec5eb66SMatthew G Knepley /*@C
221911a5261eSBarry Smith    MatDenseRestoreArray - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArray()`
222073a71a0fSBarry Smith 
222111a5261eSBarry Smith    Logically Collective on A
22228572280aSBarry Smith 
22238572280aSBarry Smith    Input Parameters:
22246947451fSStefano Zampini +  mat - a dense matrix
2225742765d3SMatthew Knepley -  array - pointer to the data (may be NULL)
22268572280aSBarry Smith 
22278572280aSBarry Smith    Level: intermediate
22288572280aSBarry Smith 
222911a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
22308572280aSBarry Smith @*/
2231d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArray(Mat A, PetscScalar **array)
2232d71ae5a4SJacob Faibussowitsch {
22338572280aSBarry Smith   PetscFunctionBegin;
2234d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2235d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2236cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array));
22379566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)A));
223847d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
2239637a0070SStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
2240637a0070SStefano Zampini #endif
22418572280aSBarry Smith   PetscFunctionReturn(0);
22428572280aSBarry Smith }
22438572280aSBarry Smith 
22448572280aSBarry Smith /*@C
224511a5261eSBarry Smith   MatDenseGetArrayRead - gives read-only access to the array where the data for a `MATDENSE`  matrix is stored
22468572280aSBarry Smith 
22478572280aSBarry Smith    Not Collective
22488572280aSBarry Smith 
22498572280aSBarry Smith    Input Parameter:
22506947451fSStefano Zampini .  mat - a dense matrix
22518572280aSBarry Smith 
22528572280aSBarry Smith    Output Parameter:
22538572280aSBarry Smith .   array - pointer to the data
22548572280aSBarry Smith 
22558572280aSBarry Smith    Level: intermediate
22568572280aSBarry Smith 
225711a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
22588572280aSBarry Smith @*/
2259d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArrayRead(Mat A, const PetscScalar **array)
2260d71ae5a4SJacob Faibussowitsch {
22618572280aSBarry Smith   PetscFunctionBegin;
2262d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2263d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2264cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, const PetscScalar **), (A, array));
22658572280aSBarry Smith   PetscFunctionReturn(0);
22668572280aSBarry Smith }
22678572280aSBarry Smith 
22688572280aSBarry Smith /*@C
226911a5261eSBarry Smith    MatDenseRestoreArrayRead - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayRead()`
22708572280aSBarry Smith 
227173a71a0fSBarry Smith    Not Collective
227273a71a0fSBarry Smith 
227373a71a0fSBarry Smith    Input Parameters:
22746947451fSStefano Zampini +  mat - a dense matrix
2275742765d3SMatthew Knepley -  array - pointer to the data (may be NULL)
227673a71a0fSBarry Smith 
227773a71a0fSBarry Smith    Level: intermediate
227873a71a0fSBarry Smith 
227911a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
228073a71a0fSBarry Smith @*/
2281d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArrayRead(Mat A, const PetscScalar **array)
2282d71ae5a4SJacob Faibussowitsch {
228373a71a0fSBarry Smith   PetscFunctionBegin;
2284d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2285d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2286cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, const PetscScalar **), (A, array));
228773a71a0fSBarry Smith   PetscFunctionReturn(0);
228873a71a0fSBarry Smith }
228973a71a0fSBarry Smith 
22906947451fSStefano Zampini /*@C
229111a5261eSBarry Smith    MatDenseGetArrayWrite - gives write-only access to the array where the data for a `MATDENSE` matrix is stored
22926947451fSStefano Zampini 
22936947451fSStefano Zampini    Not Collective
22946947451fSStefano Zampini 
22956947451fSStefano Zampini    Input Parameter:
22966947451fSStefano Zampini .  mat - a dense matrix
22976947451fSStefano Zampini 
22986947451fSStefano Zampini    Output Parameter:
22996947451fSStefano Zampini .   array - pointer to the data
23006947451fSStefano Zampini 
23016947451fSStefano Zampini    Level: intermediate
23026947451fSStefano Zampini 
230311a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`
23046947451fSStefano Zampini @*/
2305d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArrayWrite(Mat A, PetscScalar **array)
2306d71ae5a4SJacob Faibussowitsch {
23076947451fSStefano Zampini   PetscFunctionBegin;
2308d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2309d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2310cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array));
23116947451fSStefano Zampini   PetscFunctionReturn(0);
23126947451fSStefano Zampini }
23136947451fSStefano Zampini 
23146947451fSStefano Zampini /*@C
231511a5261eSBarry Smith    MatDenseRestoreArrayWrite - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayWrite()`
23166947451fSStefano Zampini 
23176947451fSStefano Zampini    Not Collective
23186947451fSStefano Zampini 
23196947451fSStefano Zampini    Input Parameters:
23206947451fSStefano Zampini +  mat - a dense matrix
2321742765d3SMatthew Knepley -  array - pointer to the data (may be NULL)
23226947451fSStefano Zampini 
23236947451fSStefano Zampini    Level: intermediate
23246947451fSStefano Zampini 
232511a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`
23266947451fSStefano Zampini @*/
2327d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArrayWrite(Mat A, PetscScalar **array)
2328d71ae5a4SJacob Faibussowitsch {
23296947451fSStefano Zampini   PetscFunctionBegin;
2330d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2331d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2332cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array));
23339566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)A));
233447d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
23356947451fSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
23366947451fSStefano Zampini #endif
23376947451fSStefano Zampini   PetscFunctionReturn(0);
23386947451fSStefano Zampini }
23396947451fSStefano Zampini 
2340d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A, IS isrow, IS iscol, MatReuse scall, Mat *B)
2341d71ae5a4SJacob Faibussowitsch {
2342c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense *)A->data;
2343bf5a80bcSToby Isaac   PetscInt        i, j, nrows, ncols, ldb;
23445d0c19d7SBarry Smith   const PetscInt *irow, *icol;
234587828ca2SBarry Smith   PetscScalar    *av, *bv, *v = mat->v;
23460754003eSLois Curfman McInnes   Mat             newmat;
23470754003eSLois Curfman McInnes 
23483a40ed3dSBarry Smith   PetscFunctionBegin;
23499566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(isrow, &irow));
23509566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(iscol, &icol));
23519566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(isrow, &nrows));
23529566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(iscol, &ncols));
23530754003eSLois Curfman McInnes 
2354182d2002SSatish Balay   /* Check submatrixcall */
2355182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
235613f74950SBarry Smith     PetscInt n_cols, n_rows;
23579566063dSJacob Faibussowitsch     PetscCall(MatGetSize(*B, &n_rows, &n_cols));
235821a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
2359f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
23609566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(*B, nrows, ncols, nrows, ncols));
236121a2c019SBarry Smith     }
2362182d2002SSatish Balay     newmat = *B;
2363182d2002SSatish Balay   } else {
23640754003eSLois Curfman McInnes     /* Create and fill new matrix */
23659566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &newmat));
23669566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(newmat, nrows, ncols, nrows, ncols));
23679566063dSJacob Faibussowitsch     PetscCall(MatSetType(newmat, ((PetscObject)A)->type_name));
23689566063dSJacob Faibussowitsch     PetscCall(MatSeqDenseSetPreallocation(newmat, NULL));
2369182d2002SSatish Balay   }
2370182d2002SSatish Balay 
2371182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
23729566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(newmat, &bv));
23739566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(newmat, &ldb));
2374182d2002SSatish Balay   for (i = 0; i < ncols; i++) {
23756de62eeeSBarry Smith     av = v + mat->lda * icol[i];
2376ca15aa20SStefano Zampini     for (j = 0; j < nrows; j++) bv[j] = av[irow[j]];
2377bf5a80bcSToby Isaac     bv += ldb;
23780754003eSLois Curfman McInnes   }
23799566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(newmat, &bv));
2380182d2002SSatish Balay 
2381182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
23829566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(newmat, MAT_FINAL_ASSEMBLY));
23839566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(newmat, MAT_FINAL_ASSEMBLY));
23840754003eSLois Curfman McInnes 
23850754003eSLois Curfman McInnes   /* Free work space */
23869566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(isrow, &irow));
23879566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(iscol, &icol));
2388182d2002SSatish Balay   *B = newmat;
23893a40ed3dSBarry Smith   PetscFunctionReturn(0);
23900754003eSLois Curfman McInnes }
23910754003eSLois Curfman McInnes 
2392d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A, PetscInt n, const IS irow[], const IS icol[], MatReuse scall, Mat *B[])
2393d71ae5a4SJacob Faibussowitsch {
239413f74950SBarry Smith   PetscInt i;
2395905e6a2fSBarry Smith 
23963a40ed3dSBarry Smith   PetscFunctionBegin;
239748a46eb9SPierre Jolivet   if (scall == MAT_INITIAL_MATRIX) PetscCall(PetscCalloc1(n, B));
2398905e6a2fSBarry Smith 
239948a46eb9SPierre Jolivet   for (i = 0; i < n; i++) PetscCall(MatCreateSubMatrix_SeqDense(A, irow[i], icol[i], scall, &(*B)[i]));
24003a40ed3dSBarry Smith   PetscFunctionReturn(0);
2401905e6a2fSBarry Smith }
2402905e6a2fSBarry Smith 
2403d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat, MatAssemblyType mode)
2404d71ae5a4SJacob Faibussowitsch {
2405c0aa2d19SHong Zhang   PetscFunctionBegin;
2406c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2407c0aa2d19SHong Zhang }
2408c0aa2d19SHong Zhang 
2409d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat, MatAssemblyType mode)
2410d71ae5a4SJacob Faibussowitsch {
2411c0aa2d19SHong Zhang   PetscFunctionBegin;
2412c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2413c0aa2d19SHong Zhang }
2414c0aa2d19SHong Zhang 
2415d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCopy_SeqDense(Mat A, Mat B, MatStructure str)
2416d71ae5a4SJacob Faibussowitsch {
24174b0e389bSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data;
2418ca15aa20SStefano Zampini   const PetscScalar *va;
2419ca15aa20SStefano Zampini   PetscScalar       *vb;
2420d0f46423SBarry Smith   PetscInt           lda1 = a->lda, lda2 = b->lda, m = A->rmap->n, n = A->cmap->n, j;
24213a40ed3dSBarry Smith 
24223a40ed3dSBarry Smith   PetscFunctionBegin;
242333f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
242433f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
24259566063dSJacob Faibussowitsch     PetscCall(MatCopy_Basic(A, B, str));
24263a40ed3dSBarry Smith     PetscFunctionReturn(0);
24273a40ed3dSBarry Smith   }
2428aed4548fSBarry Smith   PetscCheck(m == B->rmap->n && n == B->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "size(B) != size(A)");
24299566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &va));
24309566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(B, &vb));
2431a5ce6ee0Svictorle   if (lda1 > m || lda2 > m) {
243248a46eb9SPierre Jolivet     for (j = 0; j < n; j++) PetscCall(PetscArraycpy(vb + j * lda2, va + j * lda1, m));
2433a5ce6ee0Svictorle   } else {
24349566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(vb, va, A->rmap->n * A->cmap->n));
2435a5ce6ee0Svictorle   }
24369566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(B, &vb));
24379566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &va));
24389566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY));
24399566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY));
2440273d9f13SBarry Smith   PetscFunctionReturn(0);
2441273d9f13SBarry Smith }
2442273d9f13SBarry Smith 
2443d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetUp_SeqDense(Mat A)
2444d71ae5a4SJacob Faibussowitsch {
2445273d9f13SBarry Smith   PetscFunctionBegin;
24469566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(A->rmap));
24479566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(A->cmap));
244848a46eb9SPierre Jolivet   if (!A->preallocated) PetscCall(MatSeqDenseSetPreallocation(A, NULL));
24493a40ed3dSBarry Smith   PetscFunctionReturn(0);
24504b0e389bSBarry Smith }
24514b0e389bSBarry Smith 
2452d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatConjugate_SeqDense(Mat A)
2453d71ae5a4SJacob Faibussowitsch {
24544396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
245506c5243aSJose E. Roman   PetscInt      i, j;
24564396437dSToby Isaac   PetscInt      min = PetscMin(A->rmap->n, A->cmap->n);
2457ca15aa20SStefano Zampini   PetscScalar  *aa;
2458ba337c44SJed Brown 
2459ba337c44SJed Brown   PetscFunctionBegin;
24609566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &aa));
246106c5243aSJose E. Roman   for (j = 0; j < A->cmap->n; j++) {
246206c5243aSJose E. Roman     for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscConj(aa[i + j * mat->lda]);
246306c5243aSJose E. Roman   }
24649566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &aa));
24659371c9d4SSatish Balay   if (mat->tau)
24669371c9d4SSatish Balay     for (i = 0; i < min; i++) mat->tau[i] = PetscConj(mat->tau[i]);
2467ba337c44SJed Brown   PetscFunctionReturn(0);
2468ba337c44SJed Brown }
2469ba337c44SJed Brown 
2470d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRealPart_SeqDense(Mat A)
2471d71ae5a4SJacob Faibussowitsch {
247206c5243aSJose E. Roman   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
247306c5243aSJose E. Roman   PetscInt      i, j;
2474ca15aa20SStefano Zampini   PetscScalar  *aa;
2475ba337c44SJed Brown 
2476ba337c44SJed Brown   PetscFunctionBegin;
24779566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &aa));
247806c5243aSJose E. Roman   for (j = 0; j < A->cmap->n; j++) {
247906c5243aSJose E. Roman     for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscRealPart(aa[i + j * mat->lda]);
248006c5243aSJose E. Roman   }
24819566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &aa));
2482ba337c44SJed Brown   PetscFunctionReturn(0);
2483ba337c44SJed Brown }
2484ba337c44SJed Brown 
2485d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatImaginaryPart_SeqDense(Mat A)
2486d71ae5a4SJacob Faibussowitsch {
248706c5243aSJose E. Roman   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
248806c5243aSJose E. Roman   PetscInt      i, j;
2489ca15aa20SStefano Zampini   PetscScalar  *aa;
2490ba337c44SJed Brown 
2491ba337c44SJed Brown   PetscFunctionBegin;
24929566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &aa));
249306c5243aSJose E. Roman   for (j = 0; j < A->cmap->n; j++) {
249406c5243aSJose E. Roman     for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscImaginaryPart(aa[i + j * mat->lda]);
249506c5243aSJose E. Roman   }
24969566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &aa));
2497ba337c44SJed Brown   PetscFunctionReturn(0);
2498ba337c44SJed Brown }
2499284134d9SBarry Smith 
2500a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/
2501d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C)
2502d71ae5a4SJacob Faibussowitsch {
2503d0f46423SBarry Smith   PetscInt  m = A->rmap->n, n = B->cmap->n;
250447d993e7Ssuyashtn   PetscBool cisdense = PETSC_FALSE;
2505a9fe9ddaSSatish Balay 
2506ee16a9a1SHong Zhang   PetscFunctionBegin;
25079566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C, m, n, m, n));
250847d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA)
25099566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, ""));
251047d993e7Ssuyashtn #endif
251147d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP)
251247d993e7Ssuyashtn   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, ""));
251347d993e7Ssuyashtn #endif
25147a3c3d58SStefano Zampini   if (!cisdense) {
25157a3c3d58SStefano Zampini     PetscBool flg;
25167a3c3d58SStefano Zampini 
25179566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg));
25189566063dSJacob Faibussowitsch     PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE));
25197a3c3d58SStefano Zampini   }
25209566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
2521ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2522ee16a9a1SHong Zhang }
2523a9fe9ddaSSatish Balay 
2524d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C)
2525d71ae5a4SJacob Faibussowitsch {
25266718818eSStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data, *c = (Mat_SeqDense *)C->data;
25270805154bSBarry Smith   PetscBLASInt       m, n, k;
2528ca15aa20SStefano Zampini   const PetscScalar *av, *bv;
2529ca15aa20SStefano Zampini   PetscScalar       *cv;
2530a9fe9ddaSSatish Balay   PetscScalar        _DOne = 1.0, _DZero = 0.0;
2531a9fe9ddaSSatish Balay 
2532a9fe9ddaSSatish Balay   PetscFunctionBegin;
25339566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n, &m));
25349566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n, &n));
25359566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &k));
253649d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
25379566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &av));
25389566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B, &bv));
25399566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C, &cv));
2540792fecdfSBarry Smith   PetscCallBLAS("BLASgemm", BLASgemm_("N", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda));
25419566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1)));
25429566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &av));
25439566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B, &bv));
25449566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C, &cv));
2545a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2546a9fe9ddaSSatish Balay }
2547a9fe9ddaSSatish Balay 
2548d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C)
2549d71ae5a4SJacob Faibussowitsch {
255069f65d41SStefano Zampini   PetscInt  m = A->rmap->n, n = B->rmap->n;
255147d993e7Ssuyashtn   PetscBool cisdense = PETSC_FALSE;
255269f65d41SStefano Zampini 
255369f65d41SStefano Zampini   PetscFunctionBegin;
25549566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C, m, n, m, n));
255547d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA)
25569566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, ""));
255747d993e7Ssuyashtn #endif
255847d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP)
255947d993e7Ssuyashtn   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, ""));
256047d993e7Ssuyashtn #endif
25617a3c3d58SStefano Zampini   if (!cisdense) {
25627a3c3d58SStefano Zampini     PetscBool flg;
25637a3c3d58SStefano Zampini 
25649566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg));
25659566063dSJacob Faibussowitsch     PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE));
25667a3c3d58SStefano Zampini   }
25679566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
256869f65d41SStefano Zampini   PetscFunctionReturn(0);
256969f65d41SStefano Zampini }
257069f65d41SStefano Zampini 
2571d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C)
2572d71ae5a4SJacob Faibussowitsch {
257369f65d41SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
257469f65d41SStefano Zampini   Mat_SeqDense      *b = (Mat_SeqDense *)B->data;
257569f65d41SStefano Zampini   Mat_SeqDense      *c = (Mat_SeqDense *)C->data;
25766718818eSStefano Zampini   const PetscScalar *av, *bv;
25776718818eSStefano Zampini   PetscScalar       *cv;
257869f65d41SStefano Zampini   PetscBLASInt       m, n, k;
257969f65d41SStefano Zampini   PetscScalar        _DOne = 1.0, _DZero = 0.0;
258069f65d41SStefano Zampini 
258169f65d41SStefano Zampini   PetscFunctionBegin;
25829566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n, &m));
25839566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n, &n));
25849566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &k));
258549d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
25869566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &av));
25879566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B, &bv));
25889566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C, &cv));
2589792fecdfSBarry Smith   PetscCallBLAS("BLASgemm", BLASgemm_("N", "T", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda));
25909566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &av));
25919566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B, &bv));
25929566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C, &cv));
25939566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1)));
259469f65d41SStefano Zampini   PetscFunctionReturn(0);
259569f65d41SStefano Zampini }
259669f65d41SStefano Zampini 
2597d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C)
2598d71ae5a4SJacob Faibussowitsch {
2599d0f46423SBarry Smith   PetscInt  m = A->cmap->n, n = B->cmap->n;
260047d993e7Ssuyashtn   PetscBool cisdense = PETSC_FALSE;
2601a9fe9ddaSSatish Balay 
2602ee16a9a1SHong Zhang   PetscFunctionBegin;
26039566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C, m, n, m, n));
260447d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA)
26059566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, ""));
260647d993e7Ssuyashtn #endif
260747d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP)
260847d993e7Ssuyashtn   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, ""));
260947d993e7Ssuyashtn #endif
26107a3c3d58SStefano Zampini   if (!cisdense) {
26117a3c3d58SStefano Zampini     PetscBool flg;
26127a3c3d58SStefano Zampini 
26139566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg));
26149566063dSJacob Faibussowitsch     PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE));
26157a3c3d58SStefano Zampini   }
26169566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
2617ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2618ee16a9a1SHong Zhang }
2619a9fe9ddaSSatish Balay 
2620d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C)
2621d71ae5a4SJacob Faibussowitsch {
2622a9fe9ddaSSatish Balay   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
2623a9fe9ddaSSatish Balay   Mat_SeqDense      *b = (Mat_SeqDense *)B->data;
2624a9fe9ddaSSatish Balay   Mat_SeqDense      *c = (Mat_SeqDense *)C->data;
26256718818eSStefano Zampini   const PetscScalar *av, *bv;
26266718818eSStefano Zampini   PetscScalar       *cv;
26270805154bSBarry Smith   PetscBLASInt       m, n, k;
2628a9fe9ddaSSatish Balay   PetscScalar        _DOne = 1.0, _DZero = 0.0;
2629a9fe9ddaSSatish Balay 
2630a9fe9ddaSSatish Balay   PetscFunctionBegin;
26319566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n, &m));
26329566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n, &n));
26339566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &k));
263449d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
26359566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &av));
26369566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B, &bv));
26379566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C, &cv));
2638792fecdfSBarry Smith   PetscCallBLAS("BLASgemm", BLASgemm_("T", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda));
26399566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &av));
26409566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B, &bv));
26419566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C, &cv));
26429566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1)));
2643a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2644a9fe9ddaSSatish Balay }
2645985db425SBarry Smith 
26464222ddf1SHong Zhang /* ----------------------------------------------- */
2647d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C)
2648d71ae5a4SJacob Faibussowitsch {
26494222ddf1SHong Zhang   PetscFunctionBegin;
26504222ddf1SHong Zhang   C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense;
26514222ddf1SHong Zhang   C->ops->productsymbolic = MatProductSymbolic_AB;
26524222ddf1SHong Zhang   PetscFunctionReturn(0);
26534222ddf1SHong Zhang }
26544222ddf1SHong Zhang 
2655d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C)
2656d71ae5a4SJacob Faibussowitsch {
26574222ddf1SHong Zhang   PetscFunctionBegin;
26584222ddf1SHong Zhang   C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense;
26594222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_AtB;
26604222ddf1SHong Zhang   PetscFunctionReturn(0);
26614222ddf1SHong Zhang }
26624222ddf1SHong Zhang 
2663d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C)
2664d71ae5a4SJacob Faibussowitsch {
26654222ddf1SHong Zhang   PetscFunctionBegin;
26664222ddf1SHong Zhang   C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense;
26674222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_ABt;
26684222ddf1SHong Zhang   PetscFunctionReturn(0);
26694222ddf1SHong Zhang }
26704222ddf1SHong Zhang 
2671d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C)
2672d71ae5a4SJacob Faibussowitsch {
26734222ddf1SHong Zhang   Mat_Product *product = C->product;
26744222ddf1SHong Zhang 
26754222ddf1SHong Zhang   PetscFunctionBegin;
26764222ddf1SHong Zhang   switch (product->type) {
2677d71ae5a4SJacob Faibussowitsch   case MATPRODUCT_AB:
2678d71ae5a4SJacob Faibussowitsch     PetscCall(MatProductSetFromOptions_SeqDense_AB(C));
2679d71ae5a4SJacob Faibussowitsch     break;
2680d71ae5a4SJacob Faibussowitsch   case MATPRODUCT_AtB:
2681d71ae5a4SJacob Faibussowitsch     PetscCall(MatProductSetFromOptions_SeqDense_AtB(C));
2682d71ae5a4SJacob Faibussowitsch     break;
2683d71ae5a4SJacob Faibussowitsch   case MATPRODUCT_ABt:
2684d71ae5a4SJacob Faibussowitsch     PetscCall(MatProductSetFromOptions_SeqDense_ABt(C));
2685d71ae5a4SJacob Faibussowitsch     break;
2686d71ae5a4SJacob Faibussowitsch   default:
2687d71ae5a4SJacob Faibussowitsch     break;
26884222ddf1SHong Zhang   }
26894222ddf1SHong Zhang   PetscFunctionReturn(0);
26904222ddf1SHong Zhang }
26914222ddf1SHong Zhang /* ----------------------------------------------- */
26924222ddf1SHong Zhang 
2693d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMax_SeqDense(Mat A, Vec v, PetscInt idx[])
2694d71ae5a4SJacob Faibussowitsch {
2695985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
2696d0f46423SBarry Smith   PetscInt           i, j, m = A->rmap->n, n = A->cmap->n, p;
2697985db425SBarry Smith   PetscScalar       *x;
2698ca15aa20SStefano Zampini   const PetscScalar *aa;
2699985db425SBarry Smith 
2700985db425SBarry Smith   PetscFunctionBegin;
270128b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
27029566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
27039566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v, &p));
27049566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
270508401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector");
2706985db425SBarry Smith   for (i = 0; i < m; i++) {
27079371c9d4SSatish Balay     x[i] = aa[i];
27089371c9d4SSatish Balay     if (idx) idx[i] = 0;
2709985db425SBarry Smith     for (j = 1; j < n; j++) {
27109371c9d4SSatish Balay       if (PetscRealPart(x[i]) < PetscRealPart(aa[i + a->lda * j])) {
27119371c9d4SSatish Balay         x[i] = aa[i + a->lda * j];
27129371c9d4SSatish Balay         if (idx) idx[i] = j;
27139371c9d4SSatish Balay       }
2714985db425SBarry Smith     }
2715985db425SBarry Smith   }
27169566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
27179566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
2718985db425SBarry Smith   PetscFunctionReturn(0);
2719985db425SBarry Smith }
2720985db425SBarry Smith 
2721d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A, Vec v, PetscInt idx[])
2722d71ae5a4SJacob Faibussowitsch {
2723985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
2724d0f46423SBarry Smith   PetscInt           i, j, m = A->rmap->n, n = A->cmap->n, p;
2725985db425SBarry Smith   PetscScalar       *x;
2726985db425SBarry Smith   PetscReal          atmp;
2727ca15aa20SStefano Zampini   const PetscScalar *aa;
2728985db425SBarry Smith 
2729985db425SBarry Smith   PetscFunctionBegin;
273028b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
27319566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
27329566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v, &p));
27339566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
273408401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector");
2735985db425SBarry Smith   for (i = 0; i < m; i++) {
27369189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
2737985db425SBarry Smith     for (j = 1; j < n; j++) {
2738ca15aa20SStefano Zampini       atmp = PetscAbsScalar(aa[i + a->lda * j]);
27399371c9d4SSatish Balay       if (PetscAbsScalar(x[i]) < atmp) {
27409371c9d4SSatish Balay         x[i] = atmp;
27419371c9d4SSatish Balay         if (idx) idx[i] = j;
27429371c9d4SSatish Balay       }
2743985db425SBarry Smith     }
2744985db425SBarry Smith   }
27459566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
27469566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
2747985db425SBarry Smith   PetscFunctionReturn(0);
2748985db425SBarry Smith }
2749985db425SBarry Smith 
2750d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMin_SeqDense(Mat A, Vec v, PetscInt idx[])
2751d71ae5a4SJacob Faibussowitsch {
2752985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
2753d0f46423SBarry Smith   PetscInt           i, j, m = A->rmap->n, n = A->cmap->n, p;
2754985db425SBarry Smith   PetscScalar       *x;
2755ca15aa20SStefano Zampini   const PetscScalar *aa;
2756985db425SBarry Smith 
2757985db425SBarry Smith   PetscFunctionBegin;
275828b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
27599566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
27609566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
27619566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v, &p));
276208401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector");
2763985db425SBarry Smith   for (i = 0; i < m; i++) {
27649371c9d4SSatish Balay     x[i] = aa[i];
27659371c9d4SSatish Balay     if (idx) idx[i] = 0;
2766985db425SBarry Smith     for (j = 1; j < n; j++) {
27679371c9d4SSatish Balay       if (PetscRealPart(x[i]) > PetscRealPart(aa[i + a->lda * j])) {
27689371c9d4SSatish Balay         x[i] = aa[i + a->lda * j];
27699371c9d4SSatish Balay         if (idx) idx[i] = j;
27709371c9d4SSatish Balay       }
2771985db425SBarry Smith     }
2772985db425SBarry Smith   }
27739566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
27749566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
2775985db425SBarry Smith   PetscFunctionReturn(0);
2776985db425SBarry Smith }
2777985db425SBarry Smith 
2778d71ae5a4SJacob Faibussowitsch PetscErrorCode MatGetColumnVector_SeqDense(Mat A, Vec v, PetscInt col)
2779d71ae5a4SJacob Faibussowitsch {
27808d0534beSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
27818d0534beSBarry Smith   PetscScalar       *x;
2782ca15aa20SStefano Zampini   const PetscScalar *aa;
27838d0534beSBarry Smith 
27848d0534beSBarry Smith   PetscFunctionBegin;
278528b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
27869566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
27879566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
27889566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(x, aa + col * a->lda, A->rmap->n));
27899566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
27909566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
27918d0534beSBarry Smith   PetscFunctionReturn(0);
27928d0534beSBarry Smith }
27938d0534beSBarry Smith 
2794d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatGetColumnReductions_SeqDense(Mat A, PetscInt type, PetscReal *reductions)
2795d71ae5a4SJacob Faibussowitsch {
27960716a85fSBarry Smith   PetscInt           i, j, m, n;
27971683a169SBarry Smith   const PetscScalar *a;
27980716a85fSBarry Smith 
27990716a85fSBarry Smith   PetscFunctionBegin;
28009566063dSJacob Faibussowitsch   PetscCall(MatGetSize(A, &m, &n));
28019566063dSJacob Faibussowitsch   PetscCall(PetscArrayzero(reductions, n));
28029566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &a));
2803857cbf51SRichard Tran Mills   if (type == NORM_2) {
28040716a85fSBarry Smith     for (i = 0; i < n; i++) {
2805ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j] * a[j]);
28060716a85fSBarry Smith       a += m;
28070716a85fSBarry Smith     }
2808857cbf51SRichard Tran Mills   } else if (type == NORM_1) {
28090716a85fSBarry Smith     for (i = 0; i < n; i++) {
2810ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j]);
28110716a85fSBarry Smith       a += m;
28120716a85fSBarry Smith     }
2813857cbf51SRichard Tran Mills   } else if (type == NORM_INFINITY) {
28140716a85fSBarry Smith     for (i = 0; i < n; i++) {
2815ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] = PetscMax(PetscAbsScalar(a[j]), reductions[i]);
28160716a85fSBarry Smith       a += m;
28170716a85fSBarry Smith     }
2818857cbf51SRichard Tran Mills   } else if (type == REDUCTION_SUM_REALPART || type == REDUCTION_MEAN_REALPART) {
2819a873a8cdSSam Reynolds     for (i = 0; i < n; i++) {
2820ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] += PetscRealPart(a[j]);
2821a873a8cdSSam Reynolds       a += m;
2822a873a8cdSSam Reynolds     }
2823857cbf51SRichard Tran Mills   } else if (type == REDUCTION_SUM_IMAGINARYPART || type == REDUCTION_MEAN_IMAGINARYPART) {
2824857cbf51SRichard Tran Mills     for (i = 0; i < n; i++) {
2825ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] += PetscImaginaryPart(a[j]);
2826857cbf51SRichard Tran Mills       a += m;
2827857cbf51SRichard Tran Mills     }
2828857cbf51SRichard Tran Mills   } else SETERRQ(PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Unknown reduction type");
28299566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &a));
2830857cbf51SRichard Tran Mills   if (type == NORM_2) {
2831a873a8cdSSam Reynolds     for (i = 0; i < n; i++) reductions[i] = PetscSqrtReal(reductions[i]);
2832857cbf51SRichard Tran Mills   } else if (type == REDUCTION_MEAN_REALPART || type == REDUCTION_MEAN_IMAGINARYPART) {
2833a873a8cdSSam Reynolds     for (i = 0; i < n; i++) reductions[i] /= m;
28340716a85fSBarry Smith   }
28350716a85fSBarry Smith   PetscFunctionReturn(0);
28360716a85fSBarry Smith }
28370716a85fSBarry Smith 
2838d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetRandom_SeqDense(Mat x, PetscRandom rctx)
2839d71ae5a4SJacob Faibussowitsch {
284073a71a0fSBarry Smith   PetscScalar *a;
2841637a0070SStefano Zampini   PetscInt     lda, m, n, i, j;
284273a71a0fSBarry Smith 
284373a71a0fSBarry Smith   PetscFunctionBegin;
28449566063dSJacob Faibussowitsch   PetscCall(MatGetSize(x, &m, &n));
28459566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(x, &lda));
28463faff063SStefano Zampini   PetscCall(MatDenseGetArrayWrite(x, &a));
2847637a0070SStefano Zampini   for (j = 0; j < n; j++) {
284848a46eb9SPierre Jolivet     for (i = 0; i < m; i++) PetscCall(PetscRandomGetValue(rctx, a + j * lda + i));
284973a71a0fSBarry Smith   }
28503faff063SStefano Zampini   PetscCall(MatDenseRestoreArrayWrite(x, &a));
285173a71a0fSBarry Smith   PetscFunctionReturn(0);
285273a71a0fSBarry Smith }
285373a71a0fSBarry Smith 
2854d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A, PetscBool *missing, PetscInt *d)
2855d71ae5a4SJacob Faibussowitsch {
28563b49f96aSBarry Smith   PetscFunctionBegin;
28573b49f96aSBarry Smith   *missing = PETSC_FALSE;
28583b49f96aSBarry Smith   PetscFunctionReturn(0);
28593b49f96aSBarry Smith }
286073a71a0fSBarry Smith 
2861ca15aa20SStefano Zampini /* vals is not const */
2862d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A, PetscInt col, PetscScalar **vals)
2863d71ae5a4SJacob Faibussowitsch {
286486aefd0dSHong Zhang   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
2865ca15aa20SStefano Zampini   PetscScalar  *v;
286686aefd0dSHong Zhang 
286786aefd0dSHong Zhang   PetscFunctionBegin;
286828b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
28699566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
2870ca15aa20SStefano Zampini   *vals = v + col * a->lda;
28719566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
287286aefd0dSHong Zhang   PetscFunctionReturn(0);
287386aefd0dSHong Zhang }
287486aefd0dSHong Zhang 
2875d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A, PetscScalar **vals)
2876d71ae5a4SJacob Faibussowitsch {
287786aefd0dSHong Zhang   PetscFunctionBegin;
2878742765d3SMatthew Knepley   if (vals) *vals = NULL; /* user cannot accidentally use the array later */
287986aefd0dSHong Zhang   PetscFunctionReturn(0);
288086aefd0dSHong Zhang }
2881abc3b08eSStefano Zampini 
2882289bc588SBarry Smith /* -------------------------------------------------------------------*/
2883a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqDense,
2884905e6a2fSBarry Smith                                        MatGetRow_SeqDense,
2885905e6a2fSBarry Smith                                        MatRestoreRow_SeqDense,
2886905e6a2fSBarry Smith                                        MatMult_SeqDense,
288797304618SKris Buschelman                                        /*  4*/ MatMultAdd_SeqDense,
28887c922b88SBarry Smith                                        MatMultTranspose_SeqDense,
28897c922b88SBarry Smith                                        MatMultTransposeAdd_SeqDense,
2890f4259b30SLisandro Dalcin                                        NULL,
2891f4259b30SLisandro Dalcin                                        NULL,
2892f4259b30SLisandro Dalcin                                        NULL,
2893f4259b30SLisandro Dalcin                                        /* 10*/ NULL,
2894905e6a2fSBarry Smith                                        MatLUFactor_SeqDense,
2895905e6a2fSBarry Smith                                        MatCholeskyFactor_SeqDense,
289641f059aeSBarry Smith                                        MatSOR_SeqDense,
2897ec8511deSBarry Smith                                        MatTranspose_SeqDense,
289897304618SKris Buschelman                                        /* 15*/ MatGetInfo_SeqDense,
2899905e6a2fSBarry Smith                                        MatEqual_SeqDense,
2900905e6a2fSBarry Smith                                        MatGetDiagonal_SeqDense,
2901905e6a2fSBarry Smith                                        MatDiagonalScale_SeqDense,
2902905e6a2fSBarry Smith                                        MatNorm_SeqDense,
2903c0aa2d19SHong Zhang                                        /* 20*/ MatAssemblyBegin_SeqDense,
2904c0aa2d19SHong Zhang                                        MatAssemblyEnd_SeqDense,
2905905e6a2fSBarry Smith                                        MatSetOption_SeqDense,
2906905e6a2fSBarry Smith                                        MatZeroEntries_SeqDense,
2907d519adbfSMatthew Knepley                                        /* 24*/ MatZeroRows_SeqDense,
2908f4259b30SLisandro Dalcin                                        NULL,
2909f4259b30SLisandro Dalcin                                        NULL,
2910f4259b30SLisandro Dalcin                                        NULL,
2911f4259b30SLisandro Dalcin                                        NULL,
29124994cf47SJed Brown                                        /* 29*/ MatSetUp_SeqDense,
2913f4259b30SLisandro Dalcin                                        NULL,
2914f4259b30SLisandro Dalcin                                        NULL,
2915f4259b30SLisandro Dalcin                                        NULL,
2916f4259b30SLisandro Dalcin                                        NULL,
2917d519adbfSMatthew Knepley                                        /* 34*/ MatDuplicate_SeqDense,
2918f4259b30SLisandro Dalcin                                        NULL,
2919f4259b30SLisandro Dalcin                                        NULL,
2920f4259b30SLisandro Dalcin                                        NULL,
2921f4259b30SLisandro Dalcin                                        NULL,
2922d519adbfSMatthew Knepley                                        /* 39*/ MatAXPY_SeqDense,
29237dae84e0SHong Zhang                                        MatCreateSubMatrices_SeqDense,
2924f4259b30SLisandro Dalcin                                        NULL,
29254b0e389bSBarry Smith                                        MatGetValues_SeqDense,
2926a5ae1ecdSBarry Smith                                        MatCopy_SeqDense,
2927d519adbfSMatthew Knepley                                        /* 44*/ MatGetRowMax_SeqDense,
2928a5ae1ecdSBarry Smith                                        MatScale_SeqDense,
29292f605a99SJose E. Roman                                        MatShift_SeqDense,
2930f4259b30SLisandro Dalcin                                        NULL,
29313f49a652SStefano Zampini                                        MatZeroRowsColumns_SeqDense,
293273a71a0fSBarry Smith                                        /* 49*/ MatSetRandom_SeqDense,
2933f4259b30SLisandro Dalcin                                        NULL,
2934f4259b30SLisandro Dalcin                                        NULL,
2935f4259b30SLisandro Dalcin                                        NULL,
2936f4259b30SLisandro Dalcin                                        NULL,
2937f4259b30SLisandro Dalcin                                        /* 54*/ NULL,
2938f4259b30SLisandro Dalcin                                        NULL,
2939f4259b30SLisandro Dalcin                                        NULL,
2940f4259b30SLisandro Dalcin                                        NULL,
2941f4259b30SLisandro Dalcin                                        NULL,
2942023c16fcSToby Isaac                                        /* 59*/ MatCreateSubMatrix_SeqDense,
2943e03a110bSBarry Smith                                        MatDestroy_SeqDense,
2944e03a110bSBarry Smith                                        MatView_SeqDense,
2945f4259b30SLisandro Dalcin                                        NULL,
2946f4259b30SLisandro Dalcin                                        NULL,
2947f4259b30SLisandro Dalcin                                        /* 64*/ NULL,
2948f4259b30SLisandro Dalcin                                        NULL,
2949f4259b30SLisandro Dalcin                                        NULL,
2950f4259b30SLisandro Dalcin                                        NULL,
2951f4259b30SLisandro Dalcin                                        NULL,
2952d519adbfSMatthew Knepley                                        /* 69*/ MatGetRowMaxAbs_SeqDense,
2953f4259b30SLisandro Dalcin                                        NULL,
2954f4259b30SLisandro Dalcin                                        NULL,
2955f4259b30SLisandro Dalcin                                        NULL,
2956f4259b30SLisandro Dalcin                                        NULL,
2957f4259b30SLisandro Dalcin                                        /* 74*/ NULL,
2958f4259b30SLisandro Dalcin                                        NULL,
2959f4259b30SLisandro Dalcin                                        NULL,
2960f4259b30SLisandro Dalcin                                        NULL,
2961f4259b30SLisandro Dalcin                                        NULL,
2962f4259b30SLisandro Dalcin                                        /* 79*/ NULL,
2963f4259b30SLisandro Dalcin                                        NULL,
2964f4259b30SLisandro Dalcin                                        NULL,
2965f4259b30SLisandro Dalcin                                        NULL,
29665bba2384SShri Abhyankar                                        /* 83*/ MatLoad_SeqDense,
2967637a0070SStefano Zampini                                        MatIsSymmetric_SeqDense,
29681cbb95d3SBarry Smith                                        MatIsHermitian_SeqDense,
2969f4259b30SLisandro Dalcin                                        NULL,
2970f4259b30SLisandro Dalcin                                        NULL,
2971f4259b30SLisandro Dalcin                                        NULL,
2972f4259b30SLisandro Dalcin                                        /* 89*/ NULL,
2973f4259b30SLisandro Dalcin                                        NULL,
2974a9fe9ddaSSatish Balay                                        MatMatMultNumeric_SeqDense_SeqDense,
2975f4259b30SLisandro Dalcin                                        NULL,
2976f4259b30SLisandro Dalcin                                        NULL,
2977f4259b30SLisandro Dalcin                                        /* 94*/ NULL,
2978f4259b30SLisandro Dalcin                                        NULL,
2979f4259b30SLisandro Dalcin                                        NULL,
298069f65d41SStefano Zampini                                        MatMatTransposeMultNumeric_SeqDense_SeqDense,
2981f4259b30SLisandro Dalcin                                        NULL,
29824222ddf1SHong Zhang                                        /* 99*/ MatProductSetFromOptions_SeqDense,
2983f4259b30SLisandro Dalcin                                        NULL,
2984f4259b30SLisandro Dalcin                                        NULL,
2985ba337c44SJed Brown                                        MatConjugate_SeqDense,
2986f4259b30SLisandro Dalcin                                        NULL,
2987f4259b30SLisandro Dalcin                                        /*104*/ NULL,
2988ba337c44SJed Brown                                        MatRealPart_SeqDense,
2989ba337c44SJed Brown                                        MatImaginaryPart_SeqDense,
2990f4259b30SLisandro Dalcin                                        NULL,
2991f4259b30SLisandro Dalcin                                        NULL,
2992f4259b30SLisandro Dalcin                                        /*109*/ NULL,
2993f4259b30SLisandro Dalcin                                        NULL,
29948d0534beSBarry Smith                                        MatGetRowMin_SeqDense,
2995aabbc4fbSShri Abhyankar                                        MatGetColumnVector_SeqDense,
29963b49f96aSBarry Smith                                        MatMissingDiagonal_SeqDense,
2997f4259b30SLisandro Dalcin                                        /*114*/ NULL,
2998f4259b30SLisandro Dalcin                                        NULL,
2999f4259b30SLisandro Dalcin                                        NULL,
3000f4259b30SLisandro Dalcin                                        NULL,
3001f4259b30SLisandro Dalcin                                        NULL,
3002f4259b30SLisandro Dalcin                                        /*119*/ NULL,
3003f4259b30SLisandro Dalcin                                        NULL,
3004f4259b30SLisandro Dalcin                                        NULL,
3005f4259b30SLisandro Dalcin                                        NULL,
3006f4259b30SLisandro Dalcin                                        NULL,
3007f4259b30SLisandro Dalcin                                        /*124*/ NULL,
3008a873a8cdSSam Reynolds                                        MatGetColumnReductions_SeqDense,
3009f4259b30SLisandro Dalcin                                        NULL,
3010f4259b30SLisandro Dalcin                                        NULL,
3011f4259b30SLisandro Dalcin                                        NULL,
3012f4259b30SLisandro Dalcin                                        /*129*/ NULL,
3013f4259b30SLisandro Dalcin                                        NULL,
3014f4259b30SLisandro Dalcin                                        NULL,
301575648e8dSHong Zhang                                        MatTransposeMatMultNumeric_SeqDense_SeqDense,
3016f4259b30SLisandro Dalcin                                        NULL,
3017f4259b30SLisandro Dalcin                                        /*134*/ NULL,
3018f4259b30SLisandro Dalcin                                        NULL,
3019f4259b30SLisandro Dalcin                                        NULL,
3020f4259b30SLisandro Dalcin                                        NULL,
3021f4259b30SLisandro Dalcin                                        NULL,
3022f4259b30SLisandro Dalcin                                        /*139*/ NULL,
3023f4259b30SLisandro Dalcin                                        NULL,
3024f4259b30SLisandro Dalcin                                        NULL,
3025f4259b30SLisandro Dalcin                                        NULL,
3026f4259b30SLisandro Dalcin                                        NULL,
30274222ddf1SHong Zhang                                        MatCreateMPIMatConcatenateSeqMat_SeqDense,
3028f4259b30SLisandro Dalcin                                        /*145*/ NULL,
3029f4259b30SLisandro Dalcin                                        NULL,
303099a7f59eSMark Adams                                        NULL,
303199a7f59eSMark Adams                                        NULL,
30327fb60732SBarry Smith                                        NULL,
3033*dec0b466SHong Zhang                                        /*150*/ NULL,
3034*dec0b466SHong Zhang                                        NULL};
303590ace30eSBarry Smith 
30364b828684SBarry Smith /*@C
303711a5261eSBarry Smith    MatCreateSeqDense - Creates a `MATSEQDENSE` that
3038d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
3039d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
3040289bc588SBarry Smith 
3041d083f849SBarry Smith    Collective
3042db81eaa0SLois Curfman McInnes 
304320563c6bSBarry Smith    Input Parameters:
304411a5261eSBarry Smith +  comm - MPI communicator, set to `PETSC_COMM_SELF`
30450c775827SLois Curfman McInnes .  m - number of rows
304618f449edSLois Curfman McInnes .  n - number of columns
30470298fd71SBarry Smith -  data - optional location of matrix data in column major order.  Set data=NULL for PETSc
3048dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
304920563c6bSBarry Smith 
305020563c6bSBarry Smith    Output Parameter:
305144cd7ae7SLois Curfman McInnes .  A - the matrix
305220563c6bSBarry Smith 
305311a5261eSBarry Smith    Note:
305418f449edSLois Curfman McInnes    The data input variable is intended primarily for Fortran programmers
305518f449edSLois Curfman McInnes    who wish to allocate their own matrix memory space.  Most users should
30560298fd71SBarry Smith    set data=NULL.
305718f449edSLois Curfman McInnes 
3058027ccd11SLois Curfman McInnes    Level: intermediate
3059027ccd11SLois Curfman McInnes 
306011a5261eSBarry Smith .seealso: `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()`
306120563c6bSBarry Smith @*/
3062d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateSeqDense(MPI_Comm comm, PetscInt m, PetscInt n, PetscScalar *data, Mat *A)
3063d71ae5a4SJacob Faibussowitsch {
30643a40ed3dSBarry Smith   PetscFunctionBegin;
30659566063dSJacob Faibussowitsch   PetscCall(MatCreate(comm, A));
30669566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*A, m, n, m, n));
30679566063dSJacob Faibussowitsch   PetscCall(MatSetType(*A, MATSEQDENSE));
30689566063dSJacob Faibussowitsch   PetscCall(MatSeqDenseSetPreallocation(*A, data));
3069273d9f13SBarry Smith   PetscFunctionReturn(0);
3070273d9f13SBarry Smith }
3071273d9f13SBarry Smith 
3072273d9f13SBarry Smith /*@C
307311a5261eSBarry Smith    MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements of a `MATSEQDENSE` matrix
3074273d9f13SBarry Smith 
3075d083f849SBarry Smith    Collective
3076273d9f13SBarry Smith 
3077273d9f13SBarry Smith    Input Parameters:
30781c4f3114SJed Brown +  B - the matrix
30790298fd71SBarry Smith -  data - the array (or NULL)
3080273d9f13SBarry Smith 
308111a5261eSBarry Smith    Note:
3082273d9f13SBarry Smith    The data input variable is intended primarily for Fortran programmers
3083273d9f13SBarry Smith    who wish to allocate their own matrix memory space.  Most users should
3084284134d9SBarry Smith    need not call this routine.
3085273d9f13SBarry Smith 
3086273d9f13SBarry Smith    Level: intermediate
3087273d9f13SBarry Smith 
308811a5261eSBarry Smith .seealso: `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()`, `MatDenseSetLDA()`
3089273d9f13SBarry Smith @*/
3090d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation(Mat B, PetscScalar data[])
3091d71ae5a4SJacob Faibussowitsch {
3092a23d5eceSKris Buschelman   PetscFunctionBegin;
3093d5ea218eSStefano Zampini   PetscValidHeaderSpecific(B, MAT_CLASSID, 1);
3094cac4c232SBarry Smith   PetscTryMethod(B, "MatSeqDenseSetPreallocation_C", (Mat, PetscScalar[]), (B, data));
3095a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3096a23d5eceSKris Buschelman }
3097a23d5eceSKris Buschelman 
3098d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation_SeqDense(Mat B, PetscScalar *data)
3099d71ae5a4SJacob Faibussowitsch {
3100ad16ce7aSStefano Zampini   Mat_SeqDense *b = (Mat_SeqDense *)B->data;
3101273d9f13SBarry Smith 
3102273d9f13SBarry Smith   PetscFunctionBegin;
310328b400f6SJacob Faibussowitsch   PetscCheck(!b->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
3104273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
3105a868139aSShri Abhyankar 
31069566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(B->rmap));
31079566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(B->cmap));
310834ef9618SShri Abhyankar 
3109ad16ce7aSStefano Zampini   if (b->lda <= 0) b->lda = B->rmap->n;
311086d161a7SShri Abhyankar 
31119e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
31129566063dSJacob Faibussowitsch     if (!b->user_alloc) PetscCall(PetscFree(b->v));
31139566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1((size_t)b->lda * B->cmap->n, &b->v));
31142205254eSKarl Rupp 
31159e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
3116273d9f13SBarry Smith   } else { /* user-allocated storage */
31179566063dSJacob Faibussowitsch     if (!b->user_alloc) PetscCall(PetscFree(b->v));
3118273d9f13SBarry Smith     b->v          = data;
3119273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
3120273d9f13SBarry Smith   }
31210450473dSBarry Smith   B->assembled = PETSC_TRUE;
3122273d9f13SBarry Smith   PetscFunctionReturn(0);
3123273d9f13SBarry Smith }
3124273d9f13SBarry Smith 
312565b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
3126d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype, MatReuse reuse, Mat *newmat)
3127d71ae5a4SJacob Faibussowitsch {
3128d77f618aSHong Zhang   Mat                mat_elemental;
31291683a169SBarry Smith   const PetscScalar *array;
31301683a169SBarry Smith   PetscScalar       *v_colwise;
3131d77f618aSHong Zhang   PetscInt           M = A->rmap->N, N = A->cmap->N, i, j, k, *rows, *cols;
3132d77f618aSHong Zhang 
31338baccfbdSHong Zhang   PetscFunctionBegin;
31349566063dSJacob Faibussowitsch   PetscCall(PetscMalloc3(M * N, &v_colwise, M, &rows, N, &cols));
31359566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &array));
3136d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
3137d77f618aSHong Zhang   k = 0;
3138d77f618aSHong Zhang   for (j = 0; j < N; j++) {
3139d77f618aSHong Zhang     cols[j] = j;
3140ad540459SPierre Jolivet     for (i = 0; i < M; i++) v_colwise[j * M + i] = array[k++];
3141d77f618aSHong Zhang   }
3142ad540459SPierre Jolivet   for (i = 0; i < M; i++) rows[i] = i;
31439566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &array));
3144d77f618aSHong Zhang 
31459566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental));
31469566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(mat_elemental, PETSC_DECIDE, PETSC_DECIDE, M, N));
31479566063dSJacob Faibussowitsch   PetscCall(MatSetType(mat_elemental, MATELEMENTAL));
31489566063dSJacob Faibussowitsch   PetscCall(MatSetUp(mat_elemental));
3149d77f618aSHong Zhang 
3150d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
31519566063dSJacob Faibussowitsch   PetscCall(MatSetValues(mat_elemental, M, rows, N, cols, v_colwise, ADD_VALUES));
31529566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY));
31539566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY));
31549566063dSJacob Faibussowitsch   PetscCall(PetscFree3(v_colwise, rows, cols));
3155d77f618aSHong Zhang 
3156511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
31579566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A, &mat_elemental));
3158d77f618aSHong Zhang   } else {
3159d77f618aSHong Zhang     *newmat = mat_elemental;
3160d77f618aSHong Zhang   }
31618baccfbdSHong Zhang   PetscFunctionReturn(0);
31628baccfbdSHong Zhang }
316365b80a83SHong Zhang #endif
31648baccfbdSHong Zhang 
3165d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA_SeqDense(Mat B, PetscInt lda)
3166d71ae5a4SJacob Faibussowitsch {
31671b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense *)B->data;
31687422da62SJose E. Roman   PetscBool     data;
316921a2c019SBarry Smith 
31701b807ce4Svictorle   PetscFunctionBegin;
31717422da62SJose E. Roman   data = (PetscBool)((B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE);
3172aed4548fSBarry Smith   PetscCheck(b->user_alloc || !data || b->lda == lda, PETSC_COMM_SELF, PETSC_ERR_ORDER, "LDA cannot be changed after allocation of internal storage");
317308401ef6SPierre 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);
31741b807ce4Svictorle   b->lda = lda;
31751b807ce4Svictorle   PetscFunctionReturn(0);
31761b807ce4Svictorle }
31771b807ce4Svictorle 
3178d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm, Mat inmat, PetscInt n, MatReuse scall, Mat *outmat)
3179d71ae5a4SJacob Faibussowitsch {
3180d528f656SJakub Kruzik   PetscFunctionBegin;
31819566063dSJacob Faibussowitsch   PetscCall(MatCreateMPIMatConcatenateSeqMat_MPIDense(comm, inmat, n, scall, outmat));
3182d528f656SJakub Kruzik   PetscFunctionReturn(0);
3183d528f656SJakub Kruzik }
3184d528f656SJakub Kruzik 
3185d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A, PetscInt col, Vec *v)
3186d71ae5a4SJacob Faibussowitsch {
31876947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
31886947451fSStefano Zampini 
31896947451fSStefano Zampini   PetscFunctionBegin;
319028b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
319128b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
31924dfa11a4SJacob Faibussowitsch   if (!a->cvec) { PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec)); }
31936947451fSStefano Zampini   a->vecinuse = col + 1;
31949566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, (PetscScalar **)&a->ptrinuse));
31959566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda));
31966947451fSStefano Zampini   *v = a->cvec;
31976947451fSStefano Zampini   PetscFunctionReturn(0);
31986947451fSStefano Zampini }
31996947451fSStefano Zampini 
3200d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A, PetscInt col, Vec *v)
3201d71ae5a4SJacob Faibussowitsch {
32026947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
32036947451fSStefano Zampini 
32046947451fSStefano Zampini   PetscFunctionBegin;
320528b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first");
320628b400f6SJacob Faibussowitsch   PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector");
32076947451fSStefano Zampini   a->vecinuse = 0;
32089566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, (PetscScalar **)&a->ptrinuse));
32099566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
321075f6d85dSStefano Zampini   if (v) *v = NULL;
32116947451fSStefano Zampini   PetscFunctionReturn(0);
32126947451fSStefano Zampini }
32136947451fSStefano Zampini 
3214d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v)
3215d71ae5a4SJacob Faibussowitsch {
32166947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
32176947451fSStefano Zampini 
32186947451fSStefano Zampini   PetscFunctionBegin;
321928b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
322028b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
32214dfa11a4SJacob Faibussowitsch   if (!a->cvec) { PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec)); }
32226947451fSStefano Zampini   a->vecinuse = col + 1;
32239566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &a->ptrinuse));
32249566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda));
32259566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(a->cvec));
32266947451fSStefano Zampini   *v = a->cvec;
32276947451fSStefano Zampini   PetscFunctionReturn(0);
32286947451fSStefano Zampini }
32296947451fSStefano Zampini 
3230d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v)
3231d71ae5a4SJacob Faibussowitsch {
32326947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
32336947451fSStefano Zampini 
32346947451fSStefano Zampini   PetscFunctionBegin;
323528b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first");
323628b400f6SJacob Faibussowitsch   PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector");
32376947451fSStefano Zampini   a->vecinuse = 0;
32389566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &a->ptrinuse));
32399566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(a->cvec));
32409566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
324175f6d85dSStefano Zampini   if (v) *v = NULL;
32426947451fSStefano Zampini   PetscFunctionReturn(0);
32436947451fSStefano Zampini }
32446947451fSStefano Zampini 
3245d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v)
3246d71ae5a4SJacob Faibussowitsch {
32476947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
32486947451fSStefano Zampini 
32496947451fSStefano Zampini   PetscFunctionBegin;
325028b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
325128b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
32524dfa11a4SJacob Faibussowitsch   if (!a->cvec) { PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec)); }
32536947451fSStefano Zampini   a->vecinuse = col + 1;
32549566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(A, (PetscScalar **)&a->ptrinuse));
32559566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda));
32566947451fSStefano Zampini   *v = a->cvec;
32576947451fSStefano Zampini   PetscFunctionReturn(0);
32586947451fSStefano Zampini }
32596947451fSStefano Zampini 
3260d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v)
3261d71ae5a4SJacob Faibussowitsch {
32626947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
32636947451fSStefano Zampini 
32646947451fSStefano Zampini   PetscFunctionBegin;
326528b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first");
326628b400f6SJacob Faibussowitsch   PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector");
32676947451fSStefano Zampini   a->vecinuse = 0;
32689566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(A, (PetscScalar **)&a->ptrinuse));
32699566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
327075f6d85dSStefano Zampini   if (v) *v = NULL;
32716947451fSStefano Zampini   PetscFunctionReturn(0);
32726947451fSStefano Zampini }
32736947451fSStefano Zampini 
3274d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v)
3275d71ae5a4SJacob Faibussowitsch {
32765ea7661aSPierre Jolivet   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
32775ea7661aSPierre Jolivet 
32785ea7661aSPierre Jolivet   PetscFunctionBegin;
327928b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
328028b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
3281a2748737SPierre Jolivet   if (a->cmat && (cend - cbegin != a->cmat->cmap->N || rend - rbegin != a->cmat->rmap->N)) PetscCall(MatDestroy(&a->cmat));
32825ea7661aSPierre Jolivet   if (!a->cmat) {
3283a2748737SPierre Jolivet     PetscCall(MatCreateDense(PetscObjectComm((PetscObject)A), rend - rbegin, PETSC_DECIDE, rend - rbegin, cend - cbegin, a->v + rbegin + (size_t)cbegin * a->lda, &a->cmat));
32845ea7661aSPierre Jolivet   } else {
3285a2748737SPierre Jolivet     PetscCall(MatDensePlaceArray(a->cmat, a->v + rbegin + (size_t)cbegin * a->lda));
32865ea7661aSPierre Jolivet   }
32879566063dSJacob Faibussowitsch   PetscCall(MatDenseSetLDA(a->cmat, a->lda));
32885ea7661aSPierre Jolivet   a->matinuse = cbegin + 1;
32895ea7661aSPierre Jolivet   *v          = a->cmat;
329047d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
329175f6d85dSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
329275f6d85dSStefano Zampini #endif
32935ea7661aSPierre Jolivet   PetscFunctionReturn(0);
32945ea7661aSPierre Jolivet }
32955ea7661aSPierre Jolivet 
3296d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A, Mat *v)
3297d71ae5a4SJacob Faibussowitsch {
32985ea7661aSPierre Jolivet   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
32995ea7661aSPierre Jolivet 
33005ea7661aSPierre Jolivet   PetscFunctionBegin;
330128b400f6SJacob Faibussowitsch   PetscCheck(a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetSubMatrix() first");
330228b400f6SJacob Faibussowitsch   PetscCheck(a->cmat, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column matrix");
330308401ef6SPierre Jolivet   PetscCheck(*v == a->cmat, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not the matrix obtained from MatDenseGetSubMatrix()");
33045ea7661aSPierre Jolivet   a->matinuse = 0;
33059566063dSJacob Faibussowitsch   PetscCall(MatDenseResetArray(a->cmat));
3306742765d3SMatthew Knepley   if (v) *v = NULL;
330747d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
33083faff063SStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
33093faff063SStefano Zampini #endif
33105ea7661aSPierre Jolivet   PetscFunctionReturn(0);
33115ea7661aSPierre Jolivet }
33125ea7661aSPierre Jolivet 
33130bad9183SKris Buschelman /*MC
3314fafad747SKris Buschelman    MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices.
33150bad9183SKris Buschelman 
33160bad9183SKris Buschelman    Options Database Keys:
331711a5261eSBarry Smith . -mat_type seqdense - sets the matrix type to `MATSEQDENSE` during a call to `MatSetFromOptions()`
33180bad9183SKris Buschelman 
33190bad9183SKris Buschelman   Level: beginner
33200bad9183SKris Buschelman 
332111a5261eSBarry Smith .seealso: `MATSEQDENSE`, `MatCreateSeqDense()`
33220bad9183SKris Buschelman M*/
3323d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreate_SeqDense(Mat B)
3324d71ae5a4SJacob Faibussowitsch {
3325273d9f13SBarry Smith   Mat_SeqDense *b;
33267c334f02SBarry Smith   PetscMPIInt   size;
3327273d9f13SBarry Smith 
3328273d9f13SBarry Smith   PetscFunctionBegin;
33299566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)B), &size));
333008401ef6SPierre Jolivet   PetscCheck(size <= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Comm must be of size 1");
333155659b69SBarry Smith 
33324dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&b));
33339566063dSJacob Faibussowitsch   PetscCall(PetscMemcpy(B->ops, &MatOps_Values, sizeof(struct _MatOps)));
333444cd7ae7SLois Curfman McInnes   B->data = (void *)b;
333518f449edSLois Curfman McInnes 
3336273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
33374e220ebcSLois Curfman McInnes 
33389566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatQRFactor_C", MatQRFactor_SeqDense));
33399566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetLDA_C", MatDenseGetLDA_SeqDense));
33409566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseSetLDA_C", MatDenseSetLDA_SeqDense));
33419566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArray_C", MatDenseGetArray_SeqDense));
33429566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArray_C", MatDenseRestoreArray_SeqDense));
33439566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDensePlaceArray_C", MatDensePlaceArray_SeqDense));
33449566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseResetArray_C", MatDenseResetArray_SeqDense));
33459566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseReplaceArray_C", MatDenseReplaceArray_SeqDense));
33469566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayRead_C", MatDenseGetArray_SeqDense));
33479566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayRead_C", MatDenseRestoreArray_SeqDense));
33489566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayWrite_C", MatDenseGetArray_SeqDense));
33499566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayWrite_C", MatDenseRestoreArray_SeqDense));
33509566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqaij_C", MatConvert_SeqDense_SeqAIJ));
33518baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
33529566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_elemental_C", MatConvert_SeqDense_Elemental));
33538baccfbdSHong Zhang #endif
3354d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
33559566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_scalapack_C", MatConvert_Dense_ScaLAPACK));
3356d24d4204SJose E. Roman #endif
33572bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
33589566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensecuda_C", MatConvert_SeqDense_SeqDenseCUDA));
33599566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", MatProductSetFromOptions_SeqDense));
33609566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdense_C", MatProductSetFromOptions_SeqDense));
33619566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensecuda_C", MatProductSetFromOptions_SeqDense));
33622bf066beSStefano Zampini #endif
336347d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP)
336447d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensehip_C", MatConvert_SeqDense_SeqDenseHIP));
336547d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensehip_seqdensehip_C", MatProductSetFromOptions_SeqDense));
336647d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensehip_seqdense_C", MatProductSetFromOptions_SeqDense));
336747d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensehip_C", MatProductSetFromOptions_SeqDense));
336847d993e7Ssuyashtn #endif
33699566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSeqDenseSetPreallocation_C", MatSeqDenseSetPreallocation_SeqDense));
33709566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqaij_seqdense_C", MatProductSetFromOptions_SeqAIJ_SeqDense));
33719566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdense_C", MatProductSetFromOptions_SeqDense));
33729566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense));
33739566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqsbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense));
337496e6d5c4SRichard Tran Mills 
33759566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumn_C", MatDenseGetColumn_SeqDense));
33769566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumn_C", MatDenseRestoreColumn_SeqDense));
33779566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVec_C", MatDenseGetColumnVec_SeqDense));
33789566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVec_C", MatDenseRestoreColumnVec_SeqDense));
33799566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecRead_C", MatDenseGetColumnVecRead_SeqDense));
33809566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecRead_C", MatDenseRestoreColumnVecRead_SeqDense));
33819566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecWrite_C", MatDenseGetColumnVecWrite_SeqDense));
33829566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecWrite_C", MatDenseRestoreColumnVecWrite_SeqDense));
33839566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetSubMatrix_C", MatDenseGetSubMatrix_SeqDense));
33849566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreSubMatrix_C", MatDenseRestoreSubMatrix_SeqDense));
33859566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)B, MATSEQDENSE));
33863a40ed3dSBarry Smith   PetscFunctionReturn(0);
3387289bc588SBarry Smith }
338886aefd0dSHong Zhang 
338986aefd0dSHong Zhang /*@C
339011a5261eSBarry 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.
339186aefd0dSHong Zhang 
339286aefd0dSHong Zhang    Not Collective
339386aefd0dSHong Zhang 
33945ea7661aSPierre Jolivet    Input Parameters:
339511a5261eSBarry Smith +  mat - a `MATSEQDENSE` or `MATMPIDENSE` matrix
339686aefd0dSHong Zhang -  col - column index
339786aefd0dSHong Zhang 
339886aefd0dSHong Zhang    Output Parameter:
339986aefd0dSHong Zhang .  vals - pointer to the data
340086aefd0dSHong Zhang 
340186aefd0dSHong Zhang    Level: intermediate
340286aefd0dSHong Zhang 
340311a5261eSBarry Smith    Note:
340411a5261eSBarry Smith    Use `MatDenseGetColumnVec()` to get access to a column of a `MATDENSE` treated as a `Vec`
340511a5261eSBarry Smith 
340611a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreColumn()`, `MatDenseGetColumnVec()`
340786aefd0dSHong Zhang @*/
3408d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumn(Mat A, PetscInt col, PetscScalar **vals)
3409d71ae5a4SJacob Faibussowitsch {
341086aefd0dSHong Zhang   PetscFunctionBegin;
3411d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
3412d5ea218eSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
3413d5ea218eSStefano Zampini   PetscValidPointer(vals, 3);
3414cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumn_C", (Mat, PetscInt, PetscScalar **), (A, col, vals));
341586aefd0dSHong Zhang   PetscFunctionReturn(0);
341686aefd0dSHong Zhang }
341786aefd0dSHong Zhang 
341886aefd0dSHong Zhang /*@C
341911a5261eSBarry Smith    MatDenseRestoreColumn - returns access to a column of a `MATDENSE` matrix which is returned by `MatDenseGetColumn()`.
342086aefd0dSHong Zhang 
342186aefd0dSHong Zhang    Not Collective
342286aefd0dSHong Zhang 
3423742765d3SMatthew Knepley    Input Parameters:
342411a5261eSBarry Smith +  mat - a `MATSEQDENSE` or `MATMPIDENSE` matrix
3425742765d3SMatthew Knepley -  vals - pointer to the data (may be NULL)
342686aefd0dSHong Zhang 
342786aefd0dSHong Zhang    Level: intermediate
342886aefd0dSHong Zhang 
342911a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetColumn()`
343086aefd0dSHong Zhang @*/
3431d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumn(Mat A, PetscScalar **vals)
3432d71ae5a4SJacob Faibussowitsch {
343386aefd0dSHong Zhang   PetscFunctionBegin;
3434d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
3435d5ea218eSStefano Zampini   PetscValidPointer(vals, 2);
3436cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumn_C", (Mat, PetscScalar **), (A, vals));
343786aefd0dSHong Zhang   PetscFunctionReturn(0);
343886aefd0dSHong Zhang }
34396947451fSStefano Zampini 
34400f74d2c1SSatish Balay /*@
344111a5261eSBarry Smith    MatDenseGetColumnVec - Gives read-write access to a column of a `MATDENSE` matrix, represented as a `Vec`.
34426947451fSStefano Zampini 
34436947451fSStefano Zampini    Collective
34446947451fSStefano Zampini 
34455ea7661aSPierre Jolivet    Input Parameters:
344611a5261eSBarry Smith +  mat - the `Mat` object
34476947451fSStefano Zampini -  col - the column index
34486947451fSStefano Zampini 
34496947451fSStefano Zampini    Output Parameter:
34506947451fSStefano Zampini .  v - the vector
34516947451fSStefano Zampini 
34526947451fSStefano Zampini    Notes:
345311a5261eSBarry Smith      The vector is owned by PETSc. Users need to call `MatDenseRestoreColumnVec()` when the vector is no longer needed.
345411a5261eSBarry Smith 
345511a5261eSBarry Smith      Use `MatDenseGetColumnVecRead()` to obtain read-only access or `MatDenseGetColumnVecWrite()` for write-only access.
34566947451fSStefano Zampini 
34576947451fSStefano Zampini    Level: intermediate
34586947451fSStefano Zampini 
345947d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`, `MatDenseGetColumn()`
34606947451fSStefano Zampini @*/
3461d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec(Mat A, PetscInt col, Vec *v)
3462d71ae5a4SJacob Faibussowitsch {
34636947451fSStefano Zampini   PetscFunctionBegin;
34646947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
34656947451fSStefano Zampini   PetscValidType(A, 1);
34666947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
34676947451fSStefano Zampini   PetscValidPointer(v, 3);
346828b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
34692cf15c64SPierre 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);
3470cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v));
34716947451fSStefano Zampini   PetscFunctionReturn(0);
34726947451fSStefano Zampini }
34736947451fSStefano Zampini 
34740f74d2c1SSatish Balay /*@
34756947451fSStefano Zampini    MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVec().
34766947451fSStefano Zampini 
34776947451fSStefano Zampini    Collective
34786947451fSStefano Zampini 
34795ea7661aSPierre Jolivet    Input Parameters:
34806947451fSStefano Zampini +  mat - the Mat object
34816947451fSStefano Zampini .  col - the column index
3482742765d3SMatthew Knepley -  v - the Vec object (may be NULL)
34836947451fSStefano Zampini 
34846947451fSStefano Zampini    Level: intermediate
34856947451fSStefano Zampini 
348647d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVecRead()`,`MatDenseRestoreColumnVecWrite()`
34876947451fSStefano Zampini @*/
3488d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec(Mat A, PetscInt col, Vec *v)
3489d71ae5a4SJacob Faibussowitsch {
34906947451fSStefano Zampini   PetscFunctionBegin;
34916947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
34926947451fSStefano Zampini   PetscValidType(A, 1);
34936947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
349408401ef6SPierre Jolivet   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
34952cf15c64SPierre 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);
3496cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v));
34976947451fSStefano Zampini   PetscFunctionReturn(0);
34986947451fSStefano Zampini }
34996947451fSStefano Zampini 
35000f74d2c1SSatish Balay /*@
35016947451fSStefano Zampini    MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a Vec.
35026947451fSStefano Zampini 
35036947451fSStefano Zampini    Collective
35046947451fSStefano Zampini 
35055ea7661aSPierre Jolivet    Input Parameters:
35066947451fSStefano Zampini +  mat - the Mat object
35076947451fSStefano Zampini -  col - the column index
35086947451fSStefano Zampini 
35096947451fSStefano Zampini    Output Parameter:
35106947451fSStefano Zampini .  v - the vector
35116947451fSStefano Zampini 
35126947451fSStefano Zampini    Notes:
35136947451fSStefano Zampini      The vector is owned by PETSc and users cannot modify it.
351411a5261eSBarry Smith 
35156947451fSStefano Zampini      Users need to call MatDenseRestoreColumnVecRead() when the vector is no longer needed.
351611a5261eSBarry Smith 
35176947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecWrite() for write-only access.
35186947451fSStefano Zampini 
35196947451fSStefano Zampini    Level: intermediate
35206947451fSStefano Zampini 
352147d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
35226947451fSStefano Zampini @*/
3523d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead(Mat A, PetscInt col, Vec *v)
3524d71ae5a4SJacob Faibussowitsch {
35256947451fSStefano Zampini   PetscFunctionBegin;
35266947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
35276947451fSStefano Zampini   PetscValidType(A, 1);
35286947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
35296947451fSStefano Zampini   PetscValidPointer(v, 3);
353028b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
35312cf15c64SPierre 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);
3532cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v));
35336947451fSStefano Zampini   PetscFunctionReturn(0);
35346947451fSStefano Zampini }
35356947451fSStefano Zampini 
35360f74d2c1SSatish Balay /*@
35376947451fSStefano Zampini    MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecRead().
35386947451fSStefano Zampini 
35396947451fSStefano Zampini    Collective
35406947451fSStefano Zampini 
35415ea7661aSPierre Jolivet    Input Parameters:
35426947451fSStefano Zampini +  mat - the Mat object
35436947451fSStefano Zampini .  col - the column index
3544742765d3SMatthew Knepley -  v - the Vec object (may be NULL)
35456947451fSStefano Zampini 
35466947451fSStefano Zampini    Level: intermediate
35476947451fSStefano Zampini 
354847d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecWrite()`
35496947451fSStefano Zampini @*/
3550d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead(Mat A, PetscInt col, Vec *v)
3551d71ae5a4SJacob Faibussowitsch {
35526947451fSStefano Zampini   PetscFunctionBegin;
35536947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
35546947451fSStefano Zampini   PetscValidType(A, 1);
35556947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
355608401ef6SPierre Jolivet   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
35572cf15c64SPierre 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);
3558cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v));
35596947451fSStefano Zampini   PetscFunctionReturn(0);
35606947451fSStefano Zampini }
35616947451fSStefano Zampini 
35620f74d2c1SSatish Balay /*@
35636947451fSStefano Zampini    MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a Vec.
35646947451fSStefano Zampini 
35656947451fSStefano Zampini    Collective
35666947451fSStefano Zampini 
35675ea7661aSPierre Jolivet    Input Parameters:
35686947451fSStefano Zampini +  mat - the Mat object
35696947451fSStefano Zampini -  col - the column index
35706947451fSStefano Zampini 
35716947451fSStefano Zampini    Output Parameter:
35726947451fSStefano Zampini .  v - the vector
35736947451fSStefano Zampini 
35746947451fSStefano Zampini    Notes:
35756947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVecWrite() when the vector is no longer needed.
357611a5261eSBarry Smith 
35776947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecRead() for read-only access.
35786947451fSStefano Zampini 
35796947451fSStefano Zampini    Level: intermediate
35806947451fSStefano Zampini 
358147d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
35826947451fSStefano Zampini @*/
3583d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite(Mat A, PetscInt col, Vec *v)
3584d71ae5a4SJacob Faibussowitsch {
35856947451fSStefano Zampini   PetscFunctionBegin;
35866947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
35876947451fSStefano Zampini   PetscValidType(A, 1);
35886947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
35896947451fSStefano Zampini   PetscValidPointer(v, 3);
359028b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
3591aed4548fSBarry 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);
3592cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v));
35936947451fSStefano Zampini   PetscFunctionReturn(0);
35946947451fSStefano Zampini }
35956947451fSStefano Zampini 
35960f74d2c1SSatish Balay /*@
35976947451fSStefano Zampini    MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecWrite().
35986947451fSStefano Zampini 
35996947451fSStefano Zampini    Collective
36006947451fSStefano Zampini 
36015ea7661aSPierre Jolivet    Input Parameters:
36026947451fSStefano Zampini +  mat - the Mat object
36036947451fSStefano Zampini .  col - the column index
3604742765d3SMatthew Knepley -  v - the Vec object (may be NULL)
36056947451fSStefano Zampini 
36066947451fSStefano Zampini    Level: intermediate
36076947451fSStefano Zampini 
360847d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`,`MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`
36096947451fSStefano Zampini @*/
3610d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A, PetscInt col, Vec *v)
3611d71ae5a4SJacob Faibussowitsch {
36126947451fSStefano Zampini   PetscFunctionBegin;
36136947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
36146947451fSStefano Zampini   PetscValidType(A, 1);
36156947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
361608401ef6SPierre Jolivet   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
3617aed4548fSBarry 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);
3618cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v));
36196947451fSStefano Zampini   PetscFunctionReturn(0);
36206947451fSStefano Zampini }
36215ea7661aSPierre Jolivet 
36220f74d2c1SSatish Balay /*@
3623a2748737SPierre Jolivet    MatDenseGetSubMatrix - Gives access to a block of rows and columns of a dense matrix, represented as a Mat.
36245ea7661aSPierre Jolivet 
36255ea7661aSPierre Jolivet    Collective
36265ea7661aSPierre Jolivet 
36275ea7661aSPierre Jolivet    Input Parameters:
36285ea7661aSPierre Jolivet +  mat - the Mat object
3629a2748737SPierre Jolivet .  rbegin - the first global row index in the block (if PETSC_DECIDE, is 0)
3630a2748737SPierre Jolivet .  rend - the global row index past the last one in the block (if PETSC_DECIDE, is M)
3631a2748737SPierre Jolivet .  cbegin - the first global column index in the block (if PETSC_DECIDE, is 0)
3632a2748737SPierre Jolivet -  cend - the global column index past the last one in the block (if PETSC_DECIDE, is N)
36335ea7661aSPierre Jolivet 
36345ea7661aSPierre Jolivet    Output Parameter:
36355ea7661aSPierre Jolivet .  v - the matrix
36365ea7661aSPierre Jolivet 
36375ea7661aSPierre Jolivet    Notes:
36385ea7661aSPierre Jolivet      The matrix is owned by PETSc. Users need to call MatDenseRestoreSubMatrix() when the matrix is no longer needed.
363911a5261eSBarry Smith 
3640a2748737SPierre 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.
36415ea7661aSPierre Jolivet 
36425ea7661aSPierre Jolivet    Level: intermediate
36435ea7661aSPierre Jolivet 
364447d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreSubMatrix()`
36455ea7661aSPierre Jolivet @*/
3646d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v)
3647d71ae5a4SJacob Faibussowitsch {
36485ea7661aSPierre Jolivet   PetscFunctionBegin;
36495ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
36505ea7661aSPierre Jolivet   PetscValidType(A, 1);
3651a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, rbegin, 2);
3652a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, rend, 3);
3653a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, cbegin, 4);
3654a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, cend, 5);
3655a2748737SPierre Jolivet   PetscValidPointer(v, 6);
3656a2748737SPierre Jolivet   if (rbegin == PETSC_DECIDE) rbegin = 0;
3657a2748737SPierre Jolivet   if (rend == PETSC_DECIDE) rend = A->rmap->N;
3658a2748737SPierre Jolivet   if (cbegin == PETSC_DECIDE) cbegin = 0;
3659a2748737SPierre Jolivet   if (cend == PETSC_DECIDE) cend = A->cmap->N;
366028b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
3661a2748737SPierre 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);
3662a2748737SPierre 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);
3663a2748737SPierre 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);
3664a2748737SPierre 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);
3665a2748737SPierre Jolivet   PetscUseMethod(A, "MatDenseGetSubMatrix_C", (Mat, PetscInt, PetscInt, PetscInt, PetscInt, Mat *), (A, rbegin, rend, cbegin, cend, v));
36665ea7661aSPierre Jolivet   PetscFunctionReturn(0);
36675ea7661aSPierre Jolivet }
36685ea7661aSPierre Jolivet 
36690f74d2c1SSatish Balay /*@
36705ea7661aSPierre Jolivet    MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from MatDenseGetSubMatrix().
36715ea7661aSPierre Jolivet 
36725ea7661aSPierre Jolivet    Collective
36735ea7661aSPierre Jolivet 
36745ea7661aSPierre Jolivet    Input Parameters:
36755ea7661aSPierre Jolivet +  mat - the Mat object
3676742765d3SMatthew Knepley -  v - the Mat object (may be NULL)
36775ea7661aSPierre Jolivet 
36785ea7661aSPierre Jolivet    Level: intermediate
36795ea7661aSPierre Jolivet 
368047d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseGetSubMatrix()`
36815ea7661aSPierre Jolivet @*/
3682d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix(Mat A, Mat *v)
3683d71ae5a4SJacob Faibussowitsch {
36845ea7661aSPierre Jolivet   PetscFunctionBegin;
36855ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
36865ea7661aSPierre Jolivet   PetscValidType(A, 1);
36875ea7661aSPierre Jolivet   PetscValidPointer(v, 2);
3688cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreSubMatrix_C", (Mat, Mat *), (A, v));
36895ea7661aSPierre Jolivet   PetscFunctionReturn(0);
36905ea7661aSPierre Jolivet }
36918a9c020eSBarry Smith 
36928a9c020eSBarry Smith #include <petscblaslapack.h>
36938a9c020eSBarry Smith #include <petsc/private/kernels/blockinvert.h>
36948a9c020eSBarry Smith 
3695d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseInvert(Mat A)
3696d71ae5a4SJacob Faibussowitsch {
36978a9c020eSBarry Smith   Mat_SeqDense   *a              = (Mat_SeqDense *)A->data;
36988a9c020eSBarry Smith   PetscInt        bs             = A->rmap->n;
36998a9c020eSBarry Smith   MatScalar      *values         = a->v;
37008a9c020eSBarry Smith   const PetscReal shift          = 0.0;
37018a9c020eSBarry Smith   PetscBool       allowzeropivot = PetscNot(A->erroriffailure), zeropivotdetected = PETSC_FALSE;
37028a9c020eSBarry Smith 
37038a9c020eSBarry Smith   PetscFunctionBegin;
37048a9c020eSBarry Smith   /* factor and invert each block */
37058a9c020eSBarry Smith   switch (bs) {
3706d71ae5a4SJacob Faibussowitsch   case 1:
3707d71ae5a4SJacob Faibussowitsch     values[0] = (PetscScalar)1.0 / (values[0] + shift);
3708d71ae5a4SJacob Faibussowitsch     break;
37098a9c020eSBarry Smith   case 2:
37108a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_2(values, shift, allowzeropivot, &zeropivotdetected));
37118a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
37128a9c020eSBarry Smith     break;
37138a9c020eSBarry Smith   case 3:
37148a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_3(values, shift, allowzeropivot, &zeropivotdetected));
37158a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
37168a9c020eSBarry Smith     break;
37178a9c020eSBarry Smith   case 4:
37188a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_4(values, shift, allowzeropivot, &zeropivotdetected));
37198a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
37208a9c020eSBarry Smith     break;
37219371c9d4SSatish Balay   case 5: {
37228a9c020eSBarry Smith     PetscScalar work[25];
37238a9c020eSBarry Smith     PetscInt    ipvt[5];
37248a9c020eSBarry Smith 
37258a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_5(values, ipvt, work, shift, allowzeropivot, &zeropivotdetected));
37268a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
37279371c9d4SSatish Balay   } break;
37288a9c020eSBarry Smith   case 6:
37298a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_6(values, shift, allowzeropivot, &zeropivotdetected));
37308a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
37318a9c020eSBarry Smith     break;
37328a9c020eSBarry Smith   case 7:
37338a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_7(values, shift, allowzeropivot, &zeropivotdetected));
37348a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
37358a9c020eSBarry Smith     break;
37369371c9d4SSatish Balay   default: {
37378a9c020eSBarry Smith     PetscInt    *v_pivots, *IJ, j;
37388a9c020eSBarry Smith     PetscScalar *v_work;
37398a9c020eSBarry Smith 
37408a9c020eSBarry Smith     PetscCall(PetscMalloc3(bs, &v_work, bs, &v_pivots, bs, &IJ));
3741ad540459SPierre Jolivet     for (j = 0; j < bs; j++) IJ[j] = j;
37428a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A(bs, values, v_pivots, v_work, allowzeropivot, &zeropivotdetected));
37438a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
37448a9c020eSBarry Smith     PetscCall(PetscFree3(v_work, v_pivots, IJ));
37458a9c020eSBarry Smith   }
37468a9c020eSBarry Smith   }
37478a9c020eSBarry Smith   PetscFunctionReturn(0);
37488a9c020eSBarry Smith }
3749