xref: /petsc/src/mat/impls/dense/seq/dense.c (revision d71ae5a4db6382e7f06317b8d368875286fe9008)
167e560aaSBarry Smith /*
267e560aaSBarry Smith      Defines the basic matrix operations for sequential dense.
367e560aaSBarry Smith */
4289bc588SBarry Smith 
5dec5eb66SMatthew G Knepley #include <../src/mat/impls/dense/seq/dense.h> /*I "petscmat.h" I*/
6c6db04a5SJed Brown #include <petscblaslapack.h>
76a63e612SBarry Smith #include <../src/mat/impls/aij/seq/aij.h>
8b2573a8aSBarry Smith 
9*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSymmetrize_Private(Mat A, PetscBool hermitian)
10*d71ae5a4SJacob Faibussowitsch {
118c178816SStefano Zampini   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
128c178816SStefano Zampini   PetscInt      j, k, n = A->rmap->n;
13ca15aa20SStefano Zampini   PetscScalar  *v;
148c178816SStefano Zampini 
158c178816SStefano Zampini   PetscFunctionBegin;
1608401ef6SPierre Jolivet   PetscCheck(A->rmap->n == A->cmap->n, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Cannot symmetrize a rectangular matrix");
179566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
188c178816SStefano Zampini   if (!hermitian) {
198c178816SStefano Zampini     for (k = 0; k < n; k++) {
20ad540459SPierre Jolivet       for (j = k; j < n; j++) v[j * mat->lda + k] = v[k * mat->lda + j];
218c178816SStefano Zampini     }
228c178816SStefano Zampini   } else {
238c178816SStefano Zampini     for (k = 0; k < n; k++) {
24ad540459SPierre Jolivet       for (j = k; j < n; j++) v[j * mat->lda + k] = PetscConj(v[k * mat->lda + j]);
258c178816SStefano Zampini     }
268c178816SStefano Zampini   }
279566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
288c178816SStefano Zampini   PetscFunctionReturn(0);
298c178816SStefano Zampini }
308c178816SStefano Zampini 
31*d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode MatSeqDenseInvertFactors_Private(Mat A)
32*d71ae5a4SJacob Faibussowitsch {
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));
448c178816SStefano Zampini     }
459566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
46792fecdfSBarry Smith     PetscCallBLAS("LAPACKgetri", LAPACKgetri_(&n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info));
479566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
489566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0));
498c178816SStefano Zampini   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
50b94d7dedSBarry Smith     if (A->spd == PETSC_BOOL3_TRUE) {
519566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
52792fecdfSBarry Smith       PetscCallBLAS("LAPACKpotri", LAPACKpotri_("L", &n, mat->v, &mat->lda, &info));
539566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
549566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_TRUE));
558c178816SStefano Zampini #if defined(PETSC_USE_COMPLEX)
56b94d7dedSBarry Smith     } else if (A->hermitian == PETSC_BOOL3_TRUE) {
5728b400f6SJacob Faibussowitsch       PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present");
5828b400f6SJacob Faibussowitsch       PetscCheck(mat->fwork, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Fwork not present");
599566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
60792fecdfSBarry Smith       PetscCallBLAS("LAPACKhetri", LAPACKhetri_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &info));
619566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
629566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_TRUE));
638c178816SStefano Zampini #endif
648c178816SStefano Zampini     } else { /* symmetric case */
6528b400f6SJacob Faibussowitsch       PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present");
6628b400f6SJacob Faibussowitsch       PetscCheck(mat->fwork, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Fwork not present");
679566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
68792fecdfSBarry Smith       PetscCallBLAS("LAPACKsytri", LAPACKsytri_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &info));
699566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
709566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_FALSE));
718c178816SStefano Zampini     }
7228b400f6SJacob Faibussowitsch     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad Inversion: zero pivot in row %" PetscInt_FMT, (PetscInt)info - 1);
739566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0));
748c178816SStefano Zampini   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Matrix must be factored to solve");
758c178816SStefano Zampini 
768c178816SStefano Zampini   A->ops->solve             = NULL;
778c178816SStefano Zampini   A->ops->matsolve          = NULL;
788c178816SStefano Zampini   A->ops->solvetranspose    = NULL;
798c178816SStefano Zampini   A->ops->matsolvetranspose = NULL;
808c178816SStefano Zampini   A->ops->solveadd          = NULL;
818c178816SStefano Zampini   A->ops->solvetransposeadd = NULL;
828c178816SStefano Zampini   A->factortype             = MAT_FACTOR_NONE;
839566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
848c178816SStefano Zampini   PetscFunctionReturn(0);
858c178816SStefano Zampini }
868c178816SStefano Zampini 
87*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatZeroRowsColumns_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b)
88*d71ae5a4SJacob Faibussowitsch {
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 
144*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatPtAPNumeric_SeqDense_SeqDense(Mat A, Mat P, Mat C)
145*d71ae5a4SJacob Faibussowitsch {
146abc3b08eSStefano Zampini   Mat_SeqDense *c = (Mat_SeqDense *)(C->data);
147abc3b08eSStefano Zampini 
148abc3b08eSStefano Zampini   PetscFunctionBegin;
149ca15aa20SStefano Zampini   if (c->ptapwork) {
1509566063dSJacob Faibussowitsch     PetscCall((*C->ops->matmultnumeric)(A, P, c->ptapwork));
1519566063dSJacob Faibussowitsch     PetscCall((*C->ops->transposematmultnumeric)(P, c->ptapwork, C));
1524222ddf1SHong Zhang   } else SETERRQ(PetscObjectComm((PetscObject)C), PETSC_ERR_SUP, "Must call MatPtAPSymbolic_SeqDense_SeqDense() first");
153abc3b08eSStefano Zampini   PetscFunctionReturn(0);
154abc3b08eSStefano Zampini }
155abc3b08eSStefano Zampini 
156*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatPtAPSymbolic_SeqDense_SeqDense(Mat A, Mat P, PetscReal fill, Mat C)
157*d71ae5a4SJacob Faibussowitsch {
158abc3b08eSStefano Zampini   Mat_SeqDense *c;
1597a3c3d58SStefano Zampini   PetscBool     cisdense;
160abc3b08eSStefano Zampini 
161abc3b08eSStefano Zampini   PetscFunctionBegin;
1629566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C, P->cmap->n, P->cmap->n, P->cmap->N, P->cmap->N));
1639566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, ""));
1647a3c3d58SStefano Zampini   if (!cisdense) {
1657a3c3d58SStefano Zampini     PetscBool flg;
1667a3c3d58SStefano Zampini 
1679566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)P, ((PetscObject)A)->type_name, &flg));
1689566063dSJacob Faibussowitsch     PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE));
1697a3c3d58SStefano Zampini   }
1709566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
1714222ddf1SHong Zhang   c = (Mat_SeqDense *)C->data;
1729566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &c->ptapwork));
1739566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(c->ptapwork, A->rmap->n, P->cmap->n, A->rmap->N, P->cmap->N));
1749566063dSJacob Faibussowitsch   PetscCall(MatSetType(c->ptapwork, ((PetscObject)C)->type_name));
1759566063dSJacob Faibussowitsch   PetscCall(MatSetUp(c->ptapwork));
176abc3b08eSStefano Zampini   PetscFunctionReturn(0);
177abc3b08eSStefano Zampini }
178abc3b08eSStefano Zampini 
179*d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat A, MatType newtype, MatReuse reuse, Mat *newmat)
180*d71ae5a4SJacob Faibussowitsch {
181a13144ffSStefano Zampini   Mat              B = NULL;
182b49cda9fSStefano Zampini   Mat_SeqAIJ      *a = (Mat_SeqAIJ *)A->data;
183b49cda9fSStefano Zampini   Mat_SeqDense    *b;
184b49cda9fSStefano Zampini   PetscInt        *ai = a->i, *aj = a->j, m = A->rmap->N, n = A->cmap->N, i;
1852e5835c6SStefano Zampini   const MatScalar *av;
186a13144ffSStefano Zampini   PetscBool        isseqdense;
187b49cda9fSStefano Zampini 
188b49cda9fSStefano Zampini   PetscFunctionBegin;
189a13144ffSStefano Zampini   if (reuse == MAT_REUSE_MATRIX) {
1909566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)*newmat, MATSEQDENSE, &isseqdense));
19128b400f6SJacob Faibussowitsch     PetscCheck(isseqdense, PetscObjectComm((PetscObject)*newmat), PETSC_ERR_USER, "Cannot reuse matrix of type %s", ((PetscObject)(*newmat))->type_name);
192a13144ffSStefano Zampini   }
193a13144ffSStefano Zampini   if (reuse != MAT_REUSE_MATRIX) {
1949566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B));
1959566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(B, m, n, m, n));
1969566063dSJacob Faibussowitsch     PetscCall(MatSetType(B, MATSEQDENSE));
1979566063dSJacob Faibussowitsch     PetscCall(MatSeqDenseSetPreallocation(B, NULL));
198b49cda9fSStefano Zampini     b = (Mat_SeqDense *)(B->data);
199a13144ffSStefano Zampini   } else {
200a13144ffSStefano Zampini     b = (Mat_SeqDense *)((*newmat)->data);
2019566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(b->v, m * n));
202a13144ffSStefano Zampini   }
2039566063dSJacob Faibussowitsch   PetscCall(MatSeqAIJGetArrayRead(A, &av));
204b49cda9fSStefano Zampini   for (i = 0; i < m; i++) {
205b49cda9fSStefano Zampini     PetscInt j;
206b49cda9fSStefano Zampini     for (j = 0; j < ai[1] - ai[0]; j++) {
207b49cda9fSStefano Zampini       b->v[*aj * m + i] = *av;
208b49cda9fSStefano Zampini       aj++;
209b49cda9fSStefano Zampini       av++;
210b49cda9fSStefano Zampini     }
211b49cda9fSStefano Zampini     ai++;
212b49cda9fSStefano Zampini   }
2139566063dSJacob Faibussowitsch   PetscCall(MatSeqAIJRestoreArrayRead(A, &av));
214b49cda9fSStefano Zampini 
215511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
2169566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY));
2179566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY));
2189566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A, &B));
219b49cda9fSStefano Zampini   } else {
220a13144ffSStefano Zampini     if (B) *newmat = B;
2219566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(*newmat, MAT_FINAL_ASSEMBLY));
2229566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(*newmat, MAT_FINAL_ASSEMBLY));
223b49cda9fSStefano Zampini   }
224b49cda9fSStefano Zampini   PetscFunctionReturn(0);
225b49cda9fSStefano Zampini }
226b49cda9fSStefano Zampini 
227*d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqDense_SeqAIJ(Mat A, MatType newtype, MatReuse reuse, Mat *newmat)
228*d71ae5a4SJacob Faibussowitsch {
2296d4ec7b0SPierre Jolivet   Mat           B = NULL;
2306a63e612SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
2319399e1b8SMatthew G. Knepley   PetscInt      i, j;
2329399e1b8SMatthew G. Knepley   PetscInt     *rows, *nnz;
2339399e1b8SMatthew G. Knepley   MatScalar    *aa = a->v, *vals;
2346a63e612SBarry Smith 
2356a63e612SBarry Smith   PetscFunctionBegin;
2369566063dSJacob Faibussowitsch   PetscCall(PetscCalloc3(A->rmap->n, &rows, A->rmap->n, &nnz, A->rmap->n, &vals));
2376d4ec7b0SPierre Jolivet   if (reuse != MAT_REUSE_MATRIX) {
2389566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B));
2399566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(B, A->rmap->n, A->cmap->n, A->rmap->N, A->cmap->N));
2409566063dSJacob Faibussowitsch     PetscCall(MatSetType(B, MATSEQAIJ));
2419399e1b8SMatthew G. Knepley     for (j = 0; j < A->cmap->n; j++) {
2429371c9d4SSatish Balay       for (i = 0; i < A->rmap->n; i++)
2439371c9d4SSatish Balay         if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) ++nnz[i];
2446a63e612SBarry Smith       aa += a->lda;
2456a63e612SBarry Smith     }
2469566063dSJacob Faibussowitsch     PetscCall(MatSeqAIJSetPreallocation(B, PETSC_DETERMINE, nnz));
2476d4ec7b0SPierre Jolivet   } else B = *newmat;
2489399e1b8SMatthew G. Knepley   aa = a->v;
2499399e1b8SMatthew G. Knepley   for (j = 0; j < A->cmap->n; j++) {
2509399e1b8SMatthew G. Knepley     PetscInt numRows = 0;
2519371c9d4SSatish Balay     for (i = 0; i < A->rmap->n; i++)
2529371c9d4SSatish Balay       if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) {
2539371c9d4SSatish Balay         rows[numRows]   = i;
2549371c9d4SSatish Balay         vals[numRows++] = aa[i];
2559371c9d4SSatish Balay       }
2569566063dSJacob Faibussowitsch     PetscCall(MatSetValues(B, numRows, rows, 1, &j, vals, INSERT_VALUES));
2579399e1b8SMatthew G. Knepley     aa += a->lda;
2589399e1b8SMatthew G. Knepley   }
2599566063dSJacob Faibussowitsch   PetscCall(PetscFree3(rows, nnz, vals));
2609566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY));
2619566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY));
2626a63e612SBarry Smith 
263511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
2649566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A, &B));
2656d4ec7b0SPierre Jolivet   } else if (reuse != MAT_REUSE_MATRIX) *newmat = B;
2666a63e612SBarry Smith   PetscFunctionReturn(0);
2676a63e612SBarry Smith }
2686a63e612SBarry Smith 
269*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatAXPY_SeqDense(Mat Y, PetscScalar alpha, Mat X, MatStructure str)
270*d71ae5a4SJacob Faibussowitsch {
2711987afe7SBarry Smith   Mat_SeqDense      *x = (Mat_SeqDense *)X->data, *y = (Mat_SeqDense *)Y->data;
272ca15aa20SStefano Zampini   const PetscScalar *xv;
273ca15aa20SStefano Zampini   PetscScalar       *yv;
27423fff9afSBarry Smith   PetscBLASInt       N, m, ldax = 0, lday = 0, one = 1;
2753a40ed3dSBarry Smith 
2763a40ed3dSBarry Smith   PetscFunctionBegin;
2779566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(X, &xv));
2789566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(Y, &yv));
2799566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(X->rmap->n * X->cmap->n, &N));
2809566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(X->rmap->n, &m));
2819566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(x->lda, &ldax));
2829566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(y->lda, &lday));
283a5ce6ee0Svictorle   if (ldax > m || lday > m) {
284ca15aa20SStefano Zampini     PetscInt j;
285ca15aa20SStefano Zampini 
28648a46eb9SPierre Jolivet     for (j = 0; j < X->cmap->n; j++) PetscCallBLAS("BLASaxpy", BLASaxpy_(&m, &alpha, xv + j * ldax, &one, yv + j * lday, &one));
287a5ce6ee0Svictorle   } else {
288792fecdfSBarry Smith     PetscCallBLAS("BLASaxpy", BLASaxpy_(&N, &alpha, xv, &one, yv, &one));
289a5ce6ee0Svictorle   }
2909566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(X, &xv));
2919566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(Y, &yv));
2929566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(PetscMax(2.0 * N - 1, 0)));
2933a40ed3dSBarry Smith   PetscFunctionReturn(0);
2941987afe7SBarry Smith }
2951987afe7SBarry Smith 
296*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetInfo_SeqDense(Mat A, MatInfoType flag, MatInfo *info)
297*d71ae5a4SJacob Faibussowitsch {
298ca15aa20SStefano Zampini   PetscLogDouble N = A->rmap->n * A->cmap->n;
2993a40ed3dSBarry Smith 
3003a40ed3dSBarry Smith   PetscFunctionBegin;
3014e220ebcSLois Curfman McInnes   info->block_size        = 1.0;
302ca15aa20SStefano Zampini   info->nz_allocated      = N;
303ca15aa20SStefano Zampini   info->nz_used           = N;
304ca15aa20SStefano Zampini   info->nz_unneeded       = 0;
305ca15aa20SStefano Zampini   info->assemblies        = A->num_ass;
3064e220ebcSLois Curfman McInnes   info->mallocs           = 0;
3074dfa11a4SJacob Faibussowitsch   info->memory            = 0; /* REVIEW ME */
3084e220ebcSLois Curfman McInnes   info->fill_ratio_given  = 0;
3094e220ebcSLois Curfman McInnes   info->fill_ratio_needed = 0;
3104e220ebcSLois Curfman McInnes   info->factor_mallocs    = 0;
3113a40ed3dSBarry Smith   PetscFunctionReturn(0);
312289bc588SBarry Smith }
313289bc588SBarry Smith 
314*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatScale_SeqDense(Mat A, PetscScalar alpha)
315*d71ae5a4SJacob Faibussowitsch {
316273d9f13SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
317ca15aa20SStefano Zampini   PetscScalar  *v;
31823fff9afSBarry Smith   PetscBLASInt  one = 1, j, nz, lda = 0;
31980cd9d93SLois Curfman McInnes 
3203a40ed3dSBarry Smith   PetscFunctionBegin;
3219566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
3229566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(a->lda, &lda));
323d0f46423SBarry Smith   if (lda > A->rmap->n) {
3249566063dSJacob Faibussowitsch     PetscCall(PetscBLASIntCast(A->rmap->n, &nz));
32548a46eb9SPierre Jolivet     for (j = 0; j < A->cmap->n; j++) PetscCallBLAS("BLASscal", BLASscal_(&nz, &alpha, v + j * lda, &one));
326a5ce6ee0Svictorle   } else {
3279566063dSJacob Faibussowitsch     PetscCall(PetscBLASIntCast(A->rmap->n * A->cmap->n, &nz));
328792fecdfSBarry Smith     PetscCallBLAS("BLASscal", BLASscal_(&nz, &alpha, v, &one));
329a5ce6ee0Svictorle   }
33004cbc005SJose E. Roman   PetscCall(PetscLogFlops(A->rmap->n * A->cmap->n));
3319566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
3323a40ed3dSBarry Smith   PetscFunctionReturn(0);
33380cd9d93SLois Curfman McInnes }
33480cd9d93SLois Curfman McInnes 
335*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatShift_SeqDense(Mat A, PetscScalar alpha)
336*d71ae5a4SJacob Faibussowitsch {
3372f605a99SJose E. Roman   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
3382f605a99SJose E. Roman   PetscScalar  *v;
3392f605a99SJose E. Roman   PetscInt      j, k;
3402f605a99SJose E. Roman 
3412f605a99SJose E. Roman   PetscFunctionBegin;
3422f605a99SJose E. Roman   PetscCall(MatDenseGetArray(A, &v));
3432f605a99SJose E. Roman   k = PetscMin(A->rmap->n, A->cmap->n);
3442f605a99SJose E. Roman   for (j = 0; j < k; j++) v[j + j * a->lda] += alpha;
3452f605a99SJose E. Roman   PetscCall(PetscLogFlops(k));
3462f605a99SJose E. Roman   PetscCall(MatDenseRestoreArray(A, &v));
3472f605a99SJose E. Roman   PetscFunctionReturn(0);
3482f605a99SJose E. Roman }
3492f605a99SJose E. Roman 
350*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatIsHermitian_SeqDense(Mat A, PetscReal rtol, PetscBool *fl)
351*d71ae5a4SJacob Faibussowitsch {
3521cbb95d3SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
353ca15aa20SStefano Zampini   PetscInt           i, j, m = A->rmap->n, N = a->lda;
354ca15aa20SStefano Zampini   const PetscScalar *v;
3551cbb95d3SBarry Smith 
3561cbb95d3SBarry Smith   PetscFunctionBegin;
3571cbb95d3SBarry Smith   *fl = PETSC_FALSE;
358d0f46423SBarry Smith   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
3599566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &v));
3601cbb95d3SBarry Smith   for (i = 0; i < m; i++) {
361ca15aa20SStefano Zampini     for (j = i; j < m; j++) {
362ad540459SPierre Jolivet       if (PetscAbsScalar(v[i + j * N] - PetscConj(v[j + i * N])) > rtol) goto restore;
3631cbb95d3SBarry Smith     }
364637a0070SStefano Zampini   }
3651cbb95d3SBarry Smith   *fl = PETSC_TRUE;
366637a0070SStefano Zampini restore:
3679566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &v));
368637a0070SStefano Zampini   PetscFunctionReturn(0);
369637a0070SStefano Zampini }
370637a0070SStefano Zampini 
371*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatIsSymmetric_SeqDense(Mat A, PetscReal rtol, PetscBool *fl)
372*d71ae5a4SJacob Faibussowitsch {
373637a0070SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
374637a0070SStefano Zampini   PetscInt           i, j, m = A->rmap->n, N = a->lda;
375637a0070SStefano Zampini   const PetscScalar *v;
376637a0070SStefano Zampini 
377637a0070SStefano Zampini   PetscFunctionBegin;
378637a0070SStefano Zampini   *fl = PETSC_FALSE;
379637a0070SStefano Zampini   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
3809566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &v));
381637a0070SStefano Zampini   for (i = 0; i < m; i++) {
382637a0070SStefano Zampini     for (j = i; j < m; j++) {
383ad540459SPierre Jolivet       if (PetscAbsScalar(v[i + j * N] - v[j + i * N]) > rtol) goto restore;
384637a0070SStefano Zampini     }
385637a0070SStefano Zampini   }
386637a0070SStefano Zampini   *fl = PETSC_TRUE;
387637a0070SStefano Zampini restore:
3889566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &v));
3891cbb95d3SBarry Smith   PetscFunctionReturn(0);
3901cbb95d3SBarry Smith }
3911cbb95d3SBarry Smith 
392*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi, Mat A, MatDuplicateOption cpvalues)
393*d71ae5a4SJacob Faibussowitsch {
394ca15aa20SStefano Zampini   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
39523fc5dcaSStefano Zampini   PetscInt      lda = (PetscInt)mat->lda, j, m, nlda = lda;
39675f6d85dSStefano Zampini   PetscBool     isdensecpu;
397b24902e0SBarry Smith 
398b24902e0SBarry Smith   PetscFunctionBegin;
3999566063dSJacob Faibussowitsch   PetscCall(PetscLayoutReference(A->rmap, &newi->rmap));
4009566063dSJacob Faibussowitsch   PetscCall(PetscLayoutReference(A->cmap, &newi->cmap));
40123fc5dcaSStefano Zampini   if (cpvalues == MAT_SHARE_NONZERO_PATTERN) { /* propagate LDA */
4029566063dSJacob Faibussowitsch     PetscCall(MatDenseSetLDA(newi, lda));
40323fc5dcaSStefano Zampini   }
4049566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)newi, MATSEQDENSE, &isdensecpu));
4059566063dSJacob Faibussowitsch   if (isdensecpu) PetscCall(MatSeqDenseSetPreallocation(newi, NULL));
406b24902e0SBarry Smith   if (cpvalues == MAT_COPY_VALUES) {
407ca15aa20SStefano Zampini     const PetscScalar *av;
408ca15aa20SStefano Zampini     PetscScalar       *v;
409ca15aa20SStefano Zampini 
4109566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A, &av));
4119566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayWrite(newi, &v));
4129566063dSJacob Faibussowitsch     PetscCall(MatDenseGetLDA(newi, &nlda));
413d0f46423SBarry Smith     m = A->rmap->n;
41423fc5dcaSStefano Zampini     if (lda > m || nlda > m) {
41548a46eb9SPierre Jolivet       for (j = 0; j < A->cmap->n; j++) PetscCall(PetscArraycpy(v + j * nlda, av + j * lda, m));
416b24902e0SBarry Smith     } else {
4179566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(v, av, A->rmap->n * A->cmap->n));
418b24902e0SBarry Smith     }
4199566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayWrite(newi, &v));
4209566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A, &av));
421b24902e0SBarry Smith   }
422b24902e0SBarry Smith   PetscFunctionReturn(0);
423b24902e0SBarry Smith }
424b24902e0SBarry Smith 
425*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDuplicate_SeqDense(Mat A, MatDuplicateOption cpvalues, Mat *newmat)
426*d71ae5a4SJacob Faibussowitsch {
4273a40ed3dSBarry Smith   PetscFunctionBegin;
4289566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), newmat));
4299566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*newmat, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n));
4309566063dSJacob Faibussowitsch   PetscCall(MatSetType(*newmat, ((PetscObject)A)->type_name));
4319566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(*newmat, A, cpvalues));
432b24902e0SBarry Smith   PetscFunctionReturn(0);
433b24902e0SBarry Smith }
434b24902e0SBarry Smith 
435*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_LU(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T)
436*d71ae5a4SJacob Faibussowitsch {
437c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
4384396437dSToby Isaac   PetscBLASInt  info;
43967e560aaSBarry Smith 
4403a40ed3dSBarry Smith   PetscFunctionBegin;
4419566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
442792fecdfSBarry Smith   PetscCallBLAS("LAPACKgetrs", LAPACKgetrs_(T ? "T" : "N", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info));
4439566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
44405fcb23eSStefano Zampini   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "GETRS - Bad solve %d", (int)info);
4459566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m)));
4464396437dSToby Isaac   PetscFunctionReturn(0);
4474396437dSToby Isaac }
4484396437dSToby Isaac 
4494396437dSToby Isaac static PetscErrorCode MatConjugate_SeqDense(Mat);
4504396437dSToby Isaac 
451*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_Cholesky(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T)
452*d71ae5a4SJacob Faibussowitsch {
4534396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
4544396437dSToby Isaac   PetscBLASInt  info;
4554396437dSToby Isaac 
4564396437dSToby Isaac   PetscFunctionBegin;
457b94d7dedSBarry Smith   if (A->spd == PETSC_BOOL3_TRUE) {
4589566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A));
4599566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
460792fecdfSBarry Smith     PetscCallBLAS("LAPACKpotrs", LAPACKpotrs_("L", &m, &nrhs, mat->v, &mat->lda, x, &m, &info));
4619566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
46205fcb23eSStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "POTRS Bad solve %d", (int)info);
4639566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A));
464a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
465b94d7dedSBarry Smith   } else if (A->hermitian == PETSC_BOOL3_TRUE) {
4669566063dSJacob Faibussowitsch     if (T) PetscCall(MatConjugate_SeqDense(A));
4679566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
468792fecdfSBarry Smith     PetscCallBLAS("LAPACKhetrs", LAPACKhetrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info));
4699566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
47005fcb23eSStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "HETRS Bad solve %d", (int)info);
4719566063dSJacob Faibussowitsch     if (T) PetscCall(MatConjugate_SeqDense(A));
472a49dc2a2SStefano Zampini #endif
473a49dc2a2SStefano Zampini   } else { /* symmetric case */
4749566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
475792fecdfSBarry Smith     PetscCallBLAS("LAPACKsytrs", LAPACKsytrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info));
4769566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
47705fcb23eSStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "SYTRS Bad solve %d", (int)info);
478a49dc2a2SStefano Zampini   }
4799566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m)));
4804396437dSToby Isaac   PetscFunctionReturn(0);
4814396437dSToby Isaac }
48285e2c93fSHong Zhang 
483*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k)
484*d71ae5a4SJacob Faibussowitsch {
4854396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
4864396437dSToby Isaac   PetscBLASInt  info;
4874396437dSToby Isaac   char          trans;
4884396437dSToby Isaac 
4894396437dSToby Isaac   PetscFunctionBegin;
4904905a7bcSToby Isaac   if (PetscDefined(USE_COMPLEX)) {
4914905a7bcSToby Isaac     trans = 'C';
4924905a7bcSToby Isaac   } else {
4934905a7bcSToby Isaac     trans = 'T';
4944905a7bcSToby Isaac   }
4959566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
49605fcb23eSStefano Zampini   { /* lwork depends on the number of right-hand sides */
49705fcb23eSStefano Zampini     PetscBLASInt nlfwork, lfwork = -1;
49805fcb23eSStefano Zampini     PetscScalar  fwork;
49905fcb23eSStefano Zampini 
500792fecdfSBarry Smith     PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info));
50105fcb23eSStefano Zampini     nlfwork = (PetscBLASInt)PetscRealPart(fwork);
50205fcb23eSStefano Zampini     if (nlfwork > mat->lfwork) {
50305fcb23eSStefano Zampini       mat->lfwork = nlfwork;
50405fcb23eSStefano Zampini       PetscCall(PetscFree(mat->fwork));
50505fcb23eSStefano Zampini       PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
50605fcb23eSStefano Zampini     }
50705fcb23eSStefano Zampini   }
508792fecdfSBarry Smith   PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info));
5099566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
51005fcb23eSStefano Zampini   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %d", (int)info);
5119566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
512792fecdfSBarry Smith   PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "N", "N", &mat->rank, &nrhs, mat->v, &mat->lda, x, &ldx, &info));
5139566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
51405fcb23eSStefano Zampini   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %d", (int)info);
5154905a7bcSToby Isaac   for (PetscInt j = 0; j < nrhs; j++) {
516ad540459SPierre Jolivet     for (PetscInt i = mat->rank; i < k; i++) x[j * ldx + i] = 0.;
5174905a7bcSToby Isaac   }
5189566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank))));
5194905a7bcSToby Isaac   PetscFunctionReturn(0);
5204905a7bcSToby Isaac }
5214905a7bcSToby Isaac 
522*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k)
523*d71ae5a4SJacob Faibussowitsch {
5244396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
5254396437dSToby Isaac   PetscBLASInt  info;
5264396437dSToby Isaac 
5274396437dSToby Isaac   PetscFunctionBegin;
5284396437dSToby Isaac   if (A->rmap->n == A->cmap->n && mat->rank == A->rmap->n) {
5299566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
530792fecdfSBarry Smith     PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "T", "N", &m, &nrhs, mat->v, &mat->lda, x, &ldx, &info));
5319566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
53205fcb23eSStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %d", (int)info);
5339566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A));
53405fcb23eSStefano Zampini     { /* lwork depends on the number of right-hand sides */
53505fcb23eSStefano Zampini       PetscBLASInt nlfwork, lfwork = -1;
53605fcb23eSStefano Zampini       PetscScalar  fwork;
53705fcb23eSStefano Zampini 
538792fecdfSBarry Smith       PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info));
53905fcb23eSStefano Zampini       nlfwork = (PetscBLASInt)PetscRealPart(fwork);
54005fcb23eSStefano Zampini       if (nlfwork > mat->lfwork) {
54105fcb23eSStefano Zampini         mat->lfwork = nlfwork;
54205fcb23eSStefano Zampini         PetscCall(PetscFree(mat->fwork));
54305fcb23eSStefano Zampini         PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
54405fcb23eSStefano Zampini       }
54505fcb23eSStefano Zampini     }
5469566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
547792fecdfSBarry Smith     PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info));
5489566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
54905fcb23eSStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %d", (int)info);
5509566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A));
5514396437dSToby Isaac   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "QR factored matrix cannot be used for transpose solve");
5529566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank))));
5534396437dSToby Isaac   PetscFunctionReturn(0);
5544396437dSToby Isaac }
5554396437dSToby Isaac 
556*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_SetUp(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k)
557*d71ae5a4SJacob Faibussowitsch {
5584396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
5594905a7bcSToby Isaac   PetscScalar  *y;
5604905a7bcSToby Isaac   PetscBLASInt  m = 0, k = 0;
5614905a7bcSToby Isaac 
5624905a7bcSToby Isaac   PetscFunctionBegin;
5639566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
5649566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &k));
5654905a7bcSToby Isaac   if (k < m) {
5669566063dSJacob Faibussowitsch     PetscCall(VecCopy(xx, mat->qrrhs));
5679566063dSJacob Faibussowitsch     PetscCall(VecGetArray(mat->qrrhs, &y));
5684905a7bcSToby Isaac   } else {
5699566063dSJacob Faibussowitsch     PetscCall(VecCopy(xx, yy));
5709566063dSJacob Faibussowitsch     PetscCall(VecGetArray(yy, &y));
5714905a7bcSToby Isaac   }
5724396437dSToby Isaac   *_y = y;
5734396437dSToby Isaac   *_k = k;
5744396437dSToby Isaac   *_m = m;
5754396437dSToby Isaac   PetscFunctionReturn(0);
5764396437dSToby Isaac }
5774396437dSToby Isaac 
578*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_TearDown(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k)
579*d71ae5a4SJacob Faibussowitsch {
5804396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
58142e9364cSSatish Balay   PetscScalar  *y   = NULL;
5824396437dSToby Isaac   PetscBLASInt  m, k;
5834396437dSToby Isaac 
5844396437dSToby Isaac   PetscFunctionBegin;
5854396437dSToby Isaac   y   = *_y;
5864396437dSToby Isaac   *_y = NULL;
5874396437dSToby Isaac   k   = *_k;
5884396437dSToby Isaac   m   = *_m;
5894905a7bcSToby Isaac   if (k < m) {
5904905a7bcSToby Isaac     PetscScalar *yv;
5919566063dSJacob Faibussowitsch     PetscCall(VecGetArray(yy, &yv));
5929566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(yv, y, k));
5939566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(yy, &yv));
5949566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(mat->qrrhs, &y));
5954905a7bcSToby Isaac   } else {
5969566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(yy, &y));
5974905a7bcSToby Isaac   }
5984905a7bcSToby Isaac   PetscFunctionReturn(0);
5994905a7bcSToby Isaac }
6004905a7bcSToby Isaac 
601*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_LU(Mat A, Vec xx, Vec yy)
602*d71ae5a4SJacob Faibussowitsch {
60342e9364cSSatish Balay   PetscScalar *y = NULL;
60442e9364cSSatish Balay   PetscBLASInt m = 0, k = 0;
6054396437dSToby Isaac 
6064396437dSToby Isaac   PetscFunctionBegin;
6079566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6089566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_FALSE));
6099566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6104396437dSToby Isaac   PetscFunctionReturn(0);
6114396437dSToby Isaac }
6124396437dSToby Isaac 
613*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_LU(Mat A, Vec xx, Vec yy)
614*d71ae5a4SJacob Faibussowitsch {
61542e9364cSSatish Balay   PetscScalar *y = NULL;
61642e9364cSSatish Balay   PetscBLASInt m = 0, k = 0;
6174396437dSToby Isaac 
6184396437dSToby Isaac   PetscFunctionBegin;
6199566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6209566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_TRUE));
6219566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6224396437dSToby Isaac   PetscFunctionReturn(0);
6234396437dSToby Isaac }
6244396437dSToby Isaac 
625*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Cholesky(Mat A, Vec xx, Vec yy)
626*d71ae5a4SJacob Faibussowitsch {
627e54beecaSStefano Zampini   PetscScalar *y = NULL;
628e54beecaSStefano Zampini   PetscBLASInt m = 0, k = 0;
6294396437dSToby Isaac 
6304396437dSToby Isaac   PetscFunctionBegin;
6319566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6329566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_FALSE));
6339566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6344396437dSToby Isaac   PetscFunctionReturn(0);
6354396437dSToby Isaac }
6364396437dSToby Isaac 
637*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_Cholesky(Mat A, Vec xx, Vec yy)
638*d71ae5a4SJacob Faibussowitsch {
639e54beecaSStefano Zampini   PetscScalar *y = NULL;
640e54beecaSStefano Zampini   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(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_TRUE));
6459566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6464396437dSToby Isaac   PetscFunctionReturn(0);
6474396437dSToby Isaac }
6484396437dSToby Isaac 
649*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_QR(Mat A, Vec xx, Vec yy)
650*d71ae5a4SJacob Faibussowitsch {
651e54beecaSStefano Zampini   PetscScalar *y = NULL;
652e54beecaSStefano Zampini   PetscBLASInt m = 0, k = 0;
6534396437dSToby Isaac 
6544396437dSToby Isaac   PetscFunctionBegin;
6559566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6569566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k));
6579566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6584396437dSToby Isaac   PetscFunctionReturn(0);
6594396437dSToby Isaac }
6604396437dSToby Isaac 
661*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_QR(Mat A, Vec xx, Vec yy)
662*d71ae5a4SJacob Faibussowitsch {
66342e9364cSSatish Balay   PetscScalar *y = NULL;
66442e9364cSSatish Balay   PetscBLASInt m = 0, k = 0;
6654396437dSToby Isaac 
6664396437dSToby Isaac   PetscFunctionBegin;
6679566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6689566063dSJacob Faibussowitsch   PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k));
6699566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6704396437dSToby Isaac   PetscFunctionReturn(0);
6714396437dSToby Isaac }
6724396437dSToby Isaac 
673*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_SetUp(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k)
674*d71ae5a4SJacob Faibussowitsch {
6754905a7bcSToby Isaac   const PetscScalar *b;
6764396437dSToby Isaac   PetscScalar       *y;
677bf5a80bcSToby Isaac   PetscInt           n, _ldb, _ldx;
678bf5a80bcSToby Isaac   PetscBLASInt       nrhs = 0, m = 0, k = 0, ldb = 0, ldx = 0, ldy = 0;
6794905a7bcSToby Isaac 
6804905a7bcSToby Isaac   PetscFunctionBegin;
6819371c9d4SSatish Balay   *_ldy  = 0;
6829371c9d4SSatish Balay   *_m    = 0;
6839371c9d4SSatish Balay   *_nrhs = 0;
6849371c9d4SSatish Balay   *_k    = 0;
6859371c9d4SSatish Balay   *_y    = NULL;
6869566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
6879566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &k));
6889566063dSJacob Faibussowitsch   PetscCall(MatGetSize(B, NULL, &n));
6899566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(n, &nrhs));
6909566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(B, &_ldb));
6919566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldb, &ldb));
6929566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(X, &_ldx));
6939566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldx, &ldx));
694bf5a80bcSToby Isaac   if (ldx < m) {
6959566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(B, &b));
6969566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nrhs * m, &y));
697bf5a80bcSToby Isaac     if (ldb == m) {
6989566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(y, b, ldb * nrhs));
6994905a7bcSToby Isaac     } else {
70048a46eb9SPierre Jolivet       for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * m], &b[j * ldb], m));
7014905a7bcSToby Isaac     }
702bf5a80bcSToby Isaac     ldy = m;
7039566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(B, &b));
7044905a7bcSToby Isaac   } else {
705bf5a80bcSToby Isaac     if (ldb == ldx) {
7069566063dSJacob Faibussowitsch       PetscCall(MatCopy(B, X, SAME_NONZERO_PATTERN));
7079566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(X, &y));
7084905a7bcSToby Isaac     } else {
7099566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(X, &y));
7109566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArrayRead(B, &b));
71148a46eb9SPierre Jolivet       for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * ldx], &b[j * ldb], m));
7129566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArrayRead(B, &b));
7134905a7bcSToby Isaac     }
714bf5a80bcSToby Isaac     ldy = ldx;
7154905a7bcSToby Isaac   }
7164396437dSToby Isaac   *_y    = y;
717bf5a80bcSToby Isaac   *_ldy  = ldy;
7184396437dSToby Isaac   *_k    = k;
7194396437dSToby Isaac   *_m    = m;
7204396437dSToby Isaac   *_nrhs = nrhs;
7214396437dSToby Isaac   PetscFunctionReturn(0);
7224396437dSToby Isaac }
7234396437dSToby Isaac 
724*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_TearDown(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k)
725*d71ae5a4SJacob Faibussowitsch {
7264396437dSToby Isaac   PetscScalar *y;
727bf5a80bcSToby Isaac   PetscInt     _ldx;
728bf5a80bcSToby Isaac   PetscBLASInt k, ldy, nrhs, ldx = 0;
7294396437dSToby Isaac 
7304396437dSToby Isaac   PetscFunctionBegin;
7314396437dSToby Isaac   y    = *_y;
7324396437dSToby Isaac   *_y  = NULL;
7334396437dSToby Isaac   k    = *_k;
734bf5a80bcSToby Isaac   ldy  = *_ldy;
7354396437dSToby Isaac   nrhs = *_nrhs;
7369566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(X, &_ldx));
7379566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldx, &ldx));
738bf5a80bcSToby Isaac   if (ldx != ldy) {
7394905a7bcSToby Isaac     PetscScalar *xv;
7409566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArray(X, &xv));
74148a46eb9SPierre Jolivet     for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&xv[j * ldx], &y[j * ldy], k));
7429566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(X, &xv));
7439566063dSJacob Faibussowitsch     PetscCall(PetscFree(y));
7444905a7bcSToby Isaac   } else {
7459566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(X, &y));
7464905a7bcSToby Isaac   }
74785e2c93fSHong Zhang   PetscFunctionReturn(0);
74885e2c93fSHong Zhang }
74985e2c93fSHong Zhang 
750*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_LU(Mat A, Mat B, Mat X)
751*d71ae5a4SJacob Faibussowitsch {
7524396437dSToby Isaac   PetscScalar *y;
753bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7544396437dSToby Isaac 
7554396437dSToby Isaac   PetscFunctionBegin;
7569566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7579566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_FALSE));
7589566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7594396437dSToby Isaac   PetscFunctionReturn(0);
7604396437dSToby Isaac }
7614396437dSToby Isaac 
762*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_LU(Mat A, Mat B, Mat X)
763*d71ae5a4SJacob Faibussowitsch {
7644396437dSToby Isaac   PetscScalar *y;
765bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7664396437dSToby Isaac 
7674396437dSToby Isaac   PetscFunctionBegin;
7689566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7699566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_TRUE));
7709566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7714396437dSToby Isaac   PetscFunctionReturn(0);
7724396437dSToby Isaac }
7734396437dSToby Isaac 
774*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_Cholesky(Mat A, Mat B, Mat X)
775*d71ae5a4SJacob Faibussowitsch {
7764396437dSToby Isaac   PetscScalar *y;
777bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7784396437dSToby Isaac 
7794396437dSToby Isaac   PetscFunctionBegin;
7809566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7819566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_FALSE));
7829566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7834396437dSToby Isaac   PetscFunctionReturn(0);
7844396437dSToby Isaac }
7854396437dSToby Isaac 
786*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_Cholesky(Mat A, Mat B, Mat X)
787*d71ae5a4SJacob Faibussowitsch {
7884396437dSToby Isaac   PetscScalar *y;
789bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7904396437dSToby Isaac 
7914396437dSToby Isaac   PetscFunctionBegin;
7929566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7939566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_TRUE));
7949566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7954396437dSToby Isaac   PetscFunctionReturn(0);
7964396437dSToby Isaac }
7974396437dSToby Isaac 
798*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_QR(Mat A, Mat B, Mat X)
799*d71ae5a4SJacob Faibussowitsch {
8004396437dSToby Isaac   PetscScalar *y;
801bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
8024396437dSToby Isaac 
8034396437dSToby Isaac   PetscFunctionBegin;
8049566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
8059566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k));
8069566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
8074396437dSToby Isaac   PetscFunctionReturn(0);
8084396437dSToby Isaac }
8094396437dSToby Isaac 
810*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_QR(Mat A, Mat B, Mat X)
811*d71ae5a4SJacob Faibussowitsch {
8124396437dSToby Isaac   PetscScalar *y;
813bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
8144396437dSToby Isaac 
8154396437dSToby Isaac   PetscFunctionBegin;
8169566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
8179566063dSJacob Faibussowitsch   PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k));
8189566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
8194396437dSToby Isaac   PetscFunctionReturn(0);
8204396437dSToby Isaac }
8214396437dSToby Isaac 
822db4efbfdSBarry Smith /* ---------------------------------------------------------------*/
823db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots,
824db4efbfdSBarry Smith    rather than put it in the Mat->row slot.*/
825*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLUFactor_SeqDense(Mat A, IS row, IS col, const MatFactorInfo *minfo)
826*d71ae5a4SJacob Faibussowitsch {
827db4efbfdSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
828db4efbfdSBarry Smith   PetscBLASInt  n, m, info;
829db4efbfdSBarry Smith 
830db4efbfdSBarry Smith   PetscFunctionBegin;
8319566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
8329566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
8334dfa11a4SJacob Faibussowitsch   if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); }
834db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
8359566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
836792fecdfSBarry Smith   PetscCallBLAS("LAPACKgetrf", LAPACKgetrf_(&m, &n, mat->v, &mat->lda, mat->pivots, &info));
8379566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
8388e57ea43SSatish Balay 
83905fcb23eSStefano Zampini   PetscCheck(info >= 0, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to LU factorization %d", (int)info);
84005fcb23eSStefano Zampini   PetscCheck(info <= 0, PETSC_COMM_SELF, PETSC_ERR_MAT_LU_ZRPVT, "Bad LU factorization %d", (int)info);
8418208b9aeSStefano Zampini 
8424396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_LU;
8434396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_LU;
8444396437dSToby Isaac   A->ops->solvetranspose    = MatSolveTranspose_SeqDense_LU;
8454396437dSToby Isaac   A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_LU;
846d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_LU;
847db4efbfdSBarry Smith 
8489566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
8499566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype));
850f6224b95SHong Zhang 
8519566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops((2.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3));
852db4efbfdSBarry Smith   PetscFunctionReturn(0);
853db4efbfdSBarry Smith }
854db4efbfdSBarry Smith 
855*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy)
856*d71ae5a4SJacob Faibussowitsch {
8574396437dSToby Isaac   MatFactorInfo info;
8584396437dSToby Isaac 
8594396437dSToby Isaac   PetscFunctionBegin;
8609566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES));
861dbbe0bcdSBarry Smith   PetscUseTypeMethod(fact, lufactor, NULL, NULL, &info);
8624396437dSToby Isaac   PetscFunctionReturn(0);
8634396437dSToby Isaac }
8644396437dSToby Isaac 
865*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, IS col, const MatFactorInfo *info)
866*d71ae5a4SJacob Faibussowitsch {
8674396437dSToby Isaac   PetscFunctionBegin;
8684396437dSToby Isaac   fact->preallocated         = PETSC_TRUE;
8694396437dSToby Isaac   fact->assembled            = PETSC_TRUE;
8704396437dSToby Isaac   fact->ops->lufactornumeric = MatLUFactorNumeric_SeqDense;
8714396437dSToby Isaac   PetscFunctionReturn(0);
8724396437dSToby Isaac }
8734396437dSToby Isaac 
874a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */
875*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCholeskyFactor_SeqDense(Mat A, IS perm, const MatFactorInfo *factinfo)
876*d71ae5a4SJacob Faibussowitsch {
877db4efbfdSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
878c5df96a5SBarry Smith   PetscBLASInt  info, n;
879db4efbfdSBarry Smith 
880db4efbfdSBarry Smith   PetscFunctionBegin;
8819566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
882db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
883b94d7dedSBarry Smith   if (A->spd == PETSC_BOOL3_TRUE) {
8849566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
885792fecdfSBarry Smith     PetscCallBLAS("LAPACKpotrf", LAPACKpotrf_("L", &n, mat->v, &mat->lda, &info));
8869566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
887a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
888b94d7dedSBarry Smith   } else if (A->hermitian == PETSC_BOOL3_TRUE) {
8894dfa11a4SJacob Faibussowitsch     if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); }
890a49dc2a2SStefano Zampini     if (!mat->fwork) {
891a49dc2a2SStefano Zampini       PetscScalar dummy;
892a49dc2a2SStefano Zampini 
893a49dc2a2SStefano Zampini       mat->lfwork = -1;
8949566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
895792fecdfSBarry Smith       PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info));
8969566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
897a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
8989566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
899a49dc2a2SStefano Zampini     }
9009566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
901792fecdfSBarry Smith     PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info));
9029566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
903a49dc2a2SStefano Zampini #endif
904a49dc2a2SStefano Zampini   } else { /* symmetric case */
9054dfa11a4SJacob Faibussowitsch     if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); }
906a49dc2a2SStefano Zampini     if (!mat->fwork) {
907a49dc2a2SStefano Zampini       PetscScalar dummy;
908a49dc2a2SStefano Zampini 
909a49dc2a2SStefano Zampini       mat->lfwork = -1;
9109566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
911792fecdfSBarry Smith       PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info));
9129566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
913a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
9149566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
915a49dc2a2SStefano Zampini     }
9169566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
917792fecdfSBarry Smith     PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info));
9189566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
919a49dc2a2SStefano Zampini   }
92028b400f6SJacob Faibussowitsch   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad factorization: zero pivot in row %" PetscInt_FMT, (PetscInt)info - 1);
9218208b9aeSStefano Zampini 
9224396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_Cholesky;
9234396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_Cholesky;
9244396437dSToby Isaac   A->ops->solvetranspose    = MatSolveTranspose_SeqDense_Cholesky;
9254396437dSToby Isaac   A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_Cholesky;
926d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_CHOLESKY;
9272205254eSKarl Rupp 
9289566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
9299566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype));
930f6224b95SHong Zhang 
9319566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0));
932db4efbfdSBarry Smith   PetscFunctionReturn(0);
933db4efbfdSBarry Smith }
934db4efbfdSBarry Smith 
935*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy)
936*d71ae5a4SJacob Faibussowitsch {
937db4efbfdSBarry Smith   MatFactorInfo info;
938db4efbfdSBarry Smith 
939db4efbfdSBarry Smith   PetscFunctionBegin;
940db4efbfdSBarry Smith   info.fill = 1.0;
9412205254eSKarl Rupp 
9429566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES));
943dbbe0bcdSBarry Smith   PetscUseTypeMethod(fact, choleskyfactor, NULL, &info);
944db4efbfdSBarry Smith   PetscFunctionReturn(0);
945db4efbfdSBarry Smith }
946db4efbfdSBarry Smith 
947*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info)
948*d71ae5a4SJacob Faibussowitsch {
949db4efbfdSBarry Smith   PetscFunctionBegin;
950c3ef05f6SHong Zhang   fact->assembled                  = PETSC_TRUE;
9511bbcc794SSatish Balay   fact->preallocated               = PETSC_TRUE;
952719d5645SBarry Smith   fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense;
953db4efbfdSBarry Smith   PetscFunctionReturn(0);
954db4efbfdSBarry Smith }
955db4efbfdSBarry Smith 
956*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatQRFactor_SeqDense(Mat A, IS col, const MatFactorInfo *minfo)
957*d71ae5a4SJacob Faibussowitsch {
9584905a7bcSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
9594905a7bcSToby Isaac   PetscBLASInt  n, m, info, min, max;
9604905a7bcSToby Isaac 
9614905a7bcSToby Isaac   PetscFunctionBegin;
9629566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
9639566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
9644396437dSToby Isaac   max = PetscMax(m, n);
9654396437dSToby Isaac   min = PetscMin(m, n);
9664dfa11a4SJacob Faibussowitsch   if (!mat->tau) { PetscCall(PetscMalloc1(min, &mat->tau)); }
9674dfa11a4SJacob Faibussowitsch   if (!mat->pivots) { PetscCall(PetscMalloc1(n, &mat->pivots)); }
96848a46eb9SPierre Jolivet   if (!mat->qrrhs) PetscCall(MatCreateVecs(A, NULL, &(mat->qrrhs)));
9694905a7bcSToby Isaac   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
9704905a7bcSToby Isaac   if (!mat->fwork) {
9714905a7bcSToby Isaac     PetscScalar dummy;
9724905a7bcSToby Isaac 
9734905a7bcSToby Isaac     mat->lfwork = -1;
9749566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
975792fecdfSBarry Smith     PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, &dummy, &mat->lfwork, &info));
9769566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
9774905a7bcSToby Isaac     mat->lfwork = (PetscInt)PetscRealPart(dummy);
9789566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
9794905a7bcSToby Isaac   }
9809566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
981792fecdfSBarry Smith   PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, mat->fwork, &mat->lfwork, &info));
9829566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
98305fcb23eSStefano Zampini   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to QR factorization %d", (int)info);
9844905a7bcSToby 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
9854905a7bcSToby Isaac   mat->rank = min;
9864905a7bcSToby Isaac 
9874396437dSToby Isaac   A->ops->solve    = MatSolve_SeqDense_QR;
9884396437dSToby Isaac   A->ops->matsolve = MatMatSolve_SeqDense_QR;
9894905a7bcSToby Isaac   A->factortype    = MAT_FACTOR_QR;
9904905a7bcSToby Isaac   if (m == n) {
9914396437dSToby Isaac     A->ops->solvetranspose    = MatSolveTranspose_SeqDense_QR;
9924396437dSToby Isaac     A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_QR;
9934905a7bcSToby Isaac   }
9944905a7bcSToby Isaac 
9959566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
9969566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype));
9974905a7bcSToby Isaac 
9989566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0 * min * min * (max - min / 3.0)));
9994905a7bcSToby Isaac   PetscFunctionReturn(0);
10004905a7bcSToby Isaac }
10014905a7bcSToby Isaac 
1002*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatQRFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy)
1003*d71ae5a4SJacob Faibussowitsch {
10044905a7bcSToby Isaac   MatFactorInfo info;
10054905a7bcSToby Isaac 
10064905a7bcSToby Isaac   PetscFunctionBegin;
10074905a7bcSToby Isaac   info.fill = 1.0;
10084905a7bcSToby Isaac 
10099566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES));
1010cac4c232SBarry Smith   PetscUseMethod(fact, "MatQRFactor_C", (Mat, IS, const MatFactorInfo *), (fact, NULL, &info));
10114905a7bcSToby Isaac   PetscFunctionReturn(0);
10124905a7bcSToby Isaac }
10134905a7bcSToby Isaac 
1014*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatQRFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info)
1015*d71ae5a4SJacob Faibussowitsch {
10164905a7bcSToby Isaac   PetscFunctionBegin;
10174905a7bcSToby Isaac   fact->assembled    = PETSC_TRUE;
10184905a7bcSToby Isaac   fact->preallocated = PETSC_TRUE;
10199566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)fact, "MatQRFactorNumeric_C", MatQRFactorNumeric_SeqDense));
10204905a7bcSToby Isaac   PetscFunctionReturn(0);
10214905a7bcSToby Isaac }
10224905a7bcSToby Isaac 
1023ca15aa20SStefano Zampini /* uses LAPACK */
1024*d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A, MatFactorType ftype, Mat *fact)
1025*d71ae5a4SJacob Faibussowitsch {
1026db4efbfdSBarry Smith   PetscFunctionBegin;
10279566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), fact));
10289566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*fact, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n));
10299566063dSJacob Faibussowitsch   PetscCall(MatSetType(*fact, MATDENSE));
103066e17bc3SBarry Smith   (*fact)->trivialsymbolic = PETSC_TRUE;
10312a350339SBarry Smith   if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU) {
1032db4efbfdSBarry Smith     (*fact)->ops->lufactorsymbolic  = MatLUFactorSymbolic_SeqDense;
10332a350339SBarry Smith     (*fact)->ops->ilufactorsymbolic = MatLUFactorSymbolic_SeqDense;
1034bf5a80bcSToby Isaac   } else if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) {
1035db4efbfdSBarry Smith     (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense;
1036bf5a80bcSToby Isaac   } else if (ftype == MAT_FACTOR_QR) {
10379566063dSJacob Faibussowitsch     PetscCall(PetscObjectComposeFunction((PetscObject)(*fact), "MatQRFactorSymbolic_C", MatQRFactorSymbolic_SeqDense));
1038db4efbfdSBarry Smith   }
1039d5f3da31SBarry Smith   (*fact)->factortype = ftype;
104000c67f3bSHong Zhang 
10419566063dSJacob Faibussowitsch   PetscCall(PetscFree((*fact)->solvertype));
10429566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC, &(*fact)->solvertype));
10439566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_LU]));
10449566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ILU]));
10459566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_CHOLESKY]));
10469566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ICC]));
1047db4efbfdSBarry Smith   PetscFunctionReturn(0);
1048db4efbfdSBarry Smith }
1049db4efbfdSBarry Smith 
1050289bc588SBarry Smith /* ------------------------------------------------------------------*/
1051*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSOR_SeqDense(Mat A, Vec bb, PetscReal omega, MatSORType flag, PetscReal shift, PetscInt its, PetscInt lits, Vec xx)
1052*d71ae5a4SJacob Faibussowitsch {
1053c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1054d9ca1df4SBarry Smith   PetscScalar       *x, *v = mat->v, zero = 0.0, xt;
1055d9ca1df4SBarry Smith   const PetscScalar *b;
1056d0f46423SBarry Smith   PetscInt           m = A->rmap->n, i;
105723fff9afSBarry Smith   PetscBLASInt       o = 1, bm = 0;
1058289bc588SBarry Smith 
10593a40ed3dSBarry Smith   PetscFunctionBegin;
1060ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
106108401ef6SPierre Jolivet   PetscCheck(A->offloadmask != PETSC_OFFLOAD_GPU, PETSC_COMM_SELF, PETSC_ERR_SUP, "Not implemented");
1062ca15aa20SStefano Zampini #endif
1063422a814eSBarry Smith   if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */
10649566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(m, &bm));
1065289bc588SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
10663bffc371SBarry Smith     /* this is a hack fix, should have another version without the second BLASdotu */
10679566063dSJacob Faibussowitsch     PetscCall(VecSet(xx, zero));
1068289bc588SBarry Smith   }
10699566063dSJacob Faibussowitsch   PetscCall(VecGetArray(xx, &x));
10709566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(bb, &b));
1071b965ef7fSBarry Smith   its = its * lits;
107208401ef6SPierre 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);
1073289bc588SBarry Smith   while (its--) {
1074fccaa45eSBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
1075289bc588SBarry Smith       for (i = 0; i < m; i++) {
1076792fecdfSBarry Smith         PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o));
107755a1b374SBarry Smith         x[i] = (1. - omega) * x[i] + omega * (xt + v[i + i * m] * x[i]) / (v[i + i * m] + shift);
1078289bc588SBarry Smith       }
1079289bc588SBarry Smith     }
1080fccaa45eSBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
1081289bc588SBarry Smith       for (i = m - 1; i >= 0; i--) {
1082792fecdfSBarry Smith         PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o));
108355a1b374SBarry Smith         x[i] = (1. - omega) * x[i] + omega * (xt + v[i + i * m] * x[i]) / (v[i + i * m] + shift);
1084289bc588SBarry Smith       }
1085289bc588SBarry Smith     }
1086289bc588SBarry Smith   }
10879566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(bb, &b));
10889566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(xx, &x));
10893a40ed3dSBarry Smith   PetscFunctionReturn(0);
1090289bc588SBarry Smith }
1091289bc588SBarry Smith 
1092289bc588SBarry Smith /* -----------------------------------------------------------------*/
1093*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultTranspose_SeqDense(Mat A, Vec xx, Vec yy)
1094*d71ae5a4SJacob Faibussowitsch {
1095c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1096d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v, *x;
1097d9ca1df4SBarry Smith   PetscScalar       *y;
10980805154bSBarry Smith   PetscBLASInt       m, n, _One = 1;
1099ea709b57SSatish Balay   PetscScalar        _DOne = 1.0, _DZero = 0.0;
11003a40ed3dSBarry Smith 
11013a40ed3dSBarry Smith   PetscFunctionBegin;
11029566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
11039566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
11049566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx, &x));
11059566063dSJacob Faibussowitsch   PetscCall(VecGetArrayWrite(yy, &y));
11065ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
11075ac36cfcSBarry Smith     PetscBLASInt i;
11085ac36cfcSBarry Smith     for (i = 0; i < n; i++) y[i] = 0.0;
11095ac36cfcSBarry Smith   } else {
1110792fecdfSBarry Smith     PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v, &mat->lda, x, &_One, &_DZero, y, &_One));
11119566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n - A->cmap->n));
11125ac36cfcSBarry Smith   }
11139566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx, &x));
11149566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayWrite(yy, &y));
11153a40ed3dSBarry Smith   PetscFunctionReturn(0);
1116289bc588SBarry Smith }
1117800995b7SMatthew Knepley 
1118*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMult_SeqDense(Mat A, Vec xx, Vec yy)
1119*d71ae5a4SJacob Faibussowitsch {
1120c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1121d9ca1df4SBarry Smith   PetscScalar       *y, _DOne = 1.0, _DZero = 0.0;
11220805154bSBarry Smith   PetscBLASInt       m, n, _One             = 1;
1123d9ca1df4SBarry Smith   const PetscScalar *v = mat->v, *x;
11243a40ed3dSBarry Smith 
11253a40ed3dSBarry Smith   PetscFunctionBegin;
11269566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
11279566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
11289566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx, &x));
11299566063dSJacob Faibussowitsch   PetscCall(VecGetArrayWrite(yy, &y));
11305ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
11315ac36cfcSBarry Smith     PetscBLASInt i;
11325ac36cfcSBarry Smith     for (i = 0; i < m; i++) y[i] = 0.0;
11335ac36cfcSBarry Smith   } else {
1134792fecdfSBarry Smith     PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DZero, y, &_One));
11359566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n - A->rmap->n));
11365ac36cfcSBarry Smith   }
11379566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx, &x));
11389566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayWrite(yy, &y));
11393a40ed3dSBarry Smith   PetscFunctionReturn(0);
1140289bc588SBarry Smith }
11416ee01492SSatish Balay 
1142*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy)
1143*d71ae5a4SJacob Faibussowitsch {
1144c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1145d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v, *x;
1146d9ca1df4SBarry Smith   PetscScalar       *y, _DOne = 1.0;
11470805154bSBarry Smith   PetscBLASInt       m, n, _One = 1;
11483a40ed3dSBarry Smith 
11493a40ed3dSBarry Smith   PetscFunctionBegin;
11509566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
11519566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
11529566063dSJacob Faibussowitsch   PetscCall(VecCopy(zz, yy));
1153d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
11549566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx, &x));
11559566063dSJacob Faibussowitsch   PetscCall(VecGetArray(yy, &y));
1156792fecdfSBarry Smith   PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DOne, y, &_One));
11579566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx, &x));
11589566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(yy, &y));
11599566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n));
11603a40ed3dSBarry Smith   PetscFunctionReturn(0);
1161289bc588SBarry Smith }
11626ee01492SSatish Balay 
1163*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy)
1164*d71ae5a4SJacob Faibussowitsch {
1165c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1166d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v, *x;
1167d9ca1df4SBarry Smith   PetscScalar       *y;
11680805154bSBarry Smith   PetscBLASInt       m, n, _One = 1;
116987828ca2SBarry Smith   PetscScalar        _DOne = 1.0;
11703a40ed3dSBarry Smith 
11713a40ed3dSBarry Smith   PetscFunctionBegin;
11729566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
11739566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
11749566063dSJacob Faibussowitsch   PetscCall(VecCopy(zz, yy));
1175d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
11769566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx, &x));
11779566063dSJacob Faibussowitsch   PetscCall(VecGetArray(yy, &y));
1178792fecdfSBarry Smith   PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DOne, y, &_One));
11799566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx, &x));
11809566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(yy, &y));
11819566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n));
11823a40ed3dSBarry Smith   PetscFunctionReturn(0);
1183289bc588SBarry Smith }
1184289bc588SBarry Smith 
1185289bc588SBarry Smith /* -----------------------------------------------------------------*/
1186*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals)
1187*d71ae5a4SJacob Faibussowitsch {
1188c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
118913f74950SBarry Smith   PetscInt      i;
119067e560aaSBarry Smith 
11913a40ed3dSBarry Smith   PetscFunctionBegin;
1192d0f46423SBarry Smith   *ncols = A->cmap->n;
1193289bc588SBarry Smith   if (cols) {
11949566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(A->cmap->n, cols));
1195d0f46423SBarry Smith     for (i = 0; i < A->cmap->n; i++) (*cols)[i] = i;
1196289bc588SBarry Smith   }
1197289bc588SBarry Smith   if (vals) {
1198ca15aa20SStefano Zampini     const PetscScalar *v;
1199ca15aa20SStefano Zampini 
12009566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A, &v));
12019566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(A->cmap->n, vals));
1202ca15aa20SStefano Zampini     v += row;
12039371c9d4SSatish Balay     for (i = 0; i < A->cmap->n; i++) {
12049371c9d4SSatish Balay       (*vals)[i] = *v;
12059371c9d4SSatish Balay       v += mat->lda;
12069371c9d4SSatish Balay     }
12079566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A, &v));
1208289bc588SBarry Smith   }
12093a40ed3dSBarry Smith   PetscFunctionReturn(0);
1210289bc588SBarry Smith }
12116ee01492SSatish Balay 
1212*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRestoreRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals)
1213*d71ae5a4SJacob Faibussowitsch {
1214606d414cSSatish Balay   PetscFunctionBegin;
1215cb4a9cd9SHong Zhang   if (ncols) *ncols = 0;
12169566063dSJacob Faibussowitsch   if (cols) PetscCall(PetscFree(*cols));
12179566063dSJacob Faibussowitsch   if (vals) PetscCall(PetscFree(*vals));
12183a40ed3dSBarry Smith   PetscFunctionReturn(0);
1219289bc588SBarry Smith }
1220289bc588SBarry Smith /* ----------------------------------------------------------------*/
1221*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], const PetscScalar v[], InsertMode addv)
1222*d71ae5a4SJacob Faibussowitsch {
1223c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
1224ca15aa20SStefano Zampini   PetscScalar  *av;
122513f74950SBarry Smith   PetscInt      i, j, idx = 0;
1226ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1227c70f7ee4SJunchao Zhang   PetscOffloadMask oldf;
1228ca15aa20SStefano Zampini #endif
1229d6dfbf8fSBarry Smith 
12303a40ed3dSBarry Smith   PetscFunctionBegin;
12319566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &av));
1232289bc588SBarry Smith   if (!mat->roworiented) {
1233dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1234289bc588SBarry Smith       for (j = 0; j < n; j++) {
12359371c9d4SSatish Balay         if (indexn[j] < 0) {
12369371c9d4SSatish Balay           idx += m;
12379371c9d4SSatish Balay           continue;
12389371c9d4SSatish Balay         }
12396bdcaf15SBarry 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);
1240289bc588SBarry Smith         for (i = 0; i < m; i++) {
12419371c9d4SSatish Balay           if (indexm[i] < 0) {
12429371c9d4SSatish Balay             idx++;
12439371c9d4SSatish Balay             continue;
12449371c9d4SSatish Balay           }
12456bdcaf15SBarry 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);
1246ca15aa20SStefano Zampini           av[indexn[j] * mat->lda + indexm[i]] = v[idx++];
1247289bc588SBarry Smith         }
1248289bc588SBarry Smith       }
12493a40ed3dSBarry Smith     } else {
1250289bc588SBarry Smith       for (j = 0; j < n; j++) {
12519371c9d4SSatish Balay         if (indexn[j] < 0) {
12529371c9d4SSatish Balay           idx += m;
12539371c9d4SSatish Balay           continue;
12549371c9d4SSatish Balay         }
12556bdcaf15SBarry 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);
1256289bc588SBarry Smith         for (i = 0; i < m; i++) {
12579371c9d4SSatish Balay           if (indexm[i] < 0) {
12589371c9d4SSatish Balay             idx++;
12599371c9d4SSatish Balay             continue;
12609371c9d4SSatish Balay           }
12616bdcaf15SBarry 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);
1262ca15aa20SStefano Zampini           av[indexn[j] * mat->lda + indexm[i]] += v[idx++];
1263289bc588SBarry Smith         }
1264289bc588SBarry Smith       }
1265289bc588SBarry Smith     }
12663a40ed3dSBarry Smith   } else {
1267dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1268e8d4e0b9SBarry Smith       for (i = 0; i < m; i++) {
12699371c9d4SSatish Balay         if (indexm[i] < 0) {
12709371c9d4SSatish Balay           idx += n;
12719371c9d4SSatish Balay           continue;
12729371c9d4SSatish Balay         }
12736bdcaf15SBarry 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);
1274e8d4e0b9SBarry Smith         for (j = 0; j < n; j++) {
12759371c9d4SSatish Balay           if (indexn[j] < 0) {
12769371c9d4SSatish Balay             idx++;
12779371c9d4SSatish Balay             continue;
12789371c9d4SSatish Balay           }
12796bdcaf15SBarry 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);
1280ca15aa20SStefano Zampini           av[indexn[j] * mat->lda + indexm[i]] = v[idx++];
1281e8d4e0b9SBarry Smith         }
1282e8d4e0b9SBarry Smith       }
12833a40ed3dSBarry Smith     } else {
1284289bc588SBarry Smith       for (i = 0; i < m; i++) {
12859371c9d4SSatish Balay         if (indexm[i] < 0) {
12869371c9d4SSatish Balay           idx += n;
12879371c9d4SSatish Balay           continue;
12889371c9d4SSatish Balay         }
12896bdcaf15SBarry 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);
1290289bc588SBarry Smith         for (j = 0; j < n; j++) {
12919371c9d4SSatish Balay           if (indexn[j] < 0) {
12929371c9d4SSatish Balay             idx++;
12939371c9d4SSatish Balay             continue;
12949371c9d4SSatish Balay           }
12956bdcaf15SBarry 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);
1296ca15aa20SStefano Zampini           av[indexn[j] * mat->lda + indexm[i]] += v[idx++];
1297289bc588SBarry Smith         }
1298289bc588SBarry Smith       }
1299289bc588SBarry Smith     }
1300e8d4e0b9SBarry Smith   }
1301ca15aa20SStefano Zampini   /* hack to prevent unneeded copy to the GPU while returning the array */
1302ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1303c70f7ee4SJunchao Zhang   oldf           = A->offloadmask;
1304c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_GPU;
1305ca15aa20SStefano Zampini #endif
13069566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &av));
1307ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1308c70f7ee4SJunchao Zhang   A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU);
1309ca15aa20SStefano Zampini #endif
13103a40ed3dSBarry Smith   PetscFunctionReturn(0);
1311289bc588SBarry Smith }
1312e8d4e0b9SBarry Smith 
1313*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], PetscScalar v[])
1314*d71ae5a4SJacob Faibussowitsch {
1315ae80bb75SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1316ca15aa20SStefano Zampini   const PetscScalar *vv;
131713f74950SBarry Smith   PetscInt           i, j;
1318ae80bb75SLois Curfman McInnes 
13193a40ed3dSBarry Smith   PetscFunctionBegin;
13209566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &vv));
1321ae80bb75SLois Curfman McInnes   /* row-oriented output */
1322ae80bb75SLois Curfman McInnes   for (i = 0; i < m; i++) {
13239371c9d4SSatish Balay     if (indexm[i] < 0) {
13249371c9d4SSatish Balay       v += n;
13259371c9d4SSatish Balay       continue;
13269371c9d4SSatish Balay     }
132708401ef6SPierre 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);
1328ae80bb75SLois Curfman McInnes     for (j = 0; j < n; j++) {
13299371c9d4SSatish Balay       if (indexn[j] < 0) {
13309371c9d4SSatish Balay         v++;
13319371c9d4SSatish Balay         continue;
13329371c9d4SSatish Balay       }
133308401ef6SPierre 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);
1334ca15aa20SStefano Zampini       *v++ = vv[indexn[j] * mat->lda + indexm[i]];
1335ae80bb75SLois Curfman McInnes     }
1336ae80bb75SLois Curfman McInnes   }
13379566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &vv));
13383a40ed3dSBarry Smith   PetscFunctionReturn(0);
1339ae80bb75SLois Curfman McInnes }
1340ae80bb75SLois Curfman McInnes 
1341289bc588SBarry Smith /* -----------------------------------------------------------------*/
1342289bc588SBarry Smith 
1343*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_Dense_Binary(Mat mat, PetscViewer viewer)
1344*d71ae5a4SJacob Faibussowitsch {
13458491ab44SLisandro Dalcin   PetscBool          skipHeader;
13468491ab44SLisandro Dalcin   PetscViewerFormat  format;
13478491ab44SLisandro Dalcin   PetscInt           header[4], M, N, m, lda, i, j, k;
13488491ab44SLisandro Dalcin   const PetscScalar *v;
13498491ab44SLisandro Dalcin   PetscScalar       *vwork;
1350aabbc4fbSShri Abhyankar 
1351aabbc4fbSShri Abhyankar   PetscFunctionBegin;
13529566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
13539566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader));
13549566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
13558491ab44SLisandro Dalcin   if (skipHeader) format = PETSC_VIEWER_NATIVE;
1356aabbc4fbSShri Abhyankar 
13579566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat, &M, &N));
13588491ab44SLisandro Dalcin 
13598491ab44SLisandro Dalcin   /* write matrix header */
13609371c9d4SSatish Balay   header[0] = MAT_FILE_CLASSID;
13619371c9d4SSatish Balay   header[1] = M;
13629371c9d4SSatish Balay   header[2] = N;
13638491ab44SLisandro Dalcin   header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M * N;
13649566063dSJacob Faibussowitsch   if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer, header, 4, PETSC_INT));
13658491ab44SLisandro Dalcin 
13669566063dSJacob Faibussowitsch   PetscCall(MatGetLocalSize(mat, &m, NULL));
13678491ab44SLisandro Dalcin   if (format != PETSC_VIEWER_NATIVE) {
13688491ab44SLisandro Dalcin     PetscInt nnz = m * N, *iwork;
13698491ab44SLisandro Dalcin     /* store row lengths for each row */
13709566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nnz, &iwork));
13718491ab44SLisandro Dalcin     for (i = 0; i < m; i++) iwork[i] = N;
13729566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT));
13738491ab44SLisandro Dalcin     /* store column indices (zero start index) */
13748491ab44SLisandro Dalcin     for (k = 0, i = 0; i < m; i++)
13759371c9d4SSatish Balay       for (j = 0; j < N; j++, k++) iwork[k] = j;
13769566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT));
13779566063dSJacob Faibussowitsch     PetscCall(PetscFree(iwork));
13788491ab44SLisandro Dalcin   }
13798491ab44SLisandro Dalcin   /* store matrix values as a dense matrix in row major order */
13809566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(m * N, &vwork));
13819566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(mat, &v));
13829566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(mat, &lda));
13838491ab44SLisandro Dalcin   for (k = 0, i = 0; i < m; i++)
13849371c9d4SSatish Balay     for (j = 0; j < N; j++, k++) vwork[k] = v[i + lda * j];
13859566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(mat, &v));
13869566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryWriteAll(viewer, vwork, m * N, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR));
13879566063dSJacob Faibussowitsch   PetscCall(PetscFree(vwork));
13888491ab44SLisandro Dalcin   PetscFunctionReturn(0);
13898491ab44SLisandro Dalcin }
13908491ab44SLisandro Dalcin 
1391*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLoad_Dense_Binary(Mat mat, PetscViewer viewer)
1392*d71ae5a4SJacob Faibussowitsch {
13938491ab44SLisandro Dalcin   PetscBool    skipHeader;
13948491ab44SLisandro Dalcin   PetscInt     header[4], M, N, m, nz, lda, i, j, k;
13958491ab44SLisandro Dalcin   PetscInt     rows, cols;
13968491ab44SLisandro Dalcin   PetscScalar *v, *vwork;
13978491ab44SLisandro Dalcin 
13988491ab44SLisandro Dalcin   PetscFunctionBegin;
13999566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
14009566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader));
14018491ab44SLisandro Dalcin 
14028491ab44SLisandro Dalcin   if (!skipHeader) {
14039566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryRead(viewer, header, 4, NULL, PETSC_INT));
140408401ef6SPierre Jolivet     PetscCheck(header[0] == MAT_FILE_CLASSID, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Not a matrix object in file");
14059371c9d4SSatish Balay     M = header[1];
14069371c9d4SSatish Balay     N = header[2];
140708401ef6SPierre Jolivet     PetscCheck(M >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix row size (%" PetscInt_FMT ") in file is negative", M);
140808401ef6SPierre Jolivet     PetscCheck(N >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix column size (%" PetscInt_FMT ") in file is negative", N);
14098491ab44SLisandro Dalcin     nz = header[3];
1410aed4548fSBarry Smith     PetscCheck(nz == MATRIX_BINARY_FORMAT_DENSE || nz >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Unknown matrix format %" PetscInt_FMT " in file", nz);
1411aabbc4fbSShri Abhyankar   } else {
14129566063dSJacob Faibussowitsch     PetscCall(MatGetSize(mat, &M, &N));
1413aed4548fSBarry 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");
14148491ab44SLisandro Dalcin     nz = MATRIX_BINARY_FORMAT_DENSE;
1415e6324fbbSBarry Smith   }
1416aabbc4fbSShri Abhyankar 
14178491ab44SLisandro Dalcin   /* setup global sizes if not set */
14188491ab44SLisandro Dalcin   if (mat->rmap->N < 0) mat->rmap->N = M;
14198491ab44SLisandro Dalcin   if (mat->cmap->N < 0) mat->cmap->N = N;
14209566063dSJacob Faibussowitsch   PetscCall(MatSetUp(mat));
14218491ab44SLisandro Dalcin   /* check if global sizes are correct */
14229566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat, &rows, &cols));
1423aed4548fSBarry 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);
1424aabbc4fbSShri Abhyankar 
14259566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat, NULL, &N));
14269566063dSJacob Faibussowitsch   PetscCall(MatGetLocalSize(mat, &m, NULL));
14279566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(mat, &v));
14289566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(mat, &lda));
14298491ab44SLisandro Dalcin   if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense format */
14308491ab44SLisandro Dalcin     PetscInt nnz = m * N;
14318491ab44SLisandro Dalcin     /* read in matrix values */
14329566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nnz, &vwork));
14339566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR));
14348491ab44SLisandro Dalcin     /* store values in column major order */
14358491ab44SLisandro Dalcin     for (j = 0; j < N; j++)
14369371c9d4SSatish Balay       for (i = 0; i < m; i++) v[i + lda * j] = vwork[i * N + j];
14379566063dSJacob Faibussowitsch     PetscCall(PetscFree(vwork));
14388491ab44SLisandro Dalcin   } else { /* matrix in file is sparse format */
14398491ab44SLisandro Dalcin     PetscInt nnz = 0, *rlens, *icols;
14408491ab44SLisandro Dalcin     /* read in row lengths */
14419566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(m, &rlens));
14429566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer, rlens, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT));
14438491ab44SLisandro Dalcin     for (i = 0; i < m; i++) nnz += rlens[i];
14448491ab44SLisandro Dalcin     /* read in column indices and values */
14459566063dSJacob Faibussowitsch     PetscCall(PetscMalloc2(nnz, &icols, nnz, &vwork));
14469566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer, icols, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT));
14479566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR));
14488491ab44SLisandro Dalcin     /* store values in column major order */
14498491ab44SLisandro Dalcin     for (k = 0, i = 0; i < m; i++)
14509371c9d4SSatish Balay       for (j = 0; j < rlens[i]; j++, k++) v[i + lda * icols[k]] = vwork[k];
14519566063dSJacob Faibussowitsch     PetscCall(PetscFree(rlens));
14529566063dSJacob Faibussowitsch     PetscCall(PetscFree2(icols, vwork));
1453aabbc4fbSShri Abhyankar   }
14549566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(mat, &v));
14559566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY));
14569566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY));
1457aabbc4fbSShri Abhyankar   PetscFunctionReturn(0);
1458aabbc4fbSShri Abhyankar }
1459aabbc4fbSShri Abhyankar 
1460*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer)
1461*d71ae5a4SJacob Faibussowitsch {
1462eb91f321SVaclav Hapla   PetscBool isbinary, ishdf5;
1463eb91f321SVaclav Hapla 
1464eb91f321SVaclav Hapla   PetscFunctionBegin;
1465eb91f321SVaclav Hapla   PetscValidHeaderSpecific(newMat, MAT_CLASSID, 1);
1466eb91f321SVaclav Hapla   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
1467eb91f321SVaclav Hapla   /* force binary viewer to load .info file if it has not yet done so */
14689566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
14699566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
14709566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5));
1471eb91f321SVaclav Hapla   if (isbinary) {
14729566063dSJacob Faibussowitsch     PetscCall(MatLoad_Dense_Binary(newMat, viewer));
1473eb91f321SVaclav Hapla   } else if (ishdf5) {
1474eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5)
14759566063dSJacob Faibussowitsch     PetscCall(MatLoad_Dense_HDF5(newMat, viewer));
1476eb91f321SVaclav Hapla #else
1477eb91f321SVaclav Hapla     SETERRQ(PetscObjectComm((PetscObject)newMat), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5");
1478eb91f321SVaclav Hapla #endif
1479eb91f321SVaclav Hapla   } else {
148098921bdaSJacob 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);
1481eb91f321SVaclav Hapla   }
1482eb91f321SVaclav Hapla   PetscFunctionReturn(0);
1483eb91f321SVaclav Hapla }
1484eb91f321SVaclav Hapla 
1485*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_ASCII(Mat A, PetscViewer viewer)
1486*d71ae5a4SJacob Faibussowitsch {
1487932b0c3eSLois Curfman McInnes   Mat_SeqDense     *a = (Mat_SeqDense *)A->data;
148813f74950SBarry Smith   PetscInt          i, j;
14892dcb1b2aSMatthew Knepley   const char       *name;
1490ca15aa20SStefano Zampini   PetscScalar      *v, *av;
1491f3ef73ceSBarry Smith   PetscViewerFormat format;
14925f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX)
1493ace3abfcSBarry Smith   PetscBool allreal = PETSC_TRUE;
14945f481a85SSatish Balay #endif
1495932b0c3eSLois Curfman McInnes 
14963a40ed3dSBarry Smith   PetscFunctionBegin;
14979566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&av));
14989566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
1499456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
15003a40ed3dSBarry Smith     PetscFunctionReturn(0); /* do nothing for now */
1501fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
15029566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
1503d0f46423SBarry Smith     for (i = 0; i < A->rmap->n; i++) {
1504ca15aa20SStefano Zampini       v = av + i;
15059566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "row %" PetscInt_FMT ":", i));
1506d0f46423SBarry Smith       for (j = 0; j < A->cmap->n; j++) {
1507aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1508329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
15099566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g + %g i) ", j, (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v)));
1510329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
15119566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)PetscRealPart(*v)));
15126831982aSBarry Smith         }
151380cd9d93SLois Curfman McInnes #else
151448a46eb9SPierre Jolivet         if (*v) PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)*v));
151580cd9d93SLois Curfman McInnes #endif
15161b807ce4Svictorle         v += a->lda;
151780cd9d93SLois Curfman McInnes       }
15189566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
151980cd9d93SLois Curfman McInnes     }
15209566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
15213a40ed3dSBarry Smith   } else {
15229566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
1523aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
152447989497SBarry Smith     /* determine if matrix has all real values */
1525bcd8d3a4SJose E. Roman     for (j = 0; j < A->cmap->n; j++) {
1526bcd8d3a4SJose E. Roman       v = av + j * a->lda;
1527bcd8d3a4SJose E. Roman       for (i = 0; i < A->rmap->n; i++) {
15289371c9d4SSatish Balay         if (PetscImaginaryPart(v[i])) {
15299371c9d4SSatish Balay           allreal = PETSC_FALSE;
15309371c9d4SSatish Balay           break;
15319371c9d4SSatish Balay         }
153247989497SBarry Smith       }
1533bcd8d3a4SJose E. Roman     }
153447989497SBarry Smith #endif
1535fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
15369566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetName((PetscObject)A, &name));
15379566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%% Size = %" PetscInt_FMT " %" PetscInt_FMT " \n", A->rmap->n, A->cmap->n));
15389566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%s = zeros(%" PetscInt_FMT ",%" PetscInt_FMT ");\n", name, A->rmap->n, A->cmap->n));
15399566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%s = [\n", name));
1540ffac6cdbSBarry Smith     }
1541ffac6cdbSBarry Smith 
1542d0f46423SBarry Smith     for (i = 0; i < A->rmap->n; i++) {
1543ca15aa20SStefano Zampini       v = av + i;
1544d0f46423SBarry Smith       for (j = 0; j < A->cmap->n; j++) {
1545aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
154647989497SBarry Smith         if (allreal) {
15479566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)PetscRealPart(*v)));
154847989497SBarry Smith         } else {
15499566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e + %18.16ei ", (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v)));
155047989497SBarry Smith         }
1551289bc588SBarry Smith #else
15529566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)*v));
1553289bc588SBarry Smith #endif
15541b807ce4Svictorle         v += a->lda;
1555289bc588SBarry Smith       }
15569566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
1557289bc588SBarry Smith     }
155848a46eb9SPierre Jolivet     if (format == PETSC_VIEWER_ASCII_MATLAB) PetscCall(PetscViewerASCIIPrintf(viewer, "];\n"));
15599566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
1560da3a660dSBarry Smith   }
15619566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&av));
15629566063dSJacob Faibussowitsch   PetscCall(PetscViewerFlush(viewer));
15633a40ed3dSBarry Smith   PetscFunctionReturn(0);
1564289bc588SBarry Smith }
1565289bc588SBarry Smith 
15669804daf3SBarry Smith #include <petscdraw.h>
1567*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw, void *Aa)
1568*d71ae5a4SJacob Faibussowitsch {
1569f1af5d2fSBarry Smith   Mat                A = (Mat)Aa;
1570383922c3SLisandro Dalcin   PetscInt           m = A->rmap->n, n = A->cmap->n, i, j;
1571383922c3SLisandro Dalcin   int                color = PETSC_DRAW_WHITE;
1572ca15aa20SStefano Zampini   const PetscScalar *v;
1573b0a32e0cSBarry Smith   PetscViewer        viewer;
1574b05fc000SLisandro Dalcin   PetscReal          xl, yl, xr, yr, x_l, x_r, y_l, y_r;
1575f3ef73ceSBarry Smith   PetscViewerFormat  format;
1576f1af5d2fSBarry Smith 
1577f1af5d2fSBarry Smith   PetscFunctionBegin;
15789566063dSJacob Faibussowitsch   PetscCall(PetscObjectQuery((PetscObject)A, "Zoomviewer", (PetscObject *)&viewer));
15799566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
15809566063dSJacob Faibussowitsch   PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr));
1581f1af5d2fSBarry Smith 
1582f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
15839566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &v));
1584fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
1585d0609cedSBarry Smith     PetscDrawCollectiveBegin(draw);
1586f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
1587f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
15889371c9d4SSatish Balay       x_l = j;
15899371c9d4SSatish Balay       x_r = x_l + 1.0;
1590f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1591f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1592f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1593ca15aa20SStefano Zampini         if (PetscRealPart(v[j * m + i]) > 0.) color = PETSC_DRAW_RED;
1594ca15aa20SStefano Zampini         else if (PetscRealPart(v[j * m + i]) < 0.) color = PETSC_DRAW_BLUE;
1595ca15aa20SStefano Zampini         else continue;
15969566063dSJacob Faibussowitsch         PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color));
1597f1af5d2fSBarry Smith       }
1598f1af5d2fSBarry Smith     }
1599d0609cedSBarry Smith     PetscDrawCollectiveEnd(draw);
1600f1af5d2fSBarry Smith   } else {
1601f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
1602f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
1603b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1604b05fc000SLisandro Dalcin     PetscDraw popup;
1605b05fc000SLisandro Dalcin 
1606f1af5d2fSBarry Smith     for (i = 0; i < m * n; i++) {
1607f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
1608f1af5d2fSBarry Smith     }
1609383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
16109566063dSJacob Faibussowitsch     PetscCall(PetscDrawGetPopup(draw, &popup));
16119566063dSJacob Faibussowitsch     PetscCall(PetscDrawScalePopup(popup, minv, maxv));
1612383922c3SLisandro Dalcin 
1613d0609cedSBarry Smith     PetscDrawCollectiveBegin(draw);
1614f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
1615f1af5d2fSBarry Smith       x_l = j;
1616f1af5d2fSBarry Smith       x_r = x_l + 1.0;
1617f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1618f1af5d2fSBarry Smith         y_l   = m - i - 1.0;
1619f1af5d2fSBarry Smith         y_r   = y_l + 1.0;
1620b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(v[j * m + i]), minv, maxv);
16219566063dSJacob Faibussowitsch         PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color));
1622f1af5d2fSBarry Smith       }
1623f1af5d2fSBarry Smith     }
1624d0609cedSBarry Smith     PetscDrawCollectiveEnd(draw);
1625f1af5d2fSBarry Smith   }
16269566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &v));
1627f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1628f1af5d2fSBarry Smith }
1629f1af5d2fSBarry Smith 
1630*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw(Mat A, PetscViewer viewer)
1631*d71ae5a4SJacob Faibussowitsch {
1632b0a32e0cSBarry Smith   PetscDraw draw;
1633ace3abfcSBarry Smith   PetscBool isnull;
1634329f5518SBarry Smith   PetscReal xr, yr, xl, yl, h, w;
1635f1af5d2fSBarry Smith 
1636f1af5d2fSBarry Smith   PetscFunctionBegin;
16379566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
16389566063dSJacob Faibussowitsch   PetscCall(PetscDrawIsNull(draw, &isnull));
1639abc0a331SBarry Smith   if (isnull) PetscFunctionReturn(0);
1640f1af5d2fSBarry Smith 
16419371c9d4SSatish Balay   xr = A->cmap->n;
16429371c9d4SSatish Balay   yr = A->rmap->n;
16439371c9d4SSatish Balay   h  = yr / 10.0;
16449371c9d4SSatish Balay   w  = xr / 10.0;
16459371c9d4SSatish Balay   xr += w;
16469371c9d4SSatish Balay   yr += h;
16479371c9d4SSatish Balay   xl = -w;
16489371c9d4SSatish Balay   yl = -h;
16499566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetCoordinates(draw, xl, yl, xr, yr));
16509566063dSJacob Faibussowitsch   PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", (PetscObject)viewer));
16519566063dSJacob Faibussowitsch   PetscCall(PetscDrawZoom(draw, MatView_SeqDense_Draw_Zoom, A));
16529566063dSJacob Faibussowitsch   PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", NULL));
16539566063dSJacob Faibussowitsch   PetscCall(PetscDrawSave(draw));
1654f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1655f1af5d2fSBarry Smith }
1656f1af5d2fSBarry Smith 
1657*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_SeqDense(Mat A, PetscViewer viewer)
1658*d71ae5a4SJacob Faibussowitsch {
1659ace3abfcSBarry Smith   PetscBool iascii, isbinary, isdraw;
1660932b0c3eSLois Curfman McInnes 
16613a40ed3dSBarry Smith   PetscFunctionBegin;
16629566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
16639566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
16649566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
16651baa6e33SBarry Smith   if (iascii) PetscCall(MatView_SeqDense_ASCII(A, viewer));
16661baa6e33SBarry Smith   else if (isbinary) PetscCall(MatView_Dense_Binary(A, viewer));
16671baa6e33SBarry Smith   else if (isdraw) PetscCall(MatView_SeqDense_Draw(A, viewer));
16683a40ed3dSBarry Smith   PetscFunctionReturn(0);
1669932b0c3eSLois Curfman McInnes }
1670289bc588SBarry Smith 
1671*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A, const PetscScalar *array)
1672*d71ae5a4SJacob Faibussowitsch {
1673d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
1674d3042a70SBarry Smith 
1675d3042a70SBarry Smith   PetscFunctionBegin;
167628b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
167728b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
167828b400f6SJacob Faibussowitsch   PetscCheck(!a->unplacedarray, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreArray() first");
1679d3042a70SBarry Smith   a->unplacedarray       = a->v;
1680d3042a70SBarry Smith   a->unplaced_user_alloc = a->user_alloc;
1681d3042a70SBarry Smith   a->v                   = (PetscScalar *)array;
1682637a0070SStefano Zampini   a->user_alloc          = PETSC_TRUE;
1683ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1684c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1685ca15aa20SStefano Zampini #endif
1686d3042a70SBarry Smith   PetscFunctionReturn(0);
1687d3042a70SBarry Smith }
1688d3042a70SBarry Smith 
1689*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseResetArray_SeqDense(Mat A)
1690*d71ae5a4SJacob Faibussowitsch {
1691d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
1692d3042a70SBarry Smith 
1693d3042a70SBarry Smith   PetscFunctionBegin;
169428b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
169528b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
1696d3042a70SBarry Smith   a->v             = a->unplacedarray;
1697d3042a70SBarry Smith   a->user_alloc    = a->unplaced_user_alloc;
1698d3042a70SBarry Smith   a->unplacedarray = NULL;
1699ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1700c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1701ca15aa20SStefano Zampini #endif
1702d3042a70SBarry Smith   PetscFunctionReturn(0);
1703d3042a70SBarry Smith }
1704d3042a70SBarry Smith 
1705*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A, const PetscScalar *array)
1706*d71ae5a4SJacob Faibussowitsch {
1707d5ea218eSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
1708d5ea218eSStefano Zampini 
1709d5ea218eSStefano Zampini   PetscFunctionBegin;
171028b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
171128b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
17129566063dSJacob Faibussowitsch   if (!a->user_alloc) PetscCall(PetscFree(a->v));
1713d5ea218eSStefano Zampini   a->v          = (PetscScalar *)array;
1714d5ea218eSStefano Zampini   a->user_alloc = PETSC_FALSE;
1715d5ea218eSStefano Zampini #if defined(PETSC_HAVE_CUDA)
1716d5ea218eSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
1717d5ea218eSStefano Zampini #endif
1718d5ea218eSStefano Zampini   PetscFunctionReturn(0);
1719d5ea218eSStefano Zampini }
1720d5ea218eSStefano Zampini 
1721*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDestroy_SeqDense(Mat mat)
1722*d71ae5a4SJacob Faibussowitsch {
1723ec8511deSBarry Smith   Mat_SeqDense *l = (Mat_SeqDense *)mat->data;
172490f02eecSBarry Smith 
17253a40ed3dSBarry Smith   PetscFunctionBegin;
1726aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1727c0aa6a63SJacob Faibussowitsch   PetscLogObjectState((PetscObject)mat, "Rows %" PetscInt_FMT " Cols %" PetscInt_FMT, mat->rmap->n, mat->cmap->n);
1728a5a9c739SBarry Smith #endif
17299566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(l->qrrhs)));
17309566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->tau));
17319566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->pivots));
17329566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->fwork));
17339566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&l->ptapwork));
17349566063dSJacob Faibussowitsch   if (!l->user_alloc) PetscCall(PetscFree(l->v));
17359566063dSJacob Faibussowitsch   if (!l->unplaced_user_alloc) PetscCall(PetscFree(l->unplacedarray));
173628b400f6SJacob Faibussowitsch   PetscCheck(!l->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
173728b400f6SJacob Faibussowitsch   PetscCheck(!l->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
17389566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&l->cvec));
17399566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&l->cmat));
17409566063dSJacob Faibussowitsch   PetscCall(PetscFree(mat->data));
1741dbd8c25aSHong Zhang 
17429566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)mat, NULL));
17439566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactor_C", NULL));
17442e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorSymbolic_C", NULL));
17452e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorNumeric_C", NULL));
17469566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetLDA_C", NULL));
17479566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseSetLDA_C", NULL));
17489566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArray_C", NULL));
17499566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArray_C", NULL));
17509566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDensePlaceArray_C", NULL));
17519566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseResetArray_C", NULL));
17529566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseReplaceArray_C", NULL));
17539566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayRead_C", NULL));
17549566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayRead_C", NULL));
17559566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayWrite_C", NULL));
17569566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayWrite_C", NULL));
17579566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqaij_C", NULL));
17588baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
17599566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_elemental_C", NULL));
17608baccfbdSHong Zhang #endif
1761d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
17629566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_scalapack_C", NULL));
1763d24d4204SJose E. Roman #endif
17642bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
17659566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensecuda_C", NULL));
17669566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", NULL));
17679566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdense_C", NULL));
17682e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensecuda_C", NULL));
17692bf066beSStefano Zampini #endif
17709566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatSeqDenseSetPreallocation_C", NULL));
17719566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqaij_seqdense_C", NULL));
17729566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdense_C", NULL));
17739566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqbaij_seqdense_C", NULL));
17749566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqsbaij_seqdense_C", NULL));
177552c5f739Sprj- 
17769566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumn_C", NULL));
17779566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumn_C", NULL));
17789566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVec_C", NULL));
17799566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVec_C", NULL));
17809566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecRead_C", NULL));
17819566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecRead_C", NULL));
17829566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecWrite_C", NULL));
17839566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecWrite_C", NULL));
17849566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetSubMatrix_C", NULL));
17859566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreSubMatrix_C", NULL));
17863a40ed3dSBarry Smith   PetscFunctionReturn(0);
1787289bc588SBarry Smith }
1788289bc588SBarry Smith 
1789*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatTranspose_SeqDense(Mat A, MatReuse reuse, Mat *matout)
1790*d71ae5a4SJacob Faibussowitsch {
1791c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
17926536e3caSStefano Zampini   PetscInt      k, j, m = A->rmap->n, M = mat->lda, n = A->cmap->n;
179387828ca2SBarry Smith   PetscScalar  *v, tmp;
179448b35521SBarry Smith 
17953a40ed3dSBarry Smith   PetscFunctionBegin;
17967fb60732SBarry Smith   if (reuse == MAT_REUSE_MATRIX) PetscCall(MatTransposeCheckNonzeroState_Private(A, *matout));
17976536e3caSStefano Zampini   if (reuse == MAT_INPLACE_MATRIX) {
17986536e3caSStefano Zampini     if (m == n) { /* in place transpose */
17999566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(A, &v));
1800d3e5ee88SLois Curfman McInnes       for (j = 0; j < m; j++) {
1801289bc588SBarry Smith         for (k = 0; k < j; k++) {
18021b807ce4Svictorle           tmp          = v[j + k * M];
18031b807ce4Svictorle           v[j + k * M] = v[k + j * M];
18041b807ce4Svictorle           v[k + j * M] = tmp;
1805289bc588SBarry Smith         }
1806289bc588SBarry Smith       }
18079566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArray(A, &v));
18086536e3caSStefano Zampini     } else { /* reuse memory, temporary allocates new memory */
18096536e3caSStefano Zampini       PetscScalar *v2;
18106536e3caSStefano Zampini       PetscLayout  tmplayout;
18116536e3caSStefano Zampini 
18129566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1((size_t)m * n, &v2));
18139566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(A, &v));
18146536e3caSStefano Zampini       for (j = 0; j < n; j++) {
18156536e3caSStefano Zampini         for (k = 0; k < m; k++) v2[j + (size_t)k * n] = v[k + (size_t)j * M];
18166536e3caSStefano Zampini       }
18179566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(v, v2, (size_t)m * n));
18189566063dSJacob Faibussowitsch       PetscCall(PetscFree(v2));
18199566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArray(A, &v));
18206536e3caSStefano Zampini       /* cleanup size dependent quantities */
18219566063dSJacob Faibussowitsch       PetscCall(VecDestroy(&mat->cvec));
18229566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&mat->cmat));
18239566063dSJacob Faibussowitsch       PetscCall(PetscFree(mat->pivots));
18249566063dSJacob Faibussowitsch       PetscCall(PetscFree(mat->fwork));
18259566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&mat->ptapwork));
18266536e3caSStefano Zampini       /* swap row/col layouts */
18276536e3caSStefano Zampini       mat->lda  = n;
18286536e3caSStefano Zampini       tmplayout = A->rmap;
18296536e3caSStefano Zampini       A->rmap   = A->cmap;
18306536e3caSStefano Zampini       A->cmap   = tmplayout;
18316536e3caSStefano Zampini     }
18323a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1833d3e5ee88SLois Curfman McInnes     Mat           tmat;
1834ec8511deSBarry Smith     Mat_SeqDense *tmatd;
183587828ca2SBarry Smith     PetscScalar  *v2;
1836af36a384SStefano Zampini     PetscInt      M2;
1837ea709b57SSatish Balay 
18386536e3caSStefano Zampini     if (reuse == MAT_INITIAL_MATRIX) {
18399566063dSJacob Faibussowitsch       PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &tmat));
18409566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(tmat, A->cmap->n, A->rmap->n, A->cmap->n, A->rmap->n));
18419566063dSJacob Faibussowitsch       PetscCall(MatSetType(tmat, ((PetscObject)A)->type_name));
18429566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSetPreallocation(tmat, NULL));
1843ca15aa20SStefano Zampini     } else tmat = *matout;
1844ca15aa20SStefano Zampini 
18459566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&v));
18469566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArray(tmat, &v2));
1847ec8511deSBarry Smith     tmatd = (Mat_SeqDense *)tmat->data;
1848ca15aa20SStefano Zampini     M2    = tmatd->lda;
1849d3e5ee88SLois Curfman McInnes     for (j = 0; j < n; j++) {
1850af36a384SStefano Zampini       for (k = 0; k < m; k++) v2[j + k * M2] = v[k + j * M];
1851d3e5ee88SLois Curfman McInnes     }
18529566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(tmat, &v2));
18539566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&v));
18549566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(tmat, MAT_FINAL_ASSEMBLY));
18559566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(tmat, MAT_FINAL_ASSEMBLY));
18566536e3caSStefano Zampini     *matout = tmat;
185748b35521SBarry Smith   }
18583a40ed3dSBarry Smith   PetscFunctionReturn(0);
1859289bc588SBarry Smith }
1860289bc588SBarry Smith 
1861*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatEqual_SeqDense(Mat A1, Mat A2, PetscBool *flg)
1862*d71ae5a4SJacob Faibussowitsch {
1863c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat1 = (Mat_SeqDense *)A1->data;
1864c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat2 = (Mat_SeqDense *)A2->data;
1865ca15aa20SStefano Zampini   PetscInt           i;
1866ca15aa20SStefano Zampini   const PetscScalar *v1, *v2;
18679ea5d5aeSSatish Balay 
18683a40ed3dSBarry Smith   PetscFunctionBegin;
18699371c9d4SSatish Balay   if (A1->rmap->n != A2->rmap->n) {
18709371c9d4SSatish Balay     *flg = PETSC_FALSE;
18719371c9d4SSatish Balay     PetscFunctionReturn(0);
18729371c9d4SSatish Balay   }
18739371c9d4SSatish Balay   if (A1->cmap->n != A2->cmap->n) {
18749371c9d4SSatish Balay     *flg = PETSC_FALSE;
18759371c9d4SSatish Balay     PetscFunctionReturn(0);
18769371c9d4SSatish Balay   }
18779566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A1, &v1));
18789566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A2, &v2));
1879ca15aa20SStefano Zampini   for (i = 0; i < A1->cmap->n; i++) {
18809566063dSJacob Faibussowitsch     PetscCall(PetscArraycmp(v1, v2, A1->rmap->n, flg));
1881ca15aa20SStefano Zampini     if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
1882ca15aa20SStefano Zampini     v1 += mat1->lda;
1883ca15aa20SStefano Zampini     v2 += mat2->lda;
18841b807ce4Svictorle   }
18859566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A1, &v1));
18869566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A2, &v2));
188777c4ece6SBarry Smith   *flg = PETSC_TRUE;
18883a40ed3dSBarry Smith   PetscFunctionReturn(0);
1889289bc588SBarry Smith }
1890289bc588SBarry Smith 
1891*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetDiagonal_SeqDense(Mat A, Vec v)
1892*d71ae5a4SJacob Faibussowitsch {
1893c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
189413f74950SBarry Smith   PetscInt           i, n, len;
1895ca15aa20SStefano Zampini   PetscScalar       *x;
1896ca15aa20SStefano Zampini   const PetscScalar *vv;
189744cd7ae7SLois Curfman McInnes 
18983a40ed3dSBarry Smith   PetscFunctionBegin;
18999566063dSJacob Faibussowitsch   PetscCall(VecGetSize(v, &n));
19009566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
1901d0f46423SBarry Smith   len = PetscMin(A->rmap->n, A->cmap->n);
19029566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &vv));
190308401ef6SPierre Jolivet   PetscCheck(n == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming mat and vec");
1904ad540459SPierre Jolivet   for (i = 0; i < len; i++) x[i] = vv[i * mat->lda + i];
19059566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &vv));
19069566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
19073a40ed3dSBarry Smith   PetscFunctionReturn(0);
1908289bc588SBarry Smith }
1909289bc588SBarry Smith 
1910*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDiagonalScale_SeqDense(Mat A, Vec ll, Vec rr)
1911*d71ae5a4SJacob Faibussowitsch {
1912c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1913f1ceaac6SMatthew G. Knepley   const PetscScalar *l, *r;
1914ca15aa20SStefano Zampini   PetscScalar        x, *v, *vv;
1915d0f46423SBarry Smith   PetscInt           i, j, m = A->rmap->n, n = A->cmap->n;
191655659b69SBarry Smith 
19173a40ed3dSBarry Smith   PetscFunctionBegin;
19189566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &vv));
191928988994SBarry Smith   if (ll) {
19209566063dSJacob Faibussowitsch     PetscCall(VecGetSize(ll, &m));
19219566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ll, &l));
192208401ef6SPierre Jolivet     PetscCheck(m == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Left scaling vec wrong size");
1923da3a660dSBarry Smith     for (i = 0; i < m; i++) {
1924da3a660dSBarry Smith       x = l[i];
1925ca15aa20SStefano Zampini       v = vv + i;
19269371c9d4SSatish Balay       for (j = 0; j < n; j++) {
19279371c9d4SSatish Balay         (*v) *= x;
19289371c9d4SSatish Balay         v += mat->lda;
19299371c9d4SSatish Balay       }
1930da3a660dSBarry Smith     }
19319566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ll, &l));
19329566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0 * n * m));
1933da3a660dSBarry Smith   }
193428988994SBarry Smith   if (rr) {
19359566063dSJacob Faibussowitsch     PetscCall(VecGetSize(rr, &n));
19369566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(rr, &r));
193708401ef6SPierre Jolivet     PetscCheck(n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Right scaling vec wrong size");
1938da3a660dSBarry Smith     for (i = 0; i < n; i++) {
1939da3a660dSBarry Smith       x = r[i];
1940ca15aa20SStefano Zampini       v = vv + i * mat->lda;
19412205254eSKarl Rupp       for (j = 0; j < m; j++) (*v++) *= x;
1942da3a660dSBarry Smith     }
19439566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(rr, &r));
19449566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0 * n * m));
1945da3a660dSBarry Smith   }
19469566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &vv));
19473a40ed3dSBarry Smith   PetscFunctionReturn(0);
1948289bc588SBarry Smith }
1949289bc588SBarry Smith 
1950*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatNorm_SeqDense(Mat A, NormType type, PetscReal *nrm)
1951*d71ae5a4SJacob Faibussowitsch {
1952c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
1953ca15aa20SStefano Zampini   PetscScalar  *v, *vv;
1954329f5518SBarry Smith   PetscReal     sum = 0.0;
195575f6d85dSStefano Zampini   PetscInt      lda, m = A->rmap->n, i, j;
195655659b69SBarry Smith 
19573a40ed3dSBarry Smith   PetscFunctionBegin;
19589566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&vv));
19599566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(A, &lda));
1960ca15aa20SStefano Zampini   v = vv;
1961289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1962a5ce6ee0Svictorle     if (lda > m) {
1963d0f46423SBarry Smith       for (j = 0; j < A->cmap->n; j++) {
1964ca15aa20SStefano Zampini         v = vv + j * lda;
1965a5ce6ee0Svictorle         for (i = 0; i < m; i++) {
19669371c9d4SSatish Balay           sum += PetscRealPart(PetscConj(*v) * (*v));
19679371c9d4SSatish Balay           v++;
1968a5ce6ee0Svictorle         }
1969a5ce6ee0Svictorle       }
1970a5ce6ee0Svictorle     } else {
1971570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1972570b7f6dSBarry Smith       PetscBLASInt one = 1, cnt = A->cmap->n * A->rmap->n;
1973792fecdfSBarry Smith       PetscCallBLAS("BLASnrm2", *nrm = BLASnrm2_(&cnt, v, &one));
1974570b7f6dSBarry Smith     }
1975570b7f6dSBarry Smith #else
1976d0f46423SBarry Smith       for (i = 0; i < A->cmap->n * A->rmap->n; i++) {
19779371c9d4SSatish Balay         sum += PetscRealPart(PetscConj(*v) * (*v));
19789371c9d4SSatish Balay         v++;
1979289bc588SBarry Smith       }
1980a5ce6ee0Svictorle     }
19818f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1982570b7f6dSBarry Smith #endif
19839566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0 * A->cmap->n * A->rmap->n));
19843a40ed3dSBarry Smith   } else if (type == NORM_1) {
1985064f8208SBarry Smith     *nrm = 0.0;
1986d0f46423SBarry Smith     for (j = 0; j < A->cmap->n; j++) {
1987ca15aa20SStefano Zampini       v   = vv + j * mat->lda;
1988289bc588SBarry Smith       sum = 0.0;
1989d0f46423SBarry Smith       for (i = 0; i < A->rmap->n; i++) {
19909371c9d4SSatish Balay         sum += PetscAbsScalar(*v);
19919371c9d4SSatish Balay         v++;
1992289bc588SBarry Smith       }
1993064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1994289bc588SBarry Smith     }
19959566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n));
19963a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1997064f8208SBarry Smith     *nrm = 0.0;
1998d0f46423SBarry Smith     for (j = 0; j < A->rmap->n; j++) {
1999ca15aa20SStefano Zampini       v   = vv + j;
2000289bc588SBarry Smith       sum = 0.0;
2001d0f46423SBarry Smith       for (i = 0; i < A->cmap->n; i++) {
20029371c9d4SSatish Balay         sum += PetscAbsScalar(*v);
20039371c9d4SSatish Balay         v += mat->lda;
2004289bc588SBarry Smith       }
2005064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
2006289bc588SBarry Smith     }
20079566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n));
2008e7e72b3dSBarry Smith   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "No two norm");
20099566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&vv));
20103a40ed3dSBarry Smith   PetscFunctionReturn(0);
2011289bc588SBarry Smith }
2012289bc588SBarry Smith 
2013*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetOption_SeqDense(Mat A, MatOption op, PetscBool flg)
2014*d71ae5a4SJacob Faibussowitsch {
2015c0bbcb79SLois Curfman McInnes   Mat_SeqDense *aij = (Mat_SeqDense *)A->data;
201667e560aaSBarry Smith 
20173a40ed3dSBarry Smith   PetscFunctionBegin;
2018b5a2b587SKris Buschelman   switch (op) {
2019*d71ae5a4SJacob Faibussowitsch   case MAT_ROW_ORIENTED:
2020*d71ae5a4SJacob Faibussowitsch     aij->roworiented = flg;
2021*d71ae5a4SJacob Faibussowitsch     break;
2022512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
2023b5a2b587SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
20243971808eSMatthew Knepley   case MAT_NEW_NONZERO_ALLOCATION_ERR:
20258c78258cSHong Zhang   case MAT_FORCE_DIAGONAL_ENTRIES:
202613fa8e87SLisandro Dalcin   case MAT_KEEP_NONZERO_PATTERN:
2027b5a2b587SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
2028b5a2b587SKris Buschelman   case MAT_USE_HASH_TABLE:
20290f8fb01aSBarry Smith   case MAT_IGNORE_ZERO_ENTRIES:
20305021d80fSJed Brown   case MAT_IGNORE_LOWER_TRIANGULAR:
2031*d71ae5a4SJacob Faibussowitsch   case MAT_SORTED_FULL:
2032*d71ae5a4SJacob Faibussowitsch     PetscCall(PetscInfo(A, "Option %s ignored\n", MatOptions[op]));
2033*d71ae5a4SJacob Faibussowitsch     break;
20345021d80fSJed Brown   case MAT_SPD:
203577e54ba9SKris Buschelman   case MAT_SYMMETRIC:
203677e54ba9SKris Buschelman   case MAT_STRUCTURALLY_SYMMETRIC:
20379a4540c5SBarry Smith   case MAT_HERMITIAN:
20389a4540c5SBarry Smith   case MAT_SYMMETRY_ETERNAL:
2039b94d7dedSBarry Smith   case MAT_STRUCTURAL_SYMMETRY_ETERNAL:
2040*d71ae5a4SJacob Faibussowitsch   case MAT_SPD_ETERNAL:
2041*d71ae5a4SJacob Faibussowitsch     break;
2042*d71ae5a4SJacob Faibussowitsch   default:
2043*d71ae5a4SJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "unknown option %s", MatOptions[op]);
20443a40ed3dSBarry Smith   }
20453a40ed3dSBarry Smith   PetscFunctionReturn(0);
2046289bc588SBarry Smith }
2047289bc588SBarry Smith 
2048*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatZeroEntries_SeqDense(Mat A)
2049*d71ae5a4SJacob Faibussowitsch {
2050ec8511deSBarry Smith   Mat_SeqDense *l   = (Mat_SeqDense *)A->data;
20513d8925e7SStefano Zampini   PetscInt      lda = l->lda, m = A->rmap->n, n = A->cmap->n, j;
2052ca15aa20SStefano Zampini   PetscScalar  *v;
20533a40ed3dSBarry Smith 
20543a40ed3dSBarry Smith   PetscFunctionBegin;
20559566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(A, &v));
2056a5ce6ee0Svictorle   if (lda > m) {
205748a46eb9SPierre Jolivet     for (j = 0; j < n; j++) PetscCall(PetscArrayzero(v + j * lda, m));
2058a5ce6ee0Svictorle   } else {
20599566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(v, PetscInt64Mult(m, n)));
2060a5ce6ee0Svictorle   }
20619566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(A, &v));
20623a40ed3dSBarry Smith   PetscFunctionReturn(0);
20636f0a148fSBarry Smith }
20646f0a148fSBarry Smith 
2065*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatZeroRows_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b)
2066*d71ae5a4SJacob Faibussowitsch {
2067ec8511deSBarry Smith   Mat_SeqDense      *l = (Mat_SeqDense *)A->data;
2068b9679d65SBarry Smith   PetscInt           m = l->lda, n = A->cmap->n, i, j;
2069ca15aa20SStefano Zampini   PetscScalar       *slot, *bb, *v;
207097b48c8fSBarry Smith   const PetscScalar *xx;
207155659b69SBarry Smith 
20723a40ed3dSBarry Smith   PetscFunctionBegin;
207376bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
2074b9679d65SBarry Smith     for (i = 0; i < N; i++) {
207508401ef6SPierre Jolivet       PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed");
207608401ef6SPierre 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);
2077b9679d65SBarry Smith     }
207876bd3646SJed Brown   }
2079ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
2080b9679d65SBarry Smith 
208197b48c8fSBarry Smith   /* fix right hand side if needed */
208297b48c8fSBarry Smith   if (x && b) {
20839566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(x, &xx));
20849566063dSJacob Faibussowitsch     PetscCall(VecGetArray(b, &bb));
20852205254eSKarl Rupp     for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]];
20869566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(x, &xx));
20879566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(b, &bb));
208897b48c8fSBarry Smith   }
208997b48c8fSBarry Smith 
20909566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
20916f0a148fSBarry Smith   for (i = 0; i < N; i++) {
2092ca15aa20SStefano Zampini     slot = v + rows[i];
20939371c9d4SSatish Balay     for (j = 0; j < n; j++) {
20949371c9d4SSatish Balay       *slot = 0.0;
20959371c9d4SSatish Balay       slot += m;
20969371c9d4SSatish Balay     }
20976f0a148fSBarry Smith   }
2098f4df32b1SMatthew Knepley   if (diag != 0.0) {
209908401ef6SPierre Jolivet     PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices");
21006f0a148fSBarry Smith     for (i = 0; i < N; i++) {
2101ca15aa20SStefano Zampini       slot  = v + (m + 1) * rows[i];
2102f4df32b1SMatthew Knepley       *slot = diag;
21036f0a148fSBarry Smith     }
21046f0a148fSBarry Smith   }
21059566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
21063a40ed3dSBarry Smith   PetscFunctionReturn(0);
21076f0a148fSBarry Smith }
2108557bce09SLois Curfman McInnes 
2109*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A, PetscInt *lda)
2110*d71ae5a4SJacob Faibussowitsch {
211149a6ff4bSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
211249a6ff4bSBarry Smith 
211349a6ff4bSBarry Smith   PetscFunctionBegin;
211449a6ff4bSBarry Smith   *lda = mat->lda;
211549a6ff4bSBarry Smith   PetscFunctionReturn(0);
211649a6ff4bSBarry Smith }
211749a6ff4bSBarry Smith 
2118*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArray_SeqDense(Mat A, PetscScalar **array)
2119*d71ae5a4SJacob Faibussowitsch {
2120c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
21213a40ed3dSBarry Smith 
21223a40ed3dSBarry Smith   PetscFunctionBegin;
212328b400f6SJacob Faibussowitsch   PetscCheck(!mat->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
212464e87e97SBarry Smith   *array = mat->v;
21253a40ed3dSBarry Smith   PetscFunctionReturn(0);
212664e87e97SBarry Smith }
21270754003eSLois Curfman McInnes 
2128*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A, PetscScalar **array)
2129*d71ae5a4SJacob Faibussowitsch {
21303a40ed3dSBarry Smith   PetscFunctionBegin;
213175f6d85dSStefano Zampini   if (array) *array = NULL;
21323a40ed3dSBarry Smith   PetscFunctionReturn(0);
2133ff14e315SSatish Balay }
21340754003eSLois Curfman McInnes 
21350f74d2c1SSatish Balay /*@
213611a5261eSBarry Smith    MatDenseGetLDA - gets the leading dimension of the array returned from `MatDenseGetArray()`
213749a6ff4bSBarry Smith 
2138ad16ce7aSStefano Zampini    Not collective
213949a6ff4bSBarry Smith 
214049a6ff4bSBarry Smith    Input Parameter:
214111a5261eSBarry Smith .  mat - a `MATDENSE` or `MATDENSECUDA` matrix
214249a6ff4bSBarry Smith 
214349a6ff4bSBarry Smith    Output Parameter:
214449a6ff4bSBarry Smith .   lda - the leading dimension
214549a6ff4bSBarry Smith 
214649a6ff4bSBarry Smith    Level: intermediate
214749a6ff4bSBarry Smith 
214811a5261eSBarry Smith .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseSetLDA()`
214949a6ff4bSBarry Smith @*/
2150*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetLDA(Mat A, PetscInt *lda)
2151*d71ae5a4SJacob Faibussowitsch {
215249a6ff4bSBarry Smith   PetscFunctionBegin;
2153d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2154dadcf809SJacob Faibussowitsch   PetscValidIntPointer(lda, 2);
215575f6d85dSStefano Zampini   MatCheckPreallocated(A, 1);
2156cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetLDA_C", (Mat, PetscInt *), (A, lda));
215749a6ff4bSBarry Smith   PetscFunctionReturn(0);
215849a6ff4bSBarry Smith }
215949a6ff4bSBarry Smith 
21600f74d2c1SSatish Balay /*@
216111a5261eSBarry Smith    MatDenseSetLDA - Sets the leading dimension of the array used by the `MATDENSE` matrix
2162ad16ce7aSStefano Zampini 
2163ad16ce7aSStefano Zampini    Not collective
2164ad16ce7aSStefano Zampini 
2165d8d19677SJose E. Roman    Input Parameters:
216611a5261eSBarry Smith +  mat - a `MATDENSE` or `MATDENSECUDA` matrix
2167ad16ce7aSStefano Zampini -  lda - the leading dimension
2168ad16ce7aSStefano Zampini 
2169ad16ce7aSStefano Zampini    Level: intermediate
2170ad16ce7aSStefano Zampini 
217111a5261eSBarry Smith .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetLDA()`
2172ad16ce7aSStefano Zampini @*/
2173*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA(Mat A, PetscInt lda)
2174*d71ae5a4SJacob Faibussowitsch {
2175ad16ce7aSStefano Zampini   PetscFunctionBegin;
2176ad16ce7aSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2177cac4c232SBarry Smith   PetscTryMethod(A, "MatDenseSetLDA_C", (Mat, PetscInt), (A, lda));
2178ad16ce7aSStefano Zampini   PetscFunctionReturn(0);
2179ad16ce7aSStefano Zampini }
2180ad16ce7aSStefano Zampini 
2181ad16ce7aSStefano Zampini /*@C
218211a5261eSBarry Smith    MatDenseGetArray - gives read-write access to the array where the data for a `MATDENSE` matrix is stored
218373a71a0fSBarry Smith 
218411a5261eSBarry Smith    Logically Collective on A
218573a71a0fSBarry Smith 
218673a71a0fSBarry Smith    Input Parameter:
21876947451fSStefano Zampini .  mat - a dense matrix
218873a71a0fSBarry Smith 
218973a71a0fSBarry Smith    Output Parameter:
219073a71a0fSBarry Smith .   array - pointer to the data
219173a71a0fSBarry Smith 
219273a71a0fSBarry Smith    Level: intermediate
219373a71a0fSBarry Smith 
219411a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
219573a71a0fSBarry Smith @*/
2196*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArray(Mat A, PetscScalar **array)
2197*d71ae5a4SJacob Faibussowitsch {
219873a71a0fSBarry Smith   PetscFunctionBegin;
2199d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2200d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2201cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array));
220273a71a0fSBarry Smith   PetscFunctionReturn(0);
220373a71a0fSBarry Smith }
220473a71a0fSBarry Smith 
2205dec5eb66SMatthew G Knepley /*@C
220611a5261eSBarry Smith    MatDenseRestoreArray - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArray()`
220773a71a0fSBarry Smith 
220811a5261eSBarry Smith    Logically Collective on A
22098572280aSBarry Smith 
22108572280aSBarry Smith    Input Parameters:
22116947451fSStefano Zampini +  mat - a dense matrix
2212742765d3SMatthew Knepley -  array - pointer to the data (may be NULL)
22138572280aSBarry Smith 
22148572280aSBarry Smith    Level: intermediate
22158572280aSBarry Smith 
221611a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
22178572280aSBarry Smith @*/
2218*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArray(Mat A, PetscScalar **array)
2219*d71ae5a4SJacob Faibussowitsch {
22208572280aSBarry Smith   PetscFunctionBegin;
2221d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2222d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2223cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array));
22249566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)A));
2225637a0070SStefano Zampini #if defined(PETSC_HAVE_CUDA)
2226637a0070SStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
2227637a0070SStefano Zampini #endif
22288572280aSBarry Smith   PetscFunctionReturn(0);
22298572280aSBarry Smith }
22308572280aSBarry Smith 
22318572280aSBarry Smith /*@C
223211a5261eSBarry Smith   MatDenseGetArrayRead - gives read-only access to the array where the data for a `MATDENSE`  matrix is stored
22338572280aSBarry Smith 
22348572280aSBarry Smith    Not Collective
22358572280aSBarry Smith 
22368572280aSBarry Smith    Input Parameter:
22376947451fSStefano Zampini .  mat - a dense matrix
22388572280aSBarry Smith 
22398572280aSBarry Smith    Output Parameter:
22408572280aSBarry Smith .   array - pointer to the data
22418572280aSBarry Smith 
22428572280aSBarry Smith    Level: intermediate
22438572280aSBarry Smith 
224411a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
22458572280aSBarry Smith @*/
2246*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArrayRead(Mat A, const PetscScalar **array)
2247*d71ae5a4SJacob Faibussowitsch {
22488572280aSBarry Smith   PetscFunctionBegin;
2249d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2250d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2251cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, const PetscScalar **), (A, array));
22528572280aSBarry Smith   PetscFunctionReturn(0);
22538572280aSBarry Smith }
22548572280aSBarry Smith 
22558572280aSBarry Smith /*@C
225611a5261eSBarry Smith    MatDenseRestoreArrayRead - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayRead()`
22578572280aSBarry Smith 
225873a71a0fSBarry Smith    Not Collective
225973a71a0fSBarry Smith 
226073a71a0fSBarry Smith    Input Parameters:
22616947451fSStefano Zampini +  mat - a dense matrix
2262742765d3SMatthew Knepley -  array - pointer to the data (may be NULL)
226373a71a0fSBarry Smith 
226473a71a0fSBarry Smith    Level: intermediate
226573a71a0fSBarry Smith 
226611a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
226773a71a0fSBarry Smith @*/
2268*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArrayRead(Mat A, const PetscScalar **array)
2269*d71ae5a4SJacob Faibussowitsch {
227073a71a0fSBarry Smith   PetscFunctionBegin;
2271d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2272d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2273cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, const PetscScalar **), (A, array));
227473a71a0fSBarry Smith   PetscFunctionReturn(0);
227573a71a0fSBarry Smith }
227673a71a0fSBarry Smith 
22776947451fSStefano Zampini /*@C
227811a5261eSBarry Smith    MatDenseGetArrayWrite - gives write-only access to the array where the data for a `MATDENSE` matrix is stored
22796947451fSStefano Zampini 
22806947451fSStefano Zampini    Not Collective
22816947451fSStefano Zampini 
22826947451fSStefano Zampini    Input Parameter:
22836947451fSStefano Zampini .  mat - a dense matrix
22846947451fSStefano Zampini 
22856947451fSStefano Zampini    Output Parameter:
22866947451fSStefano Zampini .   array - pointer to the data
22876947451fSStefano Zampini 
22886947451fSStefano Zampini    Level: intermediate
22896947451fSStefano Zampini 
229011a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`
22916947451fSStefano Zampini @*/
2292*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArrayWrite(Mat A, PetscScalar **array)
2293*d71ae5a4SJacob Faibussowitsch {
22946947451fSStefano Zampini   PetscFunctionBegin;
2295d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2296d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2297cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array));
22986947451fSStefano Zampini   PetscFunctionReturn(0);
22996947451fSStefano Zampini }
23006947451fSStefano Zampini 
23016947451fSStefano Zampini /*@C
230211a5261eSBarry Smith    MatDenseRestoreArrayWrite - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayWrite()`
23036947451fSStefano Zampini 
23046947451fSStefano Zampini    Not Collective
23056947451fSStefano Zampini 
23066947451fSStefano Zampini    Input Parameters:
23076947451fSStefano Zampini +  mat - a dense matrix
2308742765d3SMatthew Knepley -  array - pointer to the data (may be NULL)
23096947451fSStefano Zampini 
23106947451fSStefano Zampini    Level: intermediate
23116947451fSStefano Zampini 
231211a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`
23136947451fSStefano Zampini @*/
2314*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArrayWrite(Mat A, PetscScalar **array)
2315*d71ae5a4SJacob Faibussowitsch {
23166947451fSStefano Zampini   PetscFunctionBegin;
2317d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2318d5ea218eSStefano Zampini   PetscValidPointer(array, 2);
2319cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array));
23209566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)A));
23216947451fSStefano Zampini #if defined(PETSC_HAVE_CUDA)
23226947451fSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
23236947451fSStefano Zampini #endif
23246947451fSStefano Zampini   PetscFunctionReturn(0);
23256947451fSStefano Zampini }
23266947451fSStefano Zampini 
2327*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A, IS isrow, IS iscol, MatReuse scall, Mat *B)
2328*d71ae5a4SJacob Faibussowitsch {
2329c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense *)A->data;
2330bf5a80bcSToby Isaac   PetscInt        i, j, nrows, ncols, ldb;
23315d0c19d7SBarry Smith   const PetscInt *irow, *icol;
233287828ca2SBarry Smith   PetscScalar    *av, *bv, *v = mat->v;
23330754003eSLois Curfman McInnes   Mat             newmat;
23340754003eSLois Curfman McInnes 
23353a40ed3dSBarry Smith   PetscFunctionBegin;
23369566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(isrow, &irow));
23379566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(iscol, &icol));
23389566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(isrow, &nrows));
23399566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(iscol, &ncols));
23400754003eSLois Curfman McInnes 
2341182d2002SSatish Balay   /* Check submatrixcall */
2342182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
234313f74950SBarry Smith     PetscInt n_cols, n_rows;
23449566063dSJacob Faibussowitsch     PetscCall(MatGetSize(*B, &n_rows, &n_cols));
234521a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
2346f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
23479566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(*B, nrows, ncols, nrows, ncols));
234821a2c019SBarry Smith     }
2349182d2002SSatish Balay     newmat = *B;
2350182d2002SSatish Balay   } else {
23510754003eSLois Curfman McInnes     /* Create and fill new matrix */
23529566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &newmat));
23539566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(newmat, nrows, ncols, nrows, ncols));
23549566063dSJacob Faibussowitsch     PetscCall(MatSetType(newmat, ((PetscObject)A)->type_name));
23559566063dSJacob Faibussowitsch     PetscCall(MatSeqDenseSetPreallocation(newmat, NULL));
2356182d2002SSatish Balay   }
2357182d2002SSatish Balay 
2358182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
23599566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(newmat, &bv));
23609566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(newmat, &ldb));
2361182d2002SSatish Balay   for (i = 0; i < ncols; i++) {
23626de62eeeSBarry Smith     av = v + mat->lda * icol[i];
2363ca15aa20SStefano Zampini     for (j = 0; j < nrows; j++) bv[j] = av[irow[j]];
2364bf5a80bcSToby Isaac     bv += ldb;
23650754003eSLois Curfman McInnes   }
23669566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(newmat, &bv));
2367182d2002SSatish Balay 
2368182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
23699566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(newmat, MAT_FINAL_ASSEMBLY));
23709566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(newmat, MAT_FINAL_ASSEMBLY));
23710754003eSLois Curfman McInnes 
23720754003eSLois Curfman McInnes   /* Free work space */
23739566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(isrow, &irow));
23749566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(iscol, &icol));
2375182d2002SSatish Balay   *B = newmat;
23763a40ed3dSBarry Smith   PetscFunctionReturn(0);
23770754003eSLois Curfman McInnes }
23780754003eSLois Curfman McInnes 
2379*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A, PetscInt n, const IS irow[], const IS icol[], MatReuse scall, Mat *B[])
2380*d71ae5a4SJacob Faibussowitsch {
238113f74950SBarry Smith   PetscInt i;
2382905e6a2fSBarry Smith 
23833a40ed3dSBarry Smith   PetscFunctionBegin;
238448a46eb9SPierre Jolivet   if (scall == MAT_INITIAL_MATRIX) PetscCall(PetscCalloc1(n, B));
2385905e6a2fSBarry Smith 
238648a46eb9SPierre Jolivet   for (i = 0; i < n; i++) PetscCall(MatCreateSubMatrix_SeqDense(A, irow[i], icol[i], scall, &(*B)[i]));
23873a40ed3dSBarry Smith   PetscFunctionReturn(0);
2388905e6a2fSBarry Smith }
2389905e6a2fSBarry Smith 
2390*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat, MatAssemblyType mode)
2391*d71ae5a4SJacob Faibussowitsch {
2392c0aa2d19SHong Zhang   PetscFunctionBegin;
2393c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2394c0aa2d19SHong Zhang }
2395c0aa2d19SHong Zhang 
2396*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat, MatAssemblyType mode)
2397*d71ae5a4SJacob Faibussowitsch {
2398c0aa2d19SHong Zhang   PetscFunctionBegin;
2399c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2400c0aa2d19SHong Zhang }
2401c0aa2d19SHong Zhang 
2402*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCopy_SeqDense(Mat A, Mat B, MatStructure str)
2403*d71ae5a4SJacob Faibussowitsch {
24044b0e389bSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data;
2405ca15aa20SStefano Zampini   const PetscScalar *va;
2406ca15aa20SStefano Zampini   PetscScalar       *vb;
2407d0f46423SBarry Smith   PetscInt           lda1 = a->lda, lda2 = b->lda, m = A->rmap->n, n = A->cmap->n, j;
24083a40ed3dSBarry Smith 
24093a40ed3dSBarry Smith   PetscFunctionBegin;
241033f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
241133f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
24129566063dSJacob Faibussowitsch     PetscCall(MatCopy_Basic(A, B, str));
24133a40ed3dSBarry Smith     PetscFunctionReturn(0);
24143a40ed3dSBarry Smith   }
2415aed4548fSBarry Smith   PetscCheck(m == B->rmap->n && n == B->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "size(B) != size(A)");
24169566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &va));
24179566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(B, &vb));
2418a5ce6ee0Svictorle   if (lda1 > m || lda2 > m) {
241948a46eb9SPierre Jolivet     for (j = 0; j < n; j++) PetscCall(PetscArraycpy(vb + j * lda2, va + j * lda1, m));
2420a5ce6ee0Svictorle   } else {
24219566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(vb, va, A->rmap->n * A->cmap->n));
2422a5ce6ee0Svictorle   }
24239566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(B, &vb));
24249566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &va));
24259566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY));
24269566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY));
2427273d9f13SBarry Smith   PetscFunctionReturn(0);
2428273d9f13SBarry Smith }
2429273d9f13SBarry Smith 
2430*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetUp_SeqDense(Mat A)
2431*d71ae5a4SJacob Faibussowitsch {
2432273d9f13SBarry Smith   PetscFunctionBegin;
24339566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(A->rmap));
24349566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(A->cmap));
243548a46eb9SPierre Jolivet   if (!A->preallocated) PetscCall(MatSeqDenseSetPreallocation(A, NULL));
24363a40ed3dSBarry Smith   PetscFunctionReturn(0);
24374b0e389bSBarry Smith }
24384b0e389bSBarry Smith 
2439*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatConjugate_SeqDense(Mat A)
2440*d71ae5a4SJacob Faibussowitsch {
24414396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
244206c5243aSJose E. Roman   PetscInt      i, j;
24434396437dSToby Isaac   PetscInt      min = PetscMin(A->rmap->n, A->cmap->n);
2444ca15aa20SStefano Zampini   PetscScalar  *aa;
2445ba337c44SJed Brown 
2446ba337c44SJed Brown   PetscFunctionBegin;
24479566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &aa));
244806c5243aSJose E. Roman   for (j = 0; j < A->cmap->n; j++) {
244906c5243aSJose E. Roman     for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscConj(aa[i + j * mat->lda]);
245006c5243aSJose E. Roman   }
24519566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &aa));
24529371c9d4SSatish Balay   if (mat->tau)
24539371c9d4SSatish Balay     for (i = 0; i < min; i++) mat->tau[i] = PetscConj(mat->tau[i]);
2454ba337c44SJed Brown   PetscFunctionReturn(0);
2455ba337c44SJed Brown }
2456ba337c44SJed Brown 
2457*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRealPart_SeqDense(Mat A)
2458*d71ae5a4SJacob Faibussowitsch {
245906c5243aSJose E. Roman   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
246006c5243aSJose E. Roman   PetscInt      i, j;
2461ca15aa20SStefano Zampini   PetscScalar  *aa;
2462ba337c44SJed Brown 
2463ba337c44SJed Brown   PetscFunctionBegin;
24649566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &aa));
246506c5243aSJose E. Roman   for (j = 0; j < A->cmap->n; j++) {
246606c5243aSJose E. Roman     for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscRealPart(aa[i + j * mat->lda]);
246706c5243aSJose E. Roman   }
24689566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &aa));
2469ba337c44SJed Brown   PetscFunctionReturn(0);
2470ba337c44SJed Brown }
2471ba337c44SJed Brown 
2472*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatImaginaryPart_SeqDense(Mat A)
2473*d71ae5a4SJacob Faibussowitsch {
247406c5243aSJose E. Roman   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
247506c5243aSJose E. Roman   PetscInt      i, j;
2476ca15aa20SStefano Zampini   PetscScalar  *aa;
2477ba337c44SJed Brown 
2478ba337c44SJed Brown   PetscFunctionBegin;
24799566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &aa));
248006c5243aSJose E. Roman   for (j = 0; j < A->cmap->n; j++) {
248106c5243aSJose E. Roman     for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscImaginaryPart(aa[i + j * mat->lda]);
248206c5243aSJose E. Roman   }
24839566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &aa));
2484ba337c44SJed Brown   PetscFunctionReturn(0);
2485ba337c44SJed Brown }
2486284134d9SBarry Smith 
2487a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/
2488*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C)
2489*d71ae5a4SJacob Faibussowitsch {
2490d0f46423SBarry Smith   PetscInt  m = A->rmap->n, n = B->cmap->n;
24917a3c3d58SStefano Zampini   PetscBool cisdense;
2492a9fe9ddaSSatish Balay 
2493ee16a9a1SHong Zhang   PetscFunctionBegin;
24949566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C, m, n, m, n));
24959566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, ""));
24967a3c3d58SStefano Zampini   if (!cisdense) {
24977a3c3d58SStefano Zampini     PetscBool flg;
24987a3c3d58SStefano Zampini 
24999566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg));
25009566063dSJacob Faibussowitsch     PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE));
25017a3c3d58SStefano Zampini   }
25029566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
2503ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2504ee16a9a1SHong Zhang }
2505a9fe9ddaSSatish Balay 
2506*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C)
2507*d71ae5a4SJacob Faibussowitsch {
25086718818eSStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data, *c = (Mat_SeqDense *)C->data;
25090805154bSBarry Smith   PetscBLASInt       m, n, k;
2510ca15aa20SStefano Zampini   const PetscScalar *av, *bv;
2511ca15aa20SStefano Zampini   PetscScalar       *cv;
2512a9fe9ddaSSatish Balay   PetscScalar        _DOne = 1.0, _DZero = 0.0;
2513a9fe9ddaSSatish Balay 
2514a9fe9ddaSSatish Balay   PetscFunctionBegin;
25159566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n, &m));
25169566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n, &n));
25179566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &k));
251849d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
25199566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &av));
25209566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B, &bv));
25219566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C, &cv));
2522792fecdfSBarry Smith   PetscCallBLAS("BLASgemm", BLASgemm_("N", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda));
25239566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1)));
25249566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &av));
25259566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B, &bv));
25269566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C, &cv));
2527a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2528a9fe9ddaSSatish Balay }
2529a9fe9ddaSSatish Balay 
2530*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C)
2531*d71ae5a4SJacob Faibussowitsch {
253269f65d41SStefano Zampini   PetscInt  m = A->rmap->n, n = B->rmap->n;
25337a3c3d58SStefano Zampini   PetscBool cisdense;
253469f65d41SStefano Zampini 
253569f65d41SStefano Zampini   PetscFunctionBegin;
25369566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C, m, n, m, n));
25379566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, ""));
25387a3c3d58SStefano Zampini   if (!cisdense) {
25397a3c3d58SStefano Zampini     PetscBool flg;
25407a3c3d58SStefano Zampini 
25419566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg));
25429566063dSJacob Faibussowitsch     PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE));
25437a3c3d58SStefano Zampini   }
25449566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
254569f65d41SStefano Zampini   PetscFunctionReturn(0);
254669f65d41SStefano Zampini }
254769f65d41SStefano Zampini 
2548*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C)
2549*d71ae5a4SJacob Faibussowitsch {
255069f65d41SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
255169f65d41SStefano Zampini   Mat_SeqDense      *b = (Mat_SeqDense *)B->data;
255269f65d41SStefano Zampini   Mat_SeqDense      *c = (Mat_SeqDense *)C->data;
25536718818eSStefano Zampini   const PetscScalar *av, *bv;
25546718818eSStefano Zampini   PetscScalar       *cv;
255569f65d41SStefano Zampini   PetscBLASInt       m, n, k;
255669f65d41SStefano Zampini   PetscScalar        _DOne = 1.0, _DZero = 0.0;
255769f65d41SStefano Zampini 
255869f65d41SStefano Zampini   PetscFunctionBegin;
25599566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n, &m));
25609566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n, &n));
25619566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &k));
256249d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
25639566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &av));
25649566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B, &bv));
25659566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C, &cv));
2566792fecdfSBarry Smith   PetscCallBLAS("BLASgemm", BLASgemm_("N", "T", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda));
25679566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &av));
25689566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B, &bv));
25699566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C, &cv));
25709566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1)));
257169f65d41SStefano Zampini   PetscFunctionReturn(0);
257269f65d41SStefano Zampini }
257369f65d41SStefano Zampini 
2574*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C)
2575*d71ae5a4SJacob Faibussowitsch {
2576d0f46423SBarry Smith   PetscInt  m = A->cmap->n, n = B->cmap->n;
25777a3c3d58SStefano Zampini   PetscBool cisdense;
2578a9fe9ddaSSatish Balay 
2579ee16a9a1SHong Zhang   PetscFunctionBegin;
25809566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C, m, n, m, n));
25819566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, ""));
25827a3c3d58SStefano Zampini   if (!cisdense) {
25837a3c3d58SStefano Zampini     PetscBool flg;
25847a3c3d58SStefano Zampini 
25859566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg));
25869566063dSJacob Faibussowitsch     PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE));
25877a3c3d58SStefano Zampini   }
25889566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
2589ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2590ee16a9a1SHong Zhang }
2591a9fe9ddaSSatish Balay 
2592*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C)
2593*d71ae5a4SJacob Faibussowitsch {
2594a9fe9ddaSSatish Balay   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
2595a9fe9ddaSSatish Balay   Mat_SeqDense      *b = (Mat_SeqDense *)B->data;
2596a9fe9ddaSSatish Balay   Mat_SeqDense      *c = (Mat_SeqDense *)C->data;
25976718818eSStefano Zampini   const PetscScalar *av, *bv;
25986718818eSStefano Zampini   PetscScalar       *cv;
25990805154bSBarry Smith   PetscBLASInt       m, n, k;
2600a9fe9ddaSSatish Balay   PetscScalar        _DOne = 1.0, _DZero = 0.0;
2601a9fe9ddaSSatish Balay 
2602a9fe9ddaSSatish Balay   PetscFunctionBegin;
26039566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n, &m));
26049566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n, &n));
26059566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &k));
260649d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
26079566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &av));
26089566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B, &bv));
26099566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C, &cv));
2610792fecdfSBarry Smith   PetscCallBLAS("BLASgemm", BLASgemm_("T", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda));
26119566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &av));
26129566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B, &bv));
26139566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C, &cv));
26149566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1)));
2615a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2616a9fe9ddaSSatish Balay }
2617985db425SBarry Smith 
26184222ddf1SHong Zhang /* ----------------------------------------------- */
2619*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C)
2620*d71ae5a4SJacob Faibussowitsch {
26214222ddf1SHong Zhang   PetscFunctionBegin;
26224222ddf1SHong Zhang   C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense;
26234222ddf1SHong Zhang   C->ops->productsymbolic = MatProductSymbolic_AB;
26244222ddf1SHong Zhang   PetscFunctionReturn(0);
26254222ddf1SHong Zhang }
26264222ddf1SHong Zhang 
2627*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C)
2628*d71ae5a4SJacob Faibussowitsch {
26294222ddf1SHong Zhang   PetscFunctionBegin;
26304222ddf1SHong Zhang   C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense;
26314222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_AtB;
26324222ddf1SHong Zhang   PetscFunctionReturn(0);
26334222ddf1SHong Zhang }
26344222ddf1SHong Zhang 
2635*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C)
2636*d71ae5a4SJacob Faibussowitsch {
26374222ddf1SHong Zhang   PetscFunctionBegin;
26384222ddf1SHong Zhang   C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense;
26394222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_ABt;
26404222ddf1SHong Zhang   PetscFunctionReturn(0);
26414222ddf1SHong Zhang }
26424222ddf1SHong Zhang 
2643*d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C)
2644*d71ae5a4SJacob Faibussowitsch {
26454222ddf1SHong Zhang   Mat_Product *product = C->product;
26464222ddf1SHong Zhang 
26474222ddf1SHong Zhang   PetscFunctionBegin;
26484222ddf1SHong Zhang   switch (product->type) {
2649*d71ae5a4SJacob Faibussowitsch   case MATPRODUCT_AB:
2650*d71ae5a4SJacob Faibussowitsch     PetscCall(MatProductSetFromOptions_SeqDense_AB(C));
2651*d71ae5a4SJacob Faibussowitsch     break;
2652*d71ae5a4SJacob Faibussowitsch   case MATPRODUCT_AtB:
2653*d71ae5a4SJacob Faibussowitsch     PetscCall(MatProductSetFromOptions_SeqDense_AtB(C));
2654*d71ae5a4SJacob Faibussowitsch     break;
2655*d71ae5a4SJacob Faibussowitsch   case MATPRODUCT_ABt:
2656*d71ae5a4SJacob Faibussowitsch     PetscCall(MatProductSetFromOptions_SeqDense_ABt(C));
2657*d71ae5a4SJacob Faibussowitsch     break;
2658*d71ae5a4SJacob Faibussowitsch   default:
2659*d71ae5a4SJacob Faibussowitsch     break;
26604222ddf1SHong Zhang   }
26614222ddf1SHong Zhang   PetscFunctionReturn(0);
26624222ddf1SHong Zhang }
26634222ddf1SHong Zhang /* ----------------------------------------------- */
26644222ddf1SHong Zhang 
2665*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMax_SeqDense(Mat A, Vec v, PetscInt idx[])
2666*d71ae5a4SJacob Faibussowitsch {
2667985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
2668d0f46423SBarry Smith   PetscInt           i, j, m = A->rmap->n, n = A->cmap->n, p;
2669985db425SBarry Smith   PetscScalar       *x;
2670ca15aa20SStefano Zampini   const PetscScalar *aa;
2671985db425SBarry Smith 
2672985db425SBarry Smith   PetscFunctionBegin;
267328b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
26749566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
26759566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v, &p));
26769566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
267708401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector");
2678985db425SBarry Smith   for (i = 0; i < m; i++) {
26799371c9d4SSatish Balay     x[i] = aa[i];
26809371c9d4SSatish Balay     if (idx) idx[i] = 0;
2681985db425SBarry Smith     for (j = 1; j < n; j++) {
26829371c9d4SSatish Balay       if (PetscRealPart(x[i]) < PetscRealPart(aa[i + a->lda * j])) {
26839371c9d4SSatish Balay         x[i] = aa[i + a->lda * j];
26849371c9d4SSatish Balay         if (idx) idx[i] = j;
26859371c9d4SSatish Balay       }
2686985db425SBarry Smith     }
2687985db425SBarry Smith   }
26889566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
26899566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
2690985db425SBarry Smith   PetscFunctionReturn(0);
2691985db425SBarry Smith }
2692985db425SBarry Smith 
2693*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A, Vec v, PetscInt idx[])
2694*d71ae5a4SJacob Faibussowitsch {
2695985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
2696d0f46423SBarry Smith   PetscInt           i, j, m = A->rmap->n, n = A->cmap->n, p;
2697985db425SBarry Smith   PetscScalar       *x;
2698985db425SBarry Smith   PetscReal          atmp;
2699ca15aa20SStefano Zampini   const PetscScalar *aa;
2700985db425SBarry Smith 
2701985db425SBarry Smith   PetscFunctionBegin;
270228b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
27039566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
27049566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v, &p));
27059566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
270608401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector");
2707985db425SBarry Smith   for (i = 0; i < m; i++) {
27089189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
2709985db425SBarry Smith     for (j = 1; j < n; j++) {
2710ca15aa20SStefano Zampini       atmp = PetscAbsScalar(aa[i + a->lda * j]);
27119371c9d4SSatish Balay       if (PetscAbsScalar(x[i]) < atmp) {
27129371c9d4SSatish Balay         x[i] = atmp;
27139371c9d4SSatish Balay         if (idx) idx[i] = j;
27149371c9d4SSatish Balay       }
2715985db425SBarry Smith     }
2716985db425SBarry Smith   }
27179566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
27189566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
2719985db425SBarry Smith   PetscFunctionReturn(0);
2720985db425SBarry Smith }
2721985db425SBarry Smith 
2722*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMin_SeqDense(Mat A, Vec v, PetscInt idx[])
2723*d71ae5a4SJacob Faibussowitsch {
2724985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
2725d0f46423SBarry Smith   PetscInt           i, j, m = A->rmap->n, n = A->cmap->n, p;
2726985db425SBarry Smith   PetscScalar       *x;
2727ca15aa20SStefano Zampini   const PetscScalar *aa;
2728985db425SBarry Smith 
2729985db425SBarry Smith   PetscFunctionBegin;
273028b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
27319566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
27329566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
27339566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v, &p));
273408401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector");
2735985db425SBarry Smith   for (i = 0; i < m; i++) {
27369371c9d4SSatish Balay     x[i] = aa[i];
27379371c9d4SSatish Balay     if (idx) idx[i] = 0;
2738985db425SBarry Smith     for (j = 1; j < n; j++) {
27399371c9d4SSatish Balay       if (PetscRealPart(x[i]) > PetscRealPart(aa[i + a->lda * j])) {
27409371c9d4SSatish Balay         x[i] = aa[i + a->lda * j];
27419371c9d4SSatish Balay         if (idx) idx[i] = j;
27429371c9d4SSatish Balay       }
2743985db425SBarry Smith     }
2744985db425SBarry Smith   }
27459566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
27469566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
2747985db425SBarry Smith   PetscFunctionReturn(0);
2748985db425SBarry Smith }
2749985db425SBarry Smith 
2750*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatGetColumnVector_SeqDense(Mat A, Vec v, PetscInt col)
2751*d71ae5a4SJacob Faibussowitsch {
27528d0534beSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
27538d0534beSBarry Smith   PetscScalar       *x;
2754ca15aa20SStefano Zampini   const PetscScalar *aa;
27558d0534beSBarry Smith 
27568d0534beSBarry Smith   PetscFunctionBegin;
275728b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
27589566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
27599566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
27609566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(x, aa + col * a->lda, A->rmap->n));
27619566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
27629566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
27638d0534beSBarry Smith   PetscFunctionReturn(0);
27648d0534beSBarry Smith }
27658d0534beSBarry Smith 
2766*d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatGetColumnReductions_SeqDense(Mat A, PetscInt type, PetscReal *reductions)
2767*d71ae5a4SJacob Faibussowitsch {
27680716a85fSBarry Smith   PetscInt           i, j, m, n;
27691683a169SBarry Smith   const PetscScalar *a;
27700716a85fSBarry Smith 
27710716a85fSBarry Smith   PetscFunctionBegin;
27729566063dSJacob Faibussowitsch   PetscCall(MatGetSize(A, &m, &n));
27739566063dSJacob Faibussowitsch   PetscCall(PetscArrayzero(reductions, n));
27749566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &a));
2775857cbf51SRichard Tran Mills   if (type == NORM_2) {
27760716a85fSBarry Smith     for (i = 0; i < n; i++) {
2777ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j] * a[j]);
27780716a85fSBarry Smith       a += m;
27790716a85fSBarry Smith     }
2780857cbf51SRichard Tran Mills   } else if (type == NORM_1) {
27810716a85fSBarry Smith     for (i = 0; i < n; i++) {
2782ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j]);
27830716a85fSBarry Smith       a += m;
27840716a85fSBarry Smith     }
2785857cbf51SRichard Tran Mills   } else if (type == NORM_INFINITY) {
27860716a85fSBarry Smith     for (i = 0; i < n; i++) {
2787ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] = PetscMax(PetscAbsScalar(a[j]), reductions[i]);
27880716a85fSBarry Smith       a += m;
27890716a85fSBarry Smith     }
2790857cbf51SRichard Tran Mills   } else if (type == REDUCTION_SUM_REALPART || type == REDUCTION_MEAN_REALPART) {
2791a873a8cdSSam Reynolds     for (i = 0; i < n; i++) {
2792ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] += PetscRealPart(a[j]);
2793a873a8cdSSam Reynolds       a += m;
2794a873a8cdSSam Reynolds     }
2795857cbf51SRichard Tran Mills   } else if (type == REDUCTION_SUM_IMAGINARYPART || type == REDUCTION_MEAN_IMAGINARYPART) {
2796857cbf51SRichard Tran Mills     for (i = 0; i < n; i++) {
2797ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] += PetscImaginaryPart(a[j]);
2798857cbf51SRichard Tran Mills       a += m;
2799857cbf51SRichard Tran Mills     }
2800857cbf51SRichard Tran Mills   } else SETERRQ(PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Unknown reduction type");
28019566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &a));
2802857cbf51SRichard Tran Mills   if (type == NORM_2) {
2803a873a8cdSSam Reynolds     for (i = 0; i < n; i++) reductions[i] = PetscSqrtReal(reductions[i]);
2804857cbf51SRichard Tran Mills   } else if (type == REDUCTION_MEAN_REALPART || type == REDUCTION_MEAN_IMAGINARYPART) {
2805a873a8cdSSam Reynolds     for (i = 0; i < n; i++) reductions[i] /= m;
28060716a85fSBarry Smith   }
28070716a85fSBarry Smith   PetscFunctionReturn(0);
28080716a85fSBarry Smith }
28090716a85fSBarry Smith 
2810*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetRandom_SeqDense(Mat x, PetscRandom rctx)
2811*d71ae5a4SJacob Faibussowitsch {
281273a71a0fSBarry Smith   PetscScalar *a;
2813637a0070SStefano Zampini   PetscInt     lda, m, n, i, j;
281473a71a0fSBarry Smith 
281573a71a0fSBarry Smith   PetscFunctionBegin;
28169566063dSJacob Faibussowitsch   PetscCall(MatGetSize(x, &m, &n));
28179566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(x, &lda));
28183faff063SStefano Zampini   PetscCall(MatDenseGetArrayWrite(x, &a));
2819637a0070SStefano Zampini   for (j = 0; j < n; j++) {
282048a46eb9SPierre Jolivet     for (i = 0; i < m; i++) PetscCall(PetscRandomGetValue(rctx, a + j * lda + i));
282173a71a0fSBarry Smith   }
28223faff063SStefano Zampini   PetscCall(MatDenseRestoreArrayWrite(x, &a));
282373a71a0fSBarry Smith   PetscFunctionReturn(0);
282473a71a0fSBarry Smith }
282573a71a0fSBarry Smith 
2826*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A, PetscBool *missing, PetscInt *d)
2827*d71ae5a4SJacob Faibussowitsch {
28283b49f96aSBarry Smith   PetscFunctionBegin;
28293b49f96aSBarry Smith   *missing = PETSC_FALSE;
28303b49f96aSBarry Smith   PetscFunctionReturn(0);
28313b49f96aSBarry Smith }
283273a71a0fSBarry Smith 
2833ca15aa20SStefano Zampini /* vals is not const */
2834*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A, PetscInt col, PetscScalar **vals)
2835*d71ae5a4SJacob Faibussowitsch {
283686aefd0dSHong Zhang   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
2837ca15aa20SStefano Zampini   PetscScalar  *v;
283886aefd0dSHong Zhang 
283986aefd0dSHong Zhang   PetscFunctionBegin;
284028b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
28419566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
2842ca15aa20SStefano Zampini   *vals = v + col * a->lda;
28439566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
284486aefd0dSHong Zhang   PetscFunctionReturn(0);
284586aefd0dSHong Zhang }
284686aefd0dSHong Zhang 
2847*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A, PetscScalar **vals)
2848*d71ae5a4SJacob Faibussowitsch {
284986aefd0dSHong Zhang   PetscFunctionBegin;
2850742765d3SMatthew Knepley   if (vals) *vals = NULL; /* user cannot accidentally use the array later */
285186aefd0dSHong Zhang   PetscFunctionReturn(0);
285286aefd0dSHong Zhang }
2853abc3b08eSStefano Zampini 
2854289bc588SBarry Smith /* -------------------------------------------------------------------*/
2855a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqDense,
2856905e6a2fSBarry Smith                                        MatGetRow_SeqDense,
2857905e6a2fSBarry Smith                                        MatRestoreRow_SeqDense,
2858905e6a2fSBarry Smith                                        MatMult_SeqDense,
285997304618SKris Buschelman                                        /*  4*/ MatMultAdd_SeqDense,
28607c922b88SBarry Smith                                        MatMultTranspose_SeqDense,
28617c922b88SBarry Smith                                        MatMultTransposeAdd_SeqDense,
2862f4259b30SLisandro Dalcin                                        NULL,
2863f4259b30SLisandro Dalcin                                        NULL,
2864f4259b30SLisandro Dalcin                                        NULL,
2865f4259b30SLisandro Dalcin                                        /* 10*/ NULL,
2866905e6a2fSBarry Smith                                        MatLUFactor_SeqDense,
2867905e6a2fSBarry Smith                                        MatCholeskyFactor_SeqDense,
286841f059aeSBarry Smith                                        MatSOR_SeqDense,
2869ec8511deSBarry Smith                                        MatTranspose_SeqDense,
287097304618SKris Buschelman                                        /* 15*/ MatGetInfo_SeqDense,
2871905e6a2fSBarry Smith                                        MatEqual_SeqDense,
2872905e6a2fSBarry Smith                                        MatGetDiagonal_SeqDense,
2873905e6a2fSBarry Smith                                        MatDiagonalScale_SeqDense,
2874905e6a2fSBarry Smith                                        MatNorm_SeqDense,
2875c0aa2d19SHong Zhang                                        /* 20*/ MatAssemblyBegin_SeqDense,
2876c0aa2d19SHong Zhang                                        MatAssemblyEnd_SeqDense,
2877905e6a2fSBarry Smith                                        MatSetOption_SeqDense,
2878905e6a2fSBarry Smith                                        MatZeroEntries_SeqDense,
2879d519adbfSMatthew Knepley                                        /* 24*/ MatZeroRows_SeqDense,
2880f4259b30SLisandro Dalcin                                        NULL,
2881f4259b30SLisandro Dalcin                                        NULL,
2882f4259b30SLisandro Dalcin                                        NULL,
2883f4259b30SLisandro Dalcin                                        NULL,
28844994cf47SJed Brown                                        /* 29*/ MatSetUp_SeqDense,
2885f4259b30SLisandro Dalcin                                        NULL,
2886f4259b30SLisandro Dalcin                                        NULL,
2887f4259b30SLisandro Dalcin                                        NULL,
2888f4259b30SLisandro Dalcin                                        NULL,
2889d519adbfSMatthew Knepley                                        /* 34*/ MatDuplicate_SeqDense,
2890f4259b30SLisandro Dalcin                                        NULL,
2891f4259b30SLisandro Dalcin                                        NULL,
2892f4259b30SLisandro Dalcin                                        NULL,
2893f4259b30SLisandro Dalcin                                        NULL,
2894d519adbfSMatthew Knepley                                        /* 39*/ MatAXPY_SeqDense,
28957dae84e0SHong Zhang                                        MatCreateSubMatrices_SeqDense,
2896f4259b30SLisandro Dalcin                                        NULL,
28974b0e389bSBarry Smith                                        MatGetValues_SeqDense,
2898a5ae1ecdSBarry Smith                                        MatCopy_SeqDense,
2899d519adbfSMatthew Knepley                                        /* 44*/ MatGetRowMax_SeqDense,
2900a5ae1ecdSBarry Smith                                        MatScale_SeqDense,
29012f605a99SJose E. Roman                                        MatShift_SeqDense,
2902f4259b30SLisandro Dalcin                                        NULL,
29033f49a652SStefano Zampini                                        MatZeroRowsColumns_SeqDense,
290473a71a0fSBarry Smith                                        /* 49*/ MatSetRandom_SeqDense,
2905f4259b30SLisandro Dalcin                                        NULL,
2906f4259b30SLisandro Dalcin                                        NULL,
2907f4259b30SLisandro Dalcin                                        NULL,
2908f4259b30SLisandro Dalcin                                        NULL,
2909f4259b30SLisandro Dalcin                                        /* 54*/ NULL,
2910f4259b30SLisandro Dalcin                                        NULL,
2911f4259b30SLisandro Dalcin                                        NULL,
2912f4259b30SLisandro Dalcin                                        NULL,
2913f4259b30SLisandro Dalcin                                        NULL,
2914023c16fcSToby Isaac                                        /* 59*/ MatCreateSubMatrix_SeqDense,
2915e03a110bSBarry Smith                                        MatDestroy_SeqDense,
2916e03a110bSBarry Smith                                        MatView_SeqDense,
2917f4259b30SLisandro Dalcin                                        NULL,
2918f4259b30SLisandro Dalcin                                        NULL,
2919f4259b30SLisandro Dalcin                                        /* 64*/ NULL,
2920f4259b30SLisandro Dalcin                                        NULL,
2921f4259b30SLisandro Dalcin                                        NULL,
2922f4259b30SLisandro Dalcin                                        NULL,
2923f4259b30SLisandro Dalcin                                        NULL,
2924d519adbfSMatthew Knepley                                        /* 69*/ MatGetRowMaxAbs_SeqDense,
2925f4259b30SLisandro Dalcin                                        NULL,
2926f4259b30SLisandro Dalcin                                        NULL,
2927f4259b30SLisandro Dalcin                                        NULL,
2928f4259b30SLisandro Dalcin                                        NULL,
2929f4259b30SLisandro Dalcin                                        /* 74*/ NULL,
2930f4259b30SLisandro Dalcin                                        NULL,
2931f4259b30SLisandro Dalcin                                        NULL,
2932f4259b30SLisandro Dalcin                                        NULL,
2933f4259b30SLisandro Dalcin                                        NULL,
2934f4259b30SLisandro Dalcin                                        /* 79*/ NULL,
2935f4259b30SLisandro Dalcin                                        NULL,
2936f4259b30SLisandro Dalcin                                        NULL,
2937f4259b30SLisandro Dalcin                                        NULL,
29385bba2384SShri Abhyankar                                        /* 83*/ MatLoad_SeqDense,
2939637a0070SStefano Zampini                                        MatIsSymmetric_SeqDense,
29401cbb95d3SBarry Smith                                        MatIsHermitian_SeqDense,
2941f4259b30SLisandro Dalcin                                        NULL,
2942f4259b30SLisandro Dalcin                                        NULL,
2943f4259b30SLisandro Dalcin                                        NULL,
2944f4259b30SLisandro Dalcin                                        /* 89*/ NULL,
2945f4259b30SLisandro Dalcin                                        NULL,
2946a9fe9ddaSSatish Balay                                        MatMatMultNumeric_SeqDense_SeqDense,
2947f4259b30SLisandro Dalcin                                        NULL,
2948f4259b30SLisandro Dalcin                                        NULL,
2949f4259b30SLisandro Dalcin                                        /* 94*/ NULL,
2950f4259b30SLisandro Dalcin                                        NULL,
2951f4259b30SLisandro Dalcin                                        NULL,
295269f65d41SStefano Zampini                                        MatMatTransposeMultNumeric_SeqDense_SeqDense,
2953f4259b30SLisandro Dalcin                                        NULL,
29544222ddf1SHong Zhang                                        /* 99*/ MatProductSetFromOptions_SeqDense,
2955f4259b30SLisandro Dalcin                                        NULL,
2956f4259b30SLisandro Dalcin                                        NULL,
2957ba337c44SJed Brown                                        MatConjugate_SeqDense,
2958f4259b30SLisandro Dalcin                                        NULL,
2959f4259b30SLisandro Dalcin                                        /*104*/ NULL,
2960ba337c44SJed Brown                                        MatRealPart_SeqDense,
2961ba337c44SJed Brown                                        MatImaginaryPart_SeqDense,
2962f4259b30SLisandro Dalcin                                        NULL,
2963f4259b30SLisandro Dalcin                                        NULL,
2964f4259b30SLisandro Dalcin                                        /*109*/ NULL,
2965f4259b30SLisandro Dalcin                                        NULL,
29668d0534beSBarry Smith                                        MatGetRowMin_SeqDense,
2967aabbc4fbSShri Abhyankar                                        MatGetColumnVector_SeqDense,
29683b49f96aSBarry Smith                                        MatMissingDiagonal_SeqDense,
2969f4259b30SLisandro Dalcin                                        /*114*/ NULL,
2970f4259b30SLisandro Dalcin                                        NULL,
2971f4259b30SLisandro Dalcin                                        NULL,
2972f4259b30SLisandro Dalcin                                        NULL,
2973f4259b30SLisandro Dalcin                                        NULL,
2974f4259b30SLisandro Dalcin                                        /*119*/ NULL,
2975f4259b30SLisandro Dalcin                                        NULL,
2976f4259b30SLisandro Dalcin                                        NULL,
2977f4259b30SLisandro Dalcin                                        NULL,
2978f4259b30SLisandro Dalcin                                        NULL,
2979f4259b30SLisandro Dalcin                                        /*124*/ NULL,
2980a873a8cdSSam Reynolds                                        MatGetColumnReductions_SeqDense,
2981f4259b30SLisandro Dalcin                                        NULL,
2982f4259b30SLisandro Dalcin                                        NULL,
2983f4259b30SLisandro Dalcin                                        NULL,
2984f4259b30SLisandro Dalcin                                        /*129*/ NULL,
2985f4259b30SLisandro Dalcin                                        NULL,
2986f4259b30SLisandro Dalcin                                        NULL,
298775648e8dSHong Zhang                                        MatTransposeMatMultNumeric_SeqDense_SeqDense,
2988f4259b30SLisandro Dalcin                                        NULL,
2989f4259b30SLisandro Dalcin                                        /*134*/ NULL,
2990f4259b30SLisandro Dalcin                                        NULL,
2991f4259b30SLisandro Dalcin                                        NULL,
2992f4259b30SLisandro Dalcin                                        NULL,
2993f4259b30SLisandro Dalcin                                        NULL,
2994f4259b30SLisandro Dalcin                                        /*139*/ NULL,
2995f4259b30SLisandro Dalcin                                        NULL,
2996f4259b30SLisandro Dalcin                                        NULL,
2997f4259b30SLisandro Dalcin                                        NULL,
2998f4259b30SLisandro Dalcin                                        NULL,
29994222ddf1SHong Zhang                                        MatCreateMPIMatConcatenateSeqMat_SeqDense,
3000f4259b30SLisandro Dalcin                                        /*145*/ NULL,
3001f4259b30SLisandro Dalcin                                        NULL,
300299a7f59eSMark Adams                                        NULL,
300399a7f59eSMark Adams                                        NULL,
30047fb60732SBarry Smith                                        NULL,
30059371c9d4SSatish Balay                                        /*150*/ NULL};
300690ace30eSBarry Smith 
30074b828684SBarry Smith /*@C
300811a5261eSBarry Smith    MatCreateSeqDense - Creates a `MATSEQDENSE` that
3009d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
3010d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
3011289bc588SBarry Smith 
3012d083f849SBarry Smith    Collective
3013db81eaa0SLois Curfman McInnes 
301420563c6bSBarry Smith    Input Parameters:
301511a5261eSBarry Smith +  comm - MPI communicator, set to `PETSC_COMM_SELF`
30160c775827SLois Curfman McInnes .  m - number of rows
301718f449edSLois Curfman McInnes .  n - number of columns
30180298fd71SBarry Smith -  data - optional location of matrix data in column major order.  Set data=NULL for PETSc
3019dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
302020563c6bSBarry Smith 
302120563c6bSBarry Smith    Output Parameter:
302244cd7ae7SLois Curfman McInnes .  A - the matrix
302320563c6bSBarry Smith 
302411a5261eSBarry Smith    Note:
302518f449edSLois Curfman McInnes    The data input variable is intended primarily for Fortran programmers
302618f449edSLois Curfman McInnes    who wish to allocate their own matrix memory space.  Most users should
30270298fd71SBarry Smith    set data=NULL.
302818f449edSLois Curfman McInnes 
3029027ccd11SLois Curfman McInnes    Level: intermediate
3030027ccd11SLois Curfman McInnes 
303111a5261eSBarry Smith .seealso: `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()`
303220563c6bSBarry Smith @*/
3033*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateSeqDense(MPI_Comm comm, PetscInt m, PetscInt n, PetscScalar *data, Mat *A)
3034*d71ae5a4SJacob Faibussowitsch {
30353a40ed3dSBarry Smith   PetscFunctionBegin;
30369566063dSJacob Faibussowitsch   PetscCall(MatCreate(comm, A));
30379566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*A, m, n, m, n));
30389566063dSJacob Faibussowitsch   PetscCall(MatSetType(*A, MATSEQDENSE));
30399566063dSJacob Faibussowitsch   PetscCall(MatSeqDenseSetPreallocation(*A, data));
3040273d9f13SBarry Smith   PetscFunctionReturn(0);
3041273d9f13SBarry Smith }
3042273d9f13SBarry Smith 
3043273d9f13SBarry Smith /*@C
304411a5261eSBarry Smith    MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements of a `MATSEQDENSE` matrix
3045273d9f13SBarry Smith 
3046d083f849SBarry Smith    Collective
3047273d9f13SBarry Smith 
3048273d9f13SBarry Smith    Input Parameters:
30491c4f3114SJed Brown +  B - the matrix
30500298fd71SBarry Smith -  data - the array (or NULL)
3051273d9f13SBarry Smith 
305211a5261eSBarry Smith    Note:
3053273d9f13SBarry Smith    The data input variable is intended primarily for Fortran programmers
3054273d9f13SBarry Smith    who wish to allocate their own matrix memory space.  Most users should
3055284134d9SBarry Smith    need not call this routine.
3056273d9f13SBarry Smith 
3057273d9f13SBarry Smith    Level: intermediate
3058273d9f13SBarry Smith 
305911a5261eSBarry Smith .seealso: `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()`, `MatDenseSetLDA()`
3060273d9f13SBarry Smith @*/
3061*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation(Mat B, PetscScalar data[])
3062*d71ae5a4SJacob Faibussowitsch {
3063a23d5eceSKris Buschelman   PetscFunctionBegin;
3064d5ea218eSStefano Zampini   PetscValidHeaderSpecific(B, MAT_CLASSID, 1);
3065cac4c232SBarry Smith   PetscTryMethod(B, "MatSeqDenseSetPreallocation_C", (Mat, PetscScalar[]), (B, data));
3066a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3067a23d5eceSKris Buschelman }
3068a23d5eceSKris Buschelman 
3069*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation_SeqDense(Mat B, PetscScalar *data)
3070*d71ae5a4SJacob Faibussowitsch {
3071ad16ce7aSStefano Zampini   Mat_SeqDense *b = (Mat_SeqDense *)B->data;
3072273d9f13SBarry Smith 
3073273d9f13SBarry Smith   PetscFunctionBegin;
307428b400f6SJacob Faibussowitsch   PetscCheck(!b->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
3075273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
3076a868139aSShri Abhyankar 
30779566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(B->rmap));
30789566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(B->cmap));
307934ef9618SShri Abhyankar 
3080ad16ce7aSStefano Zampini   if (b->lda <= 0) b->lda = B->rmap->n;
308186d161a7SShri Abhyankar 
30829e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
30839566063dSJacob Faibussowitsch     if (!b->user_alloc) PetscCall(PetscFree(b->v));
30849566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1((size_t)b->lda * B->cmap->n, &b->v));
30852205254eSKarl Rupp 
30869e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
3087273d9f13SBarry Smith   } else { /* user-allocated storage */
30889566063dSJacob Faibussowitsch     if (!b->user_alloc) PetscCall(PetscFree(b->v));
3089273d9f13SBarry Smith     b->v          = data;
3090273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
3091273d9f13SBarry Smith   }
30920450473dSBarry Smith   B->assembled = PETSC_TRUE;
3093273d9f13SBarry Smith   PetscFunctionReturn(0);
3094273d9f13SBarry Smith }
3095273d9f13SBarry Smith 
309665b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
3097*d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype, MatReuse reuse, Mat *newmat)
3098*d71ae5a4SJacob Faibussowitsch {
3099d77f618aSHong Zhang   Mat                mat_elemental;
31001683a169SBarry Smith   const PetscScalar *array;
31011683a169SBarry Smith   PetscScalar       *v_colwise;
3102d77f618aSHong Zhang   PetscInt           M = A->rmap->N, N = A->cmap->N, i, j, k, *rows, *cols;
3103d77f618aSHong Zhang 
31048baccfbdSHong Zhang   PetscFunctionBegin;
31059566063dSJacob Faibussowitsch   PetscCall(PetscMalloc3(M * N, &v_colwise, M, &rows, N, &cols));
31069566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &array));
3107d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
3108d77f618aSHong Zhang   k = 0;
3109d77f618aSHong Zhang   for (j = 0; j < N; j++) {
3110d77f618aSHong Zhang     cols[j] = j;
3111ad540459SPierre Jolivet     for (i = 0; i < M; i++) v_colwise[j * M + i] = array[k++];
3112d77f618aSHong Zhang   }
3113ad540459SPierre Jolivet   for (i = 0; i < M; i++) rows[i] = i;
31149566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &array));
3115d77f618aSHong Zhang 
31169566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental));
31179566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(mat_elemental, PETSC_DECIDE, PETSC_DECIDE, M, N));
31189566063dSJacob Faibussowitsch   PetscCall(MatSetType(mat_elemental, MATELEMENTAL));
31199566063dSJacob Faibussowitsch   PetscCall(MatSetUp(mat_elemental));
3120d77f618aSHong Zhang 
3121d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
31229566063dSJacob Faibussowitsch   PetscCall(MatSetValues(mat_elemental, M, rows, N, cols, v_colwise, ADD_VALUES));
31239566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY));
31249566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY));
31259566063dSJacob Faibussowitsch   PetscCall(PetscFree3(v_colwise, rows, cols));
3126d77f618aSHong Zhang 
3127511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
31289566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A, &mat_elemental));
3129d77f618aSHong Zhang   } else {
3130d77f618aSHong Zhang     *newmat = mat_elemental;
3131d77f618aSHong Zhang   }
31328baccfbdSHong Zhang   PetscFunctionReturn(0);
31338baccfbdSHong Zhang }
313465b80a83SHong Zhang #endif
31358baccfbdSHong Zhang 
3136*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA_SeqDense(Mat B, PetscInt lda)
3137*d71ae5a4SJacob Faibussowitsch {
31381b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense *)B->data;
31397422da62SJose E. Roman   PetscBool     data;
314021a2c019SBarry Smith 
31411b807ce4Svictorle   PetscFunctionBegin;
31427422da62SJose E. Roman   data = (PetscBool)((B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE);
3143aed4548fSBarry Smith   PetscCheck(b->user_alloc || !data || b->lda == lda, PETSC_COMM_SELF, PETSC_ERR_ORDER, "LDA cannot be changed after allocation of internal storage");
314408401ef6SPierre 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);
31451b807ce4Svictorle   b->lda = lda;
31461b807ce4Svictorle   PetscFunctionReturn(0);
31471b807ce4Svictorle }
31481b807ce4Svictorle 
3149*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm, Mat inmat, PetscInt n, MatReuse scall, Mat *outmat)
3150*d71ae5a4SJacob Faibussowitsch {
3151d528f656SJakub Kruzik   PetscFunctionBegin;
31529566063dSJacob Faibussowitsch   PetscCall(MatCreateMPIMatConcatenateSeqMat_MPIDense(comm, inmat, n, scall, outmat));
3153d528f656SJakub Kruzik   PetscFunctionReturn(0);
3154d528f656SJakub Kruzik }
3155d528f656SJakub Kruzik 
3156*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A, PetscInt col, Vec *v)
3157*d71ae5a4SJacob Faibussowitsch {
31586947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
31596947451fSStefano Zampini 
31606947451fSStefano Zampini   PetscFunctionBegin;
316128b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
316228b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
31634dfa11a4SJacob Faibussowitsch   if (!a->cvec) { PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec)); }
31646947451fSStefano Zampini   a->vecinuse = col + 1;
31659566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, (PetscScalar **)&a->ptrinuse));
31669566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda));
31676947451fSStefano Zampini   *v = a->cvec;
31686947451fSStefano Zampini   PetscFunctionReturn(0);
31696947451fSStefano Zampini }
31706947451fSStefano Zampini 
3171*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A, PetscInt col, Vec *v)
3172*d71ae5a4SJacob Faibussowitsch {
31736947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
31746947451fSStefano Zampini 
31756947451fSStefano Zampini   PetscFunctionBegin;
317628b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first");
317728b400f6SJacob Faibussowitsch   PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector");
31786947451fSStefano Zampini   a->vecinuse = 0;
31799566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, (PetscScalar **)&a->ptrinuse));
31809566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
318175f6d85dSStefano Zampini   if (v) *v = NULL;
31826947451fSStefano Zampini   PetscFunctionReturn(0);
31836947451fSStefano Zampini }
31846947451fSStefano Zampini 
3185*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v)
3186*d71ae5a4SJacob Faibussowitsch {
31876947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
31886947451fSStefano Zampini 
31896947451fSStefano Zampini   PetscFunctionBegin;
319028b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
319128b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
31924dfa11a4SJacob Faibussowitsch   if (!a->cvec) { PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec)); }
31936947451fSStefano Zampini   a->vecinuse = col + 1;
31949566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &a->ptrinuse));
31959566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda));
31969566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(a->cvec));
31976947451fSStefano Zampini   *v = a->cvec;
31986947451fSStefano Zampini   PetscFunctionReturn(0);
31996947451fSStefano Zampini }
32006947451fSStefano Zampini 
3201*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v)
3202*d71ae5a4SJacob Faibussowitsch {
32036947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
32046947451fSStefano Zampini 
32056947451fSStefano Zampini   PetscFunctionBegin;
320628b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first");
320728b400f6SJacob Faibussowitsch   PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector");
32086947451fSStefano Zampini   a->vecinuse = 0;
32099566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &a->ptrinuse));
32109566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(a->cvec));
32119566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
321275f6d85dSStefano Zampini   if (v) *v = NULL;
32136947451fSStefano Zampini   PetscFunctionReturn(0);
32146947451fSStefano Zampini }
32156947451fSStefano Zampini 
3216*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v)
3217*d71ae5a4SJacob Faibussowitsch {
32186947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
32196947451fSStefano Zampini 
32206947451fSStefano Zampini   PetscFunctionBegin;
322128b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
322228b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
32234dfa11a4SJacob Faibussowitsch   if (!a->cvec) { PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec)); }
32246947451fSStefano Zampini   a->vecinuse = col + 1;
32259566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(A, (PetscScalar **)&a->ptrinuse));
32269566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda));
32276947451fSStefano Zampini   *v = a->cvec;
32286947451fSStefano Zampini   PetscFunctionReturn(0);
32296947451fSStefano Zampini }
32306947451fSStefano Zampini 
3231*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v)
3232*d71ae5a4SJacob Faibussowitsch {
32336947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
32346947451fSStefano Zampini 
32356947451fSStefano Zampini   PetscFunctionBegin;
323628b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first");
323728b400f6SJacob Faibussowitsch   PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector");
32386947451fSStefano Zampini   a->vecinuse = 0;
32399566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(A, (PetscScalar **)&a->ptrinuse));
32409566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
324175f6d85dSStefano Zampini   if (v) *v = NULL;
32426947451fSStefano Zampini   PetscFunctionReturn(0);
32436947451fSStefano Zampini }
32446947451fSStefano Zampini 
3245*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v)
3246*d71ae5a4SJacob Faibussowitsch {
32475ea7661aSPierre Jolivet   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
32485ea7661aSPierre Jolivet 
32495ea7661aSPierre Jolivet   PetscFunctionBegin;
325028b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
325128b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
3252a2748737SPierre Jolivet   if (a->cmat && (cend - cbegin != a->cmat->cmap->N || rend - rbegin != a->cmat->rmap->N)) PetscCall(MatDestroy(&a->cmat));
32535ea7661aSPierre Jolivet   if (!a->cmat) {
3254a2748737SPierre Jolivet     PetscCall(MatCreateDense(PetscObjectComm((PetscObject)A), rend - rbegin, PETSC_DECIDE, rend - rbegin, cend - cbegin, a->v + rbegin + (size_t)cbegin * a->lda, &a->cmat));
32555ea7661aSPierre Jolivet   } else {
3256a2748737SPierre Jolivet     PetscCall(MatDensePlaceArray(a->cmat, a->v + rbegin + (size_t)cbegin * a->lda));
32575ea7661aSPierre Jolivet   }
32589566063dSJacob Faibussowitsch   PetscCall(MatDenseSetLDA(a->cmat, a->lda));
32595ea7661aSPierre Jolivet   a->matinuse = cbegin + 1;
32605ea7661aSPierre Jolivet   *v          = a->cmat;
326175f6d85dSStefano Zampini #if defined(PETSC_HAVE_CUDA)
326275f6d85dSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
326375f6d85dSStefano Zampini #endif
32645ea7661aSPierre Jolivet   PetscFunctionReturn(0);
32655ea7661aSPierre Jolivet }
32665ea7661aSPierre Jolivet 
3267*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A, Mat *v)
3268*d71ae5a4SJacob Faibussowitsch {
32695ea7661aSPierre Jolivet   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
32705ea7661aSPierre Jolivet 
32715ea7661aSPierre Jolivet   PetscFunctionBegin;
327228b400f6SJacob Faibussowitsch   PetscCheck(a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetSubMatrix() first");
327328b400f6SJacob Faibussowitsch   PetscCheck(a->cmat, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column matrix");
327408401ef6SPierre Jolivet   PetscCheck(*v == a->cmat, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not the matrix obtained from MatDenseGetSubMatrix()");
32755ea7661aSPierre Jolivet   a->matinuse = 0;
32769566063dSJacob Faibussowitsch   PetscCall(MatDenseResetArray(a->cmat));
3277742765d3SMatthew Knepley   if (v) *v = NULL;
32783faff063SStefano Zampini #if defined(PETSC_HAVE_CUDA)
32793faff063SStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
32803faff063SStefano Zampini #endif
32815ea7661aSPierre Jolivet   PetscFunctionReturn(0);
32825ea7661aSPierre Jolivet }
32835ea7661aSPierre Jolivet 
32840bad9183SKris Buschelman /*MC
3285fafad747SKris Buschelman    MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices.
32860bad9183SKris Buschelman 
32870bad9183SKris Buschelman    Options Database Keys:
328811a5261eSBarry Smith . -mat_type seqdense - sets the matrix type to `MATSEQDENSE` during a call to `MatSetFromOptions()`
32890bad9183SKris Buschelman 
32900bad9183SKris Buschelman   Level: beginner
32910bad9183SKris Buschelman 
329211a5261eSBarry Smith .seealso: `MATSEQDENSE`, `MatCreateSeqDense()`
32930bad9183SKris Buschelman M*/
3294*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreate_SeqDense(Mat B)
3295*d71ae5a4SJacob Faibussowitsch {
3296273d9f13SBarry Smith   Mat_SeqDense *b;
32977c334f02SBarry Smith   PetscMPIInt   size;
3298273d9f13SBarry Smith 
3299273d9f13SBarry Smith   PetscFunctionBegin;
33009566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)B), &size));
330108401ef6SPierre Jolivet   PetscCheck(size <= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Comm must be of size 1");
330255659b69SBarry Smith 
33034dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&b));
33049566063dSJacob Faibussowitsch   PetscCall(PetscMemcpy(B->ops, &MatOps_Values, sizeof(struct _MatOps)));
330544cd7ae7SLois Curfman McInnes   B->data = (void *)b;
330618f449edSLois Curfman McInnes 
3307273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
33084e220ebcSLois Curfman McInnes 
33099566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatQRFactor_C", MatQRFactor_SeqDense));
33109566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetLDA_C", MatDenseGetLDA_SeqDense));
33119566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseSetLDA_C", MatDenseSetLDA_SeqDense));
33129566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArray_C", MatDenseGetArray_SeqDense));
33139566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArray_C", MatDenseRestoreArray_SeqDense));
33149566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDensePlaceArray_C", MatDensePlaceArray_SeqDense));
33159566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseResetArray_C", MatDenseResetArray_SeqDense));
33169566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseReplaceArray_C", MatDenseReplaceArray_SeqDense));
33179566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayRead_C", MatDenseGetArray_SeqDense));
33189566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayRead_C", MatDenseRestoreArray_SeqDense));
33199566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayWrite_C", MatDenseGetArray_SeqDense));
33209566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayWrite_C", MatDenseRestoreArray_SeqDense));
33219566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqaij_C", MatConvert_SeqDense_SeqAIJ));
33228baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
33239566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_elemental_C", MatConvert_SeqDense_Elemental));
33248baccfbdSHong Zhang #endif
3325d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
33269566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_scalapack_C", MatConvert_Dense_ScaLAPACK));
3327d24d4204SJose E. Roman #endif
33282bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
33299566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensecuda_C", MatConvert_SeqDense_SeqDenseCUDA));
33309566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", MatProductSetFromOptions_SeqDense));
33319566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdense_C", MatProductSetFromOptions_SeqDense));
33329566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensecuda_C", MatProductSetFromOptions_SeqDense));
33332bf066beSStefano Zampini #endif
33349566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSeqDenseSetPreallocation_C", MatSeqDenseSetPreallocation_SeqDense));
33359566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqaij_seqdense_C", MatProductSetFromOptions_SeqAIJ_SeqDense));
33369566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdense_C", MatProductSetFromOptions_SeqDense));
33379566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense));
33389566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqsbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense));
333996e6d5c4SRichard Tran Mills 
33409566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumn_C", MatDenseGetColumn_SeqDense));
33419566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumn_C", MatDenseRestoreColumn_SeqDense));
33429566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVec_C", MatDenseGetColumnVec_SeqDense));
33439566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVec_C", MatDenseRestoreColumnVec_SeqDense));
33449566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecRead_C", MatDenseGetColumnVecRead_SeqDense));
33459566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecRead_C", MatDenseRestoreColumnVecRead_SeqDense));
33469566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecWrite_C", MatDenseGetColumnVecWrite_SeqDense));
33479566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecWrite_C", MatDenseRestoreColumnVecWrite_SeqDense));
33489566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetSubMatrix_C", MatDenseGetSubMatrix_SeqDense));
33499566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreSubMatrix_C", MatDenseRestoreSubMatrix_SeqDense));
33509566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)B, MATSEQDENSE));
33513a40ed3dSBarry Smith   PetscFunctionReturn(0);
3352289bc588SBarry Smith }
335386aefd0dSHong Zhang 
335486aefd0dSHong Zhang /*@C
335511a5261eSBarry Smith    MatDenseGetColumn - gives access to a column of a dense matrix. This is only the local part of the column. You MUST call `MatDenseRestoreColumn()` to avoid memory bleeding.
335686aefd0dSHong Zhang 
335786aefd0dSHong Zhang    Not Collective
335886aefd0dSHong Zhang 
33595ea7661aSPierre Jolivet    Input Parameters:
336011a5261eSBarry Smith +  mat - a `MATSEQDENSE` or `MATMPIDENSE` matrix
336186aefd0dSHong Zhang -  col - column index
336286aefd0dSHong Zhang 
336386aefd0dSHong Zhang    Output Parameter:
336486aefd0dSHong Zhang .  vals - pointer to the data
336586aefd0dSHong Zhang 
336686aefd0dSHong Zhang    Level: intermediate
336786aefd0dSHong Zhang 
336811a5261eSBarry Smith    Note:
336911a5261eSBarry Smith    Use `MatDenseGetColumnVec()` to get access to a column of a `MATDENSE` treated as a `Vec`
337011a5261eSBarry Smith 
337111a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreColumn()`, `MatDenseGetColumnVec()`
337286aefd0dSHong Zhang @*/
3373*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumn(Mat A, PetscInt col, PetscScalar **vals)
3374*d71ae5a4SJacob Faibussowitsch {
337586aefd0dSHong Zhang   PetscFunctionBegin;
3376d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
3377d5ea218eSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
3378d5ea218eSStefano Zampini   PetscValidPointer(vals, 3);
3379cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumn_C", (Mat, PetscInt, PetscScalar **), (A, col, vals));
338086aefd0dSHong Zhang   PetscFunctionReturn(0);
338186aefd0dSHong Zhang }
338286aefd0dSHong Zhang 
338386aefd0dSHong Zhang /*@C
338411a5261eSBarry Smith    MatDenseRestoreColumn - returns access to a column of a `MATDENSE` matrix which is returned by `MatDenseGetColumn()`.
338586aefd0dSHong Zhang 
338686aefd0dSHong Zhang    Not Collective
338786aefd0dSHong Zhang 
3388742765d3SMatthew Knepley    Input Parameters:
338911a5261eSBarry Smith +  mat - a `MATSEQDENSE` or `MATMPIDENSE` matrix
3390742765d3SMatthew Knepley -  vals - pointer to the data (may be NULL)
339186aefd0dSHong Zhang 
339286aefd0dSHong Zhang    Level: intermediate
339386aefd0dSHong Zhang 
339411a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetColumn()`
339586aefd0dSHong Zhang @*/
3396*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumn(Mat A, PetscScalar **vals)
3397*d71ae5a4SJacob Faibussowitsch {
339886aefd0dSHong Zhang   PetscFunctionBegin;
3399d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
3400d5ea218eSStefano Zampini   PetscValidPointer(vals, 2);
3401cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumn_C", (Mat, PetscScalar **), (A, vals));
340286aefd0dSHong Zhang   PetscFunctionReturn(0);
340386aefd0dSHong Zhang }
34046947451fSStefano Zampini 
34050f74d2c1SSatish Balay /*@
340611a5261eSBarry Smith    MatDenseGetColumnVec - Gives read-write access to a column of a `MATDENSE` matrix, represented as a `Vec`.
34076947451fSStefano Zampini 
34086947451fSStefano Zampini    Collective
34096947451fSStefano Zampini 
34105ea7661aSPierre Jolivet    Input Parameters:
341111a5261eSBarry Smith +  mat - the `Mat` object
34126947451fSStefano Zampini -  col - the column index
34136947451fSStefano Zampini 
34146947451fSStefano Zampini    Output Parameter:
34156947451fSStefano Zampini .  v - the vector
34166947451fSStefano Zampini 
34176947451fSStefano Zampini    Notes:
341811a5261eSBarry Smith      The vector is owned by PETSc. Users need to call `MatDenseRestoreColumnVec()` when the vector is no longer needed.
341911a5261eSBarry Smith 
342011a5261eSBarry Smith      Use `MatDenseGetColumnVecRead()` to obtain read-only access or `MatDenseGetColumnVecWrite()` for write-only access.
34216947451fSStefano Zampini 
34226947451fSStefano Zampini    Level: intermediate
34236947451fSStefano Zampini 
342411a5261eSBarry Smith .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`, `MatDenseGetColumn()`
34256947451fSStefano Zampini @*/
3426*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec(Mat A, PetscInt col, Vec *v)
3427*d71ae5a4SJacob Faibussowitsch {
34286947451fSStefano Zampini   PetscFunctionBegin;
34296947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
34306947451fSStefano Zampini   PetscValidType(A, 1);
34316947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
34326947451fSStefano Zampini   PetscValidPointer(v, 3);
343328b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
34342cf15c64SPierre 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);
3435cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v));
34366947451fSStefano Zampini   PetscFunctionReturn(0);
34376947451fSStefano Zampini }
34386947451fSStefano Zampini 
34390f74d2c1SSatish Balay /*@
34406947451fSStefano Zampini    MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVec().
34416947451fSStefano Zampini 
34426947451fSStefano Zampini    Collective
34436947451fSStefano Zampini 
34445ea7661aSPierre Jolivet    Input Parameters:
34456947451fSStefano Zampini +  mat - the Mat object
34466947451fSStefano Zampini .  col - the column index
3447742765d3SMatthew Knepley -  v - the Vec object (may be NULL)
34486947451fSStefano Zampini 
34496947451fSStefano Zampini    Level: intermediate
34506947451fSStefano Zampini 
3451db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
34526947451fSStefano Zampini @*/
3453*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec(Mat A, PetscInt col, Vec *v)
3454*d71ae5a4SJacob Faibussowitsch {
34556947451fSStefano Zampini   PetscFunctionBegin;
34566947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
34576947451fSStefano Zampini   PetscValidType(A, 1);
34586947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
345908401ef6SPierre Jolivet   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
34602cf15c64SPierre 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);
3461cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v));
34626947451fSStefano Zampini   PetscFunctionReturn(0);
34636947451fSStefano Zampini }
34646947451fSStefano Zampini 
34650f74d2c1SSatish Balay /*@
34666947451fSStefano Zampini    MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a Vec.
34676947451fSStefano Zampini 
34686947451fSStefano Zampini    Collective
34696947451fSStefano Zampini 
34705ea7661aSPierre Jolivet    Input Parameters:
34716947451fSStefano Zampini +  mat - the Mat object
34726947451fSStefano Zampini -  col - the column index
34736947451fSStefano Zampini 
34746947451fSStefano Zampini    Output Parameter:
34756947451fSStefano Zampini .  v - the vector
34766947451fSStefano Zampini 
34776947451fSStefano Zampini    Notes:
34786947451fSStefano Zampini      The vector is owned by PETSc and users cannot modify it.
347911a5261eSBarry Smith 
34806947451fSStefano Zampini      Users need to call MatDenseRestoreColumnVecRead() when the vector is no longer needed.
348111a5261eSBarry Smith 
34826947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecWrite() for write-only access.
34836947451fSStefano Zampini 
34846947451fSStefano Zampini    Level: intermediate
34856947451fSStefano Zampini 
3486db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
34876947451fSStefano Zampini @*/
3488*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead(Mat A, PetscInt col, Vec *v)
3489*d71ae5a4SJacob Faibussowitsch {
34906947451fSStefano Zampini   PetscFunctionBegin;
34916947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
34926947451fSStefano Zampini   PetscValidType(A, 1);
34936947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
34946947451fSStefano Zampini   PetscValidPointer(v, 3);
349528b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
34962cf15c64SPierre 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);
3497cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v));
34986947451fSStefano Zampini   PetscFunctionReturn(0);
34996947451fSStefano Zampini }
35006947451fSStefano Zampini 
35010f74d2c1SSatish Balay /*@
35026947451fSStefano Zampini    MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecRead().
35036947451fSStefano Zampini 
35046947451fSStefano Zampini    Collective
35056947451fSStefano Zampini 
35065ea7661aSPierre Jolivet    Input Parameters:
35076947451fSStefano Zampini +  mat - the Mat object
35086947451fSStefano Zampini .  col - the column index
3509742765d3SMatthew Knepley -  v - the Vec object (may be NULL)
35106947451fSStefano Zampini 
35116947451fSStefano Zampini    Level: intermediate
35126947451fSStefano Zampini 
3513db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecWrite()`
35146947451fSStefano Zampini @*/
3515*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead(Mat A, PetscInt col, Vec *v)
3516*d71ae5a4SJacob Faibussowitsch {
35176947451fSStefano Zampini   PetscFunctionBegin;
35186947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
35196947451fSStefano Zampini   PetscValidType(A, 1);
35206947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
352108401ef6SPierre Jolivet   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
35222cf15c64SPierre 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);
3523cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v));
35246947451fSStefano Zampini   PetscFunctionReturn(0);
35256947451fSStefano Zampini }
35266947451fSStefano Zampini 
35270f74d2c1SSatish Balay /*@
35286947451fSStefano Zampini    MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a Vec.
35296947451fSStefano Zampini 
35306947451fSStefano Zampini    Collective
35316947451fSStefano Zampini 
35325ea7661aSPierre Jolivet    Input Parameters:
35336947451fSStefano Zampini +  mat - the Mat object
35346947451fSStefano Zampini -  col - the column index
35356947451fSStefano Zampini 
35366947451fSStefano Zampini    Output Parameter:
35376947451fSStefano Zampini .  v - the vector
35386947451fSStefano Zampini 
35396947451fSStefano Zampini    Notes:
35406947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVecWrite() when the vector is no longer needed.
354111a5261eSBarry Smith 
35426947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecRead() for read-only access.
35436947451fSStefano Zampini 
35446947451fSStefano Zampini    Level: intermediate
35456947451fSStefano Zampini 
3546db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
35476947451fSStefano Zampini @*/
3548*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite(Mat A, PetscInt col, Vec *v)
3549*d71ae5a4SJacob Faibussowitsch {
35506947451fSStefano Zampini   PetscFunctionBegin;
35516947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
35526947451fSStefano Zampini   PetscValidType(A, 1);
35536947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
35546947451fSStefano Zampini   PetscValidPointer(v, 3);
355528b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
3556aed4548fSBarry 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);
3557cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v));
35586947451fSStefano Zampini   PetscFunctionReturn(0);
35596947451fSStefano Zampini }
35606947451fSStefano Zampini 
35610f74d2c1SSatish Balay /*@
35626947451fSStefano Zampini    MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecWrite().
35636947451fSStefano Zampini 
35646947451fSStefano Zampini    Collective
35656947451fSStefano Zampini 
35665ea7661aSPierre Jolivet    Input Parameters:
35676947451fSStefano Zampini +  mat - the Mat object
35686947451fSStefano Zampini .  col - the column index
3569742765d3SMatthew Knepley -  v - the Vec object (may be NULL)
35706947451fSStefano Zampini 
35716947451fSStefano Zampini    Level: intermediate
35726947451fSStefano Zampini 
3573db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`
35746947451fSStefano Zampini @*/
3575*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A, PetscInt col, Vec *v)
3576*d71ae5a4SJacob Faibussowitsch {
35776947451fSStefano Zampini   PetscFunctionBegin;
35786947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
35796947451fSStefano Zampini   PetscValidType(A, 1);
35806947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
358108401ef6SPierre Jolivet   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
3582aed4548fSBarry 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);
3583cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v));
35846947451fSStefano Zampini   PetscFunctionReturn(0);
35856947451fSStefano Zampini }
35865ea7661aSPierre Jolivet 
35870f74d2c1SSatish Balay /*@
3588a2748737SPierre Jolivet    MatDenseGetSubMatrix - Gives access to a block of rows and columns of a dense matrix, represented as a Mat.
35895ea7661aSPierre Jolivet 
35905ea7661aSPierre Jolivet    Collective
35915ea7661aSPierre Jolivet 
35925ea7661aSPierre Jolivet    Input Parameters:
35935ea7661aSPierre Jolivet +  mat - the Mat object
3594a2748737SPierre Jolivet .  rbegin - the first global row index in the block (if PETSC_DECIDE, is 0)
3595a2748737SPierre Jolivet .  rend - the global row index past the last one in the block (if PETSC_DECIDE, is M)
3596a2748737SPierre Jolivet .  cbegin - the first global column index in the block (if PETSC_DECIDE, is 0)
3597a2748737SPierre Jolivet -  cend - the global column index past the last one in the block (if PETSC_DECIDE, is N)
35985ea7661aSPierre Jolivet 
35995ea7661aSPierre Jolivet    Output Parameter:
36005ea7661aSPierre Jolivet .  v - the matrix
36015ea7661aSPierre Jolivet 
36025ea7661aSPierre Jolivet    Notes:
36035ea7661aSPierre Jolivet      The matrix is owned by PETSc. Users need to call MatDenseRestoreSubMatrix() when the matrix is no longer needed.
360411a5261eSBarry Smith 
3605a2748737SPierre 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.
36065ea7661aSPierre Jolivet 
36075ea7661aSPierre Jolivet    Level: intermediate
36085ea7661aSPierre Jolivet 
3609db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreSubMatrix()`
36105ea7661aSPierre Jolivet @*/
3611*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v)
3612*d71ae5a4SJacob Faibussowitsch {
36135ea7661aSPierre Jolivet   PetscFunctionBegin;
36145ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
36155ea7661aSPierre Jolivet   PetscValidType(A, 1);
3616a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, rbegin, 2);
3617a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, rend, 3);
3618a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, cbegin, 4);
3619a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, cend, 5);
3620a2748737SPierre Jolivet   PetscValidPointer(v, 6);
3621a2748737SPierre Jolivet   if (rbegin == PETSC_DECIDE) rbegin = 0;
3622a2748737SPierre Jolivet   if (rend == PETSC_DECIDE) rend = A->rmap->N;
3623a2748737SPierre Jolivet   if (cbegin == PETSC_DECIDE) cbegin = 0;
3624a2748737SPierre Jolivet   if (cend == PETSC_DECIDE) cend = A->cmap->N;
362528b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
3626a2748737SPierre 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);
3627a2748737SPierre 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);
3628a2748737SPierre 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);
3629a2748737SPierre 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);
3630a2748737SPierre Jolivet   PetscUseMethod(A, "MatDenseGetSubMatrix_C", (Mat, PetscInt, PetscInt, PetscInt, PetscInt, Mat *), (A, rbegin, rend, cbegin, cend, v));
36315ea7661aSPierre Jolivet   PetscFunctionReturn(0);
36325ea7661aSPierre Jolivet }
36335ea7661aSPierre Jolivet 
36340f74d2c1SSatish Balay /*@
36355ea7661aSPierre Jolivet    MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from MatDenseGetSubMatrix().
36365ea7661aSPierre Jolivet 
36375ea7661aSPierre Jolivet    Collective
36385ea7661aSPierre Jolivet 
36395ea7661aSPierre Jolivet    Input Parameters:
36405ea7661aSPierre Jolivet +  mat - the Mat object
3641742765d3SMatthew Knepley -  v - the Mat object (may be NULL)
36425ea7661aSPierre Jolivet 
36435ea7661aSPierre Jolivet    Level: intermediate
36445ea7661aSPierre Jolivet 
3645db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseGetSubMatrix()`
36465ea7661aSPierre Jolivet @*/
3647*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix(Mat A, Mat *v)
3648*d71ae5a4SJacob Faibussowitsch {
36495ea7661aSPierre Jolivet   PetscFunctionBegin;
36505ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
36515ea7661aSPierre Jolivet   PetscValidType(A, 1);
36525ea7661aSPierre Jolivet   PetscValidPointer(v, 2);
3653cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreSubMatrix_C", (Mat, Mat *), (A, v));
36545ea7661aSPierre Jolivet   PetscFunctionReturn(0);
36555ea7661aSPierre Jolivet }
36568a9c020eSBarry Smith 
36578a9c020eSBarry Smith #include <petscblaslapack.h>
36588a9c020eSBarry Smith #include <petsc/private/kernels/blockinvert.h>
36598a9c020eSBarry Smith 
3660*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseInvert(Mat A)
3661*d71ae5a4SJacob Faibussowitsch {
36628a9c020eSBarry Smith   Mat_SeqDense   *a              = (Mat_SeqDense *)A->data;
36638a9c020eSBarry Smith   PetscInt        bs             = A->rmap->n;
36648a9c020eSBarry Smith   MatScalar      *values         = a->v;
36658a9c020eSBarry Smith   const PetscReal shift          = 0.0;
36668a9c020eSBarry Smith   PetscBool       allowzeropivot = PetscNot(A->erroriffailure), zeropivotdetected = PETSC_FALSE;
36678a9c020eSBarry Smith 
36688a9c020eSBarry Smith   PetscFunctionBegin;
36698a9c020eSBarry Smith   /* factor and invert each block */
36708a9c020eSBarry Smith   switch (bs) {
3671*d71ae5a4SJacob Faibussowitsch   case 1:
3672*d71ae5a4SJacob Faibussowitsch     values[0] = (PetscScalar)1.0 / (values[0] + shift);
3673*d71ae5a4SJacob Faibussowitsch     break;
36748a9c020eSBarry Smith   case 2:
36758a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_2(values, shift, allowzeropivot, &zeropivotdetected));
36768a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
36778a9c020eSBarry Smith     break;
36788a9c020eSBarry Smith   case 3:
36798a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_3(values, shift, allowzeropivot, &zeropivotdetected));
36808a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
36818a9c020eSBarry Smith     break;
36828a9c020eSBarry Smith   case 4:
36838a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_4(values, shift, allowzeropivot, &zeropivotdetected));
36848a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
36858a9c020eSBarry Smith     break;
36869371c9d4SSatish Balay   case 5: {
36878a9c020eSBarry Smith     PetscScalar work[25];
36888a9c020eSBarry Smith     PetscInt    ipvt[5];
36898a9c020eSBarry Smith 
36908a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_5(values, ipvt, work, shift, allowzeropivot, &zeropivotdetected));
36918a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
36929371c9d4SSatish Balay   } break;
36938a9c020eSBarry Smith   case 6:
36948a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_6(values, shift, allowzeropivot, &zeropivotdetected));
36958a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
36968a9c020eSBarry Smith     break;
36978a9c020eSBarry Smith   case 7:
36988a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_7(values, shift, allowzeropivot, &zeropivotdetected));
36998a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
37008a9c020eSBarry Smith     break;
37019371c9d4SSatish Balay   default: {
37028a9c020eSBarry Smith     PetscInt    *v_pivots, *IJ, j;
37038a9c020eSBarry Smith     PetscScalar *v_work;
37048a9c020eSBarry Smith 
37058a9c020eSBarry Smith     PetscCall(PetscMalloc3(bs, &v_work, bs, &v_pivots, bs, &IJ));
3706ad540459SPierre Jolivet     for (j = 0; j < bs; j++) IJ[j] = j;
37078a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A(bs, values, v_pivots, v_work, allowzeropivot, &zeropivotdetected));
37088a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
37098a9c020eSBarry Smith     PetscCall(PetscFree3(v_work, v_pivots, IJ));
37108a9c020eSBarry Smith   }
37118a9c020eSBarry Smith   }
37128a9c020eSBarry Smith   PetscFunctionReturn(0);
37138a9c020eSBarry Smith }
3714