xref: /petsc/src/mat/impls/dense/seq/dense.c (revision 4dfa11a44d5adf2389f1d3acbc8f3c1116dc6c3a)
167e560aaSBarry Smith /*
267e560aaSBarry Smith      Defines the basic matrix operations for sequential dense.
367e560aaSBarry Smith */
4289bc588SBarry Smith 
5dec5eb66SMatthew G Knepley #include <../src/mat/impls/dense/seq/dense.h> /*I "petscmat.h" I*/
6c6db04a5SJed Brown #include <petscblaslapack.h>
76a63e612SBarry Smith #include <../src/mat/impls/aij/seq/aij.h>
8b2573a8aSBarry Smith 
99371c9d4SSatish Balay PetscErrorCode MatSeqDenseSymmetrize_Private(Mat A, PetscBool hermitian) {
108c178816SStefano Zampini   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
118c178816SStefano Zampini   PetscInt      j, k, n = A->rmap->n;
12ca15aa20SStefano Zampini   PetscScalar  *v;
138c178816SStefano Zampini 
148c178816SStefano Zampini   PetscFunctionBegin;
1508401ef6SPierre Jolivet   PetscCheck(A->rmap->n == A->cmap->n, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Cannot symmetrize a rectangular matrix");
169566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
178c178816SStefano Zampini   if (!hermitian) {
188c178816SStefano Zampini     for (k = 0; k < n; k++) {
19ad540459SPierre Jolivet       for (j = k; j < n; j++) v[j * mat->lda + k] = v[k * mat->lda + j];
208c178816SStefano Zampini     }
218c178816SStefano Zampini   } else {
228c178816SStefano Zampini     for (k = 0; k < n; k++) {
23ad540459SPierre Jolivet       for (j = k; j < n; j++) v[j * mat->lda + k] = PetscConj(v[k * mat->lda + j]);
248c178816SStefano Zampini     }
258c178816SStefano Zampini   }
269566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
278c178816SStefano Zampini   PetscFunctionReturn(0);
288c178816SStefano Zampini }
298c178816SStefano Zampini 
309371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode MatSeqDenseInvertFactors_Private(Mat A) {
318c178816SStefano Zampini   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
328c178816SStefano Zampini   PetscBLASInt  info, n;
338c178816SStefano Zampini 
348c178816SStefano Zampini   PetscFunctionBegin;
358c178816SStefano Zampini   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
369566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
378c178816SStefano Zampini   if (A->factortype == MAT_FACTOR_LU) {
3828b400f6SJacob Faibussowitsch     PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present");
398c178816SStefano Zampini     if (!mat->fwork) {
408c178816SStefano Zampini       mat->lfwork = n;
419566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
428c178816SStefano Zampini     }
439566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
44792fecdfSBarry Smith     PetscCallBLAS("LAPACKgetri", LAPACKgetri_(&n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info));
459566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
469566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0));
478c178816SStefano Zampini   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
48b94d7dedSBarry Smith     if (A->spd == PETSC_BOOL3_TRUE) {
499566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
50792fecdfSBarry Smith       PetscCallBLAS("LAPACKpotri", LAPACKpotri_("L", &n, mat->v, &mat->lda, &info));
519566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
529566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_TRUE));
538c178816SStefano Zampini #if defined(PETSC_USE_COMPLEX)
54b94d7dedSBarry Smith     } else if (A->hermitian == PETSC_BOOL3_TRUE) {
5528b400f6SJacob Faibussowitsch       PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present");
5628b400f6SJacob Faibussowitsch       PetscCheck(mat->fwork, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Fwork not present");
579566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
58792fecdfSBarry Smith       PetscCallBLAS("LAPACKhetri", LAPACKhetri_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &info));
599566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
609566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_TRUE));
618c178816SStefano Zampini #endif
628c178816SStefano Zampini     } else { /* symmetric case */
6328b400f6SJacob Faibussowitsch       PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present");
6428b400f6SJacob Faibussowitsch       PetscCheck(mat->fwork, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Fwork not present");
659566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
66792fecdfSBarry Smith       PetscCallBLAS("LAPACKsytri", LAPACKsytri_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &info));
679566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
689566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_FALSE));
698c178816SStefano Zampini     }
7028b400f6SJacob Faibussowitsch     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad Inversion: zero pivot in row %" PetscInt_FMT, (PetscInt)info - 1);
719566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0));
728c178816SStefano Zampini   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Matrix must be factored to solve");
738c178816SStefano Zampini 
748c178816SStefano Zampini   A->ops->solve             = NULL;
758c178816SStefano Zampini   A->ops->matsolve          = NULL;
768c178816SStefano Zampini   A->ops->solvetranspose    = NULL;
778c178816SStefano Zampini   A->ops->matsolvetranspose = NULL;
788c178816SStefano Zampini   A->ops->solveadd          = NULL;
798c178816SStefano Zampini   A->ops->solvetransposeadd = NULL;
808c178816SStefano Zampini   A->factortype             = MAT_FACTOR_NONE;
819566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
828c178816SStefano Zampini   PetscFunctionReturn(0);
838c178816SStefano Zampini }
848c178816SStefano Zampini 
859371c9d4SSatish Balay PetscErrorCode MatZeroRowsColumns_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) {
863f49a652SStefano Zampini   Mat_SeqDense      *l = (Mat_SeqDense *)A->data;
873f49a652SStefano Zampini   PetscInt           m = l->lda, n = A->cmap->n, r = A->rmap->n, i, j;
88ca15aa20SStefano Zampini   PetscScalar       *slot, *bb, *v;
893f49a652SStefano Zampini   const PetscScalar *xx;
903f49a652SStefano Zampini 
913f49a652SStefano Zampini   PetscFunctionBegin;
9276bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
933f49a652SStefano Zampini     for (i = 0; i < N; i++) {
9408401ef6SPierre Jolivet       PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed");
9508401ef6SPierre 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);
9608401ef6SPierre 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);
973f49a652SStefano Zampini     }
9876bd3646SJed Brown   }
99ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
1003f49a652SStefano Zampini 
1013f49a652SStefano Zampini   /* fix right hand side if needed */
1023f49a652SStefano Zampini   if (x && b) {
1036c4d906cSStefano Zampini     Vec xt;
1046c4d906cSStefano Zampini 
10508401ef6SPierre Jolivet     PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices");
1069566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(x, &xt));
1079566063dSJacob Faibussowitsch     PetscCall(VecCopy(x, xt));
1089566063dSJacob Faibussowitsch     PetscCall(VecScale(xt, -1.0));
1099566063dSJacob Faibussowitsch     PetscCall(MatMultAdd(A, xt, b, b));
1109566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&xt));
1119566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(x, &xx));
1129566063dSJacob Faibussowitsch     PetscCall(VecGetArray(b, &bb));
1133f49a652SStefano Zampini     for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]];
1149566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(x, &xx));
1159566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(b, &bb));
1163f49a652SStefano Zampini   }
1173f49a652SStefano Zampini 
1189566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
1193f49a652SStefano Zampini   for (i = 0; i < N; i++) {
120ca15aa20SStefano Zampini     slot = v + rows[i] * m;
1219566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(slot, r));
1223f49a652SStefano Zampini   }
1233f49a652SStefano Zampini   for (i = 0; i < N; i++) {
124ca15aa20SStefano Zampini     slot = v + rows[i];
1259371c9d4SSatish Balay     for (j = 0; j < n; j++) {
1269371c9d4SSatish Balay       *slot = 0.0;
1279371c9d4SSatish Balay       slot += m;
1289371c9d4SSatish Balay     }
1293f49a652SStefano Zampini   }
1303f49a652SStefano Zampini   if (diag != 0.0) {
13108401ef6SPierre Jolivet     PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices");
1323f49a652SStefano Zampini     for (i = 0; i < N; i++) {
133ca15aa20SStefano Zampini       slot  = v + (m + 1) * rows[i];
1343f49a652SStefano Zampini       *slot = diag;
1353f49a652SStefano Zampini     }
1363f49a652SStefano Zampini   }
1379566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
1383f49a652SStefano Zampini   PetscFunctionReturn(0);
1393f49a652SStefano Zampini }
1403f49a652SStefano Zampini 
1419371c9d4SSatish Balay PetscErrorCode MatPtAPNumeric_SeqDense_SeqDense(Mat A, Mat P, Mat C) {
142abc3b08eSStefano Zampini   Mat_SeqDense *c = (Mat_SeqDense *)(C->data);
143abc3b08eSStefano Zampini 
144abc3b08eSStefano Zampini   PetscFunctionBegin;
145ca15aa20SStefano Zampini   if (c->ptapwork) {
1469566063dSJacob Faibussowitsch     PetscCall((*C->ops->matmultnumeric)(A, P, c->ptapwork));
1479566063dSJacob Faibussowitsch     PetscCall((*C->ops->transposematmultnumeric)(P, c->ptapwork, C));
1484222ddf1SHong Zhang   } else SETERRQ(PetscObjectComm((PetscObject)C), PETSC_ERR_SUP, "Must call MatPtAPSymbolic_SeqDense_SeqDense() first");
149abc3b08eSStefano Zampini   PetscFunctionReturn(0);
150abc3b08eSStefano Zampini }
151abc3b08eSStefano Zampini 
1529371c9d4SSatish Balay PetscErrorCode MatPtAPSymbolic_SeqDense_SeqDense(Mat A, Mat P, PetscReal fill, Mat C) {
153abc3b08eSStefano Zampini   Mat_SeqDense *c;
1547a3c3d58SStefano Zampini   PetscBool     cisdense;
155abc3b08eSStefano Zampini 
156abc3b08eSStefano Zampini   PetscFunctionBegin;
1579566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C, P->cmap->n, P->cmap->n, P->cmap->N, P->cmap->N));
1589566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, ""));
1597a3c3d58SStefano Zampini   if (!cisdense) {
1607a3c3d58SStefano Zampini     PetscBool flg;
1617a3c3d58SStefano Zampini 
1629566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)P, ((PetscObject)A)->type_name, &flg));
1639566063dSJacob Faibussowitsch     PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE));
1647a3c3d58SStefano Zampini   }
1659566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
1664222ddf1SHong Zhang   c = (Mat_SeqDense *)C->data;
1679566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &c->ptapwork));
1689566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(c->ptapwork, A->rmap->n, P->cmap->n, A->rmap->N, P->cmap->N));
1699566063dSJacob Faibussowitsch   PetscCall(MatSetType(c->ptapwork, ((PetscObject)C)->type_name));
1709566063dSJacob Faibussowitsch   PetscCall(MatSetUp(c->ptapwork));
171abc3b08eSStefano Zampini   PetscFunctionReturn(0);
172abc3b08eSStefano Zampini }
173abc3b08eSStefano Zampini 
1749371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) {
175a13144ffSStefano Zampini   Mat              B = NULL;
176b49cda9fSStefano Zampini   Mat_SeqAIJ      *a = (Mat_SeqAIJ *)A->data;
177b49cda9fSStefano Zampini   Mat_SeqDense    *b;
178b49cda9fSStefano Zampini   PetscInt        *ai = a->i, *aj = a->j, m = A->rmap->N, n = A->cmap->N, i;
1792e5835c6SStefano Zampini   const MatScalar *av;
180a13144ffSStefano Zampini   PetscBool        isseqdense;
181b49cda9fSStefano Zampini 
182b49cda9fSStefano Zampini   PetscFunctionBegin;
183a13144ffSStefano Zampini   if (reuse == MAT_REUSE_MATRIX) {
1849566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)*newmat, MATSEQDENSE, &isseqdense));
18528b400f6SJacob Faibussowitsch     PetscCheck(isseqdense, PetscObjectComm((PetscObject)*newmat), PETSC_ERR_USER, "Cannot reuse matrix of type %s", ((PetscObject)(*newmat))->type_name);
186a13144ffSStefano Zampini   }
187a13144ffSStefano Zampini   if (reuse != MAT_REUSE_MATRIX) {
1889566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B));
1899566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(B, m, n, m, n));
1909566063dSJacob Faibussowitsch     PetscCall(MatSetType(B, MATSEQDENSE));
1919566063dSJacob Faibussowitsch     PetscCall(MatSeqDenseSetPreallocation(B, NULL));
192b49cda9fSStefano Zampini     b = (Mat_SeqDense *)(B->data);
193a13144ffSStefano Zampini   } else {
194a13144ffSStefano Zampini     b = (Mat_SeqDense *)((*newmat)->data);
1959566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(b->v, m * n));
196a13144ffSStefano Zampini   }
1979566063dSJacob Faibussowitsch   PetscCall(MatSeqAIJGetArrayRead(A, &av));
198b49cda9fSStefano Zampini   for (i = 0; i < m; i++) {
199b49cda9fSStefano Zampini     PetscInt j;
200b49cda9fSStefano Zampini     for (j = 0; j < ai[1] - ai[0]; j++) {
201b49cda9fSStefano Zampini       b->v[*aj * m + i] = *av;
202b49cda9fSStefano Zampini       aj++;
203b49cda9fSStefano Zampini       av++;
204b49cda9fSStefano Zampini     }
205b49cda9fSStefano Zampini     ai++;
206b49cda9fSStefano Zampini   }
2079566063dSJacob Faibussowitsch   PetscCall(MatSeqAIJRestoreArrayRead(A, &av));
208b49cda9fSStefano Zampini 
209511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
2109566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY));
2119566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY));
2129566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A, &B));
213b49cda9fSStefano Zampini   } else {
214a13144ffSStefano Zampini     if (B) *newmat = B;
2159566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(*newmat, MAT_FINAL_ASSEMBLY));
2169566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(*newmat, MAT_FINAL_ASSEMBLY));
217b49cda9fSStefano Zampini   }
218b49cda9fSStefano Zampini   PetscFunctionReturn(0);
219b49cda9fSStefano Zampini }
220b49cda9fSStefano Zampini 
2219371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatConvert_SeqDense_SeqAIJ(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) {
2226d4ec7b0SPierre Jolivet   Mat           B = NULL;
2236a63e612SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
2249399e1b8SMatthew G. Knepley   PetscInt      i, j;
2259399e1b8SMatthew G. Knepley   PetscInt     *rows, *nnz;
2269399e1b8SMatthew G. Knepley   MatScalar    *aa = a->v, *vals;
2276a63e612SBarry Smith 
2286a63e612SBarry Smith   PetscFunctionBegin;
2299566063dSJacob Faibussowitsch   PetscCall(PetscCalloc3(A->rmap->n, &rows, A->rmap->n, &nnz, A->rmap->n, &vals));
2306d4ec7b0SPierre Jolivet   if (reuse != MAT_REUSE_MATRIX) {
2319566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B));
2329566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(B, A->rmap->n, A->cmap->n, A->rmap->N, A->cmap->N));
2339566063dSJacob Faibussowitsch     PetscCall(MatSetType(B, MATSEQAIJ));
2349399e1b8SMatthew G. Knepley     for (j = 0; j < A->cmap->n; j++) {
2359371c9d4SSatish Balay       for (i = 0; i < A->rmap->n; i++)
2369371c9d4SSatish Balay         if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) ++nnz[i];
2376a63e612SBarry Smith       aa += a->lda;
2386a63e612SBarry Smith     }
2399566063dSJacob Faibussowitsch     PetscCall(MatSeqAIJSetPreallocation(B, PETSC_DETERMINE, nnz));
2406d4ec7b0SPierre Jolivet   } else B = *newmat;
2419399e1b8SMatthew G. Knepley   aa = a->v;
2429399e1b8SMatthew G. Knepley   for (j = 0; j < A->cmap->n; j++) {
2439399e1b8SMatthew G. Knepley     PetscInt numRows = 0;
2449371c9d4SSatish Balay     for (i = 0; i < A->rmap->n; i++)
2459371c9d4SSatish Balay       if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) {
2469371c9d4SSatish Balay         rows[numRows]   = i;
2479371c9d4SSatish Balay         vals[numRows++] = aa[i];
2489371c9d4SSatish Balay       }
2499566063dSJacob Faibussowitsch     PetscCall(MatSetValues(B, numRows, rows, 1, &j, vals, INSERT_VALUES));
2509399e1b8SMatthew G. Knepley     aa += a->lda;
2519399e1b8SMatthew G. Knepley   }
2529566063dSJacob Faibussowitsch   PetscCall(PetscFree3(rows, nnz, vals));
2539566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY));
2549566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY));
2556a63e612SBarry Smith 
256511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
2579566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A, &B));
2586d4ec7b0SPierre Jolivet   } else if (reuse != MAT_REUSE_MATRIX) *newmat = B;
2596a63e612SBarry Smith   PetscFunctionReturn(0);
2606a63e612SBarry Smith }
2616a63e612SBarry Smith 
2629371c9d4SSatish Balay PetscErrorCode MatAXPY_SeqDense(Mat Y, PetscScalar alpha, Mat X, MatStructure str) {
2631987afe7SBarry Smith   Mat_SeqDense      *x = (Mat_SeqDense *)X->data, *y = (Mat_SeqDense *)Y->data;
264ca15aa20SStefano Zampini   const PetscScalar *xv;
265ca15aa20SStefano Zampini   PetscScalar       *yv;
26623fff9afSBarry Smith   PetscBLASInt       N, m, ldax = 0, lday = 0, one = 1;
2673a40ed3dSBarry Smith 
2683a40ed3dSBarry Smith   PetscFunctionBegin;
2699566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(X, &xv));
2709566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(Y, &yv));
2719566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(X->rmap->n * X->cmap->n, &N));
2729566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(X->rmap->n, &m));
2739566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(x->lda, &ldax));
2749566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(y->lda, &lday));
275a5ce6ee0Svictorle   if (ldax > m || lday > m) {
276ca15aa20SStefano Zampini     PetscInt j;
277ca15aa20SStefano Zampini 
27848a46eb9SPierre Jolivet     for (j = 0; j < X->cmap->n; j++) PetscCallBLAS("BLASaxpy", BLASaxpy_(&m, &alpha, xv + j * ldax, &one, yv + j * lday, &one));
279a5ce6ee0Svictorle   } else {
280792fecdfSBarry Smith     PetscCallBLAS("BLASaxpy", BLASaxpy_(&N, &alpha, xv, &one, yv, &one));
281a5ce6ee0Svictorle   }
2829566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(X, &xv));
2839566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(Y, &yv));
2849566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(PetscMax(2.0 * N - 1, 0)));
2853a40ed3dSBarry Smith   PetscFunctionReturn(0);
2861987afe7SBarry Smith }
2871987afe7SBarry Smith 
2889371c9d4SSatish Balay static PetscErrorCode MatGetInfo_SeqDense(Mat A, MatInfoType flag, MatInfo *info) {
289ca15aa20SStefano Zampini   PetscLogDouble N = A->rmap->n * A->cmap->n;
2903a40ed3dSBarry Smith 
2913a40ed3dSBarry Smith   PetscFunctionBegin;
2924e220ebcSLois Curfman McInnes   info->block_size        = 1.0;
293ca15aa20SStefano Zampini   info->nz_allocated      = N;
294ca15aa20SStefano Zampini   info->nz_used           = N;
295ca15aa20SStefano Zampini   info->nz_unneeded       = 0;
296ca15aa20SStefano Zampini   info->assemblies        = A->num_ass;
2974e220ebcSLois Curfman McInnes   info->mallocs           = 0;
298*4dfa11a4SJacob Faibussowitsch   info->memory            = 0; /* REVIEW ME */
2994e220ebcSLois Curfman McInnes   info->fill_ratio_given  = 0;
3004e220ebcSLois Curfman McInnes   info->fill_ratio_needed = 0;
3014e220ebcSLois Curfman McInnes   info->factor_mallocs    = 0;
3023a40ed3dSBarry Smith   PetscFunctionReturn(0);
303289bc588SBarry Smith }
304289bc588SBarry Smith 
3059371c9d4SSatish Balay PetscErrorCode MatScale_SeqDense(Mat A, PetscScalar alpha) {
306273d9f13SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
307ca15aa20SStefano Zampini   PetscScalar  *v;
30823fff9afSBarry Smith   PetscBLASInt  one = 1, j, nz, lda = 0;
30980cd9d93SLois Curfman McInnes 
3103a40ed3dSBarry Smith   PetscFunctionBegin;
3119566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
3129566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(a->lda, &lda));
313d0f46423SBarry Smith   if (lda > A->rmap->n) {
3149566063dSJacob Faibussowitsch     PetscCall(PetscBLASIntCast(A->rmap->n, &nz));
31548a46eb9SPierre Jolivet     for (j = 0; j < A->cmap->n; j++) PetscCallBLAS("BLASscal", BLASscal_(&nz, &alpha, v + j * lda, &one));
316a5ce6ee0Svictorle   } else {
3179566063dSJacob Faibussowitsch     PetscCall(PetscBLASIntCast(A->rmap->n * A->cmap->n, &nz));
318792fecdfSBarry Smith     PetscCallBLAS("BLASscal", BLASscal_(&nz, &alpha, v, &one));
319a5ce6ee0Svictorle   }
32004cbc005SJose E. Roman   PetscCall(PetscLogFlops(A->rmap->n * A->cmap->n));
3219566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
3223a40ed3dSBarry Smith   PetscFunctionReturn(0);
32380cd9d93SLois Curfman McInnes }
32480cd9d93SLois Curfman McInnes 
3259371c9d4SSatish Balay PetscErrorCode MatShift_SeqDense(Mat A, PetscScalar alpha) {
3262f605a99SJose E. Roman   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
3272f605a99SJose E. Roman   PetscScalar  *v;
3282f605a99SJose E. Roman   PetscInt      j, k;
3292f605a99SJose E. Roman 
3302f605a99SJose E. Roman   PetscFunctionBegin;
3312f605a99SJose E. Roman   PetscCall(MatDenseGetArray(A, &v));
3322f605a99SJose E. Roman   k = PetscMin(A->rmap->n, A->cmap->n);
3332f605a99SJose E. Roman   for (j = 0; j < k; j++) v[j + j * a->lda] += alpha;
3342f605a99SJose E. Roman   PetscCall(PetscLogFlops(k));
3352f605a99SJose E. Roman   PetscCall(MatDenseRestoreArray(A, &v));
3362f605a99SJose E. Roman   PetscFunctionReturn(0);
3372f605a99SJose E. Roman }
3382f605a99SJose E. Roman 
3399371c9d4SSatish Balay static PetscErrorCode MatIsHermitian_SeqDense(Mat A, PetscReal rtol, PetscBool *fl) {
3401cbb95d3SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
341ca15aa20SStefano Zampini   PetscInt           i, j, m = A->rmap->n, N = a->lda;
342ca15aa20SStefano Zampini   const PetscScalar *v;
3431cbb95d3SBarry Smith 
3441cbb95d3SBarry Smith   PetscFunctionBegin;
3451cbb95d3SBarry Smith   *fl = PETSC_FALSE;
346d0f46423SBarry Smith   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
3479566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &v));
3481cbb95d3SBarry Smith   for (i = 0; i < m; i++) {
349ca15aa20SStefano Zampini     for (j = i; j < m; j++) {
350ad540459SPierre Jolivet       if (PetscAbsScalar(v[i + j * N] - PetscConj(v[j + i * N])) > rtol) goto restore;
3511cbb95d3SBarry Smith     }
352637a0070SStefano Zampini   }
3531cbb95d3SBarry Smith   *fl = PETSC_TRUE;
354637a0070SStefano Zampini restore:
3559566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &v));
356637a0070SStefano Zampini   PetscFunctionReturn(0);
357637a0070SStefano Zampini }
358637a0070SStefano Zampini 
3599371c9d4SSatish Balay static PetscErrorCode MatIsSymmetric_SeqDense(Mat A, PetscReal rtol, PetscBool *fl) {
360637a0070SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
361637a0070SStefano Zampini   PetscInt           i, j, m = A->rmap->n, N = a->lda;
362637a0070SStefano Zampini   const PetscScalar *v;
363637a0070SStefano Zampini 
364637a0070SStefano Zampini   PetscFunctionBegin;
365637a0070SStefano Zampini   *fl = PETSC_FALSE;
366637a0070SStefano Zampini   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
3679566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &v));
368637a0070SStefano Zampini   for (i = 0; i < m; i++) {
369637a0070SStefano Zampini     for (j = i; j < m; j++) {
370ad540459SPierre Jolivet       if (PetscAbsScalar(v[i + j * N] - v[j + i * N]) > rtol) goto restore;
371637a0070SStefano Zampini     }
372637a0070SStefano Zampini   }
373637a0070SStefano Zampini   *fl = PETSC_TRUE;
374637a0070SStefano Zampini restore:
3759566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &v));
3761cbb95d3SBarry Smith   PetscFunctionReturn(0);
3771cbb95d3SBarry Smith }
3781cbb95d3SBarry Smith 
3799371c9d4SSatish Balay PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi, Mat A, MatDuplicateOption cpvalues) {
380ca15aa20SStefano Zampini   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
38123fc5dcaSStefano Zampini   PetscInt      lda = (PetscInt)mat->lda, j, m, nlda = lda;
38275f6d85dSStefano Zampini   PetscBool     isdensecpu;
383b24902e0SBarry Smith 
384b24902e0SBarry Smith   PetscFunctionBegin;
3859566063dSJacob Faibussowitsch   PetscCall(PetscLayoutReference(A->rmap, &newi->rmap));
3869566063dSJacob Faibussowitsch   PetscCall(PetscLayoutReference(A->cmap, &newi->cmap));
38723fc5dcaSStefano Zampini   if (cpvalues == MAT_SHARE_NONZERO_PATTERN) { /* propagate LDA */
3889566063dSJacob Faibussowitsch     PetscCall(MatDenseSetLDA(newi, lda));
38923fc5dcaSStefano Zampini   }
3909566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)newi, MATSEQDENSE, &isdensecpu));
3919566063dSJacob Faibussowitsch   if (isdensecpu) PetscCall(MatSeqDenseSetPreallocation(newi, NULL));
392b24902e0SBarry Smith   if (cpvalues == MAT_COPY_VALUES) {
393ca15aa20SStefano Zampini     const PetscScalar *av;
394ca15aa20SStefano Zampini     PetscScalar       *v;
395ca15aa20SStefano Zampini 
3969566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A, &av));
3979566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayWrite(newi, &v));
3989566063dSJacob Faibussowitsch     PetscCall(MatDenseGetLDA(newi, &nlda));
399d0f46423SBarry Smith     m = A->rmap->n;
40023fc5dcaSStefano Zampini     if (lda > m || nlda > m) {
40148a46eb9SPierre Jolivet       for (j = 0; j < A->cmap->n; j++) PetscCall(PetscArraycpy(v + j * nlda, av + j * lda, m));
402b24902e0SBarry Smith     } else {
4039566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(v, av, A->rmap->n * A->cmap->n));
404b24902e0SBarry Smith     }
4059566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayWrite(newi, &v));
4069566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A, &av));
407b24902e0SBarry Smith   }
408b24902e0SBarry Smith   PetscFunctionReturn(0);
409b24902e0SBarry Smith }
410b24902e0SBarry Smith 
4119371c9d4SSatish Balay PetscErrorCode MatDuplicate_SeqDense(Mat A, MatDuplicateOption cpvalues, Mat *newmat) {
4123a40ed3dSBarry Smith   PetscFunctionBegin;
4139566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), newmat));
4149566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*newmat, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n));
4159566063dSJacob Faibussowitsch   PetscCall(MatSetType(*newmat, ((PetscObject)A)->type_name));
4169566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(*newmat, A, cpvalues));
417b24902e0SBarry Smith   PetscFunctionReturn(0);
418b24902e0SBarry Smith }
419b24902e0SBarry Smith 
4209371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_Internal_LU(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T) {
421c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
4224396437dSToby Isaac   PetscBLASInt  info;
42367e560aaSBarry Smith 
4243a40ed3dSBarry Smith   PetscFunctionBegin;
4259566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
426792fecdfSBarry Smith   PetscCallBLAS("LAPACKgetrs", LAPACKgetrs_(T ? "T" : "N", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info));
4279566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
42805fcb23eSStefano Zampini   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "GETRS - Bad solve %d", (int)info);
4299566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m)));
4304396437dSToby Isaac   PetscFunctionReturn(0);
4314396437dSToby Isaac }
4324396437dSToby Isaac 
4334396437dSToby Isaac static PetscErrorCode MatConjugate_SeqDense(Mat);
4344396437dSToby Isaac 
4359371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_Internal_Cholesky(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T) {
4364396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
4374396437dSToby Isaac   PetscBLASInt  info;
4384396437dSToby Isaac 
4394396437dSToby Isaac   PetscFunctionBegin;
440b94d7dedSBarry Smith   if (A->spd == PETSC_BOOL3_TRUE) {
4419566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A));
4429566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
443792fecdfSBarry Smith     PetscCallBLAS("LAPACKpotrs", LAPACKpotrs_("L", &m, &nrhs, mat->v, &mat->lda, x, &m, &info));
4449566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
44505fcb23eSStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "POTRS Bad solve %d", (int)info);
4469566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A));
447a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
448b94d7dedSBarry Smith   } else if (A->hermitian == PETSC_BOOL3_TRUE) {
4499566063dSJacob Faibussowitsch     if (T) PetscCall(MatConjugate_SeqDense(A));
4509566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
451792fecdfSBarry Smith     PetscCallBLAS("LAPACKhetrs", LAPACKhetrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info));
4529566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
45305fcb23eSStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "HETRS Bad solve %d", (int)info);
4549566063dSJacob Faibussowitsch     if (T) PetscCall(MatConjugate_SeqDense(A));
455a49dc2a2SStefano Zampini #endif
456a49dc2a2SStefano Zampini   } else { /* symmetric case */
4579566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
458792fecdfSBarry Smith     PetscCallBLAS("LAPACKsytrs", LAPACKsytrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info));
4599566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
46005fcb23eSStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "SYTRS Bad solve %d", (int)info);
461a49dc2a2SStefano Zampini   }
4629566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m)));
4634396437dSToby Isaac   PetscFunctionReturn(0);
4644396437dSToby Isaac }
46585e2c93fSHong Zhang 
4669371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k) {
4674396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
4684396437dSToby Isaac   PetscBLASInt  info;
4694396437dSToby Isaac   char          trans;
4704396437dSToby Isaac 
4714396437dSToby Isaac   PetscFunctionBegin;
4724905a7bcSToby Isaac   if (PetscDefined(USE_COMPLEX)) {
4734905a7bcSToby Isaac     trans = 'C';
4744905a7bcSToby Isaac   } else {
4754905a7bcSToby Isaac     trans = 'T';
4764905a7bcSToby Isaac   }
4779566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
47805fcb23eSStefano Zampini   { /* lwork depends on the number of right-hand sides */
47905fcb23eSStefano Zampini     PetscBLASInt nlfwork, lfwork = -1;
48005fcb23eSStefano Zampini     PetscScalar  fwork;
48105fcb23eSStefano Zampini 
482792fecdfSBarry Smith     PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info));
48305fcb23eSStefano Zampini     nlfwork = (PetscBLASInt)PetscRealPart(fwork);
48405fcb23eSStefano Zampini     if (nlfwork > mat->lfwork) {
48505fcb23eSStefano Zampini       mat->lfwork = nlfwork;
48605fcb23eSStefano Zampini       PetscCall(PetscFree(mat->fwork));
48705fcb23eSStefano Zampini       PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
48805fcb23eSStefano Zampini     }
48905fcb23eSStefano Zampini   }
490792fecdfSBarry Smith   PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info));
4919566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
49205fcb23eSStefano Zampini   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %d", (int)info);
4939566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
494792fecdfSBarry Smith   PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "N", "N", &mat->rank, &nrhs, mat->v, &mat->lda, x, &ldx, &info));
4959566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
49605fcb23eSStefano Zampini   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %d", (int)info);
4974905a7bcSToby Isaac   for (PetscInt j = 0; j < nrhs; j++) {
498ad540459SPierre Jolivet     for (PetscInt i = mat->rank; i < k; i++) x[j * ldx + i] = 0.;
4994905a7bcSToby Isaac   }
5009566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank))));
5014905a7bcSToby Isaac   PetscFunctionReturn(0);
5024905a7bcSToby Isaac }
5034905a7bcSToby Isaac 
5049371c9d4SSatish Balay static PetscErrorCode MatSolveTranspose_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k) {
5054396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
5064396437dSToby Isaac   PetscBLASInt  info;
5074396437dSToby Isaac 
5084396437dSToby Isaac   PetscFunctionBegin;
5094396437dSToby Isaac   if (A->rmap->n == A->cmap->n && mat->rank == A->rmap->n) {
5109566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
511792fecdfSBarry Smith     PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "T", "N", &m, &nrhs, mat->v, &mat->lda, x, &ldx, &info));
5129566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
51305fcb23eSStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %d", (int)info);
5149566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A));
51505fcb23eSStefano Zampini     { /* lwork depends on the number of right-hand sides */
51605fcb23eSStefano Zampini       PetscBLASInt nlfwork, lfwork = -1;
51705fcb23eSStefano Zampini       PetscScalar  fwork;
51805fcb23eSStefano Zampini 
519792fecdfSBarry Smith       PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info));
52005fcb23eSStefano Zampini       nlfwork = (PetscBLASInt)PetscRealPart(fwork);
52105fcb23eSStefano Zampini       if (nlfwork > mat->lfwork) {
52205fcb23eSStefano Zampini         mat->lfwork = nlfwork;
52305fcb23eSStefano Zampini         PetscCall(PetscFree(mat->fwork));
52405fcb23eSStefano Zampini         PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
52505fcb23eSStefano Zampini       }
52605fcb23eSStefano Zampini     }
5279566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
528792fecdfSBarry Smith     PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info));
5299566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
53005fcb23eSStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %d", (int)info);
5319566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A));
5324396437dSToby Isaac   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "QR factored matrix cannot be used for transpose solve");
5339566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank))));
5344396437dSToby Isaac   PetscFunctionReturn(0);
5354396437dSToby Isaac }
5364396437dSToby Isaac 
5379371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_SetUp(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k) {
5384396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
5394905a7bcSToby Isaac   PetscScalar  *y;
5404905a7bcSToby Isaac   PetscBLASInt  m = 0, k = 0;
5414905a7bcSToby Isaac 
5424905a7bcSToby Isaac   PetscFunctionBegin;
5439566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
5449566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &k));
5454905a7bcSToby Isaac   if (k < m) {
5469566063dSJacob Faibussowitsch     PetscCall(VecCopy(xx, mat->qrrhs));
5479566063dSJacob Faibussowitsch     PetscCall(VecGetArray(mat->qrrhs, &y));
5484905a7bcSToby Isaac   } else {
5499566063dSJacob Faibussowitsch     PetscCall(VecCopy(xx, yy));
5509566063dSJacob Faibussowitsch     PetscCall(VecGetArray(yy, &y));
5514905a7bcSToby Isaac   }
5524396437dSToby Isaac   *_y = y;
5534396437dSToby Isaac   *_k = k;
5544396437dSToby Isaac   *_m = m;
5554396437dSToby Isaac   PetscFunctionReturn(0);
5564396437dSToby Isaac }
5574396437dSToby Isaac 
5589371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_TearDown(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k) {
5594396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
56042e9364cSSatish Balay   PetscScalar  *y   = NULL;
5614396437dSToby Isaac   PetscBLASInt  m, k;
5624396437dSToby Isaac 
5634396437dSToby Isaac   PetscFunctionBegin;
5644396437dSToby Isaac   y   = *_y;
5654396437dSToby Isaac   *_y = NULL;
5664396437dSToby Isaac   k   = *_k;
5674396437dSToby Isaac   m   = *_m;
5684905a7bcSToby Isaac   if (k < m) {
5694905a7bcSToby Isaac     PetscScalar *yv;
5709566063dSJacob Faibussowitsch     PetscCall(VecGetArray(yy, &yv));
5719566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(yv, y, k));
5729566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(yy, &yv));
5739566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(mat->qrrhs, &y));
5744905a7bcSToby Isaac   } else {
5759566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(yy, &y));
5764905a7bcSToby Isaac   }
5774905a7bcSToby Isaac   PetscFunctionReturn(0);
5784905a7bcSToby Isaac }
5794905a7bcSToby Isaac 
5809371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_LU(Mat A, Vec xx, Vec yy) {
58142e9364cSSatish Balay   PetscScalar *y = NULL;
58242e9364cSSatish Balay   PetscBLASInt m = 0, k = 0;
5834396437dSToby Isaac 
5844396437dSToby Isaac   PetscFunctionBegin;
5859566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
5869566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_FALSE));
5879566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
5884396437dSToby Isaac   PetscFunctionReturn(0);
5894396437dSToby Isaac }
5904396437dSToby Isaac 
5919371c9d4SSatish Balay static PetscErrorCode MatSolveTranspose_SeqDense_LU(Mat A, Vec xx, Vec yy) {
59242e9364cSSatish Balay   PetscScalar *y = NULL;
59342e9364cSSatish Balay   PetscBLASInt m = 0, k = 0;
5944396437dSToby Isaac 
5954396437dSToby Isaac   PetscFunctionBegin;
5969566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
5979566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_TRUE));
5989566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
5994396437dSToby Isaac   PetscFunctionReturn(0);
6004396437dSToby Isaac }
6014396437dSToby Isaac 
6029371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_Cholesky(Mat A, Vec xx, Vec yy) {
603e54beecaSStefano Zampini   PetscScalar *y = NULL;
604e54beecaSStefano Zampini   PetscBLASInt m = 0, k = 0;
6054396437dSToby Isaac 
6064396437dSToby Isaac   PetscFunctionBegin;
6079566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6089566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_FALSE));
6099566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6104396437dSToby Isaac   PetscFunctionReturn(0);
6114396437dSToby Isaac }
6124396437dSToby Isaac 
6139371c9d4SSatish Balay static PetscErrorCode MatSolveTranspose_SeqDense_Cholesky(Mat A, Vec xx, Vec yy) {
614e54beecaSStefano Zampini   PetscScalar *y = NULL;
615e54beecaSStefano Zampini   PetscBLASInt m = 0, k = 0;
6164396437dSToby Isaac 
6174396437dSToby Isaac   PetscFunctionBegin;
6189566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6199566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_TRUE));
6209566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6214396437dSToby Isaac   PetscFunctionReturn(0);
6224396437dSToby Isaac }
6234396437dSToby Isaac 
6249371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_QR(Mat A, Vec xx, Vec yy) {
625e54beecaSStefano Zampini   PetscScalar *y = NULL;
626e54beecaSStefano Zampini   PetscBLASInt m = 0, k = 0;
6274396437dSToby Isaac 
6284396437dSToby Isaac   PetscFunctionBegin;
6299566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6309566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k));
6319566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6324396437dSToby Isaac   PetscFunctionReturn(0);
6334396437dSToby Isaac }
6344396437dSToby Isaac 
6359371c9d4SSatish Balay static PetscErrorCode MatSolveTranspose_SeqDense_QR(Mat A, Vec xx, Vec yy) {
63642e9364cSSatish Balay   PetscScalar *y = NULL;
63742e9364cSSatish Balay   PetscBLASInt m = 0, k = 0;
6384396437dSToby Isaac 
6394396437dSToby Isaac   PetscFunctionBegin;
6409566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6419566063dSJacob Faibussowitsch   PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k));
6429566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6434396437dSToby Isaac   PetscFunctionReturn(0);
6444396437dSToby Isaac }
6454396437dSToby Isaac 
6469371c9d4SSatish Balay static PetscErrorCode MatMatSolve_SeqDense_SetUp(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k) {
6474905a7bcSToby Isaac   const PetscScalar *b;
6484396437dSToby Isaac   PetscScalar       *y;
649bf5a80bcSToby Isaac   PetscInt           n, _ldb, _ldx;
650bf5a80bcSToby Isaac   PetscBLASInt       nrhs = 0, m = 0, k = 0, ldb = 0, ldx = 0, ldy = 0;
6514905a7bcSToby Isaac 
6524905a7bcSToby Isaac   PetscFunctionBegin;
6539371c9d4SSatish Balay   *_ldy  = 0;
6549371c9d4SSatish Balay   *_m    = 0;
6559371c9d4SSatish Balay   *_nrhs = 0;
6569371c9d4SSatish Balay   *_k    = 0;
6579371c9d4SSatish Balay   *_y    = NULL;
6589566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
6599566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &k));
6609566063dSJacob Faibussowitsch   PetscCall(MatGetSize(B, NULL, &n));
6619566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(n, &nrhs));
6629566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(B, &_ldb));
6639566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldb, &ldb));
6649566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(X, &_ldx));
6659566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldx, &ldx));
666bf5a80bcSToby Isaac   if (ldx < m) {
6679566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(B, &b));
6689566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nrhs * m, &y));
669bf5a80bcSToby Isaac     if (ldb == m) {
6709566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(y, b, ldb * nrhs));
6714905a7bcSToby Isaac     } else {
67248a46eb9SPierre Jolivet       for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * m], &b[j * ldb], m));
6734905a7bcSToby Isaac     }
674bf5a80bcSToby Isaac     ldy = m;
6759566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(B, &b));
6764905a7bcSToby Isaac   } else {
677bf5a80bcSToby Isaac     if (ldb == ldx) {
6789566063dSJacob Faibussowitsch       PetscCall(MatCopy(B, X, SAME_NONZERO_PATTERN));
6799566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(X, &y));
6804905a7bcSToby Isaac     } else {
6819566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(X, &y));
6829566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArrayRead(B, &b));
68348a46eb9SPierre Jolivet       for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * ldx], &b[j * ldb], m));
6849566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArrayRead(B, &b));
6854905a7bcSToby Isaac     }
686bf5a80bcSToby Isaac     ldy = ldx;
6874905a7bcSToby Isaac   }
6884396437dSToby Isaac   *_y    = y;
689bf5a80bcSToby Isaac   *_ldy  = ldy;
6904396437dSToby Isaac   *_k    = k;
6914396437dSToby Isaac   *_m    = m;
6924396437dSToby Isaac   *_nrhs = nrhs;
6934396437dSToby Isaac   PetscFunctionReturn(0);
6944396437dSToby Isaac }
6954396437dSToby Isaac 
6969371c9d4SSatish Balay static PetscErrorCode MatMatSolve_SeqDense_TearDown(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k) {
6974396437dSToby Isaac   PetscScalar *y;
698bf5a80bcSToby Isaac   PetscInt     _ldx;
699bf5a80bcSToby Isaac   PetscBLASInt k, ldy, nrhs, ldx = 0;
7004396437dSToby Isaac 
7014396437dSToby Isaac   PetscFunctionBegin;
7024396437dSToby Isaac   y    = *_y;
7034396437dSToby Isaac   *_y  = NULL;
7044396437dSToby Isaac   k    = *_k;
705bf5a80bcSToby Isaac   ldy  = *_ldy;
7064396437dSToby Isaac   nrhs = *_nrhs;
7079566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(X, &_ldx));
7089566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldx, &ldx));
709bf5a80bcSToby Isaac   if (ldx != ldy) {
7104905a7bcSToby Isaac     PetscScalar *xv;
7119566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArray(X, &xv));
71248a46eb9SPierre Jolivet     for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&xv[j * ldx], &y[j * ldy], k));
7139566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(X, &xv));
7149566063dSJacob Faibussowitsch     PetscCall(PetscFree(y));
7154905a7bcSToby Isaac   } else {
7169566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(X, &y));
7174905a7bcSToby Isaac   }
71885e2c93fSHong Zhang   PetscFunctionReturn(0);
71985e2c93fSHong Zhang }
72085e2c93fSHong Zhang 
7219371c9d4SSatish Balay static PetscErrorCode MatMatSolve_SeqDense_LU(Mat A, Mat B, Mat X) {
7224396437dSToby Isaac   PetscScalar *y;
723bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7244396437dSToby Isaac 
7254396437dSToby Isaac   PetscFunctionBegin;
7269566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7279566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_FALSE));
7289566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7294396437dSToby Isaac   PetscFunctionReturn(0);
7304396437dSToby Isaac }
7314396437dSToby Isaac 
7329371c9d4SSatish Balay static PetscErrorCode MatMatSolveTranspose_SeqDense_LU(Mat A, Mat B, Mat X) {
7334396437dSToby Isaac   PetscScalar *y;
734bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7354396437dSToby Isaac 
7364396437dSToby Isaac   PetscFunctionBegin;
7379566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7389566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_TRUE));
7399566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7404396437dSToby Isaac   PetscFunctionReturn(0);
7414396437dSToby Isaac }
7424396437dSToby Isaac 
7439371c9d4SSatish Balay static PetscErrorCode MatMatSolve_SeqDense_Cholesky(Mat A, Mat B, Mat X) {
7444396437dSToby Isaac   PetscScalar *y;
745bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7464396437dSToby Isaac 
7474396437dSToby Isaac   PetscFunctionBegin;
7489566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7499566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_FALSE));
7509566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7514396437dSToby Isaac   PetscFunctionReturn(0);
7524396437dSToby Isaac }
7534396437dSToby Isaac 
7549371c9d4SSatish Balay static PetscErrorCode MatMatSolveTranspose_SeqDense_Cholesky(Mat A, Mat B, Mat X) {
7554396437dSToby Isaac   PetscScalar *y;
756bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7574396437dSToby Isaac 
7584396437dSToby Isaac   PetscFunctionBegin;
7599566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7609566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_TRUE));
7619566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7624396437dSToby Isaac   PetscFunctionReturn(0);
7634396437dSToby Isaac }
7644396437dSToby Isaac 
7659371c9d4SSatish Balay static PetscErrorCode MatMatSolve_SeqDense_QR(Mat A, Mat B, Mat X) {
7664396437dSToby Isaac   PetscScalar *y;
767bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7684396437dSToby Isaac 
7694396437dSToby Isaac   PetscFunctionBegin;
7709566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7719566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k));
7729566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7734396437dSToby Isaac   PetscFunctionReturn(0);
7744396437dSToby Isaac }
7754396437dSToby Isaac 
7769371c9d4SSatish Balay static PetscErrorCode MatMatSolveTranspose_SeqDense_QR(Mat A, Mat B, Mat X) {
7774396437dSToby Isaac   PetscScalar *y;
778bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7794396437dSToby Isaac 
7804396437dSToby Isaac   PetscFunctionBegin;
7819566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7829566063dSJacob Faibussowitsch   PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k));
7839566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7844396437dSToby Isaac   PetscFunctionReturn(0);
7854396437dSToby Isaac }
7864396437dSToby Isaac 
787db4efbfdSBarry Smith /* ---------------------------------------------------------------*/
788db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots,
789db4efbfdSBarry Smith    rather than put it in the Mat->row slot.*/
7909371c9d4SSatish Balay PetscErrorCode MatLUFactor_SeqDense(Mat A, IS row, IS col, const MatFactorInfo *minfo) {
791db4efbfdSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
792db4efbfdSBarry Smith   PetscBLASInt  n, m, info;
793db4efbfdSBarry Smith 
794db4efbfdSBarry Smith   PetscFunctionBegin;
7959566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
7969566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
797*4dfa11a4SJacob Faibussowitsch   if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); }
798db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
7999566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
800792fecdfSBarry Smith   PetscCallBLAS("LAPACKgetrf", LAPACKgetrf_(&m, &n, mat->v, &mat->lda, mat->pivots, &info));
8019566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
8028e57ea43SSatish Balay 
80305fcb23eSStefano Zampini   PetscCheck(info >= 0, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to LU factorization %d", (int)info);
80405fcb23eSStefano Zampini   PetscCheck(info <= 0, PETSC_COMM_SELF, PETSC_ERR_MAT_LU_ZRPVT, "Bad LU factorization %d", (int)info);
8058208b9aeSStefano Zampini 
8064396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_LU;
8074396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_LU;
8084396437dSToby Isaac   A->ops->solvetranspose    = MatSolveTranspose_SeqDense_LU;
8094396437dSToby Isaac   A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_LU;
810d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_LU;
811db4efbfdSBarry Smith 
8129566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
8139566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype));
814f6224b95SHong Zhang 
8159566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops((2.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3));
816db4efbfdSBarry Smith   PetscFunctionReturn(0);
817db4efbfdSBarry Smith }
818db4efbfdSBarry Smith 
8199371c9d4SSatish Balay static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) {
8204396437dSToby Isaac   MatFactorInfo info;
8214396437dSToby Isaac 
8224396437dSToby Isaac   PetscFunctionBegin;
8239566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES));
824dbbe0bcdSBarry Smith   PetscUseTypeMethod(fact, lufactor, NULL, NULL, &info);
8254396437dSToby Isaac   PetscFunctionReturn(0);
8264396437dSToby Isaac }
8274396437dSToby Isaac 
8289371c9d4SSatish Balay PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, IS col, const MatFactorInfo *info) {
8294396437dSToby Isaac   PetscFunctionBegin;
8304396437dSToby Isaac   fact->preallocated         = PETSC_TRUE;
8314396437dSToby Isaac   fact->assembled            = PETSC_TRUE;
8324396437dSToby Isaac   fact->ops->lufactornumeric = MatLUFactorNumeric_SeqDense;
8334396437dSToby Isaac   PetscFunctionReturn(0);
8344396437dSToby Isaac }
8354396437dSToby Isaac 
836a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */
8379371c9d4SSatish Balay PetscErrorCode MatCholeskyFactor_SeqDense(Mat A, IS perm, const MatFactorInfo *factinfo) {
838db4efbfdSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
839c5df96a5SBarry Smith   PetscBLASInt  info, n;
840db4efbfdSBarry Smith 
841db4efbfdSBarry Smith   PetscFunctionBegin;
8429566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
843db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
844b94d7dedSBarry Smith   if (A->spd == PETSC_BOOL3_TRUE) {
8459566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
846792fecdfSBarry Smith     PetscCallBLAS("LAPACKpotrf", LAPACKpotrf_("L", &n, mat->v, &mat->lda, &info));
8479566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
848a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
849b94d7dedSBarry Smith   } else if (A->hermitian == PETSC_BOOL3_TRUE) {
850*4dfa11a4SJacob Faibussowitsch     if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); }
851a49dc2a2SStefano Zampini     if (!mat->fwork) {
852a49dc2a2SStefano Zampini       PetscScalar dummy;
853a49dc2a2SStefano Zampini 
854a49dc2a2SStefano Zampini       mat->lfwork = -1;
8559566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
856792fecdfSBarry Smith       PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info));
8579566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
858a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
8599566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
860a49dc2a2SStefano Zampini     }
8619566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
862792fecdfSBarry Smith     PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info));
8639566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
864a49dc2a2SStefano Zampini #endif
865a49dc2a2SStefano Zampini   } else { /* symmetric case */
866*4dfa11a4SJacob Faibussowitsch     if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); }
867a49dc2a2SStefano Zampini     if (!mat->fwork) {
868a49dc2a2SStefano Zampini       PetscScalar dummy;
869a49dc2a2SStefano Zampini 
870a49dc2a2SStefano Zampini       mat->lfwork = -1;
8719566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
872792fecdfSBarry Smith       PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info));
8739566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
874a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
8759566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
876a49dc2a2SStefano Zampini     }
8779566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
878792fecdfSBarry Smith     PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info));
8799566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
880a49dc2a2SStefano Zampini   }
88128b400f6SJacob Faibussowitsch   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad factorization: zero pivot in row %" PetscInt_FMT, (PetscInt)info - 1);
8828208b9aeSStefano Zampini 
8834396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_Cholesky;
8844396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_Cholesky;
8854396437dSToby Isaac   A->ops->solvetranspose    = MatSolveTranspose_SeqDense_Cholesky;
8864396437dSToby Isaac   A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_Cholesky;
887d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_CHOLESKY;
8882205254eSKarl Rupp 
8899566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
8909566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype));
891f6224b95SHong Zhang 
8929566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0));
893db4efbfdSBarry Smith   PetscFunctionReturn(0);
894db4efbfdSBarry Smith }
895db4efbfdSBarry Smith 
8969371c9d4SSatish Balay static PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) {
897db4efbfdSBarry Smith   MatFactorInfo info;
898db4efbfdSBarry Smith 
899db4efbfdSBarry Smith   PetscFunctionBegin;
900db4efbfdSBarry Smith   info.fill = 1.0;
9012205254eSKarl Rupp 
9029566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES));
903dbbe0bcdSBarry Smith   PetscUseTypeMethod(fact, choleskyfactor, NULL, &info);
904db4efbfdSBarry Smith   PetscFunctionReturn(0);
905db4efbfdSBarry Smith }
906db4efbfdSBarry Smith 
9079371c9d4SSatish Balay PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info) {
908db4efbfdSBarry Smith   PetscFunctionBegin;
909c3ef05f6SHong Zhang   fact->assembled                  = PETSC_TRUE;
9101bbcc794SSatish Balay   fact->preallocated               = PETSC_TRUE;
911719d5645SBarry Smith   fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense;
912db4efbfdSBarry Smith   PetscFunctionReturn(0);
913db4efbfdSBarry Smith }
914db4efbfdSBarry Smith 
9159371c9d4SSatish Balay PetscErrorCode MatQRFactor_SeqDense(Mat A, IS col, const MatFactorInfo *minfo) {
9164905a7bcSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
9174905a7bcSToby Isaac   PetscBLASInt  n, m, info, min, max;
9184905a7bcSToby Isaac 
9194905a7bcSToby Isaac   PetscFunctionBegin;
9209566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
9219566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
9224396437dSToby Isaac   max = PetscMax(m, n);
9234396437dSToby Isaac   min = PetscMin(m, n);
924*4dfa11a4SJacob Faibussowitsch   if (!mat->tau) { PetscCall(PetscMalloc1(min, &mat->tau)); }
925*4dfa11a4SJacob Faibussowitsch   if (!mat->pivots) { PetscCall(PetscMalloc1(n, &mat->pivots)); }
92648a46eb9SPierre Jolivet   if (!mat->qrrhs) PetscCall(MatCreateVecs(A, NULL, &(mat->qrrhs)));
9274905a7bcSToby Isaac   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
9284905a7bcSToby Isaac   if (!mat->fwork) {
9294905a7bcSToby Isaac     PetscScalar dummy;
9304905a7bcSToby Isaac 
9314905a7bcSToby Isaac     mat->lfwork = -1;
9329566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
933792fecdfSBarry Smith     PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, &dummy, &mat->lfwork, &info));
9349566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
9354905a7bcSToby Isaac     mat->lfwork = (PetscInt)PetscRealPart(dummy);
9369566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
9374905a7bcSToby Isaac   }
9389566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
939792fecdfSBarry Smith   PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, mat->fwork, &mat->lfwork, &info));
9409566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
94105fcb23eSStefano Zampini   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to QR factorization %d", (int)info);
9424905a7bcSToby 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
9434905a7bcSToby Isaac   mat->rank = min;
9444905a7bcSToby Isaac 
9454396437dSToby Isaac   A->ops->solve    = MatSolve_SeqDense_QR;
9464396437dSToby Isaac   A->ops->matsolve = MatMatSolve_SeqDense_QR;
9474905a7bcSToby Isaac   A->factortype    = MAT_FACTOR_QR;
9484905a7bcSToby Isaac   if (m == n) {
9494396437dSToby Isaac     A->ops->solvetranspose    = MatSolveTranspose_SeqDense_QR;
9504396437dSToby Isaac     A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_QR;
9514905a7bcSToby Isaac   }
9524905a7bcSToby Isaac 
9539566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
9549566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype));
9554905a7bcSToby Isaac 
9569566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0 * min * min * (max - min / 3.0)));
9574905a7bcSToby Isaac   PetscFunctionReturn(0);
9584905a7bcSToby Isaac }
9594905a7bcSToby Isaac 
9609371c9d4SSatish Balay static PetscErrorCode MatQRFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) {
9614905a7bcSToby Isaac   MatFactorInfo info;
9624905a7bcSToby Isaac 
9634905a7bcSToby Isaac   PetscFunctionBegin;
9644905a7bcSToby Isaac   info.fill = 1.0;
9654905a7bcSToby Isaac 
9669566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES));
967cac4c232SBarry Smith   PetscUseMethod(fact, "MatQRFactor_C", (Mat, IS, const MatFactorInfo *), (fact, NULL, &info));
9684905a7bcSToby Isaac   PetscFunctionReturn(0);
9694905a7bcSToby Isaac }
9704905a7bcSToby Isaac 
9719371c9d4SSatish Balay PetscErrorCode MatQRFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info) {
9724905a7bcSToby Isaac   PetscFunctionBegin;
9734905a7bcSToby Isaac   fact->assembled    = PETSC_TRUE;
9744905a7bcSToby Isaac   fact->preallocated = PETSC_TRUE;
9759566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)fact, "MatQRFactorNumeric_C", MatQRFactorNumeric_SeqDense));
9764905a7bcSToby Isaac   PetscFunctionReturn(0);
9774905a7bcSToby Isaac }
9784905a7bcSToby Isaac 
979ca15aa20SStefano Zampini /* uses LAPACK */
9809371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A, MatFactorType ftype, Mat *fact) {
981db4efbfdSBarry Smith   PetscFunctionBegin;
9829566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), fact));
9839566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*fact, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n));
9849566063dSJacob Faibussowitsch   PetscCall(MatSetType(*fact, MATDENSE));
98566e17bc3SBarry Smith   (*fact)->trivialsymbolic = PETSC_TRUE;
9862a350339SBarry Smith   if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU) {
987db4efbfdSBarry Smith     (*fact)->ops->lufactorsymbolic  = MatLUFactorSymbolic_SeqDense;
9882a350339SBarry Smith     (*fact)->ops->ilufactorsymbolic = MatLUFactorSymbolic_SeqDense;
989bf5a80bcSToby Isaac   } else if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) {
990db4efbfdSBarry Smith     (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense;
991bf5a80bcSToby Isaac   } else if (ftype == MAT_FACTOR_QR) {
9929566063dSJacob Faibussowitsch     PetscCall(PetscObjectComposeFunction((PetscObject)(*fact), "MatQRFactorSymbolic_C", MatQRFactorSymbolic_SeqDense));
993db4efbfdSBarry Smith   }
994d5f3da31SBarry Smith   (*fact)->factortype = ftype;
99500c67f3bSHong Zhang 
9969566063dSJacob Faibussowitsch   PetscCall(PetscFree((*fact)->solvertype));
9979566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC, &(*fact)->solvertype));
9989566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_LU]));
9999566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ILU]));
10009566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_CHOLESKY]));
10019566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ICC]));
1002db4efbfdSBarry Smith   PetscFunctionReturn(0);
1003db4efbfdSBarry Smith }
1004db4efbfdSBarry Smith 
1005289bc588SBarry Smith /* ------------------------------------------------------------------*/
10069371c9d4SSatish Balay static PetscErrorCode MatSOR_SeqDense(Mat A, Vec bb, PetscReal omega, MatSORType flag, PetscReal shift, PetscInt its, PetscInt lits, Vec xx) {
1007c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1008d9ca1df4SBarry Smith   PetscScalar       *x, *v = mat->v, zero = 0.0, xt;
1009d9ca1df4SBarry Smith   const PetscScalar *b;
1010d0f46423SBarry Smith   PetscInt           m = A->rmap->n, i;
101123fff9afSBarry Smith   PetscBLASInt       o = 1, bm = 0;
1012289bc588SBarry Smith 
10133a40ed3dSBarry Smith   PetscFunctionBegin;
1014ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
101508401ef6SPierre Jolivet   PetscCheck(A->offloadmask != PETSC_OFFLOAD_GPU, PETSC_COMM_SELF, PETSC_ERR_SUP, "Not implemented");
1016ca15aa20SStefano Zampini #endif
1017422a814eSBarry Smith   if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */
10189566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(m, &bm));
1019289bc588SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
10203bffc371SBarry Smith     /* this is a hack fix, should have another version without the second BLASdotu */
10219566063dSJacob Faibussowitsch     PetscCall(VecSet(xx, zero));
1022289bc588SBarry Smith   }
10239566063dSJacob Faibussowitsch   PetscCall(VecGetArray(xx, &x));
10249566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(bb, &b));
1025b965ef7fSBarry Smith   its = its * lits;
102608401ef6SPierre 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);
1027289bc588SBarry Smith   while (its--) {
1028fccaa45eSBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
1029289bc588SBarry Smith       for (i = 0; i < m; i++) {
1030792fecdfSBarry Smith         PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o));
103155a1b374SBarry Smith         x[i] = (1. - omega) * x[i] + omega * (xt + v[i + i * m] * x[i]) / (v[i + i * m] + shift);
1032289bc588SBarry Smith       }
1033289bc588SBarry Smith     }
1034fccaa45eSBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
1035289bc588SBarry Smith       for (i = m - 1; i >= 0; i--) {
1036792fecdfSBarry Smith         PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o));
103755a1b374SBarry Smith         x[i] = (1. - omega) * x[i] + omega * (xt + v[i + i * m] * x[i]) / (v[i + i * m] + shift);
1038289bc588SBarry Smith       }
1039289bc588SBarry Smith     }
1040289bc588SBarry Smith   }
10419566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(bb, &b));
10429566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(xx, &x));
10433a40ed3dSBarry Smith   PetscFunctionReturn(0);
1044289bc588SBarry Smith }
1045289bc588SBarry Smith 
1046289bc588SBarry Smith /* -----------------------------------------------------------------*/
10479371c9d4SSatish Balay PetscErrorCode MatMultTranspose_SeqDense(Mat A, Vec xx, Vec yy) {
1048c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1049d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v, *x;
1050d9ca1df4SBarry Smith   PetscScalar       *y;
10510805154bSBarry Smith   PetscBLASInt       m, n, _One = 1;
1052ea709b57SSatish Balay   PetscScalar        _DOne = 1.0, _DZero = 0.0;
10533a40ed3dSBarry Smith 
10543a40ed3dSBarry Smith   PetscFunctionBegin;
10559566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
10569566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
10579566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx, &x));
10589566063dSJacob Faibussowitsch   PetscCall(VecGetArrayWrite(yy, &y));
10595ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
10605ac36cfcSBarry Smith     PetscBLASInt i;
10615ac36cfcSBarry Smith     for (i = 0; i < n; i++) y[i] = 0.0;
10625ac36cfcSBarry Smith   } else {
1063792fecdfSBarry Smith     PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v, &mat->lda, x, &_One, &_DZero, y, &_One));
10649566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n - A->cmap->n));
10655ac36cfcSBarry Smith   }
10669566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx, &x));
10679566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayWrite(yy, &y));
10683a40ed3dSBarry Smith   PetscFunctionReturn(0);
1069289bc588SBarry Smith }
1070800995b7SMatthew Knepley 
10719371c9d4SSatish Balay PetscErrorCode MatMult_SeqDense(Mat A, Vec xx, Vec yy) {
1072c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1073d9ca1df4SBarry Smith   PetscScalar       *y, _DOne = 1.0, _DZero = 0.0;
10740805154bSBarry Smith   PetscBLASInt       m, n, _One             = 1;
1075d9ca1df4SBarry Smith   const PetscScalar *v = mat->v, *x;
10763a40ed3dSBarry Smith 
10773a40ed3dSBarry Smith   PetscFunctionBegin;
10789566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
10799566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
10809566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx, &x));
10819566063dSJacob Faibussowitsch   PetscCall(VecGetArrayWrite(yy, &y));
10825ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
10835ac36cfcSBarry Smith     PetscBLASInt i;
10845ac36cfcSBarry Smith     for (i = 0; i < m; i++) y[i] = 0.0;
10855ac36cfcSBarry Smith   } else {
1086792fecdfSBarry Smith     PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DZero, y, &_One));
10879566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n - A->rmap->n));
10885ac36cfcSBarry Smith   }
10899566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx, &x));
10909566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayWrite(yy, &y));
10913a40ed3dSBarry Smith   PetscFunctionReturn(0);
1092289bc588SBarry Smith }
10936ee01492SSatish Balay 
10949371c9d4SSatish Balay PetscErrorCode MatMultAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) {
1095c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1096d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v, *x;
1097d9ca1df4SBarry Smith   PetscScalar       *y, _DOne = 1.0;
10980805154bSBarry Smith   PetscBLASInt       m, n, _One = 1;
10993a40ed3dSBarry Smith 
11003a40ed3dSBarry Smith   PetscFunctionBegin;
11019566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
11029566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
11039566063dSJacob Faibussowitsch   PetscCall(VecCopy(zz, yy));
1104d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
11059566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx, &x));
11069566063dSJacob Faibussowitsch   PetscCall(VecGetArray(yy, &y));
1107792fecdfSBarry Smith   PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DOne, y, &_One));
11089566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx, &x));
11099566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(yy, &y));
11109566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n));
11113a40ed3dSBarry Smith   PetscFunctionReturn(0);
1112289bc588SBarry Smith }
11136ee01492SSatish Balay 
11149371c9d4SSatish Balay PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) {
1115c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1116d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v, *x;
1117d9ca1df4SBarry Smith   PetscScalar       *y;
11180805154bSBarry Smith   PetscBLASInt       m, n, _One = 1;
111987828ca2SBarry Smith   PetscScalar        _DOne = 1.0;
11203a40ed3dSBarry Smith 
11213a40ed3dSBarry Smith   PetscFunctionBegin;
11229566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
11239566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
11249566063dSJacob Faibussowitsch   PetscCall(VecCopy(zz, yy));
1125d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
11269566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx, &x));
11279566063dSJacob Faibussowitsch   PetscCall(VecGetArray(yy, &y));
1128792fecdfSBarry Smith   PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DOne, y, &_One));
11299566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx, &x));
11309566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(yy, &y));
11319566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n));
11323a40ed3dSBarry Smith   PetscFunctionReturn(0);
1133289bc588SBarry Smith }
1134289bc588SBarry Smith 
1135289bc588SBarry Smith /* -----------------------------------------------------------------*/
11369371c9d4SSatish Balay static PetscErrorCode MatGetRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals) {
1137c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
113813f74950SBarry Smith   PetscInt      i;
113967e560aaSBarry Smith 
11403a40ed3dSBarry Smith   PetscFunctionBegin;
1141d0f46423SBarry Smith   *ncols = A->cmap->n;
1142289bc588SBarry Smith   if (cols) {
11439566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(A->cmap->n, cols));
1144d0f46423SBarry Smith     for (i = 0; i < A->cmap->n; i++) (*cols)[i] = i;
1145289bc588SBarry Smith   }
1146289bc588SBarry Smith   if (vals) {
1147ca15aa20SStefano Zampini     const PetscScalar *v;
1148ca15aa20SStefano Zampini 
11499566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A, &v));
11509566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(A->cmap->n, vals));
1151ca15aa20SStefano Zampini     v += row;
11529371c9d4SSatish Balay     for (i = 0; i < A->cmap->n; i++) {
11539371c9d4SSatish Balay       (*vals)[i] = *v;
11549371c9d4SSatish Balay       v += mat->lda;
11559371c9d4SSatish Balay     }
11569566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A, &v));
1157289bc588SBarry Smith   }
11583a40ed3dSBarry Smith   PetscFunctionReturn(0);
1159289bc588SBarry Smith }
11606ee01492SSatish Balay 
11619371c9d4SSatish Balay static PetscErrorCode MatRestoreRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals) {
1162606d414cSSatish Balay   PetscFunctionBegin;
1163cb4a9cd9SHong Zhang   if (ncols) *ncols = 0;
11649566063dSJacob Faibussowitsch   if (cols) PetscCall(PetscFree(*cols));
11659566063dSJacob Faibussowitsch   if (vals) PetscCall(PetscFree(*vals));
11663a40ed3dSBarry Smith   PetscFunctionReturn(0);
1167289bc588SBarry Smith }
1168289bc588SBarry Smith /* ----------------------------------------------------------------*/
11699371c9d4SSatish Balay static PetscErrorCode MatSetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], const PetscScalar v[], InsertMode addv) {
1170c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
1171ca15aa20SStefano Zampini   PetscScalar  *av;
117213f74950SBarry Smith   PetscInt      i, j, idx = 0;
1173ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1174c70f7ee4SJunchao Zhang   PetscOffloadMask oldf;
1175ca15aa20SStefano Zampini #endif
1176d6dfbf8fSBarry Smith 
11773a40ed3dSBarry Smith   PetscFunctionBegin;
11789566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &av));
1179289bc588SBarry Smith   if (!mat->roworiented) {
1180dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1181289bc588SBarry Smith       for (j = 0; j < n; j++) {
11829371c9d4SSatish Balay         if (indexn[j] < 0) {
11839371c9d4SSatish Balay           idx += m;
11849371c9d4SSatish Balay           continue;
11859371c9d4SSatish Balay         }
11866bdcaf15SBarry 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);
1187289bc588SBarry Smith         for (i = 0; i < m; i++) {
11889371c9d4SSatish Balay           if (indexm[i] < 0) {
11899371c9d4SSatish Balay             idx++;
11909371c9d4SSatish Balay             continue;
11919371c9d4SSatish Balay           }
11926bdcaf15SBarry 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);
1193ca15aa20SStefano Zampini           av[indexn[j] * mat->lda + indexm[i]] = v[idx++];
1194289bc588SBarry Smith         }
1195289bc588SBarry Smith       }
11963a40ed3dSBarry Smith     } else {
1197289bc588SBarry Smith       for (j = 0; j < n; j++) {
11989371c9d4SSatish Balay         if (indexn[j] < 0) {
11999371c9d4SSatish Balay           idx += m;
12009371c9d4SSatish Balay           continue;
12019371c9d4SSatish Balay         }
12026bdcaf15SBarry 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);
1203289bc588SBarry Smith         for (i = 0; i < m; i++) {
12049371c9d4SSatish Balay           if (indexm[i] < 0) {
12059371c9d4SSatish Balay             idx++;
12069371c9d4SSatish Balay             continue;
12079371c9d4SSatish Balay           }
12086bdcaf15SBarry 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);
1209ca15aa20SStefano Zampini           av[indexn[j] * mat->lda + indexm[i]] += v[idx++];
1210289bc588SBarry Smith         }
1211289bc588SBarry Smith       }
1212289bc588SBarry Smith     }
12133a40ed3dSBarry Smith   } else {
1214dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1215e8d4e0b9SBarry Smith       for (i = 0; i < m; i++) {
12169371c9d4SSatish Balay         if (indexm[i] < 0) {
12179371c9d4SSatish Balay           idx += n;
12189371c9d4SSatish Balay           continue;
12199371c9d4SSatish Balay         }
12206bdcaf15SBarry 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);
1221e8d4e0b9SBarry Smith         for (j = 0; j < n; j++) {
12229371c9d4SSatish Balay           if (indexn[j] < 0) {
12239371c9d4SSatish Balay             idx++;
12249371c9d4SSatish Balay             continue;
12259371c9d4SSatish Balay           }
12266bdcaf15SBarry 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);
1227ca15aa20SStefano Zampini           av[indexn[j] * mat->lda + indexm[i]] = v[idx++];
1228e8d4e0b9SBarry Smith         }
1229e8d4e0b9SBarry Smith       }
12303a40ed3dSBarry Smith     } else {
1231289bc588SBarry Smith       for (i = 0; i < m; i++) {
12329371c9d4SSatish Balay         if (indexm[i] < 0) {
12339371c9d4SSatish Balay           idx += n;
12349371c9d4SSatish Balay           continue;
12359371c9d4SSatish Balay         }
12366bdcaf15SBarry 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);
1237289bc588SBarry Smith         for (j = 0; j < n; j++) {
12389371c9d4SSatish Balay           if (indexn[j] < 0) {
12399371c9d4SSatish Balay             idx++;
12409371c9d4SSatish Balay             continue;
12419371c9d4SSatish Balay           }
12426bdcaf15SBarry 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);
1243ca15aa20SStefano Zampini           av[indexn[j] * mat->lda + indexm[i]] += v[idx++];
1244289bc588SBarry Smith         }
1245289bc588SBarry Smith       }
1246289bc588SBarry Smith     }
1247e8d4e0b9SBarry Smith   }
1248ca15aa20SStefano Zampini   /* hack to prevent unneeded copy to the GPU while returning the array */
1249ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1250c70f7ee4SJunchao Zhang   oldf           = A->offloadmask;
1251c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_GPU;
1252ca15aa20SStefano Zampini #endif
12539566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &av));
1254ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1255c70f7ee4SJunchao Zhang   A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU);
1256ca15aa20SStefano Zampini #endif
12573a40ed3dSBarry Smith   PetscFunctionReturn(0);
1258289bc588SBarry Smith }
1259e8d4e0b9SBarry Smith 
12609371c9d4SSatish Balay static PetscErrorCode MatGetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], PetscScalar v[]) {
1261ae80bb75SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1262ca15aa20SStefano Zampini   const PetscScalar *vv;
126313f74950SBarry Smith   PetscInt           i, j;
1264ae80bb75SLois Curfman McInnes 
12653a40ed3dSBarry Smith   PetscFunctionBegin;
12669566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &vv));
1267ae80bb75SLois Curfman McInnes   /* row-oriented output */
1268ae80bb75SLois Curfman McInnes   for (i = 0; i < m; i++) {
12699371c9d4SSatish Balay     if (indexm[i] < 0) {
12709371c9d4SSatish Balay       v += n;
12719371c9d4SSatish Balay       continue;
12729371c9d4SSatish Balay     }
127308401ef6SPierre 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);
1274ae80bb75SLois Curfman McInnes     for (j = 0; j < n; j++) {
12759371c9d4SSatish Balay       if (indexn[j] < 0) {
12769371c9d4SSatish Balay         v++;
12779371c9d4SSatish Balay         continue;
12789371c9d4SSatish Balay       }
127908401ef6SPierre 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);
1280ca15aa20SStefano Zampini       *v++ = vv[indexn[j] * mat->lda + indexm[i]];
1281ae80bb75SLois Curfman McInnes     }
1282ae80bb75SLois Curfman McInnes   }
12839566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &vv));
12843a40ed3dSBarry Smith   PetscFunctionReturn(0);
1285ae80bb75SLois Curfman McInnes }
1286ae80bb75SLois Curfman McInnes 
1287289bc588SBarry Smith /* -----------------------------------------------------------------*/
1288289bc588SBarry Smith 
12899371c9d4SSatish Balay PetscErrorCode MatView_Dense_Binary(Mat mat, PetscViewer viewer) {
12908491ab44SLisandro Dalcin   PetscBool          skipHeader;
12918491ab44SLisandro Dalcin   PetscViewerFormat  format;
12928491ab44SLisandro Dalcin   PetscInt           header[4], M, N, m, lda, i, j, k;
12938491ab44SLisandro Dalcin   const PetscScalar *v;
12948491ab44SLisandro Dalcin   PetscScalar       *vwork;
1295aabbc4fbSShri Abhyankar 
1296aabbc4fbSShri Abhyankar   PetscFunctionBegin;
12979566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
12989566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader));
12999566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
13008491ab44SLisandro Dalcin   if (skipHeader) format = PETSC_VIEWER_NATIVE;
1301aabbc4fbSShri Abhyankar 
13029566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat, &M, &N));
13038491ab44SLisandro Dalcin 
13048491ab44SLisandro Dalcin   /* write matrix header */
13059371c9d4SSatish Balay   header[0] = MAT_FILE_CLASSID;
13069371c9d4SSatish Balay   header[1] = M;
13079371c9d4SSatish Balay   header[2] = N;
13088491ab44SLisandro Dalcin   header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M * N;
13099566063dSJacob Faibussowitsch   if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer, header, 4, PETSC_INT));
13108491ab44SLisandro Dalcin 
13119566063dSJacob Faibussowitsch   PetscCall(MatGetLocalSize(mat, &m, NULL));
13128491ab44SLisandro Dalcin   if (format != PETSC_VIEWER_NATIVE) {
13138491ab44SLisandro Dalcin     PetscInt nnz = m * N, *iwork;
13148491ab44SLisandro Dalcin     /* store row lengths for each row */
13159566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nnz, &iwork));
13168491ab44SLisandro Dalcin     for (i = 0; i < m; i++) iwork[i] = N;
13179566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT));
13188491ab44SLisandro Dalcin     /* store column indices (zero start index) */
13198491ab44SLisandro Dalcin     for (k = 0, i = 0; i < m; i++)
13209371c9d4SSatish Balay       for (j = 0; j < N; j++, k++) iwork[k] = j;
13219566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT));
13229566063dSJacob Faibussowitsch     PetscCall(PetscFree(iwork));
13238491ab44SLisandro Dalcin   }
13248491ab44SLisandro Dalcin   /* store matrix values as a dense matrix in row major order */
13259566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(m * N, &vwork));
13269566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(mat, &v));
13279566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(mat, &lda));
13288491ab44SLisandro Dalcin   for (k = 0, i = 0; i < m; i++)
13299371c9d4SSatish Balay     for (j = 0; j < N; j++, k++) vwork[k] = v[i + lda * j];
13309566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(mat, &v));
13319566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryWriteAll(viewer, vwork, m * N, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR));
13329566063dSJacob Faibussowitsch   PetscCall(PetscFree(vwork));
13338491ab44SLisandro Dalcin   PetscFunctionReturn(0);
13348491ab44SLisandro Dalcin }
13358491ab44SLisandro Dalcin 
13369371c9d4SSatish Balay PetscErrorCode MatLoad_Dense_Binary(Mat mat, PetscViewer viewer) {
13378491ab44SLisandro Dalcin   PetscBool    skipHeader;
13388491ab44SLisandro Dalcin   PetscInt     header[4], M, N, m, nz, lda, i, j, k;
13398491ab44SLisandro Dalcin   PetscInt     rows, cols;
13408491ab44SLisandro Dalcin   PetscScalar *v, *vwork;
13418491ab44SLisandro Dalcin 
13428491ab44SLisandro Dalcin   PetscFunctionBegin;
13439566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
13449566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader));
13458491ab44SLisandro Dalcin 
13468491ab44SLisandro Dalcin   if (!skipHeader) {
13479566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryRead(viewer, header, 4, NULL, PETSC_INT));
134808401ef6SPierre Jolivet     PetscCheck(header[0] == MAT_FILE_CLASSID, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Not a matrix object in file");
13499371c9d4SSatish Balay     M = header[1];
13509371c9d4SSatish Balay     N = header[2];
135108401ef6SPierre Jolivet     PetscCheck(M >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix row size (%" PetscInt_FMT ") in file is negative", M);
135208401ef6SPierre Jolivet     PetscCheck(N >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix column size (%" PetscInt_FMT ") in file is negative", N);
13538491ab44SLisandro Dalcin     nz = header[3];
1354aed4548fSBarry Smith     PetscCheck(nz == MATRIX_BINARY_FORMAT_DENSE || nz >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Unknown matrix format %" PetscInt_FMT " in file", nz);
1355aabbc4fbSShri Abhyankar   } else {
13569566063dSJacob Faibussowitsch     PetscCall(MatGetSize(mat, &M, &N));
1357aed4548fSBarry 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");
13588491ab44SLisandro Dalcin     nz = MATRIX_BINARY_FORMAT_DENSE;
1359e6324fbbSBarry Smith   }
1360aabbc4fbSShri Abhyankar 
13618491ab44SLisandro Dalcin   /* setup global sizes if not set */
13628491ab44SLisandro Dalcin   if (mat->rmap->N < 0) mat->rmap->N = M;
13638491ab44SLisandro Dalcin   if (mat->cmap->N < 0) mat->cmap->N = N;
13649566063dSJacob Faibussowitsch   PetscCall(MatSetUp(mat));
13658491ab44SLisandro Dalcin   /* check if global sizes are correct */
13669566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat, &rows, &cols));
1367aed4548fSBarry 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);
1368aabbc4fbSShri Abhyankar 
13699566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat, NULL, &N));
13709566063dSJacob Faibussowitsch   PetscCall(MatGetLocalSize(mat, &m, NULL));
13719566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(mat, &v));
13729566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(mat, &lda));
13738491ab44SLisandro Dalcin   if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense format */
13748491ab44SLisandro Dalcin     PetscInt nnz = m * N;
13758491ab44SLisandro Dalcin     /* read in matrix values */
13769566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nnz, &vwork));
13779566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR));
13788491ab44SLisandro Dalcin     /* store values in column major order */
13798491ab44SLisandro Dalcin     for (j = 0; j < N; j++)
13809371c9d4SSatish Balay       for (i = 0; i < m; i++) v[i + lda * j] = vwork[i * N + j];
13819566063dSJacob Faibussowitsch     PetscCall(PetscFree(vwork));
13828491ab44SLisandro Dalcin   } else { /* matrix in file is sparse format */
13838491ab44SLisandro Dalcin     PetscInt nnz = 0, *rlens, *icols;
13848491ab44SLisandro Dalcin     /* read in row lengths */
13859566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(m, &rlens));
13869566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer, rlens, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT));
13878491ab44SLisandro Dalcin     for (i = 0; i < m; i++) nnz += rlens[i];
13888491ab44SLisandro Dalcin     /* read in column indices and values */
13899566063dSJacob Faibussowitsch     PetscCall(PetscMalloc2(nnz, &icols, nnz, &vwork));
13909566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer, icols, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT));
13919566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR));
13928491ab44SLisandro Dalcin     /* store values in column major order */
13938491ab44SLisandro Dalcin     for (k = 0, i = 0; i < m; i++)
13949371c9d4SSatish Balay       for (j = 0; j < rlens[i]; j++, k++) v[i + lda * icols[k]] = vwork[k];
13959566063dSJacob Faibussowitsch     PetscCall(PetscFree(rlens));
13969566063dSJacob Faibussowitsch     PetscCall(PetscFree2(icols, vwork));
1397aabbc4fbSShri Abhyankar   }
13989566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(mat, &v));
13999566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY));
14009566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY));
1401aabbc4fbSShri Abhyankar   PetscFunctionReturn(0);
1402aabbc4fbSShri Abhyankar }
1403aabbc4fbSShri Abhyankar 
14049371c9d4SSatish Balay PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer) {
1405eb91f321SVaclav Hapla   PetscBool isbinary, ishdf5;
1406eb91f321SVaclav Hapla 
1407eb91f321SVaclav Hapla   PetscFunctionBegin;
1408eb91f321SVaclav Hapla   PetscValidHeaderSpecific(newMat, MAT_CLASSID, 1);
1409eb91f321SVaclav Hapla   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
1410eb91f321SVaclav Hapla   /* force binary viewer to load .info file if it has not yet done so */
14119566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
14129566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
14139566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5));
1414eb91f321SVaclav Hapla   if (isbinary) {
14159566063dSJacob Faibussowitsch     PetscCall(MatLoad_Dense_Binary(newMat, viewer));
1416eb91f321SVaclav Hapla   } else if (ishdf5) {
1417eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5)
14189566063dSJacob Faibussowitsch     PetscCall(MatLoad_Dense_HDF5(newMat, viewer));
1419eb91f321SVaclav Hapla #else
1420eb91f321SVaclav Hapla     SETERRQ(PetscObjectComm((PetscObject)newMat), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5");
1421eb91f321SVaclav Hapla #endif
1422eb91f321SVaclav Hapla   } else {
142398921bdaSJacob 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);
1424eb91f321SVaclav Hapla   }
1425eb91f321SVaclav Hapla   PetscFunctionReturn(0);
1426eb91f321SVaclav Hapla }
1427eb91f321SVaclav Hapla 
14289371c9d4SSatish Balay static PetscErrorCode MatView_SeqDense_ASCII(Mat A, PetscViewer viewer) {
1429932b0c3eSLois Curfman McInnes   Mat_SeqDense     *a = (Mat_SeqDense *)A->data;
143013f74950SBarry Smith   PetscInt          i, j;
14312dcb1b2aSMatthew Knepley   const char       *name;
1432ca15aa20SStefano Zampini   PetscScalar      *v, *av;
1433f3ef73ceSBarry Smith   PetscViewerFormat format;
14345f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX)
1435ace3abfcSBarry Smith   PetscBool allreal = PETSC_TRUE;
14365f481a85SSatish Balay #endif
1437932b0c3eSLois Curfman McInnes 
14383a40ed3dSBarry Smith   PetscFunctionBegin;
14399566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&av));
14409566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
1441456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
14423a40ed3dSBarry Smith     PetscFunctionReturn(0); /* do nothing for now */
1443fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
14449566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
1445d0f46423SBarry Smith     for (i = 0; i < A->rmap->n; i++) {
1446ca15aa20SStefano Zampini       v = av + i;
14479566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "row %" PetscInt_FMT ":", i));
1448d0f46423SBarry Smith       for (j = 0; j < A->cmap->n; j++) {
1449aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1450329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
14519566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g + %g i) ", j, (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v)));
1452329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
14539566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)PetscRealPart(*v)));
14546831982aSBarry Smith         }
145580cd9d93SLois Curfman McInnes #else
145648a46eb9SPierre Jolivet         if (*v) PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)*v));
145780cd9d93SLois Curfman McInnes #endif
14581b807ce4Svictorle         v += a->lda;
145980cd9d93SLois Curfman McInnes       }
14609566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
146180cd9d93SLois Curfman McInnes     }
14629566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
14633a40ed3dSBarry Smith   } else {
14649566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
1465aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
146647989497SBarry Smith     /* determine if matrix has all real values */
1467bcd8d3a4SJose E. Roman     for (j = 0; j < A->cmap->n; j++) {
1468bcd8d3a4SJose E. Roman       v = av + j * a->lda;
1469bcd8d3a4SJose E. Roman       for (i = 0; i < A->rmap->n; i++) {
14709371c9d4SSatish Balay         if (PetscImaginaryPart(v[i])) {
14719371c9d4SSatish Balay           allreal = PETSC_FALSE;
14729371c9d4SSatish Balay           break;
14739371c9d4SSatish Balay         }
147447989497SBarry Smith       }
1475bcd8d3a4SJose E. Roman     }
147647989497SBarry Smith #endif
1477fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
14789566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetName((PetscObject)A, &name));
14799566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%% Size = %" PetscInt_FMT " %" PetscInt_FMT " \n", A->rmap->n, A->cmap->n));
14809566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%s = zeros(%" PetscInt_FMT ",%" PetscInt_FMT ");\n", name, A->rmap->n, A->cmap->n));
14819566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%s = [\n", name));
1482ffac6cdbSBarry Smith     }
1483ffac6cdbSBarry Smith 
1484d0f46423SBarry Smith     for (i = 0; i < A->rmap->n; i++) {
1485ca15aa20SStefano Zampini       v = av + i;
1486d0f46423SBarry Smith       for (j = 0; j < A->cmap->n; j++) {
1487aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
148847989497SBarry Smith         if (allreal) {
14899566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)PetscRealPart(*v)));
149047989497SBarry Smith         } else {
14919566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e + %18.16ei ", (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v)));
149247989497SBarry Smith         }
1493289bc588SBarry Smith #else
14949566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)*v));
1495289bc588SBarry Smith #endif
14961b807ce4Svictorle         v += a->lda;
1497289bc588SBarry Smith       }
14989566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
1499289bc588SBarry Smith     }
150048a46eb9SPierre Jolivet     if (format == PETSC_VIEWER_ASCII_MATLAB) PetscCall(PetscViewerASCIIPrintf(viewer, "];\n"));
15019566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
1502da3a660dSBarry Smith   }
15039566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&av));
15049566063dSJacob Faibussowitsch   PetscCall(PetscViewerFlush(viewer));
15053a40ed3dSBarry Smith   PetscFunctionReturn(0);
1506289bc588SBarry Smith }
1507289bc588SBarry Smith 
15089804daf3SBarry Smith #include <petscdraw.h>
15099371c9d4SSatish Balay static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw, void *Aa) {
1510f1af5d2fSBarry Smith   Mat                A = (Mat)Aa;
1511383922c3SLisandro Dalcin   PetscInt           m = A->rmap->n, n = A->cmap->n, i, j;
1512383922c3SLisandro Dalcin   int                color = PETSC_DRAW_WHITE;
1513ca15aa20SStefano Zampini   const PetscScalar *v;
1514b0a32e0cSBarry Smith   PetscViewer        viewer;
1515b05fc000SLisandro Dalcin   PetscReal          xl, yl, xr, yr, x_l, x_r, y_l, y_r;
1516f3ef73ceSBarry Smith   PetscViewerFormat  format;
1517f1af5d2fSBarry Smith 
1518f1af5d2fSBarry Smith   PetscFunctionBegin;
15199566063dSJacob Faibussowitsch   PetscCall(PetscObjectQuery((PetscObject)A, "Zoomviewer", (PetscObject *)&viewer));
15209566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
15219566063dSJacob Faibussowitsch   PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr));
1522f1af5d2fSBarry Smith 
1523f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
15249566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &v));
1525fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
1526d0609cedSBarry Smith     PetscDrawCollectiveBegin(draw);
1527f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
1528f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
15299371c9d4SSatish Balay       x_l = j;
15309371c9d4SSatish Balay       x_r = x_l + 1.0;
1531f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1532f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1533f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1534ca15aa20SStefano Zampini         if (PetscRealPart(v[j * m + i]) > 0.) color = PETSC_DRAW_RED;
1535ca15aa20SStefano Zampini         else if (PetscRealPart(v[j * m + i]) < 0.) color = PETSC_DRAW_BLUE;
1536ca15aa20SStefano Zampini         else continue;
15379566063dSJacob Faibussowitsch         PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color));
1538f1af5d2fSBarry Smith       }
1539f1af5d2fSBarry Smith     }
1540d0609cedSBarry Smith     PetscDrawCollectiveEnd(draw);
1541f1af5d2fSBarry Smith   } else {
1542f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
1543f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
1544b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1545b05fc000SLisandro Dalcin     PetscDraw popup;
1546b05fc000SLisandro Dalcin 
1547f1af5d2fSBarry Smith     for (i = 0; i < m * n; i++) {
1548f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
1549f1af5d2fSBarry Smith     }
1550383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
15519566063dSJacob Faibussowitsch     PetscCall(PetscDrawGetPopup(draw, &popup));
15529566063dSJacob Faibussowitsch     PetscCall(PetscDrawScalePopup(popup, minv, maxv));
1553383922c3SLisandro Dalcin 
1554d0609cedSBarry Smith     PetscDrawCollectiveBegin(draw);
1555f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
1556f1af5d2fSBarry Smith       x_l = j;
1557f1af5d2fSBarry Smith       x_r = x_l + 1.0;
1558f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1559f1af5d2fSBarry Smith         y_l   = m - i - 1.0;
1560f1af5d2fSBarry Smith         y_r   = y_l + 1.0;
1561b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(v[j * m + i]), minv, maxv);
15629566063dSJacob Faibussowitsch         PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color));
1563f1af5d2fSBarry Smith       }
1564f1af5d2fSBarry Smith     }
1565d0609cedSBarry Smith     PetscDrawCollectiveEnd(draw);
1566f1af5d2fSBarry Smith   }
15679566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &v));
1568f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1569f1af5d2fSBarry Smith }
1570f1af5d2fSBarry Smith 
15719371c9d4SSatish Balay static PetscErrorCode MatView_SeqDense_Draw(Mat A, PetscViewer viewer) {
1572b0a32e0cSBarry Smith   PetscDraw draw;
1573ace3abfcSBarry Smith   PetscBool isnull;
1574329f5518SBarry Smith   PetscReal xr, yr, xl, yl, h, w;
1575f1af5d2fSBarry Smith 
1576f1af5d2fSBarry Smith   PetscFunctionBegin;
15779566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
15789566063dSJacob Faibussowitsch   PetscCall(PetscDrawIsNull(draw, &isnull));
1579abc0a331SBarry Smith   if (isnull) PetscFunctionReturn(0);
1580f1af5d2fSBarry Smith 
15819371c9d4SSatish Balay   xr = A->cmap->n;
15829371c9d4SSatish Balay   yr = A->rmap->n;
15839371c9d4SSatish Balay   h  = yr / 10.0;
15849371c9d4SSatish Balay   w  = xr / 10.0;
15859371c9d4SSatish Balay   xr += w;
15869371c9d4SSatish Balay   yr += h;
15879371c9d4SSatish Balay   xl = -w;
15889371c9d4SSatish Balay   yl = -h;
15899566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetCoordinates(draw, xl, yl, xr, yr));
15909566063dSJacob Faibussowitsch   PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", (PetscObject)viewer));
15919566063dSJacob Faibussowitsch   PetscCall(PetscDrawZoom(draw, MatView_SeqDense_Draw_Zoom, A));
15929566063dSJacob Faibussowitsch   PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", NULL));
15939566063dSJacob Faibussowitsch   PetscCall(PetscDrawSave(draw));
1594f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1595f1af5d2fSBarry Smith }
1596f1af5d2fSBarry Smith 
15979371c9d4SSatish Balay PetscErrorCode MatView_SeqDense(Mat A, PetscViewer viewer) {
1598ace3abfcSBarry Smith   PetscBool iascii, isbinary, isdraw;
1599932b0c3eSLois Curfman McInnes 
16003a40ed3dSBarry Smith   PetscFunctionBegin;
16019566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
16029566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
16039566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
16041baa6e33SBarry Smith   if (iascii) PetscCall(MatView_SeqDense_ASCII(A, viewer));
16051baa6e33SBarry Smith   else if (isbinary) PetscCall(MatView_Dense_Binary(A, viewer));
16061baa6e33SBarry Smith   else if (isdraw) PetscCall(MatView_SeqDense_Draw(A, viewer));
16073a40ed3dSBarry Smith   PetscFunctionReturn(0);
1608932b0c3eSLois Curfman McInnes }
1609289bc588SBarry Smith 
16109371c9d4SSatish Balay static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A, const PetscScalar *array) {
1611d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
1612d3042a70SBarry Smith 
1613d3042a70SBarry Smith   PetscFunctionBegin;
161428b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
161528b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
161628b400f6SJacob Faibussowitsch   PetscCheck(!a->unplacedarray, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreArray() first");
1617d3042a70SBarry Smith   a->unplacedarray       = a->v;
1618d3042a70SBarry Smith   a->unplaced_user_alloc = a->user_alloc;
1619d3042a70SBarry Smith   a->v                   = (PetscScalar *)array;
1620637a0070SStefano Zampini   a->user_alloc          = PETSC_TRUE;
1621ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1622c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1623ca15aa20SStefano Zampini #endif
1624d3042a70SBarry Smith   PetscFunctionReturn(0);
1625d3042a70SBarry Smith }
1626d3042a70SBarry Smith 
16279371c9d4SSatish Balay static PetscErrorCode MatDenseResetArray_SeqDense(Mat A) {
1628d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
1629d3042a70SBarry Smith 
1630d3042a70SBarry Smith   PetscFunctionBegin;
163128b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
163228b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
1633d3042a70SBarry Smith   a->v             = a->unplacedarray;
1634d3042a70SBarry Smith   a->user_alloc    = a->unplaced_user_alloc;
1635d3042a70SBarry Smith   a->unplacedarray = NULL;
1636ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1637c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1638ca15aa20SStefano Zampini #endif
1639d3042a70SBarry Smith   PetscFunctionReturn(0);
1640d3042a70SBarry Smith }
1641d3042a70SBarry Smith 
16429371c9d4SSatish Balay static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A, const PetscScalar *array) {
1643d5ea218eSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
1644d5ea218eSStefano Zampini 
1645d5ea218eSStefano Zampini   PetscFunctionBegin;
164628b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
164728b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
16489566063dSJacob Faibussowitsch   if (!a->user_alloc) PetscCall(PetscFree(a->v));
1649d5ea218eSStefano Zampini   a->v          = (PetscScalar *)array;
1650d5ea218eSStefano Zampini   a->user_alloc = PETSC_FALSE;
1651d5ea218eSStefano Zampini #if defined(PETSC_HAVE_CUDA)
1652d5ea218eSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
1653d5ea218eSStefano Zampini #endif
1654d5ea218eSStefano Zampini   PetscFunctionReturn(0);
1655d5ea218eSStefano Zampini }
1656d5ea218eSStefano Zampini 
16579371c9d4SSatish Balay PetscErrorCode MatDestroy_SeqDense(Mat mat) {
1658ec8511deSBarry Smith   Mat_SeqDense *l = (Mat_SeqDense *)mat->data;
165990f02eecSBarry Smith 
16603a40ed3dSBarry Smith   PetscFunctionBegin;
1661aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1662c0aa6a63SJacob Faibussowitsch   PetscLogObjectState((PetscObject)mat, "Rows %" PetscInt_FMT " Cols %" PetscInt_FMT, mat->rmap->n, mat->cmap->n);
1663a5a9c739SBarry Smith #endif
16649566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(l->qrrhs)));
16659566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->tau));
16669566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->pivots));
16679566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->fwork));
16689566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&l->ptapwork));
16699566063dSJacob Faibussowitsch   if (!l->user_alloc) PetscCall(PetscFree(l->v));
16709566063dSJacob Faibussowitsch   if (!l->unplaced_user_alloc) PetscCall(PetscFree(l->unplacedarray));
167128b400f6SJacob Faibussowitsch   PetscCheck(!l->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
167228b400f6SJacob Faibussowitsch   PetscCheck(!l->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
16739566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&l->cvec));
16749566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&l->cmat));
16759566063dSJacob Faibussowitsch   PetscCall(PetscFree(mat->data));
1676dbd8c25aSHong Zhang 
16779566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)mat, NULL));
16789566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactor_C", NULL));
16792e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorSymbolic_C", NULL));
16802e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorNumeric_C", NULL));
16819566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetLDA_C", NULL));
16829566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseSetLDA_C", NULL));
16839566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArray_C", NULL));
16849566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArray_C", NULL));
16859566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDensePlaceArray_C", NULL));
16869566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseResetArray_C", NULL));
16879566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseReplaceArray_C", NULL));
16889566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayRead_C", NULL));
16899566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayRead_C", NULL));
16909566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayWrite_C", NULL));
16919566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayWrite_C", NULL));
16929566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqaij_C", NULL));
16938baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
16949566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_elemental_C", NULL));
16958baccfbdSHong Zhang #endif
1696d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
16979566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_scalapack_C", NULL));
1698d24d4204SJose E. Roman #endif
16992bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
17009566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensecuda_C", NULL));
17019566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", NULL));
17029566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdense_C", NULL));
17032e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensecuda_C", NULL));
17042bf066beSStefano Zampini #endif
17059566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatSeqDenseSetPreallocation_C", NULL));
17069566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqaij_seqdense_C", NULL));
17079566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdense_C", NULL));
17089566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqbaij_seqdense_C", NULL));
17099566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqsbaij_seqdense_C", NULL));
171052c5f739Sprj- 
17119566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumn_C", NULL));
17129566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumn_C", NULL));
17139566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVec_C", NULL));
17149566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVec_C", NULL));
17159566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecRead_C", NULL));
17169566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecRead_C", NULL));
17179566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecWrite_C", NULL));
17189566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecWrite_C", NULL));
17199566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetSubMatrix_C", NULL));
17209566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreSubMatrix_C", NULL));
17213a40ed3dSBarry Smith   PetscFunctionReturn(0);
1722289bc588SBarry Smith }
1723289bc588SBarry Smith 
17249371c9d4SSatish Balay static PetscErrorCode MatTranspose_SeqDense(Mat A, MatReuse reuse, Mat *matout) {
1725c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
17266536e3caSStefano Zampini   PetscInt      k, j, m = A->rmap->n, M = mat->lda, n = A->cmap->n;
172787828ca2SBarry Smith   PetscScalar  *v, tmp;
172848b35521SBarry Smith 
17293a40ed3dSBarry Smith   PetscFunctionBegin;
17307fb60732SBarry Smith   if (reuse == MAT_REUSE_MATRIX) PetscCall(MatTransposeCheckNonzeroState_Private(A, *matout));
17316536e3caSStefano Zampini   if (reuse == MAT_INPLACE_MATRIX) {
17326536e3caSStefano Zampini     if (m == n) { /* in place transpose */
17339566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(A, &v));
1734d3e5ee88SLois Curfman McInnes       for (j = 0; j < m; j++) {
1735289bc588SBarry Smith         for (k = 0; k < j; k++) {
17361b807ce4Svictorle           tmp          = v[j + k * M];
17371b807ce4Svictorle           v[j + k * M] = v[k + j * M];
17381b807ce4Svictorle           v[k + j * M] = tmp;
1739289bc588SBarry Smith         }
1740289bc588SBarry Smith       }
17419566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArray(A, &v));
17426536e3caSStefano Zampini     } else { /* reuse memory, temporary allocates new memory */
17436536e3caSStefano Zampini       PetscScalar *v2;
17446536e3caSStefano Zampini       PetscLayout  tmplayout;
17456536e3caSStefano Zampini 
17469566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1((size_t)m * n, &v2));
17479566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(A, &v));
17486536e3caSStefano Zampini       for (j = 0; j < n; j++) {
17496536e3caSStefano Zampini         for (k = 0; k < m; k++) v2[j + (size_t)k * n] = v[k + (size_t)j * M];
17506536e3caSStefano Zampini       }
17519566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(v, v2, (size_t)m * n));
17529566063dSJacob Faibussowitsch       PetscCall(PetscFree(v2));
17539566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArray(A, &v));
17546536e3caSStefano Zampini       /* cleanup size dependent quantities */
17559566063dSJacob Faibussowitsch       PetscCall(VecDestroy(&mat->cvec));
17569566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&mat->cmat));
17579566063dSJacob Faibussowitsch       PetscCall(PetscFree(mat->pivots));
17589566063dSJacob Faibussowitsch       PetscCall(PetscFree(mat->fwork));
17599566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&mat->ptapwork));
17606536e3caSStefano Zampini       /* swap row/col layouts */
17616536e3caSStefano Zampini       mat->lda  = n;
17626536e3caSStefano Zampini       tmplayout = A->rmap;
17636536e3caSStefano Zampini       A->rmap   = A->cmap;
17646536e3caSStefano Zampini       A->cmap   = tmplayout;
17656536e3caSStefano Zampini     }
17663a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1767d3e5ee88SLois Curfman McInnes     Mat           tmat;
1768ec8511deSBarry Smith     Mat_SeqDense *tmatd;
176987828ca2SBarry Smith     PetscScalar  *v2;
1770af36a384SStefano Zampini     PetscInt      M2;
1771ea709b57SSatish Balay 
17726536e3caSStefano Zampini     if (reuse == MAT_INITIAL_MATRIX) {
17739566063dSJacob Faibussowitsch       PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &tmat));
17749566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(tmat, A->cmap->n, A->rmap->n, A->cmap->n, A->rmap->n));
17759566063dSJacob Faibussowitsch       PetscCall(MatSetType(tmat, ((PetscObject)A)->type_name));
17769566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSetPreallocation(tmat, NULL));
1777ca15aa20SStefano Zampini     } else tmat = *matout;
1778ca15aa20SStefano Zampini 
17799566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&v));
17809566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArray(tmat, &v2));
1781ec8511deSBarry Smith     tmatd = (Mat_SeqDense *)tmat->data;
1782ca15aa20SStefano Zampini     M2    = tmatd->lda;
1783d3e5ee88SLois Curfman McInnes     for (j = 0; j < n; j++) {
1784af36a384SStefano Zampini       for (k = 0; k < m; k++) v2[j + k * M2] = v[k + j * M];
1785d3e5ee88SLois Curfman McInnes     }
17869566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(tmat, &v2));
17879566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&v));
17889566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(tmat, MAT_FINAL_ASSEMBLY));
17899566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(tmat, MAT_FINAL_ASSEMBLY));
17906536e3caSStefano Zampini     *matout = tmat;
179148b35521SBarry Smith   }
17923a40ed3dSBarry Smith   PetscFunctionReturn(0);
1793289bc588SBarry Smith }
1794289bc588SBarry Smith 
17959371c9d4SSatish Balay static PetscErrorCode MatEqual_SeqDense(Mat A1, Mat A2, PetscBool *flg) {
1796c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat1 = (Mat_SeqDense *)A1->data;
1797c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat2 = (Mat_SeqDense *)A2->data;
1798ca15aa20SStefano Zampini   PetscInt           i;
1799ca15aa20SStefano Zampini   const PetscScalar *v1, *v2;
18009ea5d5aeSSatish Balay 
18013a40ed3dSBarry Smith   PetscFunctionBegin;
18029371c9d4SSatish Balay   if (A1->rmap->n != A2->rmap->n) {
18039371c9d4SSatish Balay     *flg = PETSC_FALSE;
18049371c9d4SSatish Balay     PetscFunctionReturn(0);
18059371c9d4SSatish Balay   }
18069371c9d4SSatish Balay   if (A1->cmap->n != A2->cmap->n) {
18079371c9d4SSatish Balay     *flg = PETSC_FALSE;
18089371c9d4SSatish Balay     PetscFunctionReturn(0);
18099371c9d4SSatish Balay   }
18109566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A1, &v1));
18119566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A2, &v2));
1812ca15aa20SStefano Zampini   for (i = 0; i < A1->cmap->n; i++) {
18139566063dSJacob Faibussowitsch     PetscCall(PetscArraycmp(v1, v2, A1->rmap->n, flg));
1814ca15aa20SStefano Zampini     if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
1815ca15aa20SStefano Zampini     v1 += mat1->lda;
1816ca15aa20SStefano Zampini     v2 += mat2->lda;
18171b807ce4Svictorle   }
18189566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A1, &v1));
18199566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A2, &v2));
182077c4ece6SBarry Smith   *flg = PETSC_TRUE;
18213a40ed3dSBarry Smith   PetscFunctionReturn(0);
1822289bc588SBarry Smith }
1823289bc588SBarry Smith 
18249371c9d4SSatish Balay static PetscErrorCode MatGetDiagonal_SeqDense(Mat A, Vec v) {
1825c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
182613f74950SBarry Smith   PetscInt           i, n, len;
1827ca15aa20SStefano Zampini   PetscScalar       *x;
1828ca15aa20SStefano Zampini   const PetscScalar *vv;
182944cd7ae7SLois Curfman McInnes 
18303a40ed3dSBarry Smith   PetscFunctionBegin;
18319566063dSJacob Faibussowitsch   PetscCall(VecGetSize(v, &n));
18329566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
1833d0f46423SBarry Smith   len = PetscMin(A->rmap->n, A->cmap->n);
18349566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &vv));
183508401ef6SPierre Jolivet   PetscCheck(n == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming mat and vec");
1836ad540459SPierre Jolivet   for (i = 0; i < len; i++) x[i] = vv[i * mat->lda + i];
18379566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &vv));
18389566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
18393a40ed3dSBarry Smith   PetscFunctionReturn(0);
1840289bc588SBarry Smith }
1841289bc588SBarry Smith 
18429371c9d4SSatish Balay static PetscErrorCode MatDiagonalScale_SeqDense(Mat A, Vec ll, Vec rr) {
1843c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1844f1ceaac6SMatthew G. Knepley   const PetscScalar *l, *r;
1845ca15aa20SStefano Zampini   PetscScalar        x, *v, *vv;
1846d0f46423SBarry Smith   PetscInt           i, j, m = A->rmap->n, n = A->cmap->n;
184755659b69SBarry Smith 
18483a40ed3dSBarry Smith   PetscFunctionBegin;
18499566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &vv));
185028988994SBarry Smith   if (ll) {
18519566063dSJacob Faibussowitsch     PetscCall(VecGetSize(ll, &m));
18529566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ll, &l));
185308401ef6SPierre Jolivet     PetscCheck(m == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Left scaling vec wrong size");
1854da3a660dSBarry Smith     for (i = 0; i < m; i++) {
1855da3a660dSBarry Smith       x = l[i];
1856ca15aa20SStefano Zampini       v = vv + i;
18579371c9d4SSatish Balay       for (j = 0; j < n; j++) {
18589371c9d4SSatish Balay         (*v) *= x;
18599371c9d4SSatish Balay         v += mat->lda;
18609371c9d4SSatish Balay       }
1861da3a660dSBarry Smith     }
18629566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ll, &l));
18639566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0 * n * m));
1864da3a660dSBarry Smith   }
186528988994SBarry Smith   if (rr) {
18669566063dSJacob Faibussowitsch     PetscCall(VecGetSize(rr, &n));
18679566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(rr, &r));
186808401ef6SPierre Jolivet     PetscCheck(n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Right scaling vec wrong size");
1869da3a660dSBarry Smith     for (i = 0; i < n; i++) {
1870da3a660dSBarry Smith       x = r[i];
1871ca15aa20SStefano Zampini       v = vv + i * mat->lda;
18722205254eSKarl Rupp       for (j = 0; j < m; j++) (*v++) *= x;
1873da3a660dSBarry Smith     }
18749566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(rr, &r));
18759566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0 * n * m));
1876da3a660dSBarry Smith   }
18779566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &vv));
18783a40ed3dSBarry Smith   PetscFunctionReturn(0);
1879289bc588SBarry Smith }
1880289bc588SBarry Smith 
18819371c9d4SSatish Balay PetscErrorCode MatNorm_SeqDense(Mat A, NormType type, PetscReal *nrm) {
1882c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
1883ca15aa20SStefano Zampini   PetscScalar  *v, *vv;
1884329f5518SBarry Smith   PetscReal     sum = 0.0;
188575f6d85dSStefano Zampini   PetscInt      lda, m = A->rmap->n, i, j;
188655659b69SBarry Smith 
18873a40ed3dSBarry Smith   PetscFunctionBegin;
18889566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&vv));
18899566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(A, &lda));
1890ca15aa20SStefano Zampini   v = vv;
1891289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1892a5ce6ee0Svictorle     if (lda > m) {
1893d0f46423SBarry Smith       for (j = 0; j < A->cmap->n; j++) {
1894ca15aa20SStefano Zampini         v = vv + j * lda;
1895a5ce6ee0Svictorle         for (i = 0; i < m; i++) {
18969371c9d4SSatish Balay           sum += PetscRealPart(PetscConj(*v) * (*v));
18979371c9d4SSatish Balay           v++;
1898a5ce6ee0Svictorle         }
1899a5ce6ee0Svictorle       }
1900a5ce6ee0Svictorle     } else {
1901570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1902570b7f6dSBarry Smith       PetscBLASInt one = 1, cnt = A->cmap->n * A->rmap->n;
1903792fecdfSBarry Smith       PetscCallBLAS("BLASnrm2", *nrm = BLASnrm2_(&cnt, v, &one));
1904570b7f6dSBarry Smith     }
1905570b7f6dSBarry Smith #else
1906d0f46423SBarry Smith       for (i = 0; i < A->cmap->n * A->rmap->n; i++) {
19079371c9d4SSatish Balay         sum += PetscRealPart(PetscConj(*v) * (*v));
19089371c9d4SSatish Balay         v++;
1909289bc588SBarry Smith       }
1910a5ce6ee0Svictorle     }
19118f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1912570b7f6dSBarry Smith #endif
19139566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0 * A->cmap->n * A->rmap->n));
19143a40ed3dSBarry Smith   } else if (type == NORM_1) {
1915064f8208SBarry Smith     *nrm = 0.0;
1916d0f46423SBarry Smith     for (j = 0; j < A->cmap->n; j++) {
1917ca15aa20SStefano Zampini       v   = vv + j * mat->lda;
1918289bc588SBarry Smith       sum = 0.0;
1919d0f46423SBarry Smith       for (i = 0; i < A->rmap->n; i++) {
19209371c9d4SSatish Balay         sum += PetscAbsScalar(*v);
19219371c9d4SSatish Balay         v++;
1922289bc588SBarry Smith       }
1923064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1924289bc588SBarry Smith     }
19259566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n));
19263a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1927064f8208SBarry Smith     *nrm = 0.0;
1928d0f46423SBarry Smith     for (j = 0; j < A->rmap->n; j++) {
1929ca15aa20SStefano Zampini       v   = vv + j;
1930289bc588SBarry Smith       sum = 0.0;
1931d0f46423SBarry Smith       for (i = 0; i < A->cmap->n; i++) {
19329371c9d4SSatish Balay         sum += PetscAbsScalar(*v);
19339371c9d4SSatish Balay         v += mat->lda;
1934289bc588SBarry Smith       }
1935064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1936289bc588SBarry Smith     }
19379566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n));
1938e7e72b3dSBarry Smith   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "No two norm");
19399566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&vv));
19403a40ed3dSBarry Smith   PetscFunctionReturn(0);
1941289bc588SBarry Smith }
1942289bc588SBarry Smith 
19439371c9d4SSatish Balay static PetscErrorCode MatSetOption_SeqDense(Mat A, MatOption op, PetscBool flg) {
1944c0bbcb79SLois Curfman McInnes   Mat_SeqDense *aij = (Mat_SeqDense *)A->data;
194567e560aaSBarry Smith 
19463a40ed3dSBarry Smith   PetscFunctionBegin;
1947b5a2b587SKris Buschelman   switch (op) {
19489371c9d4SSatish Balay   case MAT_ROW_ORIENTED: aij->roworiented = flg; break;
1949512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1950b5a2b587SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
19513971808eSMatthew Knepley   case MAT_NEW_NONZERO_ALLOCATION_ERR:
19528c78258cSHong Zhang   case MAT_FORCE_DIAGONAL_ENTRIES:
195313fa8e87SLisandro Dalcin   case MAT_KEEP_NONZERO_PATTERN:
1954b5a2b587SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1955b5a2b587SKris Buschelman   case MAT_USE_HASH_TABLE:
19560f8fb01aSBarry Smith   case MAT_IGNORE_ZERO_ENTRIES:
19575021d80fSJed Brown   case MAT_IGNORE_LOWER_TRIANGULAR:
19589371c9d4SSatish Balay   case MAT_SORTED_FULL: PetscCall(PetscInfo(A, "Option %s ignored\n", MatOptions[op])); break;
19595021d80fSJed Brown   case MAT_SPD:
196077e54ba9SKris Buschelman   case MAT_SYMMETRIC:
196177e54ba9SKris Buschelman   case MAT_STRUCTURALLY_SYMMETRIC:
19629a4540c5SBarry Smith   case MAT_HERMITIAN:
19639a4540c5SBarry Smith   case MAT_SYMMETRY_ETERNAL:
1964b94d7dedSBarry Smith   case MAT_STRUCTURAL_SYMMETRY_ETERNAL:
19659371c9d4SSatish Balay   case MAT_SPD_ETERNAL: break;
19669371c9d4SSatish Balay   default: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "unknown option %s", MatOptions[op]);
19673a40ed3dSBarry Smith   }
19683a40ed3dSBarry Smith   PetscFunctionReturn(0);
1969289bc588SBarry Smith }
1970289bc588SBarry Smith 
19719371c9d4SSatish Balay PetscErrorCode MatZeroEntries_SeqDense(Mat A) {
1972ec8511deSBarry Smith   Mat_SeqDense *l   = (Mat_SeqDense *)A->data;
19733d8925e7SStefano Zampini   PetscInt      lda = l->lda, m = A->rmap->n, n = A->cmap->n, j;
1974ca15aa20SStefano Zampini   PetscScalar  *v;
19753a40ed3dSBarry Smith 
19763a40ed3dSBarry Smith   PetscFunctionBegin;
19779566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(A, &v));
1978a5ce6ee0Svictorle   if (lda > m) {
197948a46eb9SPierre Jolivet     for (j = 0; j < n; j++) PetscCall(PetscArrayzero(v + j * lda, m));
1980a5ce6ee0Svictorle   } else {
19819566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(v, PetscInt64Mult(m, n)));
1982a5ce6ee0Svictorle   }
19839566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(A, &v));
19843a40ed3dSBarry Smith   PetscFunctionReturn(0);
19856f0a148fSBarry Smith }
19866f0a148fSBarry Smith 
19879371c9d4SSatish Balay static PetscErrorCode MatZeroRows_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) {
1988ec8511deSBarry Smith   Mat_SeqDense      *l = (Mat_SeqDense *)A->data;
1989b9679d65SBarry Smith   PetscInt           m = l->lda, n = A->cmap->n, i, j;
1990ca15aa20SStefano Zampini   PetscScalar       *slot, *bb, *v;
199197b48c8fSBarry Smith   const PetscScalar *xx;
199255659b69SBarry Smith 
19933a40ed3dSBarry Smith   PetscFunctionBegin;
199476bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
1995b9679d65SBarry Smith     for (i = 0; i < N; i++) {
199608401ef6SPierre Jolivet       PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed");
199708401ef6SPierre 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);
1998b9679d65SBarry Smith     }
199976bd3646SJed Brown   }
2000ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
2001b9679d65SBarry Smith 
200297b48c8fSBarry Smith   /* fix right hand side if needed */
200397b48c8fSBarry Smith   if (x && b) {
20049566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(x, &xx));
20059566063dSJacob Faibussowitsch     PetscCall(VecGetArray(b, &bb));
20062205254eSKarl Rupp     for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]];
20079566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(x, &xx));
20089566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(b, &bb));
200997b48c8fSBarry Smith   }
201097b48c8fSBarry Smith 
20119566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
20126f0a148fSBarry Smith   for (i = 0; i < N; i++) {
2013ca15aa20SStefano Zampini     slot = v + rows[i];
20149371c9d4SSatish Balay     for (j = 0; j < n; j++) {
20159371c9d4SSatish Balay       *slot = 0.0;
20169371c9d4SSatish Balay       slot += m;
20179371c9d4SSatish Balay     }
20186f0a148fSBarry Smith   }
2019f4df32b1SMatthew Knepley   if (diag != 0.0) {
202008401ef6SPierre Jolivet     PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices");
20216f0a148fSBarry Smith     for (i = 0; i < N; i++) {
2022ca15aa20SStefano Zampini       slot  = v + (m + 1) * rows[i];
2023f4df32b1SMatthew Knepley       *slot = diag;
20246f0a148fSBarry Smith     }
20256f0a148fSBarry Smith   }
20269566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
20273a40ed3dSBarry Smith   PetscFunctionReturn(0);
20286f0a148fSBarry Smith }
2029557bce09SLois Curfman McInnes 
20309371c9d4SSatish Balay static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A, PetscInt *lda) {
203149a6ff4bSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
203249a6ff4bSBarry Smith 
203349a6ff4bSBarry Smith   PetscFunctionBegin;
203449a6ff4bSBarry Smith   *lda = mat->lda;
203549a6ff4bSBarry Smith   PetscFunctionReturn(0);
203649a6ff4bSBarry Smith }
203749a6ff4bSBarry Smith 
20389371c9d4SSatish Balay PetscErrorCode MatDenseGetArray_SeqDense(Mat A, PetscScalar **array) {
2039c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
20403a40ed3dSBarry Smith 
20413a40ed3dSBarry Smith   PetscFunctionBegin;
204228b400f6SJacob Faibussowitsch   PetscCheck(!mat->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
204364e87e97SBarry Smith   *array = mat->v;
20443a40ed3dSBarry Smith   PetscFunctionReturn(0);
204564e87e97SBarry Smith }
20460754003eSLois Curfman McInnes 
20479371c9d4SSatish Balay PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A, PetscScalar **array) {
20483a40ed3dSBarry Smith   PetscFunctionBegin;
204975f6d85dSStefano Zampini   if (array) *array = NULL;
20503a40ed3dSBarry Smith   PetscFunctionReturn(0);
2051ff14e315SSatish Balay }
20520754003eSLois Curfman McInnes 
20530f74d2c1SSatish Balay /*@
205411a5261eSBarry Smith    MatDenseGetLDA - gets the leading dimension of the array returned from `MatDenseGetArray()`
205549a6ff4bSBarry Smith 
2056ad16ce7aSStefano Zampini    Not collective
205749a6ff4bSBarry Smith 
205849a6ff4bSBarry Smith    Input Parameter:
205911a5261eSBarry Smith .  mat - a `MATDENSE` or `MATDENSECUDA` matrix
206049a6ff4bSBarry Smith 
206149a6ff4bSBarry Smith    Output Parameter:
206249a6ff4bSBarry Smith .   lda - the leading dimension
206349a6ff4bSBarry Smith 
206449a6ff4bSBarry Smith    Level: intermediate
206549a6ff4bSBarry Smith 
206611a5261eSBarry Smith .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseSetLDA()`
206749a6ff4bSBarry Smith @*/
20689371c9d4SSatish Balay PetscErrorCode MatDenseGetLDA(Mat A, PetscInt *lda) {
206949a6ff4bSBarry Smith   PetscFunctionBegin;
2070d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2071dadcf809SJacob Faibussowitsch   PetscValidIntPointer(lda, 2);
207275f6d85dSStefano Zampini   MatCheckPreallocated(A, 1);
2073cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetLDA_C", (Mat, PetscInt *), (A, lda));
207449a6ff4bSBarry Smith   PetscFunctionReturn(0);
207549a6ff4bSBarry Smith }
207649a6ff4bSBarry Smith 
20770f74d2c1SSatish Balay /*@
207811a5261eSBarry Smith    MatDenseSetLDA - Sets the leading dimension of the array used by the `MATDENSE` matrix
2079ad16ce7aSStefano Zampini 
2080ad16ce7aSStefano Zampini    Not collective
2081ad16ce7aSStefano Zampini 
2082d8d19677SJose E. Roman    Input Parameters:
208311a5261eSBarry Smith +  mat - a `MATDENSE` or `MATDENSECUDA` matrix
2084ad16ce7aSStefano Zampini -  lda - the leading dimension
2085ad16ce7aSStefano Zampini 
2086ad16ce7aSStefano Zampini    Level: intermediate
2087ad16ce7aSStefano Zampini 
208811a5261eSBarry Smith .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetLDA()`
2089ad16ce7aSStefano Zampini @*/
20909371c9d4SSatish Balay PetscErrorCode MatDenseSetLDA(Mat A, PetscInt lda) {
2091ad16ce7aSStefano Zampini   PetscFunctionBegin;
2092ad16ce7aSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2093cac4c232SBarry Smith   PetscTryMethod(A, "MatDenseSetLDA_C", (Mat, PetscInt), (A, lda));
2094ad16ce7aSStefano Zampini   PetscFunctionReturn(0);
2095ad16ce7aSStefano Zampini }
2096ad16ce7aSStefano Zampini 
2097ad16ce7aSStefano Zampini /*@C
209811a5261eSBarry Smith    MatDenseGetArray - gives read-write access to the array where the data for a `MATDENSE` matrix is stored
209973a71a0fSBarry Smith 
210011a5261eSBarry Smith    Logically Collective on A
210173a71a0fSBarry Smith 
210273a71a0fSBarry Smith    Input Parameter:
21036947451fSStefano Zampini .  mat - a dense matrix
210473a71a0fSBarry Smith 
210573a71a0fSBarry Smith    Output Parameter:
210673a71a0fSBarry Smith .   array - pointer to the data
210773a71a0fSBarry Smith 
210873a71a0fSBarry Smith    Level: intermediate
210973a71a0fSBarry Smith 
211011a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
211173a71a0fSBarry Smith @*/
21129371c9d4SSatish Balay PetscErrorCode MatDenseGetArray(Mat A, PetscScalar **array) {
211373a71a0fSBarry Smith   PetscFunctionBegin;
2114d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2115d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2116cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array));
211773a71a0fSBarry Smith   PetscFunctionReturn(0);
211873a71a0fSBarry Smith }
211973a71a0fSBarry Smith 
2120dec5eb66SMatthew G Knepley /*@C
212111a5261eSBarry Smith    MatDenseRestoreArray - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArray()`
212273a71a0fSBarry Smith 
212311a5261eSBarry Smith    Logically Collective on A
21248572280aSBarry Smith 
21258572280aSBarry Smith    Input Parameters:
21266947451fSStefano Zampini +  mat - a dense matrix
2127742765d3SMatthew Knepley -  array - pointer to the data (may be NULL)
21288572280aSBarry Smith 
21298572280aSBarry Smith    Level: intermediate
21308572280aSBarry Smith 
213111a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
21328572280aSBarry Smith @*/
21339371c9d4SSatish Balay PetscErrorCode MatDenseRestoreArray(Mat A, PetscScalar **array) {
21348572280aSBarry Smith   PetscFunctionBegin;
2135d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2136d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2137cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array));
21389566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)A));
2139637a0070SStefano Zampini #if defined(PETSC_HAVE_CUDA)
2140637a0070SStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
2141637a0070SStefano Zampini #endif
21428572280aSBarry Smith   PetscFunctionReturn(0);
21438572280aSBarry Smith }
21448572280aSBarry Smith 
21458572280aSBarry Smith /*@C
214611a5261eSBarry Smith   MatDenseGetArrayRead - gives read-only access to the array where the data for a `MATDENSE`  matrix is stored
21478572280aSBarry Smith 
21488572280aSBarry Smith    Not Collective
21498572280aSBarry Smith 
21508572280aSBarry Smith    Input Parameter:
21516947451fSStefano Zampini .  mat - a dense matrix
21528572280aSBarry Smith 
21538572280aSBarry Smith    Output Parameter:
21548572280aSBarry Smith .   array - pointer to the data
21558572280aSBarry Smith 
21568572280aSBarry Smith    Level: intermediate
21578572280aSBarry Smith 
215811a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
21598572280aSBarry Smith @*/
21609371c9d4SSatish Balay PetscErrorCode MatDenseGetArrayRead(Mat A, const PetscScalar **array) {
21618572280aSBarry Smith   PetscFunctionBegin;
2162d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2163d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2164cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, const PetscScalar **), (A, array));
21658572280aSBarry Smith   PetscFunctionReturn(0);
21668572280aSBarry Smith }
21678572280aSBarry Smith 
21688572280aSBarry Smith /*@C
216911a5261eSBarry Smith    MatDenseRestoreArrayRead - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayRead()`
21708572280aSBarry Smith 
217173a71a0fSBarry Smith    Not Collective
217273a71a0fSBarry Smith 
217373a71a0fSBarry Smith    Input Parameters:
21746947451fSStefano Zampini +  mat - a dense matrix
2175742765d3SMatthew Knepley -  array - pointer to the data (may be NULL)
217673a71a0fSBarry Smith 
217773a71a0fSBarry Smith    Level: intermediate
217873a71a0fSBarry Smith 
217911a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
218073a71a0fSBarry Smith @*/
21819371c9d4SSatish Balay PetscErrorCode MatDenseRestoreArrayRead(Mat A, const PetscScalar **array) {
218273a71a0fSBarry Smith   PetscFunctionBegin;
2183d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2184d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2185cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, const PetscScalar **), (A, array));
218673a71a0fSBarry Smith   PetscFunctionReturn(0);
218773a71a0fSBarry Smith }
218873a71a0fSBarry Smith 
21896947451fSStefano Zampini /*@C
219011a5261eSBarry Smith    MatDenseGetArrayWrite - gives write-only access to the array where the data for a `MATDENSE` matrix is stored
21916947451fSStefano Zampini 
21926947451fSStefano Zampini    Not Collective
21936947451fSStefano Zampini 
21946947451fSStefano Zampini    Input Parameter:
21956947451fSStefano Zampini .  mat - a dense matrix
21966947451fSStefano Zampini 
21976947451fSStefano Zampini    Output Parameter:
21986947451fSStefano Zampini .   array - pointer to the data
21996947451fSStefano Zampini 
22006947451fSStefano Zampini    Level: intermediate
22016947451fSStefano Zampini 
220211a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`
22036947451fSStefano Zampini @*/
22049371c9d4SSatish Balay PetscErrorCode MatDenseGetArrayWrite(Mat A, PetscScalar **array) {
22056947451fSStefano Zampini   PetscFunctionBegin;
2206d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2207d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2208cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array));
22096947451fSStefano Zampini   PetscFunctionReturn(0);
22106947451fSStefano Zampini }
22116947451fSStefano Zampini 
22126947451fSStefano Zampini /*@C
221311a5261eSBarry Smith    MatDenseRestoreArrayWrite - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayWrite()`
22146947451fSStefano Zampini 
22156947451fSStefano Zampini    Not Collective
22166947451fSStefano Zampini 
22176947451fSStefano Zampini    Input Parameters:
22186947451fSStefano Zampini +  mat - a dense matrix
2219742765d3SMatthew Knepley -  array - pointer to the data (may be NULL)
22206947451fSStefano Zampini 
22216947451fSStefano Zampini    Level: intermediate
22226947451fSStefano Zampini 
222311a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`
22246947451fSStefano Zampini @*/
22259371c9d4SSatish Balay PetscErrorCode MatDenseRestoreArrayWrite(Mat A, PetscScalar **array) {
22266947451fSStefano Zampini   PetscFunctionBegin;
2227d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2228d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2229cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array));
22309566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)A));
22316947451fSStefano Zampini #if defined(PETSC_HAVE_CUDA)
22326947451fSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
22336947451fSStefano Zampini #endif
22346947451fSStefano Zampini   PetscFunctionReturn(0);
22356947451fSStefano Zampini }
22366947451fSStefano Zampini 
22379371c9d4SSatish Balay static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A, IS isrow, IS iscol, MatReuse scall, Mat *B) {
2238c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense *)A->data;
2239bf5a80bcSToby Isaac   PetscInt        i, j, nrows, ncols, ldb;
22405d0c19d7SBarry Smith   const PetscInt *irow, *icol;
224187828ca2SBarry Smith   PetscScalar    *av, *bv, *v = mat->v;
22420754003eSLois Curfman McInnes   Mat             newmat;
22430754003eSLois Curfman McInnes 
22443a40ed3dSBarry Smith   PetscFunctionBegin;
22459566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(isrow, &irow));
22469566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(iscol, &icol));
22479566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(isrow, &nrows));
22489566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(iscol, &ncols));
22490754003eSLois Curfman McInnes 
2250182d2002SSatish Balay   /* Check submatrixcall */
2251182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
225213f74950SBarry Smith     PetscInt n_cols, n_rows;
22539566063dSJacob Faibussowitsch     PetscCall(MatGetSize(*B, &n_rows, &n_cols));
225421a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
2255f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
22569566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(*B, nrows, ncols, nrows, ncols));
225721a2c019SBarry Smith     }
2258182d2002SSatish Balay     newmat = *B;
2259182d2002SSatish Balay   } else {
22600754003eSLois Curfman McInnes     /* Create and fill new matrix */
22619566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &newmat));
22629566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(newmat, nrows, ncols, nrows, ncols));
22639566063dSJacob Faibussowitsch     PetscCall(MatSetType(newmat, ((PetscObject)A)->type_name));
22649566063dSJacob Faibussowitsch     PetscCall(MatSeqDenseSetPreallocation(newmat, NULL));
2265182d2002SSatish Balay   }
2266182d2002SSatish Balay 
2267182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
22689566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(newmat, &bv));
22699566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(newmat, &ldb));
2270182d2002SSatish Balay   for (i = 0; i < ncols; i++) {
22716de62eeeSBarry Smith     av = v + mat->lda * icol[i];
2272ca15aa20SStefano Zampini     for (j = 0; j < nrows; j++) bv[j] = av[irow[j]];
2273bf5a80bcSToby Isaac     bv += ldb;
22740754003eSLois Curfman McInnes   }
22759566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(newmat, &bv));
2276182d2002SSatish Balay 
2277182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
22789566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(newmat, MAT_FINAL_ASSEMBLY));
22799566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(newmat, MAT_FINAL_ASSEMBLY));
22800754003eSLois Curfman McInnes 
22810754003eSLois Curfman McInnes   /* Free work space */
22829566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(isrow, &irow));
22839566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(iscol, &icol));
2284182d2002SSatish Balay   *B = newmat;
22853a40ed3dSBarry Smith   PetscFunctionReturn(0);
22860754003eSLois Curfman McInnes }
22870754003eSLois Curfman McInnes 
22889371c9d4SSatish Balay static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A, PetscInt n, const IS irow[], const IS icol[], MatReuse scall, Mat *B[]) {
228913f74950SBarry Smith   PetscInt i;
2290905e6a2fSBarry Smith 
22913a40ed3dSBarry Smith   PetscFunctionBegin;
229248a46eb9SPierre Jolivet   if (scall == MAT_INITIAL_MATRIX) PetscCall(PetscCalloc1(n, B));
2293905e6a2fSBarry Smith 
229448a46eb9SPierre Jolivet   for (i = 0; i < n; i++) PetscCall(MatCreateSubMatrix_SeqDense(A, irow[i], icol[i], scall, &(*B)[i]));
22953a40ed3dSBarry Smith   PetscFunctionReturn(0);
2296905e6a2fSBarry Smith }
2297905e6a2fSBarry Smith 
22989371c9d4SSatish Balay static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat, MatAssemblyType mode) {
2299c0aa2d19SHong Zhang   PetscFunctionBegin;
2300c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2301c0aa2d19SHong Zhang }
2302c0aa2d19SHong Zhang 
23039371c9d4SSatish Balay static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat, MatAssemblyType mode) {
2304c0aa2d19SHong Zhang   PetscFunctionBegin;
2305c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2306c0aa2d19SHong Zhang }
2307c0aa2d19SHong Zhang 
23089371c9d4SSatish Balay PetscErrorCode MatCopy_SeqDense(Mat A, Mat B, MatStructure str) {
23094b0e389bSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data;
2310ca15aa20SStefano Zampini   const PetscScalar *va;
2311ca15aa20SStefano Zampini   PetscScalar       *vb;
2312d0f46423SBarry Smith   PetscInt           lda1 = a->lda, lda2 = b->lda, m = A->rmap->n, n = A->cmap->n, j;
23133a40ed3dSBarry Smith 
23143a40ed3dSBarry Smith   PetscFunctionBegin;
231533f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
231633f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
23179566063dSJacob Faibussowitsch     PetscCall(MatCopy_Basic(A, B, str));
23183a40ed3dSBarry Smith     PetscFunctionReturn(0);
23193a40ed3dSBarry Smith   }
2320aed4548fSBarry Smith   PetscCheck(m == B->rmap->n && n == B->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "size(B) != size(A)");
23219566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &va));
23229566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(B, &vb));
2323a5ce6ee0Svictorle   if (lda1 > m || lda2 > m) {
232448a46eb9SPierre Jolivet     for (j = 0; j < n; j++) PetscCall(PetscArraycpy(vb + j * lda2, va + j * lda1, m));
2325a5ce6ee0Svictorle   } else {
23269566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(vb, va, A->rmap->n * A->cmap->n));
2327a5ce6ee0Svictorle   }
23289566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(B, &vb));
23299566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &va));
23309566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY));
23319566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY));
2332273d9f13SBarry Smith   PetscFunctionReturn(0);
2333273d9f13SBarry Smith }
2334273d9f13SBarry Smith 
23359371c9d4SSatish Balay PetscErrorCode MatSetUp_SeqDense(Mat A) {
2336273d9f13SBarry Smith   PetscFunctionBegin;
23379566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(A->rmap));
23389566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(A->cmap));
233948a46eb9SPierre Jolivet   if (!A->preallocated) PetscCall(MatSeqDenseSetPreallocation(A, NULL));
23403a40ed3dSBarry Smith   PetscFunctionReturn(0);
23414b0e389bSBarry Smith }
23424b0e389bSBarry Smith 
23439371c9d4SSatish Balay static PetscErrorCode MatConjugate_SeqDense(Mat A) {
23444396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
234506c5243aSJose E. Roman   PetscInt      i, j;
23464396437dSToby Isaac   PetscInt      min = PetscMin(A->rmap->n, A->cmap->n);
2347ca15aa20SStefano Zampini   PetscScalar  *aa;
2348ba337c44SJed Brown 
2349ba337c44SJed Brown   PetscFunctionBegin;
23509566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &aa));
235106c5243aSJose E. Roman   for (j = 0; j < A->cmap->n; j++) {
235206c5243aSJose E. Roman     for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscConj(aa[i + j * mat->lda]);
235306c5243aSJose E. Roman   }
23549566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &aa));
23559371c9d4SSatish Balay   if (mat->tau)
23569371c9d4SSatish Balay     for (i = 0; i < min; i++) mat->tau[i] = PetscConj(mat->tau[i]);
2357ba337c44SJed Brown   PetscFunctionReturn(0);
2358ba337c44SJed Brown }
2359ba337c44SJed Brown 
23609371c9d4SSatish Balay static PetscErrorCode MatRealPart_SeqDense(Mat A) {
236106c5243aSJose E. Roman   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
236206c5243aSJose E. Roman   PetscInt      i, j;
2363ca15aa20SStefano Zampini   PetscScalar  *aa;
2364ba337c44SJed Brown 
2365ba337c44SJed Brown   PetscFunctionBegin;
23669566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &aa));
236706c5243aSJose E. Roman   for (j = 0; j < A->cmap->n; j++) {
236806c5243aSJose E. Roman     for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscRealPart(aa[i + j * mat->lda]);
236906c5243aSJose E. Roman   }
23709566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &aa));
2371ba337c44SJed Brown   PetscFunctionReturn(0);
2372ba337c44SJed Brown }
2373ba337c44SJed Brown 
23749371c9d4SSatish Balay static PetscErrorCode MatImaginaryPart_SeqDense(Mat A) {
237506c5243aSJose E. Roman   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
237606c5243aSJose E. Roman   PetscInt      i, j;
2377ca15aa20SStefano Zampini   PetscScalar  *aa;
2378ba337c44SJed Brown 
2379ba337c44SJed Brown   PetscFunctionBegin;
23809566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &aa));
238106c5243aSJose E. Roman   for (j = 0; j < A->cmap->n; j++) {
238206c5243aSJose E. Roman     for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscImaginaryPart(aa[i + j * mat->lda]);
238306c5243aSJose E. Roman   }
23849566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &aa));
2385ba337c44SJed Brown   PetscFunctionReturn(0);
2386ba337c44SJed Brown }
2387284134d9SBarry Smith 
2388a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/
23899371c9d4SSatish Balay PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) {
2390d0f46423SBarry Smith   PetscInt  m = A->rmap->n, n = B->cmap->n;
23917a3c3d58SStefano Zampini   PetscBool cisdense;
2392a9fe9ddaSSatish Balay 
2393ee16a9a1SHong Zhang   PetscFunctionBegin;
23949566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C, m, n, m, n));
23959566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, ""));
23967a3c3d58SStefano Zampini   if (!cisdense) {
23977a3c3d58SStefano Zampini     PetscBool flg;
23987a3c3d58SStefano Zampini 
23999566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg));
24009566063dSJacob Faibussowitsch     PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE));
24017a3c3d58SStefano Zampini   }
24029566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
2403ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2404ee16a9a1SHong Zhang }
2405a9fe9ddaSSatish Balay 
24069371c9d4SSatish Balay PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) {
24076718818eSStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data, *c = (Mat_SeqDense *)C->data;
24080805154bSBarry Smith   PetscBLASInt       m, n, k;
2409ca15aa20SStefano Zampini   const PetscScalar *av, *bv;
2410ca15aa20SStefano Zampini   PetscScalar       *cv;
2411a9fe9ddaSSatish Balay   PetscScalar        _DOne = 1.0, _DZero = 0.0;
2412a9fe9ddaSSatish Balay 
2413a9fe9ddaSSatish Balay   PetscFunctionBegin;
24149566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n, &m));
24159566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n, &n));
24169566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &k));
241749d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
24189566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &av));
24199566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B, &bv));
24209566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C, &cv));
2421792fecdfSBarry Smith   PetscCallBLAS("BLASgemm", BLASgemm_("N", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda));
24229566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1)));
24239566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &av));
24249566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B, &bv));
24259566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C, &cv));
2426a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2427a9fe9ddaSSatish Balay }
2428a9fe9ddaSSatish Balay 
24299371c9d4SSatish Balay PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) {
243069f65d41SStefano Zampini   PetscInt  m = A->rmap->n, n = B->rmap->n;
24317a3c3d58SStefano Zampini   PetscBool cisdense;
243269f65d41SStefano Zampini 
243369f65d41SStefano Zampini   PetscFunctionBegin;
24349566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C, m, n, m, n));
24359566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, ""));
24367a3c3d58SStefano Zampini   if (!cisdense) {
24377a3c3d58SStefano Zampini     PetscBool flg;
24387a3c3d58SStefano Zampini 
24399566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg));
24409566063dSJacob Faibussowitsch     PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE));
24417a3c3d58SStefano Zampini   }
24429566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
244369f65d41SStefano Zampini   PetscFunctionReturn(0);
244469f65d41SStefano Zampini }
244569f65d41SStefano Zampini 
24469371c9d4SSatish Balay PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) {
244769f65d41SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
244869f65d41SStefano Zampini   Mat_SeqDense      *b = (Mat_SeqDense *)B->data;
244969f65d41SStefano Zampini   Mat_SeqDense      *c = (Mat_SeqDense *)C->data;
24506718818eSStefano Zampini   const PetscScalar *av, *bv;
24516718818eSStefano Zampini   PetscScalar       *cv;
245269f65d41SStefano Zampini   PetscBLASInt       m, n, k;
245369f65d41SStefano Zampini   PetscScalar        _DOne = 1.0, _DZero = 0.0;
245469f65d41SStefano Zampini 
245569f65d41SStefano Zampini   PetscFunctionBegin;
24569566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n, &m));
24579566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n, &n));
24589566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &k));
245949d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
24609566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &av));
24619566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B, &bv));
24629566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C, &cv));
2463792fecdfSBarry Smith   PetscCallBLAS("BLASgemm", BLASgemm_("N", "T", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda));
24649566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &av));
24659566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B, &bv));
24669566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C, &cv));
24679566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1)));
246869f65d41SStefano Zampini   PetscFunctionReturn(0);
246969f65d41SStefano Zampini }
247069f65d41SStefano Zampini 
24719371c9d4SSatish Balay PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) {
2472d0f46423SBarry Smith   PetscInt  m = A->cmap->n, n = B->cmap->n;
24737a3c3d58SStefano Zampini   PetscBool cisdense;
2474a9fe9ddaSSatish Balay 
2475ee16a9a1SHong Zhang   PetscFunctionBegin;
24769566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C, m, n, m, n));
24779566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, ""));
24787a3c3d58SStefano Zampini   if (!cisdense) {
24797a3c3d58SStefano Zampini     PetscBool flg;
24807a3c3d58SStefano Zampini 
24819566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg));
24829566063dSJacob Faibussowitsch     PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE));
24837a3c3d58SStefano Zampini   }
24849566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
2485ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2486ee16a9a1SHong Zhang }
2487a9fe9ddaSSatish Balay 
24889371c9d4SSatish Balay PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) {
2489a9fe9ddaSSatish Balay   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
2490a9fe9ddaSSatish Balay   Mat_SeqDense      *b = (Mat_SeqDense *)B->data;
2491a9fe9ddaSSatish Balay   Mat_SeqDense      *c = (Mat_SeqDense *)C->data;
24926718818eSStefano Zampini   const PetscScalar *av, *bv;
24936718818eSStefano Zampini   PetscScalar       *cv;
24940805154bSBarry Smith   PetscBLASInt       m, n, k;
2495a9fe9ddaSSatish Balay   PetscScalar        _DOne = 1.0, _DZero = 0.0;
2496a9fe9ddaSSatish Balay 
2497a9fe9ddaSSatish Balay   PetscFunctionBegin;
24989566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n, &m));
24999566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n, &n));
25009566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &k));
250149d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
25029566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &av));
25039566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B, &bv));
25049566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C, &cv));
2505792fecdfSBarry Smith   PetscCallBLAS("BLASgemm", BLASgemm_("T", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda));
25069566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &av));
25079566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B, &bv));
25089566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C, &cv));
25099566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1)));
2510a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2511a9fe9ddaSSatish Balay }
2512985db425SBarry Smith 
25134222ddf1SHong Zhang /* ----------------------------------------------- */
25149371c9d4SSatish Balay static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C) {
25154222ddf1SHong Zhang   PetscFunctionBegin;
25164222ddf1SHong Zhang   C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense;
25174222ddf1SHong Zhang   C->ops->productsymbolic = MatProductSymbolic_AB;
25184222ddf1SHong Zhang   PetscFunctionReturn(0);
25194222ddf1SHong Zhang }
25204222ddf1SHong Zhang 
25219371c9d4SSatish Balay static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C) {
25224222ddf1SHong Zhang   PetscFunctionBegin;
25234222ddf1SHong Zhang   C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense;
25244222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_AtB;
25254222ddf1SHong Zhang   PetscFunctionReturn(0);
25264222ddf1SHong Zhang }
25274222ddf1SHong Zhang 
25289371c9d4SSatish Balay static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C) {
25294222ddf1SHong Zhang   PetscFunctionBegin;
25304222ddf1SHong Zhang   C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense;
25314222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_ABt;
25324222ddf1SHong Zhang   PetscFunctionReturn(0);
25334222ddf1SHong Zhang }
25344222ddf1SHong Zhang 
25359371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C) {
25364222ddf1SHong Zhang   Mat_Product *product = C->product;
25374222ddf1SHong Zhang 
25384222ddf1SHong Zhang   PetscFunctionBegin;
25394222ddf1SHong Zhang   switch (product->type) {
25409371c9d4SSatish Balay   case MATPRODUCT_AB: PetscCall(MatProductSetFromOptions_SeqDense_AB(C)); break;
25419371c9d4SSatish Balay   case MATPRODUCT_AtB: PetscCall(MatProductSetFromOptions_SeqDense_AtB(C)); break;
25429371c9d4SSatish Balay   case MATPRODUCT_ABt: PetscCall(MatProductSetFromOptions_SeqDense_ABt(C)); break;
25439371c9d4SSatish Balay   default: break;
25444222ddf1SHong Zhang   }
25454222ddf1SHong Zhang   PetscFunctionReturn(0);
25464222ddf1SHong Zhang }
25474222ddf1SHong Zhang /* ----------------------------------------------- */
25484222ddf1SHong Zhang 
25499371c9d4SSatish Balay static PetscErrorCode MatGetRowMax_SeqDense(Mat A, Vec v, PetscInt idx[]) {
2550985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
2551d0f46423SBarry Smith   PetscInt           i, j, m = A->rmap->n, n = A->cmap->n, p;
2552985db425SBarry Smith   PetscScalar       *x;
2553ca15aa20SStefano Zampini   const PetscScalar *aa;
2554985db425SBarry Smith 
2555985db425SBarry Smith   PetscFunctionBegin;
255628b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
25579566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
25589566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v, &p));
25599566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
256008401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector");
2561985db425SBarry Smith   for (i = 0; i < m; i++) {
25629371c9d4SSatish Balay     x[i] = aa[i];
25639371c9d4SSatish Balay     if (idx) idx[i] = 0;
2564985db425SBarry Smith     for (j = 1; j < n; j++) {
25659371c9d4SSatish Balay       if (PetscRealPart(x[i]) < PetscRealPart(aa[i + a->lda * j])) {
25669371c9d4SSatish Balay         x[i] = aa[i + a->lda * j];
25679371c9d4SSatish Balay         if (idx) idx[i] = j;
25689371c9d4SSatish Balay       }
2569985db425SBarry Smith     }
2570985db425SBarry Smith   }
25719566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
25729566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
2573985db425SBarry Smith   PetscFunctionReturn(0);
2574985db425SBarry Smith }
2575985db425SBarry Smith 
25769371c9d4SSatish Balay static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A, Vec v, PetscInt idx[]) {
2577985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
2578d0f46423SBarry Smith   PetscInt           i, j, m = A->rmap->n, n = A->cmap->n, p;
2579985db425SBarry Smith   PetscScalar       *x;
2580985db425SBarry Smith   PetscReal          atmp;
2581ca15aa20SStefano Zampini   const PetscScalar *aa;
2582985db425SBarry Smith 
2583985db425SBarry Smith   PetscFunctionBegin;
258428b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
25859566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
25869566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v, &p));
25879566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
258808401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector");
2589985db425SBarry Smith   for (i = 0; i < m; i++) {
25909189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
2591985db425SBarry Smith     for (j = 1; j < n; j++) {
2592ca15aa20SStefano Zampini       atmp = PetscAbsScalar(aa[i + a->lda * j]);
25939371c9d4SSatish Balay       if (PetscAbsScalar(x[i]) < atmp) {
25949371c9d4SSatish Balay         x[i] = atmp;
25959371c9d4SSatish Balay         if (idx) idx[i] = j;
25969371c9d4SSatish Balay       }
2597985db425SBarry Smith     }
2598985db425SBarry Smith   }
25999566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
26009566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
2601985db425SBarry Smith   PetscFunctionReturn(0);
2602985db425SBarry Smith }
2603985db425SBarry Smith 
26049371c9d4SSatish Balay static PetscErrorCode MatGetRowMin_SeqDense(Mat A, Vec v, PetscInt idx[]) {
2605985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
2606d0f46423SBarry Smith   PetscInt           i, j, m = A->rmap->n, n = A->cmap->n, p;
2607985db425SBarry Smith   PetscScalar       *x;
2608ca15aa20SStefano Zampini   const PetscScalar *aa;
2609985db425SBarry Smith 
2610985db425SBarry Smith   PetscFunctionBegin;
261128b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
26129566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
26139566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
26149566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v, &p));
261508401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector");
2616985db425SBarry Smith   for (i = 0; i < m; i++) {
26179371c9d4SSatish Balay     x[i] = aa[i];
26189371c9d4SSatish Balay     if (idx) idx[i] = 0;
2619985db425SBarry Smith     for (j = 1; j < n; j++) {
26209371c9d4SSatish Balay       if (PetscRealPart(x[i]) > PetscRealPart(aa[i + a->lda * j])) {
26219371c9d4SSatish Balay         x[i] = aa[i + a->lda * j];
26229371c9d4SSatish Balay         if (idx) idx[i] = j;
26239371c9d4SSatish Balay       }
2624985db425SBarry Smith     }
2625985db425SBarry Smith   }
26269566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
26279566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
2628985db425SBarry Smith   PetscFunctionReturn(0);
2629985db425SBarry Smith }
2630985db425SBarry Smith 
26319371c9d4SSatish Balay PetscErrorCode MatGetColumnVector_SeqDense(Mat A, Vec v, PetscInt col) {
26328d0534beSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
26338d0534beSBarry Smith   PetscScalar       *x;
2634ca15aa20SStefano Zampini   const PetscScalar *aa;
26358d0534beSBarry Smith 
26368d0534beSBarry Smith   PetscFunctionBegin;
263728b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
26389566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
26399566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
26409566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(x, aa + col * a->lda, A->rmap->n));
26419566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
26429566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
26438d0534beSBarry Smith   PetscFunctionReturn(0);
26448d0534beSBarry Smith }
26458d0534beSBarry Smith 
26469371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatGetColumnReductions_SeqDense(Mat A, PetscInt type, PetscReal *reductions) {
26470716a85fSBarry Smith   PetscInt           i, j, m, n;
26481683a169SBarry Smith   const PetscScalar *a;
26490716a85fSBarry Smith 
26500716a85fSBarry Smith   PetscFunctionBegin;
26519566063dSJacob Faibussowitsch   PetscCall(MatGetSize(A, &m, &n));
26529566063dSJacob Faibussowitsch   PetscCall(PetscArrayzero(reductions, n));
26539566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &a));
2654857cbf51SRichard Tran Mills   if (type == NORM_2) {
26550716a85fSBarry Smith     for (i = 0; i < n; i++) {
2656ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j] * a[j]);
26570716a85fSBarry Smith       a += m;
26580716a85fSBarry Smith     }
2659857cbf51SRichard Tran Mills   } else if (type == NORM_1) {
26600716a85fSBarry Smith     for (i = 0; i < n; i++) {
2661ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j]);
26620716a85fSBarry Smith       a += m;
26630716a85fSBarry Smith     }
2664857cbf51SRichard Tran Mills   } else if (type == NORM_INFINITY) {
26650716a85fSBarry Smith     for (i = 0; i < n; i++) {
2666ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] = PetscMax(PetscAbsScalar(a[j]), reductions[i]);
26670716a85fSBarry Smith       a += m;
26680716a85fSBarry Smith     }
2669857cbf51SRichard Tran Mills   } else if (type == REDUCTION_SUM_REALPART || type == REDUCTION_MEAN_REALPART) {
2670a873a8cdSSam Reynolds     for (i = 0; i < n; i++) {
2671ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] += PetscRealPart(a[j]);
2672a873a8cdSSam Reynolds       a += m;
2673a873a8cdSSam Reynolds     }
2674857cbf51SRichard Tran Mills   } else if (type == REDUCTION_SUM_IMAGINARYPART || type == REDUCTION_MEAN_IMAGINARYPART) {
2675857cbf51SRichard Tran Mills     for (i = 0; i < n; i++) {
2676ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] += PetscImaginaryPart(a[j]);
2677857cbf51SRichard Tran Mills       a += m;
2678857cbf51SRichard Tran Mills     }
2679857cbf51SRichard Tran Mills   } else SETERRQ(PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Unknown reduction type");
26809566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &a));
2681857cbf51SRichard Tran Mills   if (type == NORM_2) {
2682a873a8cdSSam Reynolds     for (i = 0; i < n; i++) reductions[i] = PetscSqrtReal(reductions[i]);
2683857cbf51SRichard Tran Mills   } else if (type == REDUCTION_MEAN_REALPART || type == REDUCTION_MEAN_IMAGINARYPART) {
2684a873a8cdSSam Reynolds     for (i = 0; i < n; i++) reductions[i] /= m;
26850716a85fSBarry Smith   }
26860716a85fSBarry Smith   PetscFunctionReturn(0);
26870716a85fSBarry Smith }
26880716a85fSBarry Smith 
26893faff063SStefano Zampini PetscErrorCode MatSetRandom_SeqDense(Mat x, PetscRandom rctx) {
269073a71a0fSBarry Smith   PetscScalar *a;
2691637a0070SStefano Zampini   PetscInt     lda, m, n, i, j;
269273a71a0fSBarry Smith 
269373a71a0fSBarry Smith   PetscFunctionBegin;
26949566063dSJacob Faibussowitsch   PetscCall(MatGetSize(x, &m, &n));
26959566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(x, &lda));
26963faff063SStefano Zampini   PetscCall(MatDenseGetArrayWrite(x, &a));
2697637a0070SStefano Zampini   for (j = 0; j < n; j++) {
269848a46eb9SPierre Jolivet     for (i = 0; i < m; i++) PetscCall(PetscRandomGetValue(rctx, a + j * lda + i));
269973a71a0fSBarry Smith   }
27003faff063SStefano Zampini   PetscCall(MatDenseRestoreArrayWrite(x, &a));
270173a71a0fSBarry Smith   PetscFunctionReturn(0);
270273a71a0fSBarry Smith }
270373a71a0fSBarry Smith 
27049371c9d4SSatish Balay static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A, PetscBool *missing, PetscInt *d) {
27053b49f96aSBarry Smith   PetscFunctionBegin;
27063b49f96aSBarry Smith   *missing = PETSC_FALSE;
27073b49f96aSBarry Smith   PetscFunctionReturn(0);
27083b49f96aSBarry Smith }
270973a71a0fSBarry Smith 
2710ca15aa20SStefano Zampini /* vals is not const */
27119371c9d4SSatish Balay static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A, PetscInt col, PetscScalar **vals) {
271286aefd0dSHong Zhang   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
2713ca15aa20SStefano Zampini   PetscScalar  *v;
271486aefd0dSHong Zhang 
271586aefd0dSHong Zhang   PetscFunctionBegin;
271628b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
27179566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
2718ca15aa20SStefano Zampini   *vals = v + col * a->lda;
27199566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
272086aefd0dSHong Zhang   PetscFunctionReturn(0);
272186aefd0dSHong Zhang }
272286aefd0dSHong Zhang 
27239371c9d4SSatish Balay static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A, PetscScalar **vals) {
272486aefd0dSHong Zhang   PetscFunctionBegin;
2725742765d3SMatthew Knepley   if (vals) *vals = NULL; /* user cannot accidentally use the array later */
272686aefd0dSHong Zhang   PetscFunctionReturn(0);
272786aefd0dSHong Zhang }
2728abc3b08eSStefano Zampini 
2729289bc588SBarry Smith /* -------------------------------------------------------------------*/
2730a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqDense,
2731905e6a2fSBarry Smith                                        MatGetRow_SeqDense,
2732905e6a2fSBarry Smith                                        MatRestoreRow_SeqDense,
2733905e6a2fSBarry Smith                                        MatMult_SeqDense,
273497304618SKris Buschelman                                        /*  4*/ MatMultAdd_SeqDense,
27357c922b88SBarry Smith                                        MatMultTranspose_SeqDense,
27367c922b88SBarry Smith                                        MatMultTransposeAdd_SeqDense,
2737f4259b30SLisandro Dalcin                                        NULL,
2738f4259b30SLisandro Dalcin                                        NULL,
2739f4259b30SLisandro Dalcin                                        NULL,
2740f4259b30SLisandro Dalcin                                        /* 10*/ NULL,
2741905e6a2fSBarry Smith                                        MatLUFactor_SeqDense,
2742905e6a2fSBarry Smith                                        MatCholeskyFactor_SeqDense,
274341f059aeSBarry Smith                                        MatSOR_SeqDense,
2744ec8511deSBarry Smith                                        MatTranspose_SeqDense,
274597304618SKris Buschelman                                        /* 15*/ MatGetInfo_SeqDense,
2746905e6a2fSBarry Smith                                        MatEqual_SeqDense,
2747905e6a2fSBarry Smith                                        MatGetDiagonal_SeqDense,
2748905e6a2fSBarry Smith                                        MatDiagonalScale_SeqDense,
2749905e6a2fSBarry Smith                                        MatNorm_SeqDense,
2750c0aa2d19SHong Zhang                                        /* 20*/ MatAssemblyBegin_SeqDense,
2751c0aa2d19SHong Zhang                                        MatAssemblyEnd_SeqDense,
2752905e6a2fSBarry Smith                                        MatSetOption_SeqDense,
2753905e6a2fSBarry Smith                                        MatZeroEntries_SeqDense,
2754d519adbfSMatthew Knepley                                        /* 24*/ MatZeroRows_SeqDense,
2755f4259b30SLisandro Dalcin                                        NULL,
2756f4259b30SLisandro Dalcin                                        NULL,
2757f4259b30SLisandro Dalcin                                        NULL,
2758f4259b30SLisandro Dalcin                                        NULL,
27594994cf47SJed Brown                                        /* 29*/ MatSetUp_SeqDense,
2760f4259b30SLisandro Dalcin                                        NULL,
2761f4259b30SLisandro Dalcin                                        NULL,
2762f4259b30SLisandro Dalcin                                        NULL,
2763f4259b30SLisandro Dalcin                                        NULL,
2764d519adbfSMatthew Knepley                                        /* 34*/ MatDuplicate_SeqDense,
2765f4259b30SLisandro Dalcin                                        NULL,
2766f4259b30SLisandro Dalcin                                        NULL,
2767f4259b30SLisandro Dalcin                                        NULL,
2768f4259b30SLisandro Dalcin                                        NULL,
2769d519adbfSMatthew Knepley                                        /* 39*/ MatAXPY_SeqDense,
27707dae84e0SHong Zhang                                        MatCreateSubMatrices_SeqDense,
2771f4259b30SLisandro Dalcin                                        NULL,
27724b0e389bSBarry Smith                                        MatGetValues_SeqDense,
2773a5ae1ecdSBarry Smith                                        MatCopy_SeqDense,
2774d519adbfSMatthew Knepley                                        /* 44*/ MatGetRowMax_SeqDense,
2775a5ae1ecdSBarry Smith                                        MatScale_SeqDense,
27762f605a99SJose E. Roman                                        MatShift_SeqDense,
2777f4259b30SLisandro Dalcin                                        NULL,
27783f49a652SStefano Zampini                                        MatZeroRowsColumns_SeqDense,
277973a71a0fSBarry Smith                                        /* 49*/ MatSetRandom_SeqDense,
2780f4259b30SLisandro Dalcin                                        NULL,
2781f4259b30SLisandro Dalcin                                        NULL,
2782f4259b30SLisandro Dalcin                                        NULL,
2783f4259b30SLisandro Dalcin                                        NULL,
2784f4259b30SLisandro Dalcin                                        /* 54*/ NULL,
2785f4259b30SLisandro Dalcin                                        NULL,
2786f4259b30SLisandro Dalcin                                        NULL,
2787f4259b30SLisandro Dalcin                                        NULL,
2788f4259b30SLisandro Dalcin                                        NULL,
2789023c16fcSToby Isaac                                        /* 59*/ MatCreateSubMatrix_SeqDense,
2790e03a110bSBarry Smith                                        MatDestroy_SeqDense,
2791e03a110bSBarry Smith                                        MatView_SeqDense,
2792f4259b30SLisandro Dalcin                                        NULL,
2793f4259b30SLisandro Dalcin                                        NULL,
2794f4259b30SLisandro Dalcin                                        /* 64*/ NULL,
2795f4259b30SLisandro Dalcin                                        NULL,
2796f4259b30SLisandro Dalcin                                        NULL,
2797f4259b30SLisandro Dalcin                                        NULL,
2798f4259b30SLisandro Dalcin                                        NULL,
2799d519adbfSMatthew Knepley                                        /* 69*/ MatGetRowMaxAbs_SeqDense,
2800f4259b30SLisandro Dalcin                                        NULL,
2801f4259b30SLisandro Dalcin                                        NULL,
2802f4259b30SLisandro Dalcin                                        NULL,
2803f4259b30SLisandro Dalcin                                        NULL,
2804f4259b30SLisandro Dalcin                                        /* 74*/ NULL,
2805f4259b30SLisandro Dalcin                                        NULL,
2806f4259b30SLisandro Dalcin                                        NULL,
2807f4259b30SLisandro Dalcin                                        NULL,
2808f4259b30SLisandro Dalcin                                        NULL,
2809f4259b30SLisandro Dalcin                                        /* 79*/ NULL,
2810f4259b30SLisandro Dalcin                                        NULL,
2811f4259b30SLisandro Dalcin                                        NULL,
2812f4259b30SLisandro Dalcin                                        NULL,
28135bba2384SShri Abhyankar                                        /* 83*/ MatLoad_SeqDense,
2814637a0070SStefano Zampini                                        MatIsSymmetric_SeqDense,
28151cbb95d3SBarry Smith                                        MatIsHermitian_SeqDense,
2816f4259b30SLisandro Dalcin                                        NULL,
2817f4259b30SLisandro Dalcin                                        NULL,
2818f4259b30SLisandro Dalcin                                        NULL,
2819f4259b30SLisandro Dalcin                                        /* 89*/ NULL,
2820f4259b30SLisandro Dalcin                                        NULL,
2821a9fe9ddaSSatish Balay                                        MatMatMultNumeric_SeqDense_SeqDense,
2822f4259b30SLisandro Dalcin                                        NULL,
2823f4259b30SLisandro Dalcin                                        NULL,
2824f4259b30SLisandro Dalcin                                        /* 94*/ NULL,
2825f4259b30SLisandro Dalcin                                        NULL,
2826f4259b30SLisandro Dalcin                                        NULL,
282769f65d41SStefano Zampini                                        MatMatTransposeMultNumeric_SeqDense_SeqDense,
2828f4259b30SLisandro Dalcin                                        NULL,
28294222ddf1SHong Zhang                                        /* 99*/ MatProductSetFromOptions_SeqDense,
2830f4259b30SLisandro Dalcin                                        NULL,
2831f4259b30SLisandro Dalcin                                        NULL,
2832ba337c44SJed Brown                                        MatConjugate_SeqDense,
2833f4259b30SLisandro Dalcin                                        NULL,
2834f4259b30SLisandro Dalcin                                        /*104*/ NULL,
2835ba337c44SJed Brown                                        MatRealPart_SeqDense,
2836ba337c44SJed Brown                                        MatImaginaryPart_SeqDense,
2837f4259b30SLisandro Dalcin                                        NULL,
2838f4259b30SLisandro Dalcin                                        NULL,
2839f4259b30SLisandro Dalcin                                        /*109*/ NULL,
2840f4259b30SLisandro Dalcin                                        NULL,
28418d0534beSBarry Smith                                        MatGetRowMin_SeqDense,
2842aabbc4fbSShri Abhyankar                                        MatGetColumnVector_SeqDense,
28433b49f96aSBarry Smith                                        MatMissingDiagonal_SeqDense,
2844f4259b30SLisandro Dalcin                                        /*114*/ NULL,
2845f4259b30SLisandro Dalcin                                        NULL,
2846f4259b30SLisandro Dalcin                                        NULL,
2847f4259b30SLisandro Dalcin                                        NULL,
2848f4259b30SLisandro Dalcin                                        NULL,
2849f4259b30SLisandro Dalcin                                        /*119*/ NULL,
2850f4259b30SLisandro Dalcin                                        NULL,
2851f4259b30SLisandro Dalcin                                        NULL,
2852f4259b30SLisandro Dalcin                                        NULL,
2853f4259b30SLisandro Dalcin                                        NULL,
2854f4259b30SLisandro Dalcin                                        /*124*/ NULL,
2855a873a8cdSSam Reynolds                                        MatGetColumnReductions_SeqDense,
2856f4259b30SLisandro Dalcin                                        NULL,
2857f4259b30SLisandro Dalcin                                        NULL,
2858f4259b30SLisandro Dalcin                                        NULL,
2859f4259b30SLisandro Dalcin                                        /*129*/ NULL,
2860f4259b30SLisandro Dalcin                                        NULL,
2861f4259b30SLisandro Dalcin                                        NULL,
286275648e8dSHong Zhang                                        MatTransposeMatMultNumeric_SeqDense_SeqDense,
2863f4259b30SLisandro Dalcin                                        NULL,
2864f4259b30SLisandro Dalcin                                        /*134*/ NULL,
2865f4259b30SLisandro Dalcin                                        NULL,
2866f4259b30SLisandro Dalcin                                        NULL,
2867f4259b30SLisandro Dalcin                                        NULL,
2868f4259b30SLisandro Dalcin                                        NULL,
2869f4259b30SLisandro Dalcin                                        /*139*/ NULL,
2870f4259b30SLisandro Dalcin                                        NULL,
2871f4259b30SLisandro Dalcin                                        NULL,
2872f4259b30SLisandro Dalcin                                        NULL,
2873f4259b30SLisandro Dalcin                                        NULL,
28744222ddf1SHong Zhang                                        MatCreateMPIMatConcatenateSeqMat_SeqDense,
2875f4259b30SLisandro Dalcin                                        /*145*/ NULL,
2876f4259b30SLisandro Dalcin                                        NULL,
287799a7f59eSMark Adams                                        NULL,
287899a7f59eSMark Adams                                        NULL,
28797fb60732SBarry Smith                                        NULL,
28809371c9d4SSatish Balay                                        /*150*/ NULL};
288190ace30eSBarry Smith 
28824b828684SBarry Smith /*@C
288311a5261eSBarry Smith    MatCreateSeqDense - Creates a `MATSEQDENSE` that
2884d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
2885d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
2886289bc588SBarry Smith 
2887d083f849SBarry Smith    Collective
2888db81eaa0SLois Curfman McInnes 
288920563c6bSBarry Smith    Input Parameters:
289011a5261eSBarry Smith +  comm - MPI communicator, set to `PETSC_COMM_SELF`
28910c775827SLois Curfman McInnes .  m - number of rows
289218f449edSLois Curfman McInnes .  n - number of columns
28930298fd71SBarry Smith -  data - optional location of matrix data in column major order.  Set data=NULL for PETSc
2894dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
289520563c6bSBarry Smith 
289620563c6bSBarry Smith    Output Parameter:
289744cd7ae7SLois Curfman McInnes .  A - the matrix
289820563c6bSBarry Smith 
289911a5261eSBarry Smith    Note:
290018f449edSLois Curfman McInnes    The data input variable is intended primarily for Fortran programmers
290118f449edSLois Curfman McInnes    who wish to allocate their own matrix memory space.  Most users should
29020298fd71SBarry Smith    set data=NULL.
290318f449edSLois Curfman McInnes 
2904027ccd11SLois Curfman McInnes    Level: intermediate
2905027ccd11SLois Curfman McInnes 
290611a5261eSBarry Smith .seealso: `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()`
290720563c6bSBarry Smith @*/
29089371c9d4SSatish Balay PetscErrorCode MatCreateSeqDense(MPI_Comm comm, PetscInt m, PetscInt n, PetscScalar *data, Mat *A) {
29093a40ed3dSBarry Smith   PetscFunctionBegin;
29109566063dSJacob Faibussowitsch   PetscCall(MatCreate(comm, A));
29119566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*A, m, n, m, n));
29129566063dSJacob Faibussowitsch   PetscCall(MatSetType(*A, MATSEQDENSE));
29139566063dSJacob Faibussowitsch   PetscCall(MatSeqDenseSetPreallocation(*A, data));
2914273d9f13SBarry Smith   PetscFunctionReturn(0);
2915273d9f13SBarry Smith }
2916273d9f13SBarry Smith 
2917273d9f13SBarry Smith /*@C
291811a5261eSBarry Smith    MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements of a `MATSEQDENSE` matrix
2919273d9f13SBarry Smith 
2920d083f849SBarry Smith    Collective
2921273d9f13SBarry Smith 
2922273d9f13SBarry Smith    Input Parameters:
29231c4f3114SJed Brown +  B - the matrix
29240298fd71SBarry Smith -  data - the array (or NULL)
2925273d9f13SBarry Smith 
292611a5261eSBarry Smith    Note:
2927273d9f13SBarry Smith    The data input variable is intended primarily for Fortran programmers
2928273d9f13SBarry Smith    who wish to allocate their own matrix memory space.  Most users should
2929284134d9SBarry Smith    need not call this routine.
2930273d9f13SBarry Smith 
2931273d9f13SBarry Smith    Level: intermediate
2932273d9f13SBarry Smith 
293311a5261eSBarry Smith .seealso: `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()`, `MatDenseSetLDA()`
2934273d9f13SBarry Smith @*/
29359371c9d4SSatish Balay PetscErrorCode MatSeqDenseSetPreallocation(Mat B, PetscScalar data[]) {
2936a23d5eceSKris Buschelman   PetscFunctionBegin;
2937d5ea218eSStefano Zampini   PetscValidHeaderSpecific(B, MAT_CLASSID, 1);
2938cac4c232SBarry Smith   PetscTryMethod(B, "MatSeqDenseSetPreallocation_C", (Mat, PetscScalar[]), (B, data));
2939a23d5eceSKris Buschelman   PetscFunctionReturn(0);
2940a23d5eceSKris Buschelman }
2941a23d5eceSKris Buschelman 
29429371c9d4SSatish Balay PetscErrorCode MatSeqDenseSetPreallocation_SeqDense(Mat B, PetscScalar *data) {
2943ad16ce7aSStefano Zampini   Mat_SeqDense *b = (Mat_SeqDense *)B->data;
2944273d9f13SBarry Smith 
2945273d9f13SBarry Smith   PetscFunctionBegin;
294628b400f6SJacob Faibussowitsch   PetscCheck(!b->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
2947273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
2948a868139aSShri Abhyankar 
29499566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(B->rmap));
29509566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(B->cmap));
295134ef9618SShri Abhyankar 
2952ad16ce7aSStefano Zampini   if (b->lda <= 0) b->lda = B->rmap->n;
295386d161a7SShri Abhyankar 
29549e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
29559566063dSJacob Faibussowitsch     if (!b->user_alloc) PetscCall(PetscFree(b->v));
29569566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1((size_t)b->lda * B->cmap->n, &b->v));
29572205254eSKarl Rupp 
29589e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
2959273d9f13SBarry Smith   } else { /* user-allocated storage */
29609566063dSJacob Faibussowitsch     if (!b->user_alloc) PetscCall(PetscFree(b->v));
2961273d9f13SBarry Smith     b->v          = data;
2962273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
2963273d9f13SBarry Smith   }
29640450473dSBarry Smith   B->assembled = PETSC_TRUE;
2965273d9f13SBarry Smith   PetscFunctionReturn(0);
2966273d9f13SBarry Smith }
2967273d9f13SBarry Smith 
296865b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
29699371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) {
2970d77f618aSHong Zhang   Mat                mat_elemental;
29711683a169SBarry Smith   const PetscScalar *array;
29721683a169SBarry Smith   PetscScalar       *v_colwise;
2973d77f618aSHong Zhang   PetscInt           M = A->rmap->N, N = A->cmap->N, i, j, k, *rows, *cols;
2974d77f618aSHong Zhang 
29758baccfbdSHong Zhang   PetscFunctionBegin;
29769566063dSJacob Faibussowitsch   PetscCall(PetscMalloc3(M * N, &v_colwise, M, &rows, N, &cols));
29779566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &array));
2978d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
2979d77f618aSHong Zhang   k = 0;
2980d77f618aSHong Zhang   for (j = 0; j < N; j++) {
2981d77f618aSHong Zhang     cols[j] = j;
2982ad540459SPierre Jolivet     for (i = 0; i < M; i++) v_colwise[j * M + i] = array[k++];
2983d77f618aSHong Zhang   }
2984ad540459SPierre Jolivet   for (i = 0; i < M; i++) rows[i] = i;
29859566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &array));
2986d77f618aSHong Zhang 
29879566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental));
29889566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(mat_elemental, PETSC_DECIDE, PETSC_DECIDE, M, N));
29899566063dSJacob Faibussowitsch   PetscCall(MatSetType(mat_elemental, MATELEMENTAL));
29909566063dSJacob Faibussowitsch   PetscCall(MatSetUp(mat_elemental));
2991d77f618aSHong Zhang 
2992d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
29939566063dSJacob Faibussowitsch   PetscCall(MatSetValues(mat_elemental, M, rows, N, cols, v_colwise, ADD_VALUES));
29949566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY));
29959566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY));
29969566063dSJacob Faibussowitsch   PetscCall(PetscFree3(v_colwise, rows, cols));
2997d77f618aSHong Zhang 
2998511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
29999566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A, &mat_elemental));
3000d77f618aSHong Zhang   } else {
3001d77f618aSHong Zhang     *newmat = mat_elemental;
3002d77f618aSHong Zhang   }
30038baccfbdSHong Zhang   PetscFunctionReturn(0);
30048baccfbdSHong Zhang }
300565b80a83SHong Zhang #endif
30068baccfbdSHong Zhang 
30079371c9d4SSatish Balay PetscErrorCode MatDenseSetLDA_SeqDense(Mat B, PetscInt lda) {
30081b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense *)B->data;
30097422da62SJose E. Roman   PetscBool     data;
301021a2c019SBarry Smith 
30111b807ce4Svictorle   PetscFunctionBegin;
30127422da62SJose E. Roman   data = (PetscBool)((B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE);
3013aed4548fSBarry Smith   PetscCheck(b->user_alloc || !data || b->lda == lda, PETSC_COMM_SELF, PETSC_ERR_ORDER, "LDA cannot be changed after allocation of internal storage");
301408401ef6SPierre 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);
30151b807ce4Svictorle   b->lda = lda;
30161b807ce4Svictorle   PetscFunctionReturn(0);
30171b807ce4Svictorle }
30181b807ce4Svictorle 
30199371c9d4SSatish Balay PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm, Mat inmat, PetscInt n, MatReuse scall, Mat *outmat) {
3020d528f656SJakub Kruzik   PetscFunctionBegin;
30219566063dSJacob Faibussowitsch   PetscCall(MatCreateMPIMatConcatenateSeqMat_MPIDense(comm, inmat, n, scall, outmat));
3022d528f656SJakub Kruzik   PetscFunctionReturn(0);
3023d528f656SJakub Kruzik }
3024d528f656SJakub Kruzik 
30259371c9d4SSatish Balay PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A, PetscInt col, Vec *v) {
30266947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
30276947451fSStefano Zampini 
30286947451fSStefano Zampini   PetscFunctionBegin;
302928b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
303028b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
3031*4dfa11a4SJacob Faibussowitsch   if (!a->cvec) { PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec)); }
30326947451fSStefano Zampini   a->vecinuse = col + 1;
30339566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, (PetscScalar **)&a->ptrinuse));
30349566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda));
30356947451fSStefano Zampini   *v = a->cvec;
30366947451fSStefano Zampini   PetscFunctionReturn(0);
30376947451fSStefano Zampini }
30386947451fSStefano Zampini 
30399371c9d4SSatish Balay PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A, PetscInt col, Vec *v) {
30406947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
30416947451fSStefano Zampini 
30426947451fSStefano Zampini   PetscFunctionBegin;
304328b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first");
304428b400f6SJacob Faibussowitsch   PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector");
30456947451fSStefano Zampini   a->vecinuse = 0;
30469566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, (PetscScalar **)&a->ptrinuse));
30479566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
304875f6d85dSStefano Zampini   if (v) *v = NULL;
30496947451fSStefano Zampini   PetscFunctionReturn(0);
30506947451fSStefano Zampini }
30516947451fSStefano Zampini 
30529371c9d4SSatish Balay PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v) {
30536947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
30546947451fSStefano Zampini 
30556947451fSStefano Zampini   PetscFunctionBegin;
305628b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
305728b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
3058*4dfa11a4SJacob Faibussowitsch   if (!a->cvec) { PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec)); }
30596947451fSStefano Zampini   a->vecinuse = col + 1;
30609566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &a->ptrinuse));
30619566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda));
30629566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(a->cvec));
30636947451fSStefano Zampini   *v = a->cvec;
30646947451fSStefano Zampini   PetscFunctionReturn(0);
30656947451fSStefano Zampini }
30666947451fSStefano Zampini 
30679371c9d4SSatish Balay PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v) {
30686947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
30696947451fSStefano Zampini 
30706947451fSStefano Zampini   PetscFunctionBegin;
307128b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first");
307228b400f6SJacob Faibussowitsch   PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector");
30736947451fSStefano Zampini   a->vecinuse = 0;
30749566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &a->ptrinuse));
30759566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(a->cvec));
30769566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
307775f6d85dSStefano Zampini   if (v) *v = NULL;
30786947451fSStefano Zampini   PetscFunctionReturn(0);
30796947451fSStefano Zampini }
30806947451fSStefano Zampini 
30819371c9d4SSatish Balay PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v) {
30826947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
30836947451fSStefano Zampini 
30846947451fSStefano Zampini   PetscFunctionBegin;
308528b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
308628b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
3087*4dfa11a4SJacob Faibussowitsch   if (!a->cvec) { PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec)); }
30886947451fSStefano Zampini   a->vecinuse = col + 1;
30899566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(A, (PetscScalar **)&a->ptrinuse));
30909566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda));
30916947451fSStefano Zampini   *v = a->cvec;
30926947451fSStefano Zampini   PetscFunctionReturn(0);
30936947451fSStefano Zampini }
30946947451fSStefano Zampini 
30959371c9d4SSatish Balay PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v) {
30966947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
30976947451fSStefano Zampini 
30986947451fSStefano Zampini   PetscFunctionBegin;
309928b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first");
310028b400f6SJacob Faibussowitsch   PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector");
31016947451fSStefano Zampini   a->vecinuse = 0;
31029566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(A, (PetscScalar **)&a->ptrinuse));
31039566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
310475f6d85dSStefano Zampini   if (v) *v = NULL;
31056947451fSStefano Zampini   PetscFunctionReturn(0);
31066947451fSStefano Zampini }
31076947451fSStefano Zampini 
31089371c9d4SSatish Balay PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) {
31095ea7661aSPierre Jolivet   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
31105ea7661aSPierre Jolivet 
31115ea7661aSPierre Jolivet   PetscFunctionBegin;
311228b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
311328b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
3114a2748737SPierre Jolivet   if (a->cmat && (cend - cbegin != a->cmat->cmap->N || rend - rbegin != a->cmat->rmap->N)) PetscCall(MatDestroy(&a->cmat));
31155ea7661aSPierre Jolivet   if (!a->cmat) {
3116a2748737SPierre Jolivet     PetscCall(MatCreateDense(PetscObjectComm((PetscObject)A), rend - rbegin, PETSC_DECIDE, rend - rbegin, cend - cbegin, a->v + rbegin + (size_t)cbegin * a->lda, &a->cmat));
31175ea7661aSPierre Jolivet   } else {
3118a2748737SPierre Jolivet     PetscCall(MatDensePlaceArray(a->cmat, a->v + rbegin + (size_t)cbegin * a->lda));
31195ea7661aSPierre Jolivet   }
31209566063dSJacob Faibussowitsch   PetscCall(MatDenseSetLDA(a->cmat, a->lda));
31215ea7661aSPierre Jolivet   a->matinuse = cbegin + 1;
31225ea7661aSPierre Jolivet   *v          = a->cmat;
312375f6d85dSStefano Zampini #if defined(PETSC_HAVE_CUDA)
312475f6d85dSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
312575f6d85dSStefano Zampini #endif
31265ea7661aSPierre Jolivet   PetscFunctionReturn(0);
31275ea7661aSPierre Jolivet }
31285ea7661aSPierre Jolivet 
31299371c9d4SSatish Balay PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A, Mat *v) {
31305ea7661aSPierre Jolivet   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
31315ea7661aSPierre Jolivet 
31325ea7661aSPierre Jolivet   PetscFunctionBegin;
313328b400f6SJacob Faibussowitsch   PetscCheck(a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetSubMatrix() first");
313428b400f6SJacob Faibussowitsch   PetscCheck(a->cmat, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column matrix");
313508401ef6SPierre Jolivet   PetscCheck(*v == a->cmat, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not the matrix obtained from MatDenseGetSubMatrix()");
31365ea7661aSPierre Jolivet   a->matinuse = 0;
31379566063dSJacob Faibussowitsch   PetscCall(MatDenseResetArray(a->cmat));
3138742765d3SMatthew Knepley   if (v) *v = NULL;
31393faff063SStefano Zampini #if defined(PETSC_HAVE_CUDA)
31403faff063SStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
31413faff063SStefano Zampini #endif
31425ea7661aSPierre Jolivet   PetscFunctionReturn(0);
31435ea7661aSPierre Jolivet }
31445ea7661aSPierre Jolivet 
31450bad9183SKris Buschelman /*MC
3146fafad747SKris Buschelman    MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices.
31470bad9183SKris Buschelman 
31480bad9183SKris Buschelman    Options Database Keys:
314911a5261eSBarry Smith . -mat_type seqdense - sets the matrix type to `MATSEQDENSE` during a call to `MatSetFromOptions()`
31500bad9183SKris Buschelman 
31510bad9183SKris Buschelman   Level: beginner
31520bad9183SKris Buschelman 
315311a5261eSBarry Smith .seealso: `MATSEQDENSE`, `MatCreateSeqDense()`
31540bad9183SKris Buschelman M*/
31559371c9d4SSatish Balay PetscErrorCode MatCreate_SeqDense(Mat B) {
3156273d9f13SBarry Smith   Mat_SeqDense *b;
31577c334f02SBarry Smith   PetscMPIInt   size;
3158273d9f13SBarry Smith 
3159273d9f13SBarry Smith   PetscFunctionBegin;
31609566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)B), &size));
316108401ef6SPierre Jolivet   PetscCheck(size <= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Comm must be of size 1");
316255659b69SBarry Smith 
3163*4dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&b));
31649566063dSJacob Faibussowitsch   PetscCall(PetscMemcpy(B->ops, &MatOps_Values, sizeof(struct _MatOps)));
316544cd7ae7SLois Curfman McInnes   B->data = (void *)b;
316618f449edSLois Curfman McInnes 
3167273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
31684e220ebcSLois Curfman McInnes 
31699566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatQRFactor_C", MatQRFactor_SeqDense));
31709566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetLDA_C", MatDenseGetLDA_SeqDense));
31719566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseSetLDA_C", MatDenseSetLDA_SeqDense));
31729566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArray_C", MatDenseGetArray_SeqDense));
31739566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArray_C", MatDenseRestoreArray_SeqDense));
31749566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDensePlaceArray_C", MatDensePlaceArray_SeqDense));
31759566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseResetArray_C", MatDenseResetArray_SeqDense));
31769566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseReplaceArray_C", MatDenseReplaceArray_SeqDense));
31779566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayRead_C", MatDenseGetArray_SeqDense));
31789566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayRead_C", MatDenseRestoreArray_SeqDense));
31799566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayWrite_C", MatDenseGetArray_SeqDense));
31809566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayWrite_C", MatDenseRestoreArray_SeqDense));
31819566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqaij_C", MatConvert_SeqDense_SeqAIJ));
31828baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
31839566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_elemental_C", MatConvert_SeqDense_Elemental));
31848baccfbdSHong Zhang #endif
3185d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
31869566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_scalapack_C", MatConvert_Dense_ScaLAPACK));
3187d24d4204SJose E. Roman #endif
31882bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
31899566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensecuda_C", MatConvert_SeqDense_SeqDenseCUDA));
31909566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", MatProductSetFromOptions_SeqDense));
31919566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdense_C", MatProductSetFromOptions_SeqDense));
31929566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensecuda_C", MatProductSetFromOptions_SeqDense));
31932bf066beSStefano Zampini #endif
31949566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSeqDenseSetPreallocation_C", MatSeqDenseSetPreallocation_SeqDense));
31959566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqaij_seqdense_C", MatProductSetFromOptions_SeqAIJ_SeqDense));
31969566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdense_C", MatProductSetFromOptions_SeqDense));
31979566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense));
31989566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqsbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense));
319996e6d5c4SRichard Tran Mills 
32009566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumn_C", MatDenseGetColumn_SeqDense));
32019566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumn_C", MatDenseRestoreColumn_SeqDense));
32029566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVec_C", MatDenseGetColumnVec_SeqDense));
32039566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVec_C", MatDenseRestoreColumnVec_SeqDense));
32049566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecRead_C", MatDenseGetColumnVecRead_SeqDense));
32059566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecRead_C", MatDenseRestoreColumnVecRead_SeqDense));
32069566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecWrite_C", MatDenseGetColumnVecWrite_SeqDense));
32079566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecWrite_C", MatDenseRestoreColumnVecWrite_SeqDense));
32089566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetSubMatrix_C", MatDenseGetSubMatrix_SeqDense));
32099566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreSubMatrix_C", MatDenseRestoreSubMatrix_SeqDense));
32109566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)B, MATSEQDENSE));
32113a40ed3dSBarry Smith   PetscFunctionReturn(0);
3212289bc588SBarry Smith }
321386aefd0dSHong Zhang 
321486aefd0dSHong Zhang /*@C
321511a5261eSBarry 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.
321686aefd0dSHong Zhang 
321786aefd0dSHong Zhang    Not Collective
321886aefd0dSHong Zhang 
32195ea7661aSPierre Jolivet    Input Parameters:
322011a5261eSBarry Smith +  mat - a `MATSEQDENSE` or `MATMPIDENSE` matrix
322186aefd0dSHong Zhang -  col - column index
322286aefd0dSHong Zhang 
322386aefd0dSHong Zhang    Output Parameter:
322486aefd0dSHong Zhang .  vals - pointer to the data
322586aefd0dSHong Zhang 
322686aefd0dSHong Zhang    Level: intermediate
322786aefd0dSHong Zhang 
322811a5261eSBarry Smith    Note:
322911a5261eSBarry Smith    Use `MatDenseGetColumnVec()` to get access to a column of a `MATDENSE` treated as a `Vec`
323011a5261eSBarry Smith 
323111a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreColumn()`, `MatDenseGetColumnVec()`
323286aefd0dSHong Zhang @*/
32339371c9d4SSatish Balay PetscErrorCode MatDenseGetColumn(Mat A, PetscInt col, PetscScalar **vals) {
323486aefd0dSHong Zhang   PetscFunctionBegin;
3235d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
3236d5ea218eSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
3237d5ea218eSStefano Zampini   PetscValidPointer(vals, 3);
3238cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumn_C", (Mat, PetscInt, PetscScalar **), (A, col, vals));
323986aefd0dSHong Zhang   PetscFunctionReturn(0);
324086aefd0dSHong Zhang }
324186aefd0dSHong Zhang 
324286aefd0dSHong Zhang /*@C
324311a5261eSBarry Smith    MatDenseRestoreColumn - returns access to a column of a `MATDENSE` matrix which is returned by `MatDenseGetColumn()`.
324486aefd0dSHong Zhang 
324586aefd0dSHong Zhang    Not Collective
324686aefd0dSHong Zhang 
3247742765d3SMatthew Knepley    Input Parameters:
324811a5261eSBarry Smith +  mat - a `MATSEQDENSE` or `MATMPIDENSE` matrix
3249742765d3SMatthew Knepley -  vals - pointer to the data (may be NULL)
325086aefd0dSHong Zhang 
325186aefd0dSHong Zhang    Level: intermediate
325286aefd0dSHong Zhang 
325311a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetColumn()`
325486aefd0dSHong Zhang @*/
32559371c9d4SSatish Balay PetscErrorCode MatDenseRestoreColumn(Mat A, PetscScalar **vals) {
325686aefd0dSHong Zhang   PetscFunctionBegin;
3257d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
3258d5ea218eSStefano Zampini   PetscValidPointer(vals, 2);
3259cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumn_C", (Mat, PetscScalar **), (A, vals));
326086aefd0dSHong Zhang   PetscFunctionReturn(0);
326186aefd0dSHong Zhang }
32626947451fSStefano Zampini 
32630f74d2c1SSatish Balay /*@
326411a5261eSBarry Smith    MatDenseGetColumnVec - Gives read-write access to a column of a `MATDENSE` matrix, represented as a `Vec`.
32656947451fSStefano Zampini 
32666947451fSStefano Zampini    Collective
32676947451fSStefano Zampini 
32685ea7661aSPierre Jolivet    Input Parameters:
326911a5261eSBarry Smith +  mat - the `Mat` object
32706947451fSStefano Zampini -  col - the column index
32716947451fSStefano Zampini 
32726947451fSStefano Zampini    Output Parameter:
32736947451fSStefano Zampini .  v - the vector
32746947451fSStefano Zampini 
32756947451fSStefano Zampini    Notes:
327611a5261eSBarry Smith      The vector is owned by PETSc. Users need to call `MatDenseRestoreColumnVec()` when the vector is no longer needed.
327711a5261eSBarry Smith 
327811a5261eSBarry Smith      Use `MatDenseGetColumnVecRead()` to obtain read-only access or `MatDenseGetColumnVecWrite()` for write-only access.
32796947451fSStefano Zampini 
32806947451fSStefano Zampini    Level: intermediate
32816947451fSStefano Zampini 
328211a5261eSBarry Smith .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`, `MatDenseGetColumn()`
32836947451fSStefano Zampini @*/
32849371c9d4SSatish Balay PetscErrorCode MatDenseGetColumnVec(Mat A, PetscInt col, Vec *v) {
32856947451fSStefano Zampini   PetscFunctionBegin;
32866947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
32876947451fSStefano Zampini   PetscValidType(A, 1);
32886947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
32896947451fSStefano Zampini   PetscValidPointer(v, 3);
329028b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
32912cf15c64SPierre 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);
3292cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v));
32936947451fSStefano Zampini   PetscFunctionReturn(0);
32946947451fSStefano Zampini }
32956947451fSStefano Zampini 
32960f74d2c1SSatish Balay /*@
32976947451fSStefano Zampini    MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVec().
32986947451fSStefano Zampini 
32996947451fSStefano Zampini    Collective
33006947451fSStefano Zampini 
33015ea7661aSPierre Jolivet    Input Parameters:
33026947451fSStefano Zampini +  mat - the Mat object
33036947451fSStefano Zampini .  col - the column index
3304742765d3SMatthew Knepley -  v - the Vec object (may be NULL)
33056947451fSStefano Zampini 
33066947451fSStefano Zampini    Level: intermediate
33076947451fSStefano Zampini 
3308db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
33096947451fSStefano Zampini @*/
33109371c9d4SSatish Balay PetscErrorCode MatDenseRestoreColumnVec(Mat A, PetscInt col, Vec *v) {
33116947451fSStefano Zampini   PetscFunctionBegin;
33126947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
33136947451fSStefano Zampini   PetscValidType(A, 1);
33146947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
331508401ef6SPierre Jolivet   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
33162cf15c64SPierre 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);
3317cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v));
33186947451fSStefano Zampini   PetscFunctionReturn(0);
33196947451fSStefano Zampini }
33206947451fSStefano Zampini 
33210f74d2c1SSatish Balay /*@
33226947451fSStefano Zampini    MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a Vec.
33236947451fSStefano Zampini 
33246947451fSStefano Zampini    Collective
33256947451fSStefano Zampini 
33265ea7661aSPierre Jolivet    Input Parameters:
33276947451fSStefano Zampini +  mat - the Mat object
33286947451fSStefano Zampini -  col - the column index
33296947451fSStefano Zampini 
33306947451fSStefano Zampini    Output Parameter:
33316947451fSStefano Zampini .  v - the vector
33326947451fSStefano Zampini 
33336947451fSStefano Zampini    Notes:
33346947451fSStefano Zampini      The vector is owned by PETSc and users cannot modify it.
333511a5261eSBarry Smith 
33366947451fSStefano Zampini      Users need to call MatDenseRestoreColumnVecRead() when the vector is no longer needed.
333711a5261eSBarry Smith 
33386947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecWrite() for write-only access.
33396947451fSStefano Zampini 
33406947451fSStefano Zampini    Level: intermediate
33416947451fSStefano Zampini 
3342db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
33436947451fSStefano Zampini @*/
33449371c9d4SSatish Balay PetscErrorCode MatDenseGetColumnVecRead(Mat A, PetscInt col, Vec *v) {
33456947451fSStefano Zampini   PetscFunctionBegin;
33466947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
33476947451fSStefano Zampini   PetscValidType(A, 1);
33486947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
33496947451fSStefano Zampini   PetscValidPointer(v, 3);
335028b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
33512cf15c64SPierre 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);
3352cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v));
33536947451fSStefano Zampini   PetscFunctionReturn(0);
33546947451fSStefano Zampini }
33556947451fSStefano Zampini 
33560f74d2c1SSatish Balay /*@
33576947451fSStefano Zampini    MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecRead().
33586947451fSStefano Zampini 
33596947451fSStefano Zampini    Collective
33606947451fSStefano Zampini 
33615ea7661aSPierre Jolivet    Input Parameters:
33626947451fSStefano Zampini +  mat - the Mat object
33636947451fSStefano Zampini .  col - the column index
3364742765d3SMatthew Knepley -  v - the Vec object (may be NULL)
33656947451fSStefano Zampini 
33666947451fSStefano Zampini    Level: intermediate
33676947451fSStefano Zampini 
3368db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecWrite()`
33696947451fSStefano Zampini @*/
33709371c9d4SSatish Balay PetscErrorCode MatDenseRestoreColumnVecRead(Mat A, PetscInt col, Vec *v) {
33716947451fSStefano Zampini   PetscFunctionBegin;
33726947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
33736947451fSStefano Zampini   PetscValidType(A, 1);
33746947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
337508401ef6SPierre Jolivet   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
33762cf15c64SPierre 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);
3377cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v));
33786947451fSStefano Zampini   PetscFunctionReturn(0);
33796947451fSStefano Zampini }
33806947451fSStefano Zampini 
33810f74d2c1SSatish Balay /*@
33826947451fSStefano Zampini    MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a Vec.
33836947451fSStefano Zampini 
33846947451fSStefano Zampini    Collective
33856947451fSStefano Zampini 
33865ea7661aSPierre Jolivet    Input Parameters:
33876947451fSStefano Zampini +  mat - the Mat object
33886947451fSStefano Zampini -  col - the column index
33896947451fSStefano Zampini 
33906947451fSStefano Zampini    Output Parameter:
33916947451fSStefano Zampini .  v - the vector
33926947451fSStefano Zampini 
33936947451fSStefano Zampini    Notes:
33946947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVecWrite() when the vector is no longer needed.
339511a5261eSBarry Smith 
33966947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecRead() for read-only access.
33976947451fSStefano Zampini 
33986947451fSStefano Zampini    Level: intermediate
33996947451fSStefano Zampini 
3400db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
34016947451fSStefano Zampini @*/
34029371c9d4SSatish Balay PetscErrorCode MatDenseGetColumnVecWrite(Mat A, PetscInt col, Vec *v) {
34036947451fSStefano Zampini   PetscFunctionBegin;
34046947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
34056947451fSStefano Zampini   PetscValidType(A, 1);
34066947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
34076947451fSStefano Zampini   PetscValidPointer(v, 3);
340828b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
3409aed4548fSBarry 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);
3410cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v));
34116947451fSStefano Zampini   PetscFunctionReturn(0);
34126947451fSStefano Zampini }
34136947451fSStefano Zampini 
34140f74d2c1SSatish Balay /*@
34156947451fSStefano Zampini    MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecWrite().
34166947451fSStefano Zampini 
34176947451fSStefano Zampini    Collective
34186947451fSStefano Zampini 
34195ea7661aSPierre Jolivet    Input Parameters:
34206947451fSStefano Zampini +  mat - the Mat object
34216947451fSStefano Zampini .  col - the column index
3422742765d3SMatthew Knepley -  v - the Vec object (may be NULL)
34236947451fSStefano Zampini 
34246947451fSStefano Zampini    Level: intermediate
34256947451fSStefano Zampini 
3426db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`
34276947451fSStefano Zampini @*/
34289371c9d4SSatish Balay PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A, PetscInt col, Vec *v) {
34296947451fSStefano Zampini   PetscFunctionBegin;
34306947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
34316947451fSStefano Zampini   PetscValidType(A, 1);
34326947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
343308401ef6SPierre Jolivet   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
3434aed4548fSBarry 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);
3435cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v));
34366947451fSStefano Zampini   PetscFunctionReturn(0);
34376947451fSStefano Zampini }
34385ea7661aSPierre Jolivet 
34390f74d2c1SSatish Balay /*@
3440a2748737SPierre Jolivet    MatDenseGetSubMatrix - Gives access to a block of rows and columns of a dense matrix, represented as a Mat.
34415ea7661aSPierre Jolivet 
34425ea7661aSPierre Jolivet    Collective
34435ea7661aSPierre Jolivet 
34445ea7661aSPierre Jolivet    Input Parameters:
34455ea7661aSPierre Jolivet +  mat - the Mat object
3446a2748737SPierre Jolivet .  rbegin - the first global row index in the block (if PETSC_DECIDE, is 0)
3447a2748737SPierre Jolivet .  rend - the global row index past the last one in the block (if PETSC_DECIDE, is M)
3448a2748737SPierre Jolivet .  cbegin - the first global column index in the block (if PETSC_DECIDE, is 0)
3449a2748737SPierre Jolivet -  cend - the global column index past the last one in the block (if PETSC_DECIDE, is N)
34505ea7661aSPierre Jolivet 
34515ea7661aSPierre Jolivet    Output Parameter:
34525ea7661aSPierre Jolivet .  v - the matrix
34535ea7661aSPierre Jolivet 
34545ea7661aSPierre Jolivet    Notes:
34555ea7661aSPierre Jolivet      The matrix is owned by PETSc. Users need to call MatDenseRestoreSubMatrix() when the matrix is no longer needed.
345611a5261eSBarry Smith 
3457a2748737SPierre 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.
34585ea7661aSPierre Jolivet 
34595ea7661aSPierre Jolivet    Level: intermediate
34605ea7661aSPierre Jolivet 
3461db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreSubMatrix()`
34625ea7661aSPierre Jolivet @*/
34639371c9d4SSatish Balay PetscErrorCode MatDenseGetSubMatrix(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) {
34645ea7661aSPierre Jolivet   PetscFunctionBegin;
34655ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
34665ea7661aSPierre Jolivet   PetscValidType(A, 1);
3467a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, rbegin, 2);
3468a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, rend, 3);
3469a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, cbegin, 4);
3470a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, cend, 5);
3471a2748737SPierre Jolivet   PetscValidPointer(v, 6);
3472a2748737SPierre Jolivet   if (rbegin == PETSC_DECIDE) rbegin = 0;
3473a2748737SPierre Jolivet   if (rend == PETSC_DECIDE) rend = A->rmap->N;
3474a2748737SPierre Jolivet   if (cbegin == PETSC_DECIDE) cbegin = 0;
3475a2748737SPierre Jolivet   if (cend == PETSC_DECIDE) cend = A->cmap->N;
347628b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
3477a2748737SPierre 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);
3478a2748737SPierre 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);
3479a2748737SPierre 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);
3480a2748737SPierre 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);
3481a2748737SPierre Jolivet   PetscUseMethod(A, "MatDenseGetSubMatrix_C", (Mat, PetscInt, PetscInt, PetscInt, PetscInt, Mat *), (A, rbegin, rend, cbegin, cend, v));
34825ea7661aSPierre Jolivet   PetscFunctionReturn(0);
34835ea7661aSPierre Jolivet }
34845ea7661aSPierre Jolivet 
34850f74d2c1SSatish Balay /*@
34865ea7661aSPierre Jolivet    MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from MatDenseGetSubMatrix().
34875ea7661aSPierre Jolivet 
34885ea7661aSPierre Jolivet    Collective
34895ea7661aSPierre Jolivet 
34905ea7661aSPierre Jolivet    Input Parameters:
34915ea7661aSPierre Jolivet +  mat - the Mat object
3492742765d3SMatthew Knepley -  v - the Mat object (may be NULL)
34935ea7661aSPierre Jolivet 
34945ea7661aSPierre Jolivet    Level: intermediate
34955ea7661aSPierre Jolivet 
3496db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseGetSubMatrix()`
34975ea7661aSPierre Jolivet @*/
34989371c9d4SSatish Balay PetscErrorCode MatDenseRestoreSubMatrix(Mat A, Mat *v) {
34995ea7661aSPierre Jolivet   PetscFunctionBegin;
35005ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
35015ea7661aSPierre Jolivet   PetscValidType(A, 1);
35025ea7661aSPierre Jolivet   PetscValidPointer(v, 2);
3503cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreSubMatrix_C", (Mat, Mat *), (A, v));
35045ea7661aSPierre Jolivet   PetscFunctionReturn(0);
35055ea7661aSPierre Jolivet }
35068a9c020eSBarry Smith 
35078a9c020eSBarry Smith #include <petscblaslapack.h>
35088a9c020eSBarry Smith #include <petsc/private/kernels/blockinvert.h>
35098a9c020eSBarry Smith 
35109371c9d4SSatish Balay PetscErrorCode MatSeqDenseInvert(Mat A) {
35118a9c020eSBarry Smith   Mat_SeqDense   *a              = (Mat_SeqDense *)A->data;
35128a9c020eSBarry Smith   PetscInt        bs             = A->rmap->n;
35138a9c020eSBarry Smith   MatScalar      *values         = a->v;
35148a9c020eSBarry Smith   const PetscReal shift          = 0.0;
35158a9c020eSBarry Smith   PetscBool       allowzeropivot = PetscNot(A->erroriffailure), zeropivotdetected = PETSC_FALSE;
35168a9c020eSBarry Smith 
35178a9c020eSBarry Smith   PetscFunctionBegin;
35188a9c020eSBarry Smith   /* factor and invert each block */
35198a9c020eSBarry Smith   switch (bs) {
35209371c9d4SSatish Balay   case 1: values[0] = (PetscScalar)1.0 / (values[0] + shift); break;
35218a9c020eSBarry Smith   case 2:
35228a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_2(values, shift, allowzeropivot, &zeropivotdetected));
35238a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
35248a9c020eSBarry Smith     break;
35258a9c020eSBarry Smith   case 3:
35268a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_3(values, shift, allowzeropivot, &zeropivotdetected));
35278a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
35288a9c020eSBarry Smith     break;
35298a9c020eSBarry Smith   case 4:
35308a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_4(values, shift, allowzeropivot, &zeropivotdetected));
35318a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
35328a9c020eSBarry Smith     break;
35339371c9d4SSatish Balay   case 5: {
35348a9c020eSBarry Smith     PetscScalar work[25];
35358a9c020eSBarry Smith     PetscInt    ipvt[5];
35368a9c020eSBarry Smith 
35378a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_5(values, ipvt, work, shift, allowzeropivot, &zeropivotdetected));
35388a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
35399371c9d4SSatish Balay   } break;
35408a9c020eSBarry Smith   case 6:
35418a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_6(values, shift, allowzeropivot, &zeropivotdetected));
35428a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
35438a9c020eSBarry Smith     break;
35448a9c020eSBarry Smith   case 7:
35458a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_7(values, shift, allowzeropivot, &zeropivotdetected));
35468a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
35478a9c020eSBarry Smith     break;
35489371c9d4SSatish Balay   default: {
35498a9c020eSBarry Smith     PetscInt    *v_pivots, *IJ, j;
35508a9c020eSBarry Smith     PetscScalar *v_work;
35518a9c020eSBarry Smith 
35528a9c020eSBarry Smith     PetscCall(PetscMalloc3(bs, &v_work, bs, &v_pivots, bs, &IJ));
3553ad540459SPierre Jolivet     for (j = 0; j < bs; j++) IJ[j] = j;
35548a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A(bs, values, v_pivots, v_work, allowzeropivot, &zeropivotdetected));
35558a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
35568a9c020eSBarry Smith     PetscCall(PetscFree3(v_work, v_pivots, IJ));
35578a9c020eSBarry Smith   }
35588a9c020eSBarry Smith   }
35598a9c020eSBarry Smith   PetscFunctionReturn(0);
35608a9c020eSBarry Smith }
3561