xref: /petsc/src/mat/impls/dense/seq/dense.c (revision 3faff0630ddb0e5c928de8ab5c63f2cda2d2edd1)
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));
429566063dSJacob Faibussowitsch       PetscCall(PetscLogObjectMemory((PetscObject)A, mat->lfwork * sizeof(PetscBLASInt)));
438c178816SStefano Zampini     }
449566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
45792fecdfSBarry Smith     PetscCallBLAS("LAPACKgetri", LAPACKgetri_(&n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info));
469566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
479566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0));
488c178816SStefano Zampini   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
49b94d7dedSBarry Smith     if (A->spd == PETSC_BOOL3_TRUE) {
509566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
51792fecdfSBarry Smith       PetscCallBLAS("LAPACKpotri", LAPACKpotri_("L", &n, mat->v, &mat->lda, &info));
529566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
539566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_TRUE));
548c178816SStefano Zampini #if defined(PETSC_USE_COMPLEX)
55b94d7dedSBarry Smith     } else if (A->hermitian == PETSC_BOOL3_TRUE) {
5628b400f6SJacob Faibussowitsch       PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present");
5728b400f6SJacob Faibussowitsch       PetscCheck(mat->fwork, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Fwork not present");
589566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
59792fecdfSBarry Smith       PetscCallBLAS("LAPACKhetri", LAPACKhetri_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &info));
609566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
619566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_TRUE));
628c178816SStefano Zampini #endif
638c178816SStefano Zampini     } else { /* symmetric case */
6428b400f6SJacob Faibussowitsch       PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present");
6528b400f6SJacob Faibussowitsch       PetscCheck(mat->fwork, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Fwork not present");
669566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
67792fecdfSBarry Smith       PetscCallBLAS("LAPACKsytri", LAPACKsytri_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &info));
689566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
699566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_FALSE));
708c178816SStefano Zampini     }
7128b400f6SJacob Faibussowitsch     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad Inversion: zero pivot in row %" PetscInt_FMT, (PetscInt)info - 1);
729566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0));
738c178816SStefano Zampini   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Matrix must be factored to solve");
748c178816SStefano Zampini 
758c178816SStefano Zampini   A->ops->solve             = NULL;
768c178816SStefano Zampini   A->ops->matsolve          = NULL;
778c178816SStefano Zampini   A->ops->solvetranspose    = NULL;
788c178816SStefano Zampini   A->ops->matsolvetranspose = NULL;
798c178816SStefano Zampini   A->ops->solveadd          = NULL;
808c178816SStefano Zampini   A->ops->solvetransposeadd = NULL;
818c178816SStefano Zampini   A->factortype             = MAT_FACTOR_NONE;
829566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
838c178816SStefano Zampini   PetscFunctionReturn(0);
848c178816SStefano Zampini }
858c178816SStefano Zampini 
869371c9d4SSatish Balay PetscErrorCode MatZeroRowsColumns_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) {
873f49a652SStefano Zampini   Mat_SeqDense      *l = (Mat_SeqDense *)A->data;
883f49a652SStefano Zampini   PetscInt           m = l->lda, n = A->cmap->n, r = A->rmap->n, i, j;
89ca15aa20SStefano Zampini   PetscScalar       *slot, *bb, *v;
903f49a652SStefano Zampini   const PetscScalar *xx;
913f49a652SStefano Zampini 
923f49a652SStefano Zampini   PetscFunctionBegin;
9376bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
943f49a652SStefano Zampini     for (i = 0; i < N; i++) {
9508401ef6SPierre Jolivet       PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed");
9608401ef6SPierre 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);
9708401ef6SPierre 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);
983f49a652SStefano Zampini     }
9976bd3646SJed Brown   }
100ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
1013f49a652SStefano Zampini 
1023f49a652SStefano Zampini   /* fix right hand side if needed */
1033f49a652SStefano Zampini   if (x && b) {
1046c4d906cSStefano Zampini     Vec xt;
1056c4d906cSStefano Zampini 
10608401ef6SPierre Jolivet     PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices");
1079566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(x, &xt));
1089566063dSJacob Faibussowitsch     PetscCall(VecCopy(x, xt));
1099566063dSJacob Faibussowitsch     PetscCall(VecScale(xt, -1.0));
1109566063dSJacob Faibussowitsch     PetscCall(MatMultAdd(A, xt, b, b));
1119566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&xt));
1129566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(x, &xx));
1139566063dSJacob Faibussowitsch     PetscCall(VecGetArray(b, &bb));
1143f49a652SStefano Zampini     for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]];
1159566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(x, &xx));
1169566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(b, &bb));
1173f49a652SStefano Zampini   }
1183f49a652SStefano Zampini 
1199566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
1203f49a652SStefano Zampini   for (i = 0; i < N; i++) {
121ca15aa20SStefano Zampini     slot = v + rows[i] * m;
1229566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(slot, r));
1233f49a652SStefano Zampini   }
1243f49a652SStefano Zampini   for (i = 0; i < N; i++) {
125ca15aa20SStefano Zampini     slot = v + rows[i];
1269371c9d4SSatish Balay     for (j = 0; j < n; j++) {
1279371c9d4SSatish Balay       *slot = 0.0;
1289371c9d4SSatish Balay       slot += m;
1299371c9d4SSatish Balay     }
1303f49a652SStefano Zampini   }
1313f49a652SStefano Zampini   if (diag != 0.0) {
13208401ef6SPierre Jolivet     PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices");
1333f49a652SStefano Zampini     for (i = 0; i < N; i++) {
134ca15aa20SStefano Zampini       slot  = v + (m + 1) * rows[i];
1353f49a652SStefano Zampini       *slot = diag;
1363f49a652SStefano Zampini     }
1373f49a652SStefano Zampini   }
1389566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
1393f49a652SStefano Zampini   PetscFunctionReturn(0);
1403f49a652SStefano Zampini }
1413f49a652SStefano Zampini 
1429371c9d4SSatish Balay PetscErrorCode MatPtAPNumeric_SeqDense_SeqDense(Mat A, Mat P, Mat C) {
143abc3b08eSStefano Zampini   Mat_SeqDense *c = (Mat_SeqDense *)(C->data);
144abc3b08eSStefano Zampini 
145abc3b08eSStefano Zampini   PetscFunctionBegin;
146ca15aa20SStefano Zampini   if (c->ptapwork) {
1479566063dSJacob Faibussowitsch     PetscCall((*C->ops->matmultnumeric)(A, P, c->ptapwork));
1489566063dSJacob Faibussowitsch     PetscCall((*C->ops->transposematmultnumeric)(P, c->ptapwork, C));
1494222ddf1SHong Zhang   } else SETERRQ(PetscObjectComm((PetscObject)C), PETSC_ERR_SUP, "Must call MatPtAPSymbolic_SeqDense_SeqDense() first");
150abc3b08eSStefano Zampini   PetscFunctionReturn(0);
151abc3b08eSStefano Zampini }
152abc3b08eSStefano Zampini 
1539371c9d4SSatish Balay PetscErrorCode MatPtAPSymbolic_SeqDense_SeqDense(Mat A, Mat P, PetscReal fill, Mat C) {
154abc3b08eSStefano Zampini   Mat_SeqDense *c;
1557a3c3d58SStefano Zampini   PetscBool     cisdense;
156abc3b08eSStefano Zampini 
157abc3b08eSStefano Zampini   PetscFunctionBegin;
1589566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C, P->cmap->n, P->cmap->n, P->cmap->N, P->cmap->N));
1599566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, ""));
1607a3c3d58SStefano Zampini   if (!cisdense) {
1617a3c3d58SStefano Zampini     PetscBool flg;
1627a3c3d58SStefano Zampini 
1639566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)P, ((PetscObject)A)->type_name, &flg));
1649566063dSJacob Faibussowitsch     PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE));
1657a3c3d58SStefano Zampini   }
1669566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
1674222ddf1SHong Zhang   c = (Mat_SeqDense *)C->data;
1689566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &c->ptapwork));
1699566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(c->ptapwork, A->rmap->n, P->cmap->n, A->rmap->N, P->cmap->N));
1709566063dSJacob Faibussowitsch   PetscCall(MatSetType(c->ptapwork, ((PetscObject)C)->type_name));
1719566063dSJacob Faibussowitsch   PetscCall(MatSetUp(c->ptapwork));
172abc3b08eSStefano Zampini   PetscFunctionReturn(0);
173abc3b08eSStefano Zampini }
174abc3b08eSStefano Zampini 
1759371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) {
176a13144ffSStefano Zampini   Mat              B = NULL;
177b49cda9fSStefano Zampini   Mat_SeqAIJ      *a = (Mat_SeqAIJ *)A->data;
178b49cda9fSStefano Zampini   Mat_SeqDense    *b;
179b49cda9fSStefano Zampini   PetscInt        *ai = a->i, *aj = a->j, m = A->rmap->N, n = A->cmap->N, i;
1802e5835c6SStefano Zampini   const MatScalar *av;
181a13144ffSStefano Zampini   PetscBool        isseqdense;
182b49cda9fSStefano Zampini 
183b49cda9fSStefano Zampini   PetscFunctionBegin;
184a13144ffSStefano Zampini   if (reuse == MAT_REUSE_MATRIX) {
1859566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)*newmat, MATSEQDENSE, &isseqdense));
18628b400f6SJacob Faibussowitsch     PetscCheck(isseqdense, PetscObjectComm((PetscObject)*newmat), PETSC_ERR_USER, "Cannot reuse matrix of type %s", ((PetscObject)(*newmat))->type_name);
187a13144ffSStefano Zampini   }
188a13144ffSStefano Zampini   if (reuse != MAT_REUSE_MATRIX) {
1899566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B));
1909566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(B, m, n, m, n));
1919566063dSJacob Faibussowitsch     PetscCall(MatSetType(B, MATSEQDENSE));
1929566063dSJacob Faibussowitsch     PetscCall(MatSeqDenseSetPreallocation(B, NULL));
193b49cda9fSStefano Zampini     b = (Mat_SeqDense *)(B->data);
194a13144ffSStefano Zampini   } else {
195a13144ffSStefano Zampini     b = (Mat_SeqDense *)((*newmat)->data);
1969566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(b->v, m * n));
197a13144ffSStefano Zampini   }
1989566063dSJacob Faibussowitsch   PetscCall(MatSeqAIJGetArrayRead(A, &av));
199b49cda9fSStefano Zampini   for (i = 0; i < m; i++) {
200b49cda9fSStefano Zampini     PetscInt j;
201b49cda9fSStefano Zampini     for (j = 0; j < ai[1] - ai[0]; j++) {
202b49cda9fSStefano Zampini       b->v[*aj * m + i] = *av;
203b49cda9fSStefano Zampini       aj++;
204b49cda9fSStefano Zampini       av++;
205b49cda9fSStefano Zampini     }
206b49cda9fSStefano Zampini     ai++;
207b49cda9fSStefano Zampini   }
2089566063dSJacob Faibussowitsch   PetscCall(MatSeqAIJRestoreArrayRead(A, &av));
209b49cda9fSStefano Zampini 
210511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
2119566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY));
2129566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY));
2139566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A, &B));
214b49cda9fSStefano Zampini   } else {
215a13144ffSStefano Zampini     if (B) *newmat = B;
2169566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(*newmat, MAT_FINAL_ASSEMBLY));
2179566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(*newmat, MAT_FINAL_ASSEMBLY));
218b49cda9fSStefano Zampini   }
219b49cda9fSStefano Zampini   PetscFunctionReturn(0);
220b49cda9fSStefano Zampini }
221b49cda9fSStefano Zampini 
2229371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatConvert_SeqDense_SeqAIJ(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) {
2236d4ec7b0SPierre Jolivet   Mat           B = NULL;
2246a63e612SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
2259399e1b8SMatthew G. Knepley   PetscInt      i, j;
2269399e1b8SMatthew G. Knepley   PetscInt     *rows, *nnz;
2279399e1b8SMatthew G. Knepley   MatScalar    *aa = a->v, *vals;
2286a63e612SBarry Smith 
2296a63e612SBarry Smith   PetscFunctionBegin;
2309566063dSJacob Faibussowitsch   PetscCall(PetscCalloc3(A->rmap->n, &rows, A->rmap->n, &nnz, A->rmap->n, &vals));
2316d4ec7b0SPierre Jolivet   if (reuse != MAT_REUSE_MATRIX) {
2329566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B));
2339566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(B, A->rmap->n, A->cmap->n, A->rmap->N, A->cmap->N));
2349566063dSJacob Faibussowitsch     PetscCall(MatSetType(B, MATSEQAIJ));
2359399e1b8SMatthew G. Knepley     for (j = 0; j < A->cmap->n; j++) {
2369371c9d4SSatish Balay       for (i = 0; i < A->rmap->n; i++)
2379371c9d4SSatish Balay         if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) ++nnz[i];
2386a63e612SBarry Smith       aa += a->lda;
2396a63e612SBarry Smith     }
2409566063dSJacob Faibussowitsch     PetscCall(MatSeqAIJSetPreallocation(B, PETSC_DETERMINE, nnz));
2416d4ec7b0SPierre Jolivet   } else B = *newmat;
2429399e1b8SMatthew G. Knepley   aa = a->v;
2439399e1b8SMatthew G. Knepley   for (j = 0; j < A->cmap->n; j++) {
2449399e1b8SMatthew G. Knepley     PetscInt numRows = 0;
2459371c9d4SSatish Balay     for (i = 0; i < A->rmap->n; i++)
2469371c9d4SSatish Balay       if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) {
2479371c9d4SSatish Balay         rows[numRows]   = i;
2489371c9d4SSatish Balay         vals[numRows++] = aa[i];
2499371c9d4SSatish Balay       }
2509566063dSJacob Faibussowitsch     PetscCall(MatSetValues(B, numRows, rows, 1, &j, vals, INSERT_VALUES));
2519399e1b8SMatthew G. Knepley     aa += a->lda;
2529399e1b8SMatthew G. Knepley   }
2539566063dSJacob Faibussowitsch   PetscCall(PetscFree3(rows, nnz, vals));
2549566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY));
2559566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY));
2566a63e612SBarry Smith 
257511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
2589566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A, &B));
2596d4ec7b0SPierre Jolivet   } else if (reuse != MAT_REUSE_MATRIX) *newmat = B;
2606a63e612SBarry Smith   PetscFunctionReturn(0);
2616a63e612SBarry Smith }
2626a63e612SBarry Smith 
2639371c9d4SSatish Balay PetscErrorCode MatAXPY_SeqDense(Mat Y, PetscScalar alpha, Mat X, MatStructure str) {
2641987afe7SBarry Smith   Mat_SeqDense      *x = (Mat_SeqDense *)X->data, *y = (Mat_SeqDense *)Y->data;
265ca15aa20SStefano Zampini   const PetscScalar *xv;
266ca15aa20SStefano Zampini   PetscScalar       *yv;
26723fff9afSBarry Smith   PetscBLASInt       N, m, ldax = 0, lday = 0, one = 1;
2683a40ed3dSBarry Smith 
2693a40ed3dSBarry Smith   PetscFunctionBegin;
2709566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(X, &xv));
2719566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(Y, &yv));
2729566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(X->rmap->n * X->cmap->n, &N));
2739566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(X->rmap->n, &m));
2749566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(x->lda, &ldax));
2759566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(y->lda, &lday));
276a5ce6ee0Svictorle   if (ldax > m || lday > m) {
277ca15aa20SStefano Zampini     PetscInt j;
278ca15aa20SStefano Zampini 
27948a46eb9SPierre Jolivet     for (j = 0; j < X->cmap->n; j++) PetscCallBLAS("BLASaxpy", BLASaxpy_(&m, &alpha, xv + j * ldax, &one, yv + j * lday, &one));
280a5ce6ee0Svictorle   } else {
281792fecdfSBarry Smith     PetscCallBLAS("BLASaxpy", BLASaxpy_(&N, &alpha, xv, &one, yv, &one));
282a5ce6ee0Svictorle   }
2839566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(X, &xv));
2849566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(Y, &yv));
2859566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(PetscMax(2.0 * N - 1, 0)));
2863a40ed3dSBarry Smith   PetscFunctionReturn(0);
2871987afe7SBarry Smith }
2881987afe7SBarry Smith 
2899371c9d4SSatish Balay static PetscErrorCode MatGetInfo_SeqDense(Mat A, MatInfoType flag, MatInfo *info) {
290ca15aa20SStefano Zampini   PetscLogDouble N = A->rmap->n * A->cmap->n;
2913a40ed3dSBarry Smith 
2923a40ed3dSBarry Smith   PetscFunctionBegin;
2934e220ebcSLois Curfman McInnes   info->block_size        = 1.0;
294ca15aa20SStefano Zampini   info->nz_allocated      = N;
295ca15aa20SStefano Zampini   info->nz_used           = N;
296ca15aa20SStefano Zampini   info->nz_unneeded       = 0;
297ca15aa20SStefano Zampini   info->assemblies        = A->num_ass;
2984e220ebcSLois Curfman McInnes   info->mallocs           = 0;
2997adad957SLisandro Dalcin   info->memory            = ((PetscObject)A)->mem;
3004e220ebcSLois Curfman McInnes   info->fill_ratio_given  = 0;
3014e220ebcSLois Curfman McInnes   info->fill_ratio_needed = 0;
3024e220ebcSLois Curfman McInnes   info->factor_mallocs    = 0;
3033a40ed3dSBarry Smith   PetscFunctionReturn(0);
304289bc588SBarry Smith }
305289bc588SBarry Smith 
3069371c9d4SSatish Balay PetscErrorCode MatScale_SeqDense(Mat A, PetscScalar alpha) {
307273d9f13SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
308ca15aa20SStefano Zampini   PetscScalar  *v;
30923fff9afSBarry Smith   PetscBLASInt  one = 1, j, nz, lda = 0;
31080cd9d93SLois Curfman McInnes 
3113a40ed3dSBarry Smith   PetscFunctionBegin;
3129566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
3139566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(a->lda, &lda));
314d0f46423SBarry Smith   if (lda > A->rmap->n) {
3159566063dSJacob Faibussowitsch     PetscCall(PetscBLASIntCast(A->rmap->n, &nz));
31648a46eb9SPierre Jolivet     for (j = 0; j < A->cmap->n; j++) PetscCallBLAS("BLASscal", BLASscal_(&nz, &alpha, v + j * lda, &one));
317a5ce6ee0Svictorle   } else {
3189566063dSJacob Faibussowitsch     PetscCall(PetscBLASIntCast(A->rmap->n * A->cmap->n, &nz));
319792fecdfSBarry Smith     PetscCallBLAS("BLASscal", BLASscal_(&nz, &alpha, v, &one));
320a5ce6ee0Svictorle   }
32104cbc005SJose E. Roman   PetscCall(PetscLogFlops(A->rmap->n * A->cmap->n));
3229566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
3233a40ed3dSBarry Smith   PetscFunctionReturn(0);
32480cd9d93SLois Curfman McInnes }
32580cd9d93SLois Curfman McInnes 
3269371c9d4SSatish Balay PetscErrorCode MatShift_SeqDense(Mat A, PetscScalar alpha) {
3272f605a99SJose E. Roman   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
3282f605a99SJose E. Roman   PetscScalar  *v;
3292f605a99SJose E. Roman   PetscInt      j, k;
3302f605a99SJose E. Roman 
3312f605a99SJose E. Roman   PetscFunctionBegin;
3322f605a99SJose E. Roman   PetscCall(MatDenseGetArray(A, &v));
3332f605a99SJose E. Roman   k = PetscMin(A->rmap->n, A->cmap->n);
3342f605a99SJose E. Roman   for (j = 0; j < k; j++) v[j + j * a->lda] += alpha;
3352f605a99SJose E. Roman   PetscCall(PetscLogFlops(k));
3362f605a99SJose E. Roman   PetscCall(MatDenseRestoreArray(A, &v));
3372f605a99SJose E. Roman   PetscFunctionReturn(0);
3382f605a99SJose E. Roman }
3392f605a99SJose E. Roman 
3409371c9d4SSatish Balay static PetscErrorCode MatIsHermitian_SeqDense(Mat A, PetscReal rtol, PetscBool *fl) {
3411cbb95d3SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
342ca15aa20SStefano Zampini   PetscInt           i, j, m = A->rmap->n, N = a->lda;
343ca15aa20SStefano Zampini   const PetscScalar *v;
3441cbb95d3SBarry Smith 
3451cbb95d3SBarry Smith   PetscFunctionBegin;
3461cbb95d3SBarry Smith   *fl = PETSC_FALSE;
347d0f46423SBarry Smith   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
3489566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &v));
3491cbb95d3SBarry Smith   for (i = 0; i < m; i++) {
350ca15aa20SStefano Zampini     for (j = i; j < m; j++) {
351ad540459SPierre Jolivet       if (PetscAbsScalar(v[i + j * N] - PetscConj(v[j + i * N])) > rtol) goto restore;
3521cbb95d3SBarry Smith     }
353637a0070SStefano Zampini   }
3541cbb95d3SBarry Smith   *fl = PETSC_TRUE;
355637a0070SStefano Zampini restore:
3569566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &v));
357637a0070SStefano Zampini   PetscFunctionReturn(0);
358637a0070SStefano Zampini }
359637a0070SStefano Zampini 
3609371c9d4SSatish Balay static PetscErrorCode MatIsSymmetric_SeqDense(Mat A, PetscReal rtol, PetscBool *fl) {
361637a0070SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
362637a0070SStefano Zampini   PetscInt           i, j, m = A->rmap->n, N = a->lda;
363637a0070SStefano Zampini   const PetscScalar *v;
364637a0070SStefano Zampini 
365637a0070SStefano Zampini   PetscFunctionBegin;
366637a0070SStefano Zampini   *fl = PETSC_FALSE;
367637a0070SStefano Zampini   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
3689566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &v));
369637a0070SStefano Zampini   for (i = 0; i < m; i++) {
370637a0070SStefano Zampini     for (j = i; j < m; j++) {
371ad540459SPierre Jolivet       if (PetscAbsScalar(v[i + j * N] - v[j + i * N]) > rtol) goto restore;
372637a0070SStefano Zampini     }
373637a0070SStefano Zampini   }
374637a0070SStefano Zampini   *fl = PETSC_TRUE;
375637a0070SStefano Zampini restore:
3769566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &v));
3771cbb95d3SBarry Smith   PetscFunctionReturn(0);
3781cbb95d3SBarry Smith }
3791cbb95d3SBarry Smith 
3809371c9d4SSatish Balay PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi, Mat A, MatDuplicateOption cpvalues) {
381ca15aa20SStefano Zampini   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
38223fc5dcaSStefano Zampini   PetscInt      lda = (PetscInt)mat->lda, j, m, nlda = lda;
38375f6d85dSStefano Zampini   PetscBool     isdensecpu;
384b24902e0SBarry Smith 
385b24902e0SBarry Smith   PetscFunctionBegin;
3869566063dSJacob Faibussowitsch   PetscCall(PetscLayoutReference(A->rmap, &newi->rmap));
3879566063dSJacob Faibussowitsch   PetscCall(PetscLayoutReference(A->cmap, &newi->cmap));
38823fc5dcaSStefano Zampini   if (cpvalues == MAT_SHARE_NONZERO_PATTERN) { /* propagate LDA */
3899566063dSJacob Faibussowitsch     PetscCall(MatDenseSetLDA(newi, lda));
39023fc5dcaSStefano Zampini   }
3919566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)newi, MATSEQDENSE, &isdensecpu));
3929566063dSJacob Faibussowitsch   if (isdensecpu) PetscCall(MatSeqDenseSetPreallocation(newi, NULL));
393b24902e0SBarry Smith   if (cpvalues == MAT_COPY_VALUES) {
394ca15aa20SStefano Zampini     const PetscScalar *av;
395ca15aa20SStefano Zampini     PetscScalar       *v;
396ca15aa20SStefano Zampini 
3979566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A, &av));
3989566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayWrite(newi, &v));
3999566063dSJacob Faibussowitsch     PetscCall(MatDenseGetLDA(newi, &nlda));
400d0f46423SBarry Smith     m = A->rmap->n;
40123fc5dcaSStefano Zampini     if (lda > m || nlda > m) {
40248a46eb9SPierre Jolivet       for (j = 0; j < A->cmap->n; j++) PetscCall(PetscArraycpy(v + j * nlda, av + j * lda, m));
403b24902e0SBarry Smith     } else {
4049566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(v, av, A->rmap->n * A->cmap->n));
405b24902e0SBarry Smith     }
4069566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayWrite(newi, &v));
4079566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A, &av));
408b24902e0SBarry Smith   }
409b24902e0SBarry Smith   PetscFunctionReturn(0);
410b24902e0SBarry Smith }
411b24902e0SBarry Smith 
4129371c9d4SSatish Balay PetscErrorCode MatDuplicate_SeqDense(Mat A, MatDuplicateOption cpvalues, Mat *newmat) {
4133a40ed3dSBarry Smith   PetscFunctionBegin;
4149566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), newmat));
4159566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*newmat, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n));
4169566063dSJacob Faibussowitsch   PetscCall(MatSetType(*newmat, ((PetscObject)A)->type_name));
4179566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(*newmat, A, cpvalues));
418b24902e0SBarry Smith   PetscFunctionReturn(0);
419b24902e0SBarry Smith }
420b24902e0SBarry Smith 
4219371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_Internal_LU(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T) {
422c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
4234396437dSToby Isaac   PetscBLASInt  info;
42467e560aaSBarry Smith 
4253a40ed3dSBarry Smith   PetscFunctionBegin;
4269566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
427792fecdfSBarry Smith   PetscCallBLAS("LAPACKgetrs", LAPACKgetrs_(T ? "T" : "N", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info));
4289566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
42905fcb23eSStefano Zampini   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "GETRS - Bad solve %d", (int)info);
4309566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m)));
4314396437dSToby Isaac   PetscFunctionReturn(0);
4324396437dSToby Isaac }
4334396437dSToby Isaac 
4344396437dSToby Isaac static PetscErrorCode MatConjugate_SeqDense(Mat);
4354396437dSToby Isaac 
4369371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_Internal_Cholesky(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T) {
4374396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
4384396437dSToby Isaac   PetscBLASInt  info;
4394396437dSToby Isaac 
4404396437dSToby Isaac   PetscFunctionBegin;
441b94d7dedSBarry Smith   if (A->spd == PETSC_BOOL3_TRUE) {
4429566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A));
4439566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
444792fecdfSBarry Smith     PetscCallBLAS("LAPACKpotrs", LAPACKpotrs_("L", &m, &nrhs, mat->v, &mat->lda, x, &m, &info));
4459566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
44605fcb23eSStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "POTRS Bad solve %d", (int)info);
4479566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A));
448a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
449b94d7dedSBarry Smith   } else if (A->hermitian == PETSC_BOOL3_TRUE) {
4509566063dSJacob Faibussowitsch     if (T) PetscCall(MatConjugate_SeqDense(A));
4519566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
452792fecdfSBarry Smith     PetscCallBLAS("LAPACKhetrs", LAPACKhetrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info));
4539566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
45405fcb23eSStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "HETRS Bad solve %d", (int)info);
4559566063dSJacob Faibussowitsch     if (T) PetscCall(MatConjugate_SeqDense(A));
456a49dc2a2SStefano Zampini #endif
457a49dc2a2SStefano Zampini   } else { /* symmetric case */
4589566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
459792fecdfSBarry Smith     PetscCallBLAS("LAPACKsytrs", LAPACKsytrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info));
4609566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
46105fcb23eSStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "SYTRS Bad solve %d", (int)info);
462a49dc2a2SStefano Zampini   }
4639566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m)));
4644396437dSToby Isaac   PetscFunctionReturn(0);
4654396437dSToby Isaac }
46685e2c93fSHong Zhang 
4679371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k) {
4684396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
4694396437dSToby Isaac   PetscBLASInt  info;
4704396437dSToby Isaac   char          trans;
4714396437dSToby Isaac 
4724396437dSToby Isaac   PetscFunctionBegin;
4734905a7bcSToby Isaac   if (PetscDefined(USE_COMPLEX)) {
4744905a7bcSToby Isaac     trans = 'C';
4754905a7bcSToby Isaac   } else {
4764905a7bcSToby Isaac     trans = 'T';
4774905a7bcSToby Isaac   }
4789566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
47905fcb23eSStefano Zampini   { /* lwork depends on the number of right-hand sides */
48005fcb23eSStefano Zampini     PetscBLASInt nlfwork, lfwork = -1;
48105fcb23eSStefano Zampini     PetscScalar  fwork;
48205fcb23eSStefano Zampini 
483792fecdfSBarry Smith     PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info));
48405fcb23eSStefano Zampini     nlfwork = (PetscBLASInt)PetscRealPart(fwork);
48505fcb23eSStefano Zampini     if (nlfwork > mat->lfwork) {
48605fcb23eSStefano Zampini       mat->lfwork = nlfwork;
48705fcb23eSStefano Zampini       PetscCall(PetscFree(mat->fwork));
48805fcb23eSStefano Zampini       PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
48905fcb23eSStefano Zampini     }
49005fcb23eSStefano Zampini   }
491792fecdfSBarry Smith   PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info));
4929566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
49305fcb23eSStefano Zampini   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %d", (int)info);
4949566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
495792fecdfSBarry Smith   PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "N", "N", &mat->rank, &nrhs, mat->v, &mat->lda, x, &ldx, &info));
4969566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
49705fcb23eSStefano Zampini   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %d", (int)info);
4984905a7bcSToby Isaac   for (PetscInt j = 0; j < nrhs; j++) {
499ad540459SPierre Jolivet     for (PetscInt i = mat->rank; i < k; i++) x[j * ldx + i] = 0.;
5004905a7bcSToby Isaac   }
5019566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank))));
5024905a7bcSToby Isaac   PetscFunctionReturn(0);
5034905a7bcSToby Isaac }
5044905a7bcSToby Isaac 
5059371c9d4SSatish Balay static PetscErrorCode MatSolveTranspose_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k) {
5064396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
5074396437dSToby Isaac   PetscBLASInt  info;
5084396437dSToby Isaac 
5094396437dSToby Isaac   PetscFunctionBegin;
5104396437dSToby Isaac   if (A->rmap->n == A->cmap->n && mat->rank == A->rmap->n) {
5119566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
512792fecdfSBarry Smith     PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "T", "N", &m, &nrhs, mat->v, &mat->lda, x, &ldx, &info));
5139566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
51405fcb23eSStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %d", (int)info);
5159566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A));
51605fcb23eSStefano Zampini     { /* lwork depends on the number of right-hand sides */
51705fcb23eSStefano Zampini       PetscBLASInt nlfwork, lfwork = -1;
51805fcb23eSStefano Zampini       PetscScalar  fwork;
51905fcb23eSStefano Zampini 
520792fecdfSBarry Smith       PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info));
52105fcb23eSStefano Zampini       nlfwork = (PetscBLASInt)PetscRealPart(fwork);
52205fcb23eSStefano Zampini       if (nlfwork > mat->lfwork) {
52305fcb23eSStefano Zampini         mat->lfwork = nlfwork;
52405fcb23eSStefano Zampini         PetscCall(PetscFree(mat->fwork));
52505fcb23eSStefano Zampini         PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
52605fcb23eSStefano Zampini       }
52705fcb23eSStefano Zampini     }
5289566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
529792fecdfSBarry Smith     PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info));
5309566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
53105fcb23eSStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %d", (int)info);
5329566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A));
5334396437dSToby Isaac   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "QR factored matrix cannot be used for transpose solve");
5349566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank))));
5354396437dSToby Isaac   PetscFunctionReturn(0);
5364396437dSToby Isaac }
5374396437dSToby Isaac 
5389371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_SetUp(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k) {
5394396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
5404905a7bcSToby Isaac   PetscScalar  *y;
5414905a7bcSToby Isaac   PetscBLASInt  m = 0, k = 0;
5424905a7bcSToby Isaac 
5434905a7bcSToby Isaac   PetscFunctionBegin;
5449566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
5459566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &k));
5464905a7bcSToby Isaac   if (k < m) {
5479566063dSJacob Faibussowitsch     PetscCall(VecCopy(xx, mat->qrrhs));
5489566063dSJacob Faibussowitsch     PetscCall(VecGetArray(mat->qrrhs, &y));
5494905a7bcSToby Isaac   } else {
5509566063dSJacob Faibussowitsch     PetscCall(VecCopy(xx, yy));
5519566063dSJacob Faibussowitsch     PetscCall(VecGetArray(yy, &y));
5524905a7bcSToby Isaac   }
5534396437dSToby Isaac   *_y = y;
5544396437dSToby Isaac   *_k = k;
5554396437dSToby Isaac   *_m = m;
5564396437dSToby Isaac   PetscFunctionReturn(0);
5574396437dSToby Isaac }
5584396437dSToby Isaac 
5599371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_TearDown(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k) {
5604396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
56142e9364cSSatish Balay   PetscScalar  *y   = NULL;
5624396437dSToby Isaac   PetscBLASInt  m, k;
5634396437dSToby Isaac 
5644396437dSToby Isaac   PetscFunctionBegin;
5654396437dSToby Isaac   y   = *_y;
5664396437dSToby Isaac   *_y = NULL;
5674396437dSToby Isaac   k   = *_k;
5684396437dSToby Isaac   m   = *_m;
5694905a7bcSToby Isaac   if (k < m) {
5704905a7bcSToby Isaac     PetscScalar *yv;
5719566063dSJacob Faibussowitsch     PetscCall(VecGetArray(yy, &yv));
5729566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(yv, y, k));
5739566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(yy, &yv));
5749566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(mat->qrrhs, &y));
5754905a7bcSToby Isaac   } else {
5769566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(yy, &y));
5774905a7bcSToby Isaac   }
5784905a7bcSToby Isaac   PetscFunctionReturn(0);
5794905a7bcSToby Isaac }
5804905a7bcSToby Isaac 
5819371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_LU(Mat A, Vec xx, Vec yy) {
58242e9364cSSatish Balay   PetscScalar *y = NULL;
58342e9364cSSatish Balay   PetscBLASInt m = 0, k = 0;
5844396437dSToby Isaac 
5854396437dSToby Isaac   PetscFunctionBegin;
5869566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
5879566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_FALSE));
5889566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
5894396437dSToby Isaac   PetscFunctionReturn(0);
5904396437dSToby Isaac }
5914396437dSToby Isaac 
5929371c9d4SSatish Balay static PetscErrorCode MatSolveTranspose_SeqDense_LU(Mat A, Vec xx, Vec yy) {
59342e9364cSSatish Balay   PetscScalar *y = NULL;
59442e9364cSSatish Balay   PetscBLASInt m = 0, k = 0;
5954396437dSToby Isaac 
5964396437dSToby Isaac   PetscFunctionBegin;
5979566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
5989566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_TRUE));
5999566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6004396437dSToby Isaac   PetscFunctionReturn(0);
6014396437dSToby Isaac }
6024396437dSToby Isaac 
6039371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_Cholesky(Mat A, Vec xx, Vec yy) {
604e54beecaSStefano Zampini   PetscScalar *y = NULL;
605e54beecaSStefano Zampini   PetscBLASInt m = 0, k = 0;
6064396437dSToby Isaac 
6074396437dSToby Isaac   PetscFunctionBegin;
6089566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6099566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_FALSE));
6109566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6114396437dSToby Isaac   PetscFunctionReturn(0);
6124396437dSToby Isaac }
6134396437dSToby Isaac 
6149371c9d4SSatish Balay static PetscErrorCode MatSolveTranspose_SeqDense_Cholesky(Mat A, Vec xx, Vec yy) {
615e54beecaSStefano Zampini   PetscScalar *y = NULL;
616e54beecaSStefano Zampini   PetscBLASInt m = 0, k = 0;
6174396437dSToby Isaac 
6184396437dSToby Isaac   PetscFunctionBegin;
6199566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6209566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_TRUE));
6219566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6224396437dSToby Isaac   PetscFunctionReturn(0);
6234396437dSToby Isaac }
6244396437dSToby Isaac 
6259371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_QR(Mat A, Vec xx, Vec yy) {
626e54beecaSStefano Zampini   PetscScalar *y = NULL;
627e54beecaSStefano Zampini   PetscBLASInt m = 0, k = 0;
6284396437dSToby Isaac 
6294396437dSToby Isaac   PetscFunctionBegin;
6309566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6319566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k));
6329566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6334396437dSToby Isaac   PetscFunctionReturn(0);
6344396437dSToby Isaac }
6354396437dSToby Isaac 
6369371c9d4SSatish Balay static PetscErrorCode MatSolveTranspose_SeqDense_QR(Mat A, Vec xx, Vec yy) {
63742e9364cSSatish Balay   PetscScalar *y = NULL;
63842e9364cSSatish Balay   PetscBLASInt m = 0, k = 0;
6394396437dSToby Isaac 
6404396437dSToby Isaac   PetscFunctionBegin;
6419566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6429566063dSJacob Faibussowitsch   PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k));
6439566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6444396437dSToby Isaac   PetscFunctionReturn(0);
6454396437dSToby Isaac }
6464396437dSToby Isaac 
6479371c9d4SSatish Balay static PetscErrorCode MatMatSolve_SeqDense_SetUp(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k) {
6484905a7bcSToby Isaac   const PetscScalar *b;
6494396437dSToby Isaac   PetscScalar       *y;
650bf5a80bcSToby Isaac   PetscInt           n, _ldb, _ldx;
651bf5a80bcSToby Isaac   PetscBLASInt       nrhs = 0, m = 0, k = 0, ldb = 0, ldx = 0, ldy = 0;
6524905a7bcSToby Isaac 
6534905a7bcSToby Isaac   PetscFunctionBegin;
6549371c9d4SSatish Balay   *_ldy  = 0;
6559371c9d4SSatish Balay   *_m    = 0;
6569371c9d4SSatish Balay   *_nrhs = 0;
6579371c9d4SSatish Balay   *_k    = 0;
6589371c9d4SSatish Balay   *_y    = NULL;
6599566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
6609566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &k));
6619566063dSJacob Faibussowitsch   PetscCall(MatGetSize(B, NULL, &n));
6629566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(n, &nrhs));
6639566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(B, &_ldb));
6649566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldb, &ldb));
6659566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(X, &_ldx));
6669566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldx, &ldx));
667bf5a80bcSToby Isaac   if (ldx < m) {
6689566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(B, &b));
6699566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nrhs * m, &y));
670bf5a80bcSToby Isaac     if (ldb == m) {
6719566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(y, b, ldb * nrhs));
6724905a7bcSToby Isaac     } else {
67348a46eb9SPierre Jolivet       for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * m], &b[j * ldb], m));
6744905a7bcSToby Isaac     }
675bf5a80bcSToby Isaac     ldy = m;
6769566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(B, &b));
6774905a7bcSToby Isaac   } else {
678bf5a80bcSToby Isaac     if (ldb == ldx) {
6799566063dSJacob Faibussowitsch       PetscCall(MatCopy(B, X, SAME_NONZERO_PATTERN));
6809566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(X, &y));
6814905a7bcSToby Isaac     } else {
6829566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(X, &y));
6839566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArrayRead(B, &b));
68448a46eb9SPierre Jolivet       for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * ldx], &b[j * ldb], m));
6859566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArrayRead(B, &b));
6864905a7bcSToby Isaac     }
687bf5a80bcSToby Isaac     ldy = ldx;
6884905a7bcSToby Isaac   }
6894396437dSToby Isaac   *_y    = y;
690bf5a80bcSToby Isaac   *_ldy  = ldy;
6914396437dSToby Isaac   *_k    = k;
6924396437dSToby Isaac   *_m    = m;
6934396437dSToby Isaac   *_nrhs = nrhs;
6944396437dSToby Isaac   PetscFunctionReturn(0);
6954396437dSToby Isaac }
6964396437dSToby Isaac 
6979371c9d4SSatish Balay static PetscErrorCode MatMatSolve_SeqDense_TearDown(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k) {
6984396437dSToby Isaac   PetscScalar *y;
699bf5a80bcSToby Isaac   PetscInt     _ldx;
700bf5a80bcSToby Isaac   PetscBLASInt k, ldy, nrhs, ldx = 0;
7014396437dSToby Isaac 
7024396437dSToby Isaac   PetscFunctionBegin;
7034396437dSToby Isaac   y    = *_y;
7044396437dSToby Isaac   *_y  = NULL;
7054396437dSToby Isaac   k    = *_k;
706bf5a80bcSToby Isaac   ldy  = *_ldy;
7074396437dSToby Isaac   nrhs = *_nrhs;
7089566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(X, &_ldx));
7099566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldx, &ldx));
710bf5a80bcSToby Isaac   if (ldx != ldy) {
7114905a7bcSToby Isaac     PetscScalar *xv;
7129566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArray(X, &xv));
71348a46eb9SPierre Jolivet     for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&xv[j * ldx], &y[j * ldy], k));
7149566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(X, &xv));
7159566063dSJacob Faibussowitsch     PetscCall(PetscFree(y));
7164905a7bcSToby Isaac   } else {
7179566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(X, &y));
7184905a7bcSToby Isaac   }
71985e2c93fSHong Zhang   PetscFunctionReturn(0);
72085e2c93fSHong Zhang }
72185e2c93fSHong Zhang 
7229371c9d4SSatish Balay static PetscErrorCode MatMatSolve_SeqDense_LU(Mat A, Mat B, Mat X) {
7234396437dSToby Isaac   PetscScalar *y;
724bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7254396437dSToby Isaac 
7264396437dSToby Isaac   PetscFunctionBegin;
7279566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7289566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_FALSE));
7299566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7304396437dSToby Isaac   PetscFunctionReturn(0);
7314396437dSToby Isaac }
7324396437dSToby Isaac 
7339371c9d4SSatish Balay static PetscErrorCode MatMatSolveTranspose_SeqDense_LU(Mat A, Mat B, Mat X) {
7344396437dSToby Isaac   PetscScalar *y;
735bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7364396437dSToby Isaac 
7374396437dSToby Isaac   PetscFunctionBegin;
7389566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7399566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_TRUE));
7409566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7414396437dSToby Isaac   PetscFunctionReturn(0);
7424396437dSToby Isaac }
7434396437dSToby Isaac 
7449371c9d4SSatish Balay static PetscErrorCode MatMatSolve_SeqDense_Cholesky(Mat A, Mat B, Mat X) {
7454396437dSToby Isaac   PetscScalar *y;
746bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7474396437dSToby Isaac 
7484396437dSToby Isaac   PetscFunctionBegin;
7499566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7509566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_FALSE));
7519566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7524396437dSToby Isaac   PetscFunctionReturn(0);
7534396437dSToby Isaac }
7544396437dSToby Isaac 
7559371c9d4SSatish Balay static PetscErrorCode MatMatSolveTranspose_SeqDense_Cholesky(Mat A, Mat B, Mat X) {
7564396437dSToby Isaac   PetscScalar *y;
757bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7584396437dSToby Isaac 
7594396437dSToby Isaac   PetscFunctionBegin;
7609566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7619566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_TRUE));
7629566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7634396437dSToby Isaac   PetscFunctionReturn(0);
7644396437dSToby Isaac }
7654396437dSToby Isaac 
7669371c9d4SSatish Balay static PetscErrorCode MatMatSolve_SeqDense_QR(Mat A, Mat B, Mat X) {
7674396437dSToby Isaac   PetscScalar *y;
768bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7694396437dSToby Isaac 
7704396437dSToby Isaac   PetscFunctionBegin;
7719566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7729566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k));
7739566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7744396437dSToby Isaac   PetscFunctionReturn(0);
7754396437dSToby Isaac }
7764396437dSToby Isaac 
7779371c9d4SSatish Balay static PetscErrorCode MatMatSolveTranspose_SeqDense_QR(Mat A, Mat B, Mat X) {
7784396437dSToby Isaac   PetscScalar *y;
779bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7804396437dSToby Isaac 
7814396437dSToby Isaac   PetscFunctionBegin;
7829566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7839566063dSJacob Faibussowitsch   PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k));
7849566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7854396437dSToby Isaac   PetscFunctionReturn(0);
7864396437dSToby Isaac }
7874396437dSToby Isaac 
788db4efbfdSBarry Smith /* ---------------------------------------------------------------*/
789db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots,
790db4efbfdSBarry Smith    rather than put it in the Mat->row slot.*/
7919371c9d4SSatish Balay PetscErrorCode MatLUFactor_SeqDense(Mat A, IS row, IS col, const MatFactorInfo *minfo) {
792db4efbfdSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
793db4efbfdSBarry Smith   PetscBLASInt  n, m, info;
794db4efbfdSBarry Smith 
795db4efbfdSBarry Smith   PetscFunctionBegin;
7969566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
7979566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
798db4efbfdSBarry Smith   if (!mat->pivots) {
7999566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots));
8009566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)A, A->rmap->n * sizeof(PetscBLASInt)));
801db4efbfdSBarry Smith   }
802db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
8039566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
804792fecdfSBarry Smith   PetscCallBLAS("LAPACKgetrf", LAPACKgetrf_(&m, &n, mat->v, &mat->lda, mat->pivots, &info));
8059566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
8068e57ea43SSatish Balay 
80705fcb23eSStefano Zampini   PetscCheck(info >= 0, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to LU factorization %d", (int)info);
80805fcb23eSStefano Zampini   PetscCheck(info <= 0, PETSC_COMM_SELF, PETSC_ERR_MAT_LU_ZRPVT, "Bad LU factorization %d", (int)info);
8098208b9aeSStefano Zampini 
8104396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_LU;
8114396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_LU;
8124396437dSToby Isaac   A->ops->solvetranspose    = MatSolveTranspose_SeqDense_LU;
8134396437dSToby Isaac   A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_LU;
814d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_LU;
815db4efbfdSBarry Smith 
8169566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
8179566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype));
818f6224b95SHong Zhang 
8199566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops((2.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3));
820db4efbfdSBarry Smith   PetscFunctionReturn(0);
821db4efbfdSBarry Smith }
822db4efbfdSBarry Smith 
8239371c9d4SSatish Balay static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) {
8244396437dSToby Isaac   MatFactorInfo info;
8254396437dSToby Isaac 
8264396437dSToby Isaac   PetscFunctionBegin;
8279566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES));
828dbbe0bcdSBarry Smith   PetscUseTypeMethod(fact, lufactor, NULL, NULL, &info);
8294396437dSToby Isaac   PetscFunctionReturn(0);
8304396437dSToby Isaac }
8314396437dSToby Isaac 
8329371c9d4SSatish Balay PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, IS col, const MatFactorInfo *info) {
8334396437dSToby Isaac   PetscFunctionBegin;
8344396437dSToby Isaac   fact->preallocated         = PETSC_TRUE;
8354396437dSToby Isaac   fact->assembled            = PETSC_TRUE;
8364396437dSToby Isaac   fact->ops->lufactornumeric = MatLUFactorNumeric_SeqDense;
8374396437dSToby Isaac   PetscFunctionReturn(0);
8384396437dSToby Isaac }
8394396437dSToby Isaac 
840a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */
8419371c9d4SSatish Balay PetscErrorCode MatCholeskyFactor_SeqDense(Mat A, IS perm, const MatFactorInfo *factinfo) {
842db4efbfdSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
843c5df96a5SBarry Smith   PetscBLASInt  info, n;
844db4efbfdSBarry Smith 
845db4efbfdSBarry Smith   PetscFunctionBegin;
8469566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
847db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
848b94d7dedSBarry Smith   if (A->spd == PETSC_BOOL3_TRUE) {
8499566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
850792fecdfSBarry Smith     PetscCallBLAS("LAPACKpotrf", LAPACKpotrf_("L", &n, mat->v, &mat->lda, &info));
8519566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
852a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
853b94d7dedSBarry Smith   } else if (A->hermitian == PETSC_BOOL3_TRUE) {
854a49dc2a2SStefano Zampini     if (!mat->pivots) {
8559566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots));
8569566063dSJacob Faibussowitsch       PetscCall(PetscLogObjectMemory((PetscObject)A, A->rmap->n * sizeof(PetscBLASInt)));
857a49dc2a2SStefano Zampini     }
858a49dc2a2SStefano Zampini     if (!mat->fwork) {
859a49dc2a2SStefano Zampini       PetscScalar dummy;
860a49dc2a2SStefano Zampini 
861a49dc2a2SStefano Zampini       mat->lfwork = -1;
8629566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
863792fecdfSBarry Smith       PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info));
8649566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
865a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
8669566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
8679566063dSJacob Faibussowitsch       PetscCall(PetscLogObjectMemory((PetscObject)A, mat->lfwork * sizeof(PetscBLASInt)));
868a49dc2a2SStefano Zampini     }
8699566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
870792fecdfSBarry Smith     PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info));
8719566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
872a49dc2a2SStefano Zampini #endif
873a49dc2a2SStefano Zampini   } else { /* symmetric case */
874a49dc2a2SStefano Zampini     if (!mat->pivots) {
8759566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots));
8769566063dSJacob Faibussowitsch       PetscCall(PetscLogObjectMemory((PetscObject)A, A->rmap->n * sizeof(PetscBLASInt)));
877a49dc2a2SStefano Zampini     }
878a49dc2a2SStefano Zampini     if (!mat->fwork) {
879a49dc2a2SStefano Zampini       PetscScalar dummy;
880a49dc2a2SStefano Zampini 
881a49dc2a2SStefano Zampini       mat->lfwork = -1;
8829566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
883792fecdfSBarry Smith       PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info));
8849566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
885a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
8869566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
8879566063dSJacob Faibussowitsch       PetscCall(PetscLogObjectMemory((PetscObject)A, mat->lfwork * sizeof(PetscBLASInt)));
888a49dc2a2SStefano Zampini     }
8899566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
890792fecdfSBarry Smith     PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info));
8919566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
892a49dc2a2SStefano Zampini   }
89328b400f6SJacob Faibussowitsch   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad factorization: zero pivot in row %" PetscInt_FMT, (PetscInt)info - 1);
8948208b9aeSStefano Zampini 
8954396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_Cholesky;
8964396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_Cholesky;
8974396437dSToby Isaac   A->ops->solvetranspose    = MatSolveTranspose_SeqDense_Cholesky;
8984396437dSToby Isaac   A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_Cholesky;
899d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_CHOLESKY;
9002205254eSKarl Rupp 
9019566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
9029566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype));
903f6224b95SHong Zhang 
9049566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0));
905db4efbfdSBarry Smith   PetscFunctionReturn(0);
906db4efbfdSBarry Smith }
907db4efbfdSBarry Smith 
9089371c9d4SSatish Balay static PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) {
909db4efbfdSBarry Smith   MatFactorInfo info;
910db4efbfdSBarry Smith 
911db4efbfdSBarry Smith   PetscFunctionBegin;
912db4efbfdSBarry Smith   info.fill = 1.0;
9132205254eSKarl Rupp 
9149566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES));
915dbbe0bcdSBarry Smith   PetscUseTypeMethod(fact, choleskyfactor, NULL, &info);
916db4efbfdSBarry Smith   PetscFunctionReturn(0);
917db4efbfdSBarry Smith }
918db4efbfdSBarry Smith 
9199371c9d4SSatish Balay PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info) {
920db4efbfdSBarry Smith   PetscFunctionBegin;
921c3ef05f6SHong Zhang   fact->assembled                  = PETSC_TRUE;
9221bbcc794SSatish Balay   fact->preallocated               = PETSC_TRUE;
923719d5645SBarry Smith   fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense;
924db4efbfdSBarry Smith   PetscFunctionReturn(0);
925db4efbfdSBarry Smith }
926db4efbfdSBarry Smith 
9279371c9d4SSatish Balay PetscErrorCode MatQRFactor_SeqDense(Mat A, IS col, const MatFactorInfo *minfo) {
9284905a7bcSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
9294905a7bcSToby Isaac   PetscBLASInt  n, m, info, min, max;
9304905a7bcSToby Isaac 
9314905a7bcSToby Isaac   PetscFunctionBegin;
9329566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
9339566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
9344396437dSToby Isaac   max = PetscMax(m, n);
9354396437dSToby Isaac   min = PetscMin(m, n);
9364905a7bcSToby Isaac   if (!mat->tau) {
9379566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(min, &mat->tau));
9389566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)A, min * sizeof(PetscScalar)));
9394396437dSToby Isaac   }
9404396437dSToby Isaac   if (!mat->pivots) {
9419566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n, &mat->pivots));
9429566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)A, n * sizeof(PetscScalar)));
9434396437dSToby Isaac   }
94448a46eb9SPierre Jolivet   if (!mat->qrrhs) PetscCall(MatCreateVecs(A, NULL, &(mat->qrrhs)));
9454905a7bcSToby Isaac   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
9464905a7bcSToby Isaac   if (!mat->fwork) {
9474905a7bcSToby Isaac     PetscScalar dummy;
9484905a7bcSToby Isaac 
9494905a7bcSToby Isaac     mat->lfwork = -1;
9509566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
951792fecdfSBarry Smith     PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, &dummy, &mat->lfwork, &info));
9529566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
9534905a7bcSToby Isaac     mat->lfwork = (PetscInt)PetscRealPart(dummy);
9549566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
9559566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)A, mat->lfwork * sizeof(PetscBLASInt)));
9564905a7bcSToby Isaac   }
9579566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
958792fecdfSBarry Smith   PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, mat->fwork, &mat->lfwork, &info));
9599566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
96005fcb23eSStefano Zampini   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to QR factorization %d", (int)info);
9614905a7bcSToby 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
9624905a7bcSToby Isaac   mat->rank = min;
9634905a7bcSToby Isaac 
9644396437dSToby Isaac   A->ops->solve    = MatSolve_SeqDense_QR;
9654396437dSToby Isaac   A->ops->matsolve = MatMatSolve_SeqDense_QR;
9664905a7bcSToby Isaac   A->factortype    = MAT_FACTOR_QR;
9674905a7bcSToby Isaac   if (m == n) {
9684396437dSToby Isaac     A->ops->solvetranspose    = MatSolveTranspose_SeqDense_QR;
9694396437dSToby Isaac     A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_QR;
9704905a7bcSToby Isaac   }
9714905a7bcSToby Isaac 
9729566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
9739566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype));
9744905a7bcSToby Isaac 
9759566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0 * min * min * (max - min / 3.0)));
9764905a7bcSToby Isaac   PetscFunctionReturn(0);
9774905a7bcSToby Isaac }
9784905a7bcSToby Isaac 
9799371c9d4SSatish Balay static PetscErrorCode MatQRFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) {
9804905a7bcSToby Isaac   MatFactorInfo info;
9814905a7bcSToby Isaac 
9824905a7bcSToby Isaac   PetscFunctionBegin;
9834905a7bcSToby Isaac   info.fill = 1.0;
9844905a7bcSToby Isaac 
9859566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES));
986cac4c232SBarry Smith   PetscUseMethod(fact, "MatQRFactor_C", (Mat, IS, const MatFactorInfo *), (fact, NULL, &info));
9874905a7bcSToby Isaac   PetscFunctionReturn(0);
9884905a7bcSToby Isaac }
9894905a7bcSToby Isaac 
9909371c9d4SSatish Balay PetscErrorCode MatQRFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info) {
9914905a7bcSToby Isaac   PetscFunctionBegin;
9924905a7bcSToby Isaac   fact->assembled    = PETSC_TRUE;
9934905a7bcSToby Isaac   fact->preallocated = PETSC_TRUE;
9949566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)fact, "MatQRFactorNumeric_C", MatQRFactorNumeric_SeqDense));
9954905a7bcSToby Isaac   PetscFunctionReturn(0);
9964905a7bcSToby Isaac }
9974905a7bcSToby Isaac 
998ca15aa20SStefano Zampini /* uses LAPACK */
9999371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A, MatFactorType ftype, Mat *fact) {
1000db4efbfdSBarry Smith   PetscFunctionBegin;
10019566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), fact));
10029566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*fact, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n));
10039566063dSJacob Faibussowitsch   PetscCall(MatSetType(*fact, MATDENSE));
100466e17bc3SBarry Smith   (*fact)->trivialsymbolic = PETSC_TRUE;
10052a350339SBarry Smith   if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU) {
1006db4efbfdSBarry Smith     (*fact)->ops->lufactorsymbolic  = MatLUFactorSymbolic_SeqDense;
10072a350339SBarry Smith     (*fact)->ops->ilufactorsymbolic = MatLUFactorSymbolic_SeqDense;
1008bf5a80bcSToby Isaac   } else if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) {
1009db4efbfdSBarry Smith     (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense;
1010bf5a80bcSToby Isaac   } else if (ftype == MAT_FACTOR_QR) {
10119566063dSJacob Faibussowitsch     PetscCall(PetscObjectComposeFunction((PetscObject)(*fact), "MatQRFactorSymbolic_C", MatQRFactorSymbolic_SeqDense));
1012db4efbfdSBarry Smith   }
1013d5f3da31SBarry Smith   (*fact)->factortype = ftype;
101400c67f3bSHong Zhang 
10159566063dSJacob Faibussowitsch   PetscCall(PetscFree((*fact)->solvertype));
10169566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC, &(*fact)->solvertype));
10179566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_LU]));
10189566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ILU]));
10199566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_CHOLESKY]));
10209566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ICC]));
1021db4efbfdSBarry Smith   PetscFunctionReturn(0);
1022db4efbfdSBarry Smith }
1023db4efbfdSBarry Smith 
1024289bc588SBarry Smith /* ------------------------------------------------------------------*/
10259371c9d4SSatish Balay static PetscErrorCode MatSOR_SeqDense(Mat A, Vec bb, PetscReal omega, MatSORType flag, PetscReal shift, PetscInt its, PetscInt lits, Vec xx) {
1026c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1027d9ca1df4SBarry Smith   PetscScalar       *x, *v = mat->v, zero = 0.0, xt;
1028d9ca1df4SBarry Smith   const PetscScalar *b;
1029d0f46423SBarry Smith   PetscInt           m = A->rmap->n, i;
103023fff9afSBarry Smith   PetscBLASInt       o = 1, bm = 0;
1031289bc588SBarry Smith 
10323a40ed3dSBarry Smith   PetscFunctionBegin;
1033ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
103408401ef6SPierre Jolivet   PetscCheck(A->offloadmask != PETSC_OFFLOAD_GPU, PETSC_COMM_SELF, PETSC_ERR_SUP, "Not implemented");
1035ca15aa20SStefano Zampini #endif
1036422a814eSBarry Smith   if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */
10379566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(m, &bm));
1038289bc588SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
10393bffc371SBarry Smith     /* this is a hack fix, should have another version without the second BLASdotu */
10409566063dSJacob Faibussowitsch     PetscCall(VecSet(xx, zero));
1041289bc588SBarry Smith   }
10429566063dSJacob Faibussowitsch   PetscCall(VecGetArray(xx, &x));
10439566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(bb, &b));
1044b965ef7fSBarry Smith   its = its * lits;
104508401ef6SPierre 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);
1046289bc588SBarry Smith   while (its--) {
1047fccaa45eSBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
1048289bc588SBarry Smith       for (i = 0; i < m; i++) {
1049792fecdfSBarry Smith         PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o));
105055a1b374SBarry Smith         x[i] = (1. - omega) * x[i] + omega * (xt + v[i + i * m] * x[i]) / (v[i + i * m] + shift);
1051289bc588SBarry Smith       }
1052289bc588SBarry Smith     }
1053fccaa45eSBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
1054289bc588SBarry Smith       for (i = m - 1; i >= 0; i--) {
1055792fecdfSBarry Smith         PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o));
105655a1b374SBarry Smith         x[i] = (1. - omega) * x[i] + omega * (xt + v[i + i * m] * x[i]) / (v[i + i * m] + shift);
1057289bc588SBarry Smith       }
1058289bc588SBarry Smith     }
1059289bc588SBarry Smith   }
10609566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(bb, &b));
10619566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(xx, &x));
10623a40ed3dSBarry Smith   PetscFunctionReturn(0);
1063289bc588SBarry Smith }
1064289bc588SBarry Smith 
1065289bc588SBarry Smith /* -----------------------------------------------------------------*/
10669371c9d4SSatish Balay PetscErrorCode MatMultTranspose_SeqDense(Mat A, Vec xx, Vec yy) {
1067c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1068d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v, *x;
1069d9ca1df4SBarry Smith   PetscScalar       *y;
10700805154bSBarry Smith   PetscBLASInt       m, n, _One = 1;
1071ea709b57SSatish Balay   PetscScalar        _DOne = 1.0, _DZero = 0.0;
10723a40ed3dSBarry Smith 
10733a40ed3dSBarry Smith   PetscFunctionBegin;
10749566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
10759566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
10769566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx, &x));
10779566063dSJacob Faibussowitsch   PetscCall(VecGetArrayWrite(yy, &y));
10785ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
10795ac36cfcSBarry Smith     PetscBLASInt i;
10805ac36cfcSBarry Smith     for (i = 0; i < n; i++) y[i] = 0.0;
10815ac36cfcSBarry Smith   } else {
1082792fecdfSBarry Smith     PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v, &mat->lda, x, &_One, &_DZero, y, &_One));
10839566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n - A->cmap->n));
10845ac36cfcSBarry Smith   }
10859566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx, &x));
10869566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayWrite(yy, &y));
10873a40ed3dSBarry Smith   PetscFunctionReturn(0);
1088289bc588SBarry Smith }
1089800995b7SMatthew Knepley 
10909371c9d4SSatish Balay PetscErrorCode MatMult_SeqDense(Mat A, Vec xx, Vec yy) {
1091c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1092d9ca1df4SBarry Smith   PetscScalar       *y, _DOne = 1.0, _DZero = 0.0;
10930805154bSBarry Smith   PetscBLASInt       m, n, _One             = 1;
1094d9ca1df4SBarry Smith   const PetscScalar *v = mat->v, *x;
10953a40ed3dSBarry Smith 
10963a40ed3dSBarry Smith   PetscFunctionBegin;
10979566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
10989566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
10999566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx, &x));
11009566063dSJacob Faibussowitsch   PetscCall(VecGetArrayWrite(yy, &y));
11015ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
11025ac36cfcSBarry Smith     PetscBLASInt i;
11035ac36cfcSBarry Smith     for (i = 0; i < m; i++) y[i] = 0.0;
11045ac36cfcSBarry Smith   } else {
1105792fecdfSBarry Smith     PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DZero, y, &_One));
11069566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n - A->rmap->n));
11075ac36cfcSBarry Smith   }
11089566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx, &x));
11099566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayWrite(yy, &y));
11103a40ed3dSBarry Smith   PetscFunctionReturn(0);
1111289bc588SBarry Smith }
11126ee01492SSatish Balay 
11139371c9d4SSatish Balay PetscErrorCode MatMultAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) {
1114c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1115d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v, *x;
1116d9ca1df4SBarry Smith   PetscScalar       *y, _DOne = 1.0;
11170805154bSBarry Smith   PetscBLASInt       m, n, _One = 1;
11183a40ed3dSBarry Smith 
11193a40ed3dSBarry Smith   PetscFunctionBegin;
11209566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
11219566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
11229566063dSJacob Faibussowitsch   PetscCall(VecCopy(zz, yy));
1123d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
11249566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx, &x));
11259566063dSJacob Faibussowitsch   PetscCall(VecGetArray(yy, &y));
1126792fecdfSBarry Smith   PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DOne, y, &_One));
11279566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx, &x));
11289566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(yy, &y));
11299566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n));
11303a40ed3dSBarry Smith   PetscFunctionReturn(0);
1131289bc588SBarry Smith }
11326ee01492SSatish Balay 
11339371c9d4SSatish Balay PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) {
1134c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1135d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v, *x;
1136d9ca1df4SBarry Smith   PetscScalar       *y;
11370805154bSBarry Smith   PetscBLASInt       m, n, _One = 1;
113887828ca2SBarry Smith   PetscScalar        _DOne = 1.0;
11393a40ed3dSBarry Smith 
11403a40ed3dSBarry Smith   PetscFunctionBegin;
11419566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
11429566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
11439566063dSJacob Faibussowitsch   PetscCall(VecCopy(zz, yy));
1144d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
11459566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx, &x));
11469566063dSJacob Faibussowitsch   PetscCall(VecGetArray(yy, &y));
1147792fecdfSBarry Smith   PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DOne, y, &_One));
11489566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx, &x));
11499566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(yy, &y));
11509566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n));
11513a40ed3dSBarry Smith   PetscFunctionReturn(0);
1152289bc588SBarry Smith }
1153289bc588SBarry Smith 
1154289bc588SBarry Smith /* -----------------------------------------------------------------*/
11559371c9d4SSatish Balay static PetscErrorCode MatGetRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals) {
1156c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
115713f74950SBarry Smith   PetscInt      i;
115867e560aaSBarry Smith 
11593a40ed3dSBarry Smith   PetscFunctionBegin;
1160d0f46423SBarry Smith   *ncols = A->cmap->n;
1161289bc588SBarry Smith   if (cols) {
11629566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(A->cmap->n, cols));
1163d0f46423SBarry Smith     for (i = 0; i < A->cmap->n; i++) (*cols)[i] = i;
1164289bc588SBarry Smith   }
1165289bc588SBarry Smith   if (vals) {
1166ca15aa20SStefano Zampini     const PetscScalar *v;
1167ca15aa20SStefano Zampini 
11689566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A, &v));
11699566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(A->cmap->n, vals));
1170ca15aa20SStefano Zampini     v += row;
11719371c9d4SSatish Balay     for (i = 0; i < A->cmap->n; i++) {
11729371c9d4SSatish Balay       (*vals)[i] = *v;
11739371c9d4SSatish Balay       v += mat->lda;
11749371c9d4SSatish Balay     }
11759566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A, &v));
1176289bc588SBarry Smith   }
11773a40ed3dSBarry Smith   PetscFunctionReturn(0);
1178289bc588SBarry Smith }
11796ee01492SSatish Balay 
11809371c9d4SSatish Balay static PetscErrorCode MatRestoreRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals) {
1181606d414cSSatish Balay   PetscFunctionBegin;
1182cb4a9cd9SHong Zhang   if (ncols) *ncols = 0;
11839566063dSJacob Faibussowitsch   if (cols) PetscCall(PetscFree(*cols));
11849566063dSJacob Faibussowitsch   if (vals) PetscCall(PetscFree(*vals));
11853a40ed3dSBarry Smith   PetscFunctionReturn(0);
1186289bc588SBarry Smith }
1187289bc588SBarry Smith /* ----------------------------------------------------------------*/
11889371c9d4SSatish Balay static PetscErrorCode MatSetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], const PetscScalar v[], InsertMode addv) {
1189c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
1190ca15aa20SStefano Zampini   PetscScalar  *av;
119113f74950SBarry Smith   PetscInt      i, j, idx = 0;
1192ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1193c70f7ee4SJunchao Zhang   PetscOffloadMask oldf;
1194ca15aa20SStefano Zampini #endif
1195d6dfbf8fSBarry Smith 
11963a40ed3dSBarry Smith   PetscFunctionBegin;
11979566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &av));
1198289bc588SBarry Smith   if (!mat->roworiented) {
1199dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1200289bc588SBarry Smith       for (j = 0; j < n; j++) {
12019371c9d4SSatish Balay         if (indexn[j] < 0) {
12029371c9d4SSatish Balay           idx += m;
12039371c9d4SSatish Balay           continue;
12049371c9d4SSatish Balay         }
12056bdcaf15SBarry 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);
1206289bc588SBarry Smith         for (i = 0; i < m; i++) {
12079371c9d4SSatish Balay           if (indexm[i] < 0) {
12089371c9d4SSatish Balay             idx++;
12099371c9d4SSatish Balay             continue;
12109371c9d4SSatish Balay           }
12116bdcaf15SBarry 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);
1212ca15aa20SStefano Zampini           av[indexn[j] * mat->lda + indexm[i]] = v[idx++];
1213289bc588SBarry Smith         }
1214289bc588SBarry Smith       }
12153a40ed3dSBarry Smith     } else {
1216289bc588SBarry Smith       for (j = 0; j < n; j++) {
12179371c9d4SSatish Balay         if (indexn[j] < 0) {
12189371c9d4SSatish Balay           idx += m;
12199371c9d4SSatish Balay           continue;
12209371c9d4SSatish Balay         }
12216bdcaf15SBarry 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);
1222289bc588SBarry Smith         for (i = 0; i < m; i++) {
12239371c9d4SSatish Balay           if (indexm[i] < 0) {
12249371c9d4SSatish Balay             idx++;
12259371c9d4SSatish Balay             continue;
12269371c9d4SSatish Balay           }
12276bdcaf15SBarry 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);
1228ca15aa20SStefano Zampini           av[indexn[j] * mat->lda + indexm[i]] += v[idx++];
1229289bc588SBarry Smith         }
1230289bc588SBarry Smith       }
1231289bc588SBarry Smith     }
12323a40ed3dSBarry Smith   } else {
1233dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1234e8d4e0b9SBarry Smith       for (i = 0; i < m; i++) {
12359371c9d4SSatish Balay         if (indexm[i] < 0) {
12369371c9d4SSatish Balay           idx += n;
12379371c9d4SSatish Balay           continue;
12389371c9d4SSatish Balay         }
12396bdcaf15SBarry 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);
1240e8d4e0b9SBarry Smith         for (j = 0; j < n; j++) {
12419371c9d4SSatish Balay           if (indexn[j] < 0) {
12429371c9d4SSatish Balay             idx++;
12439371c9d4SSatish Balay             continue;
12449371c9d4SSatish Balay           }
12456bdcaf15SBarry 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);
1246ca15aa20SStefano Zampini           av[indexn[j] * mat->lda + indexm[i]] = v[idx++];
1247e8d4e0b9SBarry Smith         }
1248e8d4e0b9SBarry Smith       }
12493a40ed3dSBarry Smith     } else {
1250289bc588SBarry Smith       for (i = 0; i < m; i++) {
12519371c9d4SSatish Balay         if (indexm[i] < 0) {
12529371c9d4SSatish Balay           idx += n;
12539371c9d4SSatish Balay           continue;
12549371c9d4SSatish Balay         }
12556bdcaf15SBarry 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);
1256289bc588SBarry Smith         for (j = 0; j < n; j++) {
12579371c9d4SSatish Balay           if (indexn[j] < 0) {
12589371c9d4SSatish Balay             idx++;
12599371c9d4SSatish Balay             continue;
12609371c9d4SSatish Balay           }
12616bdcaf15SBarry 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);
1262ca15aa20SStefano Zampini           av[indexn[j] * mat->lda + indexm[i]] += v[idx++];
1263289bc588SBarry Smith         }
1264289bc588SBarry Smith       }
1265289bc588SBarry Smith     }
1266e8d4e0b9SBarry Smith   }
1267ca15aa20SStefano Zampini   /* hack to prevent unneeded copy to the GPU while returning the array */
1268ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1269c70f7ee4SJunchao Zhang   oldf           = A->offloadmask;
1270c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_GPU;
1271ca15aa20SStefano Zampini #endif
12729566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &av));
1273ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1274c70f7ee4SJunchao Zhang   A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU);
1275ca15aa20SStefano Zampini #endif
12763a40ed3dSBarry Smith   PetscFunctionReturn(0);
1277289bc588SBarry Smith }
1278e8d4e0b9SBarry Smith 
12799371c9d4SSatish Balay static PetscErrorCode MatGetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], PetscScalar v[]) {
1280ae80bb75SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1281ca15aa20SStefano Zampini   const PetscScalar *vv;
128213f74950SBarry Smith   PetscInt           i, j;
1283ae80bb75SLois Curfman McInnes 
12843a40ed3dSBarry Smith   PetscFunctionBegin;
12859566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &vv));
1286ae80bb75SLois Curfman McInnes   /* row-oriented output */
1287ae80bb75SLois Curfman McInnes   for (i = 0; i < m; i++) {
12889371c9d4SSatish Balay     if (indexm[i] < 0) {
12899371c9d4SSatish Balay       v += n;
12909371c9d4SSatish Balay       continue;
12919371c9d4SSatish Balay     }
129208401ef6SPierre 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);
1293ae80bb75SLois Curfman McInnes     for (j = 0; j < n; j++) {
12949371c9d4SSatish Balay       if (indexn[j] < 0) {
12959371c9d4SSatish Balay         v++;
12969371c9d4SSatish Balay         continue;
12979371c9d4SSatish Balay       }
129808401ef6SPierre 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);
1299ca15aa20SStefano Zampini       *v++ = vv[indexn[j] * mat->lda + indexm[i]];
1300ae80bb75SLois Curfman McInnes     }
1301ae80bb75SLois Curfman McInnes   }
13029566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &vv));
13033a40ed3dSBarry Smith   PetscFunctionReturn(0);
1304ae80bb75SLois Curfman McInnes }
1305ae80bb75SLois Curfman McInnes 
1306289bc588SBarry Smith /* -----------------------------------------------------------------*/
1307289bc588SBarry Smith 
13089371c9d4SSatish Balay PetscErrorCode MatView_Dense_Binary(Mat mat, PetscViewer viewer) {
13098491ab44SLisandro Dalcin   PetscBool          skipHeader;
13108491ab44SLisandro Dalcin   PetscViewerFormat  format;
13118491ab44SLisandro Dalcin   PetscInt           header[4], M, N, m, lda, i, j, k;
13128491ab44SLisandro Dalcin   const PetscScalar *v;
13138491ab44SLisandro Dalcin   PetscScalar       *vwork;
1314aabbc4fbSShri Abhyankar 
1315aabbc4fbSShri Abhyankar   PetscFunctionBegin;
13169566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
13179566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader));
13189566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
13198491ab44SLisandro Dalcin   if (skipHeader) format = PETSC_VIEWER_NATIVE;
1320aabbc4fbSShri Abhyankar 
13219566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat, &M, &N));
13228491ab44SLisandro Dalcin 
13238491ab44SLisandro Dalcin   /* write matrix header */
13249371c9d4SSatish Balay   header[0] = MAT_FILE_CLASSID;
13259371c9d4SSatish Balay   header[1] = M;
13269371c9d4SSatish Balay   header[2] = N;
13278491ab44SLisandro Dalcin   header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M * N;
13289566063dSJacob Faibussowitsch   if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer, header, 4, PETSC_INT));
13298491ab44SLisandro Dalcin 
13309566063dSJacob Faibussowitsch   PetscCall(MatGetLocalSize(mat, &m, NULL));
13318491ab44SLisandro Dalcin   if (format != PETSC_VIEWER_NATIVE) {
13328491ab44SLisandro Dalcin     PetscInt nnz = m * N, *iwork;
13338491ab44SLisandro Dalcin     /* store row lengths for each row */
13349566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nnz, &iwork));
13358491ab44SLisandro Dalcin     for (i = 0; i < m; i++) iwork[i] = N;
13369566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT));
13378491ab44SLisandro Dalcin     /* store column indices (zero start index) */
13388491ab44SLisandro Dalcin     for (k = 0, i = 0; i < m; i++)
13399371c9d4SSatish Balay       for (j = 0; j < N; j++, k++) iwork[k] = j;
13409566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT));
13419566063dSJacob Faibussowitsch     PetscCall(PetscFree(iwork));
13428491ab44SLisandro Dalcin   }
13438491ab44SLisandro Dalcin   /* store matrix values as a dense matrix in row major order */
13449566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(m * N, &vwork));
13459566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(mat, &v));
13469566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(mat, &lda));
13478491ab44SLisandro Dalcin   for (k = 0, i = 0; i < m; i++)
13489371c9d4SSatish Balay     for (j = 0; j < N; j++, k++) vwork[k] = v[i + lda * j];
13499566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(mat, &v));
13509566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryWriteAll(viewer, vwork, m * N, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR));
13519566063dSJacob Faibussowitsch   PetscCall(PetscFree(vwork));
13528491ab44SLisandro Dalcin   PetscFunctionReturn(0);
13538491ab44SLisandro Dalcin }
13548491ab44SLisandro Dalcin 
13559371c9d4SSatish Balay PetscErrorCode MatLoad_Dense_Binary(Mat mat, PetscViewer viewer) {
13568491ab44SLisandro Dalcin   PetscBool    skipHeader;
13578491ab44SLisandro Dalcin   PetscInt     header[4], M, N, m, nz, lda, i, j, k;
13588491ab44SLisandro Dalcin   PetscInt     rows, cols;
13598491ab44SLisandro Dalcin   PetscScalar *v, *vwork;
13608491ab44SLisandro Dalcin 
13618491ab44SLisandro Dalcin   PetscFunctionBegin;
13629566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
13639566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader));
13648491ab44SLisandro Dalcin 
13658491ab44SLisandro Dalcin   if (!skipHeader) {
13669566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryRead(viewer, header, 4, NULL, PETSC_INT));
136708401ef6SPierre Jolivet     PetscCheck(header[0] == MAT_FILE_CLASSID, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Not a matrix object in file");
13689371c9d4SSatish Balay     M = header[1];
13699371c9d4SSatish Balay     N = header[2];
137008401ef6SPierre Jolivet     PetscCheck(M >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix row size (%" PetscInt_FMT ") in file is negative", M);
137108401ef6SPierre Jolivet     PetscCheck(N >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix column size (%" PetscInt_FMT ") in file is negative", N);
13728491ab44SLisandro Dalcin     nz = header[3];
1373aed4548fSBarry Smith     PetscCheck(nz == MATRIX_BINARY_FORMAT_DENSE || nz >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Unknown matrix format %" PetscInt_FMT " in file", nz);
1374aabbc4fbSShri Abhyankar   } else {
13759566063dSJacob Faibussowitsch     PetscCall(MatGetSize(mat, &M, &N));
1376aed4548fSBarry 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");
13778491ab44SLisandro Dalcin     nz = MATRIX_BINARY_FORMAT_DENSE;
1378e6324fbbSBarry Smith   }
1379aabbc4fbSShri Abhyankar 
13808491ab44SLisandro Dalcin   /* setup global sizes if not set */
13818491ab44SLisandro Dalcin   if (mat->rmap->N < 0) mat->rmap->N = M;
13828491ab44SLisandro Dalcin   if (mat->cmap->N < 0) mat->cmap->N = N;
13839566063dSJacob Faibussowitsch   PetscCall(MatSetUp(mat));
13848491ab44SLisandro Dalcin   /* check if global sizes are correct */
13859566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat, &rows, &cols));
1386aed4548fSBarry 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);
1387aabbc4fbSShri Abhyankar 
13889566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat, NULL, &N));
13899566063dSJacob Faibussowitsch   PetscCall(MatGetLocalSize(mat, &m, NULL));
13909566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(mat, &v));
13919566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(mat, &lda));
13928491ab44SLisandro Dalcin   if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense format */
13938491ab44SLisandro Dalcin     PetscInt nnz = m * N;
13948491ab44SLisandro Dalcin     /* read in matrix values */
13959566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nnz, &vwork));
13969566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR));
13978491ab44SLisandro Dalcin     /* store values in column major order */
13988491ab44SLisandro Dalcin     for (j = 0; j < N; j++)
13999371c9d4SSatish Balay       for (i = 0; i < m; i++) v[i + lda * j] = vwork[i * N + j];
14009566063dSJacob Faibussowitsch     PetscCall(PetscFree(vwork));
14018491ab44SLisandro Dalcin   } else { /* matrix in file is sparse format */
14028491ab44SLisandro Dalcin     PetscInt nnz = 0, *rlens, *icols;
14038491ab44SLisandro Dalcin     /* read in row lengths */
14049566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(m, &rlens));
14059566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer, rlens, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT));
14068491ab44SLisandro Dalcin     for (i = 0; i < m; i++) nnz += rlens[i];
14078491ab44SLisandro Dalcin     /* read in column indices and values */
14089566063dSJacob Faibussowitsch     PetscCall(PetscMalloc2(nnz, &icols, nnz, &vwork));
14099566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer, icols, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT));
14109566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR));
14118491ab44SLisandro Dalcin     /* store values in column major order */
14128491ab44SLisandro Dalcin     for (k = 0, i = 0; i < m; i++)
14139371c9d4SSatish Balay       for (j = 0; j < rlens[i]; j++, k++) v[i + lda * icols[k]] = vwork[k];
14149566063dSJacob Faibussowitsch     PetscCall(PetscFree(rlens));
14159566063dSJacob Faibussowitsch     PetscCall(PetscFree2(icols, vwork));
1416aabbc4fbSShri Abhyankar   }
14179566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(mat, &v));
14189566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY));
14199566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY));
1420aabbc4fbSShri Abhyankar   PetscFunctionReturn(0);
1421aabbc4fbSShri Abhyankar }
1422aabbc4fbSShri Abhyankar 
14239371c9d4SSatish Balay PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer) {
1424eb91f321SVaclav Hapla   PetscBool isbinary, ishdf5;
1425eb91f321SVaclav Hapla 
1426eb91f321SVaclav Hapla   PetscFunctionBegin;
1427eb91f321SVaclav Hapla   PetscValidHeaderSpecific(newMat, MAT_CLASSID, 1);
1428eb91f321SVaclav Hapla   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
1429eb91f321SVaclav Hapla   /* force binary viewer to load .info file if it has not yet done so */
14309566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
14319566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
14329566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5));
1433eb91f321SVaclav Hapla   if (isbinary) {
14349566063dSJacob Faibussowitsch     PetscCall(MatLoad_Dense_Binary(newMat, viewer));
1435eb91f321SVaclav Hapla   } else if (ishdf5) {
1436eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5)
14379566063dSJacob Faibussowitsch     PetscCall(MatLoad_Dense_HDF5(newMat, viewer));
1438eb91f321SVaclav Hapla #else
1439eb91f321SVaclav Hapla     SETERRQ(PetscObjectComm((PetscObject)newMat), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5");
1440eb91f321SVaclav Hapla #endif
1441eb91f321SVaclav Hapla   } else {
144298921bdaSJacob 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);
1443eb91f321SVaclav Hapla   }
1444eb91f321SVaclav Hapla   PetscFunctionReturn(0);
1445eb91f321SVaclav Hapla }
1446eb91f321SVaclav Hapla 
14479371c9d4SSatish Balay static PetscErrorCode MatView_SeqDense_ASCII(Mat A, PetscViewer viewer) {
1448932b0c3eSLois Curfman McInnes   Mat_SeqDense     *a = (Mat_SeqDense *)A->data;
144913f74950SBarry Smith   PetscInt          i, j;
14502dcb1b2aSMatthew Knepley   const char       *name;
1451ca15aa20SStefano Zampini   PetscScalar      *v, *av;
1452f3ef73ceSBarry Smith   PetscViewerFormat format;
14535f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX)
1454ace3abfcSBarry Smith   PetscBool allreal = PETSC_TRUE;
14555f481a85SSatish Balay #endif
1456932b0c3eSLois Curfman McInnes 
14573a40ed3dSBarry Smith   PetscFunctionBegin;
14589566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&av));
14599566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
1460456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
14613a40ed3dSBarry Smith     PetscFunctionReturn(0); /* do nothing for now */
1462fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
14639566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
1464d0f46423SBarry Smith     for (i = 0; i < A->rmap->n; i++) {
1465ca15aa20SStefano Zampini       v = av + i;
14669566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "row %" PetscInt_FMT ":", i));
1467d0f46423SBarry Smith       for (j = 0; j < A->cmap->n; j++) {
1468aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1469329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
14709566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g + %g i) ", j, (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v)));
1471329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
14729566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)PetscRealPart(*v)));
14736831982aSBarry Smith         }
147480cd9d93SLois Curfman McInnes #else
147548a46eb9SPierre Jolivet         if (*v) PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)*v));
147680cd9d93SLois Curfman McInnes #endif
14771b807ce4Svictorle         v += a->lda;
147880cd9d93SLois Curfman McInnes       }
14799566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
148080cd9d93SLois Curfman McInnes     }
14819566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
14823a40ed3dSBarry Smith   } else {
14839566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
1484aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
148547989497SBarry Smith     /* determine if matrix has all real values */
1486bcd8d3a4SJose E. Roman     for (j = 0; j < A->cmap->n; j++) {
1487bcd8d3a4SJose E. Roman       v = av + j * a->lda;
1488bcd8d3a4SJose E. Roman       for (i = 0; i < A->rmap->n; i++) {
14899371c9d4SSatish Balay         if (PetscImaginaryPart(v[i])) {
14909371c9d4SSatish Balay           allreal = PETSC_FALSE;
14919371c9d4SSatish Balay           break;
14929371c9d4SSatish Balay         }
149347989497SBarry Smith       }
1494bcd8d3a4SJose E. Roman     }
149547989497SBarry Smith #endif
1496fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
14979566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetName((PetscObject)A, &name));
14989566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%% Size = %" PetscInt_FMT " %" PetscInt_FMT " \n", A->rmap->n, A->cmap->n));
14999566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%s = zeros(%" PetscInt_FMT ",%" PetscInt_FMT ");\n", name, A->rmap->n, A->cmap->n));
15009566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%s = [\n", name));
1501ffac6cdbSBarry Smith     }
1502ffac6cdbSBarry Smith 
1503d0f46423SBarry Smith     for (i = 0; i < A->rmap->n; i++) {
1504ca15aa20SStefano Zampini       v = av + i;
1505d0f46423SBarry Smith       for (j = 0; j < A->cmap->n; j++) {
1506aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
150747989497SBarry Smith         if (allreal) {
15089566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)PetscRealPart(*v)));
150947989497SBarry Smith         } else {
15109566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e + %18.16ei ", (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v)));
151147989497SBarry Smith         }
1512289bc588SBarry Smith #else
15139566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)*v));
1514289bc588SBarry Smith #endif
15151b807ce4Svictorle         v += a->lda;
1516289bc588SBarry Smith       }
15179566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
1518289bc588SBarry Smith     }
151948a46eb9SPierre Jolivet     if (format == PETSC_VIEWER_ASCII_MATLAB) PetscCall(PetscViewerASCIIPrintf(viewer, "];\n"));
15209566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
1521da3a660dSBarry Smith   }
15229566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&av));
15239566063dSJacob Faibussowitsch   PetscCall(PetscViewerFlush(viewer));
15243a40ed3dSBarry Smith   PetscFunctionReturn(0);
1525289bc588SBarry Smith }
1526289bc588SBarry Smith 
15279804daf3SBarry Smith #include <petscdraw.h>
15289371c9d4SSatish Balay static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw, void *Aa) {
1529f1af5d2fSBarry Smith   Mat                A = (Mat)Aa;
1530383922c3SLisandro Dalcin   PetscInt           m = A->rmap->n, n = A->cmap->n, i, j;
1531383922c3SLisandro Dalcin   int                color = PETSC_DRAW_WHITE;
1532ca15aa20SStefano Zampini   const PetscScalar *v;
1533b0a32e0cSBarry Smith   PetscViewer        viewer;
1534b05fc000SLisandro Dalcin   PetscReal          xl, yl, xr, yr, x_l, x_r, y_l, y_r;
1535f3ef73ceSBarry Smith   PetscViewerFormat  format;
1536f1af5d2fSBarry Smith 
1537f1af5d2fSBarry Smith   PetscFunctionBegin;
15389566063dSJacob Faibussowitsch   PetscCall(PetscObjectQuery((PetscObject)A, "Zoomviewer", (PetscObject *)&viewer));
15399566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
15409566063dSJacob Faibussowitsch   PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr));
1541f1af5d2fSBarry Smith 
1542f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
15439566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &v));
1544fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
1545d0609cedSBarry Smith     PetscDrawCollectiveBegin(draw);
1546f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
1547f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
15489371c9d4SSatish Balay       x_l = j;
15499371c9d4SSatish Balay       x_r = x_l + 1.0;
1550f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1551f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1552f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1553ca15aa20SStefano Zampini         if (PetscRealPart(v[j * m + i]) > 0.) color = PETSC_DRAW_RED;
1554ca15aa20SStefano Zampini         else if (PetscRealPart(v[j * m + i]) < 0.) color = PETSC_DRAW_BLUE;
1555ca15aa20SStefano Zampini         else continue;
15569566063dSJacob Faibussowitsch         PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color));
1557f1af5d2fSBarry Smith       }
1558f1af5d2fSBarry Smith     }
1559d0609cedSBarry Smith     PetscDrawCollectiveEnd(draw);
1560f1af5d2fSBarry Smith   } else {
1561f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
1562f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
1563b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1564b05fc000SLisandro Dalcin     PetscDraw popup;
1565b05fc000SLisandro Dalcin 
1566f1af5d2fSBarry Smith     for (i = 0; i < m * n; i++) {
1567f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
1568f1af5d2fSBarry Smith     }
1569383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
15709566063dSJacob Faibussowitsch     PetscCall(PetscDrawGetPopup(draw, &popup));
15719566063dSJacob Faibussowitsch     PetscCall(PetscDrawScalePopup(popup, minv, maxv));
1572383922c3SLisandro Dalcin 
1573d0609cedSBarry Smith     PetscDrawCollectiveBegin(draw);
1574f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
1575f1af5d2fSBarry Smith       x_l = j;
1576f1af5d2fSBarry Smith       x_r = x_l + 1.0;
1577f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1578f1af5d2fSBarry Smith         y_l   = m - i - 1.0;
1579f1af5d2fSBarry Smith         y_r   = y_l + 1.0;
1580b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(v[j * m + i]), minv, maxv);
15819566063dSJacob Faibussowitsch         PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color));
1582f1af5d2fSBarry Smith       }
1583f1af5d2fSBarry Smith     }
1584d0609cedSBarry Smith     PetscDrawCollectiveEnd(draw);
1585f1af5d2fSBarry Smith   }
15869566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &v));
1587f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1588f1af5d2fSBarry Smith }
1589f1af5d2fSBarry Smith 
15909371c9d4SSatish Balay static PetscErrorCode MatView_SeqDense_Draw(Mat A, PetscViewer viewer) {
1591b0a32e0cSBarry Smith   PetscDraw draw;
1592ace3abfcSBarry Smith   PetscBool isnull;
1593329f5518SBarry Smith   PetscReal xr, yr, xl, yl, h, w;
1594f1af5d2fSBarry Smith 
1595f1af5d2fSBarry Smith   PetscFunctionBegin;
15969566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
15979566063dSJacob Faibussowitsch   PetscCall(PetscDrawIsNull(draw, &isnull));
1598abc0a331SBarry Smith   if (isnull) PetscFunctionReturn(0);
1599f1af5d2fSBarry Smith 
16009371c9d4SSatish Balay   xr = A->cmap->n;
16019371c9d4SSatish Balay   yr = A->rmap->n;
16029371c9d4SSatish Balay   h  = yr / 10.0;
16039371c9d4SSatish Balay   w  = xr / 10.0;
16049371c9d4SSatish Balay   xr += w;
16059371c9d4SSatish Balay   yr += h;
16069371c9d4SSatish Balay   xl = -w;
16079371c9d4SSatish Balay   yl = -h;
16089566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetCoordinates(draw, xl, yl, xr, yr));
16099566063dSJacob Faibussowitsch   PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", (PetscObject)viewer));
16109566063dSJacob Faibussowitsch   PetscCall(PetscDrawZoom(draw, MatView_SeqDense_Draw_Zoom, A));
16119566063dSJacob Faibussowitsch   PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", NULL));
16129566063dSJacob Faibussowitsch   PetscCall(PetscDrawSave(draw));
1613f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1614f1af5d2fSBarry Smith }
1615f1af5d2fSBarry Smith 
16169371c9d4SSatish Balay PetscErrorCode MatView_SeqDense(Mat A, PetscViewer viewer) {
1617ace3abfcSBarry Smith   PetscBool iascii, isbinary, isdraw;
1618932b0c3eSLois Curfman McInnes 
16193a40ed3dSBarry Smith   PetscFunctionBegin;
16209566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
16219566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
16229566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
16231baa6e33SBarry Smith   if (iascii) PetscCall(MatView_SeqDense_ASCII(A, viewer));
16241baa6e33SBarry Smith   else if (isbinary) PetscCall(MatView_Dense_Binary(A, viewer));
16251baa6e33SBarry Smith   else if (isdraw) PetscCall(MatView_SeqDense_Draw(A, viewer));
16263a40ed3dSBarry Smith   PetscFunctionReturn(0);
1627932b0c3eSLois Curfman McInnes }
1628289bc588SBarry Smith 
16299371c9d4SSatish Balay static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A, const PetscScalar *array) {
1630d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
1631d3042a70SBarry Smith 
1632d3042a70SBarry Smith   PetscFunctionBegin;
163328b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
163428b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
163528b400f6SJacob Faibussowitsch   PetscCheck(!a->unplacedarray, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreArray() first");
1636d3042a70SBarry Smith   a->unplacedarray       = a->v;
1637d3042a70SBarry Smith   a->unplaced_user_alloc = a->user_alloc;
1638d3042a70SBarry Smith   a->v                   = (PetscScalar *)array;
1639637a0070SStefano Zampini   a->user_alloc          = PETSC_TRUE;
1640ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1641c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1642ca15aa20SStefano Zampini #endif
1643d3042a70SBarry Smith   PetscFunctionReturn(0);
1644d3042a70SBarry Smith }
1645d3042a70SBarry Smith 
16469371c9d4SSatish Balay static PetscErrorCode MatDenseResetArray_SeqDense(Mat A) {
1647d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
1648d3042a70SBarry Smith 
1649d3042a70SBarry Smith   PetscFunctionBegin;
165028b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
165128b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
1652d3042a70SBarry Smith   a->v             = a->unplacedarray;
1653d3042a70SBarry Smith   a->user_alloc    = a->unplaced_user_alloc;
1654d3042a70SBarry Smith   a->unplacedarray = NULL;
1655ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1656c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1657ca15aa20SStefano Zampini #endif
1658d3042a70SBarry Smith   PetscFunctionReturn(0);
1659d3042a70SBarry Smith }
1660d3042a70SBarry Smith 
16619371c9d4SSatish Balay static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A, const PetscScalar *array) {
1662d5ea218eSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
1663d5ea218eSStefano Zampini 
1664d5ea218eSStefano Zampini   PetscFunctionBegin;
166528b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
166628b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
16679566063dSJacob Faibussowitsch   if (!a->user_alloc) PetscCall(PetscFree(a->v));
1668d5ea218eSStefano Zampini   a->v          = (PetscScalar *)array;
1669d5ea218eSStefano Zampini   a->user_alloc = PETSC_FALSE;
1670d5ea218eSStefano Zampini #if defined(PETSC_HAVE_CUDA)
1671d5ea218eSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
1672d5ea218eSStefano Zampini #endif
1673d5ea218eSStefano Zampini   PetscFunctionReturn(0);
1674d5ea218eSStefano Zampini }
1675d5ea218eSStefano Zampini 
16769371c9d4SSatish Balay PetscErrorCode MatDestroy_SeqDense(Mat mat) {
1677ec8511deSBarry Smith   Mat_SeqDense *l = (Mat_SeqDense *)mat->data;
167890f02eecSBarry Smith 
16793a40ed3dSBarry Smith   PetscFunctionBegin;
1680aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1681c0aa6a63SJacob Faibussowitsch   PetscLogObjectState((PetscObject)mat, "Rows %" PetscInt_FMT " Cols %" PetscInt_FMT, mat->rmap->n, mat->cmap->n);
1682a5a9c739SBarry Smith #endif
16839566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(l->qrrhs)));
16849566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->tau));
16859566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->pivots));
16869566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->fwork));
16879566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&l->ptapwork));
16889566063dSJacob Faibussowitsch   if (!l->user_alloc) PetscCall(PetscFree(l->v));
16899566063dSJacob Faibussowitsch   if (!l->unplaced_user_alloc) PetscCall(PetscFree(l->unplacedarray));
169028b400f6SJacob Faibussowitsch   PetscCheck(!l->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
169128b400f6SJacob Faibussowitsch   PetscCheck(!l->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
16929566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&l->cvec));
16939566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&l->cmat));
16949566063dSJacob Faibussowitsch   PetscCall(PetscFree(mat->data));
1695dbd8c25aSHong Zhang 
16969566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)mat, NULL));
16979566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactor_C", NULL));
16982e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorSymbolic_C", NULL));
16992e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorNumeric_C", NULL));
17009566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetLDA_C", NULL));
17019566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseSetLDA_C", NULL));
17029566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArray_C", NULL));
17039566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArray_C", NULL));
17049566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDensePlaceArray_C", NULL));
17059566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseResetArray_C", NULL));
17069566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseReplaceArray_C", NULL));
17079566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayRead_C", NULL));
17089566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayRead_C", NULL));
17099566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayWrite_C", NULL));
17109566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayWrite_C", NULL));
17119566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqaij_C", NULL));
17128baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
17139566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_elemental_C", NULL));
17148baccfbdSHong Zhang #endif
1715d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
17169566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_scalapack_C", NULL));
1717d24d4204SJose E. Roman #endif
17182bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
17199566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensecuda_C", NULL));
17209566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", NULL));
17219566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdense_C", NULL));
17222e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensecuda_C", NULL));
17232bf066beSStefano Zampini #endif
17249566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatSeqDenseSetPreallocation_C", NULL));
17259566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqaij_seqdense_C", NULL));
17269566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdense_C", NULL));
17279566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqbaij_seqdense_C", NULL));
17289566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqsbaij_seqdense_C", NULL));
172952c5f739Sprj- 
17309566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumn_C", NULL));
17319566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumn_C", NULL));
17329566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVec_C", NULL));
17339566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVec_C", NULL));
17349566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecRead_C", NULL));
17359566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecRead_C", NULL));
17369566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecWrite_C", NULL));
17379566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecWrite_C", NULL));
17389566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetSubMatrix_C", NULL));
17399566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreSubMatrix_C", NULL));
17403a40ed3dSBarry Smith   PetscFunctionReturn(0);
1741289bc588SBarry Smith }
1742289bc588SBarry Smith 
17439371c9d4SSatish Balay static PetscErrorCode MatTranspose_SeqDense(Mat A, MatReuse reuse, Mat *matout) {
1744c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
17456536e3caSStefano Zampini   PetscInt      k, j, m = A->rmap->n, M = mat->lda, n = A->cmap->n;
174687828ca2SBarry Smith   PetscScalar  *v, tmp;
174748b35521SBarry Smith 
17483a40ed3dSBarry Smith   PetscFunctionBegin;
17497fb60732SBarry Smith   if (reuse == MAT_REUSE_MATRIX) PetscCall(MatTransposeCheckNonzeroState_Private(A, *matout));
17506536e3caSStefano Zampini   if (reuse == MAT_INPLACE_MATRIX) {
17516536e3caSStefano Zampini     if (m == n) { /* in place transpose */
17529566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(A, &v));
1753d3e5ee88SLois Curfman McInnes       for (j = 0; j < m; j++) {
1754289bc588SBarry Smith         for (k = 0; k < j; k++) {
17551b807ce4Svictorle           tmp          = v[j + k * M];
17561b807ce4Svictorle           v[j + k * M] = v[k + j * M];
17571b807ce4Svictorle           v[k + j * M] = tmp;
1758289bc588SBarry Smith         }
1759289bc588SBarry Smith       }
17609566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArray(A, &v));
17616536e3caSStefano Zampini     } else { /* reuse memory, temporary allocates new memory */
17626536e3caSStefano Zampini       PetscScalar *v2;
17636536e3caSStefano Zampini       PetscLayout  tmplayout;
17646536e3caSStefano Zampini 
17659566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1((size_t)m * n, &v2));
17669566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(A, &v));
17676536e3caSStefano Zampini       for (j = 0; j < n; j++) {
17686536e3caSStefano Zampini         for (k = 0; k < m; k++) v2[j + (size_t)k * n] = v[k + (size_t)j * M];
17696536e3caSStefano Zampini       }
17709566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(v, v2, (size_t)m * n));
17719566063dSJacob Faibussowitsch       PetscCall(PetscFree(v2));
17729566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArray(A, &v));
17736536e3caSStefano Zampini       /* cleanup size dependent quantities */
17749566063dSJacob Faibussowitsch       PetscCall(VecDestroy(&mat->cvec));
17759566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&mat->cmat));
17769566063dSJacob Faibussowitsch       PetscCall(PetscFree(mat->pivots));
17779566063dSJacob Faibussowitsch       PetscCall(PetscFree(mat->fwork));
17789566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&mat->ptapwork));
17796536e3caSStefano Zampini       /* swap row/col layouts */
17806536e3caSStefano Zampini       mat->lda  = n;
17816536e3caSStefano Zampini       tmplayout = A->rmap;
17826536e3caSStefano Zampini       A->rmap   = A->cmap;
17836536e3caSStefano Zampini       A->cmap   = tmplayout;
17846536e3caSStefano Zampini     }
17853a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1786d3e5ee88SLois Curfman McInnes     Mat           tmat;
1787ec8511deSBarry Smith     Mat_SeqDense *tmatd;
178887828ca2SBarry Smith     PetscScalar  *v2;
1789af36a384SStefano Zampini     PetscInt      M2;
1790ea709b57SSatish Balay 
17916536e3caSStefano Zampini     if (reuse == MAT_INITIAL_MATRIX) {
17929566063dSJacob Faibussowitsch       PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &tmat));
17939566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(tmat, A->cmap->n, A->rmap->n, A->cmap->n, A->rmap->n));
17949566063dSJacob Faibussowitsch       PetscCall(MatSetType(tmat, ((PetscObject)A)->type_name));
17959566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSetPreallocation(tmat, NULL));
1796ca15aa20SStefano Zampini     } else tmat = *matout;
1797ca15aa20SStefano Zampini 
17989566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&v));
17999566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArray(tmat, &v2));
1800ec8511deSBarry Smith     tmatd = (Mat_SeqDense *)tmat->data;
1801ca15aa20SStefano Zampini     M2    = tmatd->lda;
1802d3e5ee88SLois Curfman McInnes     for (j = 0; j < n; j++) {
1803af36a384SStefano Zampini       for (k = 0; k < m; k++) v2[j + k * M2] = v[k + j * M];
1804d3e5ee88SLois Curfman McInnes     }
18059566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(tmat, &v2));
18069566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&v));
18079566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(tmat, MAT_FINAL_ASSEMBLY));
18089566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(tmat, MAT_FINAL_ASSEMBLY));
18096536e3caSStefano Zampini     *matout = tmat;
181048b35521SBarry Smith   }
18113a40ed3dSBarry Smith   PetscFunctionReturn(0);
1812289bc588SBarry Smith }
1813289bc588SBarry Smith 
18149371c9d4SSatish Balay static PetscErrorCode MatEqual_SeqDense(Mat A1, Mat A2, PetscBool *flg) {
1815c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat1 = (Mat_SeqDense *)A1->data;
1816c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat2 = (Mat_SeqDense *)A2->data;
1817ca15aa20SStefano Zampini   PetscInt           i;
1818ca15aa20SStefano Zampini   const PetscScalar *v1, *v2;
18199ea5d5aeSSatish Balay 
18203a40ed3dSBarry Smith   PetscFunctionBegin;
18219371c9d4SSatish Balay   if (A1->rmap->n != A2->rmap->n) {
18229371c9d4SSatish Balay     *flg = PETSC_FALSE;
18239371c9d4SSatish Balay     PetscFunctionReturn(0);
18249371c9d4SSatish Balay   }
18259371c9d4SSatish Balay   if (A1->cmap->n != A2->cmap->n) {
18269371c9d4SSatish Balay     *flg = PETSC_FALSE;
18279371c9d4SSatish Balay     PetscFunctionReturn(0);
18289371c9d4SSatish Balay   }
18299566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A1, &v1));
18309566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A2, &v2));
1831ca15aa20SStefano Zampini   for (i = 0; i < A1->cmap->n; i++) {
18329566063dSJacob Faibussowitsch     PetscCall(PetscArraycmp(v1, v2, A1->rmap->n, flg));
1833ca15aa20SStefano Zampini     if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
1834ca15aa20SStefano Zampini     v1 += mat1->lda;
1835ca15aa20SStefano Zampini     v2 += mat2->lda;
18361b807ce4Svictorle   }
18379566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A1, &v1));
18389566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A2, &v2));
183977c4ece6SBarry Smith   *flg = PETSC_TRUE;
18403a40ed3dSBarry Smith   PetscFunctionReturn(0);
1841289bc588SBarry Smith }
1842289bc588SBarry Smith 
18439371c9d4SSatish Balay static PetscErrorCode MatGetDiagonal_SeqDense(Mat A, Vec v) {
1844c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
184513f74950SBarry Smith   PetscInt           i, n, len;
1846ca15aa20SStefano Zampini   PetscScalar       *x;
1847ca15aa20SStefano Zampini   const PetscScalar *vv;
184844cd7ae7SLois Curfman McInnes 
18493a40ed3dSBarry Smith   PetscFunctionBegin;
18509566063dSJacob Faibussowitsch   PetscCall(VecGetSize(v, &n));
18519566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
1852d0f46423SBarry Smith   len = PetscMin(A->rmap->n, A->cmap->n);
18539566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &vv));
185408401ef6SPierre Jolivet   PetscCheck(n == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming mat and vec");
1855ad540459SPierre Jolivet   for (i = 0; i < len; i++) x[i] = vv[i * mat->lda + i];
18569566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &vv));
18579566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
18583a40ed3dSBarry Smith   PetscFunctionReturn(0);
1859289bc588SBarry Smith }
1860289bc588SBarry Smith 
18619371c9d4SSatish Balay static PetscErrorCode MatDiagonalScale_SeqDense(Mat A, Vec ll, Vec rr) {
1862c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1863f1ceaac6SMatthew G. Knepley   const PetscScalar *l, *r;
1864ca15aa20SStefano Zampini   PetscScalar        x, *v, *vv;
1865d0f46423SBarry Smith   PetscInt           i, j, m = A->rmap->n, n = A->cmap->n;
186655659b69SBarry Smith 
18673a40ed3dSBarry Smith   PetscFunctionBegin;
18689566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &vv));
186928988994SBarry Smith   if (ll) {
18709566063dSJacob Faibussowitsch     PetscCall(VecGetSize(ll, &m));
18719566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ll, &l));
187208401ef6SPierre Jolivet     PetscCheck(m == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Left scaling vec wrong size");
1873da3a660dSBarry Smith     for (i = 0; i < m; i++) {
1874da3a660dSBarry Smith       x = l[i];
1875ca15aa20SStefano Zampini       v = vv + i;
18769371c9d4SSatish Balay       for (j = 0; j < n; j++) {
18779371c9d4SSatish Balay         (*v) *= x;
18789371c9d4SSatish Balay         v += mat->lda;
18799371c9d4SSatish Balay       }
1880da3a660dSBarry Smith     }
18819566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ll, &l));
18829566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0 * n * m));
1883da3a660dSBarry Smith   }
188428988994SBarry Smith   if (rr) {
18859566063dSJacob Faibussowitsch     PetscCall(VecGetSize(rr, &n));
18869566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(rr, &r));
188708401ef6SPierre Jolivet     PetscCheck(n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Right scaling vec wrong size");
1888da3a660dSBarry Smith     for (i = 0; i < n; i++) {
1889da3a660dSBarry Smith       x = r[i];
1890ca15aa20SStefano Zampini       v = vv + i * mat->lda;
18912205254eSKarl Rupp       for (j = 0; j < m; j++) (*v++) *= x;
1892da3a660dSBarry Smith     }
18939566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(rr, &r));
18949566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0 * n * m));
1895da3a660dSBarry Smith   }
18969566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &vv));
18973a40ed3dSBarry Smith   PetscFunctionReturn(0);
1898289bc588SBarry Smith }
1899289bc588SBarry Smith 
19009371c9d4SSatish Balay PetscErrorCode MatNorm_SeqDense(Mat A, NormType type, PetscReal *nrm) {
1901c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
1902ca15aa20SStefano Zampini   PetscScalar  *v, *vv;
1903329f5518SBarry Smith   PetscReal     sum = 0.0;
190475f6d85dSStefano Zampini   PetscInt      lda, m = A->rmap->n, i, j;
190555659b69SBarry Smith 
19063a40ed3dSBarry Smith   PetscFunctionBegin;
19079566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&vv));
19089566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(A, &lda));
1909ca15aa20SStefano Zampini   v = vv;
1910289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1911a5ce6ee0Svictorle     if (lda > m) {
1912d0f46423SBarry Smith       for (j = 0; j < A->cmap->n; j++) {
1913ca15aa20SStefano Zampini         v = vv + j * lda;
1914a5ce6ee0Svictorle         for (i = 0; i < m; i++) {
19159371c9d4SSatish Balay           sum += PetscRealPart(PetscConj(*v) * (*v));
19169371c9d4SSatish Balay           v++;
1917a5ce6ee0Svictorle         }
1918a5ce6ee0Svictorle       }
1919a5ce6ee0Svictorle     } else {
1920570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1921570b7f6dSBarry Smith       PetscBLASInt one = 1, cnt = A->cmap->n * A->rmap->n;
1922792fecdfSBarry Smith       PetscCallBLAS("BLASnrm2", *nrm = BLASnrm2_(&cnt, v, &one));
1923570b7f6dSBarry Smith     }
1924570b7f6dSBarry Smith #else
1925d0f46423SBarry Smith       for (i = 0; i < A->cmap->n * A->rmap->n; i++) {
19269371c9d4SSatish Balay         sum += PetscRealPart(PetscConj(*v) * (*v));
19279371c9d4SSatish Balay         v++;
1928289bc588SBarry Smith       }
1929a5ce6ee0Svictorle     }
19308f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1931570b7f6dSBarry Smith #endif
19329566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0 * A->cmap->n * A->rmap->n));
19333a40ed3dSBarry Smith   } else if (type == NORM_1) {
1934064f8208SBarry Smith     *nrm = 0.0;
1935d0f46423SBarry Smith     for (j = 0; j < A->cmap->n; j++) {
1936ca15aa20SStefano Zampini       v   = vv + j * mat->lda;
1937289bc588SBarry Smith       sum = 0.0;
1938d0f46423SBarry Smith       for (i = 0; i < A->rmap->n; i++) {
19399371c9d4SSatish Balay         sum += PetscAbsScalar(*v);
19409371c9d4SSatish Balay         v++;
1941289bc588SBarry Smith       }
1942064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1943289bc588SBarry Smith     }
19449566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n));
19453a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1946064f8208SBarry Smith     *nrm = 0.0;
1947d0f46423SBarry Smith     for (j = 0; j < A->rmap->n; j++) {
1948ca15aa20SStefano Zampini       v   = vv + j;
1949289bc588SBarry Smith       sum = 0.0;
1950d0f46423SBarry Smith       for (i = 0; i < A->cmap->n; i++) {
19519371c9d4SSatish Balay         sum += PetscAbsScalar(*v);
19529371c9d4SSatish Balay         v += mat->lda;
1953289bc588SBarry Smith       }
1954064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1955289bc588SBarry Smith     }
19569566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n));
1957e7e72b3dSBarry Smith   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "No two norm");
19589566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&vv));
19593a40ed3dSBarry Smith   PetscFunctionReturn(0);
1960289bc588SBarry Smith }
1961289bc588SBarry Smith 
19629371c9d4SSatish Balay static PetscErrorCode MatSetOption_SeqDense(Mat A, MatOption op, PetscBool flg) {
1963c0bbcb79SLois Curfman McInnes   Mat_SeqDense *aij = (Mat_SeqDense *)A->data;
196467e560aaSBarry Smith 
19653a40ed3dSBarry Smith   PetscFunctionBegin;
1966b5a2b587SKris Buschelman   switch (op) {
19679371c9d4SSatish Balay   case MAT_ROW_ORIENTED: aij->roworiented = flg; break;
1968512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1969b5a2b587SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
19703971808eSMatthew Knepley   case MAT_NEW_NONZERO_ALLOCATION_ERR:
19718c78258cSHong Zhang   case MAT_FORCE_DIAGONAL_ENTRIES:
197213fa8e87SLisandro Dalcin   case MAT_KEEP_NONZERO_PATTERN:
1973b5a2b587SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1974b5a2b587SKris Buschelman   case MAT_USE_HASH_TABLE:
19750f8fb01aSBarry Smith   case MAT_IGNORE_ZERO_ENTRIES:
19765021d80fSJed Brown   case MAT_IGNORE_LOWER_TRIANGULAR:
19779371c9d4SSatish Balay   case MAT_SORTED_FULL: PetscCall(PetscInfo(A, "Option %s ignored\n", MatOptions[op])); break;
19785021d80fSJed Brown   case MAT_SPD:
197977e54ba9SKris Buschelman   case MAT_SYMMETRIC:
198077e54ba9SKris Buschelman   case MAT_STRUCTURALLY_SYMMETRIC:
19819a4540c5SBarry Smith   case MAT_HERMITIAN:
19829a4540c5SBarry Smith   case MAT_SYMMETRY_ETERNAL:
1983b94d7dedSBarry Smith   case MAT_STRUCTURAL_SYMMETRY_ETERNAL:
19849371c9d4SSatish Balay   case MAT_SPD_ETERNAL: break;
19859371c9d4SSatish Balay   default: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "unknown option %s", MatOptions[op]);
19863a40ed3dSBarry Smith   }
19873a40ed3dSBarry Smith   PetscFunctionReturn(0);
1988289bc588SBarry Smith }
1989289bc588SBarry Smith 
19909371c9d4SSatish Balay PetscErrorCode MatZeroEntries_SeqDense(Mat A) {
1991ec8511deSBarry Smith   Mat_SeqDense *l   = (Mat_SeqDense *)A->data;
19923d8925e7SStefano Zampini   PetscInt      lda = l->lda, m = A->rmap->n, n = A->cmap->n, j;
1993ca15aa20SStefano Zampini   PetscScalar  *v;
19943a40ed3dSBarry Smith 
19953a40ed3dSBarry Smith   PetscFunctionBegin;
19969566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(A, &v));
1997a5ce6ee0Svictorle   if (lda > m) {
199848a46eb9SPierre Jolivet     for (j = 0; j < n; j++) PetscCall(PetscArrayzero(v + j * lda, m));
1999a5ce6ee0Svictorle   } else {
20009566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(v, PetscInt64Mult(m, n)));
2001a5ce6ee0Svictorle   }
20029566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(A, &v));
20033a40ed3dSBarry Smith   PetscFunctionReturn(0);
20046f0a148fSBarry Smith }
20056f0a148fSBarry Smith 
20069371c9d4SSatish Balay static PetscErrorCode MatZeroRows_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) {
2007ec8511deSBarry Smith   Mat_SeqDense      *l = (Mat_SeqDense *)A->data;
2008b9679d65SBarry Smith   PetscInt           m = l->lda, n = A->cmap->n, i, j;
2009ca15aa20SStefano Zampini   PetscScalar       *slot, *bb, *v;
201097b48c8fSBarry Smith   const PetscScalar *xx;
201155659b69SBarry Smith 
20123a40ed3dSBarry Smith   PetscFunctionBegin;
201376bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
2014b9679d65SBarry Smith     for (i = 0; i < N; i++) {
201508401ef6SPierre Jolivet       PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed");
201608401ef6SPierre 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);
2017b9679d65SBarry Smith     }
201876bd3646SJed Brown   }
2019ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
2020b9679d65SBarry Smith 
202197b48c8fSBarry Smith   /* fix right hand side if needed */
202297b48c8fSBarry Smith   if (x && b) {
20239566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(x, &xx));
20249566063dSJacob Faibussowitsch     PetscCall(VecGetArray(b, &bb));
20252205254eSKarl Rupp     for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]];
20269566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(x, &xx));
20279566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(b, &bb));
202897b48c8fSBarry Smith   }
202997b48c8fSBarry Smith 
20309566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
20316f0a148fSBarry Smith   for (i = 0; i < N; i++) {
2032ca15aa20SStefano Zampini     slot = v + rows[i];
20339371c9d4SSatish Balay     for (j = 0; j < n; j++) {
20349371c9d4SSatish Balay       *slot = 0.0;
20359371c9d4SSatish Balay       slot += m;
20369371c9d4SSatish Balay     }
20376f0a148fSBarry Smith   }
2038f4df32b1SMatthew Knepley   if (diag != 0.0) {
203908401ef6SPierre Jolivet     PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices");
20406f0a148fSBarry Smith     for (i = 0; i < N; i++) {
2041ca15aa20SStefano Zampini       slot  = v + (m + 1) * rows[i];
2042f4df32b1SMatthew Knepley       *slot = diag;
20436f0a148fSBarry Smith     }
20446f0a148fSBarry Smith   }
20459566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
20463a40ed3dSBarry Smith   PetscFunctionReturn(0);
20476f0a148fSBarry Smith }
2048557bce09SLois Curfman McInnes 
20499371c9d4SSatish Balay static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A, PetscInt *lda) {
205049a6ff4bSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
205149a6ff4bSBarry Smith 
205249a6ff4bSBarry Smith   PetscFunctionBegin;
205349a6ff4bSBarry Smith   *lda = mat->lda;
205449a6ff4bSBarry Smith   PetscFunctionReturn(0);
205549a6ff4bSBarry Smith }
205649a6ff4bSBarry Smith 
20579371c9d4SSatish Balay PetscErrorCode MatDenseGetArray_SeqDense(Mat A, PetscScalar **array) {
2058c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
20593a40ed3dSBarry Smith 
20603a40ed3dSBarry Smith   PetscFunctionBegin;
206128b400f6SJacob Faibussowitsch   PetscCheck(!mat->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
206264e87e97SBarry Smith   *array = mat->v;
20633a40ed3dSBarry Smith   PetscFunctionReturn(0);
206464e87e97SBarry Smith }
20650754003eSLois Curfman McInnes 
20669371c9d4SSatish Balay PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A, PetscScalar **array) {
20673a40ed3dSBarry Smith   PetscFunctionBegin;
206875f6d85dSStefano Zampini   if (array) *array = NULL;
20693a40ed3dSBarry Smith   PetscFunctionReturn(0);
2070ff14e315SSatish Balay }
20710754003eSLois Curfman McInnes 
20720f74d2c1SSatish Balay /*@
207311a5261eSBarry Smith    MatDenseGetLDA - gets the leading dimension of the array returned from `MatDenseGetArray()`
207449a6ff4bSBarry Smith 
2075ad16ce7aSStefano Zampini    Not collective
207649a6ff4bSBarry Smith 
207749a6ff4bSBarry Smith    Input Parameter:
207811a5261eSBarry Smith .  mat - a `MATDENSE` or `MATDENSECUDA` matrix
207949a6ff4bSBarry Smith 
208049a6ff4bSBarry Smith    Output Parameter:
208149a6ff4bSBarry Smith .   lda - the leading dimension
208249a6ff4bSBarry Smith 
208349a6ff4bSBarry Smith    Level: intermediate
208449a6ff4bSBarry Smith 
208511a5261eSBarry Smith .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseSetLDA()`
208649a6ff4bSBarry Smith @*/
20879371c9d4SSatish Balay PetscErrorCode MatDenseGetLDA(Mat A, PetscInt *lda) {
208849a6ff4bSBarry Smith   PetscFunctionBegin;
2089d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2090dadcf809SJacob Faibussowitsch   PetscValidIntPointer(lda, 2);
209175f6d85dSStefano Zampini   MatCheckPreallocated(A, 1);
2092cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetLDA_C", (Mat, PetscInt *), (A, lda));
209349a6ff4bSBarry Smith   PetscFunctionReturn(0);
209449a6ff4bSBarry Smith }
209549a6ff4bSBarry Smith 
20960f74d2c1SSatish Balay /*@
209711a5261eSBarry Smith    MatDenseSetLDA - Sets the leading dimension of the array used by the `MATDENSE` matrix
2098ad16ce7aSStefano Zampini 
2099ad16ce7aSStefano Zampini    Not collective
2100ad16ce7aSStefano Zampini 
2101d8d19677SJose E. Roman    Input Parameters:
210211a5261eSBarry Smith +  mat - a `MATDENSE` or `MATDENSECUDA` matrix
2103ad16ce7aSStefano Zampini -  lda - the leading dimension
2104ad16ce7aSStefano Zampini 
2105ad16ce7aSStefano Zampini    Level: intermediate
2106ad16ce7aSStefano Zampini 
210711a5261eSBarry Smith .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetLDA()`
2108ad16ce7aSStefano Zampini @*/
21099371c9d4SSatish Balay PetscErrorCode MatDenseSetLDA(Mat A, PetscInt lda) {
2110ad16ce7aSStefano Zampini   PetscFunctionBegin;
2111ad16ce7aSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2112cac4c232SBarry Smith   PetscTryMethod(A, "MatDenseSetLDA_C", (Mat, PetscInt), (A, lda));
2113ad16ce7aSStefano Zampini   PetscFunctionReturn(0);
2114ad16ce7aSStefano Zampini }
2115ad16ce7aSStefano Zampini 
2116ad16ce7aSStefano Zampini /*@C
211711a5261eSBarry Smith    MatDenseGetArray - gives read-write access to the array where the data for a `MATDENSE` matrix is stored
211873a71a0fSBarry Smith 
211911a5261eSBarry Smith    Logically Collective on A
212073a71a0fSBarry Smith 
212173a71a0fSBarry Smith    Input Parameter:
21226947451fSStefano Zampini .  mat - a dense matrix
212373a71a0fSBarry Smith 
212473a71a0fSBarry Smith    Output Parameter:
212573a71a0fSBarry Smith .   array - pointer to the data
212673a71a0fSBarry Smith 
212773a71a0fSBarry Smith    Level: intermediate
212873a71a0fSBarry Smith 
212911a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
213073a71a0fSBarry Smith @*/
21319371c9d4SSatish Balay PetscErrorCode MatDenseGetArray(Mat A, PetscScalar **array) {
213273a71a0fSBarry Smith   PetscFunctionBegin;
2133d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2134d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2135cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array));
213673a71a0fSBarry Smith   PetscFunctionReturn(0);
213773a71a0fSBarry Smith }
213873a71a0fSBarry Smith 
2139dec5eb66SMatthew G Knepley /*@C
214011a5261eSBarry Smith    MatDenseRestoreArray - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArray()`
214173a71a0fSBarry Smith 
214211a5261eSBarry Smith    Logically Collective on A
21438572280aSBarry Smith 
21448572280aSBarry Smith    Input Parameters:
21456947451fSStefano Zampini +  mat - a dense matrix
2146742765d3SMatthew Knepley -  array - pointer to the data (may be NULL)
21478572280aSBarry Smith 
21488572280aSBarry Smith    Level: intermediate
21498572280aSBarry Smith 
215011a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
21518572280aSBarry Smith @*/
21529371c9d4SSatish Balay PetscErrorCode MatDenseRestoreArray(Mat A, PetscScalar **array) {
21538572280aSBarry Smith   PetscFunctionBegin;
2154d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2155d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2156cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array));
21579566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)A));
2158637a0070SStefano Zampini #if defined(PETSC_HAVE_CUDA)
2159637a0070SStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
2160637a0070SStefano Zampini #endif
21618572280aSBarry Smith   PetscFunctionReturn(0);
21628572280aSBarry Smith }
21638572280aSBarry Smith 
21648572280aSBarry Smith /*@C
216511a5261eSBarry Smith   MatDenseGetArrayRead - gives read-only access to the array where the data for a `MATDENSE`  matrix is stored
21668572280aSBarry Smith 
21678572280aSBarry Smith    Not Collective
21688572280aSBarry Smith 
21698572280aSBarry Smith    Input Parameter:
21706947451fSStefano Zampini .  mat - a dense matrix
21718572280aSBarry Smith 
21728572280aSBarry Smith    Output Parameter:
21738572280aSBarry Smith .   array - pointer to the data
21748572280aSBarry Smith 
21758572280aSBarry Smith    Level: intermediate
21768572280aSBarry Smith 
217711a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
21788572280aSBarry Smith @*/
21799371c9d4SSatish Balay PetscErrorCode MatDenseGetArrayRead(Mat A, const PetscScalar **array) {
21808572280aSBarry Smith   PetscFunctionBegin;
2181d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2182d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2183cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, const PetscScalar **), (A, array));
21848572280aSBarry Smith   PetscFunctionReturn(0);
21858572280aSBarry Smith }
21868572280aSBarry Smith 
21878572280aSBarry Smith /*@C
218811a5261eSBarry Smith    MatDenseRestoreArrayRead - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayRead()`
21898572280aSBarry Smith 
219073a71a0fSBarry Smith    Not Collective
219173a71a0fSBarry Smith 
219273a71a0fSBarry Smith    Input Parameters:
21936947451fSStefano Zampini +  mat - a dense matrix
2194742765d3SMatthew Knepley -  array - pointer to the data (may be NULL)
219573a71a0fSBarry Smith 
219673a71a0fSBarry Smith    Level: intermediate
219773a71a0fSBarry Smith 
219811a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
219973a71a0fSBarry Smith @*/
22009371c9d4SSatish Balay PetscErrorCode MatDenseRestoreArrayRead(Mat A, const PetscScalar **array) {
220173a71a0fSBarry Smith   PetscFunctionBegin;
2202d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2203d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2204cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, const PetscScalar **), (A, array));
220573a71a0fSBarry Smith   PetscFunctionReturn(0);
220673a71a0fSBarry Smith }
220773a71a0fSBarry Smith 
22086947451fSStefano Zampini /*@C
220911a5261eSBarry Smith    MatDenseGetArrayWrite - gives write-only access to the array where the data for a `MATDENSE` matrix is stored
22106947451fSStefano Zampini 
22116947451fSStefano Zampini    Not Collective
22126947451fSStefano Zampini 
22136947451fSStefano Zampini    Input Parameter:
22146947451fSStefano Zampini .  mat - a dense matrix
22156947451fSStefano Zampini 
22166947451fSStefano Zampini    Output Parameter:
22176947451fSStefano Zampini .   array - pointer to the data
22186947451fSStefano Zampini 
22196947451fSStefano Zampini    Level: intermediate
22206947451fSStefano Zampini 
222111a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`
22226947451fSStefano Zampini @*/
22239371c9d4SSatish Balay PetscErrorCode MatDenseGetArrayWrite(Mat A, PetscScalar **array) {
22246947451fSStefano Zampini   PetscFunctionBegin;
2225d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2226d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2227cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array));
22286947451fSStefano Zampini   PetscFunctionReturn(0);
22296947451fSStefano Zampini }
22306947451fSStefano Zampini 
22316947451fSStefano Zampini /*@C
223211a5261eSBarry Smith    MatDenseRestoreArrayWrite - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayWrite()`
22336947451fSStefano Zampini 
22346947451fSStefano Zampini    Not Collective
22356947451fSStefano Zampini 
22366947451fSStefano Zampini    Input Parameters:
22376947451fSStefano Zampini +  mat - a dense matrix
2238742765d3SMatthew Knepley -  array - pointer to the data (may be NULL)
22396947451fSStefano Zampini 
22406947451fSStefano Zampini    Level: intermediate
22416947451fSStefano Zampini 
224211a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`
22436947451fSStefano Zampini @*/
22449371c9d4SSatish Balay PetscErrorCode MatDenseRestoreArrayWrite(Mat A, PetscScalar **array) {
22456947451fSStefano Zampini   PetscFunctionBegin;
2246d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2247d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2248cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array));
22499566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)A));
22506947451fSStefano Zampini #if defined(PETSC_HAVE_CUDA)
22516947451fSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
22526947451fSStefano Zampini #endif
22536947451fSStefano Zampini   PetscFunctionReturn(0);
22546947451fSStefano Zampini }
22556947451fSStefano Zampini 
22569371c9d4SSatish Balay static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A, IS isrow, IS iscol, MatReuse scall, Mat *B) {
2257c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense *)A->data;
2258bf5a80bcSToby Isaac   PetscInt        i, j, nrows, ncols, ldb;
22595d0c19d7SBarry Smith   const PetscInt *irow, *icol;
226087828ca2SBarry Smith   PetscScalar    *av, *bv, *v = mat->v;
22610754003eSLois Curfman McInnes   Mat             newmat;
22620754003eSLois Curfman McInnes 
22633a40ed3dSBarry Smith   PetscFunctionBegin;
22649566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(isrow, &irow));
22659566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(iscol, &icol));
22669566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(isrow, &nrows));
22679566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(iscol, &ncols));
22680754003eSLois Curfman McInnes 
2269182d2002SSatish Balay   /* Check submatrixcall */
2270182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
227113f74950SBarry Smith     PetscInt n_cols, n_rows;
22729566063dSJacob Faibussowitsch     PetscCall(MatGetSize(*B, &n_rows, &n_cols));
227321a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
2274f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
22759566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(*B, nrows, ncols, nrows, ncols));
227621a2c019SBarry Smith     }
2277182d2002SSatish Balay     newmat = *B;
2278182d2002SSatish Balay   } else {
22790754003eSLois Curfman McInnes     /* Create and fill new matrix */
22809566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &newmat));
22819566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(newmat, nrows, ncols, nrows, ncols));
22829566063dSJacob Faibussowitsch     PetscCall(MatSetType(newmat, ((PetscObject)A)->type_name));
22839566063dSJacob Faibussowitsch     PetscCall(MatSeqDenseSetPreallocation(newmat, NULL));
2284182d2002SSatish Balay   }
2285182d2002SSatish Balay 
2286182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
22879566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(newmat, &bv));
22889566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(newmat, &ldb));
2289182d2002SSatish Balay   for (i = 0; i < ncols; i++) {
22906de62eeeSBarry Smith     av = v + mat->lda * icol[i];
2291ca15aa20SStefano Zampini     for (j = 0; j < nrows; j++) bv[j] = av[irow[j]];
2292bf5a80bcSToby Isaac     bv += ldb;
22930754003eSLois Curfman McInnes   }
22949566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(newmat, &bv));
2295182d2002SSatish Balay 
2296182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
22979566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(newmat, MAT_FINAL_ASSEMBLY));
22989566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(newmat, MAT_FINAL_ASSEMBLY));
22990754003eSLois Curfman McInnes 
23000754003eSLois Curfman McInnes   /* Free work space */
23019566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(isrow, &irow));
23029566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(iscol, &icol));
2303182d2002SSatish Balay   *B = newmat;
23043a40ed3dSBarry Smith   PetscFunctionReturn(0);
23050754003eSLois Curfman McInnes }
23060754003eSLois Curfman McInnes 
23079371c9d4SSatish Balay static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A, PetscInt n, const IS irow[], const IS icol[], MatReuse scall, Mat *B[]) {
230813f74950SBarry Smith   PetscInt i;
2309905e6a2fSBarry Smith 
23103a40ed3dSBarry Smith   PetscFunctionBegin;
231148a46eb9SPierre Jolivet   if (scall == MAT_INITIAL_MATRIX) PetscCall(PetscCalloc1(n, B));
2312905e6a2fSBarry Smith 
231348a46eb9SPierre Jolivet   for (i = 0; i < n; i++) PetscCall(MatCreateSubMatrix_SeqDense(A, irow[i], icol[i], scall, &(*B)[i]));
23143a40ed3dSBarry Smith   PetscFunctionReturn(0);
2315905e6a2fSBarry Smith }
2316905e6a2fSBarry Smith 
23179371c9d4SSatish Balay static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat, MatAssemblyType mode) {
2318c0aa2d19SHong Zhang   PetscFunctionBegin;
2319c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2320c0aa2d19SHong Zhang }
2321c0aa2d19SHong Zhang 
23229371c9d4SSatish Balay static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat, MatAssemblyType mode) {
2323c0aa2d19SHong Zhang   PetscFunctionBegin;
2324c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2325c0aa2d19SHong Zhang }
2326c0aa2d19SHong Zhang 
23279371c9d4SSatish Balay PetscErrorCode MatCopy_SeqDense(Mat A, Mat B, MatStructure str) {
23284b0e389bSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data;
2329ca15aa20SStefano Zampini   const PetscScalar *va;
2330ca15aa20SStefano Zampini   PetscScalar       *vb;
2331d0f46423SBarry Smith   PetscInt           lda1 = a->lda, lda2 = b->lda, m = A->rmap->n, n = A->cmap->n, j;
23323a40ed3dSBarry Smith 
23333a40ed3dSBarry Smith   PetscFunctionBegin;
233433f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
233533f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
23369566063dSJacob Faibussowitsch     PetscCall(MatCopy_Basic(A, B, str));
23373a40ed3dSBarry Smith     PetscFunctionReturn(0);
23383a40ed3dSBarry Smith   }
2339aed4548fSBarry Smith   PetscCheck(m == B->rmap->n && n == B->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "size(B) != size(A)");
23409566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &va));
23419566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(B, &vb));
2342a5ce6ee0Svictorle   if (lda1 > m || lda2 > m) {
234348a46eb9SPierre Jolivet     for (j = 0; j < n; j++) PetscCall(PetscArraycpy(vb + j * lda2, va + j * lda1, m));
2344a5ce6ee0Svictorle   } else {
23459566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(vb, va, A->rmap->n * A->cmap->n));
2346a5ce6ee0Svictorle   }
23479566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(B, &vb));
23489566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &va));
23499566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY));
23509566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY));
2351273d9f13SBarry Smith   PetscFunctionReturn(0);
2352273d9f13SBarry Smith }
2353273d9f13SBarry Smith 
23549371c9d4SSatish Balay PetscErrorCode MatSetUp_SeqDense(Mat A) {
2355273d9f13SBarry Smith   PetscFunctionBegin;
23569566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(A->rmap));
23579566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(A->cmap));
235848a46eb9SPierre Jolivet   if (!A->preallocated) PetscCall(MatSeqDenseSetPreallocation(A, NULL));
23593a40ed3dSBarry Smith   PetscFunctionReturn(0);
23604b0e389bSBarry Smith }
23614b0e389bSBarry Smith 
23629371c9d4SSatish Balay static PetscErrorCode MatConjugate_SeqDense(Mat A) {
23634396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
236406c5243aSJose E. Roman   PetscInt      i, j;
23654396437dSToby Isaac   PetscInt      min = PetscMin(A->rmap->n, A->cmap->n);
2366ca15aa20SStefano Zampini   PetscScalar  *aa;
2367ba337c44SJed Brown 
2368ba337c44SJed Brown   PetscFunctionBegin;
23699566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &aa));
237006c5243aSJose E. Roman   for (j = 0; j < A->cmap->n; j++) {
237106c5243aSJose E. Roman     for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscConj(aa[i + j * mat->lda]);
237206c5243aSJose E. Roman   }
23739566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &aa));
23749371c9d4SSatish Balay   if (mat->tau)
23759371c9d4SSatish Balay     for (i = 0; i < min; i++) mat->tau[i] = PetscConj(mat->tau[i]);
2376ba337c44SJed Brown   PetscFunctionReturn(0);
2377ba337c44SJed Brown }
2378ba337c44SJed Brown 
23799371c9d4SSatish Balay static PetscErrorCode MatRealPart_SeqDense(Mat A) {
238006c5243aSJose E. Roman   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
238106c5243aSJose E. Roman   PetscInt      i, j;
2382ca15aa20SStefano Zampini   PetscScalar  *aa;
2383ba337c44SJed Brown 
2384ba337c44SJed Brown   PetscFunctionBegin;
23859566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &aa));
238606c5243aSJose E. Roman   for (j = 0; j < A->cmap->n; j++) {
238706c5243aSJose E. Roman     for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscRealPart(aa[i + j * mat->lda]);
238806c5243aSJose E. Roman   }
23899566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &aa));
2390ba337c44SJed Brown   PetscFunctionReturn(0);
2391ba337c44SJed Brown }
2392ba337c44SJed Brown 
23939371c9d4SSatish Balay static PetscErrorCode MatImaginaryPart_SeqDense(Mat A) {
239406c5243aSJose E. Roman   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
239506c5243aSJose E. Roman   PetscInt      i, j;
2396ca15aa20SStefano Zampini   PetscScalar  *aa;
2397ba337c44SJed Brown 
2398ba337c44SJed Brown   PetscFunctionBegin;
23999566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &aa));
240006c5243aSJose E. Roman   for (j = 0; j < A->cmap->n; j++) {
240106c5243aSJose E. Roman     for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscImaginaryPart(aa[i + j * mat->lda]);
240206c5243aSJose E. Roman   }
24039566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &aa));
2404ba337c44SJed Brown   PetscFunctionReturn(0);
2405ba337c44SJed Brown }
2406284134d9SBarry Smith 
2407a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/
24089371c9d4SSatish Balay PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) {
2409d0f46423SBarry Smith   PetscInt  m = A->rmap->n, n = B->cmap->n;
24107a3c3d58SStefano Zampini   PetscBool cisdense;
2411a9fe9ddaSSatish Balay 
2412ee16a9a1SHong Zhang   PetscFunctionBegin;
24139566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C, m, n, m, n));
24149566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, ""));
24157a3c3d58SStefano Zampini   if (!cisdense) {
24167a3c3d58SStefano Zampini     PetscBool flg;
24177a3c3d58SStefano Zampini 
24189566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg));
24199566063dSJacob Faibussowitsch     PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE));
24207a3c3d58SStefano Zampini   }
24219566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
2422ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2423ee16a9a1SHong Zhang }
2424a9fe9ddaSSatish Balay 
24259371c9d4SSatish Balay PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) {
24266718818eSStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data, *c = (Mat_SeqDense *)C->data;
24270805154bSBarry Smith   PetscBLASInt       m, n, k;
2428ca15aa20SStefano Zampini   const PetscScalar *av, *bv;
2429ca15aa20SStefano Zampini   PetscScalar       *cv;
2430a9fe9ddaSSatish Balay   PetscScalar        _DOne = 1.0, _DZero = 0.0;
2431a9fe9ddaSSatish Balay 
2432a9fe9ddaSSatish Balay   PetscFunctionBegin;
24339566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n, &m));
24349566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n, &n));
24359566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &k));
243649d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
24379566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &av));
24389566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B, &bv));
24399566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C, &cv));
2440792fecdfSBarry Smith   PetscCallBLAS("BLASgemm", BLASgemm_("N", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda));
24419566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1)));
24429566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &av));
24439566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B, &bv));
24449566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C, &cv));
2445a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2446a9fe9ddaSSatish Balay }
2447a9fe9ddaSSatish Balay 
24489371c9d4SSatish Balay PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) {
244969f65d41SStefano Zampini   PetscInt  m = A->rmap->n, n = B->rmap->n;
24507a3c3d58SStefano Zampini   PetscBool cisdense;
245169f65d41SStefano Zampini 
245269f65d41SStefano Zampini   PetscFunctionBegin;
24539566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C, m, n, m, n));
24549566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, ""));
24557a3c3d58SStefano Zampini   if (!cisdense) {
24567a3c3d58SStefano Zampini     PetscBool flg;
24577a3c3d58SStefano Zampini 
24589566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg));
24599566063dSJacob Faibussowitsch     PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE));
24607a3c3d58SStefano Zampini   }
24619566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
246269f65d41SStefano Zampini   PetscFunctionReturn(0);
246369f65d41SStefano Zampini }
246469f65d41SStefano Zampini 
24659371c9d4SSatish Balay PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) {
246669f65d41SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
246769f65d41SStefano Zampini   Mat_SeqDense      *b = (Mat_SeqDense *)B->data;
246869f65d41SStefano Zampini   Mat_SeqDense      *c = (Mat_SeqDense *)C->data;
24696718818eSStefano Zampini   const PetscScalar *av, *bv;
24706718818eSStefano Zampini   PetscScalar       *cv;
247169f65d41SStefano Zampini   PetscBLASInt       m, n, k;
247269f65d41SStefano Zampini   PetscScalar        _DOne = 1.0, _DZero = 0.0;
247369f65d41SStefano Zampini 
247469f65d41SStefano Zampini   PetscFunctionBegin;
24759566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n, &m));
24769566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n, &n));
24779566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &k));
247849d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
24799566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &av));
24809566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B, &bv));
24819566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C, &cv));
2482792fecdfSBarry Smith   PetscCallBLAS("BLASgemm", BLASgemm_("N", "T", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda));
24839566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &av));
24849566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B, &bv));
24859566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C, &cv));
24869566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1)));
248769f65d41SStefano Zampini   PetscFunctionReturn(0);
248869f65d41SStefano Zampini }
248969f65d41SStefano Zampini 
24909371c9d4SSatish Balay PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) {
2491d0f46423SBarry Smith   PetscInt  m = A->cmap->n, n = B->cmap->n;
24927a3c3d58SStefano Zampini   PetscBool cisdense;
2493a9fe9ddaSSatish Balay 
2494ee16a9a1SHong Zhang   PetscFunctionBegin;
24959566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C, m, n, m, n));
24969566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, ""));
24977a3c3d58SStefano Zampini   if (!cisdense) {
24987a3c3d58SStefano Zampini     PetscBool flg;
24997a3c3d58SStefano Zampini 
25009566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg));
25019566063dSJacob Faibussowitsch     PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE));
25027a3c3d58SStefano Zampini   }
25039566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
2504ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2505ee16a9a1SHong Zhang }
2506a9fe9ddaSSatish Balay 
25079371c9d4SSatish Balay PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) {
2508a9fe9ddaSSatish Balay   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
2509a9fe9ddaSSatish Balay   Mat_SeqDense      *b = (Mat_SeqDense *)B->data;
2510a9fe9ddaSSatish Balay   Mat_SeqDense      *c = (Mat_SeqDense *)C->data;
25116718818eSStefano Zampini   const PetscScalar *av, *bv;
25126718818eSStefano Zampini   PetscScalar       *cv;
25130805154bSBarry Smith   PetscBLASInt       m, n, k;
2514a9fe9ddaSSatish Balay   PetscScalar        _DOne = 1.0, _DZero = 0.0;
2515a9fe9ddaSSatish Balay 
2516a9fe9ddaSSatish Balay   PetscFunctionBegin;
25179566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n, &m));
25189566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n, &n));
25199566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &k));
252049d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
25219566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &av));
25229566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B, &bv));
25239566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C, &cv));
2524792fecdfSBarry Smith   PetscCallBLAS("BLASgemm", BLASgemm_("T", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda));
25259566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &av));
25269566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B, &bv));
25279566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C, &cv));
25289566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1)));
2529a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2530a9fe9ddaSSatish Balay }
2531985db425SBarry Smith 
25324222ddf1SHong Zhang /* ----------------------------------------------- */
25339371c9d4SSatish Balay static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C) {
25344222ddf1SHong Zhang   PetscFunctionBegin;
25354222ddf1SHong Zhang   C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense;
25364222ddf1SHong Zhang   C->ops->productsymbolic = MatProductSymbolic_AB;
25374222ddf1SHong Zhang   PetscFunctionReturn(0);
25384222ddf1SHong Zhang }
25394222ddf1SHong Zhang 
25409371c9d4SSatish Balay static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C) {
25414222ddf1SHong Zhang   PetscFunctionBegin;
25424222ddf1SHong Zhang   C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense;
25434222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_AtB;
25444222ddf1SHong Zhang   PetscFunctionReturn(0);
25454222ddf1SHong Zhang }
25464222ddf1SHong Zhang 
25479371c9d4SSatish Balay static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C) {
25484222ddf1SHong Zhang   PetscFunctionBegin;
25494222ddf1SHong Zhang   C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense;
25504222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_ABt;
25514222ddf1SHong Zhang   PetscFunctionReturn(0);
25524222ddf1SHong Zhang }
25534222ddf1SHong Zhang 
25549371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C) {
25554222ddf1SHong Zhang   Mat_Product *product = C->product;
25564222ddf1SHong Zhang 
25574222ddf1SHong Zhang   PetscFunctionBegin;
25584222ddf1SHong Zhang   switch (product->type) {
25599371c9d4SSatish Balay   case MATPRODUCT_AB: PetscCall(MatProductSetFromOptions_SeqDense_AB(C)); break;
25609371c9d4SSatish Balay   case MATPRODUCT_AtB: PetscCall(MatProductSetFromOptions_SeqDense_AtB(C)); break;
25619371c9d4SSatish Balay   case MATPRODUCT_ABt: PetscCall(MatProductSetFromOptions_SeqDense_ABt(C)); break;
25629371c9d4SSatish Balay   default: break;
25634222ddf1SHong Zhang   }
25644222ddf1SHong Zhang   PetscFunctionReturn(0);
25654222ddf1SHong Zhang }
25664222ddf1SHong Zhang /* ----------------------------------------------- */
25674222ddf1SHong Zhang 
25689371c9d4SSatish Balay static PetscErrorCode MatGetRowMax_SeqDense(Mat A, Vec v, PetscInt idx[]) {
2569985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
2570d0f46423SBarry Smith   PetscInt           i, j, m = A->rmap->n, n = A->cmap->n, p;
2571985db425SBarry Smith   PetscScalar       *x;
2572ca15aa20SStefano Zampini   const PetscScalar *aa;
2573985db425SBarry Smith 
2574985db425SBarry Smith   PetscFunctionBegin;
257528b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
25769566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
25779566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v, &p));
25789566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
257908401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector");
2580985db425SBarry Smith   for (i = 0; i < m; i++) {
25819371c9d4SSatish Balay     x[i] = aa[i];
25829371c9d4SSatish Balay     if (idx) idx[i] = 0;
2583985db425SBarry Smith     for (j = 1; j < n; j++) {
25849371c9d4SSatish Balay       if (PetscRealPart(x[i]) < PetscRealPart(aa[i + a->lda * j])) {
25859371c9d4SSatish Balay         x[i] = aa[i + a->lda * j];
25869371c9d4SSatish Balay         if (idx) idx[i] = j;
25879371c9d4SSatish Balay       }
2588985db425SBarry Smith     }
2589985db425SBarry Smith   }
25909566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
25919566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
2592985db425SBarry Smith   PetscFunctionReturn(0);
2593985db425SBarry Smith }
2594985db425SBarry Smith 
25959371c9d4SSatish Balay static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A, Vec v, PetscInt idx[]) {
2596985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
2597d0f46423SBarry Smith   PetscInt           i, j, m = A->rmap->n, n = A->cmap->n, p;
2598985db425SBarry Smith   PetscScalar       *x;
2599985db425SBarry Smith   PetscReal          atmp;
2600ca15aa20SStefano Zampini   const PetscScalar *aa;
2601985db425SBarry Smith 
2602985db425SBarry Smith   PetscFunctionBegin;
260328b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
26049566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
26059566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v, &p));
26069566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
260708401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector");
2608985db425SBarry Smith   for (i = 0; i < m; i++) {
26099189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
2610985db425SBarry Smith     for (j = 1; j < n; j++) {
2611ca15aa20SStefano Zampini       atmp = PetscAbsScalar(aa[i + a->lda * j]);
26129371c9d4SSatish Balay       if (PetscAbsScalar(x[i]) < atmp) {
26139371c9d4SSatish Balay         x[i] = atmp;
26149371c9d4SSatish Balay         if (idx) idx[i] = j;
26159371c9d4SSatish Balay       }
2616985db425SBarry Smith     }
2617985db425SBarry Smith   }
26189566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
26199566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
2620985db425SBarry Smith   PetscFunctionReturn(0);
2621985db425SBarry Smith }
2622985db425SBarry Smith 
26239371c9d4SSatish Balay static PetscErrorCode MatGetRowMin_SeqDense(Mat A, Vec v, PetscInt idx[]) {
2624985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
2625d0f46423SBarry Smith   PetscInt           i, j, m = A->rmap->n, n = A->cmap->n, p;
2626985db425SBarry Smith   PetscScalar       *x;
2627ca15aa20SStefano Zampini   const PetscScalar *aa;
2628985db425SBarry Smith 
2629985db425SBarry Smith   PetscFunctionBegin;
263028b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
26319566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
26329566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
26339566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v, &p));
263408401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector");
2635985db425SBarry Smith   for (i = 0; i < m; i++) {
26369371c9d4SSatish Balay     x[i] = aa[i];
26379371c9d4SSatish Balay     if (idx) idx[i] = 0;
2638985db425SBarry Smith     for (j = 1; j < n; j++) {
26399371c9d4SSatish Balay       if (PetscRealPart(x[i]) > PetscRealPart(aa[i + a->lda * j])) {
26409371c9d4SSatish Balay         x[i] = aa[i + a->lda * j];
26419371c9d4SSatish Balay         if (idx) idx[i] = j;
26429371c9d4SSatish Balay       }
2643985db425SBarry Smith     }
2644985db425SBarry Smith   }
26459566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
26469566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
2647985db425SBarry Smith   PetscFunctionReturn(0);
2648985db425SBarry Smith }
2649985db425SBarry Smith 
26509371c9d4SSatish Balay PetscErrorCode MatGetColumnVector_SeqDense(Mat A, Vec v, PetscInt col) {
26518d0534beSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
26528d0534beSBarry Smith   PetscScalar       *x;
2653ca15aa20SStefano Zampini   const PetscScalar *aa;
26548d0534beSBarry Smith 
26558d0534beSBarry Smith   PetscFunctionBegin;
265628b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
26579566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
26589566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
26599566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(x, aa + col * a->lda, A->rmap->n));
26609566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
26619566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
26628d0534beSBarry Smith   PetscFunctionReturn(0);
26638d0534beSBarry Smith }
26648d0534beSBarry Smith 
26659371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatGetColumnReductions_SeqDense(Mat A, PetscInt type, PetscReal *reductions) {
26660716a85fSBarry Smith   PetscInt           i, j, m, n;
26671683a169SBarry Smith   const PetscScalar *a;
26680716a85fSBarry Smith 
26690716a85fSBarry Smith   PetscFunctionBegin;
26709566063dSJacob Faibussowitsch   PetscCall(MatGetSize(A, &m, &n));
26719566063dSJacob Faibussowitsch   PetscCall(PetscArrayzero(reductions, n));
26729566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &a));
2673857cbf51SRichard Tran Mills   if (type == NORM_2) {
26740716a85fSBarry Smith     for (i = 0; i < n; i++) {
2675ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j] * a[j]);
26760716a85fSBarry Smith       a += m;
26770716a85fSBarry Smith     }
2678857cbf51SRichard Tran Mills   } else if (type == NORM_1) {
26790716a85fSBarry Smith     for (i = 0; i < n; i++) {
2680ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j]);
26810716a85fSBarry Smith       a += m;
26820716a85fSBarry Smith     }
2683857cbf51SRichard Tran Mills   } else if (type == NORM_INFINITY) {
26840716a85fSBarry Smith     for (i = 0; i < n; i++) {
2685ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] = PetscMax(PetscAbsScalar(a[j]), reductions[i]);
26860716a85fSBarry Smith       a += m;
26870716a85fSBarry Smith     }
2688857cbf51SRichard Tran Mills   } else if (type == REDUCTION_SUM_REALPART || type == REDUCTION_MEAN_REALPART) {
2689a873a8cdSSam Reynolds     for (i = 0; i < n; i++) {
2690ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] += PetscRealPart(a[j]);
2691a873a8cdSSam Reynolds       a += m;
2692a873a8cdSSam Reynolds     }
2693857cbf51SRichard Tran Mills   } else if (type == REDUCTION_SUM_IMAGINARYPART || type == REDUCTION_MEAN_IMAGINARYPART) {
2694857cbf51SRichard Tran Mills     for (i = 0; i < n; i++) {
2695ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] += PetscImaginaryPart(a[j]);
2696857cbf51SRichard Tran Mills       a += m;
2697857cbf51SRichard Tran Mills     }
2698857cbf51SRichard Tran Mills   } else SETERRQ(PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Unknown reduction type");
26999566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &a));
2700857cbf51SRichard Tran Mills   if (type == NORM_2) {
2701a873a8cdSSam Reynolds     for (i = 0; i < n; i++) reductions[i] = PetscSqrtReal(reductions[i]);
2702857cbf51SRichard Tran Mills   } else if (type == REDUCTION_MEAN_REALPART || type == REDUCTION_MEAN_IMAGINARYPART) {
2703a873a8cdSSam Reynolds     for (i = 0; i < n; i++) reductions[i] /= m;
27040716a85fSBarry Smith   }
27050716a85fSBarry Smith   PetscFunctionReturn(0);
27060716a85fSBarry Smith }
27070716a85fSBarry Smith 
2708*3faff063SStefano Zampini PetscErrorCode MatSetRandom_SeqDense(Mat x, PetscRandom rctx) {
270973a71a0fSBarry Smith   PetscScalar *a;
2710637a0070SStefano Zampini   PetscInt     lda, m, n, i, j;
271173a71a0fSBarry Smith 
271273a71a0fSBarry Smith   PetscFunctionBegin;
27139566063dSJacob Faibussowitsch   PetscCall(MatGetSize(x, &m, &n));
27149566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(x, &lda));
2715*3faff063SStefano Zampini   PetscCall(MatDenseGetArrayWrite(x, &a));
2716637a0070SStefano Zampini   for (j = 0; j < n; j++) {
271748a46eb9SPierre Jolivet     for (i = 0; i < m; i++) PetscCall(PetscRandomGetValue(rctx, a + j * lda + i));
271873a71a0fSBarry Smith   }
2719*3faff063SStefano Zampini   PetscCall(MatDenseRestoreArrayWrite(x, &a));
272073a71a0fSBarry Smith   PetscFunctionReturn(0);
272173a71a0fSBarry Smith }
272273a71a0fSBarry Smith 
27239371c9d4SSatish Balay static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A, PetscBool *missing, PetscInt *d) {
27243b49f96aSBarry Smith   PetscFunctionBegin;
27253b49f96aSBarry Smith   *missing = PETSC_FALSE;
27263b49f96aSBarry Smith   PetscFunctionReturn(0);
27273b49f96aSBarry Smith }
272873a71a0fSBarry Smith 
2729ca15aa20SStefano Zampini /* vals is not const */
27309371c9d4SSatish Balay static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A, PetscInt col, PetscScalar **vals) {
273186aefd0dSHong Zhang   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
2732ca15aa20SStefano Zampini   PetscScalar  *v;
273386aefd0dSHong Zhang 
273486aefd0dSHong Zhang   PetscFunctionBegin;
273528b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
27369566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
2737ca15aa20SStefano Zampini   *vals = v + col * a->lda;
27389566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
273986aefd0dSHong Zhang   PetscFunctionReturn(0);
274086aefd0dSHong Zhang }
274186aefd0dSHong Zhang 
27429371c9d4SSatish Balay static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A, PetscScalar **vals) {
274386aefd0dSHong Zhang   PetscFunctionBegin;
2744742765d3SMatthew Knepley   if (vals) *vals = NULL; /* user cannot accidentally use the array later */
274586aefd0dSHong Zhang   PetscFunctionReturn(0);
274686aefd0dSHong Zhang }
2747abc3b08eSStefano Zampini 
2748289bc588SBarry Smith /* -------------------------------------------------------------------*/
2749a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqDense,
2750905e6a2fSBarry Smith                                        MatGetRow_SeqDense,
2751905e6a2fSBarry Smith                                        MatRestoreRow_SeqDense,
2752905e6a2fSBarry Smith                                        MatMult_SeqDense,
275397304618SKris Buschelman                                        /*  4*/ MatMultAdd_SeqDense,
27547c922b88SBarry Smith                                        MatMultTranspose_SeqDense,
27557c922b88SBarry Smith                                        MatMultTransposeAdd_SeqDense,
2756f4259b30SLisandro Dalcin                                        NULL,
2757f4259b30SLisandro Dalcin                                        NULL,
2758f4259b30SLisandro Dalcin                                        NULL,
2759f4259b30SLisandro Dalcin                                        /* 10*/ NULL,
2760905e6a2fSBarry Smith                                        MatLUFactor_SeqDense,
2761905e6a2fSBarry Smith                                        MatCholeskyFactor_SeqDense,
276241f059aeSBarry Smith                                        MatSOR_SeqDense,
2763ec8511deSBarry Smith                                        MatTranspose_SeqDense,
276497304618SKris Buschelman                                        /* 15*/ MatGetInfo_SeqDense,
2765905e6a2fSBarry Smith                                        MatEqual_SeqDense,
2766905e6a2fSBarry Smith                                        MatGetDiagonal_SeqDense,
2767905e6a2fSBarry Smith                                        MatDiagonalScale_SeqDense,
2768905e6a2fSBarry Smith                                        MatNorm_SeqDense,
2769c0aa2d19SHong Zhang                                        /* 20*/ MatAssemblyBegin_SeqDense,
2770c0aa2d19SHong Zhang                                        MatAssemblyEnd_SeqDense,
2771905e6a2fSBarry Smith                                        MatSetOption_SeqDense,
2772905e6a2fSBarry Smith                                        MatZeroEntries_SeqDense,
2773d519adbfSMatthew Knepley                                        /* 24*/ MatZeroRows_SeqDense,
2774f4259b30SLisandro Dalcin                                        NULL,
2775f4259b30SLisandro Dalcin                                        NULL,
2776f4259b30SLisandro Dalcin                                        NULL,
2777f4259b30SLisandro Dalcin                                        NULL,
27784994cf47SJed Brown                                        /* 29*/ MatSetUp_SeqDense,
2779f4259b30SLisandro Dalcin                                        NULL,
2780f4259b30SLisandro Dalcin                                        NULL,
2781f4259b30SLisandro Dalcin                                        NULL,
2782f4259b30SLisandro Dalcin                                        NULL,
2783d519adbfSMatthew Knepley                                        /* 34*/ MatDuplicate_SeqDense,
2784f4259b30SLisandro Dalcin                                        NULL,
2785f4259b30SLisandro Dalcin                                        NULL,
2786f4259b30SLisandro Dalcin                                        NULL,
2787f4259b30SLisandro Dalcin                                        NULL,
2788d519adbfSMatthew Knepley                                        /* 39*/ MatAXPY_SeqDense,
27897dae84e0SHong Zhang                                        MatCreateSubMatrices_SeqDense,
2790f4259b30SLisandro Dalcin                                        NULL,
27914b0e389bSBarry Smith                                        MatGetValues_SeqDense,
2792a5ae1ecdSBarry Smith                                        MatCopy_SeqDense,
2793d519adbfSMatthew Knepley                                        /* 44*/ MatGetRowMax_SeqDense,
2794a5ae1ecdSBarry Smith                                        MatScale_SeqDense,
27952f605a99SJose E. Roman                                        MatShift_SeqDense,
2796f4259b30SLisandro Dalcin                                        NULL,
27973f49a652SStefano Zampini                                        MatZeroRowsColumns_SeqDense,
279873a71a0fSBarry Smith                                        /* 49*/ MatSetRandom_SeqDense,
2799f4259b30SLisandro Dalcin                                        NULL,
2800f4259b30SLisandro Dalcin                                        NULL,
2801f4259b30SLisandro Dalcin                                        NULL,
2802f4259b30SLisandro Dalcin                                        NULL,
2803f4259b30SLisandro Dalcin                                        /* 54*/ NULL,
2804f4259b30SLisandro Dalcin                                        NULL,
2805f4259b30SLisandro Dalcin                                        NULL,
2806f4259b30SLisandro Dalcin                                        NULL,
2807f4259b30SLisandro Dalcin                                        NULL,
2808023c16fcSToby Isaac                                        /* 59*/ MatCreateSubMatrix_SeqDense,
2809e03a110bSBarry Smith                                        MatDestroy_SeqDense,
2810e03a110bSBarry Smith                                        MatView_SeqDense,
2811f4259b30SLisandro Dalcin                                        NULL,
2812f4259b30SLisandro Dalcin                                        NULL,
2813f4259b30SLisandro Dalcin                                        /* 64*/ NULL,
2814f4259b30SLisandro Dalcin                                        NULL,
2815f4259b30SLisandro Dalcin                                        NULL,
2816f4259b30SLisandro Dalcin                                        NULL,
2817f4259b30SLisandro Dalcin                                        NULL,
2818d519adbfSMatthew Knepley                                        /* 69*/ MatGetRowMaxAbs_SeqDense,
2819f4259b30SLisandro Dalcin                                        NULL,
2820f4259b30SLisandro Dalcin                                        NULL,
2821f4259b30SLisandro Dalcin                                        NULL,
2822f4259b30SLisandro Dalcin                                        NULL,
2823f4259b30SLisandro Dalcin                                        /* 74*/ NULL,
2824f4259b30SLisandro Dalcin                                        NULL,
2825f4259b30SLisandro Dalcin                                        NULL,
2826f4259b30SLisandro Dalcin                                        NULL,
2827f4259b30SLisandro Dalcin                                        NULL,
2828f4259b30SLisandro Dalcin                                        /* 79*/ NULL,
2829f4259b30SLisandro Dalcin                                        NULL,
2830f4259b30SLisandro Dalcin                                        NULL,
2831f4259b30SLisandro Dalcin                                        NULL,
28325bba2384SShri Abhyankar                                        /* 83*/ MatLoad_SeqDense,
2833637a0070SStefano Zampini                                        MatIsSymmetric_SeqDense,
28341cbb95d3SBarry Smith                                        MatIsHermitian_SeqDense,
2835f4259b30SLisandro Dalcin                                        NULL,
2836f4259b30SLisandro Dalcin                                        NULL,
2837f4259b30SLisandro Dalcin                                        NULL,
2838f4259b30SLisandro Dalcin                                        /* 89*/ NULL,
2839f4259b30SLisandro Dalcin                                        NULL,
2840a9fe9ddaSSatish Balay                                        MatMatMultNumeric_SeqDense_SeqDense,
2841f4259b30SLisandro Dalcin                                        NULL,
2842f4259b30SLisandro Dalcin                                        NULL,
2843f4259b30SLisandro Dalcin                                        /* 94*/ NULL,
2844f4259b30SLisandro Dalcin                                        NULL,
2845f4259b30SLisandro Dalcin                                        NULL,
284669f65d41SStefano Zampini                                        MatMatTransposeMultNumeric_SeqDense_SeqDense,
2847f4259b30SLisandro Dalcin                                        NULL,
28484222ddf1SHong Zhang                                        /* 99*/ MatProductSetFromOptions_SeqDense,
2849f4259b30SLisandro Dalcin                                        NULL,
2850f4259b30SLisandro Dalcin                                        NULL,
2851ba337c44SJed Brown                                        MatConjugate_SeqDense,
2852f4259b30SLisandro Dalcin                                        NULL,
2853f4259b30SLisandro Dalcin                                        /*104*/ NULL,
2854ba337c44SJed Brown                                        MatRealPart_SeqDense,
2855ba337c44SJed Brown                                        MatImaginaryPart_SeqDense,
2856f4259b30SLisandro Dalcin                                        NULL,
2857f4259b30SLisandro Dalcin                                        NULL,
2858f4259b30SLisandro Dalcin                                        /*109*/ NULL,
2859f4259b30SLisandro Dalcin                                        NULL,
28608d0534beSBarry Smith                                        MatGetRowMin_SeqDense,
2861aabbc4fbSShri Abhyankar                                        MatGetColumnVector_SeqDense,
28623b49f96aSBarry Smith                                        MatMissingDiagonal_SeqDense,
2863f4259b30SLisandro Dalcin                                        /*114*/ NULL,
2864f4259b30SLisandro Dalcin                                        NULL,
2865f4259b30SLisandro Dalcin                                        NULL,
2866f4259b30SLisandro Dalcin                                        NULL,
2867f4259b30SLisandro Dalcin                                        NULL,
2868f4259b30SLisandro Dalcin                                        /*119*/ NULL,
2869f4259b30SLisandro Dalcin                                        NULL,
2870f4259b30SLisandro Dalcin                                        NULL,
2871f4259b30SLisandro Dalcin                                        NULL,
2872f4259b30SLisandro Dalcin                                        NULL,
2873f4259b30SLisandro Dalcin                                        /*124*/ NULL,
2874a873a8cdSSam Reynolds                                        MatGetColumnReductions_SeqDense,
2875f4259b30SLisandro Dalcin                                        NULL,
2876f4259b30SLisandro Dalcin                                        NULL,
2877f4259b30SLisandro Dalcin                                        NULL,
2878f4259b30SLisandro Dalcin                                        /*129*/ NULL,
2879f4259b30SLisandro Dalcin                                        NULL,
2880f4259b30SLisandro Dalcin                                        NULL,
288175648e8dSHong Zhang                                        MatTransposeMatMultNumeric_SeqDense_SeqDense,
2882f4259b30SLisandro Dalcin                                        NULL,
2883f4259b30SLisandro Dalcin                                        /*134*/ NULL,
2884f4259b30SLisandro Dalcin                                        NULL,
2885f4259b30SLisandro Dalcin                                        NULL,
2886f4259b30SLisandro Dalcin                                        NULL,
2887f4259b30SLisandro Dalcin                                        NULL,
2888f4259b30SLisandro Dalcin                                        /*139*/ NULL,
2889f4259b30SLisandro Dalcin                                        NULL,
2890f4259b30SLisandro Dalcin                                        NULL,
2891f4259b30SLisandro Dalcin                                        NULL,
2892f4259b30SLisandro Dalcin                                        NULL,
28934222ddf1SHong Zhang                                        MatCreateMPIMatConcatenateSeqMat_SeqDense,
2894f4259b30SLisandro Dalcin                                        /*145*/ NULL,
2895f4259b30SLisandro Dalcin                                        NULL,
289699a7f59eSMark Adams                                        NULL,
289799a7f59eSMark Adams                                        NULL,
28987fb60732SBarry Smith                                        NULL,
28999371c9d4SSatish Balay                                        /*150*/ NULL};
290090ace30eSBarry Smith 
29014b828684SBarry Smith /*@C
290211a5261eSBarry Smith    MatCreateSeqDense - Creates a `MATSEQDENSE` that
2903d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
2904d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
2905289bc588SBarry Smith 
2906d083f849SBarry Smith    Collective
2907db81eaa0SLois Curfman McInnes 
290820563c6bSBarry Smith    Input Parameters:
290911a5261eSBarry Smith +  comm - MPI communicator, set to `PETSC_COMM_SELF`
29100c775827SLois Curfman McInnes .  m - number of rows
291118f449edSLois Curfman McInnes .  n - number of columns
29120298fd71SBarry Smith -  data - optional location of matrix data in column major order.  Set data=NULL for PETSc
2913dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
291420563c6bSBarry Smith 
291520563c6bSBarry Smith    Output Parameter:
291644cd7ae7SLois Curfman McInnes .  A - the matrix
291720563c6bSBarry Smith 
291811a5261eSBarry Smith    Note:
291918f449edSLois Curfman McInnes    The data input variable is intended primarily for Fortran programmers
292018f449edSLois Curfman McInnes    who wish to allocate their own matrix memory space.  Most users should
29210298fd71SBarry Smith    set data=NULL.
292218f449edSLois Curfman McInnes 
2923027ccd11SLois Curfman McInnes    Level: intermediate
2924027ccd11SLois Curfman McInnes 
292511a5261eSBarry Smith .seealso: `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()`
292620563c6bSBarry Smith @*/
29279371c9d4SSatish Balay PetscErrorCode MatCreateSeqDense(MPI_Comm comm, PetscInt m, PetscInt n, PetscScalar *data, Mat *A) {
29283a40ed3dSBarry Smith   PetscFunctionBegin;
29299566063dSJacob Faibussowitsch   PetscCall(MatCreate(comm, A));
29309566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*A, m, n, m, n));
29319566063dSJacob Faibussowitsch   PetscCall(MatSetType(*A, MATSEQDENSE));
29329566063dSJacob Faibussowitsch   PetscCall(MatSeqDenseSetPreallocation(*A, data));
2933273d9f13SBarry Smith   PetscFunctionReturn(0);
2934273d9f13SBarry Smith }
2935273d9f13SBarry Smith 
2936273d9f13SBarry Smith /*@C
293711a5261eSBarry Smith    MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements of a `MATSEQDENSE` matrix
2938273d9f13SBarry Smith 
2939d083f849SBarry Smith    Collective
2940273d9f13SBarry Smith 
2941273d9f13SBarry Smith    Input Parameters:
29421c4f3114SJed Brown +  B - the matrix
29430298fd71SBarry Smith -  data - the array (or NULL)
2944273d9f13SBarry Smith 
294511a5261eSBarry Smith    Note:
2946273d9f13SBarry Smith    The data input variable is intended primarily for Fortran programmers
2947273d9f13SBarry Smith    who wish to allocate their own matrix memory space.  Most users should
2948284134d9SBarry Smith    need not call this routine.
2949273d9f13SBarry Smith 
2950273d9f13SBarry Smith    Level: intermediate
2951273d9f13SBarry Smith 
295211a5261eSBarry Smith .seealso: `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()`, `MatDenseSetLDA()`
2953273d9f13SBarry Smith @*/
29549371c9d4SSatish Balay PetscErrorCode MatSeqDenseSetPreallocation(Mat B, PetscScalar data[]) {
2955a23d5eceSKris Buschelman   PetscFunctionBegin;
2956d5ea218eSStefano Zampini   PetscValidHeaderSpecific(B, MAT_CLASSID, 1);
2957cac4c232SBarry Smith   PetscTryMethod(B, "MatSeqDenseSetPreallocation_C", (Mat, PetscScalar[]), (B, data));
2958a23d5eceSKris Buschelman   PetscFunctionReturn(0);
2959a23d5eceSKris Buschelman }
2960a23d5eceSKris Buschelman 
29619371c9d4SSatish Balay PetscErrorCode MatSeqDenseSetPreallocation_SeqDense(Mat B, PetscScalar *data) {
2962ad16ce7aSStefano Zampini   Mat_SeqDense *b = (Mat_SeqDense *)B->data;
2963273d9f13SBarry Smith 
2964273d9f13SBarry Smith   PetscFunctionBegin;
296528b400f6SJacob Faibussowitsch   PetscCheck(!b->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
2966273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
2967a868139aSShri Abhyankar 
29689566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(B->rmap));
29699566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(B->cmap));
297034ef9618SShri Abhyankar 
2971ad16ce7aSStefano Zampini   if (b->lda <= 0) b->lda = B->rmap->n;
297286d161a7SShri Abhyankar 
29739e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
29749566063dSJacob Faibussowitsch     if (!b->user_alloc) PetscCall(PetscFree(b->v));
29759566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1((size_t)b->lda * B->cmap->n, &b->v));
29769566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)B, b->lda * B->cmap->n * sizeof(PetscScalar)));
29772205254eSKarl Rupp 
29789e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
2979273d9f13SBarry Smith   } else { /* user-allocated storage */
29809566063dSJacob Faibussowitsch     if (!b->user_alloc) PetscCall(PetscFree(b->v));
2981273d9f13SBarry Smith     b->v          = data;
2982273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
2983273d9f13SBarry Smith   }
29840450473dSBarry Smith   B->assembled = PETSC_TRUE;
2985273d9f13SBarry Smith   PetscFunctionReturn(0);
2986273d9f13SBarry Smith }
2987273d9f13SBarry Smith 
298865b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
29899371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) {
2990d77f618aSHong Zhang   Mat                mat_elemental;
29911683a169SBarry Smith   const PetscScalar *array;
29921683a169SBarry Smith   PetscScalar       *v_colwise;
2993d77f618aSHong Zhang   PetscInt           M = A->rmap->N, N = A->cmap->N, i, j, k, *rows, *cols;
2994d77f618aSHong Zhang 
29958baccfbdSHong Zhang   PetscFunctionBegin;
29969566063dSJacob Faibussowitsch   PetscCall(PetscMalloc3(M * N, &v_colwise, M, &rows, N, &cols));
29979566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &array));
2998d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
2999d77f618aSHong Zhang   k = 0;
3000d77f618aSHong Zhang   for (j = 0; j < N; j++) {
3001d77f618aSHong Zhang     cols[j] = j;
3002ad540459SPierre Jolivet     for (i = 0; i < M; i++) v_colwise[j * M + i] = array[k++];
3003d77f618aSHong Zhang   }
3004ad540459SPierre Jolivet   for (i = 0; i < M; i++) rows[i] = i;
30059566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &array));
3006d77f618aSHong Zhang 
30079566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental));
30089566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(mat_elemental, PETSC_DECIDE, PETSC_DECIDE, M, N));
30099566063dSJacob Faibussowitsch   PetscCall(MatSetType(mat_elemental, MATELEMENTAL));
30109566063dSJacob Faibussowitsch   PetscCall(MatSetUp(mat_elemental));
3011d77f618aSHong Zhang 
3012d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
30139566063dSJacob Faibussowitsch   PetscCall(MatSetValues(mat_elemental, M, rows, N, cols, v_colwise, ADD_VALUES));
30149566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY));
30159566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY));
30169566063dSJacob Faibussowitsch   PetscCall(PetscFree3(v_colwise, rows, cols));
3017d77f618aSHong Zhang 
3018511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
30199566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A, &mat_elemental));
3020d77f618aSHong Zhang   } else {
3021d77f618aSHong Zhang     *newmat = mat_elemental;
3022d77f618aSHong Zhang   }
30238baccfbdSHong Zhang   PetscFunctionReturn(0);
30248baccfbdSHong Zhang }
302565b80a83SHong Zhang #endif
30268baccfbdSHong Zhang 
30279371c9d4SSatish Balay PetscErrorCode MatDenseSetLDA_SeqDense(Mat B, PetscInt lda) {
30281b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense *)B->data;
30297422da62SJose E. Roman   PetscBool     data;
303021a2c019SBarry Smith 
30311b807ce4Svictorle   PetscFunctionBegin;
30327422da62SJose E. Roman   data = (PetscBool)((B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE);
3033aed4548fSBarry Smith   PetscCheck(b->user_alloc || !data || b->lda == lda, PETSC_COMM_SELF, PETSC_ERR_ORDER, "LDA cannot be changed after allocation of internal storage");
303408401ef6SPierre 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);
30351b807ce4Svictorle   b->lda = lda;
30361b807ce4Svictorle   PetscFunctionReturn(0);
30371b807ce4Svictorle }
30381b807ce4Svictorle 
30399371c9d4SSatish Balay PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm, Mat inmat, PetscInt n, MatReuse scall, Mat *outmat) {
3040d528f656SJakub Kruzik   PetscFunctionBegin;
30419566063dSJacob Faibussowitsch   PetscCall(MatCreateMPIMatConcatenateSeqMat_MPIDense(comm, inmat, n, scall, outmat));
3042d528f656SJakub Kruzik   PetscFunctionReturn(0);
3043d528f656SJakub Kruzik }
3044d528f656SJakub Kruzik 
30459371c9d4SSatish Balay PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A, PetscInt col, Vec *v) {
30466947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
30476947451fSStefano Zampini 
30486947451fSStefano Zampini   PetscFunctionBegin;
304928b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
305028b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
30516947451fSStefano Zampini   if (!a->cvec) {
30529566063dSJacob Faibussowitsch     PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec));
30539566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)A, (PetscObject)a->cvec));
30546947451fSStefano Zampini   }
30556947451fSStefano Zampini   a->vecinuse = col + 1;
30569566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, (PetscScalar **)&a->ptrinuse));
30579566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda));
30586947451fSStefano Zampini   *v = a->cvec;
30596947451fSStefano Zampini   PetscFunctionReturn(0);
30606947451fSStefano Zampini }
30616947451fSStefano Zampini 
30629371c9d4SSatish Balay PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A, PetscInt col, Vec *v) {
30636947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
30646947451fSStefano Zampini 
30656947451fSStefano Zampini   PetscFunctionBegin;
306628b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first");
306728b400f6SJacob Faibussowitsch   PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector");
30686947451fSStefano Zampini   a->vecinuse = 0;
30699566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, (PetscScalar **)&a->ptrinuse));
30709566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
307175f6d85dSStefano Zampini   if (v) *v = NULL;
30726947451fSStefano Zampini   PetscFunctionReturn(0);
30736947451fSStefano Zampini }
30746947451fSStefano Zampini 
30759371c9d4SSatish Balay PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v) {
30766947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
30776947451fSStefano Zampini 
30786947451fSStefano Zampini   PetscFunctionBegin;
307928b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
308028b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
30816947451fSStefano Zampini   if (!a->cvec) {
30829566063dSJacob Faibussowitsch     PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec));
30839566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)A, (PetscObject)a->cvec));
30846947451fSStefano Zampini   }
30856947451fSStefano Zampini   a->vecinuse = col + 1;
30869566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &a->ptrinuse));
30879566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda));
30889566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(a->cvec));
30896947451fSStefano Zampini   *v = a->cvec;
30906947451fSStefano Zampini   PetscFunctionReturn(0);
30916947451fSStefano Zampini }
30926947451fSStefano Zampini 
30939371c9d4SSatish Balay PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v) {
30946947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
30956947451fSStefano Zampini 
30966947451fSStefano Zampini   PetscFunctionBegin;
309728b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first");
309828b400f6SJacob Faibussowitsch   PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector");
30996947451fSStefano Zampini   a->vecinuse = 0;
31009566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &a->ptrinuse));
31019566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(a->cvec));
31029566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
310375f6d85dSStefano Zampini   if (v) *v = NULL;
31046947451fSStefano Zampini   PetscFunctionReturn(0);
31056947451fSStefano Zampini }
31066947451fSStefano Zampini 
31079371c9d4SSatish Balay PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v) {
31086947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
31096947451fSStefano Zampini 
31106947451fSStefano Zampini   PetscFunctionBegin;
311128b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
311228b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
31136947451fSStefano Zampini   if (!a->cvec) {
31149566063dSJacob Faibussowitsch     PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec));
31159566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)A, (PetscObject)a->cvec));
31166947451fSStefano Zampini   }
31176947451fSStefano Zampini   a->vecinuse = col + 1;
31189566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(A, (PetscScalar **)&a->ptrinuse));
31199566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda));
31206947451fSStefano Zampini   *v = a->cvec;
31216947451fSStefano Zampini   PetscFunctionReturn(0);
31226947451fSStefano Zampini }
31236947451fSStefano Zampini 
31249371c9d4SSatish Balay PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v) {
31256947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
31266947451fSStefano Zampini 
31276947451fSStefano Zampini   PetscFunctionBegin;
312828b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first");
312928b400f6SJacob Faibussowitsch   PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector");
31306947451fSStefano Zampini   a->vecinuse = 0;
31319566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(A, (PetscScalar **)&a->ptrinuse));
31329566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
313375f6d85dSStefano Zampini   if (v) *v = NULL;
31346947451fSStefano Zampini   PetscFunctionReturn(0);
31356947451fSStefano Zampini }
31366947451fSStefano Zampini 
31379371c9d4SSatish Balay PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) {
31385ea7661aSPierre Jolivet   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
31395ea7661aSPierre Jolivet 
31405ea7661aSPierre Jolivet   PetscFunctionBegin;
314128b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
314228b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
3143a2748737SPierre Jolivet   if (a->cmat && (cend - cbegin != a->cmat->cmap->N || rend - rbegin != a->cmat->rmap->N)) PetscCall(MatDestroy(&a->cmat));
31445ea7661aSPierre Jolivet   if (!a->cmat) {
3145a2748737SPierre Jolivet     PetscCall(MatCreateDense(PetscObjectComm((PetscObject)A), rend - rbegin, PETSC_DECIDE, rend - rbegin, cend - cbegin, a->v + rbegin + (size_t)cbegin * a->lda, &a->cmat));
31469566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)A, (PetscObject)a->cmat));
31475ea7661aSPierre Jolivet   } else {
3148a2748737SPierre Jolivet     PetscCall(MatDensePlaceArray(a->cmat, a->v + rbegin + (size_t)cbegin * a->lda));
31495ea7661aSPierre Jolivet   }
31509566063dSJacob Faibussowitsch   PetscCall(MatDenseSetLDA(a->cmat, a->lda));
31515ea7661aSPierre Jolivet   a->matinuse = cbegin + 1;
31525ea7661aSPierre Jolivet   *v          = a->cmat;
315375f6d85dSStefano Zampini #if defined(PETSC_HAVE_CUDA)
315475f6d85dSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
315575f6d85dSStefano Zampini #endif
31565ea7661aSPierre Jolivet   PetscFunctionReturn(0);
31575ea7661aSPierre Jolivet }
31585ea7661aSPierre Jolivet 
31599371c9d4SSatish Balay PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A, Mat *v) {
31605ea7661aSPierre Jolivet   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
31615ea7661aSPierre Jolivet 
31625ea7661aSPierre Jolivet   PetscFunctionBegin;
316328b400f6SJacob Faibussowitsch   PetscCheck(a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetSubMatrix() first");
316428b400f6SJacob Faibussowitsch   PetscCheck(a->cmat, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column matrix");
316508401ef6SPierre Jolivet   PetscCheck(*v == a->cmat, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not the matrix obtained from MatDenseGetSubMatrix()");
31665ea7661aSPierre Jolivet   a->matinuse = 0;
31679566063dSJacob Faibussowitsch   PetscCall(MatDenseResetArray(a->cmat));
3168742765d3SMatthew Knepley   if (v) *v = NULL;
3169*3faff063SStefano Zampini #if defined(PETSC_HAVE_CUDA)
3170*3faff063SStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
3171*3faff063SStefano Zampini #endif
31725ea7661aSPierre Jolivet   PetscFunctionReturn(0);
31735ea7661aSPierre Jolivet }
31745ea7661aSPierre Jolivet 
31750bad9183SKris Buschelman /*MC
3176fafad747SKris Buschelman    MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices.
31770bad9183SKris Buschelman 
31780bad9183SKris Buschelman    Options Database Keys:
317911a5261eSBarry Smith . -mat_type seqdense - sets the matrix type to `MATSEQDENSE` during a call to `MatSetFromOptions()`
31800bad9183SKris Buschelman 
31810bad9183SKris Buschelman   Level: beginner
31820bad9183SKris Buschelman 
318311a5261eSBarry Smith .seealso: `MATSEQDENSE`, `MatCreateSeqDense()`
31840bad9183SKris Buschelman M*/
31859371c9d4SSatish Balay PetscErrorCode MatCreate_SeqDense(Mat B) {
3186273d9f13SBarry Smith   Mat_SeqDense *b;
31877c334f02SBarry Smith   PetscMPIInt   size;
3188273d9f13SBarry Smith 
3189273d9f13SBarry Smith   PetscFunctionBegin;
31909566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)B), &size));
319108401ef6SPierre Jolivet   PetscCheck(size <= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Comm must be of size 1");
319255659b69SBarry Smith 
31939566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(B, &b));
31949566063dSJacob Faibussowitsch   PetscCall(PetscMemcpy(B->ops, &MatOps_Values, sizeof(struct _MatOps)));
319544cd7ae7SLois Curfman McInnes   B->data = (void *)b;
319618f449edSLois Curfman McInnes 
3197273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
31984e220ebcSLois Curfman McInnes 
31999566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatQRFactor_C", MatQRFactor_SeqDense));
32009566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetLDA_C", MatDenseGetLDA_SeqDense));
32019566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseSetLDA_C", MatDenseSetLDA_SeqDense));
32029566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArray_C", MatDenseGetArray_SeqDense));
32039566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArray_C", MatDenseRestoreArray_SeqDense));
32049566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDensePlaceArray_C", MatDensePlaceArray_SeqDense));
32059566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseResetArray_C", MatDenseResetArray_SeqDense));
32069566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseReplaceArray_C", MatDenseReplaceArray_SeqDense));
32079566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayRead_C", MatDenseGetArray_SeqDense));
32089566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayRead_C", MatDenseRestoreArray_SeqDense));
32099566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayWrite_C", MatDenseGetArray_SeqDense));
32109566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayWrite_C", MatDenseRestoreArray_SeqDense));
32119566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqaij_C", MatConvert_SeqDense_SeqAIJ));
32128baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
32139566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_elemental_C", MatConvert_SeqDense_Elemental));
32148baccfbdSHong Zhang #endif
3215d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
32169566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_scalapack_C", MatConvert_Dense_ScaLAPACK));
3217d24d4204SJose E. Roman #endif
32182bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
32199566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensecuda_C", MatConvert_SeqDense_SeqDenseCUDA));
32209566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", MatProductSetFromOptions_SeqDense));
32219566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdense_C", MatProductSetFromOptions_SeqDense));
32229566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensecuda_C", MatProductSetFromOptions_SeqDense));
32232bf066beSStefano Zampini #endif
32249566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSeqDenseSetPreallocation_C", MatSeqDenseSetPreallocation_SeqDense));
32259566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqaij_seqdense_C", MatProductSetFromOptions_SeqAIJ_SeqDense));
32269566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdense_C", MatProductSetFromOptions_SeqDense));
32279566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense));
32289566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqsbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense));
322996e6d5c4SRichard Tran Mills 
32309566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumn_C", MatDenseGetColumn_SeqDense));
32319566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumn_C", MatDenseRestoreColumn_SeqDense));
32329566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVec_C", MatDenseGetColumnVec_SeqDense));
32339566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVec_C", MatDenseRestoreColumnVec_SeqDense));
32349566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecRead_C", MatDenseGetColumnVecRead_SeqDense));
32359566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecRead_C", MatDenseRestoreColumnVecRead_SeqDense));
32369566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecWrite_C", MatDenseGetColumnVecWrite_SeqDense));
32379566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecWrite_C", MatDenseRestoreColumnVecWrite_SeqDense));
32389566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetSubMatrix_C", MatDenseGetSubMatrix_SeqDense));
32399566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreSubMatrix_C", MatDenseRestoreSubMatrix_SeqDense));
32409566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)B, MATSEQDENSE));
32413a40ed3dSBarry Smith   PetscFunctionReturn(0);
3242289bc588SBarry Smith }
324386aefd0dSHong Zhang 
324486aefd0dSHong Zhang /*@C
324511a5261eSBarry 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.
324686aefd0dSHong Zhang 
324786aefd0dSHong Zhang    Not Collective
324886aefd0dSHong Zhang 
32495ea7661aSPierre Jolivet    Input Parameters:
325011a5261eSBarry Smith +  mat - a `MATSEQDENSE` or `MATMPIDENSE` matrix
325186aefd0dSHong Zhang -  col - column index
325286aefd0dSHong Zhang 
325386aefd0dSHong Zhang    Output Parameter:
325486aefd0dSHong Zhang .  vals - pointer to the data
325586aefd0dSHong Zhang 
325686aefd0dSHong Zhang    Level: intermediate
325786aefd0dSHong Zhang 
325811a5261eSBarry Smith    Note:
325911a5261eSBarry Smith    Use `MatDenseGetColumnVec()` to get access to a column of a `MATDENSE` treated as a `Vec`
326011a5261eSBarry Smith 
326111a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreColumn()`, `MatDenseGetColumnVec()`
326286aefd0dSHong Zhang @*/
32639371c9d4SSatish Balay PetscErrorCode MatDenseGetColumn(Mat A, PetscInt col, PetscScalar **vals) {
326486aefd0dSHong Zhang   PetscFunctionBegin;
3265d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
3266d5ea218eSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
3267d5ea218eSStefano Zampini   PetscValidPointer(vals, 3);
3268cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumn_C", (Mat, PetscInt, PetscScalar **), (A, col, vals));
326986aefd0dSHong Zhang   PetscFunctionReturn(0);
327086aefd0dSHong Zhang }
327186aefd0dSHong Zhang 
327286aefd0dSHong Zhang /*@C
327311a5261eSBarry Smith    MatDenseRestoreColumn - returns access to a column of a `MATDENSE` matrix which is returned by `MatDenseGetColumn()`.
327486aefd0dSHong Zhang 
327586aefd0dSHong Zhang    Not Collective
327686aefd0dSHong Zhang 
3277742765d3SMatthew Knepley    Input Parameters:
327811a5261eSBarry Smith +  mat - a `MATSEQDENSE` or `MATMPIDENSE` matrix
3279742765d3SMatthew Knepley -  vals - pointer to the data (may be NULL)
328086aefd0dSHong Zhang 
328186aefd0dSHong Zhang    Level: intermediate
328286aefd0dSHong Zhang 
328311a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetColumn()`
328486aefd0dSHong Zhang @*/
32859371c9d4SSatish Balay PetscErrorCode MatDenseRestoreColumn(Mat A, PetscScalar **vals) {
328686aefd0dSHong Zhang   PetscFunctionBegin;
3287d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
3288d5ea218eSStefano Zampini   PetscValidPointer(vals, 2);
3289cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumn_C", (Mat, PetscScalar **), (A, vals));
329086aefd0dSHong Zhang   PetscFunctionReturn(0);
329186aefd0dSHong Zhang }
32926947451fSStefano Zampini 
32930f74d2c1SSatish Balay /*@
329411a5261eSBarry Smith    MatDenseGetColumnVec - Gives read-write access to a column of a `MATDENSE` matrix, represented as a `Vec`.
32956947451fSStefano Zampini 
32966947451fSStefano Zampini    Collective
32976947451fSStefano Zampini 
32985ea7661aSPierre Jolivet    Input Parameters:
329911a5261eSBarry Smith +  mat - the `Mat` object
33006947451fSStefano Zampini -  col - the column index
33016947451fSStefano Zampini 
33026947451fSStefano Zampini    Output Parameter:
33036947451fSStefano Zampini .  v - the vector
33046947451fSStefano Zampini 
33056947451fSStefano Zampini    Notes:
330611a5261eSBarry Smith      The vector is owned by PETSc. Users need to call `MatDenseRestoreColumnVec()` when the vector is no longer needed.
330711a5261eSBarry Smith 
330811a5261eSBarry Smith      Use `MatDenseGetColumnVecRead()` to obtain read-only access or `MatDenseGetColumnVecWrite()` for write-only access.
33096947451fSStefano Zampini 
33106947451fSStefano Zampini    Level: intermediate
33116947451fSStefano Zampini 
331211a5261eSBarry Smith .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`, `MatDenseGetColumn()`
33136947451fSStefano Zampini @*/
33149371c9d4SSatish Balay PetscErrorCode MatDenseGetColumnVec(Mat A, PetscInt col, Vec *v) {
33156947451fSStefano Zampini   PetscFunctionBegin;
33166947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
33176947451fSStefano Zampini   PetscValidType(A, 1);
33186947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
33196947451fSStefano Zampini   PetscValidPointer(v, 3);
332028b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
33212cf15c64SPierre 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);
3322cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v));
33236947451fSStefano Zampini   PetscFunctionReturn(0);
33246947451fSStefano Zampini }
33256947451fSStefano Zampini 
33260f74d2c1SSatish Balay /*@
33276947451fSStefano Zampini    MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVec().
33286947451fSStefano Zampini 
33296947451fSStefano Zampini    Collective
33306947451fSStefano Zampini 
33315ea7661aSPierre Jolivet    Input Parameters:
33326947451fSStefano Zampini +  mat - the Mat object
33336947451fSStefano Zampini .  col - the column index
3334742765d3SMatthew Knepley -  v - the Vec object (may be NULL)
33356947451fSStefano Zampini 
33366947451fSStefano Zampini    Level: intermediate
33376947451fSStefano Zampini 
3338db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
33396947451fSStefano Zampini @*/
33409371c9d4SSatish Balay PetscErrorCode MatDenseRestoreColumnVec(Mat A, PetscInt col, Vec *v) {
33416947451fSStefano Zampini   PetscFunctionBegin;
33426947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
33436947451fSStefano Zampini   PetscValidType(A, 1);
33446947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
334508401ef6SPierre Jolivet   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
33462cf15c64SPierre 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);
3347cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v));
33486947451fSStefano Zampini   PetscFunctionReturn(0);
33496947451fSStefano Zampini }
33506947451fSStefano Zampini 
33510f74d2c1SSatish Balay /*@
33526947451fSStefano Zampini    MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a Vec.
33536947451fSStefano Zampini 
33546947451fSStefano Zampini    Collective
33556947451fSStefano Zampini 
33565ea7661aSPierre Jolivet    Input Parameters:
33576947451fSStefano Zampini +  mat - the Mat object
33586947451fSStefano Zampini -  col - the column index
33596947451fSStefano Zampini 
33606947451fSStefano Zampini    Output Parameter:
33616947451fSStefano Zampini .  v - the vector
33626947451fSStefano Zampini 
33636947451fSStefano Zampini    Notes:
33646947451fSStefano Zampini      The vector is owned by PETSc and users cannot modify it.
336511a5261eSBarry Smith 
33666947451fSStefano Zampini      Users need to call MatDenseRestoreColumnVecRead() when the vector is no longer needed.
336711a5261eSBarry Smith 
33686947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecWrite() for write-only access.
33696947451fSStefano Zampini 
33706947451fSStefano Zampini    Level: intermediate
33716947451fSStefano Zampini 
3372db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
33736947451fSStefano Zampini @*/
33749371c9d4SSatish Balay PetscErrorCode MatDenseGetColumnVecRead(Mat A, PetscInt col, Vec *v) {
33756947451fSStefano Zampini   PetscFunctionBegin;
33766947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
33776947451fSStefano Zampini   PetscValidType(A, 1);
33786947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
33796947451fSStefano Zampini   PetscValidPointer(v, 3);
338028b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
33812cf15c64SPierre 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);
3382cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v));
33836947451fSStefano Zampini   PetscFunctionReturn(0);
33846947451fSStefano Zampini }
33856947451fSStefano Zampini 
33860f74d2c1SSatish Balay /*@
33876947451fSStefano Zampini    MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecRead().
33886947451fSStefano Zampini 
33896947451fSStefano Zampini    Collective
33906947451fSStefano Zampini 
33915ea7661aSPierre Jolivet    Input Parameters:
33926947451fSStefano Zampini +  mat - the Mat object
33936947451fSStefano Zampini .  col - the column index
3394742765d3SMatthew Knepley -  v - the Vec object (may be NULL)
33956947451fSStefano Zampini 
33966947451fSStefano Zampini    Level: intermediate
33976947451fSStefano Zampini 
3398db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecWrite()`
33996947451fSStefano Zampini @*/
34009371c9d4SSatish Balay PetscErrorCode MatDenseRestoreColumnVecRead(Mat A, PetscInt col, Vec *v) {
34016947451fSStefano Zampini   PetscFunctionBegin;
34026947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
34036947451fSStefano Zampini   PetscValidType(A, 1);
34046947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
340508401ef6SPierre Jolivet   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
34062cf15c64SPierre 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);
3407cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v));
34086947451fSStefano Zampini   PetscFunctionReturn(0);
34096947451fSStefano Zampini }
34106947451fSStefano Zampini 
34110f74d2c1SSatish Balay /*@
34126947451fSStefano Zampini    MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a Vec.
34136947451fSStefano Zampini 
34146947451fSStefano Zampini    Collective
34156947451fSStefano Zampini 
34165ea7661aSPierre Jolivet    Input Parameters:
34176947451fSStefano Zampini +  mat - the Mat object
34186947451fSStefano Zampini -  col - the column index
34196947451fSStefano Zampini 
34206947451fSStefano Zampini    Output Parameter:
34216947451fSStefano Zampini .  v - the vector
34226947451fSStefano Zampini 
34236947451fSStefano Zampini    Notes:
34246947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVecWrite() when the vector is no longer needed.
342511a5261eSBarry Smith 
34266947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecRead() for read-only access.
34276947451fSStefano Zampini 
34286947451fSStefano Zampini    Level: intermediate
34296947451fSStefano Zampini 
3430db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
34316947451fSStefano Zampini @*/
34329371c9d4SSatish Balay PetscErrorCode MatDenseGetColumnVecWrite(Mat A, PetscInt col, Vec *v) {
34336947451fSStefano Zampini   PetscFunctionBegin;
34346947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
34356947451fSStefano Zampini   PetscValidType(A, 1);
34366947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
34376947451fSStefano Zampini   PetscValidPointer(v, 3);
343828b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
3439aed4548fSBarry 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);
3440cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v));
34416947451fSStefano Zampini   PetscFunctionReturn(0);
34426947451fSStefano Zampini }
34436947451fSStefano Zampini 
34440f74d2c1SSatish Balay /*@
34456947451fSStefano Zampini    MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecWrite().
34466947451fSStefano Zampini 
34476947451fSStefano Zampini    Collective
34486947451fSStefano Zampini 
34495ea7661aSPierre Jolivet    Input Parameters:
34506947451fSStefano Zampini +  mat - the Mat object
34516947451fSStefano Zampini .  col - the column index
3452742765d3SMatthew Knepley -  v - the Vec object (may be NULL)
34536947451fSStefano Zampini 
34546947451fSStefano Zampini    Level: intermediate
34556947451fSStefano Zampini 
3456db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`
34576947451fSStefano Zampini @*/
34589371c9d4SSatish Balay PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A, PetscInt col, Vec *v) {
34596947451fSStefano Zampini   PetscFunctionBegin;
34606947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
34616947451fSStefano Zampini   PetscValidType(A, 1);
34626947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
346308401ef6SPierre Jolivet   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
3464aed4548fSBarry 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);
3465cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v));
34666947451fSStefano Zampini   PetscFunctionReturn(0);
34676947451fSStefano Zampini }
34685ea7661aSPierre Jolivet 
34690f74d2c1SSatish Balay /*@
3470a2748737SPierre Jolivet    MatDenseGetSubMatrix - Gives access to a block of rows and columns of a dense matrix, represented as a Mat.
34715ea7661aSPierre Jolivet 
34725ea7661aSPierre Jolivet    Collective
34735ea7661aSPierre Jolivet 
34745ea7661aSPierre Jolivet    Input Parameters:
34755ea7661aSPierre Jolivet +  mat - the Mat object
3476a2748737SPierre Jolivet .  rbegin - the first global row index in the block (if PETSC_DECIDE, is 0)
3477a2748737SPierre Jolivet .  rend - the global row index past the last one in the block (if PETSC_DECIDE, is M)
3478a2748737SPierre Jolivet .  cbegin - the first global column index in the block (if PETSC_DECIDE, is 0)
3479a2748737SPierre Jolivet -  cend - the global column index past the last one in the block (if PETSC_DECIDE, is N)
34805ea7661aSPierre Jolivet 
34815ea7661aSPierre Jolivet    Output Parameter:
34825ea7661aSPierre Jolivet .  v - the matrix
34835ea7661aSPierre Jolivet 
34845ea7661aSPierre Jolivet    Notes:
34855ea7661aSPierre Jolivet      The matrix is owned by PETSc. Users need to call MatDenseRestoreSubMatrix() when the matrix is no longer needed.
348611a5261eSBarry Smith 
3487a2748737SPierre 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.
34885ea7661aSPierre Jolivet 
34895ea7661aSPierre Jolivet    Level: intermediate
34905ea7661aSPierre Jolivet 
3491db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreSubMatrix()`
34925ea7661aSPierre Jolivet @*/
34939371c9d4SSatish Balay PetscErrorCode MatDenseGetSubMatrix(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) {
34945ea7661aSPierre Jolivet   PetscFunctionBegin;
34955ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
34965ea7661aSPierre Jolivet   PetscValidType(A, 1);
3497a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, rbegin, 2);
3498a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, rend, 3);
3499a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, cbegin, 4);
3500a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, cend, 5);
3501a2748737SPierre Jolivet   PetscValidPointer(v, 6);
3502a2748737SPierre Jolivet   if (rbegin == PETSC_DECIDE) rbegin = 0;
3503a2748737SPierre Jolivet   if (rend == PETSC_DECIDE) rend = A->rmap->N;
3504a2748737SPierre Jolivet   if (cbegin == PETSC_DECIDE) cbegin = 0;
3505a2748737SPierre Jolivet   if (cend == PETSC_DECIDE) cend = A->cmap->N;
350628b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
3507a2748737SPierre 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);
3508a2748737SPierre 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);
3509a2748737SPierre 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);
3510a2748737SPierre 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);
3511a2748737SPierre Jolivet   PetscUseMethod(A, "MatDenseGetSubMatrix_C", (Mat, PetscInt, PetscInt, PetscInt, PetscInt, Mat *), (A, rbegin, rend, cbegin, cend, v));
35125ea7661aSPierre Jolivet   PetscFunctionReturn(0);
35135ea7661aSPierre Jolivet }
35145ea7661aSPierre Jolivet 
35150f74d2c1SSatish Balay /*@
35165ea7661aSPierre Jolivet    MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from MatDenseGetSubMatrix().
35175ea7661aSPierre Jolivet 
35185ea7661aSPierre Jolivet    Collective
35195ea7661aSPierre Jolivet 
35205ea7661aSPierre Jolivet    Input Parameters:
35215ea7661aSPierre Jolivet +  mat - the Mat object
3522742765d3SMatthew Knepley -  v - the Mat object (may be NULL)
35235ea7661aSPierre Jolivet 
35245ea7661aSPierre Jolivet    Level: intermediate
35255ea7661aSPierre Jolivet 
3526db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseGetSubMatrix()`
35275ea7661aSPierre Jolivet @*/
35289371c9d4SSatish Balay PetscErrorCode MatDenseRestoreSubMatrix(Mat A, Mat *v) {
35295ea7661aSPierre Jolivet   PetscFunctionBegin;
35305ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
35315ea7661aSPierre Jolivet   PetscValidType(A, 1);
35325ea7661aSPierre Jolivet   PetscValidPointer(v, 2);
3533cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreSubMatrix_C", (Mat, Mat *), (A, v));
35345ea7661aSPierre Jolivet   PetscFunctionReturn(0);
35355ea7661aSPierre Jolivet }
35368a9c020eSBarry Smith 
35378a9c020eSBarry Smith #include <petscblaslapack.h>
35388a9c020eSBarry Smith #include <petsc/private/kernels/blockinvert.h>
35398a9c020eSBarry Smith 
35409371c9d4SSatish Balay PetscErrorCode MatSeqDenseInvert(Mat A) {
35418a9c020eSBarry Smith   Mat_SeqDense   *a              = (Mat_SeqDense *)A->data;
35428a9c020eSBarry Smith   PetscInt        bs             = A->rmap->n;
35438a9c020eSBarry Smith   MatScalar      *values         = a->v;
35448a9c020eSBarry Smith   const PetscReal shift          = 0.0;
35458a9c020eSBarry Smith   PetscBool       allowzeropivot = PetscNot(A->erroriffailure), zeropivotdetected = PETSC_FALSE;
35468a9c020eSBarry Smith 
35478a9c020eSBarry Smith   PetscFunctionBegin;
35488a9c020eSBarry Smith   /* factor and invert each block */
35498a9c020eSBarry Smith   switch (bs) {
35509371c9d4SSatish Balay   case 1: values[0] = (PetscScalar)1.0 / (values[0] + shift); break;
35518a9c020eSBarry Smith   case 2:
35528a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_2(values, shift, allowzeropivot, &zeropivotdetected));
35538a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
35548a9c020eSBarry Smith     break;
35558a9c020eSBarry Smith   case 3:
35568a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_3(values, shift, allowzeropivot, &zeropivotdetected));
35578a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
35588a9c020eSBarry Smith     break;
35598a9c020eSBarry Smith   case 4:
35608a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_4(values, shift, allowzeropivot, &zeropivotdetected));
35618a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
35628a9c020eSBarry Smith     break;
35639371c9d4SSatish Balay   case 5: {
35648a9c020eSBarry Smith     PetscScalar work[25];
35658a9c020eSBarry Smith     PetscInt    ipvt[5];
35668a9c020eSBarry Smith 
35678a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_5(values, ipvt, work, shift, allowzeropivot, &zeropivotdetected));
35688a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
35699371c9d4SSatish Balay   } break;
35708a9c020eSBarry Smith   case 6:
35718a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_6(values, shift, allowzeropivot, &zeropivotdetected));
35728a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
35738a9c020eSBarry Smith     break;
35748a9c020eSBarry Smith   case 7:
35758a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_7(values, shift, allowzeropivot, &zeropivotdetected));
35768a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
35778a9c020eSBarry Smith     break;
35789371c9d4SSatish Balay   default: {
35798a9c020eSBarry Smith     PetscInt    *v_pivots, *IJ, j;
35808a9c020eSBarry Smith     PetscScalar *v_work;
35818a9c020eSBarry Smith 
35828a9c020eSBarry Smith     PetscCall(PetscMalloc3(bs, &v_work, bs, &v_pivots, bs, &IJ));
3583ad540459SPierre Jolivet     for (j = 0; j < bs; j++) IJ[j] = j;
35848a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A(bs, values, v_pivots, v_work, allowzeropivot, &zeropivotdetected));
35858a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
35868a9c020eSBarry Smith     PetscCall(PetscFree3(v_work, v_pivots, IJ));
35878a9c020eSBarry Smith   }
35888a9c020eSBarry Smith   }
35898a9c020eSBarry Smith   PetscFunctionReturn(0);
35908a9c020eSBarry Smith }
3591