xref: /petsc/src/mat/impls/dense/seq/dense.c (revision 5c0db29a52f0e0a315a431c2b5d53138ecf7c054)
167e560aaSBarry Smith /*
267e560aaSBarry Smith      Defines the basic matrix operations for sequential dense.
347d993e7Ssuyashtn      Portions of this code are under:
447d993e7Ssuyashtn      Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved.
567e560aaSBarry Smith */
6289bc588SBarry Smith 
7dec5eb66SMatthew G Knepley #include <../src/mat/impls/dense/seq/dense.h> /*I "petscmat.h" I*/
8cd3f9d89SJunchao Zhang #include <../src/mat/impls/dense/mpi/mpidense.h>
9c6db04a5SJed Brown #include <petscblaslapack.h>
106a63e612SBarry Smith #include <../src/mat/impls/aij/seq/aij.h>
11b2573a8aSBarry Smith 
12d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSymmetrize_Private(Mat A, PetscBool hermitian)
13d71ae5a4SJacob Faibussowitsch {
148c178816SStefano Zampini   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
158c178816SStefano Zampini   PetscInt      j, k, n = A->rmap->n;
16ca15aa20SStefano Zampini   PetscScalar  *v;
178c178816SStefano Zampini 
188c178816SStefano Zampini   PetscFunctionBegin;
1908401ef6SPierre Jolivet   PetscCheck(A->rmap->n == A->cmap->n, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Cannot symmetrize a rectangular matrix");
209566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
218c178816SStefano Zampini   if (!hermitian) {
228c178816SStefano Zampini     for (k = 0; k < n; k++) {
23ad540459SPierre Jolivet       for (j = k; j < n; j++) v[j * mat->lda + k] = v[k * mat->lda + j];
248c178816SStefano Zampini     }
258c178816SStefano Zampini   } else {
268c178816SStefano Zampini     for (k = 0; k < n; k++) {
27ad540459SPierre Jolivet       for (j = k; j < n; j++) v[j * mat->lda + k] = PetscConj(v[k * mat->lda + j]);
288c178816SStefano Zampini     }
298c178816SStefano Zampini   }
309566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
313ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
328c178816SStefano Zampini }
338c178816SStefano Zampini 
34ff6a9541SJacob Faibussowitsch PetscErrorCode MatSeqDenseInvertFactors_Private(Mat A)
35d71ae5a4SJacob Faibussowitsch {
368c178816SStefano Zampini   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
378c178816SStefano Zampini   PetscBLASInt  info, n;
388c178816SStefano Zampini 
398c178816SStefano Zampini   PetscFunctionBegin;
403ba16761SJacob Faibussowitsch   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS);
419566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
428c178816SStefano Zampini   if (A->factortype == MAT_FACTOR_LU) {
4328b400f6SJacob Faibussowitsch     PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present");
448c178816SStefano Zampini     if (!mat->fwork) {
458c178816SStefano Zampini       mat->lfwork = n;
469566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
478c178816SStefano Zampini     }
489566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
49792fecdfSBarry Smith     PetscCallBLAS("LAPACKgetri", LAPACKgetri_(&n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info));
509566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
519566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0));
528c178816SStefano Zampini   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
53b94d7dedSBarry Smith     if (A->spd == PETSC_BOOL3_TRUE) {
549566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
55792fecdfSBarry Smith       PetscCallBLAS("LAPACKpotri", LAPACKpotri_("L", &n, mat->v, &mat->lda, &info));
569566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
579566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_TRUE));
588c178816SStefano Zampini #if defined(PETSC_USE_COMPLEX)
59b94d7dedSBarry Smith     } else if (A->hermitian == PETSC_BOOL3_TRUE) {
6028b400f6SJacob Faibussowitsch       PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present");
6128b400f6SJacob Faibussowitsch       PetscCheck(mat->fwork, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Fwork not present");
629566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
63792fecdfSBarry Smith       PetscCallBLAS("LAPACKhetri", LAPACKhetri_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &info));
649566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
659566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_TRUE));
668c178816SStefano Zampini #endif
678c178816SStefano Zampini     } else { /* symmetric case */
6828b400f6SJacob Faibussowitsch       PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present");
6928b400f6SJacob Faibussowitsch       PetscCheck(mat->fwork, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Fwork not present");
709566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
71792fecdfSBarry Smith       PetscCallBLAS("LAPACKsytri", LAPACKsytri_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &info));
729566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
739566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_FALSE));
748c178816SStefano Zampini     }
7528b400f6SJacob Faibussowitsch     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad Inversion: zero pivot in row %" PetscInt_FMT, (PetscInt)info - 1);
769566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0));
778c178816SStefano Zampini   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Matrix must be factored to solve");
788c178816SStefano Zampini 
798c178816SStefano Zampini   A->ops->solve             = NULL;
808c178816SStefano Zampini   A->ops->matsolve          = NULL;
818c178816SStefano Zampini   A->ops->solvetranspose    = NULL;
828c178816SStefano Zampini   A->ops->matsolvetranspose = NULL;
838c178816SStefano Zampini   A->ops->solveadd          = NULL;
848c178816SStefano Zampini   A->ops->solvetransposeadd = NULL;
858c178816SStefano Zampini   A->factortype             = MAT_FACTOR_NONE;
869566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
873ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
888c178816SStefano Zampini }
898c178816SStefano Zampini 
9066976f2fSJacob Faibussowitsch static PetscErrorCode MatZeroRowsColumns_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b)
91d71ae5a4SJacob Faibussowitsch {
923f49a652SStefano Zampini   Mat_SeqDense      *l = (Mat_SeqDense *)A->data;
933f49a652SStefano Zampini   PetscInt           m = l->lda, n = A->cmap->n, r = A->rmap->n, i, j;
94ca15aa20SStefano Zampini   PetscScalar       *slot, *bb, *v;
953f49a652SStefano Zampini   const PetscScalar *xx;
963f49a652SStefano Zampini 
973f49a652SStefano Zampini   PetscFunctionBegin;
9876bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
993f49a652SStefano Zampini     for (i = 0; i < N; i++) {
10008401ef6SPierre Jolivet       PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed");
10108401ef6SPierre 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);
10208401ef6SPierre 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);
1033f49a652SStefano Zampini     }
10476bd3646SJed Brown   }
1053ba16761SJacob Faibussowitsch   if (!N) PetscFunctionReturn(PETSC_SUCCESS);
1063f49a652SStefano Zampini 
1073f49a652SStefano Zampini   /* fix right hand side if needed */
1083f49a652SStefano Zampini   if (x && b) {
1096c4d906cSStefano Zampini     Vec xt;
1106c4d906cSStefano Zampini 
11108401ef6SPierre Jolivet     PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices");
1129566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(x, &xt));
1139566063dSJacob Faibussowitsch     PetscCall(VecCopy(x, xt));
1149566063dSJacob Faibussowitsch     PetscCall(VecScale(xt, -1.0));
1159566063dSJacob Faibussowitsch     PetscCall(MatMultAdd(A, xt, b, b));
1169566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&xt));
1179566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(x, &xx));
1189566063dSJacob Faibussowitsch     PetscCall(VecGetArray(b, &bb));
1193f49a652SStefano Zampini     for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]];
1209566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(x, &xx));
1219566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(b, &bb));
1223f49a652SStefano Zampini   }
1233f49a652SStefano Zampini 
1249566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
1253f49a652SStefano Zampini   for (i = 0; i < N; i++) {
126ca15aa20SStefano Zampini     slot = v + rows[i] * m;
1279566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(slot, r));
1283f49a652SStefano Zampini   }
1293f49a652SStefano Zampini   for (i = 0; i < N; i++) {
130ca15aa20SStefano Zampini     slot = v + rows[i];
1319371c9d4SSatish Balay     for (j = 0; j < n; j++) {
1329371c9d4SSatish Balay       *slot = 0.0;
1339371c9d4SSatish Balay       slot += m;
1349371c9d4SSatish Balay     }
1353f49a652SStefano Zampini   }
1363f49a652SStefano Zampini   if (diag != 0.0) {
13708401ef6SPierre Jolivet     PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices");
1383f49a652SStefano Zampini     for (i = 0; i < N; i++) {
139ca15aa20SStefano Zampini       slot  = v + (m + 1) * rows[i];
1403f49a652SStefano Zampini       *slot = diag;
1413f49a652SStefano Zampini     }
1423f49a652SStefano Zampini   }
1439566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
1443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1453f49a652SStefano Zampini }
1463f49a652SStefano Zampini 
147d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat A, MatType newtype, MatReuse reuse, Mat *newmat)
148d71ae5a4SJacob Faibussowitsch {
149a13144ffSStefano Zampini   Mat              B = NULL;
150b49cda9fSStefano Zampini   Mat_SeqAIJ      *a = (Mat_SeqAIJ *)A->data;
151b49cda9fSStefano Zampini   Mat_SeqDense    *b;
152b49cda9fSStefano Zampini   PetscInt        *ai = a->i, *aj = a->j, m = A->rmap->N, n = A->cmap->N, i;
1532e5835c6SStefano Zampini   const MatScalar *av;
154a13144ffSStefano Zampini   PetscBool        isseqdense;
155b49cda9fSStefano Zampini 
156b49cda9fSStefano Zampini   PetscFunctionBegin;
157a13144ffSStefano Zampini   if (reuse == MAT_REUSE_MATRIX) {
1589566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)*newmat, MATSEQDENSE, &isseqdense));
15928b400f6SJacob Faibussowitsch     PetscCheck(isseqdense, PetscObjectComm((PetscObject)*newmat), PETSC_ERR_USER, "Cannot reuse matrix of type %s", ((PetscObject)(*newmat))->type_name);
160a13144ffSStefano Zampini   }
161a13144ffSStefano Zampini   if (reuse != MAT_REUSE_MATRIX) {
1629566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B));
1639566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(B, m, n, m, n));
1649566063dSJacob Faibussowitsch     PetscCall(MatSetType(B, MATSEQDENSE));
1659566063dSJacob Faibussowitsch     PetscCall(MatSeqDenseSetPreallocation(B, NULL));
166b49cda9fSStefano Zampini     b = (Mat_SeqDense *)(B->data);
167a13144ffSStefano Zampini   } else {
168a13144ffSStefano Zampini     b = (Mat_SeqDense *)((*newmat)->data);
1699566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(b->v, m * n));
170a13144ffSStefano Zampini   }
1719566063dSJacob Faibussowitsch   PetscCall(MatSeqAIJGetArrayRead(A, &av));
172b49cda9fSStefano Zampini   for (i = 0; i < m; i++) {
173b49cda9fSStefano Zampini     PetscInt j;
174b49cda9fSStefano Zampini     for (j = 0; j < ai[1] - ai[0]; j++) {
175b49cda9fSStefano Zampini       b->v[*aj * m + i] = *av;
176b49cda9fSStefano Zampini       aj++;
177b49cda9fSStefano Zampini       av++;
178b49cda9fSStefano Zampini     }
179b49cda9fSStefano Zampini     ai++;
180b49cda9fSStefano Zampini   }
1819566063dSJacob Faibussowitsch   PetscCall(MatSeqAIJRestoreArrayRead(A, &av));
182b49cda9fSStefano Zampini 
183511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
1849566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY));
1859566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY));
1869566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A, &B));
187b49cda9fSStefano Zampini   } else {
188a13144ffSStefano Zampini     if (B) *newmat = B;
1899566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(*newmat, MAT_FINAL_ASSEMBLY));
1909566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(*newmat, MAT_FINAL_ASSEMBLY));
191b49cda9fSStefano Zampini   }
1923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
193b49cda9fSStefano Zampini }
194b49cda9fSStefano Zampini 
195d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqDense_SeqAIJ(Mat A, MatType newtype, MatReuse reuse, Mat *newmat)
196d71ae5a4SJacob Faibussowitsch {
1976d4ec7b0SPierre Jolivet   Mat           B = NULL;
1986a63e612SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
1999399e1b8SMatthew G. Knepley   PetscInt      i, j;
2009399e1b8SMatthew G. Knepley   PetscInt     *rows, *nnz;
2019399e1b8SMatthew G. Knepley   MatScalar    *aa = a->v, *vals;
2026a63e612SBarry Smith 
2036a63e612SBarry Smith   PetscFunctionBegin;
2049566063dSJacob Faibussowitsch   PetscCall(PetscCalloc3(A->rmap->n, &rows, A->rmap->n, &nnz, A->rmap->n, &vals));
2056d4ec7b0SPierre Jolivet   if (reuse != MAT_REUSE_MATRIX) {
2069566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B));
2079566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(B, A->rmap->n, A->cmap->n, A->rmap->N, A->cmap->N));
2089566063dSJacob Faibussowitsch     PetscCall(MatSetType(B, MATSEQAIJ));
2099399e1b8SMatthew G. Knepley     for (j = 0; j < A->cmap->n; j++) {
2109371c9d4SSatish Balay       for (i = 0; i < A->rmap->n; i++)
2119371c9d4SSatish Balay         if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) ++nnz[i];
2126a63e612SBarry Smith       aa += a->lda;
2136a63e612SBarry Smith     }
2149566063dSJacob Faibussowitsch     PetscCall(MatSeqAIJSetPreallocation(B, PETSC_DETERMINE, nnz));
2156d4ec7b0SPierre Jolivet   } else B = *newmat;
2169399e1b8SMatthew G. Knepley   aa = a->v;
2179399e1b8SMatthew G. Knepley   for (j = 0; j < A->cmap->n; j++) {
2189399e1b8SMatthew G. Knepley     PetscInt numRows = 0;
2199371c9d4SSatish Balay     for (i = 0; i < A->rmap->n; i++)
2209371c9d4SSatish Balay       if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) {
2219371c9d4SSatish Balay         rows[numRows]   = i;
2229371c9d4SSatish Balay         vals[numRows++] = aa[i];
2239371c9d4SSatish Balay       }
2249566063dSJacob Faibussowitsch     PetscCall(MatSetValues(B, numRows, rows, 1, &j, vals, INSERT_VALUES));
2259399e1b8SMatthew G. Knepley     aa += a->lda;
2269399e1b8SMatthew G. Knepley   }
2279566063dSJacob Faibussowitsch   PetscCall(PetscFree3(rows, nnz, vals));
2289566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY));
2299566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY));
2306a63e612SBarry Smith 
231511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
2329566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A, &B));
2336d4ec7b0SPierre Jolivet   } else if (reuse != MAT_REUSE_MATRIX) *newmat = B;
2343ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2356a63e612SBarry Smith }
2366a63e612SBarry Smith 
237d71ae5a4SJacob Faibussowitsch PetscErrorCode MatAXPY_SeqDense(Mat Y, PetscScalar alpha, Mat X, MatStructure str)
238d71ae5a4SJacob Faibussowitsch {
2391987afe7SBarry Smith   Mat_SeqDense      *x = (Mat_SeqDense *)X->data, *y = (Mat_SeqDense *)Y->data;
240ca15aa20SStefano Zampini   const PetscScalar *xv;
241ca15aa20SStefano Zampini   PetscScalar       *yv;
24223fff9afSBarry Smith   PetscBLASInt       N, m, ldax = 0, lday = 0, one = 1;
2433a40ed3dSBarry Smith 
2443a40ed3dSBarry Smith   PetscFunctionBegin;
2459566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(X, &xv));
2469566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(Y, &yv));
2479566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(X->rmap->n * X->cmap->n, &N));
2489566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(X->rmap->n, &m));
2499566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(x->lda, &ldax));
2509566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(y->lda, &lday));
251a5ce6ee0Svictorle   if (ldax > m || lday > m) {
252ca15aa20SStefano Zampini     PetscInt j;
253ca15aa20SStefano Zampini 
25448a46eb9SPierre Jolivet     for (j = 0; j < X->cmap->n; j++) PetscCallBLAS("BLASaxpy", BLASaxpy_(&m, &alpha, xv + j * ldax, &one, yv + j * lday, &one));
255a5ce6ee0Svictorle   } else {
256792fecdfSBarry Smith     PetscCallBLAS("BLASaxpy", BLASaxpy_(&N, &alpha, xv, &one, yv, &one));
257a5ce6ee0Svictorle   }
2589566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(X, &xv));
2599566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(Y, &yv));
2609566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(PetscMax(2.0 * N - 1, 0)));
2613ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2621987afe7SBarry Smith }
2631987afe7SBarry Smith 
264d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetInfo_SeqDense(Mat A, MatInfoType flag, MatInfo *info)
265d71ae5a4SJacob Faibussowitsch {
266ca15aa20SStefano Zampini   PetscLogDouble N = A->rmap->n * A->cmap->n;
2673a40ed3dSBarry Smith 
2683a40ed3dSBarry Smith   PetscFunctionBegin;
2694e220ebcSLois Curfman McInnes   info->block_size        = 1.0;
270ca15aa20SStefano Zampini   info->nz_allocated      = N;
271ca15aa20SStefano Zampini   info->nz_used           = N;
272ca15aa20SStefano Zampini   info->nz_unneeded       = 0;
273ca15aa20SStefano Zampini   info->assemblies        = A->num_ass;
2744e220ebcSLois Curfman McInnes   info->mallocs           = 0;
2754dfa11a4SJacob Faibussowitsch   info->memory            = 0; /* REVIEW ME */
2764e220ebcSLois Curfman McInnes   info->fill_ratio_given  = 0;
2774e220ebcSLois Curfman McInnes   info->fill_ratio_needed = 0;
2784e220ebcSLois Curfman McInnes   info->factor_mallocs    = 0;
2793ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
280289bc588SBarry Smith }
281289bc588SBarry Smith 
282d71ae5a4SJacob Faibussowitsch PetscErrorCode MatScale_SeqDense(Mat A, PetscScalar alpha)
283d71ae5a4SJacob Faibussowitsch {
284273d9f13SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
285ca15aa20SStefano Zampini   PetscScalar  *v;
28623fff9afSBarry Smith   PetscBLASInt  one = 1, j, nz, lda = 0;
28780cd9d93SLois Curfman McInnes 
2883a40ed3dSBarry Smith   PetscFunctionBegin;
2899566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
2909566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(a->lda, &lda));
291d0f46423SBarry Smith   if (lda > A->rmap->n) {
2929566063dSJacob Faibussowitsch     PetscCall(PetscBLASIntCast(A->rmap->n, &nz));
29348a46eb9SPierre Jolivet     for (j = 0; j < A->cmap->n; j++) PetscCallBLAS("BLASscal", BLASscal_(&nz, &alpha, v + j * lda, &one));
294a5ce6ee0Svictorle   } else {
2959566063dSJacob Faibussowitsch     PetscCall(PetscBLASIntCast(A->rmap->n * A->cmap->n, &nz));
296792fecdfSBarry Smith     PetscCallBLAS("BLASscal", BLASscal_(&nz, &alpha, v, &one));
297a5ce6ee0Svictorle   }
29804cbc005SJose E. Roman   PetscCall(PetscLogFlops(A->rmap->n * A->cmap->n));
2999566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
3003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30180cd9d93SLois Curfman McInnes }
30280cd9d93SLois Curfman McInnes 
303d71ae5a4SJacob Faibussowitsch PetscErrorCode MatShift_SeqDense(Mat A, PetscScalar alpha)
304d71ae5a4SJacob Faibussowitsch {
3052f605a99SJose E. Roman   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
3062f605a99SJose E. Roman   PetscScalar  *v;
3072f605a99SJose E. Roman   PetscInt      j, k;
3082f605a99SJose E. Roman 
3092f605a99SJose E. Roman   PetscFunctionBegin;
3102f605a99SJose E. Roman   PetscCall(MatDenseGetArray(A, &v));
3112f605a99SJose E. Roman   k = PetscMin(A->rmap->n, A->cmap->n);
3122f605a99SJose E. Roman   for (j = 0; j < k; j++) v[j + j * a->lda] += alpha;
3132f605a99SJose E. Roman   PetscCall(PetscLogFlops(k));
3142f605a99SJose E. Roman   PetscCall(MatDenseRestoreArray(A, &v));
3153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3162f605a99SJose E. Roman }
3172f605a99SJose E. Roman 
318d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatIsHermitian_SeqDense(Mat A, PetscReal rtol, PetscBool *fl)
319d71ae5a4SJacob Faibussowitsch {
3201cbb95d3SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
321ca15aa20SStefano Zampini   PetscInt           i, j, m = A->rmap->n, N = a->lda;
322ca15aa20SStefano Zampini   const PetscScalar *v;
3231cbb95d3SBarry Smith 
3241cbb95d3SBarry Smith   PetscFunctionBegin;
3251cbb95d3SBarry Smith   *fl = PETSC_FALSE;
3263ba16761SJacob Faibussowitsch   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS);
3279566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &v));
3281cbb95d3SBarry Smith   for (i = 0; i < m; i++) {
329ca15aa20SStefano Zampini     for (j = i; j < m; j++) {
330ad540459SPierre Jolivet       if (PetscAbsScalar(v[i + j * N] - PetscConj(v[j + i * N])) > rtol) goto restore;
3311cbb95d3SBarry Smith     }
332637a0070SStefano Zampini   }
3331cbb95d3SBarry Smith   *fl = PETSC_TRUE;
334637a0070SStefano Zampini restore:
3359566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &v));
3363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
337637a0070SStefano Zampini }
338637a0070SStefano Zampini 
339d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatIsSymmetric_SeqDense(Mat A, PetscReal rtol, PetscBool *fl)
340d71ae5a4SJacob Faibussowitsch {
341637a0070SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
342637a0070SStefano Zampini   PetscInt           i, j, m = A->rmap->n, N = a->lda;
343637a0070SStefano Zampini   const PetscScalar *v;
344637a0070SStefano Zampini 
345637a0070SStefano Zampini   PetscFunctionBegin;
346637a0070SStefano Zampini   *fl = PETSC_FALSE;
3473ba16761SJacob Faibussowitsch   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS);
3489566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &v));
349637a0070SStefano Zampini   for (i = 0; i < m; i++) {
350637a0070SStefano Zampini     for (j = i; j < m; j++) {
351ad540459SPierre Jolivet       if (PetscAbsScalar(v[i + j * N] - v[j + i * N]) > rtol) goto restore;
352637a0070SStefano Zampini     }
353637a0070SStefano Zampini   }
354637a0070SStefano Zampini   *fl = PETSC_TRUE;
355637a0070SStefano Zampini restore:
3569566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &v));
3573ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3581cbb95d3SBarry Smith }
3591cbb95d3SBarry Smith 
360d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi, Mat A, MatDuplicateOption cpvalues)
361d71ae5a4SJacob Faibussowitsch {
362ca15aa20SStefano Zampini   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
36323fc5dcaSStefano Zampini   PetscInt      lda = (PetscInt)mat->lda, j, m, nlda = lda;
36475f6d85dSStefano Zampini   PetscBool     isdensecpu;
365b24902e0SBarry Smith 
366b24902e0SBarry Smith   PetscFunctionBegin;
3679566063dSJacob Faibussowitsch   PetscCall(PetscLayoutReference(A->rmap, &newi->rmap));
3689566063dSJacob Faibussowitsch   PetscCall(PetscLayoutReference(A->cmap, &newi->cmap));
36923fc5dcaSStefano Zampini   if (cpvalues == MAT_SHARE_NONZERO_PATTERN) { /* propagate LDA */
3709566063dSJacob Faibussowitsch     PetscCall(MatDenseSetLDA(newi, lda));
37123fc5dcaSStefano Zampini   }
3729566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)newi, MATSEQDENSE, &isdensecpu));
3739566063dSJacob Faibussowitsch   if (isdensecpu) PetscCall(MatSeqDenseSetPreallocation(newi, NULL));
374b24902e0SBarry Smith   if (cpvalues == MAT_COPY_VALUES) {
375ca15aa20SStefano Zampini     const PetscScalar *av;
376ca15aa20SStefano Zampini     PetscScalar       *v;
377ca15aa20SStefano Zampini 
3789566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A, &av));
3799566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayWrite(newi, &v));
3809566063dSJacob Faibussowitsch     PetscCall(MatDenseGetLDA(newi, &nlda));
381d0f46423SBarry Smith     m = A->rmap->n;
38223fc5dcaSStefano Zampini     if (lda > m || nlda > m) {
38348a46eb9SPierre Jolivet       for (j = 0; j < A->cmap->n; j++) PetscCall(PetscArraycpy(v + j * nlda, av + j * lda, m));
384b24902e0SBarry Smith     } else {
3859566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(v, av, A->rmap->n * A->cmap->n));
386b24902e0SBarry Smith     }
3879566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayWrite(newi, &v));
3889566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A, &av));
389b24902e0SBarry Smith   }
3903ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
391b24902e0SBarry Smith }
392b24902e0SBarry Smith 
393d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDuplicate_SeqDense(Mat A, MatDuplicateOption cpvalues, Mat *newmat)
394d71ae5a4SJacob Faibussowitsch {
3953a40ed3dSBarry Smith   PetscFunctionBegin;
3969566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), newmat));
3979566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*newmat, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n));
3989566063dSJacob Faibussowitsch   PetscCall(MatSetType(*newmat, ((PetscObject)A)->type_name));
3999566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(*newmat, A, cpvalues));
4003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
401b24902e0SBarry Smith }
402b24902e0SBarry Smith 
403d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_LU(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T)
404d71ae5a4SJacob Faibussowitsch {
405c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
4064396437dSToby Isaac   PetscBLASInt  info;
40767e560aaSBarry Smith 
4083a40ed3dSBarry Smith   PetscFunctionBegin;
4099566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
410792fecdfSBarry Smith   PetscCallBLAS("LAPACKgetrs", LAPACKgetrs_(T ? "T" : "N", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info));
4119566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
41205fcb23eSStefano Zampini   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "GETRS - Bad solve %d", (int)info);
4139566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m)));
4143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4154396437dSToby Isaac }
4164396437dSToby Isaac 
4174396437dSToby Isaac static PetscErrorCode MatConjugate_SeqDense(Mat);
4184396437dSToby Isaac 
419d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_Cholesky(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T)
420d71ae5a4SJacob Faibussowitsch {
4214396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
4224396437dSToby Isaac   PetscBLASInt  info;
4234396437dSToby Isaac 
4244396437dSToby Isaac   PetscFunctionBegin;
425b94d7dedSBarry Smith   if (A->spd == PETSC_BOOL3_TRUE) {
4269566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A));
4279566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
428792fecdfSBarry Smith     PetscCallBLAS("LAPACKpotrs", LAPACKpotrs_("L", &m, &nrhs, mat->v, &mat->lda, x, &m, &info));
4299566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
43005fcb23eSStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "POTRS Bad solve %d", (int)info);
4319566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A));
432a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
433b94d7dedSBarry Smith   } else if (A->hermitian == PETSC_BOOL3_TRUE) {
4349566063dSJacob Faibussowitsch     if (T) PetscCall(MatConjugate_SeqDense(A));
4359566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
436792fecdfSBarry Smith     PetscCallBLAS("LAPACKhetrs", LAPACKhetrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info));
4379566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
43805fcb23eSStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "HETRS Bad solve %d", (int)info);
4399566063dSJacob Faibussowitsch     if (T) PetscCall(MatConjugate_SeqDense(A));
440a49dc2a2SStefano Zampini #endif
441a49dc2a2SStefano Zampini   } else { /* symmetric case */
4429566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
443792fecdfSBarry Smith     PetscCallBLAS("LAPACKsytrs", LAPACKsytrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info));
4449566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
44505fcb23eSStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "SYTRS Bad solve %d", (int)info);
446a49dc2a2SStefano Zampini   }
4479566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m)));
4483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4494396437dSToby Isaac }
45085e2c93fSHong Zhang 
451d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k)
452d71ae5a4SJacob Faibussowitsch {
4534396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
4544396437dSToby Isaac   PetscBLASInt  info;
4554396437dSToby Isaac   char          trans;
4564396437dSToby Isaac 
4574396437dSToby Isaac   PetscFunctionBegin;
4584905a7bcSToby Isaac   if (PetscDefined(USE_COMPLEX)) {
4594905a7bcSToby Isaac     trans = 'C';
4604905a7bcSToby Isaac   } else {
4614905a7bcSToby Isaac     trans = 'T';
4624905a7bcSToby Isaac   }
4639566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
46405fcb23eSStefano Zampini   { /* lwork depends on the number of right-hand sides */
46505fcb23eSStefano Zampini     PetscBLASInt nlfwork, lfwork = -1;
46605fcb23eSStefano Zampini     PetscScalar  fwork;
46705fcb23eSStefano Zampini 
468792fecdfSBarry Smith     PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info));
46905fcb23eSStefano Zampini     nlfwork = (PetscBLASInt)PetscRealPart(fwork);
47005fcb23eSStefano Zampini     if (nlfwork > mat->lfwork) {
47105fcb23eSStefano Zampini       mat->lfwork = nlfwork;
47205fcb23eSStefano Zampini       PetscCall(PetscFree(mat->fwork));
47305fcb23eSStefano Zampini       PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
47405fcb23eSStefano Zampini     }
47505fcb23eSStefano Zampini   }
476792fecdfSBarry Smith   PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info));
4779566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
47805fcb23eSStefano Zampini   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %d", (int)info);
4799566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
480792fecdfSBarry Smith   PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "N", "N", &mat->rank, &nrhs, mat->v, &mat->lda, x, &ldx, &info));
4819566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
48205fcb23eSStefano Zampini   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %d", (int)info);
4834905a7bcSToby Isaac   for (PetscInt j = 0; j < nrhs; j++) {
484ad540459SPierre Jolivet     for (PetscInt i = mat->rank; i < k; i++) x[j * ldx + i] = 0.;
4854905a7bcSToby Isaac   }
4869566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank))));
4873ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4884905a7bcSToby Isaac }
4894905a7bcSToby Isaac 
490d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k)
491d71ae5a4SJacob Faibussowitsch {
4924396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
4934396437dSToby Isaac   PetscBLASInt  info;
4944396437dSToby Isaac 
4954396437dSToby Isaac   PetscFunctionBegin;
4964396437dSToby Isaac   if (A->rmap->n == A->cmap->n && mat->rank == A->rmap->n) {
4979566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
498792fecdfSBarry Smith     PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "T", "N", &m, &nrhs, mat->v, &mat->lda, x, &ldx, &info));
4999566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
50005fcb23eSStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %d", (int)info);
5019566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A));
50205fcb23eSStefano Zampini     { /* lwork depends on the number of right-hand sides */
50305fcb23eSStefano Zampini       PetscBLASInt nlfwork, lfwork = -1;
50405fcb23eSStefano Zampini       PetscScalar  fwork;
50505fcb23eSStefano Zampini 
506792fecdfSBarry Smith       PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info));
50705fcb23eSStefano Zampini       nlfwork = (PetscBLASInt)PetscRealPart(fwork);
50805fcb23eSStefano Zampini       if (nlfwork > mat->lfwork) {
50905fcb23eSStefano Zampini         mat->lfwork = nlfwork;
51005fcb23eSStefano Zampini         PetscCall(PetscFree(mat->fwork));
51105fcb23eSStefano Zampini         PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
51205fcb23eSStefano Zampini       }
51305fcb23eSStefano Zampini     }
5149566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
515792fecdfSBarry Smith     PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info));
5169566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
51705fcb23eSStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %d", (int)info);
5189566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A));
5194396437dSToby Isaac   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "QR factored matrix cannot be used for transpose solve");
5209566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank))));
5213ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5224396437dSToby Isaac }
5234396437dSToby Isaac 
524d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_SetUp(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k)
525d71ae5a4SJacob Faibussowitsch {
5264396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
5274905a7bcSToby Isaac   PetscScalar  *y;
5284905a7bcSToby Isaac   PetscBLASInt  m = 0, k = 0;
5294905a7bcSToby Isaac 
5304905a7bcSToby Isaac   PetscFunctionBegin;
5319566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
5329566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &k));
5334905a7bcSToby Isaac   if (k < m) {
5349566063dSJacob Faibussowitsch     PetscCall(VecCopy(xx, mat->qrrhs));
5359566063dSJacob Faibussowitsch     PetscCall(VecGetArray(mat->qrrhs, &y));
5364905a7bcSToby Isaac   } else {
5379566063dSJacob Faibussowitsch     PetscCall(VecCopy(xx, yy));
5389566063dSJacob Faibussowitsch     PetscCall(VecGetArray(yy, &y));
5394905a7bcSToby Isaac   }
5404396437dSToby Isaac   *_y = y;
5414396437dSToby Isaac   *_k = k;
5424396437dSToby Isaac   *_m = m;
5433ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5444396437dSToby Isaac }
5454396437dSToby Isaac 
546d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_TearDown(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k)
547d71ae5a4SJacob Faibussowitsch {
5484396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
54942e9364cSSatish Balay   PetscScalar  *y   = NULL;
5504396437dSToby Isaac   PetscBLASInt  m, k;
5514396437dSToby Isaac 
5524396437dSToby Isaac   PetscFunctionBegin;
5534396437dSToby Isaac   y   = *_y;
5544396437dSToby Isaac   *_y = NULL;
5554396437dSToby Isaac   k   = *_k;
5564396437dSToby Isaac   m   = *_m;
5574905a7bcSToby Isaac   if (k < m) {
5584905a7bcSToby Isaac     PetscScalar *yv;
5599566063dSJacob Faibussowitsch     PetscCall(VecGetArray(yy, &yv));
5609566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(yv, y, k));
5619566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(yy, &yv));
5629566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(mat->qrrhs, &y));
5634905a7bcSToby Isaac   } else {
5649566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(yy, &y));
5654905a7bcSToby Isaac   }
5663ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5674905a7bcSToby Isaac }
5684905a7bcSToby Isaac 
569d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_LU(Mat A, Vec xx, Vec yy)
570d71ae5a4SJacob Faibussowitsch {
57142e9364cSSatish Balay   PetscScalar *y = NULL;
57242e9364cSSatish Balay   PetscBLASInt m = 0, k = 0;
5734396437dSToby Isaac 
5744396437dSToby Isaac   PetscFunctionBegin;
5759566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
5769566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_FALSE));
5779566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
5783ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5794396437dSToby Isaac }
5804396437dSToby Isaac 
581d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_LU(Mat A, Vec xx, Vec yy)
582d71ae5a4SJacob Faibussowitsch {
58342e9364cSSatish Balay   PetscScalar *y = NULL;
58442e9364cSSatish Balay   PetscBLASInt m = 0, k = 0;
5854396437dSToby Isaac 
5864396437dSToby Isaac   PetscFunctionBegin;
5879566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
5889566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_TRUE));
5899566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
5903ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5914396437dSToby Isaac }
5924396437dSToby Isaac 
593d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Cholesky(Mat A, Vec xx, Vec yy)
594d71ae5a4SJacob Faibussowitsch {
595e54beecaSStefano Zampini   PetscScalar *y = NULL;
596e54beecaSStefano Zampini   PetscBLASInt m = 0, k = 0;
5974396437dSToby Isaac 
5984396437dSToby Isaac   PetscFunctionBegin;
5999566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6009566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_FALSE));
6019566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6023ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6034396437dSToby Isaac }
6044396437dSToby Isaac 
605d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_Cholesky(Mat A, Vec xx, Vec yy)
606d71ae5a4SJacob Faibussowitsch {
607e54beecaSStefano Zampini   PetscScalar *y = NULL;
608e54beecaSStefano Zampini   PetscBLASInt m = 0, k = 0;
6094396437dSToby Isaac 
6104396437dSToby Isaac   PetscFunctionBegin;
6119566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6129566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_TRUE));
6139566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6154396437dSToby Isaac }
6164396437dSToby Isaac 
617d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_QR(Mat A, Vec xx, Vec yy)
618d71ae5a4SJacob Faibussowitsch {
619e54beecaSStefano Zampini   PetscScalar *y = NULL;
620e54beecaSStefano Zampini   PetscBLASInt m = 0, k = 0;
6214396437dSToby Isaac 
6224396437dSToby Isaac   PetscFunctionBegin;
6239566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6249566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k));
6259566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6274396437dSToby Isaac }
6284396437dSToby Isaac 
629d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_QR(Mat A, Vec xx, Vec yy)
630d71ae5a4SJacob Faibussowitsch {
63142e9364cSSatish Balay   PetscScalar *y = NULL;
63242e9364cSSatish Balay   PetscBLASInt m = 0, k = 0;
6334396437dSToby Isaac 
6344396437dSToby Isaac   PetscFunctionBegin;
6359566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6369566063dSJacob Faibussowitsch   PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k));
6379566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6394396437dSToby Isaac }
6404396437dSToby Isaac 
641d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_SetUp(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k)
642d71ae5a4SJacob Faibussowitsch {
6434905a7bcSToby Isaac   const PetscScalar *b;
6444396437dSToby Isaac   PetscScalar       *y;
645bf5a80bcSToby Isaac   PetscInt           n, _ldb, _ldx;
646bf5a80bcSToby Isaac   PetscBLASInt       nrhs = 0, m = 0, k = 0, ldb = 0, ldx = 0, ldy = 0;
6474905a7bcSToby Isaac 
6484905a7bcSToby Isaac   PetscFunctionBegin;
6499371c9d4SSatish Balay   *_ldy  = 0;
6509371c9d4SSatish Balay   *_m    = 0;
6519371c9d4SSatish Balay   *_nrhs = 0;
6529371c9d4SSatish Balay   *_k    = 0;
6539371c9d4SSatish Balay   *_y    = NULL;
6549566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
6559566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &k));
6569566063dSJacob Faibussowitsch   PetscCall(MatGetSize(B, NULL, &n));
6579566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(n, &nrhs));
6589566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(B, &_ldb));
6599566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldb, &ldb));
6609566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(X, &_ldx));
6619566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldx, &ldx));
662bf5a80bcSToby Isaac   if (ldx < m) {
6639566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(B, &b));
6649566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nrhs * m, &y));
665bf5a80bcSToby Isaac     if (ldb == m) {
6669566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(y, b, ldb * nrhs));
6674905a7bcSToby Isaac     } else {
66848a46eb9SPierre Jolivet       for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * m], &b[j * ldb], m));
6694905a7bcSToby Isaac     }
670bf5a80bcSToby Isaac     ldy = m;
6719566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(B, &b));
6724905a7bcSToby Isaac   } else {
673bf5a80bcSToby Isaac     if (ldb == ldx) {
6749566063dSJacob Faibussowitsch       PetscCall(MatCopy(B, X, SAME_NONZERO_PATTERN));
6759566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(X, &y));
6764905a7bcSToby Isaac     } else {
6779566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(X, &y));
6789566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArrayRead(B, &b));
67948a46eb9SPierre Jolivet       for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * ldx], &b[j * ldb], m));
6809566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArrayRead(B, &b));
6814905a7bcSToby Isaac     }
682bf5a80bcSToby Isaac     ldy = ldx;
6834905a7bcSToby Isaac   }
6844396437dSToby Isaac   *_y    = y;
685bf5a80bcSToby Isaac   *_ldy  = ldy;
6864396437dSToby Isaac   *_k    = k;
6874396437dSToby Isaac   *_m    = m;
6884396437dSToby Isaac   *_nrhs = nrhs;
6893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6904396437dSToby Isaac }
6914396437dSToby Isaac 
692d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_TearDown(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k)
693d71ae5a4SJacob Faibussowitsch {
6944396437dSToby Isaac   PetscScalar *y;
695bf5a80bcSToby Isaac   PetscInt     _ldx;
696bf5a80bcSToby Isaac   PetscBLASInt k, ldy, nrhs, ldx = 0;
6974396437dSToby Isaac 
6984396437dSToby Isaac   PetscFunctionBegin;
6994396437dSToby Isaac   y    = *_y;
7004396437dSToby Isaac   *_y  = NULL;
7014396437dSToby Isaac   k    = *_k;
702bf5a80bcSToby Isaac   ldy  = *_ldy;
7034396437dSToby Isaac   nrhs = *_nrhs;
7049566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(X, &_ldx));
7059566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldx, &ldx));
706bf5a80bcSToby Isaac   if (ldx != ldy) {
7074905a7bcSToby Isaac     PetscScalar *xv;
7089566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArray(X, &xv));
70948a46eb9SPierre Jolivet     for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&xv[j * ldx], &y[j * ldy], k));
7109566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(X, &xv));
7119566063dSJacob Faibussowitsch     PetscCall(PetscFree(y));
7124905a7bcSToby Isaac   } else {
7139566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(X, &y));
7144905a7bcSToby Isaac   }
7153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
71685e2c93fSHong Zhang }
71785e2c93fSHong Zhang 
718d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_LU(Mat A, Mat B, Mat X)
719d71ae5a4SJacob Faibussowitsch {
7204396437dSToby Isaac   PetscScalar *y;
721bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7224396437dSToby Isaac 
7234396437dSToby Isaac   PetscFunctionBegin;
7249566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7259566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_FALSE));
7269566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7273ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7284396437dSToby Isaac }
7294396437dSToby Isaac 
730d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_LU(Mat A, Mat B, Mat X)
731d71ae5a4SJacob Faibussowitsch {
7324396437dSToby Isaac   PetscScalar *y;
733bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7344396437dSToby Isaac 
7354396437dSToby Isaac   PetscFunctionBegin;
7369566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7379566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_TRUE));
7389566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7393ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7404396437dSToby Isaac }
7414396437dSToby Isaac 
742d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_Cholesky(Mat A, Mat B, Mat X)
743d71ae5a4SJacob Faibussowitsch {
7444396437dSToby Isaac   PetscScalar *y;
745bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7464396437dSToby Isaac 
7474396437dSToby Isaac   PetscFunctionBegin;
7489566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7499566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_FALSE));
7509566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7524396437dSToby Isaac }
7534396437dSToby Isaac 
754d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_Cholesky(Mat A, Mat B, Mat X)
755d71ae5a4SJacob Faibussowitsch {
7564396437dSToby Isaac   PetscScalar *y;
757bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7584396437dSToby Isaac 
7594396437dSToby Isaac   PetscFunctionBegin;
7609566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7619566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_TRUE));
7629566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7633ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7644396437dSToby Isaac }
7654396437dSToby Isaac 
766d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_QR(Mat A, Mat B, Mat X)
767d71ae5a4SJacob Faibussowitsch {
7684396437dSToby Isaac   PetscScalar *y;
769bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7704396437dSToby Isaac 
7714396437dSToby Isaac   PetscFunctionBegin;
7729566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7739566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k));
7749566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7764396437dSToby Isaac }
7774396437dSToby Isaac 
778d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_QR(Mat A, Mat B, Mat X)
779d71ae5a4SJacob Faibussowitsch {
7804396437dSToby Isaac   PetscScalar *y;
781bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7824396437dSToby Isaac 
7834396437dSToby Isaac   PetscFunctionBegin;
7849566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7859566063dSJacob Faibussowitsch   PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k));
7869566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7873ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7884396437dSToby Isaac }
7894396437dSToby Isaac 
790db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots,
791db4efbfdSBarry Smith    rather than put it in the Mat->row slot.*/
792d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLUFactor_SeqDense(Mat A, IS row, IS col, const MatFactorInfo *minfo)
793d71ae5a4SJacob Faibussowitsch {
794db4efbfdSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
795db4efbfdSBarry Smith   PetscBLASInt  n, m, info;
796db4efbfdSBarry Smith 
797db4efbfdSBarry Smith   PetscFunctionBegin;
7989566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
7999566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
8004dfa11a4SJacob Faibussowitsch   if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); }
8013ba16761SJacob Faibussowitsch   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS);
8029566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
803792fecdfSBarry Smith   PetscCallBLAS("LAPACKgetrf", LAPACKgetrf_(&m, &n, mat->v, &mat->lda, mat->pivots, &info));
8049566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
8058e57ea43SSatish Balay 
80605fcb23eSStefano Zampini   PetscCheck(info >= 0, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to LU factorization %d", (int)info);
80705fcb23eSStefano Zampini   PetscCheck(info <= 0, PETSC_COMM_SELF, PETSC_ERR_MAT_LU_ZRPVT, "Bad LU factorization %d", (int)info);
8088208b9aeSStefano Zampini 
8094396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_LU;
8104396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_LU;
8114396437dSToby Isaac   A->ops->solvetranspose    = MatSolveTranspose_SeqDense_LU;
8124396437dSToby Isaac   A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_LU;
813d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_LU;
814db4efbfdSBarry Smith 
8159566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
8169566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype));
817f6224b95SHong Zhang 
8189566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops((2.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3));
8193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
820db4efbfdSBarry Smith }
821db4efbfdSBarry Smith 
822d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy)
823d71ae5a4SJacob Faibussowitsch {
8244396437dSToby Isaac   MatFactorInfo info;
8254396437dSToby Isaac 
8264396437dSToby Isaac   PetscFunctionBegin;
8279566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES));
828dbbe0bcdSBarry Smith   PetscUseTypeMethod(fact, lufactor, NULL, NULL, &info);
8293ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8304396437dSToby Isaac }
8314396437dSToby Isaac 
832d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, IS col, const MatFactorInfo *info)
833d71ae5a4SJacob Faibussowitsch {
8344396437dSToby Isaac   PetscFunctionBegin;
8354396437dSToby Isaac   fact->preallocated         = PETSC_TRUE;
8364396437dSToby Isaac   fact->assembled            = PETSC_TRUE;
8374396437dSToby Isaac   fact->ops->lufactornumeric = MatLUFactorNumeric_SeqDense;
8383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8394396437dSToby Isaac }
8404396437dSToby Isaac 
841a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */
842d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCholeskyFactor_SeqDense(Mat A, IS perm, const MatFactorInfo *factinfo)
843d71ae5a4SJacob Faibussowitsch {
844db4efbfdSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
845c5df96a5SBarry Smith   PetscBLASInt  info, n;
846db4efbfdSBarry Smith 
847db4efbfdSBarry Smith   PetscFunctionBegin;
8489566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
8493ba16761SJacob Faibussowitsch   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS);
850b94d7dedSBarry Smith   if (A->spd == PETSC_BOOL3_TRUE) {
8519566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
852792fecdfSBarry Smith     PetscCallBLAS("LAPACKpotrf", LAPACKpotrf_("L", &n, mat->v, &mat->lda, &info));
8539566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
854a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
855b94d7dedSBarry Smith   } else if (A->hermitian == PETSC_BOOL3_TRUE) {
8564dfa11a4SJacob Faibussowitsch     if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); }
857a49dc2a2SStefano Zampini     if (!mat->fwork) {
858a49dc2a2SStefano Zampini       PetscScalar dummy;
859a49dc2a2SStefano Zampini 
860a49dc2a2SStefano Zampini       mat->lfwork = -1;
8619566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
862792fecdfSBarry Smith       PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info));
8639566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
864a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
8659566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
866a49dc2a2SStefano Zampini     }
8679566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
868792fecdfSBarry Smith     PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info));
8699566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
870a49dc2a2SStefano Zampini #endif
871a49dc2a2SStefano Zampini   } else { /* symmetric case */
8724dfa11a4SJacob Faibussowitsch     if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); }
873a49dc2a2SStefano Zampini     if (!mat->fwork) {
874a49dc2a2SStefano Zampini       PetscScalar dummy;
875a49dc2a2SStefano Zampini 
876a49dc2a2SStefano Zampini       mat->lfwork = -1;
8779566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
878792fecdfSBarry Smith       PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info));
8799566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
880a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
8819566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
882a49dc2a2SStefano Zampini     }
8839566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
884792fecdfSBarry Smith     PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info));
8859566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
886a49dc2a2SStefano Zampini   }
88728b400f6SJacob Faibussowitsch   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad factorization: zero pivot in row %" PetscInt_FMT, (PetscInt)info - 1);
8888208b9aeSStefano Zampini 
8894396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_Cholesky;
8904396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_Cholesky;
8914396437dSToby Isaac   A->ops->solvetranspose    = MatSolveTranspose_SeqDense_Cholesky;
8924396437dSToby Isaac   A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_Cholesky;
893d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_CHOLESKY;
8942205254eSKarl Rupp 
8959566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
8969566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype));
897f6224b95SHong Zhang 
8989566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0));
8993ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
900db4efbfdSBarry Smith }
901db4efbfdSBarry Smith 
902d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy)
903d71ae5a4SJacob Faibussowitsch {
904db4efbfdSBarry Smith   MatFactorInfo info;
905db4efbfdSBarry Smith 
906db4efbfdSBarry Smith   PetscFunctionBegin;
907db4efbfdSBarry Smith   info.fill = 1.0;
9082205254eSKarl Rupp 
9099566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES));
910dbbe0bcdSBarry Smith   PetscUseTypeMethod(fact, choleskyfactor, NULL, &info);
9113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
912db4efbfdSBarry Smith }
913db4efbfdSBarry Smith 
914d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info)
915d71ae5a4SJacob Faibussowitsch {
916db4efbfdSBarry Smith   PetscFunctionBegin;
917c3ef05f6SHong Zhang   fact->assembled                  = PETSC_TRUE;
9181bbcc794SSatish Balay   fact->preallocated               = PETSC_TRUE;
919719d5645SBarry Smith   fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense;
9203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
921db4efbfdSBarry Smith }
922db4efbfdSBarry Smith 
923d71ae5a4SJacob Faibussowitsch PetscErrorCode MatQRFactor_SeqDense(Mat A, IS col, const MatFactorInfo *minfo)
924d71ae5a4SJacob Faibussowitsch {
9254905a7bcSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
9264905a7bcSToby Isaac   PetscBLASInt  n, m, info, min, max;
9274905a7bcSToby Isaac 
9284905a7bcSToby Isaac   PetscFunctionBegin;
9299566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
9309566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
9314396437dSToby Isaac   max = PetscMax(m, n);
9324396437dSToby Isaac   min = PetscMin(m, n);
9334dfa11a4SJacob Faibussowitsch   if (!mat->tau) { PetscCall(PetscMalloc1(min, &mat->tau)); }
9344dfa11a4SJacob Faibussowitsch   if (!mat->pivots) { PetscCall(PetscMalloc1(n, &mat->pivots)); }
93548a46eb9SPierre Jolivet   if (!mat->qrrhs) PetscCall(MatCreateVecs(A, NULL, &(mat->qrrhs)));
9363ba16761SJacob Faibussowitsch   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS);
9374905a7bcSToby Isaac   if (!mat->fwork) {
9384905a7bcSToby Isaac     PetscScalar dummy;
9394905a7bcSToby Isaac 
9404905a7bcSToby Isaac     mat->lfwork = -1;
9419566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
942792fecdfSBarry Smith     PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, &dummy, &mat->lfwork, &info));
9439566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
9444905a7bcSToby Isaac     mat->lfwork = (PetscInt)PetscRealPart(dummy);
9459566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
9464905a7bcSToby Isaac   }
9479566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
948792fecdfSBarry Smith   PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, mat->fwork, &mat->lfwork, &info));
9499566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
95005fcb23eSStefano Zampini   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to QR factorization %d", (int)info);
9514905a7bcSToby 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
9524905a7bcSToby Isaac   mat->rank = min;
9534905a7bcSToby Isaac 
9544396437dSToby Isaac   A->ops->solve    = MatSolve_SeqDense_QR;
9554396437dSToby Isaac   A->ops->matsolve = MatMatSolve_SeqDense_QR;
9564905a7bcSToby Isaac   A->factortype    = MAT_FACTOR_QR;
9574905a7bcSToby Isaac   if (m == n) {
9584396437dSToby Isaac     A->ops->solvetranspose    = MatSolveTranspose_SeqDense_QR;
9594396437dSToby Isaac     A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_QR;
9604905a7bcSToby Isaac   }
9614905a7bcSToby Isaac 
9629566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
9639566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype));
9644905a7bcSToby Isaac 
9659566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0 * min * min * (max - min / 3.0)));
9663ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9674905a7bcSToby Isaac }
9684905a7bcSToby Isaac 
969d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatQRFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy)
970d71ae5a4SJacob Faibussowitsch {
9714905a7bcSToby Isaac   MatFactorInfo info;
9724905a7bcSToby Isaac 
9734905a7bcSToby Isaac   PetscFunctionBegin;
9744905a7bcSToby Isaac   info.fill = 1.0;
9754905a7bcSToby Isaac 
9769566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES));
977cac4c232SBarry Smith   PetscUseMethod(fact, "MatQRFactor_C", (Mat, IS, const MatFactorInfo *), (fact, NULL, &info));
9783ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9794905a7bcSToby Isaac }
9804905a7bcSToby Isaac 
981d71ae5a4SJacob Faibussowitsch PetscErrorCode MatQRFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info)
982d71ae5a4SJacob Faibussowitsch {
9834905a7bcSToby Isaac   PetscFunctionBegin;
9844905a7bcSToby Isaac   fact->assembled    = PETSC_TRUE;
9854905a7bcSToby Isaac   fact->preallocated = PETSC_TRUE;
9869566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)fact, "MatQRFactorNumeric_C", MatQRFactorNumeric_SeqDense));
9873ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9884905a7bcSToby Isaac }
9894905a7bcSToby Isaac 
990ca15aa20SStefano Zampini /* uses LAPACK */
991d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A, MatFactorType ftype, Mat *fact)
992d71ae5a4SJacob Faibussowitsch {
993db4efbfdSBarry Smith   PetscFunctionBegin;
9949566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), fact));
9959566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*fact, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n));
9969566063dSJacob Faibussowitsch   PetscCall(MatSetType(*fact, MATDENSE));
99766e17bc3SBarry Smith   (*fact)->trivialsymbolic = PETSC_TRUE;
9982a350339SBarry Smith   if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU) {
999db4efbfdSBarry Smith     (*fact)->ops->lufactorsymbolic  = MatLUFactorSymbolic_SeqDense;
10002a350339SBarry Smith     (*fact)->ops->ilufactorsymbolic = MatLUFactorSymbolic_SeqDense;
1001bf5a80bcSToby Isaac   } else if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) {
1002db4efbfdSBarry Smith     (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense;
1003bf5a80bcSToby Isaac   } else if (ftype == MAT_FACTOR_QR) {
10049566063dSJacob Faibussowitsch     PetscCall(PetscObjectComposeFunction((PetscObject)(*fact), "MatQRFactorSymbolic_C", MatQRFactorSymbolic_SeqDense));
1005db4efbfdSBarry Smith   }
1006d5f3da31SBarry Smith   (*fact)->factortype = ftype;
100700c67f3bSHong Zhang 
10089566063dSJacob Faibussowitsch   PetscCall(PetscFree((*fact)->solvertype));
10099566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC, &(*fact)->solvertype));
10109566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_LU]));
10119566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ILU]));
10129566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_CHOLESKY]));
10139566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ICC]));
10143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1015db4efbfdSBarry Smith }
1016db4efbfdSBarry Smith 
1017d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSOR_SeqDense(Mat A, Vec bb, PetscReal omega, MatSORType flag, PetscReal shift, PetscInt its, PetscInt lits, Vec xx)
1018d71ae5a4SJacob Faibussowitsch {
1019c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1020d9ca1df4SBarry Smith   PetscScalar       *x, *v = mat->v, zero = 0.0, xt;
1021d9ca1df4SBarry Smith   const PetscScalar *b;
1022d0f46423SBarry Smith   PetscInt           m = A->rmap->n, i;
102323fff9afSBarry Smith   PetscBLASInt       o = 1, bm = 0;
1024289bc588SBarry Smith 
10253a40ed3dSBarry Smith   PetscFunctionBegin;
102647d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
102708401ef6SPierre Jolivet   PetscCheck(A->offloadmask != PETSC_OFFLOAD_GPU, PETSC_COMM_SELF, PETSC_ERR_SUP, "Not implemented");
1028ca15aa20SStefano Zampini #endif
1029422a814eSBarry Smith   if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */
10309566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(m, &bm));
1031289bc588SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
10323bffc371SBarry Smith     /* this is a hack fix, should have another version without the second BLASdotu */
10339566063dSJacob Faibussowitsch     PetscCall(VecSet(xx, zero));
1034289bc588SBarry Smith   }
10359566063dSJacob Faibussowitsch   PetscCall(VecGetArray(xx, &x));
10369566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(bb, &b));
1037b965ef7fSBarry Smith   its = its * lits;
103808401ef6SPierre 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);
1039289bc588SBarry Smith   while (its--) {
1040fccaa45eSBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
1041289bc588SBarry Smith       for (i = 0; i < m; i++) {
1042792fecdfSBarry Smith         PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o));
104355a1b374SBarry Smith         x[i] = (1. - omega) * x[i] + omega * (xt + v[i + i * m] * x[i]) / (v[i + i * m] + shift);
1044289bc588SBarry Smith       }
1045289bc588SBarry Smith     }
1046fccaa45eSBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
1047289bc588SBarry Smith       for (i = m - 1; i >= 0; i--) {
1048792fecdfSBarry Smith         PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o));
104955a1b374SBarry Smith         x[i] = (1. - omega) * x[i] + omega * (xt + v[i + i * m] * x[i]) / (v[i + i * m] + shift);
1050289bc588SBarry Smith       }
1051289bc588SBarry Smith     }
1052289bc588SBarry Smith   }
10539566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(bb, &b));
10549566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(xx, &x));
10553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1056289bc588SBarry Smith }
1057289bc588SBarry Smith 
1058d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultTranspose_SeqDense(Mat A, Vec xx, Vec yy)
1059d71ae5a4SJacob Faibussowitsch {
1060c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1061d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v, *x;
1062d9ca1df4SBarry Smith   PetscScalar       *y;
10630805154bSBarry Smith   PetscBLASInt       m, n, _One = 1;
1064ea709b57SSatish Balay   PetscScalar        _DOne = 1.0, _DZero = 0.0;
10653a40ed3dSBarry Smith 
10663a40ed3dSBarry Smith   PetscFunctionBegin;
10679566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
10689566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
10699566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx, &x));
10709566063dSJacob Faibussowitsch   PetscCall(VecGetArrayWrite(yy, &y));
10715ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
10725ac36cfcSBarry Smith     PetscBLASInt i;
10735ac36cfcSBarry Smith     for (i = 0; i < n; i++) y[i] = 0.0;
10745ac36cfcSBarry Smith   } else {
1075792fecdfSBarry Smith     PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v, &mat->lda, x, &_One, &_DZero, y, &_One));
10769566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n - A->cmap->n));
10775ac36cfcSBarry Smith   }
10789566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx, &x));
10799566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayWrite(yy, &y));
10803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1081289bc588SBarry Smith }
1082800995b7SMatthew Knepley 
1083d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMult_SeqDense(Mat A, Vec xx, Vec yy)
1084d71ae5a4SJacob Faibussowitsch {
1085c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1086d9ca1df4SBarry Smith   PetscScalar       *y, _DOne = 1.0, _DZero = 0.0;
10870805154bSBarry Smith   PetscBLASInt       m, n, _One             = 1;
1088d9ca1df4SBarry Smith   const PetscScalar *v = mat->v, *x;
10893a40ed3dSBarry Smith 
10903a40ed3dSBarry Smith   PetscFunctionBegin;
10919566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
10929566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
10939566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx, &x));
10949566063dSJacob Faibussowitsch   PetscCall(VecGetArrayWrite(yy, &y));
10955ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
10965ac36cfcSBarry Smith     PetscBLASInt i;
10975ac36cfcSBarry Smith     for (i = 0; i < m; i++) y[i] = 0.0;
10985ac36cfcSBarry Smith   } else {
1099792fecdfSBarry Smith     PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DZero, y, &_One));
11009566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n - A->rmap->n));
11015ac36cfcSBarry Smith   }
11029566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx, &x));
11039566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayWrite(yy, &y));
11043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1105289bc588SBarry Smith }
11066ee01492SSatish Balay 
1107d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy)
1108d71ae5a4SJacob Faibussowitsch {
1109c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1110d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v, *x;
1111d9ca1df4SBarry Smith   PetscScalar       *y, _DOne = 1.0;
11120805154bSBarry Smith   PetscBLASInt       m, n, _One = 1;
11133a40ed3dSBarry Smith 
11143a40ed3dSBarry Smith   PetscFunctionBegin;
11159566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
11169566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
11179566063dSJacob Faibussowitsch   PetscCall(VecCopy(zz, yy));
11183ba16761SJacob Faibussowitsch   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS);
11199566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx, &x));
11209566063dSJacob Faibussowitsch   PetscCall(VecGetArray(yy, &y));
1121792fecdfSBarry Smith   PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DOne, y, &_One));
11229566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx, &x));
11239566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(yy, &y));
11249566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n));
11253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1126289bc588SBarry Smith }
11276ee01492SSatish Balay 
1128d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy)
1129d71ae5a4SJacob Faibussowitsch {
1130c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1131d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v, *x;
1132d9ca1df4SBarry Smith   PetscScalar       *y;
11330805154bSBarry Smith   PetscBLASInt       m, n, _One = 1;
113487828ca2SBarry Smith   PetscScalar        _DOne = 1.0;
11353a40ed3dSBarry Smith 
11363a40ed3dSBarry Smith   PetscFunctionBegin;
11379566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
11389566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
11399566063dSJacob Faibussowitsch   PetscCall(VecCopy(zz, yy));
11403ba16761SJacob Faibussowitsch   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS);
11419566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx, &x));
11429566063dSJacob Faibussowitsch   PetscCall(VecGetArray(yy, &y));
1143792fecdfSBarry Smith   PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DOne, y, &_One));
11449566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx, &x));
11459566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(yy, &y));
11469566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n));
11473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1148289bc588SBarry Smith }
1149289bc588SBarry Smith 
1150d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals)
1151d71ae5a4SJacob Faibussowitsch {
1152c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
115313f74950SBarry Smith   PetscInt      i;
115467e560aaSBarry Smith 
11553a40ed3dSBarry Smith   PetscFunctionBegin;
1156d0f46423SBarry Smith   *ncols = A->cmap->n;
1157289bc588SBarry Smith   if (cols) {
11589566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(A->cmap->n, cols));
1159d0f46423SBarry Smith     for (i = 0; i < A->cmap->n; i++) (*cols)[i] = i;
1160289bc588SBarry Smith   }
1161289bc588SBarry Smith   if (vals) {
1162ca15aa20SStefano Zampini     const PetscScalar *v;
1163ca15aa20SStefano Zampini 
11649566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A, &v));
11659566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(A->cmap->n, vals));
1166ca15aa20SStefano Zampini     v += row;
11679371c9d4SSatish Balay     for (i = 0; i < A->cmap->n; i++) {
11689371c9d4SSatish Balay       (*vals)[i] = *v;
11699371c9d4SSatish Balay       v += mat->lda;
11709371c9d4SSatish Balay     }
11719566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A, &v));
1172289bc588SBarry Smith   }
11733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1174289bc588SBarry Smith }
11756ee01492SSatish Balay 
1176d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRestoreRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals)
1177d71ae5a4SJacob Faibussowitsch {
1178606d414cSSatish Balay   PetscFunctionBegin;
1179cb4a9cd9SHong Zhang   if (ncols) *ncols = 0;
11809566063dSJacob Faibussowitsch   if (cols) PetscCall(PetscFree(*cols));
11819566063dSJacob Faibussowitsch   if (vals) PetscCall(PetscFree(*vals));
11823ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1183289bc588SBarry Smith }
11842ef1f0ffSBarry Smith 
1185d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], const PetscScalar v[], InsertMode addv)
1186d71ae5a4SJacob Faibussowitsch {
1187c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
1188ca15aa20SStefano Zampini   PetscScalar  *av;
118913f74950SBarry Smith   PetscInt      i, j, idx = 0;
119047d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
1191c70f7ee4SJunchao Zhang   PetscOffloadMask oldf;
1192ca15aa20SStefano Zampini #endif
1193d6dfbf8fSBarry Smith 
11943a40ed3dSBarry Smith   PetscFunctionBegin;
11959566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &av));
1196289bc588SBarry Smith   if (!mat->roworiented) {
1197dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1198289bc588SBarry Smith       for (j = 0; j < n; j++) {
11999371c9d4SSatish Balay         if (indexn[j] < 0) {
12009371c9d4SSatish Balay           idx += m;
12019371c9d4SSatish Balay           continue;
12029371c9d4SSatish Balay         }
12036bdcaf15SBarry 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);
1204289bc588SBarry Smith         for (i = 0; i < m; i++) {
12059371c9d4SSatish Balay           if (indexm[i] < 0) {
12069371c9d4SSatish Balay             idx++;
12079371c9d4SSatish Balay             continue;
12089371c9d4SSatish Balay           }
12096bdcaf15SBarry 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);
1210ca15aa20SStefano Zampini           av[indexn[j] * mat->lda + indexm[i]] = v[idx++];
1211289bc588SBarry Smith         }
1212289bc588SBarry Smith       }
12133a40ed3dSBarry Smith     } else {
1214289bc588SBarry Smith       for (j = 0; j < n; j++) {
12159371c9d4SSatish Balay         if (indexn[j] < 0) {
12169371c9d4SSatish Balay           idx += m;
12179371c9d4SSatish Balay           continue;
12189371c9d4SSatish Balay         }
12196bdcaf15SBarry 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);
1220289bc588SBarry Smith         for (i = 0; i < m; i++) {
12219371c9d4SSatish Balay           if (indexm[i] < 0) {
12229371c9d4SSatish Balay             idx++;
12239371c9d4SSatish Balay             continue;
12249371c9d4SSatish Balay           }
12256bdcaf15SBarry 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);
1226ca15aa20SStefano Zampini           av[indexn[j] * mat->lda + indexm[i]] += v[idx++];
1227289bc588SBarry Smith         }
1228289bc588SBarry Smith       }
1229289bc588SBarry Smith     }
12303a40ed3dSBarry Smith   } else {
1231dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1232e8d4e0b9SBarry Smith       for (i = 0; i < m; i++) {
12339371c9d4SSatish Balay         if (indexm[i] < 0) {
12349371c9d4SSatish Balay           idx += n;
12359371c9d4SSatish Balay           continue;
12369371c9d4SSatish Balay         }
12376bdcaf15SBarry 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);
1238e8d4e0b9SBarry Smith         for (j = 0; j < n; j++) {
12399371c9d4SSatish Balay           if (indexn[j] < 0) {
12409371c9d4SSatish Balay             idx++;
12419371c9d4SSatish Balay             continue;
12429371c9d4SSatish Balay           }
12436bdcaf15SBarry 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);
1244ca15aa20SStefano Zampini           av[indexn[j] * mat->lda + indexm[i]] = v[idx++];
1245e8d4e0b9SBarry Smith         }
1246e8d4e0b9SBarry Smith       }
12473a40ed3dSBarry Smith     } else {
1248289bc588SBarry Smith       for (i = 0; i < m; i++) {
12499371c9d4SSatish Balay         if (indexm[i] < 0) {
12509371c9d4SSatish Balay           idx += n;
12519371c9d4SSatish Balay           continue;
12529371c9d4SSatish Balay         }
12536bdcaf15SBarry 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);
1254289bc588SBarry Smith         for (j = 0; j < n; j++) {
12559371c9d4SSatish Balay           if (indexn[j] < 0) {
12569371c9d4SSatish Balay             idx++;
12579371c9d4SSatish Balay             continue;
12589371c9d4SSatish Balay           }
12596bdcaf15SBarry 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);
1260ca15aa20SStefano Zampini           av[indexn[j] * mat->lda + indexm[i]] += v[idx++];
1261289bc588SBarry Smith         }
1262289bc588SBarry Smith       }
1263289bc588SBarry Smith     }
1264e8d4e0b9SBarry Smith   }
1265ca15aa20SStefano Zampini   /* hack to prevent unneeded copy to the GPU while returning the array */
126647d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
1267c70f7ee4SJunchao Zhang   oldf           = A->offloadmask;
1268c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_GPU;
1269ca15aa20SStefano Zampini #endif
12709566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &av));
127147d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
1272c70f7ee4SJunchao Zhang   A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU);
1273ca15aa20SStefano Zampini #endif
12743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1275289bc588SBarry Smith }
1276e8d4e0b9SBarry Smith 
1277d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], PetscScalar v[])
1278d71ae5a4SJacob Faibussowitsch {
1279ae80bb75SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1280ca15aa20SStefano Zampini   const PetscScalar *vv;
128113f74950SBarry Smith   PetscInt           i, j;
1282ae80bb75SLois Curfman McInnes 
12833a40ed3dSBarry Smith   PetscFunctionBegin;
12849566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &vv));
1285ae80bb75SLois Curfman McInnes   /* row-oriented output */
1286ae80bb75SLois Curfman McInnes   for (i = 0; i < m; i++) {
12879371c9d4SSatish Balay     if (indexm[i] < 0) {
12889371c9d4SSatish Balay       v += n;
12899371c9d4SSatish Balay       continue;
12909371c9d4SSatish Balay     }
129108401ef6SPierre 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);
1292ae80bb75SLois Curfman McInnes     for (j = 0; j < n; j++) {
12939371c9d4SSatish Balay       if (indexn[j] < 0) {
12949371c9d4SSatish Balay         v++;
12959371c9d4SSatish Balay         continue;
12969371c9d4SSatish Balay       }
129708401ef6SPierre 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);
1298ca15aa20SStefano Zampini       *v++ = vv[indexn[j] * mat->lda + indexm[i]];
1299ae80bb75SLois Curfman McInnes     }
1300ae80bb75SLois Curfman McInnes   }
13019566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &vv));
13023ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1303ae80bb75SLois Curfman McInnes }
1304ae80bb75SLois Curfman McInnes 
1305d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_Dense_Binary(Mat mat, PetscViewer viewer)
1306d71ae5a4SJacob Faibussowitsch {
13078491ab44SLisandro Dalcin   PetscBool          skipHeader;
13088491ab44SLisandro Dalcin   PetscViewerFormat  format;
13098491ab44SLisandro Dalcin   PetscInt           header[4], M, N, m, lda, i, j, k;
13108491ab44SLisandro Dalcin   const PetscScalar *v;
13118491ab44SLisandro Dalcin   PetscScalar       *vwork;
1312aabbc4fbSShri Abhyankar 
1313aabbc4fbSShri Abhyankar   PetscFunctionBegin;
13149566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
13159566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader));
13169566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
13178491ab44SLisandro Dalcin   if (skipHeader) format = PETSC_VIEWER_NATIVE;
1318aabbc4fbSShri Abhyankar 
13199566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat, &M, &N));
13208491ab44SLisandro Dalcin 
13218491ab44SLisandro Dalcin   /* write matrix header */
13229371c9d4SSatish Balay   header[0] = MAT_FILE_CLASSID;
13239371c9d4SSatish Balay   header[1] = M;
13249371c9d4SSatish Balay   header[2] = N;
13258491ab44SLisandro Dalcin   header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M * N;
13269566063dSJacob Faibussowitsch   if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer, header, 4, PETSC_INT));
13278491ab44SLisandro Dalcin 
13289566063dSJacob Faibussowitsch   PetscCall(MatGetLocalSize(mat, &m, NULL));
13298491ab44SLisandro Dalcin   if (format != PETSC_VIEWER_NATIVE) {
13308491ab44SLisandro Dalcin     PetscInt nnz = m * N, *iwork;
13318491ab44SLisandro Dalcin     /* store row lengths for each row */
13329566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nnz, &iwork));
13338491ab44SLisandro Dalcin     for (i = 0; i < m; i++) iwork[i] = N;
13349566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT));
13358491ab44SLisandro Dalcin     /* store column indices (zero start index) */
13368491ab44SLisandro Dalcin     for (k = 0, i = 0; i < m; i++)
13379371c9d4SSatish Balay       for (j = 0; j < N; j++, k++) iwork[k] = j;
13389566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT));
13399566063dSJacob Faibussowitsch     PetscCall(PetscFree(iwork));
13408491ab44SLisandro Dalcin   }
13418491ab44SLisandro Dalcin   /* store matrix values as a dense matrix in row major order */
13429566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(m * N, &vwork));
13439566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(mat, &v));
13449566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(mat, &lda));
13458491ab44SLisandro Dalcin   for (k = 0, i = 0; i < m; i++)
13469371c9d4SSatish Balay     for (j = 0; j < N; j++, k++) vwork[k] = v[i + lda * j];
13479566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(mat, &v));
13489566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryWriteAll(viewer, vwork, m * N, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR));
13499566063dSJacob Faibussowitsch   PetscCall(PetscFree(vwork));
13503ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13518491ab44SLisandro Dalcin }
13528491ab44SLisandro Dalcin 
1353d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLoad_Dense_Binary(Mat mat, PetscViewer viewer)
1354d71ae5a4SJacob Faibussowitsch {
13558491ab44SLisandro Dalcin   PetscBool    skipHeader;
13568491ab44SLisandro Dalcin   PetscInt     header[4], M, N, m, nz, lda, i, j, k;
13578491ab44SLisandro Dalcin   PetscInt     rows, cols;
13588491ab44SLisandro Dalcin   PetscScalar *v, *vwork;
13598491ab44SLisandro Dalcin 
13608491ab44SLisandro Dalcin   PetscFunctionBegin;
13619566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
13629566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader));
13638491ab44SLisandro Dalcin 
13648491ab44SLisandro Dalcin   if (!skipHeader) {
13659566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryRead(viewer, header, 4, NULL, PETSC_INT));
136608401ef6SPierre Jolivet     PetscCheck(header[0] == MAT_FILE_CLASSID, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Not a matrix object in file");
13679371c9d4SSatish Balay     M = header[1];
13689371c9d4SSatish Balay     N = header[2];
136908401ef6SPierre Jolivet     PetscCheck(M >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix row size (%" PetscInt_FMT ") in file is negative", M);
137008401ef6SPierre Jolivet     PetscCheck(N >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix column size (%" PetscInt_FMT ") in file is negative", N);
13718491ab44SLisandro Dalcin     nz = header[3];
1372aed4548fSBarry Smith     PetscCheck(nz == MATRIX_BINARY_FORMAT_DENSE || nz >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Unknown matrix format %" PetscInt_FMT " in file", nz);
1373aabbc4fbSShri Abhyankar   } else {
13749566063dSJacob Faibussowitsch     PetscCall(MatGetSize(mat, &M, &N));
1375aed4548fSBarry 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");
13768491ab44SLisandro Dalcin     nz = MATRIX_BINARY_FORMAT_DENSE;
1377e6324fbbSBarry Smith   }
1378aabbc4fbSShri Abhyankar 
13798491ab44SLisandro Dalcin   /* setup global sizes if not set */
13808491ab44SLisandro Dalcin   if (mat->rmap->N < 0) mat->rmap->N = M;
13818491ab44SLisandro Dalcin   if (mat->cmap->N < 0) mat->cmap->N = N;
13829566063dSJacob Faibussowitsch   PetscCall(MatSetUp(mat));
13838491ab44SLisandro Dalcin   /* check if global sizes are correct */
13849566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat, &rows, &cols));
1385aed4548fSBarry 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);
1386aabbc4fbSShri Abhyankar 
13879566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat, NULL, &N));
13889566063dSJacob Faibussowitsch   PetscCall(MatGetLocalSize(mat, &m, NULL));
13899566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(mat, &v));
13909566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(mat, &lda));
13918491ab44SLisandro Dalcin   if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense format */
13928491ab44SLisandro Dalcin     PetscInt nnz = m * N;
13938491ab44SLisandro Dalcin     /* read in matrix values */
13949566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nnz, &vwork));
13959566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR));
13968491ab44SLisandro Dalcin     /* store values in column major order */
13978491ab44SLisandro Dalcin     for (j = 0; j < N; j++)
13989371c9d4SSatish Balay       for (i = 0; i < m; i++) v[i + lda * j] = vwork[i * N + j];
13999566063dSJacob Faibussowitsch     PetscCall(PetscFree(vwork));
14008491ab44SLisandro Dalcin   } else { /* matrix in file is sparse format */
14018491ab44SLisandro Dalcin     PetscInt nnz = 0, *rlens, *icols;
14028491ab44SLisandro Dalcin     /* read in row lengths */
14039566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(m, &rlens));
14049566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer, rlens, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT));
14058491ab44SLisandro Dalcin     for (i = 0; i < m; i++) nnz += rlens[i];
14068491ab44SLisandro Dalcin     /* read in column indices and values */
14079566063dSJacob Faibussowitsch     PetscCall(PetscMalloc2(nnz, &icols, nnz, &vwork));
14089566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer, icols, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT));
14099566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR));
14108491ab44SLisandro Dalcin     /* store values in column major order */
14118491ab44SLisandro Dalcin     for (k = 0, i = 0; i < m; i++)
14129371c9d4SSatish Balay       for (j = 0; j < rlens[i]; j++, k++) v[i + lda * icols[k]] = vwork[k];
14139566063dSJacob Faibussowitsch     PetscCall(PetscFree(rlens));
14149566063dSJacob Faibussowitsch     PetscCall(PetscFree2(icols, vwork));
1415aabbc4fbSShri Abhyankar   }
14169566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(mat, &v));
14179566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY));
14189566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY));
14193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1420aabbc4fbSShri Abhyankar }
1421aabbc4fbSShri Abhyankar 
142266976f2fSJacob Faibussowitsch static PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer)
1423d71ae5a4SJacob Faibussowitsch {
1424eb91f321SVaclav Hapla   PetscBool isbinary, ishdf5;
1425eb91f321SVaclav Hapla 
1426eb91f321SVaclav Hapla   PetscFunctionBegin;
1427eb91f321SVaclav Hapla   PetscValidHeaderSpecific(newMat, MAT_CLASSID, 1);
1428eb91f321SVaclav Hapla   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
1429eb91f321SVaclav Hapla   /* force binary viewer to load .info file if it has not yet done so */
14309566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
14319566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
14329566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5));
1433eb91f321SVaclav Hapla   if (isbinary) {
14349566063dSJacob Faibussowitsch     PetscCall(MatLoad_Dense_Binary(newMat, viewer));
1435eb91f321SVaclav Hapla   } else if (ishdf5) {
1436eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5)
14379566063dSJacob Faibussowitsch     PetscCall(MatLoad_Dense_HDF5(newMat, viewer));
1438eb91f321SVaclav Hapla #else
1439eb91f321SVaclav Hapla     SETERRQ(PetscObjectComm((PetscObject)newMat), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5");
1440eb91f321SVaclav Hapla #endif
1441eb91f321SVaclav Hapla   } else {
144298921bdaSJacob Faibussowitsch     SETERRQ(PetscObjectComm((PetscObject)newMat), PETSC_ERR_SUP, "Viewer type %s not yet supported for reading %s matrices", ((PetscObject)viewer)->type_name, ((PetscObject)newMat)->type_name);
1443eb91f321SVaclav Hapla   }
14443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1445eb91f321SVaclav Hapla }
1446eb91f321SVaclav Hapla 
1447d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_ASCII(Mat A, PetscViewer viewer)
1448d71ae5a4SJacob Faibussowitsch {
1449932b0c3eSLois Curfman McInnes   Mat_SeqDense     *a = (Mat_SeqDense *)A->data;
145013f74950SBarry Smith   PetscInt          i, j;
14512dcb1b2aSMatthew Knepley   const char       *name;
1452ca15aa20SStefano Zampini   PetscScalar      *v, *av;
1453f3ef73ceSBarry Smith   PetscViewerFormat format;
14545f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX)
1455ace3abfcSBarry Smith   PetscBool allreal = PETSC_TRUE;
14565f481a85SSatish Balay #endif
1457932b0c3eSLois Curfman McInnes 
14583a40ed3dSBarry Smith   PetscFunctionBegin;
14599566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&av));
14609566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
1461456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
14623ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS); /* do nothing for now */
1463fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
14649566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
1465d0f46423SBarry Smith     for (i = 0; i < A->rmap->n; i++) {
1466ca15aa20SStefano Zampini       v = av + i;
14679566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "row %" PetscInt_FMT ":", i));
1468d0f46423SBarry Smith       for (j = 0; j < A->cmap->n; j++) {
1469aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1470329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
14719566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g + %g i) ", j, (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v)));
1472329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
14739566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)PetscRealPart(*v)));
14746831982aSBarry Smith         }
147580cd9d93SLois Curfman McInnes #else
147648a46eb9SPierre Jolivet         if (*v) PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)*v));
147780cd9d93SLois Curfman McInnes #endif
14781b807ce4Svictorle         v += a->lda;
147980cd9d93SLois Curfman McInnes       }
14809566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
148180cd9d93SLois Curfman McInnes     }
14829566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
14833a40ed3dSBarry Smith   } else {
14849566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
1485aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
148647989497SBarry Smith     /* determine if matrix has all real values */
1487bcd8d3a4SJose E. Roman     for (j = 0; j < A->cmap->n; j++) {
1488bcd8d3a4SJose E. Roman       v = av + j * a->lda;
1489bcd8d3a4SJose E. Roman       for (i = 0; i < A->rmap->n; i++) {
14909371c9d4SSatish Balay         if (PetscImaginaryPart(v[i])) {
14919371c9d4SSatish Balay           allreal = PETSC_FALSE;
14929371c9d4SSatish Balay           break;
14939371c9d4SSatish Balay         }
149447989497SBarry Smith       }
1495bcd8d3a4SJose E. Roman     }
149647989497SBarry Smith #endif
1497fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
14989566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetName((PetscObject)A, &name));
14999566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%% Size = %" PetscInt_FMT " %" PetscInt_FMT " \n", A->rmap->n, A->cmap->n));
15009566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%s = zeros(%" PetscInt_FMT ",%" PetscInt_FMT ");\n", name, A->rmap->n, A->cmap->n));
15019566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%s = [\n", name));
1502ffac6cdbSBarry Smith     }
1503ffac6cdbSBarry Smith 
1504d0f46423SBarry Smith     for (i = 0; i < A->rmap->n; i++) {
1505ca15aa20SStefano Zampini       v = av + i;
1506d0f46423SBarry Smith       for (j = 0; j < A->cmap->n; j++) {
1507aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
150847989497SBarry Smith         if (allreal) {
15099566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)PetscRealPart(*v)));
151047989497SBarry Smith         } else {
15119566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e + %18.16ei ", (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v)));
151247989497SBarry Smith         }
1513289bc588SBarry Smith #else
15149566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)*v));
1515289bc588SBarry Smith #endif
15161b807ce4Svictorle         v += a->lda;
1517289bc588SBarry Smith       }
15189566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
1519289bc588SBarry Smith     }
152048a46eb9SPierre Jolivet     if (format == PETSC_VIEWER_ASCII_MATLAB) PetscCall(PetscViewerASCIIPrintf(viewer, "];\n"));
15219566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
1522da3a660dSBarry Smith   }
15239566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&av));
15249566063dSJacob Faibussowitsch   PetscCall(PetscViewerFlush(viewer));
15253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1526289bc588SBarry Smith }
1527289bc588SBarry Smith 
15289804daf3SBarry Smith #include <petscdraw.h>
1529d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw, void *Aa)
1530d71ae5a4SJacob Faibussowitsch {
1531f1af5d2fSBarry Smith   Mat                A = (Mat)Aa;
1532383922c3SLisandro Dalcin   PetscInt           m = A->rmap->n, n = A->cmap->n, i, j;
1533383922c3SLisandro Dalcin   int                color = PETSC_DRAW_WHITE;
1534ca15aa20SStefano Zampini   const PetscScalar *v;
1535b0a32e0cSBarry Smith   PetscViewer        viewer;
1536b05fc000SLisandro Dalcin   PetscReal          xl, yl, xr, yr, x_l, x_r, y_l, y_r;
1537f3ef73ceSBarry Smith   PetscViewerFormat  format;
1538f1af5d2fSBarry Smith 
1539f1af5d2fSBarry Smith   PetscFunctionBegin;
15409566063dSJacob Faibussowitsch   PetscCall(PetscObjectQuery((PetscObject)A, "Zoomviewer", (PetscObject *)&viewer));
15419566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
15429566063dSJacob Faibussowitsch   PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr));
1543f1af5d2fSBarry Smith 
1544f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
15459566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &v));
1546fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
1547d0609cedSBarry Smith     PetscDrawCollectiveBegin(draw);
1548f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
1549f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
15509371c9d4SSatish Balay       x_l = j;
15519371c9d4SSatish Balay       x_r = x_l + 1.0;
1552f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1553f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1554f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1555ca15aa20SStefano Zampini         if (PetscRealPart(v[j * m + i]) > 0.) color = PETSC_DRAW_RED;
1556ca15aa20SStefano Zampini         else if (PetscRealPart(v[j * m + i]) < 0.) color = PETSC_DRAW_BLUE;
1557ca15aa20SStefano Zampini         else continue;
15589566063dSJacob Faibussowitsch         PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color));
1559f1af5d2fSBarry Smith       }
1560f1af5d2fSBarry Smith     }
1561d0609cedSBarry Smith     PetscDrawCollectiveEnd(draw);
1562f1af5d2fSBarry Smith   } else {
1563f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
1564f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
1565b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1566b05fc000SLisandro Dalcin     PetscDraw popup;
1567b05fc000SLisandro Dalcin 
1568f1af5d2fSBarry Smith     for (i = 0; i < m * n; i++) {
1569f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
1570f1af5d2fSBarry Smith     }
1571383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
15729566063dSJacob Faibussowitsch     PetscCall(PetscDrawGetPopup(draw, &popup));
15739566063dSJacob Faibussowitsch     PetscCall(PetscDrawScalePopup(popup, minv, maxv));
1574383922c3SLisandro Dalcin 
1575d0609cedSBarry Smith     PetscDrawCollectiveBegin(draw);
1576f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
1577f1af5d2fSBarry Smith       x_l = j;
1578f1af5d2fSBarry Smith       x_r = x_l + 1.0;
1579f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1580f1af5d2fSBarry Smith         y_l   = m - i - 1.0;
1581f1af5d2fSBarry Smith         y_r   = y_l + 1.0;
1582b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(v[j * m + i]), minv, maxv);
15839566063dSJacob Faibussowitsch         PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color));
1584f1af5d2fSBarry Smith       }
1585f1af5d2fSBarry Smith     }
1586d0609cedSBarry Smith     PetscDrawCollectiveEnd(draw);
1587f1af5d2fSBarry Smith   }
15889566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &v));
15893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1590f1af5d2fSBarry Smith }
1591f1af5d2fSBarry Smith 
1592d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw(Mat A, PetscViewer viewer)
1593d71ae5a4SJacob Faibussowitsch {
1594b0a32e0cSBarry Smith   PetscDraw draw;
1595ace3abfcSBarry Smith   PetscBool isnull;
1596329f5518SBarry Smith   PetscReal xr, yr, xl, yl, h, w;
1597f1af5d2fSBarry Smith 
1598f1af5d2fSBarry Smith   PetscFunctionBegin;
15999566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
16009566063dSJacob Faibussowitsch   PetscCall(PetscDrawIsNull(draw, &isnull));
16013ba16761SJacob Faibussowitsch   if (isnull) PetscFunctionReturn(PETSC_SUCCESS);
1602f1af5d2fSBarry Smith 
16039371c9d4SSatish Balay   xr = A->cmap->n;
16049371c9d4SSatish Balay   yr = A->rmap->n;
16059371c9d4SSatish Balay   h  = yr / 10.0;
16069371c9d4SSatish Balay   w  = xr / 10.0;
16079371c9d4SSatish Balay   xr += w;
16089371c9d4SSatish Balay   yr += h;
16099371c9d4SSatish Balay   xl = -w;
16109371c9d4SSatish Balay   yl = -h;
16119566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetCoordinates(draw, xl, yl, xr, yr));
16129566063dSJacob Faibussowitsch   PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", (PetscObject)viewer));
16139566063dSJacob Faibussowitsch   PetscCall(PetscDrawZoom(draw, MatView_SeqDense_Draw_Zoom, A));
16149566063dSJacob Faibussowitsch   PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", NULL));
16159566063dSJacob Faibussowitsch   PetscCall(PetscDrawSave(draw));
16163ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1617f1af5d2fSBarry Smith }
1618f1af5d2fSBarry Smith 
1619d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_SeqDense(Mat A, PetscViewer viewer)
1620d71ae5a4SJacob Faibussowitsch {
1621ace3abfcSBarry Smith   PetscBool iascii, isbinary, isdraw;
1622932b0c3eSLois Curfman McInnes 
16233a40ed3dSBarry Smith   PetscFunctionBegin;
16249566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
16259566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
16269566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
16271baa6e33SBarry Smith   if (iascii) PetscCall(MatView_SeqDense_ASCII(A, viewer));
16281baa6e33SBarry Smith   else if (isbinary) PetscCall(MatView_Dense_Binary(A, viewer));
16291baa6e33SBarry Smith   else if (isdraw) PetscCall(MatView_SeqDense_Draw(A, viewer));
16303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1631932b0c3eSLois Curfman McInnes }
1632289bc588SBarry Smith 
1633d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A, const PetscScalar *array)
1634d71ae5a4SJacob Faibussowitsch {
1635d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
1636d3042a70SBarry Smith 
1637d3042a70SBarry Smith   PetscFunctionBegin;
163828b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
163928b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
164028b400f6SJacob Faibussowitsch   PetscCheck(!a->unplacedarray, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreArray() first");
1641d3042a70SBarry Smith   a->unplacedarray       = a->v;
1642d3042a70SBarry Smith   a->unplaced_user_alloc = a->user_alloc;
1643d3042a70SBarry Smith   a->v                   = (PetscScalar *)array;
1644637a0070SStefano Zampini   a->user_alloc          = PETSC_TRUE;
164547d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
1646c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1647ca15aa20SStefano Zampini #endif
16483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1649d3042a70SBarry Smith }
1650d3042a70SBarry Smith 
1651d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseResetArray_SeqDense(Mat A)
1652d71ae5a4SJacob Faibussowitsch {
1653d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
1654d3042a70SBarry Smith 
1655d3042a70SBarry Smith   PetscFunctionBegin;
165628b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
165728b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
1658d3042a70SBarry Smith   a->v             = a->unplacedarray;
1659d3042a70SBarry Smith   a->user_alloc    = a->unplaced_user_alloc;
1660d3042a70SBarry Smith   a->unplacedarray = NULL;
166147d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
1662c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1663ca15aa20SStefano Zampini #endif
16643ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1665d3042a70SBarry Smith }
1666d3042a70SBarry Smith 
1667d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A, const PetscScalar *array)
1668d71ae5a4SJacob Faibussowitsch {
1669d5ea218eSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
1670d5ea218eSStefano Zampini 
1671d5ea218eSStefano Zampini   PetscFunctionBegin;
167228b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
167328b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
16749566063dSJacob Faibussowitsch   if (!a->user_alloc) PetscCall(PetscFree(a->v));
1675d5ea218eSStefano Zampini   a->v          = (PetscScalar *)array;
1676d5ea218eSStefano Zampini   a->user_alloc = PETSC_FALSE;
167747d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
1678d5ea218eSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
1679d5ea218eSStefano Zampini #endif
16803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1681d5ea218eSStefano Zampini }
1682d5ea218eSStefano Zampini 
1683d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDestroy_SeqDense(Mat mat)
1684d71ae5a4SJacob Faibussowitsch {
1685ec8511deSBarry Smith   Mat_SeqDense *l = (Mat_SeqDense *)mat->data;
168690f02eecSBarry Smith 
16873a40ed3dSBarry Smith   PetscFunctionBegin;
16883ba16761SJacob Faibussowitsch   PetscCall(PetscLogObjectState((PetscObject)mat, "Rows %" PetscInt_FMT " Cols %" PetscInt_FMT, mat->rmap->n, mat->cmap->n));
16899566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(l->qrrhs)));
16909566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->tau));
16919566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->pivots));
16929566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->fwork));
16939566063dSJacob Faibussowitsch   if (!l->user_alloc) PetscCall(PetscFree(l->v));
16949566063dSJacob Faibussowitsch   if (!l->unplaced_user_alloc) PetscCall(PetscFree(l->unplacedarray));
169528b400f6SJacob Faibussowitsch   PetscCheck(!l->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
169628b400f6SJacob Faibussowitsch   PetscCheck(!l->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
16979566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&l->cvec));
16989566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&l->cmat));
16999566063dSJacob Faibussowitsch   PetscCall(PetscFree(mat->data));
1700dbd8c25aSHong Zhang 
17019566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)mat, NULL));
17029566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactor_C", NULL));
17032e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorSymbolic_C", NULL));
17042e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorNumeric_C", NULL));
17059566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetLDA_C", NULL));
17069566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseSetLDA_C", NULL));
17079566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArray_C", NULL));
17089566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArray_C", NULL));
17099566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDensePlaceArray_C", NULL));
17109566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseResetArray_C", NULL));
17119566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseReplaceArray_C", NULL));
17129566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayRead_C", NULL));
17139566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayRead_C", NULL));
17149566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayWrite_C", NULL));
17159566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayWrite_C", NULL));
17169566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqaij_C", NULL));
17178baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
17189566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_elemental_C", NULL));
17198baccfbdSHong Zhang #endif
1720d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
17219566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_scalapack_C", NULL));
1722d24d4204SJose E. Roman #endif
17232bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
17249566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensecuda_C", NULL));
17259566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", NULL));
17269566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdense_C", NULL));
17272e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensecuda_C", NULL));
17282bf066beSStefano Zampini #endif
172947d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP)
173047d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensehip_C", NULL));
173147d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensehip_seqdensehip_C", NULL));
173247d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensehip_seqdense_C", NULL));
173347d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensehip_C", NULL));
173447d993e7Ssuyashtn #endif
17359566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatSeqDenseSetPreallocation_C", NULL));
17369566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqaij_seqdense_C", NULL));
17379566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdense_C", NULL));
17389566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqbaij_seqdense_C", NULL));
17399566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqsbaij_seqdense_C", NULL));
174052c5f739Sprj- 
17419566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumn_C", NULL));
17429566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumn_C", NULL));
17439566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVec_C", NULL));
17449566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVec_C", NULL));
17459566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecRead_C", NULL));
17469566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecRead_C", NULL));
17479566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecWrite_C", NULL));
17489566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecWrite_C", NULL));
17499566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetSubMatrix_C", NULL));
17509566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreSubMatrix_C", NULL));
17513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1752289bc588SBarry Smith }
1753289bc588SBarry Smith 
1754d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatTranspose_SeqDense(Mat A, MatReuse reuse, Mat *matout)
1755d71ae5a4SJacob Faibussowitsch {
1756c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
17576536e3caSStefano Zampini   PetscInt      k, j, m = A->rmap->n, M = mat->lda, n = A->cmap->n;
175887828ca2SBarry Smith   PetscScalar  *v, tmp;
175948b35521SBarry Smith 
17603a40ed3dSBarry Smith   PetscFunctionBegin;
17617fb60732SBarry Smith   if (reuse == MAT_REUSE_MATRIX) PetscCall(MatTransposeCheckNonzeroState_Private(A, *matout));
17626536e3caSStefano Zampini   if (reuse == MAT_INPLACE_MATRIX) {
17636536e3caSStefano Zampini     if (m == n) { /* in place transpose */
17649566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(A, &v));
1765d3e5ee88SLois Curfman McInnes       for (j = 0; j < m; j++) {
1766289bc588SBarry Smith         for (k = 0; k < j; k++) {
17671b807ce4Svictorle           tmp          = v[j + k * M];
17681b807ce4Svictorle           v[j + k * M] = v[k + j * M];
17691b807ce4Svictorle           v[k + j * M] = tmp;
1770289bc588SBarry Smith         }
1771289bc588SBarry Smith       }
17729566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArray(A, &v));
17736536e3caSStefano Zampini     } else { /* reuse memory, temporary allocates new memory */
17746536e3caSStefano Zampini       PetscScalar *v2;
17756536e3caSStefano Zampini       PetscLayout  tmplayout;
17766536e3caSStefano Zampini 
17779566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1((size_t)m * n, &v2));
17789566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(A, &v));
17796536e3caSStefano Zampini       for (j = 0; j < n; j++) {
17806536e3caSStefano Zampini         for (k = 0; k < m; k++) v2[j + (size_t)k * n] = v[k + (size_t)j * M];
17816536e3caSStefano Zampini       }
17829566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(v, v2, (size_t)m * n));
17839566063dSJacob Faibussowitsch       PetscCall(PetscFree(v2));
17849566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArray(A, &v));
17856536e3caSStefano Zampini       /* cleanup size dependent quantities */
17869566063dSJacob Faibussowitsch       PetscCall(VecDestroy(&mat->cvec));
17879566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&mat->cmat));
17889566063dSJacob Faibussowitsch       PetscCall(PetscFree(mat->pivots));
17899566063dSJacob Faibussowitsch       PetscCall(PetscFree(mat->fwork));
17906536e3caSStefano Zampini       /* swap row/col layouts */
17916536e3caSStefano Zampini       mat->lda  = n;
17926536e3caSStefano Zampini       tmplayout = A->rmap;
17936536e3caSStefano Zampini       A->rmap   = A->cmap;
17946536e3caSStefano Zampini       A->cmap   = tmplayout;
17956536e3caSStefano Zampini     }
17963a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1797d3e5ee88SLois Curfman McInnes     Mat           tmat;
1798ec8511deSBarry Smith     Mat_SeqDense *tmatd;
179987828ca2SBarry Smith     PetscScalar  *v2;
1800af36a384SStefano Zampini     PetscInt      M2;
1801ea709b57SSatish Balay 
18026536e3caSStefano Zampini     if (reuse == MAT_INITIAL_MATRIX) {
18039566063dSJacob Faibussowitsch       PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &tmat));
18049566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(tmat, A->cmap->n, A->rmap->n, A->cmap->n, A->rmap->n));
18059566063dSJacob Faibussowitsch       PetscCall(MatSetType(tmat, ((PetscObject)A)->type_name));
18069566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSetPreallocation(tmat, NULL));
1807ca15aa20SStefano Zampini     } else tmat = *matout;
1808ca15aa20SStefano Zampini 
18099566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&v));
18109566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArray(tmat, &v2));
1811ec8511deSBarry Smith     tmatd = (Mat_SeqDense *)tmat->data;
1812ca15aa20SStefano Zampini     M2    = tmatd->lda;
1813d3e5ee88SLois Curfman McInnes     for (j = 0; j < n; j++) {
1814af36a384SStefano Zampini       for (k = 0; k < m; k++) v2[j + k * M2] = v[k + j * M];
1815d3e5ee88SLois Curfman McInnes     }
18169566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(tmat, &v2));
18179566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&v));
18189566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(tmat, MAT_FINAL_ASSEMBLY));
18199566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(tmat, MAT_FINAL_ASSEMBLY));
18206536e3caSStefano Zampini     *matout = tmat;
182148b35521SBarry Smith   }
18223ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1823289bc588SBarry Smith }
1824289bc588SBarry Smith 
1825d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatEqual_SeqDense(Mat A1, Mat A2, PetscBool *flg)
1826d71ae5a4SJacob Faibussowitsch {
1827c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat1 = (Mat_SeqDense *)A1->data;
1828c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat2 = (Mat_SeqDense *)A2->data;
1829ca15aa20SStefano Zampini   PetscInt           i;
1830ca15aa20SStefano Zampini   const PetscScalar *v1, *v2;
18319ea5d5aeSSatish Balay 
18323a40ed3dSBarry Smith   PetscFunctionBegin;
18339371c9d4SSatish Balay   if (A1->rmap->n != A2->rmap->n) {
18349371c9d4SSatish Balay     *flg = PETSC_FALSE;
18353ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
18369371c9d4SSatish Balay   }
18379371c9d4SSatish Balay   if (A1->cmap->n != A2->cmap->n) {
18389371c9d4SSatish Balay     *flg = PETSC_FALSE;
18393ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
18409371c9d4SSatish Balay   }
18419566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A1, &v1));
18429566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A2, &v2));
1843ca15aa20SStefano Zampini   for (i = 0; i < A1->cmap->n; i++) {
18449566063dSJacob Faibussowitsch     PetscCall(PetscArraycmp(v1, v2, A1->rmap->n, flg));
18453ba16761SJacob Faibussowitsch     if (*flg == PETSC_FALSE) PetscFunctionReturn(PETSC_SUCCESS);
1846ca15aa20SStefano Zampini     v1 += mat1->lda;
1847ca15aa20SStefano Zampini     v2 += mat2->lda;
18481b807ce4Svictorle   }
18499566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A1, &v1));
18509566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A2, &v2));
185177c4ece6SBarry Smith   *flg = PETSC_TRUE;
18523ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1853289bc588SBarry Smith }
1854289bc588SBarry Smith 
185514277c92SJacob Faibussowitsch PetscErrorCode MatGetDiagonal_SeqDense(Mat A, Vec v)
1856d71ae5a4SJacob Faibussowitsch {
1857c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
185813f74950SBarry Smith   PetscInt           i, n, len;
1859ca15aa20SStefano Zampini   PetscScalar       *x;
1860ca15aa20SStefano Zampini   const PetscScalar *vv;
186144cd7ae7SLois Curfman McInnes 
18623a40ed3dSBarry Smith   PetscFunctionBegin;
18639566063dSJacob Faibussowitsch   PetscCall(VecGetSize(v, &n));
18649566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
1865d0f46423SBarry Smith   len = PetscMin(A->rmap->n, A->cmap->n);
18669566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &vv));
186708401ef6SPierre Jolivet   PetscCheck(n == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming mat and vec");
1868ad540459SPierre Jolivet   for (i = 0; i < len; i++) x[i] = vv[i * mat->lda + i];
18699566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &vv));
18709566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
18713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1872289bc588SBarry Smith }
1873289bc588SBarry Smith 
1874d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDiagonalScale_SeqDense(Mat A, Vec ll, Vec rr)
1875d71ae5a4SJacob Faibussowitsch {
1876c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1877f1ceaac6SMatthew G. Knepley   const PetscScalar *l, *r;
1878ca15aa20SStefano Zampini   PetscScalar        x, *v, *vv;
1879d0f46423SBarry Smith   PetscInt           i, j, m = A->rmap->n, n = A->cmap->n;
188055659b69SBarry Smith 
18813a40ed3dSBarry Smith   PetscFunctionBegin;
18829566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &vv));
188328988994SBarry Smith   if (ll) {
18849566063dSJacob Faibussowitsch     PetscCall(VecGetSize(ll, &m));
18859566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ll, &l));
188608401ef6SPierre Jolivet     PetscCheck(m == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Left scaling vec wrong size");
1887da3a660dSBarry Smith     for (i = 0; i < m; i++) {
1888da3a660dSBarry Smith       x = l[i];
1889ca15aa20SStefano Zampini       v = vv + i;
18909371c9d4SSatish Balay       for (j = 0; j < n; j++) {
18919371c9d4SSatish Balay         (*v) *= x;
18929371c9d4SSatish Balay         v += mat->lda;
18939371c9d4SSatish Balay       }
1894da3a660dSBarry Smith     }
18959566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ll, &l));
18969566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0 * n * m));
1897da3a660dSBarry Smith   }
189828988994SBarry Smith   if (rr) {
18999566063dSJacob Faibussowitsch     PetscCall(VecGetSize(rr, &n));
19009566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(rr, &r));
190108401ef6SPierre Jolivet     PetscCheck(n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Right scaling vec wrong size");
1902da3a660dSBarry Smith     for (i = 0; i < n; i++) {
1903da3a660dSBarry Smith       x = r[i];
1904ca15aa20SStefano Zampini       v = vv + i * mat->lda;
19052205254eSKarl Rupp       for (j = 0; j < m; j++) (*v++) *= x;
1906da3a660dSBarry Smith     }
19079566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(rr, &r));
19089566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0 * n * m));
1909da3a660dSBarry Smith   }
19109566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &vv));
19113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1912289bc588SBarry Smith }
1913289bc588SBarry Smith 
1914d71ae5a4SJacob Faibussowitsch PetscErrorCode MatNorm_SeqDense(Mat A, NormType type, PetscReal *nrm)
1915d71ae5a4SJacob Faibussowitsch {
1916c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
1917ca15aa20SStefano Zampini   PetscScalar  *v, *vv;
1918329f5518SBarry Smith   PetscReal     sum = 0.0;
191975f6d85dSStefano Zampini   PetscInt      lda, m = A->rmap->n, i, j;
192055659b69SBarry Smith 
19213a40ed3dSBarry Smith   PetscFunctionBegin;
19229566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&vv));
19239566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(A, &lda));
1924ca15aa20SStefano Zampini   v = vv;
1925289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1926a5ce6ee0Svictorle     if (lda > m) {
1927d0f46423SBarry Smith       for (j = 0; j < A->cmap->n; j++) {
1928ca15aa20SStefano Zampini         v = vv + j * lda;
1929a5ce6ee0Svictorle         for (i = 0; i < m; i++) {
19309371c9d4SSatish Balay           sum += PetscRealPart(PetscConj(*v) * (*v));
19319371c9d4SSatish Balay           v++;
1932a5ce6ee0Svictorle         }
1933a5ce6ee0Svictorle       }
1934a5ce6ee0Svictorle     } else {
1935570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1936570b7f6dSBarry Smith       PetscBLASInt one = 1, cnt = A->cmap->n * A->rmap->n;
1937792fecdfSBarry Smith       PetscCallBLAS("BLASnrm2", *nrm = BLASnrm2_(&cnt, v, &one));
1938570b7f6dSBarry Smith     }
1939570b7f6dSBarry Smith #else
1940d0f46423SBarry Smith       for (i = 0; i < A->cmap->n * A->rmap->n; i++) {
19419371c9d4SSatish Balay         sum += PetscRealPart(PetscConj(*v) * (*v));
19429371c9d4SSatish Balay         v++;
1943289bc588SBarry Smith       }
1944a5ce6ee0Svictorle     }
19458f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1946570b7f6dSBarry Smith #endif
19479566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0 * A->cmap->n * A->rmap->n));
19483a40ed3dSBarry Smith   } else if (type == NORM_1) {
1949064f8208SBarry Smith     *nrm = 0.0;
1950d0f46423SBarry Smith     for (j = 0; j < A->cmap->n; j++) {
1951ca15aa20SStefano Zampini       v   = vv + j * mat->lda;
1952289bc588SBarry Smith       sum = 0.0;
1953d0f46423SBarry Smith       for (i = 0; i < A->rmap->n; i++) {
19549371c9d4SSatish Balay         sum += PetscAbsScalar(*v);
19559371c9d4SSatish Balay         v++;
1956289bc588SBarry Smith       }
1957064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1958289bc588SBarry Smith     }
19599566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n));
19603a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1961064f8208SBarry Smith     *nrm = 0.0;
1962d0f46423SBarry Smith     for (j = 0; j < A->rmap->n; j++) {
1963ca15aa20SStefano Zampini       v   = vv + j;
1964289bc588SBarry Smith       sum = 0.0;
1965d0f46423SBarry Smith       for (i = 0; i < A->cmap->n; i++) {
19669371c9d4SSatish Balay         sum += PetscAbsScalar(*v);
19679371c9d4SSatish Balay         v += mat->lda;
1968289bc588SBarry Smith       }
1969064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1970289bc588SBarry Smith     }
19719566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n));
1972e7e72b3dSBarry Smith   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "No two norm");
19739566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&vv));
19743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1975289bc588SBarry Smith }
1976289bc588SBarry Smith 
1977d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetOption_SeqDense(Mat A, MatOption op, PetscBool flg)
1978d71ae5a4SJacob Faibussowitsch {
1979c0bbcb79SLois Curfman McInnes   Mat_SeqDense *aij = (Mat_SeqDense *)A->data;
198067e560aaSBarry Smith 
19813a40ed3dSBarry Smith   PetscFunctionBegin;
1982b5a2b587SKris Buschelman   switch (op) {
1983d71ae5a4SJacob Faibussowitsch   case MAT_ROW_ORIENTED:
1984d71ae5a4SJacob Faibussowitsch     aij->roworiented = flg;
1985d71ae5a4SJacob Faibussowitsch     break;
1986512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1987b5a2b587SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
19883971808eSMatthew Knepley   case MAT_NEW_NONZERO_ALLOCATION_ERR:
19898c78258cSHong Zhang   case MAT_FORCE_DIAGONAL_ENTRIES:
199013fa8e87SLisandro Dalcin   case MAT_KEEP_NONZERO_PATTERN:
1991b5a2b587SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1992b5a2b587SKris Buschelman   case MAT_USE_HASH_TABLE:
19930f8fb01aSBarry Smith   case MAT_IGNORE_ZERO_ENTRIES:
19945021d80fSJed Brown   case MAT_IGNORE_LOWER_TRIANGULAR:
1995d71ae5a4SJacob Faibussowitsch   case MAT_SORTED_FULL:
1996d71ae5a4SJacob Faibussowitsch     PetscCall(PetscInfo(A, "Option %s ignored\n", MatOptions[op]));
1997d71ae5a4SJacob Faibussowitsch     break;
19985021d80fSJed Brown   case MAT_SPD:
199977e54ba9SKris Buschelman   case MAT_SYMMETRIC:
200077e54ba9SKris Buschelman   case MAT_STRUCTURALLY_SYMMETRIC:
20019a4540c5SBarry Smith   case MAT_HERMITIAN:
20029a4540c5SBarry Smith   case MAT_SYMMETRY_ETERNAL:
2003b94d7dedSBarry Smith   case MAT_STRUCTURAL_SYMMETRY_ETERNAL:
2004d71ae5a4SJacob Faibussowitsch   case MAT_SPD_ETERNAL:
2005d71ae5a4SJacob Faibussowitsch     break;
2006d71ae5a4SJacob Faibussowitsch   default:
2007d71ae5a4SJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "unknown option %s", MatOptions[op]);
20083a40ed3dSBarry Smith   }
20093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2010289bc588SBarry Smith }
2011289bc588SBarry Smith 
2012d71ae5a4SJacob Faibussowitsch PetscErrorCode MatZeroEntries_SeqDense(Mat A)
2013d71ae5a4SJacob Faibussowitsch {
2014ec8511deSBarry Smith   Mat_SeqDense *l   = (Mat_SeqDense *)A->data;
20153d8925e7SStefano Zampini   PetscInt      lda = l->lda, m = A->rmap->n, n = A->cmap->n, j;
2016ca15aa20SStefano Zampini   PetscScalar  *v;
20173a40ed3dSBarry Smith 
20183a40ed3dSBarry Smith   PetscFunctionBegin;
20199566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(A, &v));
2020a5ce6ee0Svictorle   if (lda > m) {
202148a46eb9SPierre Jolivet     for (j = 0; j < n; j++) PetscCall(PetscArrayzero(v + j * lda, m));
2022a5ce6ee0Svictorle   } else {
20239566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(v, PetscInt64Mult(m, n)));
2024a5ce6ee0Svictorle   }
20259566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(A, &v));
20263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20276f0a148fSBarry Smith }
20286f0a148fSBarry Smith 
2029d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatZeroRows_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b)
2030d71ae5a4SJacob Faibussowitsch {
2031ec8511deSBarry Smith   Mat_SeqDense      *l = (Mat_SeqDense *)A->data;
2032b9679d65SBarry Smith   PetscInt           m = l->lda, n = A->cmap->n, i, j;
2033ca15aa20SStefano Zampini   PetscScalar       *slot, *bb, *v;
203497b48c8fSBarry Smith   const PetscScalar *xx;
203555659b69SBarry Smith 
20363a40ed3dSBarry Smith   PetscFunctionBegin;
203776bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
2038b9679d65SBarry Smith     for (i = 0; i < N; i++) {
203908401ef6SPierre Jolivet       PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed");
204008401ef6SPierre 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);
2041b9679d65SBarry Smith     }
204276bd3646SJed Brown   }
20433ba16761SJacob Faibussowitsch   if (!N) PetscFunctionReturn(PETSC_SUCCESS);
2044b9679d65SBarry Smith 
204597b48c8fSBarry Smith   /* fix right hand side if needed */
204697b48c8fSBarry Smith   if (x && b) {
20479566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(x, &xx));
20489566063dSJacob Faibussowitsch     PetscCall(VecGetArray(b, &bb));
20492205254eSKarl Rupp     for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]];
20509566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(x, &xx));
20519566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(b, &bb));
205297b48c8fSBarry Smith   }
205397b48c8fSBarry Smith 
20549566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
20556f0a148fSBarry Smith   for (i = 0; i < N; i++) {
2056ca15aa20SStefano Zampini     slot = v + rows[i];
20579371c9d4SSatish Balay     for (j = 0; j < n; j++) {
20589371c9d4SSatish Balay       *slot = 0.0;
20599371c9d4SSatish Balay       slot += m;
20609371c9d4SSatish Balay     }
20616f0a148fSBarry Smith   }
2062f4df32b1SMatthew Knepley   if (diag != 0.0) {
206308401ef6SPierre Jolivet     PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices");
20646f0a148fSBarry Smith     for (i = 0; i < N; i++) {
2065ca15aa20SStefano Zampini       slot  = v + (m + 1) * rows[i];
2066f4df32b1SMatthew Knepley       *slot = diag;
20676f0a148fSBarry Smith     }
20686f0a148fSBarry Smith   }
20699566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
20703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20716f0a148fSBarry Smith }
2072557bce09SLois Curfman McInnes 
2073d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A, PetscInt *lda)
2074d71ae5a4SJacob Faibussowitsch {
207549a6ff4bSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
207649a6ff4bSBarry Smith 
207749a6ff4bSBarry Smith   PetscFunctionBegin;
207849a6ff4bSBarry Smith   *lda = mat->lda;
20793ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
208049a6ff4bSBarry Smith }
208149a6ff4bSBarry Smith 
2082d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArray_SeqDense(Mat A, PetscScalar **array)
2083d71ae5a4SJacob Faibussowitsch {
2084c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
20853a40ed3dSBarry Smith 
20863a40ed3dSBarry Smith   PetscFunctionBegin;
208728b400f6SJacob Faibussowitsch   PetscCheck(!mat->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
208864e87e97SBarry Smith   *array = mat->v;
20893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
209064e87e97SBarry Smith }
20910754003eSLois Curfman McInnes 
2092d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A, PetscScalar **array)
2093d71ae5a4SJacob Faibussowitsch {
20943a40ed3dSBarry Smith   PetscFunctionBegin;
209575f6d85dSStefano Zampini   if (array) *array = NULL;
20963ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2097ff14e315SSatish Balay }
20980754003eSLois Curfman McInnes 
20990f74d2c1SSatish Balay /*@
210011a5261eSBarry Smith   MatDenseGetLDA - gets the leading dimension of the array returned from `MatDenseGetArray()`
210149a6ff4bSBarry Smith 
21022ef1f0ffSBarry Smith   Not Collective
210349a6ff4bSBarry Smith 
210449a6ff4bSBarry Smith   Input Parameter:
2105fe59aa6dSJacob Faibussowitsch . A - a `MATDENSE` or `MATDENSECUDA` matrix
210649a6ff4bSBarry Smith 
210749a6ff4bSBarry Smith   Output Parameter:
210849a6ff4bSBarry Smith . lda - the leading dimension
210949a6ff4bSBarry Smith 
211049a6ff4bSBarry Smith   Level: intermediate
211149a6ff4bSBarry Smith 
21121cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseSetLDA()`
211349a6ff4bSBarry Smith @*/
2114d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetLDA(Mat A, PetscInt *lda)
2115d71ae5a4SJacob Faibussowitsch {
211649a6ff4bSBarry Smith   PetscFunctionBegin;
2117d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
21184f572ea9SToby Isaac   PetscAssertPointer(lda, 2);
211975f6d85dSStefano Zampini   MatCheckPreallocated(A, 1);
2120cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetLDA_C", (Mat, PetscInt *), (A, lda));
21213ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
212249a6ff4bSBarry Smith }
212349a6ff4bSBarry Smith 
21240f74d2c1SSatish Balay /*@
212511a5261eSBarry Smith   MatDenseSetLDA - Sets the leading dimension of the array used by the `MATDENSE` matrix
2126ad16ce7aSStefano Zampini 
21272ef1f0ffSBarry Smith   Not Collective
2128ad16ce7aSStefano Zampini 
2129d8d19677SJose E. Roman   Input Parameters:
2130fe59aa6dSJacob Faibussowitsch + A   - a `MATDENSE` or `MATDENSECUDA` matrix
2131ad16ce7aSStefano Zampini - lda - the leading dimension
2132ad16ce7aSStefano Zampini 
2133ad16ce7aSStefano Zampini   Level: intermediate
2134ad16ce7aSStefano Zampini 
21351cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetLDA()`
2136ad16ce7aSStefano Zampini @*/
2137d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA(Mat A, PetscInt lda)
2138d71ae5a4SJacob Faibussowitsch {
2139ad16ce7aSStefano Zampini   PetscFunctionBegin;
2140ad16ce7aSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2141cac4c232SBarry Smith   PetscTryMethod(A, "MatDenseSetLDA_C", (Mat, PetscInt), (A, lda));
21423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2143ad16ce7aSStefano Zampini }
2144ad16ce7aSStefano Zampini 
2145ad16ce7aSStefano Zampini /*@C
214611a5261eSBarry Smith   MatDenseGetArray - gives read-write access to the array where the data for a `MATDENSE` matrix is stored
214773a71a0fSBarry Smith 
2148c3339decSBarry Smith   Logically Collective
214973a71a0fSBarry Smith 
215073a71a0fSBarry Smith   Input Parameter:
2151fe59aa6dSJacob Faibussowitsch . A - a dense matrix
215273a71a0fSBarry Smith 
215373a71a0fSBarry Smith   Output Parameter:
215473a71a0fSBarry Smith . array - pointer to the data
215573a71a0fSBarry Smith 
215673a71a0fSBarry Smith   Level: intermediate
215773a71a0fSBarry Smith 
2158fe59aa6dSJacob Faibussowitsch   Fortran Notes:
21590ab4885dSBarry Smith   `MatDenseGetArray()` Fortran binding is deprecated (since PETSc 3.19), use `MatDenseGetArrayF90()`
21600ab4885dSBarry Smith 
21611cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
216273a71a0fSBarry Smith @*/
2163d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArray(Mat A, PetscScalar **array)
2164d71ae5a4SJacob Faibussowitsch {
216573a71a0fSBarry Smith   PetscFunctionBegin;
2166d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
21674f572ea9SToby Isaac   PetscAssertPointer(array, 2);
2168cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array));
21693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
217073a71a0fSBarry Smith }
217173a71a0fSBarry Smith 
2172dec5eb66SMatthew G Knepley /*@C
217311a5261eSBarry Smith   MatDenseRestoreArray - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArray()`
217473a71a0fSBarry Smith 
2175c3339decSBarry Smith   Logically Collective
21768572280aSBarry Smith 
21778572280aSBarry Smith   Input Parameters:
2178fe59aa6dSJacob Faibussowitsch + A     - a dense matrix
21792ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`)
21808572280aSBarry Smith 
21818572280aSBarry Smith   Level: intermediate
21828572280aSBarry Smith 
2183fe59aa6dSJacob Faibussowitsch   Fortran Notes:
21840ab4885dSBarry Smith   `MatDenseRestoreArray()` Fortran binding is deprecated (since PETSc 3.19), use `MatDenseRestoreArrayF90()`
21850ab4885dSBarry Smith 
21861cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
21878572280aSBarry Smith @*/
2188d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArray(Mat A, PetscScalar **array)
2189d71ae5a4SJacob Faibussowitsch {
21908572280aSBarry Smith   PetscFunctionBegin;
2191d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
21924f572ea9SToby Isaac   if (array) PetscAssertPointer(array, 2);
2193cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array));
21949566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)A));
219547d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
2196637a0070SStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
2197637a0070SStefano Zampini #endif
21983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
21998572280aSBarry Smith }
22008572280aSBarry Smith 
22018572280aSBarry Smith /*@C
220211a5261eSBarry Smith   MatDenseGetArrayRead - gives read-only access to the array where the data for a `MATDENSE`  matrix is stored
22038572280aSBarry Smith 
22040ab4885dSBarry Smith   Not Collective; No Fortran Support
22058572280aSBarry Smith 
22068572280aSBarry Smith   Input Parameter:
2207fe59aa6dSJacob Faibussowitsch . A - a dense matrix
22088572280aSBarry Smith 
22098572280aSBarry Smith   Output Parameter:
22108572280aSBarry Smith . array - pointer to the data
22118572280aSBarry Smith 
22128572280aSBarry Smith   Level: intermediate
22138572280aSBarry Smith 
22141cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
22158572280aSBarry Smith @*/
2216d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArrayRead(Mat A, const PetscScalar **array)
2217d71ae5a4SJacob Faibussowitsch {
22188572280aSBarry Smith   PetscFunctionBegin;
2219d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
22204f572ea9SToby Isaac   PetscAssertPointer(array, 2);
2221*5c0db29aSPierre Jolivet   PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array));
22223ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22238572280aSBarry Smith }
22248572280aSBarry Smith 
22258572280aSBarry Smith /*@C
222611a5261eSBarry Smith   MatDenseRestoreArrayRead - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayRead()`
22278572280aSBarry Smith 
22280ab4885dSBarry Smith   Not Collective; No Fortran Support
222973a71a0fSBarry Smith 
223073a71a0fSBarry Smith   Input Parameters:
2231fe59aa6dSJacob Faibussowitsch + A     - a dense matrix
22322ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`)
223373a71a0fSBarry Smith 
223473a71a0fSBarry Smith   Level: intermediate
223573a71a0fSBarry Smith 
22361cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
223773a71a0fSBarry Smith @*/
2238d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArrayRead(Mat A, const PetscScalar **array)
2239d71ae5a4SJacob Faibussowitsch {
224073a71a0fSBarry Smith   PetscFunctionBegin;
2241d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
22424f572ea9SToby Isaac   if (array) PetscAssertPointer(array, 2);
2243*5c0db29aSPierre Jolivet   PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array));
22443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
224573a71a0fSBarry Smith }
224673a71a0fSBarry Smith 
22476947451fSStefano Zampini /*@C
224811a5261eSBarry Smith   MatDenseGetArrayWrite - gives write-only access to the array where the data for a `MATDENSE` matrix is stored
22496947451fSStefano Zampini 
22500ab4885dSBarry Smith   Not Collective; No Fortran Support
22516947451fSStefano Zampini 
22526947451fSStefano Zampini   Input Parameter:
2253fe59aa6dSJacob Faibussowitsch . A - a dense matrix
22546947451fSStefano Zampini 
22556947451fSStefano Zampini   Output Parameter:
22566947451fSStefano Zampini . array - pointer to the data
22576947451fSStefano Zampini 
22586947451fSStefano Zampini   Level: intermediate
22596947451fSStefano Zampini 
22601cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`
22616947451fSStefano Zampini @*/
2262d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArrayWrite(Mat A, PetscScalar **array)
2263d71ae5a4SJacob Faibussowitsch {
22646947451fSStefano Zampini   PetscFunctionBegin;
2265d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
22664f572ea9SToby Isaac   PetscAssertPointer(array, 2);
2267cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array));
22683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22696947451fSStefano Zampini }
22706947451fSStefano Zampini 
22716947451fSStefano Zampini /*@C
227211a5261eSBarry Smith   MatDenseRestoreArrayWrite - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayWrite()`
22736947451fSStefano Zampini 
22740ab4885dSBarry Smith   Not Collective; No Fortran Support
22756947451fSStefano Zampini 
22766947451fSStefano Zampini   Input Parameters:
2277fe59aa6dSJacob Faibussowitsch + A     - a dense matrix
22782ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`)
22796947451fSStefano Zampini 
22806947451fSStefano Zampini   Level: intermediate
22816947451fSStefano Zampini 
22821cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`
22836947451fSStefano Zampini @*/
2284d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArrayWrite(Mat A, PetscScalar **array)
2285d71ae5a4SJacob Faibussowitsch {
22866947451fSStefano Zampini   PetscFunctionBegin;
2287d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
22884f572ea9SToby Isaac   if (array) PetscAssertPointer(array, 2);
2289cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array));
22909566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)A));
229147d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
22926947451fSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
22936947451fSStefano Zampini #endif
22943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22956947451fSStefano Zampini }
22966947451fSStefano Zampini 
2297cd3f9d89SJunchao Zhang /*@C
2298cd3f9d89SJunchao Zhang   MatDenseGetArrayAndMemType - gives read-write access to the array where the data for a `MATDENSE` matrix is stored
2299cd3f9d89SJunchao Zhang 
2300cd3f9d89SJunchao Zhang   Logically Collective
2301cd3f9d89SJunchao Zhang 
2302cd3f9d89SJunchao Zhang   Input Parameter:
2303fe59aa6dSJacob Faibussowitsch . A - a dense matrix
2304cd3f9d89SJunchao Zhang 
2305cd3f9d89SJunchao Zhang   Output Parameters:
2306cd3f9d89SJunchao Zhang + array - pointer to the data
2307cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer
2308cd3f9d89SJunchao Zhang 
2309cd3f9d89SJunchao Zhang   Level: intermediate
2310cd3f9d89SJunchao Zhang 
23112ef1f0ffSBarry Smith   Notes:
23122ef1f0ffSBarry Smith   If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc.,
23132ef1f0ffSBarry Smith   an array on device is always returned and is guaranteed to contain the matrix's latest data.
23142ef1f0ffSBarry Smith 
23151cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayAndMemType()`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArrayWriteAndMemType()`, `MatDenseGetArrayRead()`,
2316cd3f9d89SJunchao Zhang    `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()`
2317cd3f9d89SJunchao Zhang @*/
2318cd3f9d89SJunchao Zhang PetscErrorCode MatDenseGetArrayAndMemType(Mat A, PetscScalar **array, PetscMemType *mtype)
2319cd3f9d89SJunchao Zhang {
2320cd3f9d89SJunchao Zhang   PetscBool isMPI;
2321cd3f9d89SJunchao Zhang 
2322cd3f9d89SJunchao Zhang   PetscFunctionBegin;
2323cd3f9d89SJunchao Zhang   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
23244f572ea9SToby Isaac   PetscAssertPointer(array, 2);
2325e865de01SJunchao Zhang   PetscCall(MatBindToCPU(A, PETSC_FALSE)); /* We want device matrices to always return device arrays, so we unbind the matrix if it is bound to CPU */
2326cd3f9d89SJunchao Zhang   PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI));
2327cd3f9d89SJunchao Zhang   if (isMPI) {
2328cd3f9d89SJunchao Zhang     /* Dispatch here so that the code can be reused for all subclasses of MATDENSE */
2329cd3f9d89SJunchao Zhang     PetscCall(MatDenseGetArrayAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype));
2330cd3f9d89SJunchao Zhang   } else {
2331cd3f9d89SJunchao Zhang     PetscErrorCode (*fptr)(Mat, PetscScalar **, PetscMemType *);
23323ba16761SJacob Faibussowitsch 
23333ba16761SJacob Faibussowitsch     PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayAndMemType_C", &fptr));
2334cd3f9d89SJunchao Zhang     if (fptr) {
2335cd3f9d89SJunchao Zhang       PetscCall((*fptr)(A, array, mtype));
2336cd3f9d89SJunchao Zhang     } else {
2337cd3f9d89SJunchao Zhang       PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array));
2338cd3f9d89SJunchao Zhang       if (mtype) *mtype = PETSC_MEMTYPE_HOST;
2339cd3f9d89SJunchao Zhang     }
2340cd3f9d89SJunchao Zhang   }
23413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2342cd3f9d89SJunchao Zhang }
2343cd3f9d89SJunchao Zhang 
2344cd3f9d89SJunchao Zhang /*@C
2345cd3f9d89SJunchao Zhang   MatDenseRestoreArrayAndMemType - returns access to the array that is obtained by `MatDenseGetArrayAndMemType()`
2346cd3f9d89SJunchao Zhang 
2347cd3f9d89SJunchao Zhang   Logically Collective
2348cd3f9d89SJunchao Zhang 
2349cd3f9d89SJunchao Zhang   Input Parameters:
2350fe59aa6dSJacob Faibussowitsch + A     - a dense matrix
2351cd3f9d89SJunchao Zhang - array - pointer to the data
2352cd3f9d89SJunchao Zhang 
2353cd3f9d89SJunchao Zhang   Level: intermediate
2354cd3f9d89SJunchao Zhang 
23551cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
2356cd3f9d89SJunchao Zhang @*/
2357cd3f9d89SJunchao Zhang PetscErrorCode MatDenseRestoreArrayAndMemType(Mat A, PetscScalar **array)
2358cd3f9d89SJunchao Zhang {
2359cd3f9d89SJunchao Zhang   PetscBool isMPI;
2360cd3f9d89SJunchao Zhang 
2361cd3f9d89SJunchao Zhang   PetscFunctionBegin;
2362cd3f9d89SJunchao Zhang   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
23634f572ea9SToby Isaac   PetscAssertPointer(array, 2);
2364cd3f9d89SJunchao Zhang   PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI));
2365cd3f9d89SJunchao Zhang   if (isMPI) {
2366cd3f9d89SJunchao Zhang     PetscCall(MatDenseRestoreArrayAndMemType(((Mat_MPIDense *)A->data)->A, array));
2367cd3f9d89SJunchao Zhang   } else {
2368cd3f9d89SJunchao Zhang     PetscErrorCode (*fptr)(Mat, PetscScalar **);
23693ba16761SJacob Faibussowitsch 
23703ba16761SJacob Faibussowitsch     PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayAndMemType_C", &fptr));
2371cd3f9d89SJunchao Zhang     if (fptr) {
2372cd3f9d89SJunchao Zhang       PetscCall((*fptr)(A, array));
2373cd3f9d89SJunchao Zhang     } else {
2374cd3f9d89SJunchao Zhang       PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array));
2375cd3f9d89SJunchao Zhang     }
2376cd3f9d89SJunchao Zhang     *array = NULL;
2377cd3f9d89SJunchao Zhang   }
2378cd3f9d89SJunchao Zhang   PetscCall(PetscObjectStateIncrease((PetscObject)A));
23793ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2380cd3f9d89SJunchao Zhang }
2381cd3f9d89SJunchao Zhang 
2382cd3f9d89SJunchao Zhang /*@C
2383cd3f9d89SJunchao Zhang   MatDenseGetArrayReadAndMemType - gives read-only access to the array where the data for a `MATDENSE` matrix is stored
2384cd3f9d89SJunchao Zhang 
2385cd3f9d89SJunchao Zhang   Logically Collective
2386cd3f9d89SJunchao Zhang 
2387cd3f9d89SJunchao Zhang   Input Parameter:
2388fe59aa6dSJacob Faibussowitsch . A - a dense matrix
2389cd3f9d89SJunchao Zhang 
2390cd3f9d89SJunchao Zhang   Output Parameters:
2391cd3f9d89SJunchao Zhang + array - pointer to the data
2392cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer
2393cd3f9d89SJunchao Zhang 
2394cd3f9d89SJunchao Zhang   Level: intermediate
2395cd3f9d89SJunchao Zhang 
23962ef1f0ffSBarry Smith   Notes:
23972ef1f0ffSBarry Smith   If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc.,
23982ef1f0ffSBarry Smith   an array on device is always returned and is guaranteed to contain the matrix's latest data.
23992ef1f0ffSBarry Smith 
24001cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayReadAndMemType()`, `MatDenseGetArrayWriteAndMemType()`,
2401cd3f9d89SJunchao Zhang    `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()`
2402cd3f9d89SJunchao Zhang @*/
2403cd3f9d89SJunchao Zhang PetscErrorCode MatDenseGetArrayReadAndMemType(Mat A, const PetscScalar **array, PetscMemType *mtype)
2404cd3f9d89SJunchao Zhang {
2405cd3f9d89SJunchao Zhang   PetscBool isMPI;
2406cd3f9d89SJunchao Zhang 
2407cd3f9d89SJunchao Zhang   PetscFunctionBegin;
2408cd3f9d89SJunchao Zhang   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
24094f572ea9SToby Isaac   PetscAssertPointer(array, 2);
2410e865de01SJunchao Zhang   PetscCall(MatBindToCPU(A, PETSC_FALSE)); /* We want device matrices to always return device arrays, so we unbind the matrix if it is bound to CPU */
2411cd3f9d89SJunchao Zhang   PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI));
2412cd3f9d89SJunchao Zhang   if (isMPI) { /* Dispatch here so that the code can be reused for all subclasses of MATDENSE */
2413cd3f9d89SJunchao Zhang     PetscCall(MatDenseGetArrayReadAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype));
2414cd3f9d89SJunchao Zhang   } else {
2415cd3f9d89SJunchao Zhang     PetscErrorCode (*fptr)(Mat, const PetscScalar **, PetscMemType *);
24163ba16761SJacob Faibussowitsch 
24173ba16761SJacob Faibussowitsch     PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayReadAndMemType_C", &fptr));
2418cd3f9d89SJunchao Zhang     if (fptr) {
2419cd3f9d89SJunchao Zhang       PetscCall((*fptr)(A, array, mtype));
2420cd3f9d89SJunchao Zhang     } else {
2421*5c0db29aSPierre Jolivet       PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array));
2422cd3f9d89SJunchao Zhang       if (mtype) *mtype = PETSC_MEMTYPE_HOST;
2423cd3f9d89SJunchao Zhang     }
2424cd3f9d89SJunchao Zhang   }
24253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2426cd3f9d89SJunchao Zhang }
2427cd3f9d89SJunchao Zhang 
2428cd3f9d89SJunchao Zhang /*@C
2429cd3f9d89SJunchao Zhang   MatDenseRestoreArrayReadAndMemType - returns access to the array that is obtained by `MatDenseGetArrayReadAndMemType()`
2430cd3f9d89SJunchao Zhang 
2431cd3f9d89SJunchao Zhang   Logically Collective
2432cd3f9d89SJunchao Zhang 
2433cd3f9d89SJunchao Zhang   Input Parameters:
2434fe59aa6dSJacob Faibussowitsch + A     - a dense matrix
2435cd3f9d89SJunchao Zhang - array - pointer to the data
2436cd3f9d89SJunchao Zhang 
2437cd3f9d89SJunchao Zhang   Level: intermediate
2438cd3f9d89SJunchao Zhang 
24391cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
2440cd3f9d89SJunchao Zhang @*/
2441cd3f9d89SJunchao Zhang PetscErrorCode MatDenseRestoreArrayReadAndMemType(Mat A, const PetscScalar **array)
2442cd3f9d89SJunchao Zhang {
2443cd3f9d89SJunchao Zhang   PetscBool isMPI;
2444cd3f9d89SJunchao Zhang 
2445cd3f9d89SJunchao Zhang   PetscFunctionBegin;
2446cd3f9d89SJunchao Zhang   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
24474f572ea9SToby Isaac   PetscAssertPointer(array, 2);
2448cd3f9d89SJunchao Zhang   PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI));
2449cd3f9d89SJunchao Zhang   if (isMPI) {
2450cd3f9d89SJunchao Zhang     PetscCall(MatDenseRestoreArrayReadAndMemType(((Mat_MPIDense *)A->data)->A, array));
2451cd3f9d89SJunchao Zhang   } else {
2452cd3f9d89SJunchao Zhang     PetscErrorCode (*fptr)(Mat, const PetscScalar **);
24533ba16761SJacob Faibussowitsch 
24543ba16761SJacob Faibussowitsch     PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayReadAndMemType_C", &fptr));
2455cd3f9d89SJunchao Zhang     if (fptr) {
2456cd3f9d89SJunchao Zhang       PetscCall((*fptr)(A, array));
2457cd3f9d89SJunchao Zhang     } else {
2458*5c0db29aSPierre Jolivet       PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array));
2459cd3f9d89SJunchao Zhang     }
2460cd3f9d89SJunchao Zhang     *array = NULL;
2461cd3f9d89SJunchao Zhang   }
24623ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2463cd3f9d89SJunchao Zhang }
2464cd3f9d89SJunchao Zhang 
2465cd3f9d89SJunchao Zhang /*@C
2466cd3f9d89SJunchao Zhang   MatDenseGetArrayWriteAndMemType - gives write-only access to the array where the data for a `MATDENSE` matrix is stored
2467cd3f9d89SJunchao Zhang 
2468cd3f9d89SJunchao Zhang   Logically Collective
2469cd3f9d89SJunchao Zhang 
2470cd3f9d89SJunchao Zhang   Input Parameter:
2471fe59aa6dSJacob Faibussowitsch . A - a dense matrix
2472cd3f9d89SJunchao Zhang 
2473cd3f9d89SJunchao Zhang   Output Parameters:
2474cd3f9d89SJunchao Zhang + array - pointer to the data
2475cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer
2476cd3f9d89SJunchao Zhang 
2477cd3f9d89SJunchao Zhang   Level: intermediate
2478cd3f9d89SJunchao Zhang 
24792ef1f0ffSBarry Smith   Notes:
24802ef1f0ffSBarry Smith   If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc.,
24812ef1f0ffSBarry Smith   an array on device is always returned and is guaranteed to contain the matrix's latest data.
24822ef1f0ffSBarry Smith 
24831cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayWriteAndMemType()`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArrayRead()`,
2484cd3f9d89SJunchao Zhang   `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()`
2485cd3f9d89SJunchao Zhang @*/
2486cd3f9d89SJunchao Zhang PetscErrorCode MatDenseGetArrayWriteAndMemType(Mat A, PetscScalar **array, PetscMemType *mtype)
2487cd3f9d89SJunchao Zhang {
2488cd3f9d89SJunchao Zhang   PetscBool isMPI;
2489cd3f9d89SJunchao Zhang 
2490cd3f9d89SJunchao Zhang   PetscFunctionBegin;
2491cd3f9d89SJunchao Zhang   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
24924f572ea9SToby Isaac   PetscAssertPointer(array, 2);
2493e865de01SJunchao Zhang   PetscCall(MatBindToCPU(A, PETSC_FALSE)); /* We want device matrices to always return device arrays, so we unbind the matrix if it is bound to CPU */
2494cd3f9d89SJunchao Zhang   PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI));
2495cd3f9d89SJunchao Zhang   if (isMPI) {
2496cd3f9d89SJunchao Zhang     PetscCall(MatDenseGetArrayWriteAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype));
2497cd3f9d89SJunchao Zhang   } else {
2498cd3f9d89SJunchao Zhang     PetscErrorCode (*fptr)(Mat, PetscScalar **, PetscMemType *);
24993ba16761SJacob Faibussowitsch 
25003ba16761SJacob Faibussowitsch     PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayWriteAndMemType_C", &fptr));
2501cd3f9d89SJunchao Zhang     if (fptr) {
2502cd3f9d89SJunchao Zhang       PetscCall((*fptr)(A, array, mtype));
2503cd3f9d89SJunchao Zhang     } else {
2504cd3f9d89SJunchao Zhang       PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array));
2505cd3f9d89SJunchao Zhang       if (mtype) *mtype = PETSC_MEMTYPE_HOST;
2506cd3f9d89SJunchao Zhang     }
2507cd3f9d89SJunchao Zhang   }
25083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2509cd3f9d89SJunchao Zhang }
2510cd3f9d89SJunchao Zhang 
2511cd3f9d89SJunchao Zhang /*@C
2512cd3f9d89SJunchao Zhang   MatDenseRestoreArrayWriteAndMemType - returns access to the array that is obtained by `MatDenseGetArrayReadAndMemType()`
2513cd3f9d89SJunchao Zhang 
2514cd3f9d89SJunchao Zhang   Logically Collective
2515cd3f9d89SJunchao Zhang 
2516cd3f9d89SJunchao Zhang   Input Parameters:
2517fe59aa6dSJacob Faibussowitsch + A     - a dense matrix
2518cd3f9d89SJunchao Zhang - array - pointer to the data
2519cd3f9d89SJunchao Zhang 
2520cd3f9d89SJunchao Zhang   Level: intermediate
2521cd3f9d89SJunchao Zhang 
25221cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayWriteAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
2523cd3f9d89SJunchao Zhang @*/
2524cd3f9d89SJunchao Zhang PetscErrorCode MatDenseRestoreArrayWriteAndMemType(Mat A, PetscScalar **array)
2525cd3f9d89SJunchao Zhang {
2526cd3f9d89SJunchao Zhang   PetscBool isMPI;
2527cd3f9d89SJunchao Zhang 
2528cd3f9d89SJunchao Zhang   PetscFunctionBegin;
2529cd3f9d89SJunchao Zhang   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
25304f572ea9SToby Isaac   PetscAssertPointer(array, 2);
2531cd3f9d89SJunchao Zhang   PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI));
2532cd3f9d89SJunchao Zhang   if (isMPI) {
2533cd3f9d89SJunchao Zhang     PetscCall(MatDenseRestoreArrayWriteAndMemType(((Mat_MPIDense *)A->data)->A, array));
2534cd3f9d89SJunchao Zhang   } else {
2535cd3f9d89SJunchao Zhang     PetscErrorCode (*fptr)(Mat, PetscScalar **);
25363ba16761SJacob Faibussowitsch 
25373ba16761SJacob Faibussowitsch     PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayWriteAndMemType_C", &fptr));
2538cd3f9d89SJunchao Zhang     if (fptr) {
2539cd3f9d89SJunchao Zhang       PetscCall((*fptr)(A, array));
2540cd3f9d89SJunchao Zhang     } else {
2541cd3f9d89SJunchao Zhang       PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array));
2542cd3f9d89SJunchao Zhang     }
2543cd3f9d89SJunchao Zhang     *array = NULL;
2544cd3f9d89SJunchao Zhang   }
2545cd3f9d89SJunchao Zhang   PetscCall(PetscObjectStateIncrease((PetscObject)A));
25463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2547cd3f9d89SJunchao Zhang }
2548cd3f9d89SJunchao Zhang 
2549d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A, IS isrow, IS iscol, MatReuse scall, Mat *B)
2550d71ae5a4SJacob Faibussowitsch {
2551c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense *)A->data;
2552bf5a80bcSToby Isaac   PetscInt        i, j, nrows, ncols, ldb;
25535d0c19d7SBarry Smith   const PetscInt *irow, *icol;
255487828ca2SBarry Smith   PetscScalar    *av, *bv, *v = mat->v;
25550754003eSLois Curfman McInnes   Mat             newmat;
25560754003eSLois Curfman McInnes 
25573a40ed3dSBarry Smith   PetscFunctionBegin;
25589566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(isrow, &irow));
25599566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(iscol, &icol));
25609566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(isrow, &nrows));
25619566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(iscol, &ncols));
25620754003eSLois Curfman McInnes 
2563182d2002SSatish Balay   /* Check submatrixcall */
2564182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
256513f74950SBarry Smith     PetscInt n_cols, n_rows;
25669566063dSJacob Faibussowitsch     PetscCall(MatGetSize(*B, &n_rows, &n_cols));
256721a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
2568f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
25699566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(*B, nrows, ncols, nrows, ncols));
257021a2c019SBarry Smith     }
2571182d2002SSatish Balay     newmat = *B;
2572182d2002SSatish Balay   } else {
25730754003eSLois Curfman McInnes     /* Create and fill new matrix */
25749566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &newmat));
25759566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(newmat, nrows, ncols, nrows, ncols));
25769566063dSJacob Faibussowitsch     PetscCall(MatSetType(newmat, ((PetscObject)A)->type_name));
25779566063dSJacob Faibussowitsch     PetscCall(MatSeqDenseSetPreallocation(newmat, NULL));
2578182d2002SSatish Balay   }
2579182d2002SSatish Balay 
2580182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
25819566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(newmat, &bv));
25829566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(newmat, &ldb));
2583182d2002SSatish Balay   for (i = 0; i < ncols; i++) {
25846de62eeeSBarry Smith     av = v + mat->lda * icol[i];
2585ca15aa20SStefano Zampini     for (j = 0; j < nrows; j++) bv[j] = av[irow[j]];
2586bf5a80bcSToby Isaac     bv += ldb;
25870754003eSLois Curfman McInnes   }
25889566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(newmat, &bv));
2589182d2002SSatish Balay 
2590182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
25919566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(newmat, MAT_FINAL_ASSEMBLY));
25929566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(newmat, MAT_FINAL_ASSEMBLY));
25930754003eSLois Curfman McInnes 
25940754003eSLois Curfman McInnes   /* Free work space */
25959566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(isrow, &irow));
25969566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(iscol, &icol));
2597182d2002SSatish Balay   *B = newmat;
25983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
25990754003eSLois Curfman McInnes }
26000754003eSLois Curfman McInnes 
2601d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A, PetscInt n, const IS irow[], const IS icol[], MatReuse scall, Mat *B[])
2602d71ae5a4SJacob Faibussowitsch {
260313f74950SBarry Smith   PetscInt i;
2604905e6a2fSBarry Smith 
26053a40ed3dSBarry Smith   PetscFunctionBegin;
260648a46eb9SPierre Jolivet   if (scall == MAT_INITIAL_MATRIX) PetscCall(PetscCalloc1(n, B));
2607905e6a2fSBarry Smith 
260848a46eb9SPierre Jolivet   for (i = 0; i < n; i++) PetscCall(MatCreateSubMatrix_SeqDense(A, irow[i], icol[i], scall, &(*B)[i]));
26093ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2610905e6a2fSBarry Smith }
2611905e6a2fSBarry Smith 
2612d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat, MatAssemblyType mode)
2613d71ae5a4SJacob Faibussowitsch {
2614c0aa2d19SHong Zhang   PetscFunctionBegin;
26153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2616c0aa2d19SHong Zhang }
2617c0aa2d19SHong Zhang 
2618d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat, MatAssemblyType mode)
2619d71ae5a4SJacob Faibussowitsch {
2620c0aa2d19SHong Zhang   PetscFunctionBegin;
26213ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2622c0aa2d19SHong Zhang }
2623c0aa2d19SHong Zhang 
2624d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCopy_SeqDense(Mat A, Mat B, MatStructure str)
2625d71ae5a4SJacob Faibussowitsch {
26264b0e389bSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data;
2627ca15aa20SStefano Zampini   const PetscScalar *va;
2628ca15aa20SStefano Zampini   PetscScalar       *vb;
2629d0f46423SBarry Smith   PetscInt           lda1 = a->lda, lda2 = b->lda, m = A->rmap->n, n = A->cmap->n, j;
26303a40ed3dSBarry Smith 
26313a40ed3dSBarry Smith   PetscFunctionBegin;
263233f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
263333f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
26349566063dSJacob Faibussowitsch     PetscCall(MatCopy_Basic(A, B, str));
26353ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
26363a40ed3dSBarry Smith   }
2637aed4548fSBarry Smith   PetscCheck(m == B->rmap->n && n == B->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "size(B) != size(A)");
26389566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &va));
26399566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(B, &vb));
2640a5ce6ee0Svictorle   if (lda1 > m || lda2 > m) {
264148a46eb9SPierre Jolivet     for (j = 0; j < n; j++) PetscCall(PetscArraycpy(vb + j * lda2, va + j * lda1, m));
2642a5ce6ee0Svictorle   } else {
26439566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(vb, va, A->rmap->n * A->cmap->n));
2644a5ce6ee0Svictorle   }
26459566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(B, &vb));
26469566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &va));
26479566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY));
26489566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY));
26493ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2650273d9f13SBarry Smith }
2651273d9f13SBarry Smith 
2652d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetUp_SeqDense(Mat A)
2653d71ae5a4SJacob Faibussowitsch {
2654273d9f13SBarry Smith   PetscFunctionBegin;
26559566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(A->rmap));
26569566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(A->cmap));
265748a46eb9SPierre Jolivet   if (!A->preallocated) PetscCall(MatSeqDenseSetPreallocation(A, NULL));
26583ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
26594b0e389bSBarry Smith }
26604b0e389bSBarry Smith 
2661d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatConjugate_SeqDense(Mat A)
2662d71ae5a4SJacob Faibussowitsch {
26634396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
266406c5243aSJose E. Roman   PetscInt      i, j;
26654396437dSToby Isaac   PetscInt      min = PetscMin(A->rmap->n, A->cmap->n);
2666ca15aa20SStefano Zampini   PetscScalar  *aa;
2667ba337c44SJed Brown 
2668ba337c44SJed Brown   PetscFunctionBegin;
26699566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &aa));
267006c5243aSJose E. Roman   for (j = 0; j < A->cmap->n; j++) {
267106c5243aSJose E. Roman     for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscConj(aa[i + j * mat->lda]);
267206c5243aSJose E. Roman   }
26739566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &aa));
26749371c9d4SSatish Balay   if (mat->tau)
26759371c9d4SSatish Balay     for (i = 0; i < min; i++) mat->tau[i] = PetscConj(mat->tau[i]);
26763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2677ba337c44SJed Brown }
2678ba337c44SJed Brown 
2679d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRealPart_SeqDense(Mat A)
2680d71ae5a4SJacob Faibussowitsch {
268106c5243aSJose E. Roman   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
268206c5243aSJose E. Roman   PetscInt      i, j;
2683ca15aa20SStefano Zampini   PetscScalar  *aa;
2684ba337c44SJed Brown 
2685ba337c44SJed Brown   PetscFunctionBegin;
26869566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &aa));
268706c5243aSJose E. Roman   for (j = 0; j < A->cmap->n; j++) {
268806c5243aSJose E. Roman     for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscRealPart(aa[i + j * mat->lda]);
268906c5243aSJose E. Roman   }
26909566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &aa));
26913ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2692ba337c44SJed Brown }
2693ba337c44SJed Brown 
2694d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatImaginaryPart_SeqDense(Mat A)
2695d71ae5a4SJacob Faibussowitsch {
269606c5243aSJose E. Roman   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
269706c5243aSJose E. Roman   PetscInt      i, j;
2698ca15aa20SStefano Zampini   PetscScalar  *aa;
2699ba337c44SJed Brown 
2700ba337c44SJed Brown   PetscFunctionBegin;
27019566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &aa));
270206c5243aSJose E. Roman   for (j = 0; j < A->cmap->n; j++) {
270306c5243aSJose E. Roman     for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscImaginaryPart(aa[i + j * mat->lda]);
270406c5243aSJose E. Roman   }
27059566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &aa));
27063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2707ba337c44SJed Brown }
2708284134d9SBarry Smith 
2709d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C)
2710d71ae5a4SJacob Faibussowitsch {
2711d0f46423SBarry Smith   PetscInt  m = A->rmap->n, n = B->cmap->n;
271247d993e7Ssuyashtn   PetscBool cisdense = PETSC_FALSE;
2713a9fe9ddaSSatish Balay 
2714ee16a9a1SHong Zhang   PetscFunctionBegin;
27159566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C, m, n, m, n));
271647d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA)
27179566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, ""));
271847d993e7Ssuyashtn #endif
271947d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP)
272047d993e7Ssuyashtn   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, ""));
272147d993e7Ssuyashtn #endif
27227a3c3d58SStefano Zampini   if (!cisdense) {
27237a3c3d58SStefano Zampini     PetscBool flg;
27247a3c3d58SStefano Zampini 
27259566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg));
27269566063dSJacob Faibussowitsch     PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE));
27277a3c3d58SStefano Zampini   }
27289566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
27293ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2730ee16a9a1SHong Zhang }
2731a9fe9ddaSSatish Balay 
2732d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C)
2733d71ae5a4SJacob Faibussowitsch {
27346718818eSStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data, *c = (Mat_SeqDense *)C->data;
27350805154bSBarry Smith   PetscBLASInt       m, n, k;
2736ca15aa20SStefano Zampini   const PetscScalar *av, *bv;
2737ca15aa20SStefano Zampini   PetscScalar       *cv;
2738a9fe9ddaSSatish Balay   PetscScalar        _DOne = 1.0, _DZero = 0.0;
2739a9fe9ddaSSatish Balay 
2740a9fe9ddaSSatish Balay   PetscFunctionBegin;
27419566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n, &m));
27429566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n, &n));
27439566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &k));
27443ba16761SJacob Faibussowitsch   if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS);
27459566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &av));
27469566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B, &bv));
27479566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C, &cv));
2748792fecdfSBarry Smith   PetscCallBLAS("BLASgemm", BLASgemm_("N", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda));
27499566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1)));
27509566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &av));
27519566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B, &bv));
27529566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C, &cv));
27533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2754a9fe9ddaSSatish Balay }
2755a9fe9ddaSSatish Balay 
2756d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C)
2757d71ae5a4SJacob Faibussowitsch {
275869f65d41SStefano Zampini   PetscInt  m = A->rmap->n, n = B->rmap->n;
275947d993e7Ssuyashtn   PetscBool cisdense = PETSC_FALSE;
276069f65d41SStefano Zampini 
276169f65d41SStefano Zampini   PetscFunctionBegin;
27629566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C, m, n, m, n));
276347d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA)
27649566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, ""));
276547d993e7Ssuyashtn #endif
276647d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP)
276747d993e7Ssuyashtn   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, ""));
276847d993e7Ssuyashtn #endif
27697a3c3d58SStefano Zampini   if (!cisdense) {
27707a3c3d58SStefano Zampini     PetscBool flg;
27717a3c3d58SStefano Zampini 
27729566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg));
27739566063dSJacob Faibussowitsch     PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE));
27747a3c3d58SStefano Zampini   }
27759566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
27763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
277769f65d41SStefano Zampini }
277869f65d41SStefano Zampini 
2779d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C)
2780d71ae5a4SJacob Faibussowitsch {
278169f65d41SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
278269f65d41SStefano Zampini   Mat_SeqDense      *b = (Mat_SeqDense *)B->data;
278369f65d41SStefano Zampini   Mat_SeqDense      *c = (Mat_SeqDense *)C->data;
27846718818eSStefano Zampini   const PetscScalar *av, *bv;
27856718818eSStefano Zampini   PetscScalar       *cv;
278669f65d41SStefano Zampini   PetscBLASInt       m, n, k;
278769f65d41SStefano Zampini   PetscScalar        _DOne = 1.0, _DZero = 0.0;
278869f65d41SStefano Zampini 
278969f65d41SStefano Zampini   PetscFunctionBegin;
27909566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n, &m));
27919566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n, &n));
27929566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &k));
27933ba16761SJacob Faibussowitsch   if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS);
27949566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &av));
27959566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B, &bv));
27969566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C, &cv));
2797792fecdfSBarry Smith   PetscCallBLAS("BLASgemm", BLASgemm_("N", "T", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda));
27989566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &av));
27999566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B, &bv));
28009566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C, &cv));
28019566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1)));
28023ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
280369f65d41SStefano Zampini }
280469f65d41SStefano Zampini 
2805d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C)
2806d71ae5a4SJacob Faibussowitsch {
2807d0f46423SBarry Smith   PetscInt  m = A->cmap->n, n = B->cmap->n;
280847d993e7Ssuyashtn   PetscBool cisdense = PETSC_FALSE;
2809a9fe9ddaSSatish Balay 
2810ee16a9a1SHong Zhang   PetscFunctionBegin;
28119566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C, m, n, m, n));
281247d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA)
28139566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, ""));
281447d993e7Ssuyashtn #endif
281547d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP)
281647d993e7Ssuyashtn   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, ""));
281747d993e7Ssuyashtn #endif
28187a3c3d58SStefano Zampini   if (!cisdense) {
28197a3c3d58SStefano Zampini     PetscBool flg;
28207a3c3d58SStefano Zampini 
28219566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg));
28229566063dSJacob Faibussowitsch     PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE));
28237a3c3d58SStefano Zampini   }
28249566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
28253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2826ee16a9a1SHong Zhang }
2827a9fe9ddaSSatish Balay 
2828d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C)
2829d71ae5a4SJacob Faibussowitsch {
2830a9fe9ddaSSatish Balay   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
2831a9fe9ddaSSatish Balay   Mat_SeqDense      *b = (Mat_SeqDense *)B->data;
2832a9fe9ddaSSatish Balay   Mat_SeqDense      *c = (Mat_SeqDense *)C->data;
28336718818eSStefano Zampini   const PetscScalar *av, *bv;
28346718818eSStefano Zampini   PetscScalar       *cv;
28350805154bSBarry Smith   PetscBLASInt       m, n, k;
2836a9fe9ddaSSatish Balay   PetscScalar        _DOne = 1.0, _DZero = 0.0;
2837a9fe9ddaSSatish Balay 
2838a9fe9ddaSSatish Balay   PetscFunctionBegin;
28399566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n, &m));
28409566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n, &n));
28419566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &k));
28423ba16761SJacob Faibussowitsch   if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS);
28439566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &av));
28449566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B, &bv));
28459566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C, &cv));
2846792fecdfSBarry Smith   PetscCallBLAS("BLASgemm", BLASgemm_("T", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda));
28479566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &av));
28489566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B, &bv));
28499566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C, &cv));
28509566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1)));
28513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2852a9fe9ddaSSatish Balay }
2853985db425SBarry Smith 
2854d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C)
2855d71ae5a4SJacob Faibussowitsch {
28564222ddf1SHong Zhang   PetscFunctionBegin;
28574222ddf1SHong Zhang   C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense;
28584222ddf1SHong Zhang   C->ops->productsymbolic = MatProductSymbolic_AB;
28593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
28604222ddf1SHong Zhang }
28614222ddf1SHong Zhang 
2862d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C)
2863d71ae5a4SJacob Faibussowitsch {
28644222ddf1SHong Zhang   PetscFunctionBegin;
28654222ddf1SHong Zhang   C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense;
28664222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_AtB;
28673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
28684222ddf1SHong Zhang }
28694222ddf1SHong Zhang 
2870d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C)
2871d71ae5a4SJacob Faibussowitsch {
28724222ddf1SHong Zhang   PetscFunctionBegin;
28734222ddf1SHong Zhang   C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense;
28744222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_ABt;
28753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
28764222ddf1SHong Zhang }
28774222ddf1SHong Zhang 
2878d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C)
2879d71ae5a4SJacob Faibussowitsch {
28804222ddf1SHong Zhang   Mat_Product *product = C->product;
28814222ddf1SHong Zhang 
28824222ddf1SHong Zhang   PetscFunctionBegin;
28834222ddf1SHong Zhang   switch (product->type) {
2884d71ae5a4SJacob Faibussowitsch   case MATPRODUCT_AB:
2885d71ae5a4SJacob Faibussowitsch     PetscCall(MatProductSetFromOptions_SeqDense_AB(C));
2886d71ae5a4SJacob Faibussowitsch     break;
2887d71ae5a4SJacob Faibussowitsch   case MATPRODUCT_AtB:
2888d71ae5a4SJacob Faibussowitsch     PetscCall(MatProductSetFromOptions_SeqDense_AtB(C));
2889d71ae5a4SJacob Faibussowitsch     break;
2890d71ae5a4SJacob Faibussowitsch   case MATPRODUCT_ABt:
2891d71ae5a4SJacob Faibussowitsch     PetscCall(MatProductSetFromOptions_SeqDense_ABt(C));
2892d71ae5a4SJacob Faibussowitsch     break;
2893d71ae5a4SJacob Faibussowitsch   default:
2894d71ae5a4SJacob Faibussowitsch     break;
28954222ddf1SHong Zhang   }
28963ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
28974222ddf1SHong Zhang }
28984222ddf1SHong Zhang 
2899d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMax_SeqDense(Mat A, Vec v, PetscInt idx[])
2900d71ae5a4SJacob Faibussowitsch {
2901985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
2902d0f46423SBarry Smith   PetscInt           i, j, m = A->rmap->n, n = A->cmap->n, p;
2903985db425SBarry Smith   PetscScalar       *x;
2904ca15aa20SStefano Zampini   const PetscScalar *aa;
2905985db425SBarry Smith 
2906985db425SBarry Smith   PetscFunctionBegin;
290728b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
29089566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
29099566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v, &p));
29109566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
291108401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector");
2912985db425SBarry Smith   for (i = 0; i < m; i++) {
29139371c9d4SSatish Balay     x[i] = aa[i];
29149371c9d4SSatish Balay     if (idx) idx[i] = 0;
2915985db425SBarry Smith     for (j = 1; j < n; j++) {
29169371c9d4SSatish Balay       if (PetscRealPart(x[i]) < PetscRealPart(aa[i + a->lda * j])) {
29179371c9d4SSatish Balay         x[i] = aa[i + a->lda * j];
29189371c9d4SSatish Balay         if (idx) idx[i] = j;
29199371c9d4SSatish Balay       }
2920985db425SBarry Smith     }
2921985db425SBarry Smith   }
29229566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
29239566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
29243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2925985db425SBarry Smith }
2926985db425SBarry Smith 
2927d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A, Vec v, PetscInt idx[])
2928d71ae5a4SJacob Faibussowitsch {
2929985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
2930d0f46423SBarry Smith   PetscInt           i, j, m = A->rmap->n, n = A->cmap->n, p;
2931985db425SBarry Smith   PetscScalar       *x;
2932985db425SBarry Smith   PetscReal          atmp;
2933ca15aa20SStefano Zampini   const PetscScalar *aa;
2934985db425SBarry Smith 
2935985db425SBarry Smith   PetscFunctionBegin;
293628b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
29379566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
29389566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v, &p));
29399566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
294008401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector");
2941985db425SBarry Smith   for (i = 0; i < m; i++) {
29429189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
2943985db425SBarry Smith     for (j = 1; j < n; j++) {
2944ca15aa20SStefano Zampini       atmp = PetscAbsScalar(aa[i + a->lda * j]);
29459371c9d4SSatish Balay       if (PetscAbsScalar(x[i]) < atmp) {
29469371c9d4SSatish Balay         x[i] = atmp;
29479371c9d4SSatish Balay         if (idx) idx[i] = j;
29489371c9d4SSatish Balay       }
2949985db425SBarry Smith     }
2950985db425SBarry Smith   }
29519566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
29529566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
29533ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2954985db425SBarry Smith }
2955985db425SBarry Smith 
2956d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMin_SeqDense(Mat A, Vec v, PetscInt idx[])
2957d71ae5a4SJacob Faibussowitsch {
2958985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
2959d0f46423SBarry Smith   PetscInt           i, j, m = A->rmap->n, n = A->cmap->n, p;
2960985db425SBarry Smith   PetscScalar       *x;
2961ca15aa20SStefano Zampini   const PetscScalar *aa;
2962985db425SBarry Smith 
2963985db425SBarry Smith   PetscFunctionBegin;
296428b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
29659566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
29669566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
29679566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v, &p));
296808401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector");
2969985db425SBarry Smith   for (i = 0; i < m; i++) {
29709371c9d4SSatish Balay     x[i] = aa[i];
29719371c9d4SSatish Balay     if (idx) idx[i] = 0;
2972985db425SBarry Smith     for (j = 1; j < n; j++) {
29739371c9d4SSatish Balay       if (PetscRealPart(x[i]) > PetscRealPart(aa[i + a->lda * j])) {
29749371c9d4SSatish Balay         x[i] = aa[i + a->lda * j];
29759371c9d4SSatish Balay         if (idx) idx[i] = j;
29769371c9d4SSatish Balay       }
2977985db425SBarry Smith     }
2978985db425SBarry Smith   }
29799566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
29809566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
29813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2982985db425SBarry Smith }
2983985db425SBarry Smith 
2984d71ae5a4SJacob Faibussowitsch PetscErrorCode MatGetColumnVector_SeqDense(Mat A, Vec v, PetscInt col)
2985d71ae5a4SJacob Faibussowitsch {
29868d0534beSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
29878d0534beSBarry Smith   PetscScalar       *x;
2988ca15aa20SStefano Zampini   const PetscScalar *aa;
29898d0534beSBarry Smith 
29908d0534beSBarry Smith   PetscFunctionBegin;
299128b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
29929566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
29939566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
29949566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(x, aa + col * a->lda, A->rmap->n));
29959566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
29969566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
29973ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29988d0534beSBarry Smith }
29998d0534beSBarry Smith 
3000d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatGetColumnReductions_SeqDense(Mat A, PetscInt type, PetscReal *reductions)
3001d71ae5a4SJacob Faibussowitsch {
30020716a85fSBarry Smith   PetscInt           i, j, m, n;
30031683a169SBarry Smith   const PetscScalar *a;
30040716a85fSBarry Smith 
30050716a85fSBarry Smith   PetscFunctionBegin;
30069566063dSJacob Faibussowitsch   PetscCall(MatGetSize(A, &m, &n));
30079566063dSJacob Faibussowitsch   PetscCall(PetscArrayzero(reductions, n));
30089566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &a));
3009857cbf51SRichard Tran Mills   if (type == NORM_2) {
30100716a85fSBarry Smith     for (i = 0; i < n; i++) {
3011ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j] * a[j]);
30120716a85fSBarry Smith       a += m;
30130716a85fSBarry Smith     }
3014857cbf51SRichard Tran Mills   } else if (type == NORM_1) {
30150716a85fSBarry Smith     for (i = 0; i < n; i++) {
3016ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j]);
30170716a85fSBarry Smith       a += m;
30180716a85fSBarry Smith     }
3019857cbf51SRichard Tran Mills   } else if (type == NORM_INFINITY) {
30200716a85fSBarry Smith     for (i = 0; i < n; i++) {
3021ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] = PetscMax(PetscAbsScalar(a[j]), reductions[i]);
30220716a85fSBarry Smith       a += m;
30230716a85fSBarry Smith     }
3024857cbf51SRichard Tran Mills   } else if (type == REDUCTION_SUM_REALPART || type == REDUCTION_MEAN_REALPART) {
3025a873a8cdSSam Reynolds     for (i = 0; i < n; i++) {
3026ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] += PetscRealPart(a[j]);
3027a873a8cdSSam Reynolds       a += m;
3028a873a8cdSSam Reynolds     }
3029857cbf51SRichard Tran Mills   } else if (type == REDUCTION_SUM_IMAGINARYPART || type == REDUCTION_MEAN_IMAGINARYPART) {
3030857cbf51SRichard Tran Mills     for (i = 0; i < n; i++) {
3031ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] += PetscImaginaryPart(a[j]);
3032857cbf51SRichard Tran Mills       a += m;
3033857cbf51SRichard Tran Mills     }
3034857cbf51SRichard Tran Mills   } else SETERRQ(PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Unknown reduction type");
30359566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &a));
3036857cbf51SRichard Tran Mills   if (type == NORM_2) {
3037a873a8cdSSam Reynolds     for (i = 0; i < n; i++) reductions[i] = PetscSqrtReal(reductions[i]);
3038857cbf51SRichard Tran Mills   } else if (type == REDUCTION_MEAN_REALPART || type == REDUCTION_MEAN_IMAGINARYPART) {
3039a873a8cdSSam Reynolds     for (i = 0; i < n; i++) reductions[i] /= m;
30400716a85fSBarry Smith   }
30413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30420716a85fSBarry Smith }
30430716a85fSBarry Smith 
3044d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetRandom_SeqDense(Mat x, PetscRandom rctx)
3045d71ae5a4SJacob Faibussowitsch {
304673a71a0fSBarry Smith   PetscScalar *a;
3047637a0070SStefano Zampini   PetscInt     lda, m, n, i, j;
304873a71a0fSBarry Smith 
304973a71a0fSBarry Smith   PetscFunctionBegin;
30509566063dSJacob Faibussowitsch   PetscCall(MatGetSize(x, &m, &n));
30519566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(x, &lda));
30523faff063SStefano Zampini   PetscCall(MatDenseGetArrayWrite(x, &a));
3053637a0070SStefano Zampini   for (j = 0; j < n; j++) {
305448a46eb9SPierre Jolivet     for (i = 0; i < m; i++) PetscCall(PetscRandomGetValue(rctx, a + j * lda + i));
305573a71a0fSBarry Smith   }
30563faff063SStefano Zampini   PetscCall(MatDenseRestoreArrayWrite(x, &a));
30573ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
305873a71a0fSBarry Smith }
305973a71a0fSBarry Smith 
3060d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A, PetscBool *missing, PetscInt *d)
3061d71ae5a4SJacob Faibussowitsch {
30623b49f96aSBarry Smith   PetscFunctionBegin;
30633b49f96aSBarry Smith   *missing = PETSC_FALSE;
30643ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30653b49f96aSBarry Smith }
306673a71a0fSBarry Smith 
3067ca15aa20SStefano Zampini /* vals is not const */
3068d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A, PetscInt col, PetscScalar **vals)
3069d71ae5a4SJacob Faibussowitsch {
307086aefd0dSHong Zhang   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
3071ca15aa20SStefano Zampini   PetscScalar  *v;
307286aefd0dSHong Zhang 
307386aefd0dSHong Zhang   PetscFunctionBegin;
307428b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
30759566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
3076ca15aa20SStefano Zampini   *vals = v + col * a->lda;
30779566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
30783ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
307986aefd0dSHong Zhang }
308086aefd0dSHong Zhang 
3081d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A, PetscScalar **vals)
3082d71ae5a4SJacob Faibussowitsch {
308386aefd0dSHong Zhang   PetscFunctionBegin;
3084742765d3SMatthew Knepley   if (vals) *vals = NULL; /* user cannot accidentally use the array later */
30853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
308686aefd0dSHong Zhang }
3087abc3b08eSStefano Zampini 
3088a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqDense,
3089905e6a2fSBarry Smith                                        MatGetRow_SeqDense,
3090905e6a2fSBarry Smith                                        MatRestoreRow_SeqDense,
3091905e6a2fSBarry Smith                                        MatMult_SeqDense,
309297304618SKris Buschelman                                        /*  4*/ MatMultAdd_SeqDense,
30937c922b88SBarry Smith                                        MatMultTranspose_SeqDense,
30947c922b88SBarry Smith                                        MatMultTransposeAdd_SeqDense,
3095f4259b30SLisandro Dalcin                                        NULL,
3096f4259b30SLisandro Dalcin                                        NULL,
3097f4259b30SLisandro Dalcin                                        NULL,
3098f4259b30SLisandro Dalcin                                        /* 10*/ NULL,
3099905e6a2fSBarry Smith                                        MatLUFactor_SeqDense,
3100905e6a2fSBarry Smith                                        MatCholeskyFactor_SeqDense,
310141f059aeSBarry Smith                                        MatSOR_SeqDense,
3102ec8511deSBarry Smith                                        MatTranspose_SeqDense,
310397304618SKris Buschelman                                        /* 15*/ MatGetInfo_SeqDense,
3104905e6a2fSBarry Smith                                        MatEqual_SeqDense,
3105905e6a2fSBarry Smith                                        MatGetDiagonal_SeqDense,
3106905e6a2fSBarry Smith                                        MatDiagonalScale_SeqDense,
3107905e6a2fSBarry Smith                                        MatNorm_SeqDense,
3108c0aa2d19SHong Zhang                                        /* 20*/ MatAssemblyBegin_SeqDense,
3109c0aa2d19SHong Zhang                                        MatAssemblyEnd_SeqDense,
3110905e6a2fSBarry Smith                                        MatSetOption_SeqDense,
3111905e6a2fSBarry Smith                                        MatZeroEntries_SeqDense,
3112d519adbfSMatthew Knepley                                        /* 24*/ MatZeroRows_SeqDense,
3113f4259b30SLisandro Dalcin                                        NULL,
3114f4259b30SLisandro Dalcin                                        NULL,
3115f4259b30SLisandro Dalcin                                        NULL,
3116f4259b30SLisandro Dalcin                                        NULL,
31174994cf47SJed Brown                                        /* 29*/ MatSetUp_SeqDense,
3118f4259b30SLisandro Dalcin                                        NULL,
3119f4259b30SLisandro Dalcin                                        NULL,
3120f4259b30SLisandro Dalcin                                        NULL,
3121f4259b30SLisandro Dalcin                                        NULL,
3122d519adbfSMatthew Knepley                                        /* 34*/ MatDuplicate_SeqDense,
3123f4259b30SLisandro Dalcin                                        NULL,
3124f4259b30SLisandro Dalcin                                        NULL,
3125f4259b30SLisandro Dalcin                                        NULL,
3126f4259b30SLisandro Dalcin                                        NULL,
3127d519adbfSMatthew Knepley                                        /* 39*/ MatAXPY_SeqDense,
31287dae84e0SHong Zhang                                        MatCreateSubMatrices_SeqDense,
3129f4259b30SLisandro Dalcin                                        NULL,
31304b0e389bSBarry Smith                                        MatGetValues_SeqDense,
3131a5ae1ecdSBarry Smith                                        MatCopy_SeqDense,
3132d519adbfSMatthew Knepley                                        /* 44*/ MatGetRowMax_SeqDense,
3133a5ae1ecdSBarry Smith                                        MatScale_SeqDense,
31342f605a99SJose E. Roman                                        MatShift_SeqDense,
3135f4259b30SLisandro Dalcin                                        NULL,
31363f49a652SStefano Zampini                                        MatZeroRowsColumns_SeqDense,
313773a71a0fSBarry Smith                                        /* 49*/ MatSetRandom_SeqDense,
3138f4259b30SLisandro Dalcin                                        NULL,
3139f4259b30SLisandro Dalcin                                        NULL,
3140f4259b30SLisandro Dalcin                                        NULL,
3141f4259b30SLisandro Dalcin                                        NULL,
3142f4259b30SLisandro Dalcin                                        /* 54*/ NULL,
3143f4259b30SLisandro Dalcin                                        NULL,
3144f4259b30SLisandro Dalcin                                        NULL,
3145f4259b30SLisandro Dalcin                                        NULL,
3146f4259b30SLisandro Dalcin                                        NULL,
3147023c16fcSToby Isaac                                        /* 59*/ MatCreateSubMatrix_SeqDense,
3148e03a110bSBarry Smith                                        MatDestroy_SeqDense,
3149e03a110bSBarry Smith                                        MatView_SeqDense,
3150f4259b30SLisandro Dalcin                                        NULL,
3151f4259b30SLisandro Dalcin                                        NULL,
3152f4259b30SLisandro Dalcin                                        /* 64*/ NULL,
3153f4259b30SLisandro Dalcin                                        NULL,
3154f4259b30SLisandro Dalcin                                        NULL,
3155f4259b30SLisandro Dalcin                                        NULL,
3156f4259b30SLisandro Dalcin                                        NULL,
3157d519adbfSMatthew Knepley                                        /* 69*/ MatGetRowMaxAbs_SeqDense,
3158f4259b30SLisandro Dalcin                                        NULL,
3159f4259b30SLisandro Dalcin                                        NULL,
3160f4259b30SLisandro Dalcin                                        NULL,
3161f4259b30SLisandro Dalcin                                        NULL,
3162f4259b30SLisandro Dalcin                                        /* 74*/ NULL,
3163f4259b30SLisandro Dalcin                                        NULL,
3164f4259b30SLisandro Dalcin                                        NULL,
3165f4259b30SLisandro Dalcin                                        NULL,
3166f4259b30SLisandro Dalcin                                        NULL,
3167f4259b30SLisandro Dalcin                                        /* 79*/ NULL,
3168f4259b30SLisandro Dalcin                                        NULL,
3169f4259b30SLisandro Dalcin                                        NULL,
3170f4259b30SLisandro Dalcin                                        NULL,
31715bba2384SShri Abhyankar                                        /* 83*/ MatLoad_SeqDense,
3172637a0070SStefano Zampini                                        MatIsSymmetric_SeqDense,
31731cbb95d3SBarry Smith                                        MatIsHermitian_SeqDense,
3174f4259b30SLisandro Dalcin                                        NULL,
3175f4259b30SLisandro Dalcin                                        NULL,
3176f4259b30SLisandro Dalcin                                        NULL,
3177f4259b30SLisandro Dalcin                                        /* 89*/ NULL,
3178f4259b30SLisandro Dalcin                                        NULL,
3179a9fe9ddaSSatish Balay                                        MatMatMultNumeric_SeqDense_SeqDense,
3180f4259b30SLisandro Dalcin                                        NULL,
3181f4259b30SLisandro Dalcin                                        NULL,
3182f4259b30SLisandro Dalcin                                        /* 94*/ NULL,
3183f4259b30SLisandro Dalcin                                        NULL,
3184f4259b30SLisandro Dalcin                                        NULL,
318569f65d41SStefano Zampini                                        MatMatTransposeMultNumeric_SeqDense_SeqDense,
3186f4259b30SLisandro Dalcin                                        NULL,
31874222ddf1SHong Zhang                                        /* 99*/ MatProductSetFromOptions_SeqDense,
3188f4259b30SLisandro Dalcin                                        NULL,
3189f4259b30SLisandro Dalcin                                        NULL,
3190ba337c44SJed Brown                                        MatConjugate_SeqDense,
3191f4259b30SLisandro Dalcin                                        NULL,
3192f4259b30SLisandro Dalcin                                        /*104*/ NULL,
3193ba337c44SJed Brown                                        MatRealPart_SeqDense,
3194ba337c44SJed Brown                                        MatImaginaryPart_SeqDense,
3195f4259b30SLisandro Dalcin                                        NULL,
3196f4259b30SLisandro Dalcin                                        NULL,
3197f4259b30SLisandro Dalcin                                        /*109*/ NULL,
3198f4259b30SLisandro Dalcin                                        NULL,
31998d0534beSBarry Smith                                        MatGetRowMin_SeqDense,
3200aabbc4fbSShri Abhyankar                                        MatGetColumnVector_SeqDense,
32013b49f96aSBarry Smith                                        MatMissingDiagonal_SeqDense,
3202f4259b30SLisandro Dalcin                                        /*114*/ NULL,
3203f4259b30SLisandro Dalcin                                        NULL,
3204f4259b30SLisandro Dalcin                                        NULL,
3205f4259b30SLisandro Dalcin                                        NULL,
3206f4259b30SLisandro Dalcin                                        NULL,
3207f4259b30SLisandro Dalcin                                        /*119*/ NULL,
3208f4259b30SLisandro Dalcin                                        NULL,
3209f4259b30SLisandro Dalcin                                        NULL,
3210f4259b30SLisandro Dalcin                                        NULL,
3211f4259b30SLisandro Dalcin                                        NULL,
3212f4259b30SLisandro Dalcin                                        /*124*/ NULL,
3213a873a8cdSSam Reynolds                                        MatGetColumnReductions_SeqDense,
3214f4259b30SLisandro Dalcin                                        NULL,
3215f4259b30SLisandro Dalcin                                        NULL,
3216f4259b30SLisandro Dalcin                                        NULL,
3217f4259b30SLisandro Dalcin                                        /*129*/ NULL,
3218f4259b30SLisandro Dalcin                                        NULL,
3219f4259b30SLisandro Dalcin                                        NULL,
322075648e8dSHong Zhang                                        MatTransposeMatMultNumeric_SeqDense_SeqDense,
3221f4259b30SLisandro Dalcin                                        NULL,
3222f4259b30SLisandro Dalcin                                        /*134*/ NULL,
3223f4259b30SLisandro Dalcin                                        NULL,
3224f4259b30SLisandro Dalcin                                        NULL,
3225f4259b30SLisandro Dalcin                                        NULL,
3226f4259b30SLisandro Dalcin                                        NULL,
3227f4259b30SLisandro Dalcin                                        /*139*/ NULL,
3228f4259b30SLisandro Dalcin                                        NULL,
3229f4259b30SLisandro Dalcin                                        NULL,
3230f4259b30SLisandro Dalcin                                        NULL,
3231f4259b30SLisandro Dalcin                                        NULL,
32324222ddf1SHong Zhang                                        MatCreateMPIMatConcatenateSeqMat_SeqDense,
3233f4259b30SLisandro Dalcin                                        /*145*/ NULL,
3234f4259b30SLisandro Dalcin                                        NULL,
323599a7f59eSMark Adams                                        NULL,
323699a7f59eSMark Adams                                        NULL,
32377fb60732SBarry Smith                                        NULL,
3238dec0b466SHong Zhang                                        /*150*/ NULL,
3239dec0b466SHong Zhang                                        NULL};
324090ace30eSBarry Smith 
32414b828684SBarry Smith /*@C
324211a5261eSBarry Smith   MatCreateSeqDense - Creates a `MATSEQDENSE` that
32432ef1f0ffSBarry Smith   is stored in column major order (the usual Fortran manner). Many
3244d65003e9SLois Curfman McInnes   of the matrix operations use the BLAS and LAPACK routines.
3245289bc588SBarry Smith 
3246d083f849SBarry Smith   Collective
3247db81eaa0SLois Curfman McInnes 
324820563c6bSBarry Smith   Input Parameters:
324911a5261eSBarry Smith + comm - MPI communicator, set to `PETSC_COMM_SELF`
32500c775827SLois Curfman McInnes . m    - number of rows
325118f449edSLois Curfman McInnes . n    - number of columns
32522ef1f0ffSBarry Smith - data - optional location of matrix data in column major order.  Use `NULL` for PETSc
3253dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
325420563c6bSBarry Smith 
325520563c6bSBarry Smith   Output Parameter:
325644cd7ae7SLois Curfman McInnes . A - the matrix
325720563c6bSBarry Smith 
32582ef1f0ffSBarry Smith   Level: intermediate
32592ef1f0ffSBarry Smith 
326011a5261eSBarry Smith   Note:
326118f449edSLois Curfman McInnes   The data input variable is intended primarily for Fortran programmers
326218f449edSLois Curfman McInnes   who wish to allocate their own matrix memory space.  Most users should
32632ef1f0ffSBarry Smith   set `data` = `NULL`.
326418f449edSLois Curfman McInnes 
32651cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()`
326620563c6bSBarry Smith @*/
3267d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateSeqDense(MPI_Comm comm, PetscInt m, PetscInt n, PetscScalar *data, Mat *A)
3268d71ae5a4SJacob Faibussowitsch {
32693a40ed3dSBarry Smith   PetscFunctionBegin;
32709566063dSJacob Faibussowitsch   PetscCall(MatCreate(comm, A));
32719566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*A, m, n, m, n));
32729566063dSJacob Faibussowitsch   PetscCall(MatSetType(*A, MATSEQDENSE));
32739566063dSJacob Faibussowitsch   PetscCall(MatSeqDenseSetPreallocation(*A, data));
32743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3275273d9f13SBarry Smith }
3276273d9f13SBarry Smith 
3277273d9f13SBarry Smith /*@C
327811a5261eSBarry Smith   MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements of a `MATSEQDENSE` matrix
3279273d9f13SBarry Smith 
3280d083f849SBarry Smith   Collective
3281273d9f13SBarry Smith 
3282273d9f13SBarry Smith   Input Parameters:
32831c4f3114SJed Brown + B    - the matrix
32842ef1f0ffSBarry Smith - data - the array (or `NULL`)
32852ef1f0ffSBarry Smith 
32862ef1f0ffSBarry Smith   Level: intermediate
3287273d9f13SBarry Smith 
328811a5261eSBarry Smith   Note:
3289273d9f13SBarry Smith   The data input variable is intended primarily for Fortran programmers
3290273d9f13SBarry Smith   who wish to allocate their own matrix memory space.  Most users should
3291284134d9SBarry Smith   need not call this routine.
3292273d9f13SBarry Smith 
32931cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()`, `MatDenseSetLDA()`
3294273d9f13SBarry Smith @*/
3295d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation(Mat B, PetscScalar data[])
3296d71ae5a4SJacob Faibussowitsch {
3297a23d5eceSKris Buschelman   PetscFunctionBegin;
3298d5ea218eSStefano Zampini   PetscValidHeaderSpecific(B, MAT_CLASSID, 1);
3299cac4c232SBarry Smith   PetscTryMethod(B, "MatSeqDenseSetPreallocation_C", (Mat, PetscScalar[]), (B, data));
33003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3301a23d5eceSKris Buschelman }
3302a23d5eceSKris Buschelman 
3303d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation_SeqDense(Mat B, PetscScalar *data)
3304d71ae5a4SJacob Faibussowitsch {
3305ad16ce7aSStefano Zampini   Mat_SeqDense *b = (Mat_SeqDense *)B->data;
3306273d9f13SBarry Smith 
3307273d9f13SBarry Smith   PetscFunctionBegin;
330828b400f6SJacob Faibussowitsch   PetscCheck(!b->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
3309273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
3310a868139aSShri Abhyankar 
33119566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(B->rmap));
33129566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(B->cmap));
331334ef9618SShri Abhyankar 
3314ad16ce7aSStefano Zampini   if (b->lda <= 0) b->lda = B->rmap->n;
331586d161a7SShri Abhyankar 
33169e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
33179566063dSJacob Faibussowitsch     if (!b->user_alloc) PetscCall(PetscFree(b->v));
33189566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1((size_t)b->lda * B->cmap->n, &b->v));
33192205254eSKarl Rupp 
33209e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
3321273d9f13SBarry Smith   } else { /* user-allocated storage */
33229566063dSJacob Faibussowitsch     if (!b->user_alloc) PetscCall(PetscFree(b->v));
3323273d9f13SBarry Smith     b->v          = data;
3324273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
3325273d9f13SBarry Smith   }
33260450473dSBarry Smith   B->assembled = PETSC_TRUE;
33273ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3328273d9f13SBarry Smith }
3329273d9f13SBarry Smith 
333065b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
3331d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype, MatReuse reuse, Mat *newmat)
3332d71ae5a4SJacob Faibussowitsch {
3333d77f618aSHong Zhang   Mat                mat_elemental;
33341683a169SBarry Smith   const PetscScalar *array;
33351683a169SBarry Smith   PetscScalar       *v_colwise;
3336d77f618aSHong Zhang   PetscInt           M = A->rmap->N, N = A->cmap->N, i, j, k, *rows, *cols;
3337d77f618aSHong Zhang 
33388baccfbdSHong Zhang   PetscFunctionBegin;
33399566063dSJacob Faibussowitsch   PetscCall(PetscMalloc3(M * N, &v_colwise, M, &rows, N, &cols));
33409566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &array));
3341d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
3342d77f618aSHong Zhang   k = 0;
3343d77f618aSHong Zhang   for (j = 0; j < N; j++) {
3344d77f618aSHong Zhang     cols[j] = j;
3345ad540459SPierre Jolivet     for (i = 0; i < M; i++) v_colwise[j * M + i] = array[k++];
3346d77f618aSHong Zhang   }
3347ad540459SPierre Jolivet   for (i = 0; i < M; i++) rows[i] = i;
33489566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &array));
3349d77f618aSHong Zhang 
33509566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental));
33519566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(mat_elemental, PETSC_DECIDE, PETSC_DECIDE, M, N));
33529566063dSJacob Faibussowitsch   PetscCall(MatSetType(mat_elemental, MATELEMENTAL));
33539566063dSJacob Faibussowitsch   PetscCall(MatSetUp(mat_elemental));
3354d77f618aSHong Zhang 
3355d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
33569566063dSJacob Faibussowitsch   PetscCall(MatSetValues(mat_elemental, M, rows, N, cols, v_colwise, ADD_VALUES));
33579566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY));
33589566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY));
33599566063dSJacob Faibussowitsch   PetscCall(PetscFree3(v_colwise, rows, cols));
3360d77f618aSHong Zhang 
3361511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
33629566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A, &mat_elemental));
3363d77f618aSHong Zhang   } else {
3364d77f618aSHong Zhang     *newmat = mat_elemental;
3365d77f618aSHong Zhang   }
33663ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
33678baccfbdSHong Zhang }
336865b80a83SHong Zhang #endif
33698baccfbdSHong Zhang 
3370d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA_SeqDense(Mat B, PetscInt lda)
3371d71ae5a4SJacob Faibussowitsch {
33721b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense *)B->data;
33737422da62SJose E. Roman   PetscBool     data;
337421a2c019SBarry Smith 
33751b807ce4Svictorle   PetscFunctionBegin;
33767422da62SJose E. Roman   data = (PetscBool)((B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE);
3377aed4548fSBarry Smith   PetscCheck(b->user_alloc || !data || b->lda == lda, PETSC_COMM_SELF, PETSC_ERR_ORDER, "LDA cannot be changed after allocation of internal storage");
337808401ef6SPierre 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);
33791b807ce4Svictorle   b->lda = lda;
33803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
33811b807ce4Svictorle }
33821b807ce4Svictorle 
3383d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm, Mat inmat, PetscInt n, MatReuse scall, Mat *outmat)
3384d71ae5a4SJacob Faibussowitsch {
3385d528f656SJakub Kruzik   PetscFunctionBegin;
33869566063dSJacob Faibussowitsch   PetscCall(MatCreateMPIMatConcatenateSeqMat_MPIDense(comm, inmat, n, scall, outmat));
33873ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3388d528f656SJakub Kruzik }
3389d528f656SJakub Kruzik 
3390d16ceb75SStefano Zampini PetscErrorCode MatDenseCreateColumnVec_Private(Mat A, Vec *v)
3391d16ceb75SStefano Zampini {
3392d16ceb75SStefano Zampini   PetscBool   isstd, iskok, iscuda, iship;
3393d16ceb75SStefano Zampini   PetscMPIInt size;
3394d16ceb75SStefano Zampini #if PetscDefined(HAVE_CUDA) || PetscDefined(HAVE_HIP)
3395d16ceb75SStefano Zampini   /* we pass the data of A, to prevent allocating needless GPU memory the first time VecCUPMPlaceArray is called. */
3396d16ceb75SStefano Zampini   const PetscScalar *a;
3397d16ceb75SStefano Zampini #endif
3398d16ceb75SStefano Zampini 
3399d16ceb75SStefano Zampini   PetscFunctionBegin;
3400d16ceb75SStefano Zampini   *v = NULL;
3401d16ceb75SStefano Zampini   PetscCall(PetscStrcmpAny(A->defaultvectype, &isstd, VECSTANDARD, VECSEQ, VECMPI, ""));
3402d16ceb75SStefano Zampini   PetscCall(PetscStrcmpAny(A->defaultvectype, &iskok, VECKOKKOS, VECSEQKOKKOS, VECMPIKOKKOS, ""));
3403d16ceb75SStefano Zampini   PetscCall(PetscStrcmpAny(A->defaultvectype, &iscuda, VECCUDA, VECSEQCUDA, VECMPICUDA, ""));
3404d16ceb75SStefano Zampini   PetscCall(PetscStrcmpAny(A->defaultvectype, &iship, VECHIP, VECSEQHIP, VECMPIHIP, ""));
3405d16ceb75SStefano Zampini   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A), &size));
3406d16ceb75SStefano Zampini   if (isstd) {
3407d16ceb75SStefano Zampini     if (size > 1) PetscCall(VecCreateMPIWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, v));
3408d16ceb75SStefano Zampini     else PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, v));
3409d16ceb75SStefano Zampini   } else if (iskok) {
3410d16ceb75SStefano Zampini     PetscCheck(PetscDefined(HAVE_KOKKOS_KERNELS), PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Reconfigure using KOKKOS kernels support");
3411d16ceb75SStefano Zampini #if PetscDefined(HAVE_KOKKOS_KERNELS)
3412d16ceb75SStefano Zampini     if (size > 1) PetscCall(VecCreateMPIKokkosWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, v));
3413d16ceb75SStefano Zampini     else PetscCall(VecCreateSeqKokkosWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, v));
3414d16ceb75SStefano Zampini #endif
3415d16ceb75SStefano Zampini   } else if (iscuda) {
3416d16ceb75SStefano Zampini     PetscCheck(PetscDefined(HAVE_CUDA), PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Reconfigure using CUDA support");
3417d16ceb75SStefano Zampini #if PetscDefined(HAVE_CUDA)
3418d16ceb75SStefano Zampini     PetscCall(MatDenseCUDAGetArrayRead(A, &a));
3419d16ceb75SStefano Zampini     if (size > 1) PetscCall(VecCreateMPICUDAWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, a, v));
3420d16ceb75SStefano Zampini     else PetscCall(VecCreateSeqCUDAWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, a, v));
3421d16ceb75SStefano Zampini #endif
3422d16ceb75SStefano Zampini   } else if (iship) {
3423d16ceb75SStefano Zampini     PetscCheck(PetscDefined(HAVE_HIP), PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Reconfigure using HIP support");
3424d16ceb75SStefano Zampini #if PetscDefined(HAVE_HIP)
3425d16ceb75SStefano Zampini     PetscCall(MatDenseHIPGetArrayRead(A, &a));
3426d16ceb75SStefano Zampini     if (size > 1) PetscCall(VecCreateMPIHIPWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, a, v));
3427d16ceb75SStefano Zampini     else PetscCall(VecCreateSeqHIPWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, a, v));
3428d16ceb75SStefano Zampini #endif
3429d16ceb75SStefano Zampini   }
3430d16ceb75SStefano Zampini   PetscCheck(*v, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Not coded for type %s", A->defaultvectype);
3431d16ceb75SStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
3432d16ceb75SStefano Zampini }
3433d16ceb75SStefano Zampini 
3434d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A, PetscInt col, Vec *v)
3435d71ae5a4SJacob Faibussowitsch {
34366947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
34376947451fSStefano Zampini 
34386947451fSStefano Zampini   PetscFunctionBegin;
343928b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
344028b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
3441d16ceb75SStefano Zampini   if (!a->cvec) PetscCall(MatDenseCreateColumnVec_Private(A, &a->cvec));
34426947451fSStefano Zampini   a->vecinuse = col + 1;
34439566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, (PetscScalar **)&a->ptrinuse));
34449566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda));
34456947451fSStefano Zampini   *v = a->cvec;
34463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
34476947451fSStefano Zampini }
34486947451fSStefano Zampini 
3449d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A, PetscInt col, Vec *v)
3450d71ae5a4SJacob Faibussowitsch {
34516947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
34526947451fSStefano Zampini 
34536947451fSStefano Zampini   PetscFunctionBegin;
345428b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first");
345528b400f6SJacob Faibussowitsch   PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector");
34566947451fSStefano Zampini   a->vecinuse = 0;
34579566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, (PetscScalar **)&a->ptrinuse));
34589566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
345975f6d85dSStefano Zampini   if (v) *v = NULL;
34603ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
34616947451fSStefano Zampini }
34626947451fSStefano Zampini 
3463d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v)
3464d71ae5a4SJacob Faibussowitsch {
34656947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
34666947451fSStefano Zampini 
34676947451fSStefano Zampini   PetscFunctionBegin;
346828b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
346928b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
3470d16ceb75SStefano Zampini   if (!a->cvec) PetscCall(MatDenseCreateColumnVec_Private(A, &a->cvec));
34716947451fSStefano Zampini   a->vecinuse = col + 1;
34729566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &a->ptrinuse));
34739566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda));
34749566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(a->cvec));
34756947451fSStefano Zampini   *v = a->cvec;
34763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
34776947451fSStefano Zampini }
34786947451fSStefano Zampini 
3479d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v)
3480d71ae5a4SJacob Faibussowitsch {
34816947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
34826947451fSStefano Zampini 
34836947451fSStefano Zampini   PetscFunctionBegin;
348428b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first");
348528b400f6SJacob Faibussowitsch   PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector");
34866947451fSStefano Zampini   a->vecinuse = 0;
34879566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &a->ptrinuse));
34889566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(a->cvec));
34899566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
349075f6d85dSStefano Zampini   if (v) *v = NULL;
34913ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
34926947451fSStefano Zampini }
34936947451fSStefano Zampini 
3494d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v)
3495d71ae5a4SJacob Faibussowitsch {
34966947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
34976947451fSStefano Zampini 
34986947451fSStefano Zampini   PetscFunctionBegin;
349928b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
350028b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
3501d16ceb75SStefano Zampini   if (!a->cvec) PetscCall(MatDenseCreateColumnVec_Private(A, &a->cvec));
35026947451fSStefano Zampini   a->vecinuse = col + 1;
35039566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(A, (PetscScalar **)&a->ptrinuse));
35049566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda));
35056947451fSStefano Zampini   *v = a->cvec;
35063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
35076947451fSStefano Zampini }
35086947451fSStefano Zampini 
3509d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v)
3510d71ae5a4SJacob Faibussowitsch {
35116947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
35126947451fSStefano Zampini 
35136947451fSStefano Zampini   PetscFunctionBegin;
351428b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first");
351528b400f6SJacob Faibussowitsch   PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector");
35166947451fSStefano Zampini   a->vecinuse = 0;
35179566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(A, (PetscScalar **)&a->ptrinuse));
35189566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
351975f6d85dSStefano Zampini   if (v) *v = NULL;
35203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
35216947451fSStefano Zampini }
35226947451fSStefano Zampini 
3523d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v)
3524d71ae5a4SJacob Faibussowitsch {
35255ea7661aSPierre Jolivet   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
35265ea7661aSPierre Jolivet 
35275ea7661aSPierre Jolivet   PetscFunctionBegin;
352828b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
352928b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
3530a2748737SPierre Jolivet   if (a->cmat && (cend - cbegin != a->cmat->cmap->N || rend - rbegin != a->cmat->rmap->N)) PetscCall(MatDestroy(&a->cmat));
35315ea7661aSPierre Jolivet   if (!a->cmat) {
3532*5c0db29aSPierre Jolivet     PetscCall(MatCreateDense(PetscObjectComm((PetscObject)A), rend - rbegin, PETSC_DECIDE, rend - rbegin, cend - cbegin, a->v ? a->v + rbegin + (size_t)cbegin * a->lda : NULL, &a->cmat));
35335ea7661aSPierre Jolivet   } else {
3534*5c0db29aSPierre Jolivet     PetscCall(MatDensePlaceArray(a->cmat, a->v ? a->v + rbegin + (size_t)cbegin * a->lda : NULL));
35355ea7661aSPierre Jolivet   }
35369566063dSJacob Faibussowitsch   PetscCall(MatDenseSetLDA(a->cmat, a->lda));
35375ea7661aSPierre Jolivet   a->matinuse = cbegin + 1;
35385ea7661aSPierre Jolivet   *v          = a->cmat;
353947d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
354075f6d85dSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
354175f6d85dSStefano Zampini #endif
35423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
35435ea7661aSPierre Jolivet }
35445ea7661aSPierre Jolivet 
3545d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A, Mat *v)
3546d71ae5a4SJacob Faibussowitsch {
35475ea7661aSPierre Jolivet   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
35485ea7661aSPierre Jolivet 
35495ea7661aSPierre Jolivet   PetscFunctionBegin;
355028b400f6SJacob Faibussowitsch   PetscCheck(a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetSubMatrix() first");
355128b400f6SJacob Faibussowitsch   PetscCheck(a->cmat, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column matrix");
355208401ef6SPierre Jolivet   PetscCheck(*v == a->cmat, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not the matrix obtained from MatDenseGetSubMatrix()");
35535ea7661aSPierre Jolivet   a->matinuse = 0;
35549566063dSJacob Faibussowitsch   PetscCall(MatDenseResetArray(a->cmat));
3555742765d3SMatthew Knepley   if (v) *v = NULL;
355647d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
35573faff063SStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
35583faff063SStefano Zampini #endif
35593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
35605ea7661aSPierre Jolivet }
35615ea7661aSPierre Jolivet 
35620bad9183SKris Buschelman /*MC
3563fafad747SKris Buschelman    MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices.
35640bad9183SKris Buschelman 
35652ef1f0ffSBarry Smith    Options Database Key:
356611a5261eSBarry Smith . -mat_type seqdense - sets the matrix type to `MATSEQDENSE` during a call to `MatSetFromOptions()`
35670bad9183SKris Buschelman 
35680bad9183SKris Buschelman   Level: beginner
35690bad9183SKris Buschelman 
35701cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreateSeqDense()`
35710bad9183SKris Buschelman M*/
3572d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreate_SeqDense(Mat B)
3573d71ae5a4SJacob Faibussowitsch {
3574273d9f13SBarry Smith   Mat_SeqDense *b;
35757c334f02SBarry Smith   PetscMPIInt   size;
3576273d9f13SBarry Smith 
3577273d9f13SBarry Smith   PetscFunctionBegin;
35789566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)B), &size));
357908401ef6SPierre Jolivet   PetscCheck(size <= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Comm must be of size 1");
358055659b69SBarry Smith 
35814dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&b));
358244cd7ae7SLois Curfman McInnes   B->data   = (void *)b;
3583aea10558SJacob Faibussowitsch   B->ops[0] = MatOps_Values;
358418f449edSLois Curfman McInnes 
3585273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
35864e220ebcSLois Curfman McInnes 
35879566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatQRFactor_C", MatQRFactor_SeqDense));
35889566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetLDA_C", MatDenseGetLDA_SeqDense));
35899566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseSetLDA_C", MatDenseSetLDA_SeqDense));
35909566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArray_C", MatDenseGetArray_SeqDense));
35919566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArray_C", MatDenseRestoreArray_SeqDense));
35929566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDensePlaceArray_C", MatDensePlaceArray_SeqDense));
35939566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseResetArray_C", MatDenseResetArray_SeqDense));
35949566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseReplaceArray_C", MatDenseReplaceArray_SeqDense));
35959566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayRead_C", MatDenseGetArray_SeqDense));
35969566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayRead_C", MatDenseRestoreArray_SeqDense));
35979566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayWrite_C", MatDenseGetArray_SeqDense));
35989566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayWrite_C", MatDenseRestoreArray_SeqDense));
35999566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqaij_C", MatConvert_SeqDense_SeqAIJ));
36008baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
36019566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_elemental_C", MatConvert_SeqDense_Elemental));
36028baccfbdSHong Zhang #endif
3603d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
36049566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_scalapack_C", MatConvert_Dense_ScaLAPACK));
3605d24d4204SJose E. Roman #endif
36062bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
36079566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensecuda_C", MatConvert_SeqDense_SeqDenseCUDA));
36089566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", MatProductSetFromOptions_SeqDense));
36099566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdense_C", MatProductSetFromOptions_SeqDense));
36109566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensecuda_C", MatProductSetFromOptions_SeqDense));
36112bf066beSStefano Zampini #endif
361247d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP)
361347d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensehip_C", MatConvert_SeqDense_SeqDenseHIP));
361447d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensehip_seqdensehip_C", MatProductSetFromOptions_SeqDense));
361547d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensehip_seqdense_C", MatProductSetFromOptions_SeqDense));
361647d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensehip_C", MatProductSetFromOptions_SeqDense));
361747d993e7Ssuyashtn #endif
36189566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSeqDenseSetPreallocation_C", MatSeqDenseSetPreallocation_SeqDense));
36199566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqaij_seqdense_C", MatProductSetFromOptions_SeqAIJ_SeqDense));
36209566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdense_C", MatProductSetFromOptions_SeqDense));
36219566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense));
36229566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqsbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense));
362396e6d5c4SRichard Tran Mills 
36249566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumn_C", MatDenseGetColumn_SeqDense));
36259566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumn_C", MatDenseRestoreColumn_SeqDense));
36269566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVec_C", MatDenseGetColumnVec_SeqDense));
36279566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVec_C", MatDenseRestoreColumnVec_SeqDense));
36289566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecRead_C", MatDenseGetColumnVecRead_SeqDense));
36299566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecRead_C", MatDenseRestoreColumnVecRead_SeqDense));
36309566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecWrite_C", MatDenseGetColumnVecWrite_SeqDense));
36319566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecWrite_C", MatDenseRestoreColumnVecWrite_SeqDense));
36329566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetSubMatrix_C", MatDenseGetSubMatrix_SeqDense));
36339566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreSubMatrix_C", MatDenseRestoreSubMatrix_SeqDense));
36349566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)B, MATSEQDENSE));
36353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3636289bc588SBarry Smith }
363786aefd0dSHong Zhang 
363886aefd0dSHong Zhang /*@C
363911a5261eSBarry 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.
364086aefd0dSHong Zhang 
364186aefd0dSHong Zhang   Not Collective
364286aefd0dSHong Zhang 
36435ea7661aSPierre Jolivet   Input Parameters:
3644fe59aa6dSJacob Faibussowitsch + A   - a `MATSEQDENSE` or `MATMPIDENSE` matrix
364586aefd0dSHong Zhang - col - column index
364686aefd0dSHong Zhang 
364786aefd0dSHong Zhang   Output Parameter:
364886aefd0dSHong Zhang . vals - pointer to the data
364986aefd0dSHong Zhang 
365086aefd0dSHong Zhang   Level: intermediate
365186aefd0dSHong Zhang 
365211a5261eSBarry Smith   Note:
365311a5261eSBarry Smith   Use `MatDenseGetColumnVec()` to get access to a column of a `MATDENSE` treated as a `Vec`
365411a5261eSBarry Smith 
36551cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreColumn()`, `MatDenseGetColumnVec()`
365686aefd0dSHong Zhang @*/
3657d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumn(Mat A, PetscInt col, PetscScalar **vals)
3658d71ae5a4SJacob Faibussowitsch {
365986aefd0dSHong Zhang   PetscFunctionBegin;
3660d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
3661d5ea218eSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
36624f572ea9SToby Isaac   PetscAssertPointer(vals, 3);
3663cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumn_C", (Mat, PetscInt, PetscScalar **), (A, col, vals));
36643ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
366586aefd0dSHong Zhang }
366686aefd0dSHong Zhang 
366786aefd0dSHong Zhang /*@C
366811a5261eSBarry Smith   MatDenseRestoreColumn - returns access to a column of a `MATDENSE` matrix which is returned by `MatDenseGetColumn()`.
366986aefd0dSHong Zhang 
367086aefd0dSHong Zhang   Not Collective
367186aefd0dSHong Zhang 
3672742765d3SMatthew Knepley   Input Parameters:
3673fe59aa6dSJacob Faibussowitsch + A    - a `MATSEQDENSE` or `MATMPIDENSE` matrix
36742ef1f0ffSBarry Smith - vals - pointer to the data (may be `NULL`)
367586aefd0dSHong Zhang 
367686aefd0dSHong Zhang   Level: intermediate
367786aefd0dSHong Zhang 
36781cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetColumn()`
367986aefd0dSHong Zhang @*/
3680d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumn(Mat A, PetscScalar **vals)
3681d71ae5a4SJacob Faibussowitsch {
368286aefd0dSHong Zhang   PetscFunctionBegin;
3683d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
36844f572ea9SToby Isaac   PetscAssertPointer(vals, 2);
3685cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumn_C", (Mat, PetscScalar **), (A, vals));
36863ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
368786aefd0dSHong Zhang }
36886947451fSStefano Zampini 
36890f74d2c1SSatish Balay /*@
369011a5261eSBarry Smith   MatDenseGetColumnVec - Gives read-write access to a column of a `MATDENSE` matrix, represented as a `Vec`.
36916947451fSStefano Zampini 
36926947451fSStefano Zampini   Collective
36936947451fSStefano Zampini 
36945ea7661aSPierre Jolivet   Input Parameters:
3695fe59aa6dSJacob Faibussowitsch + A   - the `Mat` object
36966947451fSStefano Zampini - col - the column index
36976947451fSStefano Zampini 
36986947451fSStefano Zampini   Output Parameter:
36996947451fSStefano Zampini . v - the vector
37006947451fSStefano Zampini 
37012ef1f0ffSBarry Smith   Level: intermediate
37022ef1f0ffSBarry Smith 
37036947451fSStefano Zampini   Notes:
370411a5261eSBarry Smith   The vector is owned by PETSc. Users need to call `MatDenseRestoreColumnVec()` when the vector is no longer needed.
370511a5261eSBarry Smith 
370611a5261eSBarry Smith   Use `MatDenseGetColumnVecRead()` to obtain read-only access or `MatDenseGetColumnVecWrite()` for write-only access.
37076947451fSStefano Zampini 
37081cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`, `MatDenseGetColumn()`
37096947451fSStefano Zampini @*/
3710d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec(Mat A, PetscInt col, Vec *v)
3711d71ae5a4SJacob Faibussowitsch {
37126947451fSStefano Zampini   PetscFunctionBegin;
37136947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
37146947451fSStefano Zampini   PetscValidType(A, 1);
37156947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
37164f572ea9SToby Isaac   PetscAssertPointer(v, 3);
371728b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
37182cf15c64SPierre 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);
3719cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v));
37203ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
37216947451fSStefano Zampini }
37226947451fSStefano Zampini 
37230f74d2c1SSatish Balay /*@
37246947451fSStefano Zampini   MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVec().
37256947451fSStefano Zampini 
37266947451fSStefano Zampini   Collective
37276947451fSStefano Zampini 
37285ea7661aSPierre Jolivet   Input Parameters:
3729fe59aa6dSJacob Faibussowitsch + A   - the Mat object
37306947451fSStefano Zampini . col - the column index
37312ef1f0ffSBarry Smith - v   - the Vec object (may be `NULL`)
37326947451fSStefano Zampini 
37336947451fSStefano Zampini   Level: intermediate
37346947451fSStefano Zampini 
37351cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
37366947451fSStefano Zampini @*/
3737d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec(Mat A, PetscInt col, Vec *v)
3738d71ae5a4SJacob Faibussowitsch {
37396947451fSStefano Zampini   PetscFunctionBegin;
37406947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
37416947451fSStefano Zampini   PetscValidType(A, 1);
37426947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
374308401ef6SPierre Jolivet   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
37442cf15c64SPierre 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);
3745cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v));
37463ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
37476947451fSStefano Zampini }
37486947451fSStefano Zampini 
37490f74d2c1SSatish Balay /*@
37506947451fSStefano Zampini   MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a Vec.
37516947451fSStefano Zampini 
37526947451fSStefano Zampini   Collective
37536947451fSStefano Zampini 
37545ea7661aSPierre Jolivet   Input Parameters:
3755fe59aa6dSJacob Faibussowitsch + A   - the `Mat` object
37566947451fSStefano Zampini - col - the column index
37576947451fSStefano Zampini 
37586947451fSStefano Zampini   Output Parameter:
37596947451fSStefano Zampini . v - the vector
37606947451fSStefano Zampini 
37612ef1f0ffSBarry Smith   Level: intermediate
37622ef1f0ffSBarry Smith 
37636947451fSStefano Zampini   Notes:
37646947451fSStefano Zampini   The vector is owned by PETSc and users cannot modify it.
376511a5261eSBarry Smith 
37662ef1f0ffSBarry Smith   Users need to call `MatDenseRestoreColumnVecRead()` when the vector is no longer needed.
376711a5261eSBarry Smith 
37682ef1f0ffSBarry Smith   Use `MatDenseGetColumnVec()` to obtain read-write access or `MatDenseGetColumnVecWrite()` for write-only access.
37696947451fSStefano Zampini 
37701cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
37716947451fSStefano Zampini @*/
3772d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead(Mat A, PetscInt col, Vec *v)
3773d71ae5a4SJacob Faibussowitsch {
37746947451fSStefano Zampini   PetscFunctionBegin;
37756947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
37766947451fSStefano Zampini   PetscValidType(A, 1);
37776947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
37784f572ea9SToby Isaac   PetscAssertPointer(v, 3);
377928b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
37802cf15c64SPierre 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);
3781cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v));
37823ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
37836947451fSStefano Zampini }
37846947451fSStefano Zampini 
37850f74d2c1SSatish Balay /*@
37866947451fSStefano Zampini   MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecRead().
37876947451fSStefano Zampini 
37886947451fSStefano Zampini   Collective
37896947451fSStefano Zampini 
37905ea7661aSPierre Jolivet   Input Parameters:
3791fe59aa6dSJacob Faibussowitsch + A   - the `Mat` object
37926947451fSStefano Zampini . col - the column index
37932ef1f0ffSBarry Smith - v   - the Vec object (may be `NULL`)
37946947451fSStefano Zampini 
37956947451fSStefano Zampini   Level: intermediate
37966947451fSStefano Zampini 
37971cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecWrite()`
37986947451fSStefano Zampini @*/
3799d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead(Mat A, PetscInt col, Vec *v)
3800d71ae5a4SJacob Faibussowitsch {
38016947451fSStefano Zampini   PetscFunctionBegin;
38026947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
38036947451fSStefano Zampini   PetscValidType(A, 1);
38046947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
380508401ef6SPierre Jolivet   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
38062cf15c64SPierre 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);
3807cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v));
38083ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
38096947451fSStefano Zampini }
38106947451fSStefano Zampini 
38110f74d2c1SSatish Balay /*@
38126947451fSStefano Zampini   MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a Vec.
38136947451fSStefano Zampini 
38146947451fSStefano Zampini   Collective
38156947451fSStefano Zampini 
38165ea7661aSPierre Jolivet   Input Parameters:
3817fe59aa6dSJacob Faibussowitsch + A   - the `Mat` object
38186947451fSStefano Zampini - col - the column index
38196947451fSStefano Zampini 
38206947451fSStefano Zampini   Output Parameter:
38216947451fSStefano Zampini . v - the vector
38226947451fSStefano Zampini 
38236947451fSStefano Zampini   Level: intermediate
38246947451fSStefano Zampini 
38252ef1f0ffSBarry Smith   Notes:
38262ef1f0ffSBarry Smith   The vector is owned by PETSc. Users need to call `MatDenseRestoreColumnVecWrite()` when the vector is no longer needed.
38272ef1f0ffSBarry Smith 
38282ef1f0ffSBarry Smith   Use `MatDenseGetColumnVec()` to obtain read-write access or `MatDenseGetColumnVecRead()` for read-only access.
38292ef1f0ffSBarry Smith 
38301cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
38316947451fSStefano Zampini @*/
3832d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite(Mat A, PetscInt col, Vec *v)
3833d71ae5a4SJacob Faibussowitsch {
38346947451fSStefano Zampini   PetscFunctionBegin;
38356947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
38366947451fSStefano Zampini   PetscValidType(A, 1);
38376947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
38384f572ea9SToby Isaac   PetscAssertPointer(v, 3);
383928b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
3840aed4548fSBarry 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);
3841cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v));
38423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
38436947451fSStefano Zampini }
38446947451fSStefano Zampini 
38450f74d2c1SSatish Balay /*@
38466947451fSStefano Zampini   MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecWrite().
38476947451fSStefano Zampini 
38486947451fSStefano Zampini   Collective
38496947451fSStefano Zampini 
38505ea7661aSPierre Jolivet   Input Parameters:
3851fe59aa6dSJacob Faibussowitsch + A   - the `Mat` object
38526947451fSStefano Zampini . col - the column index
38532ef1f0ffSBarry Smith - v   - the `Vec` object (may be `NULL`)
38546947451fSStefano Zampini 
38556947451fSStefano Zampini   Level: intermediate
38566947451fSStefano Zampini 
38571cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`
38586947451fSStefano Zampini @*/
3859d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A, PetscInt col, Vec *v)
3860d71ae5a4SJacob Faibussowitsch {
38616947451fSStefano Zampini   PetscFunctionBegin;
38626947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
38636947451fSStefano Zampini   PetscValidType(A, 1);
38646947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
386508401ef6SPierre Jolivet   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
3866aed4548fSBarry 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);
3867cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v));
38683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
38696947451fSStefano Zampini }
38705ea7661aSPierre Jolivet 
38710f74d2c1SSatish Balay /*@
3872a2748737SPierre Jolivet   MatDenseGetSubMatrix - Gives access to a block of rows and columns of a dense matrix, represented as a Mat.
38735ea7661aSPierre Jolivet 
38745ea7661aSPierre Jolivet   Collective
38755ea7661aSPierre Jolivet 
38765ea7661aSPierre Jolivet   Input Parameters:
3877fe59aa6dSJacob Faibussowitsch + A      - the Mat object
38782ef1f0ffSBarry Smith . rbegin - the first global row index in the block (if `PETSC_DECIDE`, is 0)
38792ef1f0ffSBarry Smith . rend   - the global row index past the last one in the block (if `PETSC_DECIDE`, is `M`)
38802ef1f0ffSBarry Smith . cbegin - the first global column index in the block (if `PETSC_DECIDE`, is 0)
38812ef1f0ffSBarry Smith - cend   - the global column index past the last one in the block (if `PETSC_DECIDE`, is `N`)
38825ea7661aSPierre Jolivet 
38835ea7661aSPierre Jolivet   Output Parameter:
38845ea7661aSPierre Jolivet . v - the matrix
38855ea7661aSPierre Jolivet 
38865ea7661aSPierre Jolivet   Level: intermediate
38875ea7661aSPierre Jolivet 
38882ef1f0ffSBarry Smith   Notes:
38892ef1f0ffSBarry Smith   The matrix is owned by PETSc. Users need to call `MatDenseRestoreSubMatrix()` when the matrix is no longer needed.
38902ef1f0ffSBarry Smith 
38912ef1f0ffSBarry Smith   The output matrix is not redistributed by PETSc, so depending on the values of `rbegin` and `rend`, some processes may have no local rows.
38922ef1f0ffSBarry Smith 
38931cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreSubMatrix()`
38945ea7661aSPierre Jolivet @*/
3895d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v)
3896d71ae5a4SJacob Faibussowitsch {
38975ea7661aSPierre Jolivet   PetscFunctionBegin;
38985ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
38995ea7661aSPierre Jolivet   PetscValidType(A, 1);
3900a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, rbegin, 2);
3901a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, rend, 3);
3902a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, cbegin, 4);
3903a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, cend, 5);
39044f572ea9SToby Isaac   PetscAssertPointer(v, 6);
3905a2748737SPierre Jolivet   if (rbegin == PETSC_DECIDE) rbegin = 0;
3906a2748737SPierre Jolivet   if (rend == PETSC_DECIDE) rend = A->rmap->N;
3907a2748737SPierre Jolivet   if (cbegin == PETSC_DECIDE) cbegin = 0;
3908a2748737SPierre Jolivet   if (cend == PETSC_DECIDE) cend = A->cmap->N;
390928b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
3910a2748737SPierre 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);
3911a2748737SPierre 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);
3912a2748737SPierre 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);
3913a2748737SPierre 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);
3914a2748737SPierre Jolivet   PetscUseMethod(A, "MatDenseGetSubMatrix_C", (Mat, PetscInt, PetscInt, PetscInt, PetscInt, Mat *), (A, rbegin, rend, cbegin, cend, v));
39153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
39165ea7661aSPierre Jolivet }
39175ea7661aSPierre Jolivet 
39180f74d2c1SSatish Balay /*@
39195ea7661aSPierre Jolivet   MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from MatDenseGetSubMatrix().
39205ea7661aSPierre Jolivet 
39215ea7661aSPierre Jolivet   Collective
39225ea7661aSPierre Jolivet 
39235ea7661aSPierre Jolivet   Input Parameters:
3924fe59aa6dSJacob Faibussowitsch + A - the `Mat` object
39252ef1f0ffSBarry Smith - v - the `Mat` object (may be `NULL`)
39265ea7661aSPierre Jolivet 
39275ea7661aSPierre Jolivet   Level: intermediate
39285ea7661aSPierre Jolivet 
39291cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseGetSubMatrix()`
39305ea7661aSPierre Jolivet @*/
3931d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix(Mat A, Mat *v)
3932d71ae5a4SJacob Faibussowitsch {
39335ea7661aSPierre Jolivet   PetscFunctionBegin;
39345ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
39355ea7661aSPierre Jolivet   PetscValidType(A, 1);
39364f572ea9SToby Isaac   PetscAssertPointer(v, 2);
3937cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreSubMatrix_C", (Mat, Mat *), (A, v));
39383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
39395ea7661aSPierre Jolivet }
39408a9c020eSBarry Smith 
39418a9c020eSBarry Smith #include <petscblaslapack.h>
39428a9c020eSBarry Smith #include <petsc/private/kernels/blockinvert.h>
39438a9c020eSBarry Smith 
3944d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseInvert(Mat A)
3945d71ae5a4SJacob Faibussowitsch {
3946d63b1753SJacob Faibussowitsch   PetscInt        m;
39478a9c020eSBarry Smith   const PetscReal shift = 0.0;
3948d63b1753SJacob Faibussowitsch   PetscBool       allowzeropivot, zeropivotdetected = PETSC_FALSE;
3949d63b1753SJacob Faibussowitsch   PetscScalar    *values;
39508a9c020eSBarry Smith 
39518a9c020eSBarry Smith   PetscFunctionBegin;
3952d63b1753SJacob Faibussowitsch   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
3953d63b1753SJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &values));
3954d63b1753SJacob Faibussowitsch   PetscCall(MatGetLocalSize(A, &m, NULL));
3955d63b1753SJacob Faibussowitsch   allowzeropivot = PetscNot(A->erroriffailure);
39568a9c020eSBarry Smith   /* factor and invert each block */
3957d63b1753SJacob Faibussowitsch   switch (m) {
3958d71ae5a4SJacob Faibussowitsch   case 1:
3959d71ae5a4SJacob Faibussowitsch     values[0] = (PetscScalar)1.0 / (values[0] + shift);
3960d71ae5a4SJacob Faibussowitsch     break;
39618a9c020eSBarry Smith   case 2:
39628a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_2(values, shift, allowzeropivot, &zeropivotdetected));
39638a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
39648a9c020eSBarry Smith     break;
39658a9c020eSBarry Smith   case 3:
39668a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_3(values, shift, allowzeropivot, &zeropivotdetected));
39678a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
39688a9c020eSBarry Smith     break;
39698a9c020eSBarry Smith   case 4:
39708a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_4(values, shift, allowzeropivot, &zeropivotdetected));
39718a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
39728a9c020eSBarry Smith     break;
39739371c9d4SSatish Balay   case 5: {
39748a9c020eSBarry Smith     PetscScalar work[25];
39758a9c020eSBarry Smith     PetscInt    ipvt[5];
39768a9c020eSBarry Smith 
39778a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_5(values, ipvt, work, shift, allowzeropivot, &zeropivotdetected));
39788a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
39799371c9d4SSatish Balay   } break;
39808a9c020eSBarry Smith   case 6:
39818a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_6(values, shift, allowzeropivot, &zeropivotdetected));
39828a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
39838a9c020eSBarry Smith     break;
39848a9c020eSBarry Smith   case 7:
39858a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_7(values, shift, allowzeropivot, &zeropivotdetected));
39868a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
39878a9c020eSBarry Smith     break;
39889371c9d4SSatish Balay   default: {
39898a9c020eSBarry Smith     PetscInt    *v_pivots, *IJ, j;
39908a9c020eSBarry Smith     PetscScalar *v_work;
39918a9c020eSBarry Smith 
3992d63b1753SJacob Faibussowitsch     PetscCall(PetscMalloc3(m, &v_work, m, &v_pivots, m, &IJ));
3993d63b1753SJacob Faibussowitsch     for (j = 0; j < m; j++) IJ[j] = j;
3994d63b1753SJacob Faibussowitsch     PetscCall(PetscKernel_A_gets_inverse_A(m, values, v_pivots, v_work, allowzeropivot, &zeropivotdetected));
39958a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
39968a9c020eSBarry Smith     PetscCall(PetscFree3(v_work, v_pivots, IJ));
39978a9c020eSBarry Smith   }
39988a9c020eSBarry Smith   }
3999d63b1753SJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &values));
40003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
40018a9c020eSBarry Smith }
4002