xref: /petsc/src/mat/impls/dense/seq/dense.c (revision 48a46eb9bd028bec07ec0f396b1a3abb43f14558)
1be1d678aSKris Buschelman 
267e560aaSBarry Smith /*
367e560aaSBarry Smith      Defines the basic matrix operations for sequential dense.
467e560aaSBarry Smith */
5289bc588SBarry Smith 
6dec5eb66SMatthew G Knepley #include <../src/mat/impls/dense/seq/dense.h> /*I "petscmat.h" I*/
7c6db04a5SJed Brown #include <petscblaslapack.h>
8289bc588SBarry Smith 
96a63e612SBarry Smith #include <../src/mat/impls/aij/seq/aij.h>
10b2573a8aSBarry Smith 
119371c9d4SSatish Balay PetscErrorCode MatSeqDenseSymmetrize_Private(Mat A, PetscBool hermitian) {
128c178816SStefano Zampini   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
138c178816SStefano Zampini   PetscInt      j, k, n = A->rmap->n;
14ca15aa20SStefano Zampini   PetscScalar  *v;
158c178816SStefano Zampini 
168c178816SStefano Zampini   PetscFunctionBegin;
1708401ef6SPierre Jolivet   PetscCheck(A->rmap->n == A->cmap->n, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Cannot symmetrize a rectangular matrix");
189566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
198c178816SStefano Zampini   if (!hermitian) {
208c178816SStefano Zampini     for (k = 0; k < n; k++) {
219371c9d4SSatish Balay       for (j = k; j < n; j++) { v[j * mat->lda + k] = v[k * mat->lda + j]; }
228c178816SStefano Zampini     }
238c178816SStefano Zampini   } else {
248c178816SStefano Zampini     for (k = 0; k < n; k++) {
259371c9d4SSatish Balay       for (j = k; j < n; j++) { v[j * mat->lda + k] = PetscConj(v[k * mat->lda + j]); }
268c178816SStefano Zampini     }
278c178816SStefano Zampini   }
289566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
298c178816SStefano Zampini   PetscFunctionReturn(0);
308c178816SStefano Zampini }
318c178816SStefano Zampini 
329371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode MatSeqDenseInvertFactors_Private(Mat A) {
338c178816SStefano Zampini   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
348c178816SStefano Zampini   PetscBLASInt  info, n;
358c178816SStefano Zampini 
368c178816SStefano Zampini   PetscFunctionBegin;
378c178816SStefano Zampini   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
389566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
398c178816SStefano Zampini   if (A->factortype == MAT_FACTOR_LU) {
4028b400f6SJacob Faibussowitsch     PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present");
418c178816SStefano Zampini     if (!mat->fwork) {
428c178816SStefano Zampini       mat->lfwork = n;
439566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
449566063dSJacob Faibussowitsch       PetscCall(PetscLogObjectMemory((PetscObject)A, mat->lfwork * sizeof(PetscBLASInt)));
458c178816SStefano Zampini     }
469566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
47792fecdfSBarry Smith     PetscCallBLAS("LAPACKgetri", LAPACKgetri_(&n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info));
489566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
499566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0));
508c178816SStefano Zampini   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
51b94d7dedSBarry Smith     if (A->spd == PETSC_BOOL3_TRUE) {
529566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
53792fecdfSBarry Smith       PetscCallBLAS("LAPACKpotri", LAPACKpotri_("L", &n, mat->v, &mat->lda, &info));
549566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
559566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_TRUE));
568c178816SStefano Zampini #if defined(PETSC_USE_COMPLEX)
57b94d7dedSBarry Smith     } else if (A->hermitian == PETSC_BOOL3_TRUE) {
5828b400f6SJacob Faibussowitsch       PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present");
5928b400f6SJacob Faibussowitsch       PetscCheck(mat->fwork, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Fwork not present");
609566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
61792fecdfSBarry Smith       PetscCallBLAS("LAPACKhetri", LAPACKhetri_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &info));
629566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
639566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_TRUE));
648c178816SStefano Zampini #endif
658c178816SStefano Zampini     } else { /* symmetric case */
6628b400f6SJacob Faibussowitsch       PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present");
6728b400f6SJacob Faibussowitsch       PetscCheck(mat->fwork, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Fwork not present");
689566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
69792fecdfSBarry Smith       PetscCallBLAS("LAPACKsytri", LAPACKsytri_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &info));
709566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
719566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_FALSE));
728c178816SStefano Zampini     }
7328b400f6SJacob Faibussowitsch     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad Inversion: zero pivot in row %" PetscInt_FMT, (PetscInt)info - 1);
749566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0));
758c178816SStefano Zampini   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Matrix must be factored to solve");
768c178816SStefano Zampini 
778c178816SStefano Zampini   A->ops->solve             = NULL;
788c178816SStefano Zampini   A->ops->matsolve          = NULL;
798c178816SStefano Zampini   A->ops->solvetranspose    = NULL;
808c178816SStefano Zampini   A->ops->matsolvetranspose = NULL;
818c178816SStefano Zampini   A->ops->solveadd          = NULL;
828c178816SStefano Zampini   A->ops->solvetransposeadd = NULL;
838c178816SStefano Zampini   A->factortype             = MAT_FACTOR_NONE;
849566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
858c178816SStefano Zampini   PetscFunctionReturn(0);
868c178816SStefano Zampini }
878c178816SStefano Zampini 
889371c9d4SSatish Balay PetscErrorCode MatZeroRowsColumns_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) {
893f49a652SStefano Zampini   Mat_SeqDense      *l = (Mat_SeqDense *)A->data;
903f49a652SStefano Zampini   PetscInt           m = l->lda, n = A->cmap->n, r = A->rmap->n, i, j;
91ca15aa20SStefano Zampini   PetscScalar       *slot, *bb, *v;
923f49a652SStefano Zampini   const PetscScalar *xx;
933f49a652SStefano Zampini 
943f49a652SStefano Zampini   PetscFunctionBegin;
9576bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
963f49a652SStefano Zampini     for (i = 0; i < N; i++) {
9708401ef6SPierre Jolivet       PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed");
9808401ef6SPierre 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);
9908401ef6SPierre 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);
1003f49a652SStefano Zampini     }
10176bd3646SJed Brown   }
102ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
1033f49a652SStefano Zampini 
1043f49a652SStefano Zampini   /* fix right hand side if needed */
1053f49a652SStefano Zampini   if (x && b) {
1066c4d906cSStefano Zampini     Vec xt;
1076c4d906cSStefano Zampini 
10808401ef6SPierre Jolivet     PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices");
1099566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(x, &xt));
1109566063dSJacob Faibussowitsch     PetscCall(VecCopy(x, xt));
1119566063dSJacob Faibussowitsch     PetscCall(VecScale(xt, -1.0));
1129566063dSJacob Faibussowitsch     PetscCall(MatMultAdd(A, xt, b, b));
1139566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&xt));
1149566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(x, &xx));
1159566063dSJacob Faibussowitsch     PetscCall(VecGetArray(b, &bb));
1163f49a652SStefano Zampini     for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]];
1179566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(x, &xx));
1189566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(b, &bb));
1193f49a652SStefano Zampini   }
1203f49a652SStefano Zampini 
1219566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
1223f49a652SStefano Zampini   for (i = 0; i < N; i++) {
123ca15aa20SStefano Zampini     slot = v + rows[i] * m;
1249566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(slot, r));
1253f49a652SStefano Zampini   }
1263f49a652SStefano Zampini   for (i = 0; i < N; i++) {
127ca15aa20SStefano Zampini     slot = v + rows[i];
1289371c9d4SSatish Balay     for (j = 0; j < n; j++) {
1299371c9d4SSatish Balay       *slot = 0.0;
1309371c9d4SSatish Balay       slot += m;
1319371c9d4SSatish Balay     }
1323f49a652SStefano Zampini   }
1333f49a652SStefano Zampini   if (diag != 0.0) {
13408401ef6SPierre Jolivet     PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices");
1353f49a652SStefano Zampini     for (i = 0; i < N; i++) {
136ca15aa20SStefano Zampini       slot  = v + (m + 1) * rows[i];
1373f49a652SStefano Zampini       *slot = diag;
1383f49a652SStefano Zampini     }
1393f49a652SStefano Zampini   }
1409566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
1413f49a652SStefano Zampini   PetscFunctionReturn(0);
1423f49a652SStefano Zampini }
1433f49a652SStefano Zampini 
1449371c9d4SSatish Balay PetscErrorCode MatPtAPNumeric_SeqDense_SeqDense(Mat A, Mat P, Mat C) {
145abc3b08eSStefano Zampini   Mat_SeqDense *c = (Mat_SeqDense *)(C->data);
146abc3b08eSStefano Zampini 
147abc3b08eSStefano Zampini   PetscFunctionBegin;
148ca15aa20SStefano Zampini   if (c->ptapwork) {
1499566063dSJacob Faibussowitsch     PetscCall((*C->ops->matmultnumeric)(A, P, c->ptapwork));
1509566063dSJacob Faibussowitsch     PetscCall((*C->ops->transposematmultnumeric)(P, c->ptapwork, C));
1514222ddf1SHong Zhang   } else SETERRQ(PetscObjectComm((PetscObject)C), PETSC_ERR_SUP, "Must call MatPtAPSymbolic_SeqDense_SeqDense() first");
152abc3b08eSStefano Zampini   PetscFunctionReturn(0);
153abc3b08eSStefano Zampini }
154abc3b08eSStefano Zampini 
1559371c9d4SSatish Balay PetscErrorCode MatPtAPSymbolic_SeqDense_SeqDense(Mat A, Mat P, PetscReal fill, Mat C) {
156abc3b08eSStefano Zampini   Mat_SeqDense *c;
1577a3c3d58SStefano Zampini   PetscBool     cisdense;
158abc3b08eSStefano Zampini 
159abc3b08eSStefano Zampini   PetscFunctionBegin;
1609566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C, P->cmap->n, P->cmap->n, P->cmap->N, P->cmap->N));
1619566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, ""));
1627a3c3d58SStefano Zampini   if (!cisdense) {
1637a3c3d58SStefano Zampini     PetscBool flg;
1647a3c3d58SStefano Zampini 
1659566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)P, ((PetscObject)A)->type_name, &flg));
1669566063dSJacob Faibussowitsch     PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE));
1677a3c3d58SStefano Zampini   }
1689566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
1694222ddf1SHong Zhang   c = (Mat_SeqDense *)C->data;
1709566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &c->ptapwork));
1719566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(c->ptapwork, A->rmap->n, P->cmap->n, A->rmap->N, P->cmap->N));
1729566063dSJacob Faibussowitsch   PetscCall(MatSetType(c->ptapwork, ((PetscObject)C)->type_name));
1739566063dSJacob Faibussowitsch   PetscCall(MatSetUp(c->ptapwork));
174abc3b08eSStefano Zampini   PetscFunctionReturn(0);
175abc3b08eSStefano Zampini }
176abc3b08eSStefano Zampini 
1779371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) {
178a13144ffSStefano Zampini   Mat              B = NULL;
179b49cda9fSStefano Zampini   Mat_SeqAIJ      *a = (Mat_SeqAIJ *)A->data;
180b49cda9fSStefano Zampini   Mat_SeqDense    *b;
181b49cda9fSStefano Zampini   PetscInt        *ai = a->i, *aj = a->j, m = A->rmap->N, n = A->cmap->N, i;
1822e5835c6SStefano Zampini   const MatScalar *av;
183a13144ffSStefano Zampini   PetscBool        isseqdense;
184b49cda9fSStefano Zampini 
185b49cda9fSStefano Zampini   PetscFunctionBegin;
186a13144ffSStefano Zampini   if (reuse == MAT_REUSE_MATRIX) {
1879566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)*newmat, MATSEQDENSE, &isseqdense));
18828b400f6SJacob Faibussowitsch     PetscCheck(isseqdense, PetscObjectComm((PetscObject)*newmat), PETSC_ERR_USER, "Cannot reuse matrix of type %s", ((PetscObject)(*newmat))->type_name);
189a13144ffSStefano Zampini   }
190a13144ffSStefano Zampini   if (reuse != MAT_REUSE_MATRIX) {
1919566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B));
1929566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(B, m, n, m, n));
1939566063dSJacob Faibussowitsch     PetscCall(MatSetType(B, MATSEQDENSE));
1949566063dSJacob Faibussowitsch     PetscCall(MatSeqDenseSetPreallocation(B, NULL));
195b49cda9fSStefano Zampini     b = (Mat_SeqDense *)(B->data);
196a13144ffSStefano Zampini   } else {
197a13144ffSStefano Zampini     b = (Mat_SeqDense *)((*newmat)->data);
1989566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(b->v, m * n));
199a13144ffSStefano Zampini   }
2009566063dSJacob Faibussowitsch   PetscCall(MatSeqAIJGetArrayRead(A, &av));
201b49cda9fSStefano Zampini   for (i = 0; i < m; i++) {
202b49cda9fSStefano Zampini     PetscInt j;
203b49cda9fSStefano Zampini     for (j = 0; j < ai[1] - ai[0]; j++) {
204b49cda9fSStefano Zampini       b->v[*aj * m + i] = *av;
205b49cda9fSStefano Zampini       aj++;
206b49cda9fSStefano Zampini       av++;
207b49cda9fSStefano Zampini     }
208b49cda9fSStefano Zampini     ai++;
209b49cda9fSStefano Zampini   }
2109566063dSJacob Faibussowitsch   PetscCall(MatSeqAIJRestoreArrayRead(A, &av));
211b49cda9fSStefano Zampini 
212511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
2139566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY));
2149566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY));
2159566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A, &B));
216b49cda9fSStefano Zampini   } else {
217a13144ffSStefano Zampini     if (B) *newmat = B;
2189566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(*newmat, MAT_FINAL_ASSEMBLY));
2199566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(*newmat, MAT_FINAL_ASSEMBLY));
220b49cda9fSStefano Zampini   }
221b49cda9fSStefano Zampini   PetscFunctionReturn(0);
222b49cda9fSStefano Zampini }
223b49cda9fSStefano Zampini 
2249371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatConvert_SeqDense_SeqAIJ(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) {
2256d4ec7b0SPierre Jolivet   Mat           B = NULL;
2266a63e612SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
2279399e1b8SMatthew G. Knepley   PetscInt      i, j;
2289399e1b8SMatthew G. Knepley   PetscInt     *rows, *nnz;
2299399e1b8SMatthew G. Knepley   MatScalar    *aa = a->v, *vals;
2306a63e612SBarry Smith 
2316a63e612SBarry Smith   PetscFunctionBegin;
2329566063dSJacob Faibussowitsch   PetscCall(PetscCalloc3(A->rmap->n, &rows, A->rmap->n, &nnz, A->rmap->n, &vals));
2336d4ec7b0SPierre Jolivet   if (reuse != MAT_REUSE_MATRIX) {
2349566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B));
2359566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(B, A->rmap->n, A->cmap->n, A->rmap->N, A->cmap->N));
2369566063dSJacob Faibussowitsch     PetscCall(MatSetType(B, MATSEQAIJ));
2379399e1b8SMatthew G. Knepley     for (j = 0; j < A->cmap->n; j++) {
2389371c9d4SSatish Balay       for (i = 0; i < A->rmap->n; i++)
2399371c9d4SSatish Balay         if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) ++nnz[i];
2406a63e612SBarry Smith       aa += a->lda;
2416a63e612SBarry Smith     }
2429566063dSJacob Faibussowitsch     PetscCall(MatSeqAIJSetPreallocation(B, PETSC_DETERMINE, nnz));
2436d4ec7b0SPierre Jolivet   } else B = *newmat;
2449399e1b8SMatthew G. Knepley   aa = a->v;
2459399e1b8SMatthew G. Knepley   for (j = 0; j < A->cmap->n; j++) {
2469399e1b8SMatthew G. Knepley     PetscInt numRows = 0;
2479371c9d4SSatish Balay     for (i = 0; i < A->rmap->n; i++)
2489371c9d4SSatish Balay       if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) {
2499371c9d4SSatish Balay         rows[numRows]   = i;
2509371c9d4SSatish Balay         vals[numRows++] = aa[i];
2519371c9d4SSatish Balay       }
2529566063dSJacob Faibussowitsch     PetscCall(MatSetValues(B, numRows, rows, 1, &j, vals, INSERT_VALUES));
2539399e1b8SMatthew G. Knepley     aa += a->lda;
2549399e1b8SMatthew G. Knepley   }
2559566063dSJacob Faibussowitsch   PetscCall(PetscFree3(rows, nnz, vals));
2569566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY));
2579566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY));
2586a63e612SBarry Smith 
259511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
2609566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A, &B));
2616d4ec7b0SPierre Jolivet   } else if (reuse != MAT_REUSE_MATRIX) *newmat = B;
2626a63e612SBarry Smith   PetscFunctionReturn(0);
2636a63e612SBarry Smith }
2646a63e612SBarry Smith 
2659371c9d4SSatish Balay PetscErrorCode MatAXPY_SeqDense(Mat Y, PetscScalar alpha, Mat X, MatStructure str) {
2661987afe7SBarry Smith   Mat_SeqDense      *x = (Mat_SeqDense *)X->data, *y = (Mat_SeqDense *)Y->data;
267ca15aa20SStefano Zampini   const PetscScalar *xv;
268ca15aa20SStefano Zampini   PetscScalar       *yv;
26923fff9afSBarry Smith   PetscBLASInt       N, m, ldax = 0, lday = 0, one = 1;
2703a40ed3dSBarry Smith 
2713a40ed3dSBarry Smith   PetscFunctionBegin;
2729566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(X, &xv));
2739566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(Y, &yv));
2749566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(X->rmap->n * X->cmap->n, &N));
2759566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(X->rmap->n, &m));
2769566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(x->lda, &ldax));
2779566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(y->lda, &lday));
278a5ce6ee0Svictorle   if (ldax > m || lday > m) {
279ca15aa20SStefano Zampini     PetscInt j;
280ca15aa20SStefano Zampini 
281*48a46eb9SPierre Jolivet     for (j = 0; j < X->cmap->n; j++) PetscCallBLAS("BLASaxpy", BLASaxpy_(&m, &alpha, xv + j * ldax, &one, yv + j * lday, &one));
282a5ce6ee0Svictorle   } else {
283792fecdfSBarry Smith     PetscCallBLAS("BLASaxpy", BLASaxpy_(&N, &alpha, xv, &one, yv, &one));
284a5ce6ee0Svictorle   }
2859566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(X, &xv));
2869566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(Y, &yv));
2879566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(PetscMax(2.0 * N - 1, 0)));
2883a40ed3dSBarry Smith   PetscFunctionReturn(0);
2891987afe7SBarry Smith }
2901987afe7SBarry Smith 
2919371c9d4SSatish Balay static PetscErrorCode MatGetInfo_SeqDense(Mat A, MatInfoType flag, MatInfo *info) {
292ca15aa20SStefano Zampini   PetscLogDouble N = A->rmap->n * A->cmap->n;
2933a40ed3dSBarry Smith 
2943a40ed3dSBarry Smith   PetscFunctionBegin;
2954e220ebcSLois Curfman McInnes   info->block_size        = 1.0;
296ca15aa20SStefano Zampini   info->nz_allocated      = N;
297ca15aa20SStefano Zampini   info->nz_used           = N;
298ca15aa20SStefano Zampini   info->nz_unneeded       = 0;
299ca15aa20SStefano Zampini   info->assemblies        = A->num_ass;
3004e220ebcSLois Curfman McInnes   info->mallocs           = 0;
3017adad957SLisandro Dalcin   info->memory            = ((PetscObject)A)->mem;
3024e220ebcSLois Curfman McInnes   info->fill_ratio_given  = 0;
3034e220ebcSLois Curfman McInnes   info->fill_ratio_needed = 0;
3044e220ebcSLois Curfman McInnes   info->factor_mallocs    = 0;
3053a40ed3dSBarry Smith   PetscFunctionReturn(0);
306289bc588SBarry Smith }
307289bc588SBarry Smith 
3089371c9d4SSatish Balay PetscErrorCode MatScale_SeqDense(Mat A, PetscScalar alpha) {
309273d9f13SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
310ca15aa20SStefano Zampini   PetscScalar  *v;
31123fff9afSBarry Smith   PetscBLASInt  one = 1, j, nz, lda = 0;
31280cd9d93SLois Curfman McInnes 
3133a40ed3dSBarry Smith   PetscFunctionBegin;
3149566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
3159566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(a->lda, &lda));
316d0f46423SBarry Smith   if (lda > A->rmap->n) {
3179566063dSJacob Faibussowitsch     PetscCall(PetscBLASIntCast(A->rmap->n, &nz));
318*48a46eb9SPierre Jolivet     for (j = 0; j < A->cmap->n; j++) PetscCallBLAS("BLASscal", BLASscal_(&nz, &alpha, v + j * lda, &one));
319a5ce6ee0Svictorle   } else {
3209566063dSJacob Faibussowitsch     PetscCall(PetscBLASIntCast(A->rmap->n * A->cmap->n, &nz));
321792fecdfSBarry Smith     PetscCallBLAS("BLASscal", BLASscal_(&nz, &alpha, v, &one));
322a5ce6ee0Svictorle   }
32304cbc005SJose E. Roman   PetscCall(PetscLogFlops(A->rmap->n * A->cmap->n));
3249566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
3253a40ed3dSBarry Smith   PetscFunctionReturn(0);
32680cd9d93SLois Curfman McInnes }
32780cd9d93SLois Curfman McInnes 
3289371c9d4SSatish Balay PetscErrorCode MatShift_SeqDense(Mat A, PetscScalar alpha) {
3292f605a99SJose E. Roman   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
3302f605a99SJose E. Roman   PetscScalar  *v;
3312f605a99SJose E. Roman   PetscInt      j, k;
3322f605a99SJose E. Roman 
3332f605a99SJose E. Roman   PetscFunctionBegin;
3342f605a99SJose E. Roman   PetscCall(MatDenseGetArray(A, &v));
3352f605a99SJose E. Roman   k = PetscMin(A->rmap->n, A->cmap->n);
3362f605a99SJose E. Roman   for (j = 0; j < k; j++) v[j + j * a->lda] += alpha;
3372f605a99SJose E. Roman   PetscCall(PetscLogFlops(k));
3382f605a99SJose E. Roman   PetscCall(MatDenseRestoreArray(A, &v));
3392f605a99SJose E. Roman   PetscFunctionReturn(0);
3402f605a99SJose E. Roman }
3412f605a99SJose E. Roman 
3429371c9d4SSatish Balay static PetscErrorCode MatIsHermitian_SeqDense(Mat A, PetscReal rtol, PetscBool *fl) {
3431cbb95d3SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
344ca15aa20SStefano Zampini   PetscInt           i, j, m = A->rmap->n, N = a->lda;
345ca15aa20SStefano Zampini   const PetscScalar *v;
3461cbb95d3SBarry Smith 
3471cbb95d3SBarry Smith   PetscFunctionBegin;
3481cbb95d3SBarry Smith   *fl = PETSC_FALSE;
349d0f46423SBarry Smith   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
3509566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &v));
3511cbb95d3SBarry Smith   for (i = 0; i < m; i++) {
352ca15aa20SStefano Zampini     for (j = i; j < m; j++) {
3539371c9d4SSatish Balay       if (PetscAbsScalar(v[i + j * N] - PetscConj(v[j + i * N])) > rtol) { goto restore; }
3541cbb95d3SBarry Smith     }
355637a0070SStefano Zampini   }
3561cbb95d3SBarry Smith   *fl = PETSC_TRUE;
357637a0070SStefano Zampini restore:
3589566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &v));
359637a0070SStefano Zampini   PetscFunctionReturn(0);
360637a0070SStefano Zampini }
361637a0070SStefano Zampini 
3629371c9d4SSatish Balay static PetscErrorCode MatIsSymmetric_SeqDense(Mat A, PetscReal rtol, PetscBool *fl) {
363637a0070SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
364637a0070SStefano Zampini   PetscInt           i, j, m = A->rmap->n, N = a->lda;
365637a0070SStefano Zampini   const PetscScalar *v;
366637a0070SStefano Zampini 
367637a0070SStefano Zampini   PetscFunctionBegin;
368637a0070SStefano Zampini   *fl = PETSC_FALSE;
369637a0070SStefano Zampini   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
3709566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &v));
371637a0070SStefano Zampini   for (i = 0; i < m; i++) {
372637a0070SStefano Zampini     for (j = i; j < m; j++) {
3739371c9d4SSatish Balay       if (PetscAbsScalar(v[i + j * N] - v[j + i * N]) > rtol) { goto restore; }
374637a0070SStefano Zampini     }
375637a0070SStefano Zampini   }
376637a0070SStefano Zampini   *fl = PETSC_TRUE;
377637a0070SStefano Zampini restore:
3789566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &v));
3791cbb95d3SBarry Smith   PetscFunctionReturn(0);
3801cbb95d3SBarry Smith }
3811cbb95d3SBarry Smith 
3829371c9d4SSatish Balay PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi, Mat A, MatDuplicateOption cpvalues) {
383ca15aa20SStefano Zampini   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
38423fc5dcaSStefano Zampini   PetscInt      lda = (PetscInt)mat->lda, j, m, nlda = lda;
38575f6d85dSStefano Zampini   PetscBool     isdensecpu;
386b24902e0SBarry Smith 
387b24902e0SBarry Smith   PetscFunctionBegin;
3889566063dSJacob Faibussowitsch   PetscCall(PetscLayoutReference(A->rmap, &newi->rmap));
3899566063dSJacob Faibussowitsch   PetscCall(PetscLayoutReference(A->cmap, &newi->cmap));
39023fc5dcaSStefano Zampini   if (cpvalues == MAT_SHARE_NONZERO_PATTERN) { /* propagate LDA */
3919566063dSJacob Faibussowitsch     PetscCall(MatDenseSetLDA(newi, lda));
39223fc5dcaSStefano Zampini   }
3939566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)newi, MATSEQDENSE, &isdensecpu));
3949566063dSJacob Faibussowitsch   if (isdensecpu) PetscCall(MatSeqDenseSetPreallocation(newi, NULL));
395b24902e0SBarry Smith   if (cpvalues == MAT_COPY_VALUES) {
396ca15aa20SStefano Zampini     const PetscScalar *av;
397ca15aa20SStefano Zampini     PetscScalar       *v;
398ca15aa20SStefano Zampini 
3999566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A, &av));
4009566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayWrite(newi, &v));
4019566063dSJacob Faibussowitsch     PetscCall(MatDenseGetLDA(newi, &nlda));
402d0f46423SBarry Smith     m = A->rmap->n;
40323fc5dcaSStefano Zampini     if (lda > m || nlda > m) {
404*48a46eb9SPierre Jolivet       for (j = 0; j < A->cmap->n; j++) PetscCall(PetscArraycpy(v + j * nlda, av + j * lda, m));
405b24902e0SBarry Smith     } else {
4069566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(v, av, A->rmap->n * A->cmap->n));
407b24902e0SBarry Smith     }
4089566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayWrite(newi, &v));
4099566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A, &av));
410b24902e0SBarry Smith   }
411b24902e0SBarry Smith   PetscFunctionReturn(0);
412b24902e0SBarry Smith }
413b24902e0SBarry Smith 
4149371c9d4SSatish Balay PetscErrorCode MatDuplicate_SeqDense(Mat A, MatDuplicateOption cpvalues, Mat *newmat) {
4153a40ed3dSBarry Smith   PetscFunctionBegin;
4169566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), newmat));
4179566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*newmat, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n));
4189566063dSJacob Faibussowitsch   PetscCall(MatSetType(*newmat, ((PetscObject)A)->type_name));
4199566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(*newmat, A, cpvalues));
420b24902e0SBarry Smith   PetscFunctionReturn(0);
421b24902e0SBarry Smith }
422b24902e0SBarry Smith 
4239371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_Internal_LU(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T) {
424c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
4254396437dSToby Isaac   PetscBLASInt  info;
42667e560aaSBarry Smith 
4273a40ed3dSBarry Smith   PetscFunctionBegin;
4289566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
429792fecdfSBarry Smith   PetscCallBLAS("LAPACKgetrs", LAPACKgetrs_(T ? "T" : "N", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info));
4309566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
43105fcb23eSStefano Zampini   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "GETRS - Bad solve %d", (int)info);
4329566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m)));
4334396437dSToby Isaac   PetscFunctionReturn(0);
4344396437dSToby Isaac }
4354396437dSToby Isaac 
4364396437dSToby Isaac static PetscErrorCode MatConjugate_SeqDense(Mat);
4374396437dSToby Isaac 
4389371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_Internal_Cholesky(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T) {
4394396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
4404396437dSToby Isaac   PetscBLASInt  info;
4414396437dSToby Isaac 
4424396437dSToby Isaac   PetscFunctionBegin;
443b94d7dedSBarry Smith   if (A->spd == PETSC_BOOL3_TRUE) {
4449566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A));
4459566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
446792fecdfSBarry Smith     PetscCallBLAS("LAPACKpotrs", LAPACKpotrs_("L", &m, &nrhs, mat->v, &mat->lda, x, &m, &info));
4479566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
44805fcb23eSStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "POTRS Bad solve %d", (int)info);
4499566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A));
450a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
451b94d7dedSBarry Smith   } else if (A->hermitian == PETSC_BOOL3_TRUE) {
4529566063dSJacob Faibussowitsch     if (T) PetscCall(MatConjugate_SeqDense(A));
4539566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
454792fecdfSBarry Smith     PetscCallBLAS("LAPACKhetrs", LAPACKhetrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info));
4559566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
45605fcb23eSStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "HETRS Bad solve %d", (int)info);
4579566063dSJacob Faibussowitsch     if (T) PetscCall(MatConjugate_SeqDense(A));
458a49dc2a2SStefano Zampini #endif
459a49dc2a2SStefano Zampini   } else { /* symmetric case */
4609566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
461792fecdfSBarry Smith     PetscCallBLAS("LAPACKsytrs", LAPACKsytrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info));
4629566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
46305fcb23eSStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "SYTRS Bad solve %d", (int)info);
464a49dc2a2SStefano Zampini   }
4659566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m)));
4664396437dSToby Isaac   PetscFunctionReturn(0);
4674396437dSToby Isaac }
46885e2c93fSHong Zhang 
4699371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k) {
4704396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
4714396437dSToby Isaac   PetscBLASInt  info;
4724396437dSToby Isaac   char          trans;
4734396437dSToby Isaac 
4744396437dSToby Isaac   PetscFunctionBegin;
4754905a7bcSToby Isaac   if (PetscDefined(USE_COMPLEX)) {
4764905a7bcSToby Isaac     trans = 'C';
4774905a7bcSToby Isaac   } else {
4784905a7bcSToby Isaac     trans = 'T';
4794905a7bcSToby Isaac   }
4809566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
48105fcb23eSStefano Zampini   { /* lwork depends on the number of right-hand sides */
48205fcb23eSStefano Zampini     PetscBLASInt nlfwork, lfwork = -1;
48305fcb23eSStefano Zampini     PetscScalar  fwork;
48405fcb23eSStefano Zampini 
485792fecdfSBarry Smith     PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info));
48605fcb23eSStefano Zampini     nlfwork = (PetscBLASInt)PetscRealPart(fwork);
48705fcb23eSStefano Zampini     if (nlfwork > mat->lfwork) {
48805fcb23eSStefano Zampini       mat->lfwork = nlfwork;
48905fcb23eSStefano Zampini       PetscCall(PetscFree(mat->fwork));
49005fcb23eSStefano Zampini       PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
49105fcb23eSStefano Zampini     }
49205fcb23eSStefano Zampini   }
493792fecdfSBarry Smith   PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info));
4949566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
49505fcb23eSStefano Zampini   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %d", (int)info);
4969566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
497792fecdfSBarry Smith   PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "N", "N", &mat->rank, &nrhs, mat->v, &mat->lda, x, &ldx, &info));
4989566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
49905fcb23eSStefano Zampini   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %d", (int)info);
5004905a7bcSToby Isaac   for (PetscInt j = 0; j < nrhs; j++) {
5019371c9d4SSatish Balay     for (PetscInt i = mat->rank; i < k; i++) { x[j * ldx + i] = 0.; }
5024905a7bcSToby Isaac   }
5039566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank))));
5044905a7bcSToby Isaac   PetscFunctionReturn(0);
5054905a7bcSToby Isaac }
5064905a7bcSToby Isaac 
5079371c9d4SSatish Balay static PetscErrorCode MatSolveTranspose_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k) {
5084396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
5094396437dSToby Isaac   PetscBLASInt  info;
5104396437dSToby Isaac 
5114396437dSToby Isaac   PetscFunctionBegin;
5124396437dSToby Isaac   if (A->rmap->n == A->cmap->n && mat->rank == A->rmap->n) {
5139566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
514792fecdfSBarry Smith     PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "T", "N", &m, &nrhs, mat->v, &mat->lda, x, &ldx, &info));
5159566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
51605fcb23eSStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %d", (int)info);
5179566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A));
51805fcb23eSStefano Zampini     { /* lwork depends on the number of right-hand sides */
51905fcb23eSStefano Zampini       PetscBLASInt nlfwork, lfwork = -1;
52005fcb23eSStefano Zampini       PetscScalar  fwork;
52105fcb23eSStefano Zampini 
522792fecdfSBarry Smith       PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info));
52305fcb23eSStefano Zampini       nlfwork = (PetscBLASInt)PetscRealPart(fwork);
52405fcb23eSStefano Zampini       if (nlfwork > mat->lfwork) {
52505fcb23eSStefano Zampini         mat->lfwork = nlfwork;
52605fcb23eSStefano Zampini         PetscCall(PetscFree(mat->fwork));
52705fcb23eSStefano Zampini         PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
52805fcb23eSStefano Zampini       }
52905fcb23eSStefano Zampini     }
5309566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
531792fecdfSBarry Smith     PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info));
5329566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
53305fcb23eSStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %d", (int)info);
5349566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A));
5354396437dSToby Isaac   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "QR factored matrix cannot be used for transpose solve");
5369566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank))));
5374396437dSToby Isaac   PetscFunctionReturn(0);
5384396437dSToby Isaac }
5394396437dSToby Isaac 
5409371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_SetUp(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k) {
5414396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
5424905a7bcSToby Isaac   PetscScalar  *y;
5434905a7bcSToby Isaac   PetscBLASInt  m = 0, k = 0;
5444905a7bcSToby Isaac 
5454905a7bcSToby Isaac   PetscFunctionBegin;
5469566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
5479566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &k));
5484905a7bcSToby Isaac   if (k < m) {
5499566063dSJacob Faibussowitsch     PetscCall(VecCopy(xx, mat->qrrhs));
5509566063dSJacob Faibussowitsch     PetscCall(VecGetArray(mat->qrrhs, &y));
5514905a7bcSToby Isaac   } else {
5529566063dSJacob Faibussowitsch     PetscCall(VecCopy(xx, yy));
5539566063dSJacob Faibussowitsch     PetscCall(VecGetArray(yy, &y));
5544905a7bcSToby Isaac   }
5554396437dSToby Isaac   *_y = y;
5564396437dSToby Isaac   *_k = k;
5574396437dSToby Isaac   *_m = m;
5584396437dSToby Isaac   PetscFunctionReturn(0);
5594396437dSToby Isaac }
5604396437dSToby Isaac 
5619371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_TearDown(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k) {
5624396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
56342e9364cSSatish Balay   PetscScalar  *y   = NULL;
5644396437dSToby Isaac   PetscBLASInt  m, k;
5654396437dSToby Isaac 
5664396437dSToby Isaac   PetscFunctionBegin;
5674396437dSToby Isaac   y   = *_y;
5684396437dSToby Isaac   *_y = NULL;
5694396437dSToby Isaac   k   = *_k;
5704396437dSToby Isaac   m   = *_m;
5714905a7bcSToby Isaac   if (k < m) {
5724905a7bcSToby Isaac     PetscScalar *yv;
5739566063dSJacob Faibussowitsch     PetscCall(VecGetArray(yy, &yv));
5749566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(yv, y, k));
5759566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(yy, &yv));
5769566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(mat->qrrhs, &y));
5774905a7bcSToby Isaac   } else {
5789566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(yy, &y));
5794905a7bcSToby Isaac   }
5804905a7bcSToby Isaac   PetscFunctionReturn(0);
5814905a7bcSToby Isaac }
5824905a7bcSToby Isaac 
5839371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_LU(Mat A, Vec xx, Vec yy) {
58442e9364cSSatish Balay   PetscScalar *y = NULL;
58542e9364cSSatish Balay   PetscBLASInt m = 0, k = 0;
5864396437dSToby Isaac 
5874396437dSToby Isaac   PetscFunctionBegin;
5889566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
5899566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_FALSE));
5909566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
5914396437dSToby Isaac   PetscFunctionReturn(0);
5924396437dSToby Isaac }
5934396437dSToby Isaac 
5949371c9d4SSatish Balay static PetscErrorCode MatSolveTranspose_SeqDense_LU(Mat A, Vec xx, Vec yy) {
59542e9364cSSatish Balay   PetscScalar *y = NULL;
59642e9364cSSatish Balay   PetscBLASInt m = 0, k = 0;
5974396437dSToby Isaac 
5984396437dSToby Isaac   PetscFunctionBegin;
5999566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6009566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_TRUE));
6019566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6024396437dSToby Isaac   PetscFunctionReturn(0);
6034396437dSToby Isaac }
6044396437dSToby Isaac 
6059371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_Cholesky(Mat A, Vec xx, Vec yy) {
606e54beecaSStefano Zampini   PetscScalar *y = NULL;
607e54beecaSStefano Zampini   PetscBLASInt m = 0, k = 0;
6084396437dSToby Isaac 
6094396437dSToby Isaac   PetscFunctionBegin;
6109566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6119566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_FALSE));
6129566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6134396437dSToby Isaac   PetscFunctionReturn(0);
6144396437dSToby Isaac }
6154396437dSToby Isaac 
6169371c9d4SSatish Balay static PetscErrorCode MatSolveTranspose_SeqDense_Cholesky(Mat A, Vec xx, Vec yy) {
617e54beecaSStefano Zampini   PetscScalar *y = NULL;
618e54beecaSStefano Zampini   PetscBLASInt m = 0, k = 0;
6194396437dSToby Isaac 
6204396437dSToby Isaac   PetscFunctionBegin;
6219566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6229566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_TRUE));
6239566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6244396437dSToby Isaac   PetscFunctionReturn(0);
6254396437dSToby Isaac }
6264396437dSToby Isaac 
6279371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_QR(Mat A, Vec xx, Vec yy) {
628e54beecaSStefano Zampini   PetscScalar *y = NULL;
629e54beecaSStefano Zampini   PetscBLASInt m = 0, k = 0;
6304396437dSToby Isaac 
6314396437dSToby Isaac   PetscFunctionBegin;
6329566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6339566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k));
6349566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6354396437dSToby Isaac   PetscFunctionReturn(0);
6364396437dSToby Isaac }
6374396437dSToby Isaac 
6389371c9d4SSatish Balay static PetscErrorCode MatSolveTranspose_SeqDense_QR(Mat A, Vec xx, Vec yy) {
63942e9364cSSatish Balay   PetscScalar *y = NULL;
64042e9364cSSatish Balay   PetscBLASInt m = 0, k = 0;
6414396437dSToby Isaac 
6424396437dSToby Isaac   PetscFunctionBegin;
6439566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6449566063dSJacob Faibussowitsch   PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k));
6459566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6464396437dSToby Isaac   PetscFunctionReturn(0);
6474396437dSToby Isaac }
6484396437dSToby Isaac 
6499371c9d4SSatish Balay static PetscErrorCode MatMatSolve_SeqDense_SetUp(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k) {
6504905a7bcSToby Isaac   const PetscScalar *b;
6514396437dSToby Isaac   PetscScalar       *y;
652bf5a80bcSToby Isaac   PetscInt           n, _ldb, _ldx;
653bf5a80bcSToby Isaac   PetscBLASInt       nrhs = 0, m = 0, k = 0, ldb = 0, ldx = 0, ldy = 0;
6544905a7bcSToby Isaac 
6554905a7bcSToby Isaac   PetscFunctionBegin;
6569371c9d4SSatish Balay   *_ldy  = 0;
6579371c9d4SSatish Balay   *_m    = 0;
6589371c9d4SSatish Balay   *_nrhs = 0;
6599371c9d4SSatish Balay   *_k    = 0;
6609371c9d4SSatish Balay   *_y    = NULL;
6619566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
6629566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &k));
6639566063dSJacob Faibussowitsch   PetscCall(MatGetSize(B, NULL, &n));
6649566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(n, &nrhs));
6659566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(B, &_ldb));
6669566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldb, &ldb));
6679566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(X, &_ldx));
6689566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldx, &ldx));
669bf5a80bcSToby Isaac   if (ldx < m) {
6709566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(B, &b));
6719566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nrhs * m, &y));
672bf5a80bcSToby Isaac     if (ldb == m) {
6739566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(y, b, ldb * nrhs));
6744905a7bcSToby Isaac     } else {
675*48a46eb9SPierre Jolivet       for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * m], &b[j * ldb], m));
6764905a7bcSToby Isaac     }
677bf5a80bcSToby Isaac     ldy = m;
6789566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(B, &b));
6794905a7bcSToby Isaac   } else {
680bf5a80bcSToby Isaac     if (ldb == ldx) {
6819566063dSJacob Faibussowitsch       PetscCall(MatCopy(B, X, SAME_NONZERO_PATTERN));
6829566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(X, &y));
6834905a7bcSToby Isaac     } else {
6849566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(X, &y));
6859566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArrayRead(B, &b));
686*48a46eb9SPierre Jolivet       for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * ldx], &b[j * ldb], m));
6879566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArrayRead(B, &b));
6884905a7bcSToby Isaac     }
689bf5a80bcSToby Isaac     ldy = ldx;
6904905a7bcSToby Isaac   }
6914396437dSToby Isaac   *_y    = y;
692bf5a80bcSToby Isaac   *_ldy  = ldy;
6934396437dSToby Isaac   *_k    = k;
6944396437dSToby Isaac   *_m    = m;
6954396437dSToby Isaac   *_nrhs = nrhs;
6964396437dSToby Isaac   PetscFunctionReturn(0);
6974396437dSToby Isaac }
6984396437dSToby Isaac 
6999371c9d4SSatish Balay static PetscErrorCode MatMatSolve_SeqDense_TearDown(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k) {
7004396437dSToby Isaac   PetscScalar *y;
701bf5a80bcSToby Isaac   PetscInt     _ldx;
702bf5a80bcSToby Isaac   PetscBLASInt k, ldy, nrhs, ldx = 0;
7034396437dSToby Isaac 
7044396437dSToby Isaac   PetscFunctionBegin;
7054396437dSToby Isaac   y    = *_y;
7064396437dSToby Isaac   *_y  = NULL;
7074396437dSToby Isaac   k    = *_k;
708bf5a80bcSToby Isaac   ldy  = *_ldy;
7094396437dSToby Isaac   nrhs = *_nrhs;
7109566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(X, &_ldx));
7119566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldx, &ldx));
712bf5a80bcSToby Isaac   if (ldx != ldy) {
7134905a7bcSToby Isaac     PetscScalar *xv;
7149566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArray(X, &xv));
715*48a46eb9SPierre Jolivet     for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&xv[j * ldx], &y[j * ldy], k));
7169566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(X, &xv));
7179566063dSJacob Faibussowitsch     PetscCall(PetscFree(y));
7184905a7bcSToby Isaac   } else {
7199566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(X, &y));
7204905a7bcSToby Isaac   }
72185e2c93fSHong Zhang   PetscFunctionReturn(0);
72285e2c93fSHong Zhang }
72385e2c93fSHong Zhang 
7249371c9d4SSatish Balay static PetscErrorCode MatMatSolve_SeqDense_LU(Mat A, Mat B, Mat X) {
7254396437dSToby Isaac   PetscScalar *y;
726bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7274396437dSToby Isaac 
7284396437dSToby Isaac   PetscFunctionBegin;
7299566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7309566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_FALSE));
7319566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7324396437dSToby Isaac   PetscFunctionReturn(0);
7334396437dSToby Isaac }
7344396437dSToby Isaac 
7359371c9d4SSatish Balay static PetscErrorCode MatMatSolveTranspose_SeqDense_LU(Mat A, Mat B, Mat X) {
7364396437dSToby Isaac   PetscScalar *y;
737bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7384396437dSToby Isaac 
7394396437dSToby Isaac   PetscFunctionBegin;
7409566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7419566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_TRUE));
7429566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7434396437dSToby Isaac   PetscFunctionReturn(0);
7444396437dSToby Isaac }
7454396437dSToby Isaac 
7469371c9d4SSatish Balay static PetscErrorCode MatMatSolve_SeqDense_Cholesky(Mat A, Mat B, Mat X) {
7474396437dSToby Isaac   PetscScalar *y;
748bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7494396437dSToby Isaac 
7504396437dSToby Isaac   PetscFunctionBegin;
7519566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7529566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_FALSE));
7539566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7544396437dSToby Isaac   PetscFunctionReturn(0);
7554396437dSToby Isaac }
7564396437dSToby Isaac 
7579371c9d4SSatish Balay static PetscErrorCode MatMatSolveTranspose_SeqDense_Cholesky(Mat A, Mat B, Mat X) {
7584396437dSToby Isaac   PetscScalar *y;
759bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7604396437dSToby Isaac 
7614396437dSToby Isaac   PetscFunctionBegin;
7629566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7639566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_TRUE));
7649566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7654396437dSToby Isaac   PetscFunctionReturn(0);
7664396437dSToby Isaac }
7674396437dSToby Isaac 
7689371c9d4SSatish Balay static PetscErrorCode MatMatSolve_SeqDense_QR(Mat A, Mat B, Mat X) {
7694396437dSToby Isaac   PetscScalar *y;
770bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7714396437dSToby Isaac 
7724396437dSToby Isaac   PetscFunctionBegin;
7739566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7749566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k));
7759566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7764396437dSToby Isaac   PetscFunctionReturn(0);
7774396437dSToby Isaac }
7784396437dSToby Isaac 
7799371c9d4SSatish Balay static PetscErrorCode MatMatSolveTranspose_SeqDense_QR(Mat A, Mat B, Mat X) {
7804396437dSToby Isaac   PetscScalar *y;
781bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7824396437dSToby Isaac 
7834396437dSToby Isaac   PetscFunctionBegin;
7849566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7859566063dSJacob Faibussowitsch   PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k));
7869566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7874396437dSToby Isaac   PetscFunctionReturn(0);
7884396437dSToby Isaac }
7894396437dSToby Isaac 
790db4efbfdSBarry Smith /* ---------------------------------------------------------------*/
791db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots,
792db4efbfdSBarry Smith    rather than put it in the Mat->row slot.*/
7939371c9d4SSatish Balay PetscErrorCode MatLUFactor_SeqDense(Mat A, IS row, IS col, const MatFactorInfo *minfo) {
794db4efbfdSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
795db4efbfdSBarry Smith   PetscBLASInt  n, m, info;
796db4efbfdSBarry Smith 
797db4efbfdSBarry Smith   PetscFunctionBegin;
7989566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
7999566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
800db4efbfdSBarry Smith   if (!mat->pivots) {
8019566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots));
8029566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)A, A->rmap->n * sizeof(PetscBLASInt)));
803db4efbfdSBarry Smith   }
804db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
8059566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
806792fecdfSBarry Smith   PetscCallBLAS("LAPACKgetrf", LAPACKgetrf_(&m, &n, mat->v, &mat->lda, mat->pivots, &info));
8079566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
8088e57ea43SSatish Balay 
80905fcb23eSStefano Zampini   PetscCheck(info >= 0, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to LU factorization %d", (int)info);
81005fcb23eSStefano Zampini   PetscCheck(info <= 0, PETSC_COMM_SELF, PETSC_ERR_MAT_LU_ZRPVT, "Bad LU factorization %d", (int)info);
8118208b9aeSStefano Zampini 
8124396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_LU;
8134396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_LU;
8144396437dSToby Isaac   A->ops->solvetranspose    = MatSolveTranspose_SeqDense_LU;
8154396437dSToby Isaac   A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_LU;
816d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_LU;
817db4efbfdSBarry Smith 
8189566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
8199566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype));
820f6224b95SHong Zhang 
8219566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops((2.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3));
822db4efbfdSBarry Smith   PetscFunctionReturn(0);
823db4efbfdSBarry Smith }
824db4efbfdSBarry Smith 
8259371c9d4SSatish Balay static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) {
8264396437dSToby Isaac   MatFactorInfo info;
8274396437dSToby Isaac 
8284396437dSToby Isaac   PetscFunctionBegin;
8299566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES));
830dbbe0bcdSBarry Smith   PetscUseTypeMethod(fact, lufactor, NULL, NULL, &info);
8314396437dSToby Isaac   PetscFunctionReturn(0);
8324396437dSToby Isaac }
8334396437dSToby Isaac 
8349371c9d4SSatish Balay PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, IS col, const MatFactorInfo *info) {
8354396437dSToby Isaac   PetscFunctionBegin;
8364396437dSToby Isaac   fact->preallocated         = PETSC_TRUE;
8374396437dSToby Isaac   fact->assembled            = PETSC_TRUE;
8384396437dSToby Isaac   fact->ops->lufactornumeric = MatLUFactorNumeric_SeqDense;
8394396437dSToby Isaac   PetscFunctionReturn(0);
8404396437dSToby Isaac }
8414396437dSToby Isaac 
842a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */
8439371c9d4SSatish Balay PetscErrorCode MatCholeskyFactor_SeqDense(Mat A, IS perm, const MatFactorInfo *factinfo) {
844db4efbfdSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
845c5df96a5SBarry Smith   PetscBLASInt  info, n;
846db4efbfdSBarry Smith 
847db4efbfdSBarry Smith   PetscFunctionBegin;
8489566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
849db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
850b94d7dedSBarry Smith   if (A->spd == PETSC_BOOL3_TRUE) {
8519566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
852792fecdfSBarry Smith     PetscCallBLAS("LAPACKpotrf", LAPACKpotrf_("L", &n, mat->v, &mat->lda, &info));
8539566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
854a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
855b94d7dedSBarry Smith   } else if (A->hermitian == PETSC_BOOL3_TRUE) {
856a49dc2a2SStefano Zampini     if (!mat->pivots) {
8579566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots));
8589566063dSJacob Faibussowitsch       PetscCall(PetscLogObjectMemory((PetscObject)A, A->rmap->n * sizeof(PetscBLASInt)));
859a49dc2a2SStefano Zampini     }
860a49dc2a2SStefano Zampini     if (!mat->fwork) {
861a49dc2a2SStefano Zampini       PetscScalar dummy;
862a49dc2a2SStefano Zampini 
863a49dc2a2SStefano Zampini       mat->lfwork = -1;
8649566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
865792fecdfSBarry Smith       PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info));
8669566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
867a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
8689566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
8699566063dSJacob Faibussowitsch       PetscCall(PetscLogObjectMemory((PetscObject)A, mat->lfwork * sizeof(PetscBLASInt)));
870a49dc2a2SStefano Zampini     }
8719566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
872792fecdfSBarry Smith     PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info));
8739566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
874a49dc2a2SStefano Zampini #endif
875a49dc2a2SStefano Zampini   } else { /* symmetric case */
876a49dc2a2SStefano Zampini     if (!mat->pivots) {
8779566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots));
8789566063dSJacob Faibussowitsch       PetscCall(PetscLogObjectMemory((PetscObject)A, A->rmap->n * sizeof(PetscBLASInt)));
879a49dc2a2SStefano Zampini     }
880a49dc2a2SStefano Zampini     if (!mat->fwork) {
881a49dc2a2SStefano Zampini       PetscScalar dummy;
882a49dc2a2SStefano Zampini 
883a49dc2a2SStefano Zampini       mat->lfwork = -1;
8849566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
885792fecdfSBarry Smith       PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info));
8869566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
887a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
8889566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
8899566063dSJacob Faibussowitsch       PetscCall(PetscLogObjectMemory((PetscObject)A, mat->lfwork * sizeof(PetscBLASInt)));
890a49dc2a2SStefano Zampini     }
8919566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
892792fecdfSBarry Smith     PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info));
8939566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
894a49dc2a2SStefano Zampini   }
89528b400f6SJacob Faibussowitsch   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad factorization: zero pivot in row %" PetscInt_FMT, (PetscInt)info - 1);
8968208b9aeSStefano Zampini 
8974396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_Cholesky;
8984396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_Cholesky;
8994396437dSToby Isaac   A->ops->solvetranspose    = MatSolveTranspose_SeqDense_Cholesky;
9004396437dSToby Isaac   A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_Cholesky;
901d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_CHOLESKY;
9022205254eSKarl Rupp 
9039566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
9049566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype));
905f6224b95SHong Zhang 
9069566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0));
907db4efbfdSBarry Smith   PetscFunctionReturn(0);
908db4efbfdSBarry Smith }
909db4efbfdSBarry Smith 
9109371c9d4SSatish Balay static PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) {
911db4efbfdSBarry Smith   MatFactorInfo info;
912db4efbfdSBarry Smith 
913db4efbfdSBarry Smith   PetscFunctionBegin;
914db4efbfdSBarry Smith   info.fill = 1.0;
9152205254eSKarl Rupp 
9169566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES));
917dbbe0bcdSBarry Smith   PetscUseTypeMethod(fact, choleskyfactor, NULL, &info);
918db4efbfdSBarry Smith   PetscFunctionReturn(0);
919db4efbfdSBarry Smith }
920db4efbfdSBarry Smith 
9219371c9d4SSatish Balay PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info) {
922db4efbfdSBarry Smith   PetscFunctionBegin;
923c3ef05f6SHong Zhang   fact->assembled                  = PETSC_TRUE;
9241bbcc794SSatish Balay   fact->preallocated               = PETSC_TRUE;
925719d5645SBarry Smith   fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense;
926db4efbfdSBarry Smith   PetscFunctionReturn(0);
927db4efbfdSBarry Smith }
928db4efbfdSBarry Smith 
9299371c9d4SSatish Balay PetscErrorCode MatQRFactor_SeqDense(Mat A, IS col, const MatFactorInfo *minfo) {
9304905a7bcSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
9314905a7bcSToby Isaac   PetscBLASInt  n, m, info, min, max;
9324905a7bcSToby Isaac 
9334905a7bcSToby Isaac   PetscFunctionBegin;
9349566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
9359566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
9364396437dSToby Isaac   max = PetscMax(m, n);
9374396437dSToby Isaac   min = PetscMin(m, n);
9384905a7bcSToby Isaac   if (!mat->tau) {
9399566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(min, &mat->tau));
9409566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)A, min * sizeof(PetscScalar)));
9414396437dSToby Isaac   }
9424396437dSToby Isaac   if (!mat->pivots) {
9439566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n, &mat->pivots));
9449566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)A, n * sizeof(PetscScalar)));
9454396437dSToby Isaac   }
946*48a46eb9SPierre Jolivet   if (!mat->qrrhs) PetscCall(MatCreateVecs(A, NULL, &(mat->qrrhs)));
9474905a7bcSToby Isaac   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
9484905a7bcSToby Isaac   if (!mat->fwork) {
9494905a7bcSToby Isaac     PetscScalar dummy;
9504905a7bcSToby Isaac 
9514905a7bcSToby Isaac     mat->lfwork = -1;
9529566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
953792fecdfSBarry Smith     PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, &dummy, &mat->lfwork, &info));
9549566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
9554905a7bcSToby Isaac     mat->lfwork = (PetscInt)PetscRealPart(dummy);
9569566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
9579566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)A, mat->lfwork * sizeof(PetscBLASInt)));
9584905a7bcSToby Isaac   }
9599566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
960792fecdfSBarry Smith   PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, mat->fwork, &mat->lfwork, &info));
9619566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
96205fcb23eSStefano Zampini   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to QR factorization %d", (int)info);
9634905a7bcSToby 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
9644905a7bcSToby Isaac   mat->rank = min;
9654905a7bcSToby Isaac 
9664396437dSToby Isaac   A->ops->solve    = MatSolve_SeqDense_QR;
9674396437dSToby Isaac   A->ops->matsolve = MatMatSolve_SeqDense_QR;
9684905a7bcSToby Isaac   A->factortype    = MAT_FACTOR_QR;
9694905a7bcSToby Isaac   if (m == n) {
9704396437dSToby Isaac     A->ops->solvetranspose    = MatSolveTranspose_SeqDense_QR;
9714396437dSToby Isaac     A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_QR;
9724905a7bcSToby Isaac   }
9734905a7bcSToby Isaac 
9749566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
9759566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype));
9764905a7bcSToby Isaac 
9779566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0 * min * min * (max - min / 3.0)));
9784905a7bcSToby Isaac   PetscFunctionReturn(0);
9794905a7bcSToby Isaac }
9804905a7bcSToby Isaac 
9819371c9d4SSatish Balay static PetscErrorCode MatQRFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) {
9824905a7bcSToby Isaac   MatFactorInfo info;
9834905a7bcSToby Isaac 
9844905a7bcSToby Isaac   PetscFunctionBegin;
9854905a7bcSToby Isaac   info.fill = 1.0;
9864905a7bcSToby Isaac 
9879566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES));
988cac4c232SBarry Smith   PetscUseMethod(fact, "MatQRFactor_C", (Mat, IS, const MatFactorInfo *), (fact, NULL, &info));
9894905a7bcSToby Isaac   PetscFunctionReturn(0);
9904905a7bcSToby Isaac }
9914905a7bcSToby Isaac 
9929371c9d4SSatish Balay PetscErrorCode MatQRFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info) {
9934905a7bcSToby Isaac   PetscFunctionBegin;
9944905a7bcSToby Isaac   fact->assembled    = PETSC_TRUE;
9954905a7bcSToby Isaac   fact->preallocated = PETSC_TRUE;
9969566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)fact, "MatQRFactorNumeric_C", MatQRFactorNumeric_SeqDense));
9974905a7bcSToby Isaac   PetscFunctionReturn(0);
9984905a7bcSToby Isaac }
9994905a7bcSToby Isaac 
1000ca15aa20SStefano Zampini /* uses LAPACK */
10019371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A, MatFactorType ftype, Mat *fact) {
1002db4efbfdSBarry Smith   PetscFunctionBegin;
10039566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), fact));
10049566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*fact, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n));
10059566063dSJacob Faibussowitsch   PetscCall(MatSetType(*fact, MATDENSE));
100666e17bc3SBarry Smith   (*fact)->trivialsymbolic = PETSC_TRUE;
10072a350339SBarry Smith   if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU) {
1008db4efbfdSBarry Smith     (*fact)->ops->lufactorsymbolic  = MatLUFactorSymbolic_SeqDense;
10092a350339SBarry Smith     (*fact)->ops->ilufactorsymbolic = MatLUFactorSymbolic_SeqDense;
1010bf5a80bcSToby Isaac   } else if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) {
1011db4efbfdSBarry Smith     (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense;
1012bf5a80bcSToby Isaac   } else if (ftype == MAT_FACTOR_QR) {
10139566063dSJacob Faibussowitsch     PetscCall(PetscObjectComposeFunction((PetscObject)(*fact), "MatQRFactorSymbolic_C", MatQRFactorSymbolic_SeqDense));
1014db4efbfdSBarry Smith   }
1015d5f3da31SBarry Smith   (*fact)->factortype = ftype;
101600c67f3bSHong Zhang 
10179566063dSJacob Faibussowitsch   PetscCall(PetscFree((*fact)->solvertype));
10189566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC, &(*fact)->solvertype));
10199566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_LU]));
10209566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ILU]));
10219566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_CHOLESKY]));
10229566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ICC]));
1023db4efbfdSBarry Smith   PetscFunctionReturn(0);
1024db4efbfdSBarry Smith }
1025db4efbfdSBarry Smith 
1026289bc588SBarry Smith /* ------------------------------------------------------------------*/
10279371c9d4SSatish Balay static PetscErrorCode MatSOR_SeqDense(Mat A, Vec bb, PetscReal omega, MatSORType flag, PetscReal shift, PetscInt its, PetscInt lits, Vec xx) {
1028c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1029d9ca1df4SBarry Smith   PetscScalar       *x, *v = mat->v, zero = 0.0, xt;
1030d9ca1df4SBarry Smith   const PetscScalar *b;
1031d0f46423SBarry Smith   PetscInt           m = A->rmap->n, i;
103223fff9afSBarry Smith   PetscBLASInt       o = 1, bm = 0;
1033289bc588SBarry Smith 
10343a40ed3dSBarry Smith   PetscFunctionBegin;
1035ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
103608401ef6SPierre Jolivet   PetscCheck(A->offloadmask != PETSC_OFFLOAD_GPU, PETSC_COMM_SELF, PETSC_ERR_SUP, "Not implemented");
1037ca15aa20SStefano Zampini #endif
1038422a814eSBarry Smith   if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */
10399566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(m, &bm));
1040289bc588SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
10413bffc371SBarry Smith     /* this is a hack fix, should have another version without the second BLASdotu */
10429566063dSJacob Faibussowitsch     PetscCall(VecSet(xx, zero));
1043289bc588SBarry Smith   }
10449566063dSJacob Faibussowitsch   PetscCall(VecGetArray(xx, &x));
10459566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(bb, &b));
1046b965ef7fSBarry Smith   its = its * lits;
104708401ef6SPierre 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);
1048289bc588SBarry Smith   while (its--) {
1049fccaa45eSBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
1050289bc588SBarry Smith       for (i = 0; i < m; i++) {
1051792fecdfSBarry Smith         PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o));
105255a1b374SBarry Smith         x[i] = (1. - omega) * x[i] + omega * (xt + v[i + i * m] * x[i]) / (v[i + i * m] + shift);
1053289bc588SBarry Smith       }
1054289bc588SBarry Smith     }
1055fccaa45eSBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
1056289bc588SBarry Smith       for (i = m - 1; i >= 0; i--) {
1057792fecdfSBarry Smith         PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o));
105855a1b374SBarry Smith         x[i] = (1. - omega) * x[i] + omega * (xt + v[i + i * m] * x[i]) / (v[i + i * m] + shift);
1059289bc588SBarry Smith       }
1060289bc588SBarry Smith     }
1061289bc588SBarry Smith   }
10629566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(bb, &b));
10639566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(xx, &x));
10643a40ed3dSBarry Smith   PetscFunctionReturn(0);
1065289bc588SBarry Smith }
1066289bc588SBarry Smith 
1067289bc588SBarry Smith /* -----------------------------------------------------------------*/
10689371c9d4SSatish Balay PetscErrorCode MatMultTranspose_SeqDense(Mat A, Vec xx, Vec yy) {
1069c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1070d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v, *x;
1071d9ca1df4SBarry Smith   PetscScalar       *y;
10720805154bSBarry Smith   PetscBLASInt       m, n, _One = 1;
1073ea709b57SSatish Balay   PetscScalar        _DOne = 1.0, _DZero = 0.0;
10743a40ed3dSBarry Smith 
10753a40ed3dSBarry Smith   PetscFunctionBegin;
10769566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
10779566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
10789566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx, &x));
10799566063dSJacob Faibussowitsch   PetscCall(VecGetArrayWrite(yy, &y));
10805ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
10815ac36cfcSBarry Smith     PetscBLASInt i;
10825ac36cfcSBarry Smith     for (i = 0; i < n; i++) y[i] = 0.0;
10835ac36cfcSBarry Smith   } else {
1084792fecdfSBarry Smith     PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v, &mat->lda, x, &_One, &_DZero, y, &_One));
10859566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n - A->cmap->n));
10865ac36cfcSBarry Smith   }
10879566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx, &x));
10889566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayWrite(yy, &y));
10893a40ed3dSBarry Smith   PetscFunctionReturn(0);
1090289bc588SBarry Smith }
1091800995b7SMatthew Knepley 
10929371c9d4SSatish Balay PetscErrorCode MatMult_SeqDense(Mat A, Vec xx, Vec yy) {
1093c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1094d9ca1df4SBarry Smith   PetscScalar       *y, _DOne = 1.0, _DZero = 0.0;
10950805154bSBarry Smith   PetscBLASInt       m, n, _One             = 1;
1096d9ca1df4SBarry Smith   const PetscScalar *v = mat->v, *x;
10973a40ed3dSBarry Smith 
10983a40ed3dSBarry Smith   PetscFunctionBegin;
10999566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
11009566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
11019566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx, &x));
11029566063dSJacob Faibussowitsch   PetscCall(VecGetArrayWrite(yy, &y));
11035ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
11045ac36cfcSBarry Smith     PetscBLASInt i;
11055ac36cfcSBarry Smith     for (i = 0; i < m; i++) y[i] = 0.0;
11065ac36cfcSBarry Smith   } else {
1107792fecdfSBarry Smith     PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DZero, y, &_One));
11089566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n - A->rmap->n));
11095ac36cfcSBarry Smith   }
11109566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx, &x));
11119566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayWrite(yy, &y));
11123a40ed3dSBarry Smith   PetscFunctionReturn(0);
1113289bc588SBarry Smith }
11146ee01492SSatish Balay 
11159371c9d4SSatish Balay PetscErrorCode MatMultAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) {
1116c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1117d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v, *x;
1118d9ca1df4SBarry Smith   PetscScalar       *y, _DOne = 1.0;
11190805154bSBarry Smith   PetscBLASInt       m, n, _One = 1;
11203a40ed3dSBarry Smith 
11213a40ed3dSBarry Smith   PetscFunctionBegin;
11229566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
11239566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
11249566063dSJacob Faibussowitsch   PetscCall(VecCopy(zz, yy));
1125d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
11269566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx, &x));
11279566063dSJacob Faibussowitsch   PetscCall(VecGetArray(yy, &y));
1128792fecdfSBarry Smith   PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DOne, y, &_One));
11299566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx, &x));
11309566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(yy, &y));
11319566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n));
11323a40ed3dSBarry Smith   PetscFunctionReturn(0);
1133289bc588SBarry Smith }
11346ee01492SSatish Balay 
11359371c9d4SSatish Balay PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) {
1136c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1137d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v, *x;
1138d9ca1df4SBarry Smith   PetscScalar       *y;
11390805154bSBarry Smith   PetscBLASInt       m, n, _One = 1;
114087828ca2SBarry Smith   PetscScalar        _DOne = 1.0;
11413a40ed3dSBarry Smith 
11423a40ed3dSBarry Smith   PetscFunctionBegin;
11439566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
11449566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
11459566063dSJacob Faibussowitsch   PetscCall(VecCopy(zz, yy));
1146d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
11479566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx, &x));
11489566063dSJacob Faibussowitsch   PetscCall(VecGetArray(yy, &y));
1149792fecdfSBarry Smith   PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DOne, y, &_One));
11509566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx, &x));
11519566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(yy, &y));
11529566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n));
11533a40ed3dSBarry Smith   PetscFunctionReturn(0);
1154289bc588SBarry Smith }
1155289bc588SBarry Smith 
1156289bc588SBarry Smith /* -----------------------------------------------------------------*/
11579371c9d4SSatish Balay static PetscErrorCode MatGetRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals) {
1158c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
115913f74950SBarry Smith   PetscInt      i;
116067e560aaSBarry Smith 
11613a40ed3dSBarry Smith   PetscFunctionBegin;
1162d0f46423SBarry Smith   *ncols = A->cmap->n;
1163289bc588SBarry Smith   if (cols) {
11649566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(A->cmap->n, cols));
1165d0f46423SBarry Smith     for (i = 0; i < A->cmap->n; i++) (*cols)[i] = i;
1166289bc588SBarry Smith   }
1167289bc588SBarry Smith   if (vals) {
1168ca15aa20SStefano Zampini     const PetscScalar *v;
1169ca15aa20SStefano Zampini 
11709566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A, &v));
11719566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(A->cmap->n, vals));
1172ca15aa20SStefano Zampini     v += row;
11739371c9d4SSatish Balay     for (i = 0; i < A->cmap->n; i++) {
11749371c9d4SSatish Balay       (*vals)[i] = *v;
11759371c9d4SSatish Balay       v += mat->lda;
11769371c9d4SSatish Balay     }
11779566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A, &v));
1178289bc588SBarry Smith   }
11793a40ed3dSBarry Smith   PetscFunctionReturn(0);
1180289bc588SBarry Smith }
11816ee01492SSatish Balay 
11829371c9d4SSatish Balay static PetscErrorCode MatRestoreRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals) {
1183606d414cSSatish Balay   PetscFunctionBegin;
1184cb4a9cd9SHong Zhang   if (ncols) *ncols = 0;
11859566063dSJacob Faibussowitsch   if (cols) PetscCall(PetscFree(*cols));
11869566063dSJacob Faibussowitsch   if (vals) PetscCall(PetscFree(*vals));
11873a40ed3dSBarry Smith   PetscFunctionReturn(0);
1188289bc588SBarry Smith }
1189289bc588SBarry Smith /* ----------------------------------------------------------------*/
11909371c9d4SSatish Balay static PetscErrorCode MatSetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], const PetscScalar v[], InsertMode addv) {
1191c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
1192ca15aa20SStefano Zampini   PetscScalar  *av;
119313f74950SBarry Smith   PetscInt      i, j, idx = 0;
1194ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1195c70f7ee4SJunchao Zhang   PetscOffloadMask oldf;
1196ca15aa20SStefano Zampini #endif
1197d6dfbf8fSBarry Smith 
11983a40ed3dSBarry Smith   PetscFunctionBegin;
11999566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &av));
1200289bc588SBarry Smith   if (!mat->roworiented) {
1201dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1202289bc588SBarry Smith       for (j = 0; j < n; j++) {
12039371c9d4SSatish Balay         if (indexn[j] < 0) {
12049371c9d4SSatish Balay           idx += m;
12059371c9d4SSatish Balay           continue;
12069371c9d4SSatish Balay         }
12076bdcaf15SBarry 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);
1208289bc588SBarry Smith         for (i = 0; i < m; i++) {
12099371c9d4SSatish Balay           if (indexm[i] < 0) {
12109371c9d4SSatish Balay             idx++;
12119371c9d4SSatish Balay             continue;
12129371c9d4SSatish Balay           }
12136bdcaf15SBarry 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);
1214ca15aa20SStefano Zampini           av[indexn[j] * mat->lda + indexm[i]] = v[idx++];
1215289bc588SBarry Smith         }
1216289bc588SBarry Smith       }
12173a40ed3dSBarry Smith     } else {
1218289bc588SBarry Smith       for (j = 0; j < n; j++) {
12199371c9d4SSatish Balay         if (indexn[j] < 0) {
12209371c9d4SSatish Balay           idx += m;
12219371c9d4SSatish Balay           continue;
12229371c9d4SSatish Balay         }
12236bdcaf15SBarry 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);
1224289bc588SBarry Smith         for (i = 0; i < m; i++) {
12259371c9d4SSatish Balay           if (indexm[i] < 0) {
12269371c9d4SSatish Balay             idx++;
12279371c9d4SSatish Balay             continue;
12289371c9d4SSatish Balay           }
12296bdcaf15SBarry 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);
1230ca15aa20SStefano Zampini           av[indexn[j] * mat->lda + indexm[i]] += v[idx++];
1231289bc588SBarry Smith         }
1232289bc588SBarry Smith       }
1233289bc588SBarry Smith     }
12343a40ed3dSBarry Smith   } else {
1235dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1236e8d4e0b9SBarry Smith       for (i = 0; i < m; i++) {
12379371c9d4SSatish Balay         if (indexm[i] < 0) {
12389371c9d4SSatish Balay           idx += n;
12399371c9d4SSatish Balay           continue;
12409371c9d4SSatish Balay         }
12416bdcaf15SBarry 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);
1242e8d4e0b9SBarry Smith         for (j = 0; j < n; j++) {
12439371c9d4SSatish Balay           if (indexn[j] < 0) {
12449371c9d4SSatish Balay             idx++;
12459371c9d4SSatish Balay             continue;
12469371c9d4SSatish Balay           }
12476bdcaf15SBarry Smith           PetscCheck(indexn[j] < A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Column too large: col %" PetscInt_FMT " max %" PetscInt_FMT, indexn[j], A->cmap->n - 1);
1248ca15aa20SStefano Zampini           av[indexn[j] * mat->lda + indexm[i]] = v[idx++];
1249e8d4e0b9SBarry Smith         }
1250e8d4e0b9SBarry Smith       }
12513a40ed3dSBarry Smith     } else {
1252289bc588SBarry Smith       for (i = 0; i < m; i++) {
12539371c9d4SSatish Balay         if (indexm[i] < 0) {
12549371c9d4SSatish Balay           idx += n;
12559371c9d4SSatish Balay           continue;
12569371c9d4SSatish Balay         }
12576bdcaf15SBarry 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);
1258289bc588SBarry Smith         for (j = 0; j < n; j++) {
12599371c9d4SSatish Balay           if (indexn[j] < 0) {
12609371c9d4SSatish Balay             idx++;
12619371c9d4SSatish Balay             continue;
12629371c9d4SSatish Balay           }
12636bdcaf15SBarry Smith           PetscCheck(indexn[j] < A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Column too large: col %" PetscInt_FMT " max %" PetscInt_FMT, indexn[j], A->cmap->n - 1);
1264ca15aa20SStefano Zampini           av[indexn[j] * mat->lda + indexm[i]] += v[idx++];
1265289bc588SBarry Smith         }
1266289bc588SBarry Smith       }
1267289bc588SBarry Smith     }
1268e8d4e0b9SBarry Smith   }
1269ca15aa20SStefano Zampini   /* hack to prevent unneeded copy to the GPU while returning the array */
1270ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1271c70f7ee4SJunchao Zhang   oldf           = A->offloadmask;
1272c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_GPU;
1273ca15aa20SStefano Zampini #endif
12749566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &av));
1275ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1276c70f7ee4SJunchao Zhang   A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU);
1277ca15aa20SStefano Zampini #endif
12783a40ed3dSBarry Smith   PetscFunctionReturn(0);
1279289bc588SBarry Smith }
1280e8d4e0b9SBarry Smith 
12819371c9d4SSatish Balay static PetscErrorCode MatGetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], PetscScalar v[]) {
1282ae80bb75SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1283ca15aa20SStefano Zampini   const PetscScalar *vv;
128413f74950SBarry Smith   PetscInt           i, j;
1285ae80bb75SLois Curfman McInnes 
12863a40ed3dSBarry Smith   PetscFunctionBegin;
12879566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &vv));
1288ae80bb75SLois Curfman McInnes   /* row-oriented output */
1289ae80bb75SLois Curfman McInnes   for (i = 0; i < m; i++) {
12909371c9d4SSatish Balay     if (indexm[i] < 0) {
12919371c9d4SSatish Balay       v += n;
12929371c9d4SSatish Balay       continue;
12939371c9d4SSatish Balay     }
129408401ef6SPierre 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);
1295ae80bb75SLois Curfman McInnes     for (j = 0; j < n; j++) {
12969371c9d4SSatish Balay       if (indexn[j] < 0) {
12979371c9d4SSatish Balay         v++;
12989371c9d4SSatish Balay         continue;
12999371c9d4SSatish Balay       }
130008401ef6SPierre 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);
1301ca15aa20SStefano Zampini       *v++ = vv[indexn[j] * mat->lda + indexm[i]];
1302ae80bb75SLois Curfman McInnes     }
1303ae80bb75SLois Curfman McInnes   }
13049566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &vv));
13053a40ed3dSBarry Smith   PetscFunctionReturn(0);
1306ae80bb75SLois Curfman McInnes }
1307ae80bb75SLois Curfman McInnes 
1308289bc588SBarry Smith /* -----------------------------------------------------------------*/
1309289bc588SBarry Smith 
13109371c9d4SSatish Balay PetscErrorCode MatView_Dense_Binary(Mat mat, PetscViewer viewer) {
13118491ab44SLisandro Dalcin   PetscBool          skipHeader;
13128491ab44SLisandro Dalcin   PetscViewerFormat  format;
13138491ab44SLisandro Dalcin   PetscInt           header[4], M, N, m, lda, i, j, k;
13148491ab44SLisandro Dalcin   const PetscScalar *v;
13158491ab44SLisandro Dalcin   PetscScalar       *vwork;
1316aabbc4fbSShri Abhyankar 
1317aabbc4fbSShri Abhyankar   PetscFunctionBegin;
13189566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
13199566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader));
13209566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
13218491ab44SLisandro Dalcin   if (skipHeader) format = PETSC_VIEWER_NATIVE;
1322aabbc4fbSShri Abhyankar 
13239566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat, &M, &N));
13248491ab44SLisandro Dalcin 
13258491ab44SLisandro Dalcin   /* write matrix header */
13269371c9d4SSatish Balay   header[0] = MAT_FILE_CLASSID;
13279371c9d4SSatish Balay   header[1] = M;
13289371c9d4SSatish Balay   header[2] = N;
13298491ab44SLisandro Dalcin   header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M * N;
13309566063dSJacob Faibussowitsch   if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer, header, 4, PETSC_INT));
13318491ab44SLisandro Dalcin 
13329566063dSJacob Faibussowitsch   PetscCall(MatGetLocalSize(mat, &m, NULL));
13338491ab44SLisandro Dalcin   if (format != PETSC_VIEWER_NATIVE) {
13348491ab44SLisandro Dalcin     PetscInt nnz = m * N, *iwork;
13358491ab44SLisandro Dalcin     /* store row lengths for each row */
13369566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nnz, &iwork));
13378491ab44SLisandro Dalcin     for (i = 0; i < m; i++) iwork[i] = N;
13389566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT));
13398491ab44SLisandro Dalcin     /* store column indices (zero start index) */
13408491ab44SLisandro Dalcin     for (k = 0, i = 0; i < m; i++)
13419371c9d4SSatish Balay       for (j = 0; j < N; j++, k++) iwork[k] = j;
13429566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT));
13439566063dSJacob Faibussowitsch     PetscCall(PetscFree(iwork));
13448491ab44SLisandro Dalcin   }
13458491ab44SLisandro Dalcin   /* store matrix values as a dense matrix in row major order */
13469566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(m * N, &vwork));
13479566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(mat, &v));
13489566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(mat, &lda));
13498491ab44SLisandro Dalcin   for (k = 0, i = 0; i < m; i++)
13509371c9d4SSatish Balay     for (j = 0; j < N; j++, k++) vwork[k] = v[i + lda * j];
13519566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(mat, &v));
13529566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryWriteAll(viewer, vwork, m * N, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR));
13539566063dSJacob Faibussowitsch   PetscCall(PetscFree(vwork));
13548491ab44SLisandro Dalcin   PetscFunctionReturn(0);
13558491ab44SLisandro Dalcin }
13568491ab44SLisandro Dalcin 
13579371c9d4SSatish Balay PetscErrorCode MatLoad_Dense_Binary(Mat mat, PetscViewer viewer) {
13588491ab44SLisandro Dalcin   PetscBool    skipHeader;
13598491ab44SLisandro Dalcin   PetscInt     header[4], M, N, m, nz, lda, i, j, k;
13608491ab44SLisandro Dalcin   PetscInt     rows, cols;
13618491ab44SLisandro Dalcin   PetscScalar *v, *vwork;
13628491ab44SLisandro Dalcin 
13638491ab44SLisandro Dalcin   PetscFunctionBegin;
13649566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
13659566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader));
13668491ab44SLisandro Dalcin 
13678491ab44SLisandro Dalcin   if (!skipHeader) {
13689566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryRead(viewer, header, 4, NULL, PETSC_INT));
136908401ef6SPierre Jolivet     PetscCheck(header[0] == MAT_FILE_CLASSID, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Not a matrix object in file");
13709371c9d4SSatish Balay     M = header[1];
13719371c9d4SSatish Balay     N = header[2];
137208401ef6SPierre Jolivet     PetscCheck(M >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix row size (%" PetscInt_FMT ") in file is negative", M);
137308401ef6SPierre Jolivet     PetscCheck(N >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix column size (%" PetscInt_FMT ") in file is negative", N);
13748491ab44SLisandro Dalcin     nz = header[3];
1375aed4548fSBarry Smith     PetscCheck(nz == MATRIX_BINARY_FORMAT_DENSE || nz >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Unknown matrix format %" PetscInt_FMT " in file", nz);
1376aabbc4fbSShri Abhyankar   } else {
13779566063dSJacob Faibussowitsch     PetscCall(MatGetSize(mat, &M, &N));
1378aed4548fSBarry 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");
13798491ab44SLisandro Dalcin     nz = MATRIX_BINARY_FORMAT_DENSE;
1380e6324fbbSBarry Smith   }
1381aabbc4fbSShri Abhyankar 
13828491ab44SLisandro Dalcin   /* setup global sizes if not set */
13838491ab44SLisandro Dalcin   if (mat->rmap->N < 0) mat->rmap->N = M;
13848491ab44SLisandro Dalcin   if (mat->cmap->N < 0) mat->cmap->N = N;
13859566063dSJacob Faibussowitsch   PetscCall(MatSetUp(mat));
13868491ab44SLisandro Dalcin   /* check if global sizes are correct */
13879566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat, &rows, &cols));
1388aed4548fSBarry 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);
1389aabbc4fbSShri Abhyankar 
13909566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat, NULL, &N));
13919566063dSJacob Faibussowitsch   PetscCall(MatGetLocalSize(mat, &m, NULL));
13929566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(mat, &v));
13939566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(mat, &lda));
13948491ab44SLisandro Dalcin   if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense format */
13958491ab44SLisandro Dalcin     PetscInt nnz = m * N;
13968491ab44SLisandro Dalcin     /* read in matrix values */
13979566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nnz, &vwork));
13989566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR));
13998491ab44SLisandro Dalcin     /* store values in column major order */
14008491ab44SLisandro Dalcin     for (j = 0; j < N; j++)
14019371c9d4SSatish Balay       for (i = 0; i < m; i++) v[i + lda * j] = vwork[i * N + j];
14029566063dSJacob Faibussowitsch     PetscCall(PetscFree(vwork));
14038491ab44SLisandro Dalcin   } else { /* matrix in file is sparse format */
14048491ab44SLisandro Dalcin     PetscInt nnz = 0, *rlens, *icols;
14058491ab44SLisandro Dalcin     /* read in row lengths */
14069566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(m, &rlens));
14079566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer, rlens, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT));
14088491ab44SLisandro Dalcin     for (i = 0; i < m; i++) nnz += rlens[i];
14098491ab44SLisandro Dalcin     /* read in column indices and values */
14109566063dSJacob Faibussowitsch     PetscCall(PetscMalloc2(nnz, &icols, nnz, &vwork));
14119566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer, icols, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT));
14129566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR));
14138491ab44SLisandro Dalcin     /* store values in column major order */
14148491ab44SLisandro Dalcin     for (k = 0, i = 0; i < m; i++)
14159371c9d4SSatish Balay       for (j = 0; j < rlens[i]; j++, k++) v[i + lda * icols[k]] = vwork[k];
14169566063dSJacob Faibussowitsch     PetscCall(PetscFree(rlens));
14179566063dSJacob Faibussowitsch     PetscCall(PetscFree2(icols, vwork));
1418aabbc4fbSShri Abhyankar   }
14199566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(mat, &v));
14209566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY));
14219566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY));
1422aabbc4fbSShri Abhyankar   PetscFunctionReturn(0);
1423aabbc4fbSShri Abhyankar }
1424aabbc4fbSShri Abhyankar 
14259371c9d4SSatish Balay PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer) {
1426eb91f321SVaclav Hapla   PetscBool isbinary, ishdf5;
1427eb91f321SVaclav Hapla 
1428eb91f321SVaclav Hapla   PetscFunctionBegin;
1429eb91f321SVaclav Hapla   PetscValidHeaderSpecific(newMat, MAT_CLASSID, 1);
1430eb91f321SVaclav Hapla   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
1431eb91f321SVaclav Hapla   /* force binary viewer to load .info file if it has not yet done so */
14329566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
14339566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
14349566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5));
1435eb91f321SVaclav Hapla   if (isbinary) {
14369566063dSJacob Faibussowitsch     PetscCall(MatLoad_Dense_Binary(newMat, viewer));
1437eb91f321SVaclav Hapla   } else if (ishdf5) {
1438eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5)
14399566063dSJacob Faibussowitsch     PetscCall(MatLoad_Dense_HDF5(newMat, viewer));
1440eb91f321SVaclav Hapla #else
1441eb91f321SVaclav Hapla     SETERRQ(PetscObjectComm((PetscObject)newMat), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5");
1442eb91f321SVaclav Hapla #endif
1443eb91f321SVaclav Hapla   } else {
144498921bdaSJacob 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);
1445eb91f321SVaclav Hapla   }
1446eb91f321SVaclav Hapla   PetscFunctionReturn(0);
1447eb91f321SVaclav Hapla }
1448eb91f321SVaclav Hapla 
14499371c9d4SSatish Balay static PetscErrorCode MatView_SeqDense_ASCII(Mat A, PetscViewer viewer) {
1450932b0c3eSLois Curfman McInnes   Mat_SeqDense     *a = (Mat_SeqDense *)A->data;
145113f74950SBarry Smith   PetscInt          i, j;
14522dcb1b2aSMatthew Knepley   const char       *name;
1453ca15aa20SStefano Zampini   PetscScalar      *v, *av;
1454f3ef73ceSBarry Smith   PetscViewerFormat format;
14555f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX)
1456ace3abfcSBarry Smith   PetscBool allreal = PETSC_TRUE;
14575f481a85SSatish Balay #endif
1458932b0c3eSLois Curfman McInnes 
14593a40ed3dSBarry Smith   PetscFunctionBegin;
14609566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&av));
14619566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
1462456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
14633a40ed3dSBarry Smith     PetscFunctionReturn(0); /* do nothing for now */
1464fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
14659566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
1466d0f46423SBarry Smith     for (i = 0; i < A->rmap->n; i++) {
1467ca15aa20SStefano Zampini       v = av + i;
14689566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "row %" PetscInt_FMT ":", i));
1469d0f46423SBarry Smith       for (j = 0; j < A->cmap->n; j++) {
1470aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1471329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
14729566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g + %g i) ", j, (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v)));
1473329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
14749566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)PetscRealPart(*v)));
14756831982aSBarry Smith         }
147680cd9d93SLois Curfman McInnes #else
1477*48a46eb9SPierre Jolivet         if (*v) PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)*v));
147880cd9d93SLois Curfman McInnes #endif
14791b807ce4Svictorle         v += a->lda;
148080cd9d93SLois Curfman McInnes       }
14819566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
148280cd9d93SLois Curfman McInnes     }
14839566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
14843a40ed3dSBarry Smith   } else {
14859566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
1486aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
148747989497SBarry Smith     /* determine if matrix has all real values */
1488bcd8d3a4SJose E. Roman     for (j = 0; j < A->cmap->n; j++) {
1489bcd8d3a4SJose E. Roman       v = av + j * a->lda;
1490bcd8d3a4SJose E. Roman       for (i = 0; i < A->rmap->n; i++) {
14919371c9d4SSatish Balay         if (PetscImaginaryPart(v[i])) {
14929371c9d4SSatish Balay           allreal = PETSC_FALSE;
14939371c9d4SSatish Balay           break;
14949371c9d4SSatish Balay         }
149547989497SBarry Smith       }
1496bcd8d3a4SJose E. Roman     }
149747989497SBarry Smith #endif
1498fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
14999566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetName((PetscObject)A, &name));
15009566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%% Size = %" PetscInt_FMT " %" PetscInt_FMT " \n", A->rmap->n, A->cmap->n));
15019566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%s = zeros(%" PetscInt_FMT ",%" PetscInt_FMT ");\n", name, A->rmap->n, A->cmap->n));
15029566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%s = [\n", name));
1503ffac6cdbSBarry Smith     }
1504ffac6cdbSBarry Smith 
1505d0f46423SBarry Smith     for (i = 0; i < A->rmap->n; i++) {
1506ca15aa20SStefano Zampini       v = av + i;
1507d0f46423SBarry Smith       for (j = 0; j < A->cmap->n; j++) {
1508aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
150947989497SBarry Smith         if (allreal) {
15109566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)PetscRealPart(*v)));
151147989497SBarry Smith         } else {
15129566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e + %18.16ei ", (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v)));
151347989497SBarry Smith         }
1514289bc588SBarry Smith #else
15159566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)*v));
1516289bc588SBarry Smith #endif
15171b807ce4Svictorle         v += a->lda;
1518289bc588SBarry Smith       }
15199566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
1520289bc588SBarry Smith     }
1521*48a46eb9SPierre Jolivet     if (format == PETSC_VIEWER_ASCII_MATLAB) PetscCall(PetscViewerASCIIPrintf(viewer, "];\n"));
15229566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
1523da3a660dSBarry Smith   }
15249566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&av));
15259566063dSJacob Faibussowitsch   PetscCall(PetscViewerFlush(viewer));
15263a40ed3dSBarry Smith   PetscFunctionReturn(0);
1527289bc588SBarry Smith }
1528289bc588SBarry Smith 
15299804daf3SBarry Smith #include <petscdraw.h>
15309371c9d4SSatish Balay static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw, void *Aa) {
1531f1af5d2fSBarry Smith   Mat                A = (Mat)Aa;
1532383922c3SLisandro Dalcin   PetscInt           m = A->rmap->n, n = A->cmap->n, i, j;
1533383922c3SLisandro Dalcin   int                color = PETSC_DRAW_WHITE;
1534ca15aa20SStefano Zampini   const PetscScalar *v;
1535b0a32e0cSBarry Smith   PetscViewer        viewer;
1536b05fc000SLisandro Dalcin   PetscReal          xl, yl, xr, yr, x_l, x_r, y_l, y_r;
1537f3ef73ceSBarry Smith   PetscViewerFormat  format;
1538f1af5d2fSBarry Smith 
1539f1af5d2fSBarry Smith   PetscFunctionBegin;
15409566063dSJacob Faibussowitsch   PetscCall(PetscObjectQuery((PetscObject)A, "Zoomviewer", (PetscObject *)&viewer));
15419566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
15429566063dSJacob Faibussowitsch   PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr));
1543f1af5d2fSBarry Smith 
1544f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
15459566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &v));
1546fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
1547d0609cedSBarry Smith     PetscDrawCollectiveBegin(draw);
1548f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
1549f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
15509371c9d4SSatish Balay       x_l = j;
15519371c9d4SSatish Balay       x_r = x_l + 1.0;
1552f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1553f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1554f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1555ca15aa20SStefano Zampini         if (PetscRealPart(v[j * m + i]) > 0.) color = PETSC_DRAW_RED;
1556ca15aa20SStefano Zampini         else if (PetscRealPart(v[j * m + i]) < 0.) color = PETSC_DRAW_BLUE;
1557ca15aa20SStefano Zampini         else continue;
15589566063dSJacob Faibussowitsch         PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color));
1559f1af5d2fSBarry Smith       }
1560f1af5d2fSBarry Smith     }
1561d0609cedSBarry Smith     PetscDrawCollectiveEnd(draw);
1562f1af5d2fSBarry Smith   } else {
1563f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
1564f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
1565b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1566b05fc000SLisandro Dalcin     PetscDraw popup;
1567b05fc000SLisandro Dalcin 
1568f1af5d2fSBarry Smith     for (i = 0; i < m * n; i++) {
1569f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
1570f1af5d2fSBarry Smith     }
1571383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
15729566063dSJacob Faibussowitsch     PetscCall(PetscDrawGetPopup(draw, &popup));
15739566063dSJacob Faibussowitsch     PetscCall(PetscDrawScalePopup(popup, minv, maxv));
1574383922c3SLisandro Dalcin 
1575d0609cedSBarry Smith     PetscDrawCollectiveBegin(draw);
1576f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
1577f1af5d2fSBarry Smith       x_l = j;
1578f1af5d2fSBarry Smith       x_r = x_l + 1.0;
1579f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1580f1af5d2fSBarry Smith         y_l   = m - i - 1.0;
1581f1af5d2fSBarry Smith         y_r   = y_l + 1.0;
1582b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(v[j * m + i]), minv, maxv);
15839566063dSJacob Faibussowitsch         PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color));
1584f1af5d2fSBarry Smith       }
1585f1af5d2fSBarry Smith     }
1586d0609cedSBarry Smith     PetscDrawCollectiveEnd(draw);
1587f1af5d2fSBarry Smith   }
15889566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &v));
1589f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1590f1af5d2fSBarry Smith }
1591f1af5d2fSBarry Smith 
15929371c9d4SSatish Balay static PetscErrorCode MatView_SeqDense_Draw(Mat A, PetscViewer viewer) {
1593b0a32e0cSBarry Smith   PetscDraw draw;
1594ace3abfcSBarry Smith   PetscBool isnull;
1595329f5518SBarry Smith   PetscReal xr, yr, xl, yl, h, w;
1596f1af5d2fSBarry Smith 
1597f1af5d2fSBarry Smith   PetscFunctionBegin;
15989566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
15999566063dSJacob Faibussowitsch   PetscCall(PetscDrawIsNull(draw, &isnull));
1600abc0a331SBarry Smith   if (isnull) PetscFunctionReturn(0);
1601f1af5d2fSBarry Smith 
16029371c9d4SSatish Balay   xr = A->cmap->n;
16039371c9d4SSatish Balay   yr = A->rmap->n;
16049371c9d4SSatish Balay   h  = yr / 10.0;
16059371c9d4SSatish Balay   w  = xr / 10.0;
16069371c9d4SSatish Balay   xr += w;
16079371c9d4SSatish Balay   yr += h;
16089371c9d4SSatish Balay   xl = -w;
16099371c9d4SSatish Balay   yl = -h;
16109566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetCoordinates(draw, xl, yl, xr, yr));
16119566063dSJacob Faibussowitsch   PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", (PetscObject)viewer));
16129566063dSJacob Faibussowitsch   PetscCall(PetscDrawZoom(draw, MatView_SeqDense_Draw_Zoom, A));
16139566063dSJacob Faibussowitsch   PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", NULL));
16149566063dSJacob Faibussowitsch   PetscCall(PetscDrawSave(draw));
1615f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1616f1af5d2fSBarry Smith }
1617f1af5d2fSBarry Smith 
16189371c9d4SSatish Balay PetscErrorCode MatView_SeqDense(Mat A, PetscViewer viewer) {
1619ace3abfcSBarry Smith   PetscBool iascii, isbinary, isdraw;
1620932b0c3eSLois Curfman McInnes 
16213a40ed3dSBarry Smith   PetscFunctionBegin;
16229566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
16239566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
16249566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
16251baa6e33SBarry Smith   if (iascii) PetscCall(MatView_SeqDense_ASCII(A, viewer));
16261baa6e33SBarry Smith   else if (isbinary) PetscCall(MatView_Dense_Binary(A, viewer));
16271baa6e33SBarry Smith   else if (isdraw) PetscCall(MatView_SeqDense_Draw(A, viewer));
16283a40ed3dSBarry Smith   PetscFunctionReturn(0);
1629932b0c3eSLois Curfman McInnes }
1630289bc588SBarry Smith 
16319371c9d4SSatish Balay static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A, const PetscScalar *array) {
1632d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
1633d3042a70SBarry Smith 
1634d3042a70SBarry Smith   PetscFunctionBegin;
163528b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
163628b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
163728b400f6SJacob Faibussowitsch   PetscCheck(!a->unplacedarray, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreArray() first");
1638d3042a70SBarry Smith   a->unplacedarray       = a->v;
1639d3042a70SBarry Smith   a->unplaced_user_alloc = a->user_alloc;
1640d3042a70SBarry Smith   a->v                   = (PetscScalar *)array;
1641637a0070SStefano Zampini   a->user_alloc          = PETSC_TRUE;
1642ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1643c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1644ca15aa20SStefano Zampini #endif
1645d3042a70SBarry Smith   PetscFunctionReturn(0);
1646d3042a70SBarry Smith }
1647d3042a70SBarry Smith 
16489371c9d4SSatish Balay static PetscErrorCode MatDenseResetArray_SeqDense(Mat A) {
1649d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
1650d3042a70SBarry Smith 
1651d3042a70SBarry Smith   PetscFunctionBegin;
165228b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
165328b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
1654d3042a70SBarry Smith   a->v             = a->unplacedarray;
1655d3042a70SBarry Smith   a->user_alloc    = a->unplaced_user_alloc;
1656d3042a70SBarry Smith   a->unplacedarray = NULL;
1657ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1658c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1659ca15aa20SStefano Zampini #endif
1660d3042a70SBarry Smith   PetscFunctionReturn(0);
1661d3042a70SBarry Smith }
1662d3042a70SBarry Smith 
16639371c9d4SSatish Balay static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A, const PetscScalar *array) {
1664d5ea218eSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
1665d5ea218eSStefano Zampini 
1666d5ea218eSStefano Zampini   PetscFunctionBegin;
166728b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
166828b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
16699566063dSJacob Faibussowitsch   if (!a->user_alloc) PetscCall(PetscFree(a->v));
1670d5ea218eSStefano Zampini   a->v          = (PetscScalar *)array;
1671d5ea218eSStefano Zampini   a->user_alloc = PETSC_FALSE;
1672d5ea218eSStefano Zampini #if defined(PETSC_HAVE_CUDA)
1673d5ea218eSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
1674d5ea218eSStefano Zampini #endif
1675d5ea218eSStefano Zampini   PetscFunctionReturn(0);
1676d5ea218eSStefano Zampini }
1677d5ea218eSStefano Zampini 
16789371c9d4SSatish Balay PetscErrorCode MatDestroy_SeqDense(Mat mat) {
1679ec8511deSBarry Smith   Mat_SeqDense *l = (Mat_SeqDense *)mat->data;
168090f02eecSBarry Smith 
16813a40ed3dSBarry Smith   PetscFunctionBegin;
1682aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1683c0aa6a63SJacob Faibussowitsch   PetscLogObjectState((PetscObject)mat, "Rows %" PetscInt_FMT " Cols %" PetscInt_FMT, mat->rmap->n, mat->cmap->n);
1684a5a9c739SBarry Smith #endif
16859566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(l->qrrhs)));
16869566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->tau));
16879566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->pivots));
16889566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->fwork));
16899566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&l->ptapwork));
16909566063dSJacob Faibussowitsch   if (!l->user_alloc) PetscCall(PetscFree(l->v));
16919566063dSJacob Faibussowitsch   if (!l->unplaced_user_alloc) PetscCall(PetscFree(l->unplacedarray));
169228b400f6SJacob Faibussowitsch   PetscCheck(!l->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
169328b400f6SJacob Faibussowitsch   PetscCheck(!l->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
16949566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&l->cvec));
16959566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&l->cmat));
16969566063dSJacob Faibussowitsch   PetscCall(PetscFree(mat->data));
1697dbd8c25aSHong Zhang 
16989566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)mat, NULL));
16999566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactor_C", NULL));
17002e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorSymbolic_C", NULL));
17012e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorNumeric_C", NULL));
17029566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetLDA_C", NULL));
17039566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseSetLDA_C", NULL));
17049566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArray_C", NULL));
17059566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArray_C", NULL));
17069566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDensePlaceArray_C", NULL));
17079566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseResetArray_C", NULL));
17089566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseReplaceArray_C", NULL));
17099566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayRead_C", NULL));
17109566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayRead_C", NULL));
17119566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayWrite_C", NULL));
17129566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayWrite_C", NULL));
17139566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqaij_C", NULL));
17148baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
17159566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_elemental_C", NULL));
17168baccfbdSHong Zhang #endif
1717d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
17189566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_scalapack_C", NULL));
1719d24d4204SJose E. Roman #endif
17202bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
17219566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensecuda_C", NULL));
17229566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", NULL));
17239566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdense_C", NULL));
17242e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensecuda_C", NULL));
17252bf066beSStefano Zampini #endif
17269566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatSeqDenseSetPreallocation_C", NULL));
17279566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqaij_seqdense_C", NULL));
17289566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdense_C", NULL));
17299566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqbaij_seqdense_C", NULL));
17309566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqsbaij_seqdense_C", NULL));
173152c5f739Sprj- 
17329566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumn_C", NULL));
17339566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumn_C", NULL));
17349566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVec_C", NULL));
17359566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVec_C", NULL));
17369566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecRead_C", NULL));
17379566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecRead_C", NULL));
17389566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecWrite_C", NULL));
17399566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecWrite_C", NULL));
17409566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetSubMatrix_C", NULL));
17419566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreSubMatrix_C", NULL));
17423a40ed3dSBarry Smith   PetscFunctionReturn(0);
1743289bc588SBarry Smith }
1744289bc588SBarry Smith 
17459371c9d4SSatish Balay static PetscErrorCode MatTranspose_SeqDense(Mat A, MatReuse reuse, Mat *matout) {
1746c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
17476536e3caSStefano Zampini   PetscInt      k, j, m = A->rmap->n, M = mat->lda, n = A->cmap->n;
174887828ca2SBarry Smith   PetscScalar  *v, tmp;
174948b35521SBarry Smith 
17503a40ed3dSBarry Smith   PetscFunctionBegin;
17517fb60732SBarry Smith   if (reuse == MAT_REUSE_MATRIX) PetscCall(MatTransposeCheckNonzeroState_Private(A, *matout));
17526536e3caSStefano Zampini   if (reuse == MAT_INPLACE_MATRIX) {
17536536e3caSStefano Zampini     if (m == n) { /* in place transpose */
17549566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(A, &v));
1755d3e5ee88SLois Curfman McInnes       for (j = 0; j < m; j++) {
1756289bc588SBarry Smith         for (k = 0; k < j; k++) {
17571b807ce4Svictorle           tmp          = v[j + k * M];
17581b807ce4Svictorle           v[j + k * M] = v[k + j * M];
17591b807ce4Svictorle           v[k + j * M] = tmp;
1760289bc588SBarry Smith         }
1761289bc588SBarry Smith       }
17629566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArray(A, &v));
17636536e3caSStefano Zampini     } else { /* reuse memory, temporary allocates new memory */
17646536e3caSStefano Zampini       PetscScalar *v2;
17656536e3caSStefano Zampini       PetscLayout  tmplayout;
17666536e3caSStefano Zampini 
17679566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1((size_t)m * n, &v2));
17689566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(A, &v));
17696536e3caSStefano Zampini       for (j = 0; j < n; j++) {
17706536e3caSStefano Zampini         for (k = 0; k < m; k++) v2[j + (size_t)k * n] = v[k + (size_t)j * M];
17716536e3caSStefano Zampini       }
17729566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(v, v2, (size_t)m * n));
17739566063dSJacob Faibussowitsch       PetscCall(PetscFree(v2));
17749566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArray(A, &v));
17756536e3caSStefano Zampini       /* cleanup size dependent quantities */
17769566063dSJacob Faibussowitsch       PetscCall(VecDestroy(&mat->cvec));
17779566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&mat->cmat));
17789566063dSJacob Faibussowitsch       PetscCall(PetscFree(mat->pivots));
17799566063dSJacob Faibussowitsch       PetscCall(PetscFree(mat->fwork));
17809566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&mat->ptapwork));
17816536e3caSStefano Zampini       /* swap row/col layouts */
17826536e3caSStefano Zampini       mat->lda  = n;
17836536e3caSStefano Zampini       tmplayout = A->rmap;
17846536e3caSStefano Zampini       A->rmap   = A->cmap;
17856536e3caSStefano Zampini       A->cmap   = tmplayout;
17866536e3caSStefano Zampini     }
17873a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1788d3e5ee88SLois Curfman McInnes     Mat           tmat;
1789ec8511deSBarry Smith     Mat_SeqDense *tmatd;
179087828ca2SBarry Smith     PetscScalar  *v2;
1791af36a384SStefano Zampini     PetscInt      M2;
1792ea709b57SSatish Balay 
17936536e3caSStefano Zampini     if (reuse == MAT_INITIAL_MATRIX) {
17949566063dSJacob Faibussowitsch       PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &tmat));
17959566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(tmat, A->cmap->n, A->rmap->n, A->cmap->n, A->rmap->n));
17969566063dSJacob Faibussowitsch       PetscCall(MatSetType(tmat, ((PetscObject)A)->type_name));
17979566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSetPreallocation(tmat, NULL));
1798ca15aa20SStefano Zampini     } else tmat = *matout;
1799ca15aa20SStefano Zampini 
18009566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&v));
18019566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArray(tmat, &v2));
1802ec8511deSBarry Smith     tmatd = (Mat_SeqDense *)tmat->data;
1803ca15aa20SStefano Zampini     M2    = tmatd->lda;
1804d3e5ee88SLois Curfman McInnes     for (j = 0; j < n; j++) {
1805af36a384SStefano Zampini       for (k = 0; k < m; k++) v2[j + k * M2] = v[k + j * M];
1806d3e5ee88SLois Curfman McInnes     }
18079566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(tmat, &v2));
18089566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&v));
18099566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(tmat, MAT_FINAL_ASSEMBLY));
18109566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(tmat, MAT_FINAL_ASSEMBLY));
18116536e3caSStefano Zampini     *matout = tmat;
181248b35521SBarry Smith   }
18133a40ed3dSBarry Smith   PetscFunctionReturn(0);
1814289bc588SBarry Smith }
1815289bc588SBarry Smith 
18169371c9d4SSatish Balay static PetscErrorCode MatEqual_SeqDense(Mat A1, Mat A2, PetscBool *flg) {
1817c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat1 = (Mat_SeqDense *)A1->data;
1818c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat2 = (Mat_SeqDense *)A2->data;
1819ca15aa20SStefano Zampini   PetscInt           i;
1820ca15aa20SStefano Zampini   const PetscScalar *v1, *v2;
18219ea5d5aeSSatish Balay 
18223a40ed3dSBarry Smith   PetscFunctionBegin;
18239371c9d4SSatish Balay   if (A1->rmap->n != A2->rmap->n) {
18249371c9d4SSatish Balay     *flg = PETSC_FALSE;
18259371c9d4SSatish Balay     PetscFunctionReturn(0);
18269371c9d4SSatish Balay   }
18279371c9d4SSatish Balay   if (A1->cmap->n != A2->cmap->n) {
18289371c9d4SSatish Balay     *flg = PETSC_FALSE;
18299371c9d4SSatish Balay     PetscFunctionReturn(0);
18309371c9d4SSatish Balay   }
18319566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A1, &v1));
18329566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A2, &v2));
1833ca15aa20SStefano Zampini   for (i = 0; i < A1->cmap->n; i++) {
18349566063dSJacob Faibussowitsch     PetscCall(PetscArraycmp(v1, v2, A1->rmap->n, flg));
1835ca15aa20SStefano Zampini     if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
1836ca15aa20SStefano Zampini     v1 += mat1->lda;
1837ca15aa20SStefano Zampini     v2 += mat2->lda;
18381b807ce4Svictorle   }
18399566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A1, &v1));
18409566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A2, &v2));
184177c4ece6SBarry Smith   *flg = PETSC_TRUE;
18423a40ed3dSBarry Smith   PetscFunctionReturn(0);
1843289bc588SBarry Smith }
1844289bc588SBarry Smith 
18459371c9d4SSatish Balay static PetscErrorCode MatGetDiagonal_SeqDense(Mat A, Vec v) {
1846c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
184713f74950SBarry Smith   PetscInt           i, n, len;
1848ca15aa20SStefano Zampini   PetscScalar       *x;
1849ca15aa20SStefano Zampini   const PetscScalar *vv;
185044cd7ae7SLois Curfman McInnes 
18513a40ed3dSBarry Smith   PetscFunctionBegin;
18529566063dSJacob Faibussowitsch   PetscCall(VecGetSize(v, &n));
18539566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
1854d0f46423SBarry Smith   len = PetscMin(A->rmap->n, A->cmap->n);
18559566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &vv));
185608401ef6SPierre Jolivet   PetscCheck(n == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming mat and vec");
18579371c9d4SSatish Balay   for (i = 0; i < len; i++) { x[i] = vv[i * mat->lda + i]; }
18589566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &vv));
18599566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
18603a40ed3dSBarry Smith   PetscFunctionReturn(0);
1861289bc588SBarry Smith }
1862289bc588SBarry Smith 
18639371c9d4SSatish Balay static PetscErrorCode MatDiagonalScale_SeqDense(Mat A, Vec ll, Vec rr) {
1864c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1865f1ceaac6SMatthew G. Knepley   const PetscScalar *l, *r;
1866ca15aa20SStefano Zampini   PetscScalar        x, *v, *vv;
1867d0f46423SBarry Smith   PetscInt           i, j, m = A->rmap->n, n = A->cmap->n;
186855659b69SBarry Smith 
18693a40ed3dSBarry Smith   PetscFunctionBegin;
18709566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &vv));
187128988994SBarry Smith   if (ll) {
18729566063dSJacob Faibussowitsch     PetscCall(VecGetSize(ll, &m));
18739566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ll, &l));
187408401ef6SPierre Jolivet     PetscCheck(m == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Left scaling vec wrong size");
1875da3a660dSBarry Smith     for (i = 0; i < m; i++) {
1876da3a660dSBarry Smith       x = l[i];
1877ca15aa20SStefano Zampini       v = vv + i;
18789371c9d4SSatish Balay       for (j = 0; j < n; j++) {
18799371c9d4SSatish Balay         (*v) *= x;
18809371c9d4SSatish Balay         v += mat->lda;
18819371c9d4SSatish Balay       }
1882da3a660dSBarry Smith     }
18839566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ll, &l));
18849566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0 * n * m));
1885da3a660dSBarry Smith   }
188628988994SBarry Smith   if (rr) {
18879566063dSJacob Faibussowitsch     PetscCall(VecGetSize(rr, &n));
18889566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(rr, &r));
188908401ef6SPierre Jolivet     PetscCheck(n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Right scaling vec wrong size");
1890da3a660dSBarry Smith     for (i = 0; i < n; i++) {
1891da3a660dSBarry Smith       x = r[i];
1892ca15aa20SStefano Zampini       v = vv + i * mat->lda;
18932205254eSKarl Rupp       for (j = 0; j < m; j++) (*v++) *= x;
1894da3a660dSBarry Smith     }
18959566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(rr, &r));
18969566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0 * n * m));
1897da3a660dSBarry Smith   }
18989566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &vv));
18993a40ed3dSBarry Smith   PetscFunctionReturn(0);
1900289bc588SBarry Smith }
1901289bc588SBarry Smith 
19029371c9d4SSatish Balay PetscErrorCode MatNorm_SeqDense(Mat A, NormType type, PetscReal *nrm) {
1903c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
1904ca15aa20SStefano Zampini   PetscScalar  *v, *vv;
1905329f5518SBarry Smith   PetscReal     sum = 0.0;
190675f6d85dSStefano Zampini   PetscInt      lda, m = A->rmap->n, i, j;
190755659b69SBarry Smith 
19083a40ed3dSBarry Smith   PetscFunctionBegin;
19099566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&vv));
19109566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(A, &lda));
1911ca15aa20SStefano Zampini   v = vv;
1912289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1913a5ce6ee0Svictorle     if (lda > m) {
1914d0f46423SBarry Smith       for (j = 0; j < A->cmap->n; j++) {
1915ca15aa20SStefano Zampini         v = vv + j * lda;
1916a5ce6ee0Svictorle         for (i = 0; i < m; i++) {
19179371c9d4SSatish Balay           sum += PetscRealPart(PetscConj(*v) * (*v));
19189371c9d4SSatish Balay           v++;
1919a5ce6ee0Svictorle         }
1920a5ce6ee0Svictorle       }
1921a5ce6ee0Svictorle     } else {
1922570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1923570b7f6dSBarry Smith       PetscBLASInt one = 1, cnt = A->cmap->n * A->rmap->n;
1924792fecdfSBarry Smith       PetscCallBLAS("BLASnrm2", *nrm = BLASnrm2_(&cnt, v, &one));
1925570b7f6dSBarry Smith     }
1926570b7f6dSBarry Smith #else
1927d0f46423SBarry Smith       for (i = 0; i < A->cmap->n * A->rmap->n; i++) {
19289371c9d4SSatish Balay         sum += PetscRealPart(PetscConj(*v) * (*v));
19299371c9d4SSatish Balay         v++;
1930289bc588SBarry Smith       }
1931a5ce6ee0Svictorle     }
19328f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1933570b7f6dSBarry Smith #endif
19349566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0 * A->cmap->n * A->rmap->n));
19353a40ed3dSBarry Smith   } else if (type == NORM_1) {
1936064f8208SBarry Smith     *nrm = 0.0;
1937d0f46423SBarry Smith     for (j = 0; j < A->cmap->n; j++) {
1938ca15aa20SStefano Zampini       v   = vv + j * mat->lda;
1939289bc588SBarry Smith       sum = 0.0;
1940d0f46423SBarry Smith       for (i = 0; i < A->rmap->n; i++) {
19419371c9d4SSatish Balay         sum += PetscAbsScalar(*v);
19429371c9d4SSatish Balay         v++;
1943289bc588SBarry Smith       }
1944064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1945289bc588SBarry Smith     }
19469566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n));
19473a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1948064f8208SBarry Smith     *nrm = 0.0;
1949d0f46423SBarry Smith     for (j = 0; j < A->rmap->n; j++) {
1950ca15aa20SStefano Zampini       v   = vv + j;
1951289bc588SBarry Smith       sum = 0.0;
1952d0f46423SBarry Smith       for (i = 0; i < A->cmap->n; i++) {
19539371c9d4SSatish Balay         sum += PetscAbsScalar(*v);
19549371c9d4SSatish Balay         v += mat->lda;
1955289bc588SBarry Smith       }
1956064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1957289bc588SBarry Smith     }
19589566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n));
1959e7e72b3dSBarry Smith   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "No two norm");
19609566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&vv));
19613a40ed3dSBarry Smith   PetscFunctionReturn(0);
1962289bc588SBarry Smith }
1963289bc588SBarry Smith 
19649371c9d4SSatish Balay static PetscErrorCode MatSetOption_SeqDense(Mat A, MatOption op, PetscBool flg) {
1965c0bbcb79SLois Curfman McInnes   Mat_SeqDense *aij = (Mat_SeqDense *)A->data;
196667e560aaSBarry Smith 
19673a40ed3dSBarry Smith   PetscFunctionBegin;
1968b5a2b587SKris Buschelman   switch (op) {
19699371c9d4SSatish Balay   case MAT_ROW_ORIENTED: aij->roworiented = flg; break;
1970512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1971b5a2b587SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
19723971808eSMatthew Knepley   case MAT_NEW_NONZERO_ALLOCATION_ERR:
19738c78258cSHong Zhang   case MAT_FORCE_DIAGONAL_ENTRIES:
197413fa8e87SLisandro Dalcin   case MAT_KEEP_NONZERO_PATTERN:
1975b5a2b587SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1976b5a2b587SKris Buschelman   case MAT_USE_HASH_TABLE:
19770f8fb01aSBarry Smith   case MAT_IGNORE_ZERO_ENTRIES:
19785021d80fSJed Brown   case MAT_IGNORE_LOWER_TRIANGULAR:
19799371c9d4SSatish Balay   case MAT_SORTED_FULL: PetscCall(PetscInfo(A, "Option %s ignored\n", MatOptions[op])); break;
19805021d80fSJed Brown   case MAT_SPD:
198177e54ba9SKris Buschelman   case MAT_SYMMETRIC:
198277e54ba9SKris Buschelman   case MAT_STRUCTURALLY_SYMMETRIC:
19839a4540c5SBarry Smith   case MAT_HERMITIAN:
19849a4540c5SBarry Smith   case MAT_SYMMETRY_ETERNAL:
1985b94d7dedSBarry Smith   case MAT_STRUCTURAL_SYMMETRY_ETERNAL:
19869371c9d4SSatish Balay   case MAT_SPD_ETERNAL: break;
19879371c9d4SSatish Balay   default: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "unknown option %s", MatOptions[op]);
19883a40ed3dSBarry Smith   }
19893a40ed3dSBarry Smith   PetscFunctionReturn(0);
1990289bc588SBarry Smith }
1991289bc588SBarry Smith 
19929371c9d4SSatish Balay PetscErrorCode MatZeroEntries_SeqDense(Mat A) {
1993ec8511deSBarry Smith   Mat_SeqDense *l   = (Mat_SeqDense *)A->data;
19943d8925e7SStefano Zampini   PetscInt      lda = l->lda, m = A->rmap->n, n = A->cmap->n, j;
1995ca15aa20SStefano Zampini   PetscScalar  *v;
19963a40ed3dSBarry Smith 
19973a40ed3dSBarry Smith   PetscFunctionBegin;
19989566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(A, &v));
1999a5ce6ee0Svictorle   if (lda > m) {
2000*48a46eb9SPierre Jolivet     for (j = 0; j < n; j++) PetscCall(PetscArrayzero(v + j * lda, m));
2001a5ce6ee0Svictorle   } else {
20029566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(v, PetscInt64Mult(m, n)));
2003a5ce6ee0Svictorle   }
20049566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(A, &v));
20053a40ed3dSBarry Smith   PetscFunctionReturn(0);
20066f0a148fSBarry Smith }
20076f0a148fSBarry Smith 
20089371c9d4SSatish Balay static PetscErrorCode MatZeroRows_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) {
2009ec8511deSBarry Smith   Mat_SeqDense      *l = (Mat_SeqDense *)A->data;
2010b9679d65SBarry Smith   PetscInt           m = l->lda, n = A->cmap->n, i, j;
2011ca15aa20SStefano Zampini   PetscScalar       *slot, *bb, *v;
201297b48c8fSBarry Smith   const PetscScalar *xx;
201355659b69SBarry Smith 
20143a40ed3dSBarry Smith   PetscFunctionBegin;
201576bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
2016b9679d65SBarry Smith     for (i = 0; i < N; i++) {
201708401ef6SPierre Jolivet       PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed");
201808401ef6SPierre 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);
2019b9679d65SBarry Smith     }
202076bd3646SJed Brown   }
2021ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
2022b9679d65SBarry Smith 
202397b48c8fSBarry Smith   /* fix right hand side if needed */
202497b48c8fSBarry Smith   if (x && b) {
20259566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(x, &xx));
20269566063dSJacob Faibussowitsch     PetscCall(VecGetArray(b, &bb));
20272205254eSKarl Rupp     for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]];
20289566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(x, &xx));
20299566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(b, &bb));
203097b48c8fSBarry Smith   }
203197b48c8fSBarry Smith 
20329566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
20336f0a148fSBarry Smith   for (i = 0; i < N; i++) {
2034ca15aa20SStefano Zampini     slot = v + rows[i];
20359371c9d4SSatish Balay     for (j = 0; j < n; j++) {
20369371c9d4SSatish Balay       *slot = 0.0;
20379371c9d4SSatish Balay       slot += m;
20389371c9d4SSatish Balay     }
20396f0a148fSBarry Smith   }
2040f4df32b1SMatthew Knepley   if (diag != 0.0) {
204108401ef6SPierre Jolivet     PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices");
20426f0a148fSBarry Smith     for (i = 0; i < N; i++) {
2043ca15aa20SStefano Zampini       slot  = v + (m + 1) * rows[i];
2044f4df32b1SMatthew Knepley       *slot = diag;
20456f0a148fSBarry Smith     }
20466f0a148fSBarry Smith   }
20479566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
20483a40ed3dSBarry Smith   PetscFunctionReturn(0);
20496f0a148fSBarry Smith }
2050557bce09SLois Curfman McInnes 
20519371c9d4SSatish Balay static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A, PetscInt *lda) {
205249a6ff4bSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
205349a6ff4bSBarry Smith 
205449a6ff4bSBarry Smith   PetscFunctionBegin;
205549a6ff4bSBarry Smith   *lda = mat->lda;
205649a6ff4bSBarry Smith   PetscFunctionReturn(0);
205749a6ff4bSBarry Smith }
205849a6ff4bSBarry Smith 
20599371c9d4SSatish Balay PetscErrorCode MatDenseGetArray_SeqDense(Mat A, PetscScalar **array) {
2060c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
20613a40ed3dSBarry Smith 
20623a40ed3dSBarry Smith   PetscFunctionBegin;
206328b400f6SJacob Faibussowitsch   PetscCheck(!mat->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
206464e87e97SBarry Smith   *array = mat->v;
20653a40ed3dSBarry Smith   PetscFunctionReturn(0);
206664e87e97SBarry Smith }
20670754003eSLois Curfman McInnes 
20689371c9d4SSatish Balay PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A, PetscScalar **array) {
20693a40ed3dSBarry Smith   PetscFunctionBegin;
207075f6d85dSStefano Zampini   if (array) *array = NULL;
20713a40ed3dSBarry Smith   PetscFunctionReturn(0);
2072ff14e315SSatish Balay }
20730754003eSLois Curfman McInnes 
20740f74d2c1SSatish Balay /*@
207549a6ff4bSBarry Smith    MatDenseGetLDA - gets the leading dimension of the array returned from MatDenseGetArray()
207649a6ff4bSBarry Smith 
2077ad16ce7aSStefano Zampini    Not collective
207849a6ff4bSBarry Smith 
207949a6ff4bSBarry Smith    Input Parameter:
208049a6ff4bSBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
208149a6ff4bSBarry Smith 
208249a6ff4bSBarry Smith    Output Parameter:
208349a6ff4bSBarry Smith .   lda - the leading dimension
208449a6ff4bSBarry Smith 
208549a6ff4bSBarry Smith    Level: intermediate
208649a6ff4bSBarry Smith 
2087db781477SPatrick Sanan .seealso: `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseSetLDA()`
208849a6ff4bSBarry Smith @*/
20899371c9d4SSatish Balay PetscErrorCode MatDenseGetLDA(Mat A, PetscInt *lda) {
209049a6ff4bSBarry Smith   PetscFunctionBegin;
2091d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2092dadcf809SJacob Faibussowitsch   PetscValidIntPointer(lda, 2);
209375f6d85dSStefano Zampini   MatCheckPreallocated(A, 1);
2094cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetLDA_C", (Mat, PetscInt *), (A, lda));
209549a6ff4bSBarry Smith   PetscFunctionReturn(0);
209649a6ff4bSBarry Smith }
209749a6ff4bSBarry Smith 
20980f74d2c1SSatish Balay /*@
2099ad16ce7aSStefano Zampini    MatDenseSetLDA - Sets the leading dimension of the array used by the dense matrix
2100ad16ce7aSStefano Zampini 
2101ad16ce7aSStefano Zampini    Not collective
2102ad16ce7aSStefano Zampini 
2103d8d19677SJose E. Roman    Input Parameters:
2104ad16ce7aSStefano Zampini +  mat - a MATSEQDENSE or MATMPIDENSE matrix
2105ad16ce7aSStefano Zampini -  lda - the leading dimension
2106ad16ce7aSStefano Zampini 
2107ad16ce7aSStefano Zampini    Level: intermediate
2108ad16ce7aSStefano Zampini 
2109db781477SPatrick Sanan .seealso: `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetLDA()`
2110ad16ce7aSStefano Zampini @*/
21119371c9d4SSatish Balay PetscErrorCode MatDenseSetLDA(Mat A, PetscInt lda) {
2112ad16ce7aSStefano Zampini   PetscFunctionBegin;
2113ad16ce7aSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2114cac4c232SBarry Smith   PetscTryMethod(A, "MatDenseSetLDA_C", (Mat, PetscInt), (A, lda));
2115ad16ce7aSStefano Zampini   PetscFunctionReturn(0);
2116ad16ce7aSStefano Zampini }
2117ad16ce7aSStefano Zampini 
2118ad16ce7aSStefano Zampini /*@C
21196947451fSStefano Zampini    MatDenseGetArray - gives read-write access to the array where the data for a dense matrix is stored
212073a71a0fSBarry Smith 
21218572280aSBarry Smith    Logically Collective on Mat
212273a71a0fSBarry Smith 
212373a71a0fSBarry Smith    Input Parameter:
21246947451fSStefano Zampini .  mat - a dense matrix
212573a71a0fSBarry Smith 
212673a71a0fSBarry Smith    Output Parameter:
212773a71a0fSBarry Smith .   array - pointer to the data
212873a71a0fSBarry Smith 
212973a71a0fSBarry Smith    Level: intermediate
213073a71a0fSBarry Smith 
2131db781477SPatrick Sanan .seealso: `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
213273a71a0fSBarry Smith @*/
21339371c9d4SSatish Balay PetscErrorCode MatDenseGetArray(Mat A, PetscScalar **array) {
213473a71a0fSBarry Smith   PetscFunctionBegin;
2135d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2136d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2137cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array));
213873a71a0fSBarry Smith   PetscFunctionReturn(0);
213973a71a0fSBarry Smith }
214073a71a0fSBarry Smith 
2141dec5eb66SMatthew G Knepley /*@C
2142579dbff0SBarry Smith    MatDenseRestoreArray - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
214373a71a0fSBarry Smith 
21448572280aSBarry Smith    Logically Collective on Mat
21458572280aSBarry Smith 
21468572280aSBarry Smith    Input Parameters:
21476947451fSStefano Zampini +  mat - a dense matrix
2148742765d3SMatthew Knepley -  array - pointer to the data (may be NULL)
21498572280aSBarry Smith 
21508572280aSBarry Smith    Level: intermediate
21518572280aSBarry Smith 
2152db781477SPatrick Sanan .seealso: `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
21538572280aSBarry Smith @*/
21549371c9d4SSatish Balay PetscErrorCode MatDenseRestoreArray(Mat A, PetscScalar **array) {
21558572280aSBarry Smith   PetscFunctionBegin;
2156d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2157d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2158cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array));
21599566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)A));
2160637a0070SStefano Zampini #if defined(PETSC_HAVE_CUDA)
2161637a0070SStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
2162637a0070SStefano Zampini #endif
21638572280aSBarry Smith   PetscFunctionReturn(0);
21648572280aSBarry Smith }
21658572280aSBarry Smith 
21668572280aSBarry Smith /*@C
21676947451fSStefano Zampini    MatDenseGetArrayRead - gives read-only access to the array where the data for a dense matrix is stored
21688572280aSBarry Smith 
21698572280aSBarry Smith    Not Collective
21708572280aSBarry Smith 
21718572280aSBarry Smith    Input Parameter:
21726947451fSStefano Zampini .  mat - a dense matrix
21738572280aSBarry Smith 
21748572280aSBarry Smith    Output Parameter:
21758572280aSBarry Smith .   array - pointer to the data
21768572280aSBarry Smith 
21778572280aSBarry Smith    Level: intermediate
21788572280aSBarry Smith 
2179db781477SPatrick Sanan .seealso: `MatDenseRestoreArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
21808572280aSBarry Smith @*/
21819371c9d4SSatish Balay PetscErrorCode MatDenseGetArrayRead(Mat A, const PetscScalar **array) {
21828572280aSBarry Smith   PetscFunctionBegin;
2183d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2184d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2185cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, const PetscScalar **), (A, array));
21868572280aSBarry Smith   PetscFunctionReturn(0);
21878572280aSBarry Smith }
21888572280aSBarry Smith 
21898572280aSBarry Smith /*@C
21906947451fSStefano Zampini    MatDenseRestoreArrayRead - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArrayRead()
21918572280aSBarry Smith 
219273a71a0fSBarry Smith    Not Collective
219373a71a0fSBarry Smith 
219473a71a0fSBarry Smith    Input Parameters:
21956947451fSStefano Zampini +  mat - a dense matrix
2196742765d3SMatthew Knepley -  array - pointer to the data (may be NULL)
219773a71a0fSBarry Smith 
219873a71a0fSBarry Smith    Level: intermediate
219973a71a0fSBarry Smith 
2200db781477SPatrick Sanan .seealso: `MatDenseGetArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
220173a71a0fSBarry Smith @*/
22029371c9d4SSatish Balay PetscErrorCode MatDenseRestoreArrayRead(Mat A, const PetscScalar **array) {
220373a71a0fSBarry Smith   PetscFunctionBegin;
2204d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2205d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2206cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, const PetscScalar **), (A, array));
220773a71a0fSBarry Smith   PetscFunctionReturn(0);
220873a71a0fSBarry Smith }
220973a71a0fSBarry Smith 
22106947451fSStefano Zampini /*@C
22116947451fSStefano Zampini    MatDenseGetArrayWrite - gives write-only access to the array where the data for a dense matrix is stored
22126947451fSStefano Zampini 
22136947451fSStefano Zampini    Not Collective
22146947451fSStefano Zampini 
22156947451fSStefano Zampini    Input Parameter:
22166947451fSStefano Zampini .  mat - a dense matrix
22176947451fSStefano Zampini 
22186947451fSStefano Zampini    Output Parameter:
22196947451fSStefano Zampini .   array - pointer to the data
22206947451fSStefano Zampini 
22216947451fSStefano Zampini    Level: intermediate
22226947451fSStefano Zampini 
2223db781477SPatrick Sanan .seealso: `MatDenseRestoreArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`
22246947451fSStefano Zampini @*/
22259371c9d4SSatish Balay PetscErrorCode MatDenseGetArrayWrite(Mat A, PetscScalar **array) {
22266947451fSStefano Zampini   PetscFunctionBegin;
2227d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2228d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2229cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array));
22306947451fSStefano Zampini   PetscFunctionReturn(0);
22316947451fSStefano Zampini }
22326947451fSStefano Zampini 
22336947451fSStefano Zampini /*@C
22346947451fSStefano Zampini    MatDenseRestoreArrayWrite - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArrayWrite()
22356947451fSStefano Zampini 
22366947451fSStefano Zampini    Not Collective
22376947451fSStefano Zampini 
22386947451fSStefano Zampini    Input Parameters:
22396947451fSStefano Zampini +  mat - a dense matrix
2240742765d3SMatthew Knepley -  array - pointer to the data (may be NULL)
22416947451fSStefano Zampini 
22426947451fSStefano Zampini    Level: intermediate
22436947451fSStefano Zampini 
2244db781477SPatrick Sanan .seealso: `MatDenseGetArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`
22456947451fSStefano Zampini @*/
22469371c9d4SSatish Balay PetscErrorCode MatDenseRestoreArrayWrite(Mat A, PetscScalar **array) {
22476947451fSStefano Zampini   PetscFunctionBegin;
2248d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2249d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2250cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array));
22519566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)A));
22526947451fSStefano Zampini #if defined(PETSC_HAVE_CUDA)
22536947451fSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
22546947451fSStefano Zampini #endif
22556947451fSStefano Zampini   PetscFunctionReturn(0);
22566947451fSStefano Zampini }
22576947451fSStefano Zampini 
22589371c9d4SSatish Balay static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A, IS isrow, IS iscol, MatReuse scall, Mat *B) {
2259c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense *)A->data;
2260bf5a80bcSToby Isaac   PetscInt        i, j, nrows, ncols, ldb;
22615d0c19d7SBarry Smith   const PetscInt *irow, *icol;
226287828ca2SBarry Smith   PetscScalar    *av, *bv, *v = mat->v;
22630754003eSLois Curfman McInnes   Mat             newmat;
22640754003eSLois Curfman McInnes 
22653a40ed3dSBarry Smith   PetscFunctionBegin;
22669566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(isrow, &irow));
22679566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(iscol, &icol));
22689566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(isrow, &nrows));
22699566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(iscol, &ncols));
22700754003eSLois Curfman McInnes 
2271182d2002SSatish Balay   /* Check submatrixcall */
2272182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
227313f74950SBarry Smith     PetscInt n_cols, n_rows;
22749566063dSJacob Faibussowitsch     PetscCall(MatGetSize(*B, &n_rows, &n_cols));
227521a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
2276f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
22779566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(*B, nrows, ncols, nrows, ncols));
227821a2c019SBarry Smith     }
2279182d2002SSatish Balay     newmat = *B;
2280182d2002SSatish Balay   } else {
22810754003eSLois Curfman McInnes     /* Create and fill new matrix */
22829566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &newmat));
22839566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(newmat, nrows, ncols, nrows, ncols));
22849566063dSJacob Faibussowitsch     PetscCall(MatSetType(newmat, ((PetscObject)A)->type_name));
22859566063dSJacob Faibussowitsch     PetscCall(MatSeqDenseSetPreallocation(newmat, NULL));
2286182d2002SSatish Balay   }
2287182d2002SSatish Balay 
2288182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
22899566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(newmat, &bv));
22909566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(newmat, &ldb));
2291182d2002SSatish Balay   for (i = 0; i < ncols; i++) {
22926de62eeeSBarry Smith     av = v + mat->lda * icol[i];
2293ca15aa20SStefano Zampini     for (j = 0; j < nrows; j++) bv[j] = av[irow[j]];
2294bf5a80bcSToby Isaac     bv += ldb;
22950754003eSLois Curfman McInnes   }
22969566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(newmat, &bv));
2297182d2002SSatish Balay 
2298182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
22999566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(newmat, MAT_FINAL_ASSEMBLY));
23009566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(newmat, MAT_FINAL_ASSEMBLY));
23010754003eSLois Curfman McInnes 
23020754003eSLois Curfman McInnes   /* Free work space */
23039566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(isrow, &irow));
23049566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(iscol, &icol));
2305182d2002SSatish Balay   *B = newmat;
23063a40ed3dSBarry Smith   PetscFunctionReturn(0);
23070754003eSLois Curfman McInnes }
23080754003eSLois Curfman McInnes 
23099371c9d4SSatish Balay static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A, PetscInt n, const IS irow[], const IS icol[], MatReuse scall, Mat *B[]) {
231013f74950SBarry Smith   PetscInt i;
2311905e6a2fSBarry Smith 
23123a40ed3dSBarry Smith   PetscFunctionBegin;
2313*48a46eb9SPierre Jolivet   if (scall == MAT_INITIAL_MATRIX) PetscCall(PetscCalloc1(n, B));
2314905e6a2fSBarry Smith 
2315*48a46eb9SPierre Jolivet   for (i = 0; i < n; i++) PetscCall(MatCreateSubMatrix_SeqDense(A, irow[i], icol[i], scall, &(*B)[i]));
23163a40ed3dSBarry Smith   PetscFunctionReturn(0);
2317905e6a2fSBarry Smith }
2318905e6a2fSBarry Smith 
23199371c9d4SSatish Balay static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat, MatAssemblyType mode) {
2320c0aa2d19SHong Zhang   PetscFunctionBegin;
2321c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2322c0aa2d19SHong Zhang }
2323c0aa2d19SHong Zhang 
23249371c9d4SSatish Balay static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat, MatAssemblyType mode) {
2325c0aa2d19SHong Zhang   PetscFunctionBegin;
2326c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2327c0aa2d19SHong Zhang }
2328c0aa2d19SHong Zhang 
23299371c9d4SSatish Balay PetscErrorCode MatCopy_SeqDense(Mat A, Mat B, MatStructure str) {
23304b0e389bSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data;
2331ca15aa20SStefano Zampini   const PetscScalar *va;
2332ca15aa20SStefano Zampini   PetscScalar       *vb;
2333d0f46423SBarry Smith   PetscInt           lda1 = a->lda, lda2 = b->lda, m = A->rmap->n, n = A->cmap->n, j;
23343a40ed3dSBarry Smith 
23353a40ed3dSBarry Smith   PetscFunctionBegin;
233633f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
233733f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
23389566063dSJacob Faibussowitsch     PetscCall(MatCopy_Basic(A, B, str));
23393a40ed3dSBarry Smith     PetscFunctionReturn(0);
23403a40ed3dSBarry Smith   }
2341aed4548fSBarry Smith   PetscCheck(m == B->rmap->n && n == B->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "size(B) != size(A)");
23429566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &va));
23439566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(B, &vb));
2344a5ce6ee0Svictorle   if (lda1 > m || lda2 > m) {
2345*48a46eb9SPierre Jolivet     for (j = 0; j < n; j++) PetscCall(PetscArraycpy(vb + j * lda2, va + j * lda1, m));
2346a5ce6ee0Svictorle   } else {
23479566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(vb, va, A->rmap->n * A->cmap->n));
2348a5ce6ee0Svictorle   }
23499566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(B, &vb));
23509566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &va));
23519566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY));
23529566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY));
2353273d9f13SBarry Smith   PetscFunctionReturn(0);
2354273d9f13SBarry Smith }
2355273d9f13SBarry Smith 
23569371c9d4SSatish Balay PetscErrorCode MatSetUp_SeqDense(Mat A) {
2357273d9f13SBarry Smith   PetscFunctionBegin;
23589566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(A->rmap));
23599566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(A->cmap));
2360*48a46eb9SPierre Jolivet   if (!A->preallocated) PetscCall(MatSeqDenseSetPreallocation(A, NULL));
23613a40ed3dSBarry Smith   PetscFunctionReturn(0);
23624b0e389bSBarry Smith }
23634b0e389bSBarry Smith 
23649371c9d4SSatish Balay static PetscErrorCode MatConjugate_SeqDense(Mat A) {
23654396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
236606c5243aSJose E. Roman   PetscInt      i, j;
23674396437dSToby Isaac   PetscInt      min = PetscMin(A->rmap->n, A->cmap->n);
2368ca15aa20SStefano Zampini   PetscScalar  *aa;
2369ba337c44SJed Brown 
2370ba337c44SJed Brown   PetscFunctionBegin;
23719566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &aa));
237206c5243aSJose E. Roman   for (j = 0; j < A->cmap->n; j++) {
237306c5243aSJose E. Roman     for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscConj(aa[i + j * mat->lda]);
237406c5243aSJose E. Roman   }
23759566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &aa));
23769371c9d4SSatish Balay   if (mat->tau)
23779371c9d4SSatish Balay     for (i = 0; i < min; i++) mat->tau[i] = PetscConj(mat->tau[i]);
2378ba337c44SJed Brown   PetscFunctionReturn(0);
2379ba337c44SJed Brown }
2380ba337c44SJed Brown 
23819371c9d4SSatish Balay static PetscErrorCode MatRealPart_SeqDense(Mat A) {
238206c5243aSJose E. Roman   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
238306c5243aSJose E. Roman   PetscInt      i, j;
2384ca15aa20SStefano Zampini   PetscScalar  *aa;
2385ba337c44SJed Brown 
2386ba337c44SJed Brown   PetscFunctionBegin;
23879566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &aa));
238806c5243aSJose E. Roman   for (j = 0; j < A->cmap->n; j++) {
238906c5243aSJose E. Roman     for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscRealPart(aa[i + j * mat->lda]);
239006c5243aSJose E. Roman   }
23919566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &aa));
2392ba337c44SJed Brown   PetscFunctionReturn(0);
2393ba337c44SJed Brown }
2394ba337c44SJed Brown 
23959371c9d4SSatish Balay static PetscErrorCode MatImaginaryPart_SeqDense(Mat A) {
239606c5243aSJose E. Roman   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
239706c5243aSJose E. Roman   PetscInt      i, j;
2398ca15aa20SStefano Zampini   PetscScalar  *aa;
2399ba337c44SJed Brown 
2400ba337c44SJed Brown   PetscFunctionBegin;
24019566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &aa));
240206c5243aSJose E. Roman   for (j = 0; j < A->cmap->n; j++) {
240306c5243aSJose E. Roman     for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscImaginaryPart(aa[i + j * mat->lda]);
240406c5243aSJose E. Roman   }
24059566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &aa));
2406ba337c44SJed Brown   PetscFunctionReturn(0);
2407ba337c44SJed Brown }
2408284134d9SBarry Smith 
2409a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/
24109371c9d4SSatish Balay PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) {
2411d0f46423SBarry Smith   PetscInt  m = A->rmap->n, n = B->cmap->n;
24127a3c3d58SStefano Zampini   PetscBool cisdense;
2413a9fe9ddaSSatish Balay 
2414ee16a9a1SHong Zhang   PetscFunctionBegin;
24159566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C, m, n, m, n));
24169566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, ""));
24177a3c3d58SStefano Zampini   if (!cisdense) {
24187a3c3d58SStefano Zampini     PetscBool flg;
24197a3c3d58SStefano Zampini 
24209566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg));
24219566063dSJacob Faibussowitsch     PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE));
24227a3c3d58SStefano Zampini   }
24239566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
2424ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2425ee16a9a1SHong Zhang }
2426a9fe9ddaSSatish Balay 
24279371c9d4SSatish Balay PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) {
24286718818eSStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data, *c = (Mat_SeqDense *)C->data;
24290805154bSBarry Smith   PetscBLASInt       m, n, k;
2430ca15aa20SStefano Zampini   const PetscScalar *av, *bv;
2431ca15aa20SStefano Zampini   PetscScalar       *cv;
2432a9fe9ddaSSatish Balay   PetscScalar        _DOne = 1.0, _DZero = 0.0;
2433a9fe9ddaSSatish Balay 
2434a9fe9ddaSSatish Balay   PetscFunctionBegin;
24359566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n, &m));
24369566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n, &n));
24379566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &k));
243849d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
24399566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &av));
24409566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B, &bv));
24419566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C, &cv));
2442792fecdfSBarry Smith   PetscCallBLAS("BLASgemm", BLASgemm_("N", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda));
24439566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1)));
24449566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &av));
24459566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B, &bv));
24469566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C, &cv));
2447a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2448a9fe9ddaSSatish Balay }
2449a9fe9ddaSSatish Balay 
24509371c9d4SSatish Balay PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) {
245169f65d41SStefano Zampini   PetscInt  m = A->rmap->n, n = B->rmap->n;
24527a3c3d58SStefano Zampini   PetscBool cisdense;
245369f65d41SStefano Zampini 
245469f65d41SStefano Zampini   PetscFunctionBegin;
24559566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C, m, n, m, n));
24569566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, ""));
24577a3c3d58SStefano Zampini   if (!cisdense) {
24587a3c3d58SStefano Zampini     PetscBool flg;
24597a3c3d58SStefano Zampini 
24609566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg));
24619566063dSJacob Faibussowitsch     PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE));
24627a3c3d58SStefano Zampini   }
24639566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
246469f65d41SStefano Zampini   PetscFunctionReturn(0);
246569f65d41SStefano Zampini }
246669f65d41SStefano Zampini 
24679371c9d4SSatish Balay PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) {
246869f65d41SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
246969f65d41SStefano Zampini   Mat_SeqDense      *b = (Mat_SeqDense *)B->data;
247069f65d41SStefano Zampini   Mat_SeqDense      *c = (Mat_SeqDense *)C->data;
24716718818eSStefano Zampini   const PetscScalar *av, *bv;
24726718818eSStefano Zampini   PetscScalar       *cv;
247369f65d41SStefano Zampini   PetscBLASInt       m, n, k;
247469f65d41SStefano Zampini   PetscScalar        _DOne = 1.0, _DZero = 0.0;
247569f65d41SStefano Zampini 
247669f65d41SStefano Zampini   PetscFunctionBegin;
24779566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n, &m));
24789566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n, &n));
24799566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &k));
248049d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
24819566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &av));
24829566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B, &bv));
24839566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C, &cv));
2484792fecdfSBarry Smith   PetscCallBLAS("BLASgemm", BLASgemm_("N", "T", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda));
24859566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &av));
24869566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B, &bv));
24879566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C, &cv));
24889566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1)));
248969f65d41SStefano Zampini   PetscFunctionReturn(0);
249069f65d41SStefano Zampini }
249169f65d41SStefano Zampini 
24929371c9d4SSatish Balay PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) {
2493d0f46423SBarry Smith   PetscInt  m = A->cmap->n, n = B->cmap->n;
24947a3c3d58SStefano Zampini   PetscBool cisdense;
2495a9fe9ddaSSatish Balay 
2496ee16a9a1SHong Zhang   PetscFunctionBegin;
24979566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C, m, n, m, n));
24989566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, ""));
24997a3c3d58SStefano Zampini   if (!cisdense) {
25007a3c3d58SStefano Zampini     PetscBool flg;
25017a3c3d58SStefano Zampini 
25029566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg));
25039566063dSJacob Faibussowitsch     PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE));
25047a3c3d58SStefano Zampini   }
25059566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
2506ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2507ee16a9a1SHong Zhang }
2508a9fe9ddaSSatish Balay 
25099371c9d4SSatish Balay PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) {
2510a9fe9ddaSSatish Balay   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
2511a9fe9ddaSSatish Balay   Mat_SeqDense      *b = (Mat_SeqDense *)B->data;
2512a9fe9ddaSSatish Balay   Mat_SeqDense      *c = (Mat_SeqDense *)C->data;
25136718818eSStefano Zampini   const PetscScalar *av, *bv;
25146718818eSStefano Zampini   PetscScalar       *cv;
25150805154bSBarry Smith   PetscBLASInt       m, n, k;
2516a9fe9ddaSSatish Balay   PetscScalar        _DOne = 1.0, _DZero = 0.0;
2517a9fe9ddaSSatish Balay 
2518a9fe9ddaSSatish Balay   PetscFunctionBegin;
25199566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n, &m));
25209566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n, &n));
25219566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &k));
252249d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
25239566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &av));
25249566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B, &bv));
25259566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C, &cv));
2526792fecdfSBarry Smith   PetscCallBLAS("BLASgemm", BLASgemm_("T", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda));
25279566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &av));
25289566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B, &bv));
25299566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C, &cv));
25309566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1)));
2531a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2532a9fe9ddaSSatish Balay }
2533985db425SBarry Smith 
25344222ddf1SHong Zhang /* ----------------------------------------------- */
25359371c9d4SSatish Balay static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C) {
25364222ddf1SHong Zhang   PetscFunctionBegin;
25374222ddf1SHong Zhang   C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense;
25384222ddf1SHong Zhang   C->ops->productsymbolic = MatProductSymbolic_AB;
25394222ddf1SHong Zhang   PetscFunctionReturn(0);
25404222ddf1SHong Zhang }
25414222ddf1SHong Zhang 
25429371c9d4SSatish Balay static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C) {
25434222ddf1SHong Zhang   PetscFunctionBegin;
25444222ddf1SHong Zhang   C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense;
25454222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_AtB;
25464222ddf1SHong Zhang   PetscFunctionReturn(0);
25474222ddf1SHong Zhang }
25484222ddf1SHong Zhang 
25499371c9d4SSatish Balay static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C) {
25504222ddf1SHong Zhang   PetscFunctionBegin;
25514222ddf1SHong Zhang   C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense;
25524222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_ABt;
25534222ddf1SHong Zhang   PetscFunctionReturn(0);
25544222ddf1SHong Zhang }
25554222ddf1SHong Zhang 
25569371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C) {
25574222ddf1SHong Zhang   Mat_Product *product = C->product;
25584222ddf1SHong Zhang 
25594222ddf1SHong Zhang   PetscFunctionBegin;
25604222ddf1SHong Zhang   switch (product->type) {
25619371c9d4SSatish Balay   case MATPRODUCT_AB: PetscCall(MatProductSetFromOptions_SeqDense_AB(C)); break;
25629371c9d4SSatish Balay   case MATPRODUCT_AtB: PetscCall(MatProductSetFromOptions_SeqDense_AtB(C)); break;
25639371c9d4SSatish Balay   case MATPRODUCT_ABt: PetscCall(MatProductSetFromOptions_SeqDense_ABt(C)); break;
25649371c9d4SSatish Balay   default: break;
25654222ddf1SHong Zhang   }
25664222ddf1SHong Zhang   PetscFunctionReturn(0);
25674222ddf1SHong Zhang }
25684222ddf1SHong Zhang /* ----------------------------------------------- */
25694222ddf1SHong Zhang 
25709371c9d4SSatish Balay static PetscErrorCode MatGetRowMax_SeqDense(Mat A, Vec v, PetscInt idx[]) {
2571985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
2572d0f46423SBarry Smith   PetscInt           i, j, m = A->rmap->n, n = A->cmap->n, p;
2573985db425SBarry Smith   PetscScalar       *x;
2574ca15aa20SStefano Zampini   const PetscScalar *aa;
2575985db425SBarry Smith 
2576985db425SBarry Smith   PetscFunctionBegin;
257728b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
25789566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
25799566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v, &p));
25809566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
258108401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector");
2582985db425SBarry Smith   for (i = 0; i < m; i++) {
25839371c9d4SSatish Balay     x[i] = aa[i];
25849371c9d4SSatish Balay     if (idx) idx[i] = 0;
2585985db425SBarry Smith     for (j = 1; j < n; j++) {
25869371c9d4SSatish Balay       if (PetscRealPart(x[i]) < PetscRealPart(aa[i + a->lda * j])) {
25879371c9d4SSatish Balay         x[i] = aa[i + a->lda * j];
25889371c9d4SSatish Balay         if (idx) idx[i] = j;
25899371c9d4SSatish Balay       }
2590985db425SBarry Smith     }
2591985db425SBarry Smith   }
25929566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
25939566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
2594985db425SBarry Smith   PetscFunctionReturn(0);
2595985db425SBarry Smith }
2596985db425SBarry Smith 
25979371c9d4SSatish Balay static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A, Vec v, PetscInt idx[]) {
2598985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
2599d0f46423SBarry Smith   PetscInt           i, j, m = A->rmap->n, n = A->cmap->n, p;
2600985db425SBarry Smith   PetscScalar       *x;
2601985db425SBarry Smith   PetscReal          atmp;
2602ca15aa20SStefano Zampini   const PetscScalar *aa;
2603985db425SBarry Smith 
2604985db425SBarry Smith   PetscFunctionBegin;
260528b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
26069566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
26079566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v, &p));
26089566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
260908401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector");
2610985db425SBarry Smith   for (i = 0; i < m; i++) {
26119189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
2612985db425SBarry Smith     for (j = 1; j < n; j++) {
2613ca15aa20SStefano Zampini       atmp = PetscAbsScalar(aa[i + a->lda * j]);
26149371c9d4SSatish Balay       if (PetscAbsScalar(x[i]) < atmp) {
26159371c9d4SSatish Balay         x[i] = atmp;
26169371c9d4SSatish Balay         if (idx) idx[i] = j;
26179371c9d4SSatish Balay       }
2618985db425SBarry Smith     }
2619985db425SBarry Smith   }
26209566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
26219566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
2622985db425SBarry Smith   PetscFunctionReturn(0);
2623985db425SBarry Smith }
2624985db425SBarry Smith 
26259371c9d4SSatish Balay static PetscErrorCode MatGetRowMin_SeqDense(Mat A, Vec v, PetscInt idx[]) {
2626985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
2627d0f46423SBarry Smith   PetscInt           i, j, m = A->rmap->n, n = A->cmap->n, p;
2628985db425SBarry Smith   PetscScalar       *x;
2629ca15aa20SStefano Zampini   const PetscScalar *aa;
2630985db425SBarry Smith 
2631985db425SBarry Smith   PetscFunctionBegin;
263228b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
26339566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
26349566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
26359566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v, &p));
263608401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector");
2637985db425SBarry Smith   for (i = 0; i < m; i++) {
26389371c9d4SSatish Balay     x[i] = aa[i];
26399371c9d4SSatish Balay     if (idx) idx[i] = 0;
2640985db425SBarry Smith     for (j = 1; j < n; j++) {
26419371c9d4SSatish Balay       if (PetscRealPart(x[i]) > PetscRealPart(aa[i + a->lda * j])) {
26429371c9d4SSatish Balay         x[i] = aa[i + a->lda * j];
26439371c9d4SSatish Balay         if (idx) idx[i] = j;
26449371c9d4SSatish Balay       }
2645985db425SBarry Smith     }
2646985db425SBarry Smith   }
26479566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
26489566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
2649985db425SBarry Smith   PetscFunctionReturn(0);
2650985db425SBarry Smith }
2651985db425SBarry Smith 
26529371c9d4SSatish Balay PetscErrorCode MatGetColumnVector_SeqDense(Mat A, Vec v, PetscInt col) {
26538d0534beSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
26548d0534beSBarry Smith   PetscScalar       *x;
2655ca15aa20SStefano Zampini   const PetscScalar *aa;
26568d0534beSBarry Smith 
26578d0534beSBarry Smith   PetscFunctionBegin;
265828b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
26599566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
26609566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
26619566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(x, aa + col * a->lda, A->rmap->n));
26629566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
26639566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
26648d0534beSBarry Smith   PetscFunctionReturn(0);
26658d0534beSBarry Smith }
26668d0534beSBarry Smith 
26679371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatGetColumnReductions_SeqDense(Mat A, PetscInt type, PetscReal *reductions) {
26680716a85fSBarry Smith   PetscInt           i, j, m, n;
26691683a169SBarry Smith   const PetscScalar *a;
26700716a85fSBarry Smith 
26710716a85fSBarry Smith   PetscFunctionBegin;
26729566063dSJacob Faibussowitsch   PetscCall(MatGetSize(A, &m, &n));
26739566063dSJacob Faibussowitsch   PetscCall(PetscArrayzero(reductions, n));
26749566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &a));
2675857cbf51SRichard Tran Mills   if (type == NORM_2) {
26760716a85fSBarry Smith     for (i = 0; i < n; i++) {
26779371c9d4SSatish Balay       for (j = 0; j < m; j++) { reductions[i] += PetscAbsScalar(a[j] * a[j]); }
26780716a85fSBarry Smith       a += m;
26790716a85fSBarry Smith     }
2680857cbf51SRichard Tran Mills   } else if (type == NORM_1) {
26810716a85fSBarry Smith     for (i = 0; i < n; i++) {
26829371c9d4SSatish Balay       for (j = 0; j < m; j++) { reductions[i] += PetscAbsScalar(a[j]); }
26830716a85fSBarry Smith       a += m;
26840716a85fSBarry Smith     }
2685857cbf51SRichard Tran Mills   } else if (type == NORM_INFINITY) {
26860716a85fSBarry Smith     for (i = 0; i < n; i++) {
26879371c9d4SSatish Balay       for (j = 0; j < m; j++) { reductions[i] = PetscMax(PetscAbsScalar(a[j]), reductions[i]); }
26880716a85fSBarry Smith       a += m;
26890716a85fSBarry Smith     }
2690857cbf51SRichard Tran Mills   } else if (type == REDUCTION_SUM_REALPART || type == REDUCTION_MEAN_REALPART) {
2691a873a8cdSSam Reynolds     for (i = 0; i < n; i++) {
26929371c9d4SSatish Balay       for (j = 0; j < m; j++) { reductions[i] += PetscRealPart(a[j]); }
2693a873a8cdSSam Reynolds       a += m;
2694a873a8cdSSam Reynolds     }
2695857cbf51SRichard Tran Mills   } else if (type == REDUCTION_SUM_IMAGINARYPART || type == REDUCTION_MEAN_IMAGINARYPART) {
2696857cbf51SRichard Tran Mills     for (i = 0; i < n; i++) {
26979371c9d4SSatish Balay       for (j = 0; j < m; j++) { reductions[i] += PetscImaginaryPart(a[j]); }
2698857cbf51SRichard Tran Mills       a += m;
2699857cbf51SRichard Tran Mills     }
2700857cbf51SRichard Tran Mills   } else SETERRQ(PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Unknown reduction type");
27019566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &a));
2702857cbf51SRichard Tran Mills   if (type == NORM_2) {
2703a873a8cdSSam Reynolds     for (i = 0; i < n; i++) reductions[i] = PetscSqrtReal(reductions[i]);
2704857cbf51SRichard Tran Mills   } else if (type == REDUCTION_MEAN_REALPART || type == REDUCTION_MEAN_IMAGINARYPART) {
2705a873a8cdSSam Reynolds     for (i = 0; i < n; i++) reductions[i] /= m;
27060716a85fSBarry Smith   }
27070716a85fSBarry Smith   PetscFunctionReturn(0);
27080716a85fSBarry Smith }
27090716a85fSBarry Smith 
27109371c9d4SSatish Balay static PetscErrorCode MatSetRandom_SeqDense(Mat x, PetscRandom rctx) {
271173a71a0fSBarry Smith   PetscScalar *a;
2712637a0070SStefano Zampini   PetscInt     lda, m, n, i, j;
271373a71a0fSBarry Smith 
271473a71a0fSBarry Smith   PetscFunctionBegin;
27159566063dSJacob Faibussowitsch   PetscCall(MatGetSize(x, &m, &n));
27169566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(x, &lda));
27179566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(x, &a));
2718637a0070SStefano Zampini   for (j = 0; j < n; j++) {
2719*48a46eb9SPierre Jolivet     for (i = 0; i < m; i++) PetscCall(PetscRandomGetValue(rctx, a + j * lda + i));
272073a71a0fSBarry Smith   }
27219566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(x, &a));
272273a71a0fSBarry Smith   PetscFunctionReturn(0);
272373a71a0fSBarry Smith }
272473a71a0fSBarry Smith 
27259371c9d4SSatish Balay static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A, PetscBool *missing, PetscInt *d) {
27263b49f96aSBarry Smith   PetscFunctionBegin;
27273b49f96aSBarry Smith   *missing = PETSC_FALSE;
27283b49f96aSBarry Smith   PetscFunctionReturn(0);
27293b49f96aSBarry Smith }
273073a71a0fSBarry Smith 
2731ca15aa20SStefano Zampini /* vals is not const */
27329371c9d4SSatish Balay static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A, PetscInt col, PetscScalar **vals) {
273386aefd0dSHong Zhang   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
2734ca15aa20SStefano Zampini   PetscScalar  *v;
273586aefd0dSHong Zhang 
273686aefd0dSHong Zhang   PetscFunctionBegin;
273728b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
27389566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
2739ca15aa20SStefano Zampini   *vals = v + col * a->lda;
27409566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
274186aefd0dSHong Zhang   PetscFunctionReturn(0);
274286aefd0dSHong Zhang }
274386aefd0dSHong Zhang 
27449371c9d4SSatish Balay static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A, PetscScalar **vals) {
274586aefd0dSHong Zhang   PetscFunctionBegin;
2746742765d3SMatthew Knepley   if (vals) *vals = NULL; /* user cannot accidentally use the array later */
274786aefd0dSHong Zhang   PetscFunctionReturn(0);
274886aefd0dSHong Zhang }
2749abc3b08eSStefano Zampini 
2750289bc588SBarry Smith /* -------------------------------------------------------------------*/
2751a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqDense,
2752905e6a2fSBarry Smith                                        MatGetRow_SeqDense,
2753905e6a2fSBarry Smith                                        MatRestoreRow_SeqDense,
2754905e6a2fSBarry Smith                                        MatMult_SeqDense,
275597304618SKris Buschelman                                        /*  4*/ MatMultAdd_SeqDense,
27567c922b88SBarry Smith                                        MatMultTranspose_SeqDense,
27577c922b88SBarry Smith                                        MatMultTransposeAdd_SeqDense,
2758f4259b30SLisandro Dalcin                                        NULL,
2759f4259b30SLisandro Dalcin                                        NULL,
2760f4259b30SLisandro Dalcin                                        NULL,
2761f4259b30SLisandro Dalcin                                        /* 10*/ NULL,
2762905e6a2fSBarry Smith                                        MatLUFactor_SeqDense,
2763905e6a2fSBarry Smith                                        MatCholeskyFactor_SeqDense,
276441f059aeSBarry Smith                                        MatSOR_SeqDense,
2765ec8511deSBarry Smith                                        MatTranspose_SeqDense,
276697304618SKris Buschelman                                        /* 15*/ MatGetInfo_SeqDense,
2767905e6a2fSBarry Smith                                        MatEqual_SeqDense,
2768905e6a2fSBarry Smith                                        MatGetDiagonal_SeqDense,
2769905e6a2fSBarry Smith                                        MatDiagonalScale_SeqDense,
2770905e6a2fSBarry Smith                                        MatNorm_SeqDense,
2771c0aa2d19SHong Zhang                                        /* 20*/ MatAssemblyBegin_SeqDense,
2772c0aa2d19SHong Zhang                                        MatAssemblyEnd_SeqDense,
2773905e6a2fSBarry Smith                                        MatSetOption_SeqDense,
2774905e6a2fSBarry Smith                                        MatZeroEntries_SeqDense,
2775d519adbfSMatthew Knepley                                        /* 24*/ MatZeroRows_SeqDense,
2776f4259b30SLisandro Dalcin                                        NULL,
2777f4259b30SLisandro Dalcin                                        NULL,
2778f4259b30SLisandro Dalcin                                        NULL,
2779f4259b30SLisandro Dalcin                                        NULL,
27804994cf47SJed Brown                                        /* 29*/ MatSetUp_SeqDense,
2781f4259b30SLisandro Dalcin                                        NULL,
2782f4259b30SLisandro Dalcin                                        NULL,
2783f4259b30SLisandro Dalcin                                        NULL,
2784f4259b30SLisandro Dalcin                                        NULL,
2785d519adbfSMatthew Knepley                                        /* 34*/ MatDuplicate_SeqDense,
2786f4259b30SLisandro Dalcin                                        NULL,
2787f4259b30SLisandro Dalcin                                        NULL,
2788f4259b30SLisandro Dalcin                                        NULL,
2789f4259b30SLisandro Dalcin                                        NULL,
2790d519adbfSMatthew Knepley                                        /* 39*/ MatAXPY_SeqDense,
27917dae84e0SHong Zhang                                        MatCreateSubMatrices_SeqDense,
2792f4259b30SLisandro Dalcin                                        NULL,
27934b0e389bSBarry Smith                                        MatGetValues_SeqDense,
2794a5ae1ecdSBarry Smith                                        MatCopy_SeqDense,
2795d519adbfSMatthew Knepley                                        /* 44*/ MatGetRowMax_SeqDense,
2796a5ae1ecdSBarry Smith                                        MatScale_SeqDense,
27972f605a99SJose E. Roman                                        MatShift_SeqDense,
2798f4259b30SLisandro Dalcin                                        NULL,
27993f49a652SStefano Zampini                                        MatZeroRowsColumns_SeqDense,
280073a71a0fSBarry Smith                                        /* 49*/ MatSetRandom_SeqDense,
2801f4259b30SLisandro Dalcin                                        NULL,
2802f4259b30SLisandro Dalcin                                        NULL,
2803f4259b30SLisandro Dalcin                                        NULL,
2804f4259b30SLisandro Dalcin                                        NULL,
2805f4259b30SLisandro Dalcin                                        /* 54*/ NULL,
2806f4259b30SLisandro Dalcin                                        NULL,
2807f4259b30SLisandro Dalcin                                        NULL,
2808f4259b30SLisandro Dalcin                                        NULL,
2809f4259b30SLisandro Dalcin                                        NULL,
2810023c16fcSToby Isaac                                        /* 59*/ MatCreateSubMatrix_SeqDense,
2811e03a110bSBarry Smith                                        MatDestroy_SeqDense,
2812e03a110bSBarry Smith                                        MatView_SeqDense,
2813f4259b30SLisandro Dalcin                                        NULL,
2814f4259b30SLisandro Dalcin                                        NULL,
2815f4259b30SLisandro Dalcin                                        /* 64*/ NULL,
2816f4259b30SLisandro Dalcin                                        NULL,
2817f4259b30SLisandro Dalcin                                        NULL,
2818f4259b30SLisandro Dalcin                                        NULL,
2819f4259b30SLisandro Dalcin                                        NULL,
2820d519adbfSMatthew Knepley                                        /* 69*/ MatGetRowMaxAbs_SeqDense,
2821f4259b30SLisandro Dalcin                                        NULL,
2822f4259b30SLisandro Dalcin                                        NULL,
2823f4259b30SLisandro Dalcin                                        NULL,
2824f4259b30SLisandro Dalcin                                        NULL,
2825f4259b30SLisandro Dalcin                                        /* 74*/ NULL,
2826f4259b30SLisandro Dalcin                                        NULL,
2827f4259b30SLisandro Dalcin                                        NULL,
2828f4259b30SLisandro Dalcin                                        NULL,
2829f4259b30SLisandro Dalcin                                        NULL,
2830f4259b30SLisandro Dalcin                                        /* 79*/ NULL,
2831f4259b30SLisandro Dalcin                                        NULL,
2832f4259b30SLisandro Dalcin                                        NULL,
2833f4259b30SLisandro Dalcin                                        NULL,
28345bba2384SShri Abhyankar                                        /* 83*/ MatLoad_SeqDense,
2835637a0070SStefano Zampini                                        MatIsSymmetric_SeqDense,
28361cbb95d3SBarry Smith                                        MatIsHermitian_SeqDense,
2837f4259b30SLisandro Dalcin                                        NULL,
2838f4259b30SLisandro Dalcin                                        NULL,
2839f4259b30SLisandro Dalcin                                        NULL,
2840f4259b30SLisandro Dalcin                                        /* 89*/ NULL,
2841f4259b30SLisandro Dalcin                                        NULL,
2842a9fe9ddaSSatish Balay                                        MatMatMultNumeric_SeqDense_SeqDense,
2843f4259b30SLisandro Dalcin                                        NULL,
2844f4259b30SLisandro Dalcin                                        NULL,
2845f4259b30SLisandro Dalcin                                        /* 94*/ NULL,
2846f4259b30SLisandro Dalcin                                        NULL,
2847f4259b30SLisandro Dalcin                                        NULL,
284869f65d41SStefano Zampini                                        MatMatTransposeMultNumeric_SeqDense_SeqDense,
2849f4259b30SLisandro Dalcin                                        NULL,
28504222ddf1SHong Zhang                                        /* 99*/ MatProductSetFromOptions_SeqDense,
2851f4259b30SLisandro Dalcin                                        NULL,
2852f4259b30SLisandro Dalcin                                        NULL,
2853ba337c44SJed Brown                                        MatConjugate_SeqDense,
2854f4259b30SLisandro Dalcin                                        NULL,
2855f4259b30SLisandro Dalcin                                        /*104*/ NULL,
2856ba337c44SJed Brown                                        MatRealPart_SeqDense,
2857ba337c44SJed Brown                                        MatImaginaryPart_SeqDense,
2858f4259b30SLisandro Dalcin                                        NULL,
2859f4259b30SLisandro Dalcin                                        NULL,
2860f4259b30SLisandro Dalcin                                        /*109*/ NULL,
2861f4259b30SLisandro Dalcin                                        NULL,
28628d0534beSBarry Smith                                        MatGetRowMin_SeqDense,
2863aabbc4fbSShri Abhyankar                                        MatGetColumnVector_SeqDense,
28643b49f96aSBarry Smith                                        MatMissingDiagonal_SeqDense,
2865f4259b30SLisandro Dalcin                                        /*114*/ NULL,
2866f4259b30SLisandro Dalcin                                        NULL,
2867f4259b30SLisandro Dalcin                                        NULL,
2868f4259b30SLisandro Dalcin                                        NULL,
2869f4259b30SLisandro Dalcin                                        NULL,
2870f4259b30SLisandro Dalcin                                        /*119*/ NULL,
2871f4259b30SLisandro Dalcin                                        NULL,
2872f4259b30SLisandro Dalcin                                        NULL,
2873f4259b30SLisandro Dalcin                                        NULL,
2874f4259b30SLisandro Dalcin                                        NULL,
2875f4259b30SLisandro Dalcin                                        /*124*/ NULL,
2876a873a8cdSSam Reynolds                                        MatGetColumnReductions_SeqDense,
2877f4259b30SLisandro Dalcin                                        NULL,
2878f4259b30SLisandro Dalcin                                        NULL,
2879f4259b30SLisandro Dalcin                                        NULL,
2880f4259b30SLisandro Dalcin                                        /*129*/ NULL,
2881f4259b30SLisandro Dalcin                                        NULL,
2882f4259b30SLisandro Dalcin                                        NULL,
288375648e8dSHong Zhang                                        MatTransposeMatMultNumeric_SeqDense_SeqDense,
2884f4259b30SLisandro Dalcin                                        NULL,
2885f4259b30SLisandro Dalcin                                        /*134*/ NULL,
2886f4259b30SLisandro Dalcin                                        NULL,
2887f4259b30SLisandro Dalcin                                        NULL,
2888f4259b30SLisandro Dalcin                                        NULL,
2889f4259b30SLisandro Dalcin                                        NULL,
2890f4259b30SLisandro Dalcin                                        /*139*/ NULL,
2891f4259b30SLisandro Dalcin                                        NULL,
2892f4259b30SLisandro Dalcin                                        NULL,
2893f4259b30SLisandro Dalcin                                        NULL,
2894f4259b30SLisandro Dalcin                                        NULL,
28954222ddf1SHong Zhang                                        MatCreateMPIMatConcatenateSeqMat_SeqDense,
2896f4259b30SLisandro Dalcin                                        /*145*/ NULL,
2897f4259b30SLisandro Dalcin                                        NULL,
289899a7f59eSMark Adams                                        NULL,
289999a7f59eSMark Adams                                        NULL,
29007fb60732SBarry Smith                                        NULL,
29019371c9d4SSatish Balay                                        /*150*/ NULL};
290290ace30eSBarry Smith 
29034b828684SBarry Smith /*@C
2904fafbff53SBarry Smith    MatCreateSeqDense - Creates a sequential dense matrix that
2905d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
2906d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
2907289bc588SBarry Smith 
2908d083f849SBarry Smith    Collective
2909db81eaa0SLois Curfman McInnes 
291020563c6bSBarry Smith    Input Parameters:
2911db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
29120c775827SLois Curfman McInnes .  m - number of rows
291318f449edSLois Curfman McInnes .  n - number of columns
29140298fd71SBarry Smith -  data - optional location of matrix data in column major order.  Set data=NULL for PETSc
2915dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
291620563c6bSBarry Smith 
291720563c6bSBarry Smith    Output Parameter:
291844cd7ae7SLois Curfman McInnes .  A - the matrix
291920563c6bSBarry Smith 
2920b259b22eSLois Curfman McInnes    Notes:
292118f449edSLois Curfman McInnes    The data input variable is intended primarily for Fortran programmers
292218f449edSLois Curfman McInnes    who wish to allocate their own matrix memory space.  Most users should
29230298fd71SBarry Smith    set data=NULL.
292418f449edSLois Curfman McInnes 
2925027ccd11SLois Curfman McInnes    Level: intermediate
2926027ccd11SLois Curfman McInnes 
2927db781477SPatrick Sanan .seealso: `MatCreate()`, `MatCreateDense()`, `MatSetValues()`
292820563c6bSBarry Smith @*/
29299371c9d4SSatish Balay PetscErrorCode MatCreateSeqDense(MPI_Comm comm, PetscInt m, PetscInt n, PetscScalar *data, Mat *A) {
29303a40ed3dSBarry Smith   PetscFunctionBegin;
29319566063dSJacob Faibussowitsch   PetscCall(MatCreate(comm, A));
29329566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*A, m, n, m, n));
29339566063dSJacob Faibussowitsch   PetscCall(MatSetType(*A, MATSEQDENSE));
29349566063dSJacob Faibussowitsch   PetscCall(MatSeqDenseSetPreallocation(*A, data));
2935273d9f13SBarry Smith   PetscFunctionReturn(0);
2936273d9f13SBarry Smith }
2937273d9f13SBarry Smith 
2938273d9f13SBarry Smith /*@C
2939273d9f13SBarry Smith    MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements
2940273d9f13SBarry Smith 
2941d083f849SBarry Smith    Collective
2942273d9f13SBarry Smith 
2943273d9f13SBarry Smith    Input Parameters:
29441c4f3114SJed Brown +  B - the matrix
29450298fd71SBarry Smith -  data - the array (or NULL)
2946273d9f13SBarry Smith 
2947273d9f13SBarry Smith    Notes:
2948273d9f13SBarry Smith    The data input variable is intended primarily for Fortran programmers
2949273d9f13SBarry Smith    who wish to allocate their own matrix memory space.  Most users should
2950284134d9SBarry Smith    need not call this routine.
2951273d9f13SBarry Smith 
2952273d9f13SBarry Smith    Level: intermediate
2953273d9f13SBarry Smith 
2954db781477SPatrick Sanan .seealso: `MatCreate()`, `MatCreateDense()`, `MatSetValues()`, `MatDenseSetLDA()`
2955867c911aSBarry Smith 
2956273d9f13SBarry Smith @*/
29579371c9d4SSatish Balay PetscErrorCode MatSeqDenseSetPreallocation(Mat B, PetscScalar data[]) {
2958a23d5eceSKris Buschelman   PetscFunctionBegin;
2959d5ea218eSStefano Zampini   PetscValidHeaderSpecific(B, MAT_CLASSID, 1);
2960cac4c232SBarry Smith   PetscTryMethod(B, "MatSeqDenseSetPreallocation_C", (Mat, PetscScalar[]), (B, data));
2961a23d5eceSKris Buschelman   PetscFunctionReturn(0);
2962a23d5eceSKris Buschelman }
2963a23d5eceSKris Buschelman 
29649371c9d4SSatish Balay PetscErrorCode MatSeqDenseSetPreallocation_SeqDense(Mat B, PetscScalar *data) {
2965ad16ce7aSStefano Zampini   Mat_SeqDense *b = (Mat_SeqDense *)B->data;
2966273d9f13SBarry Smith 
2967273d9f13SBarry Smith   PetscFunctionBegin;
296828b400f6SJacob Faibussowitsch   PetscCheck(!b->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
2969273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
2970a868139aSShri Abhyankar 
29719566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(B->rmap));
29729566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(B->cmap));
297334ef9618SShri Abhyankar 
2974ad16ce7aSStefano Zampini   if (b->lda <= 0) b->lda = B->rmap->n;
297586d161a7SShri Abhyankar 
29769e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
29779566063dSJacob Faibussowitsch     if (!b->user_alloc) PetscCall(PetscFree(b->v));
29789566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1((size_t)b->lda * B->cmap->n, &b->v));
29799566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)B, b->lda * B->cmap->n * sizeof(PetscScalar)));
29802205254eSKarl Rupp 
29819e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
2982273d9f13SBarry Smith   } else { /* user-allocated storage */
29839566063dSJacob Faibussowitsch     if (!b->user_alloc) PetscCall(PetscFree(b->v));
2984273d9f13SBarry Smith     b->v          = data;
2985273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
2986273d9f13SBarry Smith   }
29870450473dSBarry Smith   B->assembled = PETSC_TRUE;
2988273d9f13SBarry Smith   PetscFunctionReturn(0);
2989273d9f13SBarry Smith }
2990273d9f13SBarry Smith 
299165b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
29929371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) {
2993d77f618aSHong Zhang   Mat                mat_elemental;
29941683a169SBarry Smith   const PetscScalar *array;
29951683a169SBarry Smith   PetscScalar       *v_colwise;
2996d77f618aSHong Zhang   PetscInt           M = A->rmap->N, N = A->cmap->N, i, j, k, *rows, *cols;
2997d77f618aSHong Zhang 
29988baccfbdSHong Zhang   PetscFunctionBegin;
29999566063dSJacob Faibussowitsch   PetscCall(PetscMalloc3(M * N, &v_colwise, M, &rows, N, &cols));
30009566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &array));
3001d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
3002d77f618aSHong Zhang   k = 0;
3003d77f618aSHong Zhang   for (j = 0; j < N; j++) {
3004d77f618aSHong Zhang     cols[j] = j;
30059371c9d4SSatish Balay     for (i = 0; i < M; i++) { v_colwise[j * M + i] = array[k++]; }
3006d77f618aSHong Zhang   }
30079371c9d4SSatish Balay   for (i = 0; i < M; i++) { rows[i] = i; }
30089566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &array));
3009d77f618aSHong Zhang 
30109566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental));
30119566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(mat_elemental, PETSC_DECIDE, PETSC_DECIDE, M, N));
30129566063dSJacob Faibussowitsch   PetscCall(MatSetType(mat_elemental, MATELEMENTAL));
30139566063dSJacob Faibussowitsch   PetscCall(MatSetUp(mat_elemental));
3014d77f618aSHong Zhang 
3015d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
30169566063dSJacob Faibussowitsch   PetscCall(MatSetValues(mat_elemental, M, rows, N, cols, v_colwise, ADD_VALUES));
30179566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY));
30189566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY));
30199566063dSJacob Faibussowitsch   PetscCall(PetscFree3(v_colwise, rows, cols));
3020d77f618aSHong Zhang 
3021511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
30229566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A, &mat_elemental));
3023d77f618aSHong Zhang   } else {
3024d77f618aSHong Zhang     *newmat = mat_elemental;
3025d77f618aSHong Zhang   }
30268baccfbdSHong Zhang   PetscFunctionReturn(0);
30278baccfbdSHong Zhang }
302865b80a83SHong Zhang #endif
30298baccfbdSHong Zhang 
30309371c9d4SSatish Balay PetscErrorCode MatDenseSetLDA_SeqDense(Mat B, PetscInt lda) {
30311b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense *)B->data;
30327422da62SJose E. Roman   PetscBool     data;
303321a2c019SBarry Smith 
30341b807ce4Svictorle   PetscFunctionBegin;
30357422da62SJose E. Roman   data = (PetscBool)((B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE);
3036aed4548fSBarry Smith   PetscCheck(b->user_alloc || !data || b->lda == lda, PETSC_COMM_SELF, PETSC_ERR_ORDER, "LDA cannot be changed after allocation of internal storage");
303708401ef6SPierre 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);
30381b807ce4Svictorle   b->lda = lda;
30391b807ce4Svictorle   PetscFunctionReturn(0);
30401b807ce4Svictorle }
30411b807ce4Svictorle 
30429371c9d4SSatish Balay PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm, Mat inmat, PetscInt n, MatReuse scall, Mat *outmat) {
3043d528f656SJakub Kruzik   PetscFunctionBegin;
30449566063dSJacob Faibussowitsch   PetscCall(MatCreateMPIMatConcatenateSeqMat_MPIDense(comm, inmat, n, scall, outmat));
3045d528f656SJakub Kruzik   PetscFunctionReturn(0);
3046d528f656SJakub Kruzik }
3047d528f656SJakub Kruzik 
30489371c9d4SSatish Balay PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A, PetscInt col, Vec *v) {
30496947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
30506947451fSStefano Zampini 
30516947451fSStefano Zampini   PetscFunctionBegin;
305228b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
305328b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
30546947451fSStefano Zampini   if (!a->cvec) {
30559566063dSJacob Faibussowitsch     PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec));
30569566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)A, (PetscObject)a->cvec));
30576947451fSStefano Zampini   }
30586947451fSStefano Zampini   a->vecinuse = col + 1;
30599566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, (PetscScalar **)&a->ptrinuse));
30609566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda));
30616947451fSStefano Zampini   *v = a->cvec;
30626947451fSStefano Zampini   PetscFunctionReturn(0);
30636947451fSStefano Zampini }
30646947451fSStefano Zampini 
30659371c9d4SSatish Balay PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A, PetscInt col, Vec *v) {
30666947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
30676947451fSStefano Zampini 
30686947451fSStefano Zampini   PetscFunctionBegin;
306928b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first");
307028b400f6SJacob Faibussowitsch   PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector");
30716947451fSStefano Zampini   a->vecinuse = 0;
30729566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, (PetscScalar **)&a->ptrinuse));
30739566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
307475f6d85dSStefano Zampini   if (v) *v = NULL;
30756947451fSStefano Zampini   PetscFunctionReturn(0);
30766947451fSStefano Zampini }
30776947451fSStefano Zampini 
30789371c9d4SSatish Balay PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v) {
30796947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
30806947451fSStefano Zampini 
30816947451fSStefano Zampini   PetscFunctionBegin;
308228b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
308328b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
30846947451fSStefano Zampini   if (!a->cvec) {
30859566063dSJacob Faibussowitsch     PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec));
30869566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)A, (PetscObject)a->cvec));
30876947451fSStefano Zampini   }
30886947451fSStefano Zampini   a->vecinuse = col + 1;
30899566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &a->ptrinuse));
30909566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda));
30919566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(a->cvec));
30926947451fSStefano Zampini   *v = a->cvec;
30936947451fSStefano Zampini   PetscFunctionReturn(0);
30946947451fSStefano Zampini }
30956947451fSStefano Zampini 
30969371c9d4SSatish Balay PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v) {
30976947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
30986947451fSStefano Zampini 
30996947451fSStefano Zampini   PetscFunctionBegin;
310028b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first");
310128b400f6SJacob Faibussowitsch   PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector");
31026947451fSStefano Zampini   a->vecinuse = 0;
31039566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &a->ptrinuse));
31049566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(a->cvec));
31059566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
310675f6d85dSStefano Zampini   if (v) *v = NULL;
31076947451fSStefano Zampini   PetscFunctionReturn(0);
31086947451fSStefano Zampini }
31096947451fSStefano Zampini 
31109371c9d4SSatish Balay PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v) {
31116947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
31126947451fSStefano Zampini 
31136947451fSStefano Zampini   PetscFunctionBegin;
311428b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
311528b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
31166947451fSStefano Zampini   if (!a->cvec) {
31179566063dSJacob Faibussowitsch     PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec));
31189566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)A, (PetscObject)a->cvec));
31196947451fSStefano Zampini   }
31206947451fSStefano Zampini   a->vecinuse = col + 1;
31219566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(A, (PetscScalar **)&a->ptrinuse));
31229566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda));
31236947451fSStefano Zampini   *v = a->cvec;
31246947451fSStefano Zampini   PetscFunctionReturn(0);
31256947451fSStefano Zampini }
31266947451fSStefano Zampini 
31279371c9d4SSatish Balay PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v) {
31286947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
31296947451fSStefano Zampini 
31306947451fSStefano Zampini   PetscFunctionBegin;
313128b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first");
313228b400f6SJacob Faibussowitsch   PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector");
31336947451fSStefano Zampini   a->vecinuse = 0;
31349566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(A, (PetscScalar **)&a->ptrinuse));
31359566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
313675f6d85dSStefano Zampini   if (v) *v = NULL;
31376947451fSStefano Zampini   PetscFunctionReturn(0);
31386947451fSStefano Zampini }
31396947451fSStefano Zampini 
31409371c9d4SSatish Balay PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) {
31415ea7661aSPierre Jolivet   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
31425ea7661aSPierre Jolivet 
31435ea7661aSPierre Jolivet   PetscFunctionBegin;
314428b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
314528b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
3146a2748737SPierre Jolivet   if (a->cmat && (cend - cbegin != a->cmat->cmap->N || rend - rbegin != a->cmat->rmap->N)) PetscCall(MatDestroy(&a->cmat));
31475ea7661aSPierre Jolivet   if (!a->cmat) {
3148a2748737SPierre Jolivet     PetscCall(MatCreateDense(PetscObjectComm((PetscObject)A), rend - rbegin, PETSC_DECIDE, rend - rbegin, cend - cbegin, a->v + rbegin + (size_t)cbegin * a->lda, &a->cmat));
31499566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)A, (PetscObject)a->cmat));
31505ea7661aSPierre Jolivet   } else {
3151a2748737SPierre Jolivet     PetscCall(MatDensePlaceArray(a->cmat, a->v + rbegin + (size_t)cbegin * a->lda));
31525ea7661aSPierre Jolivet   }
31539566063dSJacob Faibussowitsch   PetscCall(MatDenseSetLDA(a->cmat, a->lda));
31545ea7661aSPierre Jolivet   a->matinuse = cbegin + 1;
31555ea7661aSPierre Jolivet   *v          = a->cmat;
315675f6d85dSStefano Zampini #if defined(PETSC_HAVE_CUDA)
315775f6d85dSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
315875f6d85dSStefano Zampini #endif
31595ea7661aSPierre Jolivet   PetscFunctionReturn(0);
31605ea7661aSPierre Jolivet }
31615ea7661aSPierre Jolivet 
31629371c9d4SSatish Balay PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A, Mat *v) {
31635ea7661aSPierre Jolivet   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
31645ea7661aSPierre Jolivet 
31655ea7661aSPierre Jolivet   PetscFunctionBegin;
316628b400f6SJacob Faibussowitsch   PetscCheck(a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetSubMatrix() first");
316728b400f6SJacob Faibussowitsch   PetscCheck(a->cmat, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column matrix");
316808401ef6SPierre Jolivet   PetscCheck(*v == a->cmat, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not the matrix obtained from MatDenseGetSubMatrix()");
31695ea7661aSPierre Jolivet   a->matinuse = 0;
31709566063dSJacob Faibussowitsch   PetscCall(MatDenseResetArray(a->cmat));
3171742765d3SMatthew Knepley   if (v) *v = NULL;
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:
31790bad9183SKris Buschelman . -mat_type seqdense - sets the matrix type to "seqdense" during a call to MatSetFromOptions()
31800bad9183SKris Buschelman 
31810bad9183SKris Buschelman   Level: beginner
31820bad9183SKris Buschelman 
3183db781477SPatrick Sanan .seealso: `MatCreateSeqDense()`
318489665df3SBarry Smith 
31850bad9183SKris Buschelman M*/
31869371c9d4SSatish Balay PetscErrorCode MatCreate_SeqDense(Mat B) {
3187273d9f13SBarry Smith   Mat_SeqDense *b;
31887c334f02SBarry Smith   PetscMPIInt   size;
3189273d9f13SBarry Smith 
3190273d9f13SBarry Smith   PetscFunctionBegin;
31919566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)B), &size));
319208401ef6SPierre Jolivet   PetscCheck(size <= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Comm must be of size 1");
319355659b69SBarry Smith 
31949566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(B, &b));
31959566063dSJacob Faibussowitsch   PetscCall(PetscMemcpy(B->ops, &MatOps_Values, sizeof(struct _MatOps)));
319644cd7ae7SLois Curfman McInnes   B->data = (void *)b;
319718f449edSLois Curfman McInnes 
3198273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
31994e220ebcSLois Curfman McInnes 
32009566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatQRFactor_C", MatQRFactor_SeqDense));
32019566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetLDA_C", MatDenseGetLDA_SeqDense));
32029566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseSetLDA_C", MatDenseSetLDA_SeqDense));
32039566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArray_C", MatDenseGetArray_SeqDense));
32049566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArray_C", MatDenseRestoreArray_SeqDense));
32059566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDensePlaceArray_C", MatDensePlaceArray_SeqDense));
32069566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseResetArray_C", MatDenseResetArray_SeqDense));
32079566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseReplaceArray_C", MatDenseReplaceArray_SeqDense));
32089566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayRead_C", MatDenseGetArray_SeqDense));
32099566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayRead_C", MatDenseRestoreArray_SeqDense));
32109566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayWrite_C", MatDenseGetArray_SeqDense));
32119566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayWrite_C", MatDenseRestoreArray_SeqDense));
32129566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqaij_C", MatConvert_SeqDense_SeqAIJ));
32138baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
32149566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_elemental_C", MatConvert_SeqDense_Elemental));
32158baccfbdSHong Zhang #endif
3216d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
32179566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_scalapack_C", MatConvert_Dense_ScaLAPACK));
3218d24d4204SJose E. Roman #endif
32192bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
32209566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensecuda_C", MatConvert_SeqDense_SeqDenseCUDA));
32219566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", MatProductSetFromOptions_SeqDense));
32229566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdense_C", MatProductSetFromOptions_SeqDense));
32239566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensecuda_C", MatProductSetFromOptions_SeqDense));
32242bf066beSStefano Zampini #endif
32259566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSeqDenseSetPreallocation_C", MatSeqDenseSetPreallocation_SeqDense));
32269566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqaij_seqdense_C", MatProductSetFromOptions_SeqAIJ_SeqDense));
32279566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdense_C", MatProductSetFromOptions_SeqDense));
32289566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense));
32299566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqsbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense));
323096e6d5c4SRichard Tran Mills 
32319566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumn_C", MatDenseGetColumn_SeqDense));
32329566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumn_C", MatDenseRestoreColumn_SeqDense));
32339566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVec_C", MatDenseGetColumnVec_SeqDense));
32349566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVec_C", MatDenseRestoreColumnVec_SeqDense));
32359566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecRead_C", MatDenseGetColumnVecRead_SeqDense));
32369566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecRead_C", MatDenseRestoreColumnVecRead_SeqDense));
32379566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecWrite_C", MatDenseGetColumnVecWrite_SeqDense));
32389566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecWrite_C", MatDenseRestoreColumnVecWrite_SeqDense));
32399566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetSubMatrix_C", MatDenseGetSubMatrix_SeqDense));
32409566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreSubMatrix_C", MatDenseRestoreSubMatrix_SeqDense));
32419566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)B, MATSEQDENSE));
32423a40ed3dSBarry Smith   PetscFunctionReturn(0);
3243289bc588SBarry Smith }
324486aefd0dSHong Zhang 
324586aefd0dSHong Zhang /*@C
3246af53bab2SHong Zhang    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.
324786aefd0dSHong Zhang 
324886aefd0dSHong Zhang    Not Collective
324986aefd0dSHong Zhang 
32505ea7661aSPierre Jolivet    Input Parameters:
325186aefd0dSHong Zhang +  mat - a MATSEQDENSE or MATMPIDENSE matrix
325286aefd0dSHong Zhang -  col - column index
325386aefd0dSHong Zhang 
325486aefd0dSHong Zhang    Output Parameter:
325586aefd0dSHong Zhang .  vals - pointer to the data
325686aefd0dSHong Zhang 
325786aefd0dSHong Zhang    Level: intermediate
325886aefd0dSHong Zhang 
3259db781477SPatrick Sanan .seealso: `MatDenseRestoreColumn()`
326086aefd0dSHong Zhang @*/
32619371c9d4SSatish Balay PetscErrorCode MatDenseGetColumn(Mat A, PetscInt col, PetscScalar **vals) {
326286aefd0dSHong Zhang   PetscFunctionBegin;
3263d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
3264d5ea218eSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
3265d5ea218eSStefano Zampini   PetscValidPointer(vals, 3);
3266cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumn_C", (Mat, PetscInt, PetscScalar **), (A, col, vals));
326786aefd0dSHong Zhang   PetscFunctionReturn(0);
326886aefd0dSHong Zhang }
326986aefd0dSHong Zhang 
327086aefd0dSHong Zhang /*@C
327186aefd0dSHong Zhang    MatDenseRestoreColumn - returns access to a column of a dense matrix which is returned by MatDenseGetColumn().
327286aefd0dSHong Zhang 
327386aefd0dSHong Zhang    Not Collective
327486aefd0dSHong Zhang 
3275742765d3SMatthew Knepley    Input Parameters:
3276742765d3SMatthew Knepley +  mat - a MATSEQDENSE or MATMPIDENSE matrix
3277742765d3SMatthew Knepley -  vals - pointer to the data (may be NULL)
327886aefd0dSHong Zhang 
327986aefd0dSHong Zhang    Level: intermediate
328086aefd0dSHong Zhang 
3281db781477SPatrick Sanan .seealso: `MatDenseGetColumn()`
328286aefd0dSHong Zhang @*/
32839371c9d4SSatish Balay PetscErrorCode MatDenseRestoreColumn(Mat A, PetscScalar **vals) {
328486aefd0dSHong Zhang   PetscFunctionBegin;
3285d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
3286d5ea218eSStefano Zampini   PetscValidPointer(vals, 2);
3287cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumn_C", (Mat, PetscScalar **), (A, vals));
328886aefd0dSHong Zhang   PetscFunctionReturn(0);
328986aefd0dSHong Zhang }
32906947451fSStefano Zampini 
32910f74d2c1SSatish Balay /*@
32926947451fSStefano Zampini    MatDenseGetColumnVec - Gives read-write access to a column of a dense matrix, represented as a Vec.
32936947451fSStefano Zampini 
32946947451fSStefano Zampini    Collective
32956947451fSStefano Zampini 
32965ea7661aSPierre Jolivet    Input Parameters:
32976947451fSStefano Zampini +  mat - the Mat object
32986947451fSStefano Zampini -  col - the column index
32996947451fSStefano Zampini 
33006947451fSStefano Zampini    Output Parameter:
33016947451fSStefano Zampini .  v - the vector
33026947451fSStefano Zampini 
33036947451fSStefano Zampini    Notes:
33046947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVec() when the vector is no longer needed.
33056947451fSStefano Zampini      Use MatDenseGetColumnVecRead() to obtain read-only access or MatDenseGetColumnVecWrite() for write-only access.
33066947451fSStefano Zampini 
33076947451fSStefano Zampini    Level: intermediate
33086947451fSStefano Zampini 
3309db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
33106947451fSStefano Zampini @*/
33119371c9d4SSatish Balay PetscErrorCode MatDenseGetColumnVec(Mat A, PetscInt col, Vec *v) {
33126947451fSStefano Zampini   PetscFunctionBegin;
33136947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
33146947451fSStefano Zampini   PetscValidType(A, 1);
33156947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
33166947451fSStefano Zampini   PetscValidPointer(v, 3);
331728b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
33182cf15c64SPierre 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);
3319cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v));
33206947451fSStefano Zampini   PetscFunctionReturn(0);
33216947451fSStefano Zampini }
33226947451fSStefano Zampini 
33230f74d2c1SSatish Balay /*@
33246947451fSStefano Zampini    MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVec().
33256947451fSStefano Zampini 
33266947451fSStefano Zampini    Collective
33276947451fSStefano Zampini 
33285ea7661aSPierre Jolivet    Input Parameters:
33296947451fSStefano Zampini +  mat - the Mat object
33306947451fSStefano Zampini .  col - the column index
3331742765d3SMatthew Knepley -  v - the Vec object (may be NULL)
33326947451fSStefano Zampini 
33336947451fSStefano Zampini    Level: intermediate
33346947451fSStefano Zampini 
3335db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
33366947451fSStefano Zampini @*/
33379371c9d4SSatish Balay PetscErrorCode MatDenseRestoreColumnVec(Mat A, PetscInt col, Vec *v) {
33386947451fSStefano Zampini   PetscFunctionBegin;
33396947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
33406947451fSStefano Zampini   PetscValidType(A, 1);
33416947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
334208401ef6SPierre Jolivet   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
33432cf15c64SPierre 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);
3344cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v));
33456947451fSStefano Zampini   PetscFunctionReturn(0);
33466947451fSStefano Zampini }
33476947451fSStefano Zampini 
33480f74d2c1SSatish Balay /*@
33496947451fSStefano Zampini    MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a Vec.
33506947451fSStefano Zampini 
33516947451fSStefano Zampini    Collective
33526947451fSStefano Zampini 
33535ea7661aSPierre Jolivet    Input Parameters:
33546947451fSStefano Zampini +  mat - the Mat object
33556947451fSStefano Zampini -  col - the column index
33566947451fSStefano Zampini 
33576947451fSStefano Zampini    Output Parameter:
33586947451fSStefano Zampini .  v - the vector
33596947451fSStefano Zampini 
33606947451fSStefano Zampini    Notes:
33616947451fSStefano Zampini      The vector is owned by PETSc and users cannot modify it.
33626947451fSStefano Zampini      Users need to call MatDenseRestoreColumnVecRead() when the vector is no longer needed.
33636947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecWrite() for write-only access.
33646947451fSStefano Zampini 
33656947451fSStefano Zampini    Level: intermediate
33666947451fSStefano Zampini 
3367db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
33686947451fSStefano Zampini @*/
33699371c9d4SSatish Balay PetscErrorCode MatDenseGetColumnVecRead(Mat A, PetscInt col, Vec *v) {
33706947451fSStefano Zampini   PetscFunctionBegin;
33716947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
33726947451fSStefano Zampini   PetscValidType(A, 1);
33736947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
33746947451fSStefano Zampini   PetscValidPointer(v, 3);
337528b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
33762cf15c64SPierre Jolivet   PetscCheck(col >= 0 && col < A->cmap->N, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")", col, A->cmap->N);
3377cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v));
33786947451fSStefano Zampini   PetscFunctionReturn(0);
33796947451fSStefano Zampini }
33806947451fSStefano Zampini 
33810f74d2c1SSatish Balay /*@
33826947451fSStefano Zampini    MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecRead().
33836947451fSStefano Zampini 
33846947451fSStefano Zampini    Collective
33856947451fSStefano Zampini 
33865ea7661aSPierre Jolivet    Input Parameters:
33876947451fSStefano Zampini +  mat - the Mat object
33886947451fSStefano Zampini .  col - the column index
3389742765d3SMatthew Knepley -  v - the Vec object (may be NULL)
33906947451fSStefano Zampini 
33916947451fSStefano Zampini    Level: intermediate
33926947451fSStefano Zampini 
3393db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecWrite()`
33946947451fSStefano Zampini @*/
33959371c9d4SSatish Balay PetscErrorCode MatDenseRestoreColumnVecRead(Mat A, PetscInt col, Vec *v) {
33966947451fSStefano Zampini   PetscFunctionBegin;
33976947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
33986947451fSStefano Zampini   PetscValidType(A, 1);
33996947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
340008401ef6SPierre Jolivet   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
34012cf15c64SPierre 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);
3402cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v));
34036947451fSStefano Zampini   PetscFunctionReturn(0);
34046947451fSStefano Zampini }
34056947451fSStefano Zampini 
34060f74d2c1SSatish Balay /*@
34076947451fSStefano Zampini    MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a Vec.
34086947451fSStefano Zampini 
34096947451fSStefano Zampini    Collective
34106947451fSStefano Zampini 
34115ea7661aSPierre Jolivet    Input Parameters:
34126947451fSStefano Zampini +  mat - the Mat object
34136947451fSStefano Zampini -  col - the column index
34146947451fSStefano Zampini 
34156947451fSStefano Zampini    Output Parameter:
34166947451fSStefano Zampini .  v - the vector
34176947451fSStefano Zampini 
34186947451fSStefano Zampini    Notes:
34196947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVecWrite() when the vector is no longer needed.
34206947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecRead() for read-only access.
34216947451fSStefano Zampini 
34226947451fSStefano Zampini    Level: intermediate
34236947451fSStefano Zampini 
3424db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
34256947451fSStefano Zampini @*/
34269371c9d4SSatish Balay PetscErrorCode MatDenseGetColumnVecWrite(Mat A, PetscInt col, Vec *v) {
34276947451fSStefano Zampini   PetscFunctionBegin;
34286947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
34296947451fSStefano Zampini   PetscValidType(A, 1);
34306947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
34316947451fSStefano Zampini   PetscValidPointer(v, 3);
343228b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
3433aed4548fSBarry 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);
3434cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v));
34356947451fSStefano Zampini   PetscFunctionReturn(0);
34366947451fSStefano Zampini }
34376947451fSStefano Zampini 
34380f74d2c1SSatish Balay /*@
34396947451fSStefano Zampini    MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecWrite().
34406947451fSStefano Zampini 
34416947451fSStefano Zampini    Collective
34426947451fSStefano Zampini 
34435ea7661aSPierre Jolivet    Input Parameters:
34446947451fSStefano Zampini +  mat - the Mat object
34456947451fSStefano Zampini .  col - the column index
3446742765d3SMatthew Knepley -  v - the Vec object (may be NULL)
34476947451fSStefano Zampini 
34486947451fSStefano Zampini    Level: intermediate
34496947451fSStefano Zampini 
3450db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`
34516947451fSStefano Zampini @*/
34529371c9d4SSatish Balay PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A, PetscInt col, Vec *v) {
34536947451fSStefano Zampini   PetscFunctionBegin;
34546947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
34556947451fSStefano Zampini   PetscValidType(A, 1);
34566947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
345708401ef6SPierre Jolivet   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
3458aed4548fSBarry 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);
3459cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v));
34606947451fSStefano Zampini   PetscFunctionReturn(0);
34616947451fSStefano Zampini }
34625ea7661aSPierre Jolivet 
34630f74d2c1SSatish Balay /*@
3464a2748737SPierre Jolivet    MatDenseGetSubMatrix - Gives access to a block of rows and columns of a dense matrix, represented as a Mat.
34655ea7661aSPierre Jolivet 
34665ea7661aSPierre Jolivet    Collective
34675ea7661aSPierre Jolivet 
34685ea7661aSPierre Jolivet    Input Parameters:
34695ea7661aSPierre Jolivet +  mat - the Mat object
3470a2748737SPierre Jolivet .  rbegin - the first global row index in the block (if PETSC_DECIDE, is 0)
3471a2748737SPierre Jolivet .  rend - the global row index past the last one in the block (if PETSC_DECIDE, is M)
3472a2748737SPierre Jolivet .  cbegin - the first global column index in the block (if PETSC_DECIDE, is 0)
3473a2748737SPierre Jolivet -  cend - the global column index past the last one in the block (if PETSC_DECIDE, is N)
34745ea7661aSPierre Jolivet 
34755ea7661aSPierre Jolivet    Output Parameter:
34765ea7661aSPierre Jolivet .  v - the matrix
34775ea7661aSPierre Jolivet 
34785ea7661aSPierre Jolivet    Notes:
34795ea7661aSPierre Jolivet      The matrix is owned by PETSc. Users need to call MatDenseRestoreSubMatrix() when the matrix is no longer needed.
3480a2748737SPierre 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.
34815ea7661aSPierre Jolivet 
34825ea7661aSPierre Jolivet    Level: intermediate
34835ea7661aSPierre Jolivet 
3484db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreSubMatrix()`
34855ea7661aSPierre Jolivet @*/
34869371c9d4SSatish Balay PetscErrorCode MatDenseGetSubMatrix(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) {
34875ea7661aSPierre Jolivet   PetscFunctionBegin;
34885ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
34895ea7661aSPierre Jolivet   PetscValidType(A, 1);
3490a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, rbegin, 2);
3491a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, rend, 3);
3492a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, cbegin, 4);
3493a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, cend, 5);
3494a2748737SPierre Jolivet   PetscValidPointer(v, 6);
3495a2748737SPierre Jolivet   if (rbegin == PETSC_DECIDE) rbegin = 0;
3496a2748737SPierre Jolivet   if (rend == PETSC_DECIDE) rend = A->rmap->N;
3497a2748737SPierre Jolivet   if (cbegin == PETSC_DECIDE) cbegin = 0;
3498a2748737SPierre Jolivet   if (cend == PETSC_DECIDE) cend = A->cmap->N;
349928b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
3500a2748737SPierre 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);
3501a2748737SPierre 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);
3502a2748737SPierre 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);
3503a2748737SPierre 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);
3504a2748737SPierre Jolivet   PetscUseMethod(A, "MatDenseGetSubMatrix_C", (Mat, PetscInt, PetscInt, PetscInt, PetscInt, Mat *), (A, rbegin, rend, cbegin, cend, v));
35055ea7661aSPierre Jolivet   PetscFunctionReturn(0);
35065ea7661aSPierre Jolivet }
35075ea7661aSPierre Jolivet 
35080f74d2c1SSatish Balay /*@
35095ea7661aSPierre Jolivet    MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from MatDenseGetSubMatrix().
35105ea7661aSPierre Jolivet 
35115ea7661aSPierre Jolivet    Collective
35125ea7661aSPierre Jolivet 
35135ea7661aSPierre Jolivet    Input Parameters:
35145ea7661aSPierre Jolivet +  mat - the Mat object
3515742765d3SMatthew Knepley -  v - the Mat object (may be NULL)
35165ea7661aSPierre Jolivet 
35175ea7661aSPierre Jolivet    Level: intermediate
35185ea7661aSPierre Jolivet 
3519db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseGetSubMatrix()`
35205ea7661aSPierre Jolivet @*/
35219371c9d4SSatish Balay PetscErrorCode MatDenseRestoreSubMatrix(Mat A, Mat *v) {
35225ea7661aSPierre Jolivet   PetscFunctionBegin;
35235ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
35245ea7661aSPierre Jolivet   PetscValidType(A, 1);
35255ea7661aSPierre Jolivet   PetscValidPointer(v, 2);
3526cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreSubMatrix_C", (Mat, Mat *), (A, v));
35275ea7661aSPierre Jolivet   PetscFunctionReturn(0);
35285ea7661aSPierre Jolivet }
35298a9c020eSBarry Smith 
35308a9c020eSBarry Smith #include <petscblaslapack.h>
35318a9c020eSBarry Smith #include <petsc/private/kernels/blockinvert.h>
35328a9c020eSBarry Smith 
35339371c9d4SSatish Balay PetscErrorCode MatSeqDenseInvert(Mat A) {
35348a9c020eSBarry Smith   Mat_SeqDense   *a              = (Mat_SeqDense *)A->data;
35358a9c020eSBarry Smith   PetscInt        bs             = A->rmap->n;
35368a9c020eSBarry Smith   MatScalar      *values         = a->v;
35378a9c020eSBarry Smith   const PetscReal shift          = 0.0;
35388a9c020eSBarry Smith   PetscBool       allowzeropivot = PetscNot(A->erroriffailure), zeropivotdetected = PETSC_FALSE;
35398a9c020eSBarry Smith 
35408a9c020eSBarry Smith   PetscFunctionBegin;
35418a9c020eSBarry Smith   /* factor and invert each block */
35428a9c020eSBarry Smith   switch (bs) {
35439371c9d4SSatish Balay   case 1: values[0] = (PetscScalar)1.0 / (values[0] + shift); break;
35448a9c020eSBarry Smith   case 2:
35458a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_2(values, shift, allowzeropivot, &zeropivotdetected));
35468a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
35478a9c020eSBarry Smith     break;
35488a9c020eSBarry Smith   case 3:
35498a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_3(values, shift, allowzeropivot, &zeropivotdetected));
35508a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
35518a9c020eSBarry Smith     break;
35528a9c020eSBarry Smith   case 4:
35538a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_4(values, shift, allowzeropivot, &zeropivotdetected));
35548a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
35558a9c020eSBarry Smith     break;
35569371c9d4SSatish Balay   case 5: {
35578a9c020eSBarry Smith     PetscScalar work[25];
35588a9c020eSBarry Smith     PetscInt    ipvt[5];
35598a9c020eSBarry Smith 
35608a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_5(values, ipvt, work, shift, allowzeropivot, &zeropivotdetected));
35618a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
35629371c9d4SSatish Balay   } break;
35638a9c020eSBarry Smith   case 6:
35648a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_6(values, shift, allowzeropivot, &zeropivotdetected));
35658a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
35668a9c020eSBarry Smith     break;
35678a9c020eSBarry Smith   case 7:
35688a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_7(values, shift, allowzeropivot, &zeropivotdetected));
35698a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
35708a9c020eSBarry Smith     break;
35719371c9d4SSatish Balay   default: {
35728a9c020eSBarry Smith     PetscInt    *v_pivots, *IJ, j;
35738a9c020eSBarry Smith     PetscScalar *v_work;
35748a9c020eSBarry Smith 
35758a9c020eSBarry Smith     PetscCall(PetscMalloc3(bs, &v_work, bs, &v_pivots, bs, &IJ));
35769371c9d4SSatish Balay     for (j = 0; j < bs; j++) { IJ[j] = j; }
35778a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A(bs, values, v_pivots, v_work, allowzeropivot, &zeropivotdetected));
35788a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
35798a9c020eSBarry Smith     PetscCall(PetscFree3(v_work, v_pivots, IJ));
35808a9c020eSBarry Smith   }
35818a9c020eSBarry Smith   }
35828a9c020eSBarry Smith   PetscFunctionReturn(0);
35838a9c020eSBarry Smith }
3584