xref: /petsc/src/mat/impls/dense/seq/dense.c (revision 27f169480a6668db3ba90f8ef6ef68d542d113fa)
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>
114186a4bbSPierre Jolivet #include <petsc/private/vecimpl.h>
12b2573a8aSBarry Smith 
MatSeqDenseSymmetrize_Private(Mat A,PetscBool hermitian)13d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSymmetrize_Private(Mat A, PetscBool hermitian)
14d71ae5a4SJacob Faibussowitsch {
158c178816SStefano Zampini   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
168c178816SStefano Zampini   PetscInt      j, k, n = A->rmap->n;
17ca15aa20SStefano Zampini   PetscScalar  *v;
188c178816SStefano Zampini 
198c178816SStefano Zampini   PetscFunctionBegin;
2008401ef6SPierre Jolivet   PetscCheck(A->rmap->n == A->cmap->n, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Cannot symmetrize a rectangular matrix");
219566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
228c178816SStefano Zampini   if (!hermitian) {
238c178816SStefano Zampini     for (k = 0; k < n; k++) {
24ad540459SPierre Jolivet       for (j = k; j < n; j++) v[j * mat->lda + k] = v[k * mat->lda + j];
258c178816SStefano Zampini     }
268c178816SStefano Zampini   } else {
278c178816SStefano Zampini     for (k = 0; k < n; k++) {
28ad540459SPierre Jolivet       for (j = k; j < n; j++) v[j * mat->lda + k] = PetscConj(v[k * mat->lda + j]);
298c178816SStefano Zampini     }
308c178816SStefano Zampini   }
319566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
323ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
338c178816SStefano Zampini }
348c178816SStefano Zampini 
MatSeqDenseInvertFactors_Private(Mat A)35ff6a9541SJacob Faibussowitsch PetscErrorCode MatSeqDenseInvertFactors_Private(Mat A)
36d71ae5a4SJacob Faibussowitsch {
378c178816SStefano Zampini   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
388c178816SStefano Zampini   PetscBLASInt  info, n;
398c178816SStefano Zampini 
408c178816SStefano Zampini   PetscFunctionBegin;
413ba16761SJacob Faibussowitsch   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS);
429566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
438c178816SStefano Zampini   if (A->factortype == MAT_FACTOR_LU) {
4428b400f6SJacob Faibussowitsch     PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present");
458c178816SStefano Zampini     if (!mat->fwork) {
468c178816SStefano Zampini       mat->lfwork = n;
479566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
488c178816SStefano Zampini     }
499566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
50792fecdfSBarry Smith     PetscCallBLAS("LAPACKgetri", LAPACKgetri_(&n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info));
519566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
529566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0));
538c178816SStefano Zampini   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
54b94d7dedSBarry Smith     if (A->spd == PETSC_BOOL3_TRUE) {
559566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
56792fecdfSBarry Smith       PetscCallBLAS("LAPACKpotri", LAPACKpotri_("L", &n, mat->v, &mat->lda, &info));
579566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
589566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_TRUE));
598c178816SStefano Zampini #if defined(PETSC_USE_COMPLEX)
60b94d7dedSBarry Smith     } else if (A->hermitian == PETSC_BOOL3_TRUE) {
6128b400f6SJacob Faibussowitsch       PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present");
6228b400f6SJacob Faibussowitsch       PetscCheck(mat->fwork, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Fwork not present");
639566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
64792fecdfSBarry Smith       PetscCallBLAS("LAPACKhetri", LAPACKhetri_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &info));
659566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
669566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_TRUE));
678c178816SStefano Zampini #endif
688c178816SStefano Zampini     } else { /* symmetric case */
6928b400f6SJacob Faibussowitsch       PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present");
7028b400f6SJacob Faibussowitsch       PetscCheck(mat->fwork, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Fwork not present");
719566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
72792fecdfSBarry Smith       PetscCallBLAS("LAPACKsytri", LAPACKsytri_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &info));
739566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
749566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_FALSE));
758c178816SStefano Zampini     }
76835f2295SStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad Inversion: zero pivot in row %" PetscBLASInt_FMT, info - 1);
779566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0));
788c178816SStefano Zampini   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Matrix must be factored to solve");
798c178816SStefano Zampini 
808c178816SStefano Zampini   A->ops->solve             = NULL;
818c178816SStefano Zampini   A->ops->matsolve          = NULL;
828c178816SStefano Zampini   A->ops->solvetranspose    = NULL;
838c178816SStefano Zampini   A->ops->matsolvetranspose = NULL;
848c178816SStefano Zampini   A->ops->solveadd          = NULL;
858c178816SStefano Zampini   A->ops->solvetransposeadd = NULL;
868c178816SStefano Zampini   A->factortype             = MAT_FACTOR_NONE;
879566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
898c178816SStefano Zampini }
908c178816SStefano Zampini 
MatZeroRowsColumns_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)9166976f2fSJacob Faibussowitsch static PetscErrorCode MatZeroRowsColumns_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b)
92d71ae5a4SJacob Faibussowitsch {
933f49a652SStefano Zampini   Mat_SeqDense      *l = (Mat_SeqDense *)A->data;
943f49a652SStefano Zampini   PetscInt           m = l->lda, n = A->cmap->n, r = A->rmap->n, i, j;
95ca15aa20SStefano Zampini   PetscScalar       *slot, *bb, *v;
963f49a652SStefano Zampini   const PetscScalar *xx;
973f49a652SStefano Zampini 
983f49a652SStefano Zampini   PetscFunctionBegin;
9976bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
1003f49a652SStefano Zampini     for (i = 0; i < N; i++) {
10108401ef6SPierre Jolivet       PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed");
10208401ef6SPierre 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);
10308401ef6SPierre 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);
1043f49a652SStefano Zampini     }
10576bd3646SJed Brown   }
1063ba16761SJacob Faibussowitsch   if (!N) PetscFunctionReturn(PETSC_SUCCESS);
1073f49a652SStefano Zampini 
108dd8e379bSPierre Jolivet   /* fix right-hand side if needed */
1093f49a652SStefano Zampini   if (x && b) {
1106c4d906cSStefano Zampini     Vec xt;
1116c4d906cSStefano Zampini 
11208401ef6SPierre Jolivet     PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices");
1139566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(x, &xt));
1149566063dSJacob Faibussowitsch     PetscCall(VecCopy(x, xt));
1159566063dSJacob Faibussowitsch     PetscCall(VecScale(xt, -1.0));
1169566063dSJacob Faibussowitsch     PetscCall(MatMultAdd(A, xt, b, b));
1179566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&xt));
1189566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(x, &xx));
1199566063dSJacob Faibussowitsch     PetscCall(VecGetArray(b, &bb));
1203f49a652SStefano Zampini     for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]];
1219566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(x, &xx));
1229566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(b, &bb));
1233f49a652SStefano Zampini   }
1243f49a652SStefano Zampini 
1259566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
1263f49a652SStefano Zampini   for (i = 0; i < N; i++) {
127ca15aa20SStefano Zampini     slot = v + rows[i] * m;
1289566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(slot, r));
1293f49a652SStefano Zampini   }
1303f49a652SStefano Zampini   for (i = 0; i < N; i++) {
131ca15aa20SStefano Zampini     slot = v + rows[i];
1329371c9d4SSatish Balay     for (j = 0; j < n; j++) {
1339371c9d4SSatish Balay       *slot = 0.0;
1349371c9d4SSatish Balay       slot += m;
1359371c9d4SSatish Balay     }
1363f49a652SStefano Zampini   }
1373f49a652SStefano Zampini   if (diag != 0.0) {
13808401ef6SPierre Jolivet     PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices");
1393f49a652SStefano Zampini     for (i = 0; i < N; i++) {
140ca15aa20SStefano Zampini       slot  = v + (m + 1) * rows[i];
1413f49a652SStefano Zampini       *slot = diag;
1423f49a652SStefano Zampini     }
1433f49a652SStefano Zampini   }
1449566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
1453ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1463f49a652SStefano Zampini }
1473f49a652SStefano Zampini 
MatConvert_SeqAIJ_SeqDense(Mat A,MatType newtype,MatReuse reuse,Mat * newmat)148d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat A, MatType newtype, MatReuse reuse, Mat *newmat)
149d71ae5a4SJacob Faibussowitsch {
150a13144ffSStefano Zampini   Mat              B = NULL;
151b49cda9fSStefano Zampini   Mat_SeqAIJ      *a = (Mat_SeqAIJ *)A->data;
152b49cda9fSStefano Zampini   Mat_SeqDense    *b;
153b49cda9fSStefano Zampini   PetscInt        *ai = a->i, *aj = a->j, m = A->rmap->N, n = A->cmap->N, i;
1542e5835c6SStefano Zampini   const MatScalar *av;
155a13144ffSStefano Zampini   PetscBool        isseqdense;
156b49cda9fSStefano Zampini 
157b49cda9fSStefano Zampini   PetscFunctionBegin;
158a13144ffSStefano Zampini   if (reuse == MAT_REUSE_MATRIX) {
1599566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)*newmat, MATSEQDENSE, &isseqdense));
160f4f49eeaSPierre Jolivet     PetscCheck(isseqdense, PetscObjectComm((PetscObject)*newmat), PETSC_ERR_USER, "Cannot reuse matrix of type %s", ((PetscObject)*newmat)->type_name);
161a13144ffSStefano Zampini   }
162a13144ffSStefano Zampini   if (reuse != MAT_REUSE_MATRIX) {
1639566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B));
1649566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(B, m, n, m, n));
1659566063dSJacob Faibussowitsch     PetscCall(MatSetType(B, MATSEQDENSE));
1669566063dSJacob Faibussowitsch     PetscCall(MatSeqDenseSetPreallocation(B, NULL));
167f4f49eeaSPierre Jolivet     b = (Mat_SeqDense *)B->data;
168a13144ffSStefano Zampini   } else {
169a13144ffSStefano Zampini     b = (Mat_SeqDense *)((*newmat)->data);
170e1ea5af7SJose E. Roman     for (i = 0; i < n; i++) PetscCall(PetscArrayzero(b->v + i * b->lda, m));
171a13144ffSStefano Zampini   }
1729566063dSJacob Faibussowitsch   PetscCall(MatSeqAIJGetArrayRead(A, &av));
173b49cda9fSStefano Zampini   for (i = 0; i < m; i++) {
174b49cda9fSStefano Zampini     PetscInt j;
175b49cda9fSStefano Zampini     for (j = 0; j < ai[1] - ai[0]; j++) {
176e1ea5af7SJose E. Roman       b->v[*aj * b->lda + i] = *av;
177b49cda9fSStefano Zampini       aj++;
178b49cda9fSStefano Zampini       av++;
179b49cda9fSStefano Zampini     }
180b49cda9fSStefano Zampini     ai++;
181b49cda9fSStefano Zampini   }
1829566063dSJacob Faibussowitsch   PetscCall(MatSeqAIJRestoreArrayRead(A, &av));
183b49cda9fSStefano Zampini 
184511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
1859566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY));
1869566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY));
1879566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A, &B));
188b49cda9fSStefano Zampini   } else {
189a13144ffSStefano Zampini     if (B) *newmat = B;
1909566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(*newmat, MAT_FINAL_ASSEMBLY));
1919566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(*newmat, MAT_FINAL_ASSEMBLY));
192b49cda9fSStefano Zampini   }
1933ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
194b49cda9fSStefano Zampini }
195b49cda9fSStefano Zampini 
MatConvert_SeqDense_SeqAIJ(Mat A,MatType newtype,MatReuse reuse,Mat * newmat)196d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqDense_SeqAIJ(Mat A, MatType newtype, MatReuse reuse, Mat *newmat)
197d71ae5a4SJacob Faibussowitsch {
1986d4ec7b0SPierre Jolivet   Mat           B = NULL;
1996a63e612SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
2009399e1b8SMatthew G. Knepley   PetscInt      i, j;
2019399e1b8SMatthew G. Knepley   PetscInt     *rows, *nnz;
2029399e1b8SMatthew G. Knepley   MatScalar    *aa = a->v, *vals;
2036a63e612SBarry Smith 
2046a63e612SBarry Smith   PetscFunctionBegin;
2059566063dSJacob Faibussowitsch   PetscCall(PetscCalloc3(A->rmap->n, &rows, A->rmap->n, &nnz, A->rmap->n, &vals));
2066d4ec7b0SPierre Jolivet   if (reuse != MAT_REUSE_MATRIX) {
2079566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B));
2089566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(B, A->rmap->n, A->cmap->n, A->rmap->N, A->cmap->N));
2099566063dSJacob Faibussowitsch     PetscCall(MatSetType(B, MATSEQAIJ));
2109399e1b8SMatthew G. Knepley     for (j = 0; j < A->cmap->n; j++) {
2119371c9d4SSatish Balay       for (i = 0; i < A->rmap->n; i++)
2129371c9d4SSatish Balay         if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) ++nnz[i];
2136a63e612SBarry Smith       aa += a->lda;
2146a63e612SBarry Smith     }
2159566063dSJacob Faibussowitsch     PetscCall(MatSeqAIJSetPreallocation(B, PETSC_DETERMINE, nnz));
2166d4ec7b0SPierre Jolivet   } else B = *newmat;
2179399e1b8SMatthew G. Knepley   aa = a->v;
2189399e1b8SMatthew G. Knepley   for (j = 0; j < A->cmap->n; j++) {
2199399e1b8SMatthew G. Knepley     PetscInt numRows = 0;
2209371c9d4SSatish Balay     for (i = 0; i < A->rmap->n; i++)
2219371c9d4SSatish Balay       if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) {
2229371c9d4SSatish Balay         rows[numRows]   = i;
2239371c9d4SSatish Balay         vals[numRows++] = aa[i];
2249371c9d4SSatish Balay       }
2259566063dSJacob Faibussowitsch     PetscCall(MatSetValues(B, numRows, rows, 1, &j, vals, INSERT_VALUES));
2269399e1b8SMatthew G. Knepley     aa += a->lda;
2279399e1b8SMatthew G. Knepley   }
2289566063dSJacob Faibussowitsch   PetscCall(PetscFree3(rows, nnz, vals));
2299566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY));
2309566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY));
2316a63e612SBarry Smith 
232ac530a7eSPierre Jolivet   if (reuse == MAT_INPLACE_MATRIX) PetscCall(MatHeaderReplace(A, &B));
233ac530a7eSPierre Jolivet   else if (reuse != MAT_REUSE_MATRIX) *newmat = B;
2343ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2356a63e612SBarry Smith }
2366a63e612SBarry Smith 
MatAXPY_SeqDense(Mat Y,PetscScalar alpha,Mat X,MatStructure str)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) {
2528e3a54c0SPierre Jolivet     for (PetscInt j = 0; j < X->cmap->n; j++) PetscCallBLAS("BLASaxpy", BLASaxpy_(&m, &alpha, PetscSafePointerPlusOffset(xv, j * ldax), &one, PetscSafePointerPlusOffset(yv, j * lday), &one));
253a5ce6ee0Svictorle   } else {
254792fecdfSBarry Smith     PetscCallBLAS("BLASaxpy", BLASaxpy_(&N, &alpha, xv, &one, yv, &one));
255a5ce6ee0Svictorle   }
2569566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(X, &xv));
2579566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(Y, &yv));
2589566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(PetscMax(2.0 * N - 1, 0)));
2593ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2601987afe7SBarry Smith }
2611987afe7SBarry Smith 
MatGetInfo_SeqDense(Mat A,MatInfoType flag,MatInfo * info)262d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetInfo_SeqDense(Mat A, MatInfoType flag, MatInfo *info)
263d71ae5a4SJacob Faibussowitsch {
264ca15aa20SStefano Zampini   PetscLogDouble N = A->rmap->n * A->cmap->n;
2653a40ed3dSBarry Smith 
2663a40ed3dSBarry Smith   PetscFunctionBegin;
2674e220ebcSLois Curfman McInnes   info->block_size        = 1.0;
268ca15aa20SStefano Zampini   info->nz_allocated      = N;
269ca15aa20SStefano Zampini   info->nz_used           = N;
270ca15aa20SStefano Zampini   info->nz_unneeded       = 0;
271ca15aa20SStefano Zampini   info->assemblies        = A->num_ass;
2724e220ebcSLois Curfman McInnes   info->mallocs           = 0;
2734dfa11a4SJacob Faibussowitsch   info->memory            = 0; /* REVIEW ME */
2744e220ebcSLois Curfman McInnes   info->fill_ratio_given  = 0;
2754e220ebcSLois Curfman McInnes   info->fill_ratio_needed = 0;
2764e220ebcSLois Curfman McInnes   info->factor_mallocs    = 0;
2773ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
278289bc588SBarry Smith }
279289bc588SBarry Smith 
MatScale_SeqDense(Mat A,PetscScalar alpha)280d71ae5a4SJacob Faibussowitsch PetscErrorCode MatScale_SeqDense(Mat A, PetscScalar alpha)
281d71ae5a4SJacob Faibussowitsch {
282273d9f13SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
283ca15aa20SStefano Zampini   PetscScalar  *v;
28423fff9afSBarry Smith   PetscBLASInt  one = 1, j, nz, lda = 0;
28580cd9d93SLois Curfman McInnes 
2863a40ed3dSBarry Smith   PetscFunctionBegin;
2879566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
2889566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(a->lda, &lda));
289d0f46423SBarry Smith   if (lda > A->rmap->n) {
2909566063dSJacob Faibussowitsch     PetscCall(PetscBLASIntCast(A->rmap->n, &nz));
29148a46eb9SPierre Jolivet     for (j = 0; j < A->cmap->n; j++) PetscCallBLAS("BLASscal", BLASscal_(&nz, &alpha, v + j * lda, &one));
292a5ce6ee0Svictorle   } else {
2939566063dSJacob Faibussowitsch     PetscCall(PetscBLASIntCast(A->rmap->n * A->cmap->n, &nz));
294792fecdfSBarry Smith     PetscCallBLAS("BLASscal", BLASscal_(&nz, &alpha, v, &one));
295a5ce6ee0Svictorle   }
29604cbc005SJose E. Roman   PetscCall(PetscLogFlops(A->rmap->n * A->cmap->n));
2979566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
2983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29980cd9d93SLois Curfman McInnes }
30080cd9d93SLois Curfman McInnes 
MatShift_SeqDense(Mat A,PetscScalar alpha)301d71ae5a4SJacob Faibussowitsch PetscErrorCode MatShift_SeqDense(Mat A, PetscScalar alpha)
302d71ae5a4SJacob Faibussowitsch {
3032f605a99SJose E. Roman   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
3042f605a99SJose E. Roman   PetscScalar  *v;
3052f605a99SJose E. Roman   PetscInt      j, k;
3062f605a99SJose E. Roman 
3072f605a99SJose E. Roman   PetscFunctionBegin;
3082f605a99SJose E. Roman   PetscCall(MatDenseGetArray(A, &v));
3092f605a99SJose E. Roman   k = PetscMin(A->rmap->n, A->cmap->n);
3102f605a99SJose E. Roman   for (j = 0; j < k; j++) v[j + j * a->lda] += alpha;
3112f605a99SJose E. Roman   PetscCall(PetscLogFlops(k));
3122f605a99SJose E. Roman   PetscCall(MatDenseRestoreArray(A, &v));
3133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3142f605a99SJose E. Roman }
3152f605a99SJose E. Roman 
MatIsHermitian_SeqDense(Mat A,PetscReal rtol,PetscBool * fl)316d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatIsHermitian_SeqDense(Mat A, PetscReal rtol, PetscBool *fl)
317d71ae5a4SJacob Faibussowitsch {
3181cbb95d3SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
319ca15aa20SStefano Zampini   PetscInt           i, j, m = A->rmap->n, N = a->lda;
320ca15aa20SStefano Zampini   const PetscScalar *v;
3211cbb95d3SBarry Smith 
3221cbb95d3SBarry Smith   PetscFunctionBegin;
3231cbb95d3SBarry Smith   *fl = PETSC_FALSE;
3243ba16761SJacob Faibussowitsch   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS);
3259566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &v));
3261cbb95d3SBarry Smith   for (i = 0; i < m; i++) {
327ca15aa20SStefano Zampini     for (j = i; j < m; j++) {
328ad540459SPierre Jolivet       if (PetscAbsScalar(v[i + j * N] - PetscConj(v[j + i * N])) > rtol) goto restore;
3291cbb95d3SBarry Smith     }
330637a0070SStefano Zampini   }
3311cbb95d3SBarry Smith   *fl = PETSC_TRUE;
332637a0070SStefano Zampini restore:
3339566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &v));
3343ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
335637a0070SStefano Zampini }
336637a0070SStefano Zampini 
MatIsSymmetric_SeqDense(Mat A,PetscReal rtol,PetscBool * fl)337d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatIsSymmetric_SeqDense(Mat A, PetscReal rtol, PetscBool *fl)
338d71ae5a4SJacob Faibussowitsch {
339637a0070SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
340637a0070SStefano Zampini   PetscInt           i, j, m = A->rmap->n, N = a->lda;
341637a0070SStefano Zampini   const PetscScalar *v;
342637a0070SStefano Zampini 
343637a0070SStefano Zampini   PetscFunctionBegin;
344637a0070SStefano Zampini   *fl = PETSC_FALSE;
3453ba16761SJacob Faibussowitsch   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS);
3469566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &v));
347637a0070SStefano Zampini   for (i = 0; i < m; i++) {
348637a0070SStefano Zampini     for (j = i; j < m; j++) {
349ad540459SPierre Jolivet       if (PetscAbsScalar(v[i + j * N] - v[j + i * N]) > rtol) goto restore;
350637a0070SStefano Zampini     }
351637a0070SStefano Zampini   }
352637a0070SStefano Zampini   *fl = PETSC_TRUE;
353637a0070SStefano Zampini restore:
3549566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &v));
3553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3561cbb95d3SBarry Smith }
3571cbb95d3SBarry Smith 
MatDuplicateNoCreate_SeqDense(Mat newi,Mat A,MatDuplicateOption cpvalues)358d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi, Mat A, MatDuplicateOption cpvalues)
359d71ae5a4SJacob Faibussowitsch {
360ca15aa20SStefano Zampini   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
361835f2295SStefano Zampini   PetscInt      lda = mat->lda, j, m, nlda = lda;
36275f6d85dSStefano Zampini   PetscBool     isdensecpu;
363b24902e0SBarry Smith 
364b24902e0SBarry Smith   PetscFunctionBegin;
3659566063dSJacob Faibussowitsch   PetscCall(PetscLayoutReference(A->rmap, &newi->rmap));
3669566063dSJacob Faibussowitsch   PetscCall(PetscLayoutReference(A->cmap, &newi->cmap));
36723fc5dcaSStefano Zampini   if (cpvalues == MAT_SHARE_NONZERO_PATTERN) { /* propagate LDA */
3689566063dSJacob Faibussowitsch     PetscCall(MatDenseSetLDA(newi, lda));
36923fc5dcaSStefano Zampini   }
3709566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)newi, MATSEQDENSE, &isdensecpu));
3719566063dSJacob Faibussowitsch   if (isdensecpu) PetscCall(MatSeqDenseSetPreallocation(newi, NULL));
372b24902e0SBarry Smith   if (cpvalues == MAT_COPY_VALUES) {
373ca15aa20SStefano Zampini     const PetscScalar *av;
374ca15aa20SStefano Zampini     PetscScalar       *v;
375ca15aa20SStefano Zampini 
3769566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A, &av));
3779566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayWrite(newi, &v));
3789566063dSJacob Faibussowitsch     PetscCall(MatDenseGetLDA(newi, &nlda));
379d0f46423SBarry Smith     m = A->rmap->n;
38023fc5dcaSStefano Zampini     if (lda > m || nlda > m) {
3818e3a54c0SPierre Jolivet       for (j = 0; j < A->cmap->n; j++) PetscCall(PetscArraycpy(PetscSafePointerPlusOffset(v, j * nlda), PetscSafePointerPlusOffset(av, j * lda), m));
382b24902e0SBarry Smith     } else {
3839566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(v, av, A->rmap->n * A->cmap->n));
384b24902e0SBarry Smith     }
3859566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayWrite(newi, &v));
3869566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A, &av));
387c956ced0SPierre Jolivet     PetscCall(MatPropagateSymmetryOptions(A, newi));
388b24902e0SBarry Smith   }
3893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
390b24902e0SBarry Smith }
391b24902e0SBarry Smith 
MatDuplicate_SeqDense(Mat A,MatDuplicateOption cpvalues,Mat * newmat)392d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDuplicate_SeqDense(Mat A, MatDuplicateOption cpvalues, Mat *newmat)
393d71ae5a4SJacob Faibussowitsch {
3943a40ed3dSBarry Smith   PetscFunctionBegin;
3959566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), newmat));
3969566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*newmat, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n));
3979566063dSJacob Faibussowitsch   PetscCall(MatSetType(*newmat, ((PetscObject)A)->type_name));
3989566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(*newmat, A, cpvalues));
3993ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
400b24902e0SBarry Smith }
401b24902e0SBarry Smith 
MatSolve_SeqDense_Internal_LU(Mat A,PetscScalar * x,PetscBLASInt ldx,PetscBLASInt m,PetscBLASInt nrhs,PetscBLASInt k,PetscBool T)402d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_LU(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T)
403d71ae5a4SJacob Faibussowitsch {
404c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
4054396437dSToby Isaac   PetscBLASInt  info;
40667e560aaSBarry Smith 
4073a40ed3dSBarry Smith   PetscFunctionBegin;
4089566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
409792fecdfSBarry Smith   PetscCallBLAS("LAPACKgetrs", LAPACKgetrs_(T ? "T" : "N", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info));
4109566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
411835f2295SStefano Zampini   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "GETRS - Bad solve %" PetscBLASInt_FMT, info);
4129566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m)));
4133ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4144396437dSToby Isaac }
4154396437dSToby Isaac 
MatSolve_SeqDense_Internal_Cholesky(Mat A,PetscScalar * x,PetscBLASInt ldx,PetscBLASInt m,PetscBLASInt nrhs,PetscBLASInt k,PetscBool T)416d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_Cholesky(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T)
417d71ae5a4SJacob Faibussowitsch {
4184396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
4194396437dSToby Isaac   PetscBLASInt  info;
4204396437dSToby Isaac 
4214396437dSToby Isaac   PetscFunctionBegin;
422b94d7dedSBarry Smith   if (A->spd == PETSC_BOOL3_TRUE) {
4239566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A));
4249566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
425792fecdfSBarry Smith     PetscCallBLAS("LAPACKpotrs", LAPACKpotrs_("L", &m, &nrhs, mat->v, &mat->lda, x, &m, &info));
4269566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
427835f2295SStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "POTRS Bad solve %" PetscBLASInt_FMT, info);
4289566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A));
429a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
430b94d7dedSBarry Smith   } else if (A->hermitian == PETSC_BOOL3_TRUE) {
4319566063dSJacob Faibussowitsch     if (T) PetscCall(MatConjugate_SeqDense(A));
4329566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
433792fecdfSBarry Smith     PetscCallBLAS("LAPACKhetrs", LAPACKhetrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info));
4349566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
435835f2295SStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "HETRS Bad solve %" PetscBLASInt_FMT, info);
4369566063dSJacob Faibussowitsch     if (T) PetscCall(MatConjugate_SeqDense(A));
437a49dc2a2SStefano Zampini #endif
438a49dc2a2SStefano Zampini   } else { /* symmetric case */
4399566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
440792fecdfSBarry Smith     PetscCallBLAS("LAPACKsytrs", LAPACKsytrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info));
4419566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
442835f2295SStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "SYTRS Bad solve %" PetscBLASInt_FMT, info);
443a49dc2a2SStefano Zampini   }
4449566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m)));
4453ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4464396437dSToby Isaac }
44785e2c93fSHong Zhang 
MatSolve_SeqDense_Internal_QR(Mat A,PetscScalar * x,PetscBLASInt ldx,PetscBLASInt m,PetscBLASInt nrhs,PetscBLASInt k)448d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k)
449d71ae5a4SJacob Faibussowitsch {
4504396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
4514396437dSToby Isaac   PetscBLASInt  info;
4524396437dSToby Isaac   char          trans;
4534396437dSToby Isaac 
4544396437dSToby Isaac   PetscFunctionBegin;
4554905a7bcSToby Isaac   if (PetscDefined(USE_COMPLEX)) {
4564905a7bcSToby Isaac     trans = 'C';
4574905a7bcSToby Isaac   } else {
4584905a7bcSToby Isaac     trans = 'T';
4594905a7bcSToby Isaac   }
4609566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
46105fcb23eSStefano Zampini   { /* lwork depends on the number of right-hand sides */
46205fcb23eSStefano Zampini     PetscBLASInt nlfwork, lfwork = -1;
46305fcb23eSStefano Zampini     PetscScalar  fwork;
46405fcb23eSStefano Zampini 
465792fecdfSBarry Smith     PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info));
46605fcb23eSStefano Zampini     nlfwork = (PetscBLASInt)PetscRealPart(fwork);
46705fcb23eSStefano Zampini     if (nlfwork > mat->lfwork) {
46805fcb23eSStefano Zampini       mat->lfwork = nlfwork;
46905fcb23eSStefano Zampini       PetscCall(PetscFree(mat->fwork));
47005fcb23eSStefano Zampini       PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
47105fcb23eSStefano Zampini     }
47205fcb23eSStefano Zampini   }
473792fecdfSBarry Smith   PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info));
4749566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
475835f2295SStefano Zampini   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %" PetscBLASInt_FMT, info);
4769566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
477792fecdfSBarry Smith   PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "N", "N", &mat->rank, &nrhs, mat->v, &mat->lda, x, &ldx, &info));
4789566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
479835f2295SStefano Zampini   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %" PetscBLASInt_FMT, info);
4804905a7bcSToby Isaac   for (PetscInt j = 0; j < nrhs; j++) {
481ad540459SPierre Jolivet     for (PetscInt i = mat->rank; i < k; i++) x[j * ldx + i] = 0.;
4824905a7bcSToby Isaac   }
4839566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank))));
4843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
4854905a7bcSToby Isaac }
4864905a7bcSToby Isaac 
MatSolveTranspose_SeqDense_Internal_QR(Mat A,PetscScalar * x,PetscBLASInt ldx,PetscBLASInt m,PetscBLASInt nrhs,PetscBLASInt k)487d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k)
488d71ae5a4SJacob Faibussowitsch {
4894396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
4904396437dSToby Isaac   PetscBLASInt  info;
4914396437dSToby Isaac 
4924396437dSToby Isaac   PetscFunctionBegin;
4934396437dSToby Isaac   if (A->rmap->n == A->cmap->n && mat->rank == A->rmap->n) {
4949566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
495792fecdfSBarry Smith     PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "T", "N", &m, &nrhs, mat->v, &mat->lda, x, &ldx, &info));
4969566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
497835f2295SStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %" PetscBLASInt_FMT, info);
4989566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A));
49905fcb23eSStefano Zampini     { /* lwork depends on the number of right-hand sides */
50005fcb23eSStefano Zampini       PetscBLASInt nlfwork, lfwork = -1;
50105fcb23eSStefano Zampini       PetscScalar  fwork;
50205fcb23eSStefano Zampini 
503792fecdfSBarry Smith       PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info));
50405fcb23eSStefano Zampini       nlfwork = (PetscBLASInt)PetscRealPart(fwork);
50505fcb23eSStefano Zampini       if (nlfwork > mat->lfwork) {
50605fcb23eSStefano Zampini         mat->lfwork = nlfwork;
50705fcb23eSStefano Zampini         PetscCall(PetscFree(mat->fwork));
50805fcb23eSStefano Zampini         PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
50905fcb23eSStefano Zampini       }
51005fcb23eSStefano Zampini     }
5119566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
512792fecdfSBarry Smith     PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info));
5139566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
514835f2295SStefano Zampini     PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %" PetscBLASInt_FMT, info);
5159566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A));
5164396437dSToby Isaac   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "QR factored matrix cannot be used for transpose solve");
5179566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank))));
5183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5194396437dSToby Isaac }
5204396437dSToby Isaac 
MatSolve_SeqDense_SetUp(Mat A,Vec xx,Vec yy,PetscScalar ** _y,PetscBLASInt * _m,PetscBLASInt * _k)521d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_SetUp(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k)
522d71ae5a4SJacob Faibussowitsch {
5234396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
5244905a7bcSToby Isaac   PetscScalar  *y;
5254905a7bcSToby Isaac   PetscBLASInt  m = 0, k = 0;
5264905a7bcSToby Isaac 
5274905a7bcSToby Isaac   PetscFunctionBegin;
5289566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
5299566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &k));
5304905a7bcSToby Isaac   if (k < m) {
5319566063dSJacob Faibussowitsch     PetscCall(VecCopy(xx, mat->qrrhs));
5329566063dSJacob Faibussowitsch     PetscCall(VecGetArray(mat->qrrhs, &y));
5334905a7bcSToby Isaac   } else {
5349566063dSJacob Faibussowitsch     PetscCall(VecCopy(xx, yy));
5359566063dSJacob Faibussowitsch     PetscCall(VecGetArray(yy, &y));
5364905a7bcSToby Isaac   }
5374396437dSToby Isaac   *_y = y;
5384396437dSToby Isaac   *_k = k;
5394396437dSToby Isaac   *_m = m;
5403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5414396437dSToby Isaac }
5424396437dSToby Isaac 
MatSolve_SeqDense_TearDown(Mat A,Vec xx,Vec yy,PetscScalar ** _y,PetscBLASInt * _m,PetscBLASInt * _k)543d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_TearDown(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k)
544d71ae5a4SJacob Faibussowitsch {
5454396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
54642e9364cSSatish Balay   PetscScalar  *y   = NULL;
5474396437dSToby Isaac   PetscBLASInt  m, k;
5484396437dSToby Isaac 
5494396437dSToby Isaac   PetscFunctionBegin;
5504396437dSToby Isaac   y   = *_y;
5514396437dSToby Isaac   *_y = NULL;
5524396437dSToby Isaac   k   = *_k;
5534396437dSToby Isaac   m   = *_m;
5544905a7bcSToby Isaac   if (k < m) {
5554905a7bcSToby Isaac     PetscScalar *yv;
5569566063dSJacob Faibussowitsch     PetscCall(VecGetArray(yy, &yv));
5579566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(yv, y, k));
5589566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(yy, &yv));
5599566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(mat->qrrhs, &y));
5604905a7bcSToby Isaac   } else {
5619566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(yy, &y));
5624905a7bcSToby Isaac   }
5633ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5644905a7bcSToby Isaac }
5654905a7bcSToby Isaac 
MatSolve_SeqDense_LU(Mat A,Vec xx,Vec yy)566d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_LU(Mat A, Vec xx, Vec yy)
567d71ae5a4SJacob Faibussowitsch {
56842e9364cSSatish Balay   PetscScalar *y = NULL;
56942e9364cSSatish Balay   PetscBLASInt m = 0, k = 0;
5704396437dSToby Isaac 
5714396437dSToby Isaac   PetscFunctionBegin;
5729566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
5739566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_FALSE));
5749566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
5753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5764396437dSToby Isaac }
5774396437dSToby Isaac 
MatSolveTranspose_SeqDense_LU(Mat A,Vec xx,Vec yy)578d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_LU(Mat A, Vec xx, Vec yy)
579d71ae5a4SJacob Faibussowitsch {
58042e9364cSSatish Balay   PetscScalar *y = NULL;
58142e9364cSSatish Balay   PetscBLASInt m = 0, k = 0;
5824396437dSToby Isaac 
5834396437dSToby Isaac   PetscFunctionBegin;
5849566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
5859566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_TRUE));
5869566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
5873ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
5884396437dSToby Isaac }
5894396437dSToby Isaac 
MatSolve_SeqDense_Cholesky(Mat A,Vec xx,Vec yy)590d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Cholesky(Mat A, Vec xx, Vec yy)
591d71ae5a4SJacob Faibussowitsch {
592e54beecaSStefano Zampini   PetscScalar *y = NULL;
593e54beecaSStefano Zampini   PetscBLASInt m = 0, k = 0;
5944396437dSToby Isaac 
5954396437dSToby Isaac   PetscFunctionBegin;
5969566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
5979566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_FALSE));
5989566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
5993ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6004396437dSToby Isaac }
6014396437dSToby Isaac 
MatSolveTranspose_SeqDense_Cholesky(Mat A,Vec xx,Vec yy)602d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_Cholesky(Mat A, Vec xx, Vec yy)
603d71ae5a4SJacob Faibussowitsch {
604e54beecaSStefano Zampini   PetscScalar *y = NULL;
605e54beecaSStefano Zampini   PetscBLASInt m = 0, k = 0;
6064396437dSToby Isaac 
6074396437dSToby Isaac   PetscFunctionBegin;
6089566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6099566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_TRUE));
6109566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6124396437dSToby Isaac }
6134396437dSToby Isaac 
MatSolve_SeqDense_QR(Mat A,Vec xx,Vec yy)614d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_QR(Mat A, Vec xx, Vec yy)
615d71ae5a4SJacob Faibussowitsch {
616e54beecaSStefano Zampini   PetscScalar *y = NULL;
617e54beecaSStefano Zampini   PetscBLASInt m = 0, k = 0;
6184396437dSToby Isaac 
6194396437dSToby Isaac   PetscFunctionBegin;
6209566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6219566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k));
6229566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6233ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6244396437dSToby Isaac }
6254396437dSToby Isaac 
MatSolveTranspose_SeqDense_QR(Mat A,Vec xx,Vec yy)626d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_QR(Mat A, Vec xx, Vec yy)
627d71ae5a4SJacob Faibussowitsch {
62842e9364cSSatish Balay   PetscScalar *y = NULL;
62942e9364cSSatish Balay   PetscBLASInt m = 0, k = 0;
6304396437dSToby Isaac 
6314396437dSToby Isaac   PetscFunctionBegin;
6329566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6339566063dSJacob Faibussowitsch   PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k));
6349566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6364396437dSToby Isaac }
6374396437dSToby Isaac 
MatMatSolve_SeqDense_SetUp(Mat A,Mat B,Mat X,PetscScalar ** _y,PetscBLASInt * _ldy,PetscBLASInt * _m,PetscBLASInt * _nrhs,PetscBLASInt * _k)638d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_SetUp(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k)
639d71ae5a4SJacob Faibussowitsch {
6404905a7bcSToby Isaac   const PetscScalar *b;
6414396437dSToby Isaac   PetscScalar       *y;
642bf5a80bcSToby Isaac   PetscInt           n, _ldb, _ldx;
643bf5a80bcSToby Isaac   PetscBLASInt       nrhs = 0, m = 0, k = 0, ldb = 0, ldx = 0, ldy = 0;
6444905a7bcSToby Isaac 
6454905a7bcSToby Isaac   PetscFunctionBegin;
6469371c9d4SSatish Balay   *_ldy  = 0;
6479371c9d4SSatish Balay   *_m    = 0;
6489371c9d4SSatish Balay   *_nrhs = 0;
6499371c9d4SSatish Balay   *_k    = 0;
6509371c9d4SSatish Balay   *_y    = NULL;
6519566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
6529566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &k));
6539566063dSJacob Faibussowitsch   PetscCall(MatGetSize(B, NULL, &n));
6549566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(n, &nrhs));
6559566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(B, &_ldb));
6569566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldb, &ldb));
6579566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(X, &_ldx));
6589566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldx, &ldx));
659bf5a80bcSToby Isaac   if (ldx < m) {
6609566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(B, &b));
6619566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nrhs * m, &y));
662bf5a80bcSToby Isaac     if (ldb == m) {
6639566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(y, b, ldb * nrhs));
6644905a7bcSToby Isaac     } else {
66548a46eb9SPierre Jolivet       for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * m], &b[j * ldb], m));
6664905a7bcSToby Isaac     }
667bf5a80bcSToby Isaac     ldy = m;
6689566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(B, &b));
6694905a7bcSToby Isaac   } else {
670bf5a80bcSToby Isaac     if (ldb == ldx) {
6719566063dSJacob Faibussowitsch       PetscCall(MatCopy(B, X, SAME_NONZERO_PATTERN));
6729566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(X, &y));
6734905a7bcSToby Isaac     } else {
6749566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(X, &y));
6759566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArrayRead(B, &b));
67648a46eb9SPierre Jolivet       for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * ldx], &b[j * ldb], m));
6779566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArrayRead(B, &b));
6784905a7bcSToby Isaac     }
679bf5a80bcSToby Isaac     ldy = ldx;
6804905a7bcSToby Isaac   }
6814396437dSToby Isaac   *_y    = y;
682bf5a80bcSToby Isaac   *_ldy  = ldy;
6834396437dSToby Isaac   *_k    = k;
6844396437dSToby Isaac   *_m    = m;
6854396437dSToby Isaac   *_nrhs = nrhs;
6863ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
6874396437dSToby Isaac }
6884396437dSToby Isaac 
MatMatSolve_SeqDense_TearDown(Mat A,Mat B,Mat X,PetscScalar ** _y,PetscBLASInt * _ldy,PetscBLASInt * _m,PetscBLASInt * _nrhs,PetscBLASInt * _k)689d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_TearDown(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k)
690d71ae5a4SJacob Faibussowitsch {
6914396437dSToby Isaac   PetscScalar *y;
692bf5a80bcSToby Isaac   PetscInt     _ldx;
693bf5a80bcSToby Isaac   PetscBLASInt k, ldy, nrhs, ldx = 0;
6944396437dSToby Isaac 
6954396437dSToby Isaac   PetscFunctionBegin;
6964396437dSToby Isaac   y    = *_y;
6974396437dSToby Isaac   *_y  = NULL;
6984396437dSToby Isaac   k    = *_k;
699bf5a80bcSToby Isaac   ldy  = *_ldy;
7004396437dSToby Isaac   nrhs = *_nrhs;
7019566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(X, &_ldx));
7029566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldx, &ldx));
703bf5a80bcSToby Isaac   if (ldx != ldy) {
7044905a7bcSToby Isaac     PetscScalar *xv;
7059566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArray(X, &xv));
70648a46eb9SPierre Jolivet     for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&xv[j * ldx], &y[j * ldy], k));
7079566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(X, &xv));
7089566063dSJacob Faibussowitsch     PetscCall(PetscFree(y));
7094905a7bcSToby Isaac   } else {
7109566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(X, &y));
7114905a7bcSToby Isaac   }
7123ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
71385e2c93fSHong Zhang }
71485e2c93fSHong Zhang 
MatMatSolve_SeqDense_LU(Mat A,Mat B,Mat X)715d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_LU(Mat A, Mat B, Mat X)
716d71ae5a4SJacob Faibussowitsch {
7174396437dSToby Isaac   PetscScalar *y;
718bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7194396437dSToby Isaac 
7204396437dSToby Isaac   PetscFunctionBegin;
7219566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7229566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_FALSE));
7239566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7254396437dSToby Isaac }
7264396437dSToby Isaac 
MatMatSolveTranspose_SeqDense_LU(Mat A,Mat B,Mat X)727d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_LU(Mat A, Mat B, Mat X)
728d71ae5a4SJacob Faibussowitsch {
7294396437dSToby Isaac   PetscScalar *y;
730bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7314396437dSToby Isaac 
7324396437dSToby Isaac   PetscFunctionBegin;
7339566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7349566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_TRUE));
7359566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7363ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7374396437dSToby Isaac }
7384396437dSToby Isaac 
MatMatSolve_SeqDense_Cholesky(Mat A,Mat B,Mat X)739d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_Cholesky(Mat A, Mat B, Mat X)
740d71ae5a4SJacob Faibussowitsch {
7414396437dSToby Isaac   PetscScalar *y;
742bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7434396437dSToby Isaac 
7444396437dSToby Isaac   PetscFunctionBegin;
7459566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7469566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_FALSE));
7479566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7494396437dSToby Isaac }
7504396437dSToby Isaac 
MatMatSolveTranspose_SeqDense_Cholesky(Mat A,Mat B,Mat X)751d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_Cholesky(Mat A, Mat B, Mat X)
752d71ae5a4SJacob Faibussowitsch {
7534396437dSToby Isaac   PetscScalar *y;
754bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7554396437dSToby Isaac 
7564396437dSToby Isaac   PetscFunctionBegin;
7579566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7589566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_TRUE));
7599566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7603ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7614396437dSToby Isaac }
7624396437dSToby Isaac 
MatMatSolve_SeqDense_QR(Mat A,Mat B,Mat X)763d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_QR(Mat A, Mat B, Mat X)
764d71ae5a4SJacob Faibussowitsch {
7654396437dSToby Isaac   PetscScalar *y;
766bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7674396437dSToby Isaac 
7684396437dSToby Isaac   PetscFunctionBegin;
7699566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7709566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k));
7719566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7734396437dSToby Isaac }
7744396437dSToby Isaac 
MatMatSolveTranspose_SeqDense_QR(Mat A,Mat B,Mat X)775d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_QR(Mat A, Mat B, Mat X)
776d71ae5a4SJacob Faibussowitsch {
7774396437dSToby Isaac   PetscScalar *y;
778bf5a80bcSToby Isaac   PetscBLASInt m, k, ldy, nrhs;
7794396437dSToby Isaac 
7804396437dSToby Isaac   PetscFunctionBegin;
7819566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7829566063dSJacob Faibussowitsch   PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k));
7839566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7843ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
7854396437dSToby Isaac }
7864396437dSToby Isaac 
787db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots,
788db4efbfdSBarry Smith    rather than put it in the Mat->row slot.*/
MatLUFactor_SeqDense(Mat A,IS row,IS col,PETSC_UNUSED const MatFactorInfo * minfo)78997b17b2cSPierre Jolivet PetscErrorCode MatLUFactor_SeqDense(Mat A, IS row, IS col, PETSC_UNUSED const MatFactorInfo *minfo)
790d71ae5a4SJacob Faibussowitsch {
791db4efbfdSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
792db4efbfdSBarry Smith   PetscBLASInt  n, m, info;
793db4efbfdSBarry Smith 
794db4efbfdSBarry Smith   PetscFunctionBegin;
7959566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
7969566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
7973a7d0413SPierre Jolivet   if (!mat->pivots) PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots));
7983ba16761SJacob Faibussowitsch   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS);
7999566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
800792fecdfSBarry Smith   PetscCallBLAS("LAPACKgetrf", LAPACKgetrf_(&m, &n, mat->v, &mat->lda, mat->pivots, &info));
8019566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
8028e57ea43SSatish Balay 
803835f2295SStefano Zampini   PetscCheck(info >= 0, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to LU factorization %" PetscBLASInt_FMT, info);
804835f2295SStefano Zampini   PetscCheck(info <= 0, PETSC_COMM_SELF, PETSC_ERR_MAT_LU_ZRPVT, "Bad LU factorization %" PetscBLASInt_FMT, info);
8058208b9aeSStefano Zampini 
8064396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_LU;
8074396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_LU;
8084396437dSToby Isaac   A->ops->solvetranspose    = MatSolveTranspose_SeqDense_LU;
8094396437dSToby Isaac   A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_LU;
810d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_LU;
811db4efbfdSBarry Smith 
8129566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
8139566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype));
814f6224b95SHong Zhang 
8159566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops((2.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3));
8163ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
817db4efbfdSBarry Smith }
818db4efbfdSBarry Smith 
MatLUFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo * info)81997b17b2cSPierre Jolivet static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info)
820d71ae5a4SJacob Faibussowitsch {
8214396437dSToby Isaac   PetscFunctionBegin;
8229566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES));
82397b17b2cSPierre Jolivet   PetscUseTypeMethod(fact, lufactor, NULL, NULL, info);
8243ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8254396437dSToby Isaac }
8264396437dSToby Isaac 
MatLUFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,IS col,PETSC_UNUSED const MatFactorInfo * info)82797b17b2cSPierre Jolivet PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, IS col, PETSC_UNUSED const MatFactorInfo *info)
828d71ae5a4SJacob Faibussowitsch {
8294396437dSToby Isaac   PetscFunctionBegin;
8304396437dSToby Isaac   fact->preallocated         = PETSC_TRUE;
8314396437dSToby Isaac   fact->assembled            = PETSC_TRUE;
8324396437dSToby Isaac   fact->ops->lufactornumeric = MatLUFactorNumeric_SeqDense;
8333ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
8344396437dSToby Isaac }
8354396437dSToby Isaac 
836a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */
MatCholeskyFactor_SeqDense(Mat A,IS perm,PETSC_UNUSED const MatFactorInfo * minfo)83797b17b2cSPierre Jolivet PetscErrorCode MatCholeskyFactor_SeqDense(Mat A, IS perm, PETSC_UNUSED const MatFactorInfo *minfo)
838d71ae5a4SJacob Faibussowitsch {
839db4efbfdSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
840c5df96a5SBarry Smith   PetscBLASInt  info, n;
841db4efbfdSBarry Smith 
842db4efbfdSBarry Smith   PetscFunctionBegin;
8439566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
8443ba16761SJacob Faibussowitsch   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS);
845b94d7dedSBarry Smith   if (A->spd == PETSC_BOOL3_TRUE) {
8469566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
847792fecdfSBarry Smith     PetscCallBLAS("LAPACKpotrf", LAPACKpotrf_("L", &n, mat->v, &mat->lda, &info));
8489566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
849a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
850b94d7dedSBarry Smith   } else if (A->hermitian == PETSC_BOOL3_TRUE) {
851789736e1SBarry Smith     if (!mat->pivots) PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots));
852a49dc2a2SStefano Zampini     if (!mat->fwork) {
853a49dc2a2SStefano Zampini       PetscScalar dummy;
854a49dc2a2SStefano Zampini 
855a49dc2a2SStefano Zampini       mat->lfwork = -1;
8569566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
857792fecdfSBarry Smith       PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info));
8589566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
85907c83e99SJose E. Roman       PetscCall(PetscBLASIntCast((PetscCount)(PetscRealPart(dummy)), &mat->lfwork));
8609566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
861a49dc2a2SStefano Zampini     }
8629566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
863792fecdfSBarry Smith     PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info));
8649566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
865a49dc2a2SStefano Zampini #endif
866a49dc2a2SStefano Zampini   } else { /* symmetric case */
867789736e1SBarry Smith     if (!mat->pivots) PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots));
868a49dc2a2SStefano Zampini     if (!mat->fwork) {
869a49dc2a2SStefano Zampini       PetscScalar dummy;
870a49dc2a2SStefano Zampini 
871a49dc2a2SStefano Zampini       mat->lfwork = -1;
8729566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
873792fecdfSBarry Smith       PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info));
8749566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
8756497c311SBarry Smith       PetscCall(PetscBLASIntCast((PetscCount)(PetscRealPart(dummy)), &mat->lfwork));
8769566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
877a49dc2a2SStefano Zampini     }
8789566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
879792fecdfSBarry Smith     PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info));
8809566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
881a49dc2a2SStefano Zampini   }
882835f2295SStefano Zampini   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad factorization: zero pivot in row %" PetscBLASInt_FMT, info - 1);
8838208b9aeSStefano Zampini 
8844396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_Cholesky;
8854396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_Cholesky;
8864396437dSToby Isaac   A->ops->solvetranspose    = MatSolveTranspose_SeqDense_Cholesky;
8874396437dSToby Isaac   A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_Cholesky;
888d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_CHOLESKY;
8892205254eSKarl Rupp 
8909566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
8919566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype));
892f6224b95SHong Zhang 
8939566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0));
8943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
895db4efbfdSBarry Smith }
896db4efbfdSBarry Smith 
MatCholeskyFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo * info)89797b17b2cSPierre Jolivet static PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info)
898d71ae5a4SJacob Faibussowitsch {
899db4efbfdSBarry Smith   PetscFunctionBegin;
9009566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES));
90197b17b2cSPierre Jolivet   PetscUseTypeMethod(fact, choleskyfactor, NULL, info);
9023ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
903db4efbfdSBarry Smith }
904db4efbfdSBarry Smith 
MatCholeskyFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo * info)905d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info)
906d71ae5a4SJacob Faibussowitsch {
907db4efbfdSBarry Smith   PetscFunctionBegin;
908c3ef05f6SHong Zhang   fact->assembled                  = PETSC_TRUE;
9091bbcc794SSatish Balay   fact->preallocated               = PETSC_TRUE;
910719d5645SBarry Smith   fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense;
9113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
912db4efbfdSBarry Smith }
913db4efbfdSBarry Smith 
MatQRFactor_SeqDense(Mat A,IS col,PETSC_UNUSED const MatFactorInfo * minfo)91497b17b2cSPierre Jolivet PetscErrorCode MatQRFactor_SeqDense(Mat A, IS col, PETSC_UNUSED const MatFactorInfo *minfo)
915d71ae5a4SJacob Faibussowitsch {
9164905a7bcSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
9174905a7bcSToby Isaac   PetscBLASInt  n, m, info, min, max;
9184905a7bcSToby Isaac 
9194905a7bcSToby Isaac   PetscFunctionBegin;
9209566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &n));
9219566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
9224396437dSToby Isaac   max = PetscMax(m, n);
9234396437dSToby Isaac   min = PetscMin(m, n);
924789736e1SBarry Smith   if (!mat->tau) PetscCall(PetscMalloc1(min, &mat->tau));
925789736e1SBarry Smith   if (!mat->pivots) PetscCall(PetscMalloc1(n, &mat->pivots));
926f4f49eeaSPierre Jolivet   if (!mat->qrrhs) PetscCall(MatCreateVecs(A, NULL, &mat->qrrhs));
9273ba16761SJacob Faibussowitsch   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS);
9284905a7bcSToby Isaac   if (!mat->fwork) {
9294905a7bcSToby Isaac     PetscScalar dummy;
9304905a7bcSToby Isaac 
9314905a7bcSToby Isaac     mat->lfwork = -1;
9329566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
933792fecdfSBarry Smith     PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, &dummy, &mat->lfwork, &info));
9349566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
9356497c311SBarry Smith     PetscCall(PetscBLASIntCast((PetscCount)(PetscRealPart(dummy)), &mat->lfwork));
9369566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork));
9374905a7bcSToby Isaac   }
9389566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
939792fecdfSBarry Smith   PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, mat->fwork, &mat->lfwork, &info));
9409566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
941835f2295SStefano Zampini   PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to QR factorization %" PetscBLASInt_FMT, info);
9424905a7bcSToby Isaac   // TODO: try to estimate rank or test for and use geqp3 for rank revealing QR.  For now just say rank is min of m and n
9434905a7bcSToby Isaac   mat->rank = min;
9444905a7bcSToby Isaac 
9454396437dSToby Isaac   A->ops->solve    = MatSolve_SeqDense_QR;
9464396437dSToby Isaac   A->ops->matsolve = MatMatSolve_SeqDense_QR;
9474905a7bcSToby Isaac   A->factortype    = MAT_FACTOR_QR;
9484905a7bcSToby Isaac   if (m == n) {
9494396437dSToby Isaac     A->ops->solvetranspose    = MatSolveTranspose_SeqDense_QR;
9504396437dSToby Isaac     A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_QR;
9514905a7bcSToby Isaac   }
9524905a7bcSToby Isaac 
9539566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
9549566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype));
9554905a7bcSToby Isaac 
9569566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0 * min * min * (max - min / 3.0)));
9573ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9584905a7bcSToby Isaac }
9594905a7bcSToby Isaac 
MatQRFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo * info)96097b17b2cSPierre Jolivet static PetscErrorCode MatQRFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info)
961d71ae5a4SJacob Faibussowitsch {
9624905a7bcSToby Isaac   PetscFunctionBegin;
9639566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES));
96497b17b2cSPierre Jolivet   PetscUseMethod(fact, "MatQRFactor_C", (Mat, IS, const MatFactorInfo *), (fact, NULL, info));
9653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9664905a7bcSToby Isaac }
9674905a7bcSToby Isaac 
MatQRFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo * info)968d71ae5a4SJacob Faibussowitsch PetscErrorCode MatQRFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info)
969d71ae5a4SJacob Faibussowitsch {
9704905a7bcSToby Isaac   PetscFunctionBegin;
9714905a7bcSToby Isaac   fact->assembled    = PETSC_TRUE;
9724905a7bcSToby Isaac   fact->preallocated = PETSC_TRUE;
9739566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)fact, "MatQRFactorNumeric_C", MatQRFactorNumeric_SeqDense));
9743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
9754905a7bcSToby Isaac }
9764905a7bcSToby Isaac 
977ca15aa20SStefano Zampini /* uses LAPACK */
MatGetFactor_seqdense_petsc(Mat A,MatFactorType ftype,Mat * fact)978d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A, MatFactorType ftype, Mat *fact)
979d71ae5a4SJacob Faibussowitsch {
980db4efbfdSBarry Smith   PetscFunctionBegin;
9819566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), fact));
9829566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*fact, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n));
9839566063dSJacob Faibussowitsch   PetscCall(MatSetType(*fact, MATDENSE));
98466e17bc3SBarry Smith   (*fact)->trivialsymbolic = PETSC_TRUE;
9852a350339SBarry Smith   if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU) {
986db4efbfdSBarry Smith     (*fact)->ops->lufactorsymbolic  = MatLUFactorSymbolic_SeqDense;
9872a350339SBarry Smith     (*fact)->ops->ilufactorsymbolic = MatLUFactorSymbolic_SeqDense;
988bf5a80bcSToby Isaac   } else if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) {
989db4efbfdSBarry Smith     (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense;
990bf5a80bcSToby Isaac   } else if (ftype == MAT_FACTOR_QR) {
991f4f49eeaSPierre Jolivet     PetscCall(PetscObjectComposeFunction((PetscObject)*fact, "MatQRFactorSymbolic_C", MatQRFactorSymbolic_SeqDense));
992db4efbfdSBarry Smith   }
993d5f3da31SBarry Smith   (*fact)->factortype = ftype;
99400c67f3bSHong Zhang 
9959566063dSJacob Faibussowitsch   PetscCall(PetscFree((*fact)->solvertype));
9969566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC, &(*fact)->solvertype));
9979566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_LU]));
9989566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ILU]));
9999566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_CHOLESKY]));
10009566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ICC]));
10013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1002db4efbfdSBarry Smith }
1003db4efbfdSBarry Smith 
MatSOR_SeqDense(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec xx)1004d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSOR_SeqDense(Mat A, Vec bb, PetscReal omega, MatSORType flag, PetscReal shift, PetscInt its, PetscInt lits, Vec xx)
1005d71ae5a4SJacob Faibussowitsch {
1006c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1007d9ca1df4SBarry Smith   PetscScalar       *x, *v = mat->v, zero = 0.0, xt;
1008d9ca1df4SBarry Smith   const PetscScalar *b;
1009d0f46423SBarry Smith   PetscInt           m = A->rmap->n, i;
101023fff9afSBarry Smith   PetscBLASInt       o = 1, bm = 0;
1011289bc588SBarry Smith 
10123a40ed3dSBarry Smith   PetscFunctionBegin;
101347d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
101408401ef6SPierre Jolivet   PetscCheck(A->offloadmask != PETSC_OFFLOAD_GPU, PETSC_COMM_SELF, PETSC_ERR_SUP, "Not implemented");
1015ca15aa20SStefano Zampini #endif
1016422a814eSBarry Smith   if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */
10179566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(m, &bm));
1018289bc588SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
10193bffc371SBarry Smith     /* this is a hack fix, should have another version without the second BLASdotu */
10209566063dSJacob Faibussowitsch     PetscCall(VecSet(xx, zero));
1021289bc588SBarry Smith   }
10229566063dSJacob Faibussowitsch   PetscCall(VecGetArray(xx, &x));
10239566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(bb, &b));
1024b965ef7fSBarry Smith   its = its * lits;
102508401ef6SPierre 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);
1026289bc588SBarry Smith   while (its--) {
1027fccaa45eSBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
1028289bc588SBarry Smith       for (i = 0; i < m; i++) {
1029792fecdfSBarry Smith         PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o));
1030883424caSPierre Jolivet         x[i] = (1. - omega) * x[i] + (xt + v[i + i * m] * x[i]) * omega / (v[i + i * m] + shift);
1031289bc588SBarry Smith       }
1032289bc588SBarry Smith     }
1033fccaa45eSBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
1034289bc588SBarry Smith       for (i = m - 1; i >= 0; i--) {
1035792fecdfSBarry Smith         PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o));
1036883424caSPierre Jolivet         x[i] = (1. - omega) * x[i] + (xt + v[i + i * m] * x[i]) * omega / (v[i + i * m] + shift);
1037289bc588SBarry Smith       }
1038289bc588SBarry Smith     }
1039289bc588SBarry Smith   }
10409566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(bb, &b));
10419566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(xx, &x));
10423ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1043289bc588SBarry Smith }
1044289bc588SBarry Smith 
MatMultColumnRangeKernel_SeqDense(Mat A,Vec xx,Vec yy,PetscInt c_start,PetscInt c_end,PetscBool trans,PetscBool herm)1045d016bddeSToby Isaac PETSC_INTERN PetscErrorCode MatMultColumnRangeKernel_SeqDense(Mat A, Vec xx, Vec yy, PetscInt c_start, PetscInt c_end, PetscBool trans, PetscBool herm)
1046d71ae5a4SJacob Faibussowitsch {
1047c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1048d9ca1df4SBarry Smith   PetscScalar       *y, _DOne = 1.0, _DZero = 0.0;
10490805154bSBarry Smith   PetscBLASInt       m, n, _One             = 1;
1050d9ca1df4SBarry Smith   const PetscScalar *v = mat->v, *x;
10513a40ed3dSBarry Smith 
10523a40ed3dSBarry Smith   PetscFunctionBegin;
10539566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
10540be0d8bdSHansol Suh   PetscCall(PetscBLASIntCast(c_end - c_start, &n));
10559566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx, &x));
10569566063dSJacob Faibussowitsch   PetscCall(VecGetArrayWrite(yy, &y));
10570be0d8bdSHansol Suh   if (!m || !n) {
10585ac36cfcSBarry Smith     PetscBLASInt i;
1059459e8d23SBlanca Mellado Pinto     if (trans)
1060459e8d23SBlanca Mellado Pinto       for (i = 0; i < n; i++) y[i] = 0.0;
1061459e8d23SBlanca Mellado Pinto     else
10625ac36cfcSBarry Smith       for (i = 0; i < m; i++) y[i] = 0.0;
10635ac36cfcSBarry Smith   } else {
1064459e8d23SBlanca Mellado Pinto     if (trans) {
10650be0d8bdSHansol Suh       if (herm) PetscCallBLAS("BLASgemv", BLASgemv_("C", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x, &_One, &_DZero, y + c_start, &_One));
10660be0d8bdSHansol Suh       else PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x, &_One, &_DZero, y + c_start, &_One));
1067459e8d23SBlanca Mellado Pinto     } else {
10680be0d8bdSHansol Suh       PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x + c_start, &_One, &_DZero, y, &_One));
1069459e8d23SBlanca Mellado Pinto     }
10700be0d8bdSHansol Suh     PetscCall(PetscLogFlops(2.0 * m * n - n));
10715ac36cfcSBarry Smith   }
10729566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx, &x));
10739566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayWrite(yy, &y));
10743ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1075289bc588SBarry Smith }
10766ee01492SSatish Balay 
MatMultHermitianTransposeColumnRange_SeqDense(Mat A,Vec xx,Vec yy,PetscInt c_start,PetscInt c_end)10770be0d8bdSHansol Suh PetscErrorCode MatMultHermitianTransposeColumnRange_SeqDense(Mat A, Vec xx, Vec yy, PetscInt c_start, PetscInt c_end)
10780be0d8bdSHansol Suh {
10790be0d8bdSHansol Suh   PetscFunctionBegin;
10800be0d8bdSHansol Suh   PetscCall(MatMultColumnRangeKernel_SeqDense(A, xx, yy, c_start, c_end, PETSC_TRUE, PETSC_TRUE));
10810be0d8bdSHansol Suh   PetscFunctionReturn(PETSC_SUCCESS);
10820be0d8bdSHansol Suh }
10830be0d8bdSHansol Suh 
MatMult_SeqDense(Mat A,Vec xx,Vec yy)1084459e8d23SBlanca Mellado Pinto PetscErrorCode MatMult_SeqDense(Mat A, Vec xx, Vec yy)
1085459e8d23SBlanca Mellado Pinto {
1086459e8d23SBlanca Mellado Pinto   PetscFunctionBegin;
10870be0d8bdSHansol Suh   PetscCall(MatMultColumnRangeKernel_SeqDense(A, xx, yy, 0, A->cmap->n, PETSC_FALSE, PETSC_FALSE));
1088459e8d23SBlanca Mellado Pinto   PetscFunctionReturn(PETSC_SUCCESS);
1089459e8d23SBlanca Mellado Pinto }
1090459e8d23SBlanca Mellado Pinto 
MatMultTranspose_SeqDense(Mat A,Vec xx,Vec yy)1091459e8d23SBlanca Mellado Pinto PetscErrorCode MatMultTranspose_SeqDense(Mat A, Vec xx, Vec yy)
1092459e8d23SBlanca Mellado Pinto {
1093459e8d23SBlanca Mellado Pinto   PetscFunctionBegin;
10940be0d8bdSHansol Suh   PetscCall(MatMultColumnRangeKernel_SeqDense(A, xx, yy, 0, A->cmap->n, PETSC_TRUE, PETSC_FALSE));
1095459e8d23SBlanca Mellado Pinto   PetscFunctionReturn(PETSC_SUCCESS);
1096459e8d23SBlanca Mellado Pinto }
1097459e8d23SBlanca Mellado Pinto 
MatMultHermitianTranspose_SeqDense(Mat A,Vec xx,Vec yy)1098459e8d23SBlanca Mellado Pinto PetscErrorCode MatMultHermitianTranspose_SeqDense(Mat A, Vec xx, Vec yy)
1099459e8d23SBlanca Mellado Pinto {
1100459e8d23SBlanca Mellado Pinto   PetscFunctionBegin;
11010be0d8bdSHansol Suh   PetscCall(MatMultColumnRangeKernel_SeqDense(A, xx, yy, 0, A->cmap->n, PETSC_TRUE, PETSC_TRUE));
1102459e8d23SBlanca Mellado Pinto   PetscFunctionReturn(PETSC_SUCCESS);
1103459e8d23SBlanca Mellado Pinto }
1104459e8d23SBlanca Mellado Pinto 
MatMultAddColumnRangeKernel_SeqDense(Mat A,Vec xx,Vec zz,Vec yy,PetscInt c_start,PetscInt c_end,PetscBool trans,PetscBool herm)1105d016bddeSToby Isaac PETSC_INTERN PetscErrorCode MatMultAddColumnRangeKernel_SeqDense(Mat A, Vec xx, Vec zz, Vec yy, PetscInt c_start, PetscInt c_end, PetscBool trans, PetscBool herm)
1106d71ae5a4SJacob Faibussowitsch {
1107c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1108d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v, *x;
1109d9ca1df4SBarry Smith   PetscScalar       *y, _DOne = 1.0;
11100805154bSBarry Smith   PetscBLASInt       m, n, _One = 1;
11113a40ed3dSBarry Smith 
11123a40ed3dSBarry Smith   PetscFunctionBegin;
11139566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &m));
11140be0d8bdSHansol Suh   PetscCall(PetscBLASIntCast(c_end - c_start, &n));
11159566063dSJacob Faibussowitsch   PetscCall(VecCopy(zz, yy));
11160be0d8bdSHansol Suh   if (!m || !n) PetscFunctionReturn(PETSC_SUCCESS);
11179566063dSJacob Faibussowitsch   PetscCall(VecGetArray(yy, &y));
1118459e8d23SBlanca Mellado Pinto   PetscCall(VecGetArrayRead(xx, &x));
1119459e8d23SBlanca Mellado Pinto   if (trans) {
11200be0d8bdSHansol Suh     if (herm) PetscCallBLAS("BLASgemv", BLASgemv_("C", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x, &_One, &_DOne, y + c_start, &_One));
11210be0d8bdSHansol Suh     else PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x, &_One, &_DOne, y + c_start, &_One));
1122459e8d23SBlanca Mellado Pinto   } else {
11230be0d8bdSHansol Suh     PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x + c_start, &_One, &_DOne, y, &_One));
1124459e8d23SBlanca Mellado Pinto   }
11259566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx, &x));
11269566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(yy, &y));
11270be0d8bdSHansol Suh   PetscCall(PetscLogFlops(2.0 * m * n));
11280be0d8bdSHansol Suh   PetscFunctionReturn(PETSC_SUCCESS);
11290be0d8bdSHansol Suh }
11300be0d8bdSHansol Suh 
MatMultColumnRange_SeqDense(Mat A,Vec xx,Vec yy,PetscInt c_start,PetscInt c_end)1131d016bddeSToby Isaac PetscErrorCode MatMultColumnRange_SeqDense(Mat A, Vec xx, Vec yy, PetscInt c_start, PetscInt c_end)
1132d016bddeSToby Isaac {
1133d016bddeSToby Isaac   PetscFunctionBegin;
1134d016bddeSToby Isaac   PetscCall(MatMultColumnRangeKernel_SeqDense(A, xx, yy, c_start, c_end, PETSC_FALSE, PETSC_FALSE));
1135d016bddeSToby Isaac   PetscFunctionReturn(PETSC_SUCCESS);
1136d016bddeSToby Isaac }
1137d016bddeSToby Isaac 
MatMultAddColumnRange_SeqDense(Mat A,Vec xx,Vec zz,Vec yy,PetscInt c_start,PetscInt c_end)11380be0d8bdSHansol Suh PetscErrorCode MatMultAddColumnRange_SeqDense(Mat A, Vec xx, Vec zz, Vec yy, PetscInt c_start, PetscInt c_end)
11390be0d8bdSHansol Suh {
11400be0d8bdSHansol Suh   PetscFunctionBegin;
11410be0d8bdSHansol Suh   PetscCall(MatMultAddColumnRangeKernel_SeqDense(A, xx, zz, yy, c_start, c_end, PETSC_FALSE, PETSC_FALSE));
11420be0d8bdSHansol Suh   PetscFunctionReturn(PETSC_SUCCESS);
11430be0d8bdSHansol Suh }
11440be0d8bdSHansol Suh 
MatMultHermitianTransposeAddColumnRange_SeqDense(Mat A,Vec xx,Vec zz,Vec yy,PetscInt c_start,PetscInt c_end)11450be0d8bdSHansol Suh PetscErrorCode MatMultHermitianTransposeAddColumnRange_SeqDense(Mat A, Vec xx, Vec zz, Vec yy, PetscInt c_start, PetscInt c_end)
11460be0d8bdSHansol Suh {
11470be0d8bdSHansol Suh   PetscFunctionBegin;
11480be0d8bdSHansol Suh   PetscMPIInt rank;
11490be0d8bdSHansol Suh   PetscCallMPI(MPI_Comm_rank(MPI_COMM_WORLD, &rank));
11500be0d8bdSHansol Suh   PetscCall(MatMultAddColumnRangeKernel_SeqDense(A, xx, zz, yy, c_start, c_end, PETSC_TRUE, PETSC_TRUE));
11513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1152289bc588SBarry Smith }
11536ee01492SSatish Balay 
MatMultAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)1154459e8d23SBlanca Mellado Pinto PetscErrorCode MatMultAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy)
1155459e8d23SBlanca Mellado Pinto {
1156459e8d23SBlanca Mellado Pinto   PetscFunctionBegin;
11570be0d8bdSHansol Suh   PetscCall(MatMultAddColumnRangeKernel_SeqDense(A, xx, zz, yy, 0, A->cmap->n, PETSC_FALSE, PETSC_FALSE));
1158459e8d23SBlanca Mellado Pinto   PetscFunctionReturn(PETSC_SUCCESS);
1159459e8d23SBlanca Mellado Pinto }
1160459e8d23SBlanca Mellado Pinto 
MatMultTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)1161d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy)
1162d71ae5a4SJacob Faibussowitsch {
11633a40ed3dSBarry Smith   PetscFunctionBegin;
11640be0d8bdSHansol Suh   PetscCall(MatMultAddColumnRangeKernel_SeqDense(A, xx, zz, yy, 0, A->cmap->n, PETSC_TRUE, PETSC_FALSE));
1165459e8d23SBlanca Mellado Pinto   PetscFunctionReturn(PETSC_SUCCESS);
1166459e8d23SBlanca Mellado Pinto }
1167459e8d23SBlanca Mellado Pinto 
MatMultHermitianTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)1168459e8d23SBlanca Mellado Pinto PetscErrorCode MatMultHermitianTransposeAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy)
1169459e8d23SBlanca Mellado Pinto {
1170459e8d23SBlanca Mellado Pinto   PetscFunctionBegin;
11710be0d8bdSHansol Suh   PetscCall(MatMultAddColumnRangeKernel_SeqDense(A, xx, zz, yy, 0, A->cmap->n, PETSC_TRUE, PETSC_TRUE));
11723ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1173289bc588SBarry Smith }
1174289bc588SBarry Smith 
MatGetRow_SeqDense(Mat A,PetscInt row,PetscInt * ncols,PetscInt ** cols,PetscScalar ** vals)1175d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals)
1176d71ae5a4SJacob Faibussowitsch {
1177c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
117813f74950SBarry Smith   PetscInt      i;
117967e560aaSBarry Smith 
11803a40ed3dSBarry Smith   PetscFunctionBegin;
1181c3e1b152SPierre Jolivet   if (ncols) *ncols = A->cmap->n;
1182289bc588SBarry Smith   if (cols) {
11839566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(A->cmap->n, cols));
1184d0f46423SBarry Smith     for (i = 0; i < A->cmap->n; i++) (*cols)[i] = i;
1185289bc588SBarry Smith   }
1186289bc588SBarry Smith   if (vals) {
1187ca15aa20SStefano Zampini     const PetscScalar *v;
1188ca15aa20SStefano Zampini 
11899566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A, &v));
11909566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(A->cmap->n, vals));
1191ca15aa20SStefano Zampini     v += row;
11929371c9d4SSatish Balay     for (i = 0; i < A->cmap->n; i++) {
11939371c9d4SSatish Balay       (*vals)[i] = *v;
11949371c9d4SSatish Balay       v += mat->lda;
11959371c9d4SSatish Balay     }
11969566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A, &v));
1197289bc588SBarry Smith   }
11983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1199289bc588SBarry Smith }
12006ee01492SSatish Balay 
MatRestoreRow_SeqDense(Mat A,PetscInt row,PetscInt * ncols,PetscInt ** cols,PetscScalar ** vals)1201d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRestoreRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals)
1202d71ae5a4SJacob Faibussowitsch {
1203606d414cSSatish Balay   PetscFunctionBegin;
12049566063dSJacob Faibussowitsch   if (cols) PetscCall(PetscFree(*cols));
12059566063dSJacob Faibussowitsch   if (vals) PetscCall(PetscFree(*vals));
12063ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1207289bc588SBarry Smith }
12082ef1f0ffSBarry Smith 
MatSetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],const PetscScalar v[],InsertMode addv)1209d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], const PetscScalar v[], InsertMode addv)
1210d71ae5a4SJacob Faibussowitsch {
1211c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
1212ca15aa20SStefano Zampini   PetscScalar  *av;
121313f74950SBarry Smith   PetscInt      i, j, idx = 0;
121447d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
1215c70f7ee4SJunchao Zhang   PetscOffloadMask oldf;
1216ca15aa20SStefano Zampini #endif
1217d6dfbf8fSBarry Smith 
12183a40ed3dSBarry Smith   PetscFunctionBegin;
12199566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &av));
1220289bc588SBarry Smith   if (!mat->roworiented) {
1221dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1222289bc588SBarry Smith       for (j = 0; j < n; j++) {
12239371c9d4SSatish Balay         if (indexn[j] < 0) {
12249371c9d4SSatish Balay           idx += m;
12259371c9d4SSatish Balay           continue;
12269371c9d4SSatish Balay         }
12276bdcaf15SBarry 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);
1228289bc588SBarry Smith         for (i = 0; i < m; i++) {
12299371c9d4SSatish Balay           if (indexm[i] < 0) {
12309371c9d4SSatish Balay             idx++;
12319371c9d4SSatish Balay             continue;
12329371c9d4SSatish Balay           }
12336bdcaf15SBarry 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);
12348c4a67a0SStefano Zampini           av[indexn[j] * mat->lda + indexm[i]] = v ? v[idx++] : (idx++, 0.0);
1235289bc588SBarry Smith         }
1236289bc588SBarry Smith       }
12370be0d8bdSHansol Suh     } else {
1238289bc588SBarry Smith       for (j = 0; j < n; j++) {
12399371c9d4SSatish Balay         if (indexn[j] < 0) {
12409371c9d4SSatish Balay           idx += m;
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);
1244289bc588SBarry Smith         for (i = 0; i < m; i++) {
12459371c9d4SSatish Balay           if (indexm[i] < 0) {
12469371c9d4SSatish Balay             idx++;
12479371c9d4SSatish Balay             continue;
12489371c9d4SSatish Balay           }
12496bdcaf15SBarry 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);
12508c4a67a0SStefano Zampini           av[indexn[j] * mat->lda + indexm[i]] += v ? v[idx++] : (idx++, 0.0);
1251289bc588SBarry Smith         }
1252289bc588SBarry Smith       }
1253289bc588SBarry Smith     }
12543a40ed3dSBarry Smith   } else {
1255dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1256e8d4e0b9SBarry Smith       for (i = 0; i < m; i++) {
12579371c9d4SSatish Balay         if (indexm[i] < 0) {
12589371c9d4SSatish Balay           idx += n;
12599371c9d4SSatish Balay           continue;
12609371c9d4SSatish Balay         }
12616bdcaf15SBarry Smith         PetscCheck(indexm[i] < A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Row too large: row %" PetscInt_FMT " max %" PetscInt_FMT, indexm[i], A->rmap->n - 1);
1262e8d4e0b9SBarry Smith         for (j = 0; j < n; j++) {
12639371c9d4SSatish Balay           if (indexn[j] < 0) {
12649371c9d4SSatish Balay             idx++;
12659371c9d4SSatish Balay             continue;
12669371c9d4SSatish Balay           }
12676bdcaf15SBarry 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);
12688c4a67a0SStefano Zampini           av[indexn[j] * mat->lda + indexm[i]] = v ? v[idx++] : (idx++, 0.0);
1269e8d4e0b9SBarry Smith         }
1270e8d4e0b9SBarry Smith       }
12710be0d8bdSHansol Suh     } else {
1272289bc588SBarry Smith       for (i = 0; i < m; i++) {
12739371c9d4SSatish Balay         if (indexm[i] < 0) {
12749371c9d4SSatish Balay           idx += n;
12759371c9d4SSatish Balay           continue;
12769371c9d4SSatish Balay         }
12776bdcaf15SBarry 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);
1278289bc588SBarry Smith         for (j = 0; j < n; j++) {
12799371c9d4SSatish Balay           if (indexn[j] < 0) {
12809371c9d4SSatish Balay             idx++;
12819371c9d4SSatish Balay             continue;
12829371c9d4SSatish Balay           }
12836bdcaf15SBarry 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);
12848c4a67a0SStefano Zampini           av[indexn[j] * mat->lda + indexm[i]] += v ? v[idx++] : (idx++, 0.0);
1285289bc588SBarry Smith         }
1286289bc588SBarry Smith       }
1287289bc588SBarry Smith     }
1288e8d4e0b9SBarry Smith   }
1289ca15aa20SStefano Zampini   /* hack to prevent unneeded copy to the GPU while returning the array */
129047d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
1291c70f7ee4SJunchao Zhang   oldf           = A->offloadmask;
1292c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_GPU;
1293ca15aa20SStefano Zampini #endif
12949566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &av));
129547d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
1296c70f7ee4SJunchao Zhang   A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU);
1297ca15aa20SStefano Zampini #endif
12983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1299289bc588SBarry Smith }
1300e8d4e0b9SBarry Smith 
MatGetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],PetscScalar v[])1301d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], PetscScalar v[])
1302d71ae5a4SJacob Faibussowitsch {
1303ae80bb75SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1304ca15aa20SStefano Zampini   const PetscScalar *vv;
130513f74950SBarry Smith   PetscInt           i, j;
1306ae80bb75SLois Curfman McInnes 
13073a40ed3dSBarry Smith   PetscFunctionBegin;
13089566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &vv));
1309ae80bb75SLois Curfman McInnes   /* row-oriented output */
1310ae80bb75SLois Curfman McInnes   for (i = 0; i < m; i++) {
13119371c9d4SSatish Balay     if (indexm[i] < 0) {
13129371c9d4SSatish Balay       v += n;
13139371c9d4SSatish Balay       continue;
13149371c9d4SSatish Balay     }
131508401ef6SPierre 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);
1316ae80bb75SLois Curfman McInnes     for (j = 0; j < n; j++) {
13179371c9d4SSatish Balay       if (indexn[j] < 0) {
13189371c9d4SSatish Balay         v++;
13199371c9d4SSatish Balay         continue;
13209371c9d4SSatish Balay       }
132108401ef6SPierre 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);
1322ca15aa20SStefano Zampini       *v++ = vv[indexn[j] * mat->lda + indexm[i]];
1323ae80bb75SLois Curfman McInnes     }
1324ae80bb75SLois Curfman McInnes   }
13259566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &vv));
13263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1327ae80bb75SLois Curfman McInnes }
1328ae80bb75SLois Curfman McInnes 
MatView_Dense_Binary(Mat mat,PetscViewer viewer)1329d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_Dense_Binary(Mat mat, PetscViewer viewer)
1330d71ae5a4SJacob Faibussowitsch {
13318491ab44SLisandro Dalcin   PetscBool          skipHeader;
13328491ab44SLisandro Dalcin   PetscViewerFormat  format;
13333e1d7bceSPierre Jolivet   PetscInt           header[4], M, N, m, lda, i, j;
13343e1d7bceSPierre Jolivet   PetscCount         k;
13358491ab44SLisandro Dalcin   const PetscScalar *v;
13368491ab44SLisandro Dalcin   PetscScalar       *vwork;
1337aabbc4fbSShri Abhyankar 
1338aabbc4fbSShri Abhyankar   PetscFunctionBegin;
13399566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
13409566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader));
13419566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
13428491ab44SLisandro Dalcin   if (skipHeader) format = PETSC_VIEWER_NATIVE;
1343aabbc4fbSShri Abhyankar 
13449566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat, &M, &N));
13458491ab44SLisandro Dalcin 
13468491ab44SLisandro Dalcin   /* write matrix header */
13479371c9d4SSatish Balay   header[0] = MAT_FILE_CLASSID;
13489371c9d4SSatish Balay   header[1] = M;
13499371c9d4SSatish Balay   header[2] = N;
13508491ab44SLisandro Dalcin   header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M * N;
13519566063dSJacob Faibussowitsch   if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer, header, 4, PETSC_INT));
13528491ab44SLisandro Dalcin 
13539566063dSJacob Faibussowitsch   PetscCall(MatGetLocalSize(mat, &m, NULL));
13548491ab44SLisandro Dalcin   if (format != PETSC_VIEWER_NATIVE) {
13558491ab44SLisandro Dalcin     PetscInt nnz = m * N, *iwork;
13568491ab44SLisandro Dalcin     /* store row lengths for each row */
13579566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nnz, &iwork));
13588491ab44SLisandro Dalcin     for (i = 0; i < m; i++) iwork[i] = N;
13599566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT));
13608491ab44SLisandro Dalcin     /* store column indices (zero start index) */
13618491ab44SLisandro Dalcin     for (k = 0, i = 0; i < m; i++)
13629371c9d4SSatish Balay       for (j = 0; j < N; j++, k++) iwork[k] = j;
13639566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT));
13649566063dSJacob Faibussowitsch     PetscCall(PetscFree(iwork));
13658491ab44SLisandro Dalcin   }
13668491ab44SLisandro Dalcin   /* store matrix values as a dense matrix in row major order */
13679566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(m * N, &vwork));
13689566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(mat, &v));
13699566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(mat, &lda));
13708491ab44SLisandro Dalcin   for (k = 0, i = 0; i < m; i++)
13713e1d7bceSPierre Jolivet     for (j = 0; j < N; j++, k++) vwork[k] = v[i + (size_t)lda * j];
13729566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(mat, &v));
13739566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryWriteAll(viewer, vwork, m * N, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR));
13749566063dSJacob Faibussowitsch   PetscCall(PetscFree(vwork));
13753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
13768491ab44SLisandro Dalcin }
13778491ab44SLisandro Dalcin 
MatLoad_Dense_Binary(Mat mat,PetscViewer viewer)1378d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLoad_Dense_Binary(Mat mat, PetscViewer viewer)
1379d71ae5a4SJacob Faibussowitsch {
13808491ab44SLisandro Dalcin   PetscBool    skipHeader;
13818491ab44SLisandro Dalcin   PetscInt     header[4], M, N, m, nz, lda, i, j, k;
13828491ab44SLisandro Dalcin   PetscInt     rows, cols;
13838491ab44SLisandro Dalcin   PetscScalar *v, *vwork;
13848491ab44SLisandro Dalcin 
13858491ab44SLisandro Dalcin   PetscFunctionBegin;
13869566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
13879566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader));
13888491ab44SLisandro Dalcin 
13898491ab44SLisandro Dalcin   if (!skipHeader) {
13909566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryRead(viewer, header, 4, NULL, PETSC_INT));
139108401ef6SPierre Jolivet     PetscCheck(header[0] == MAT_FILE_CLASSID, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Not a matrix object in file");
13929371c9d4SSatish Balay     M = header[1];
13939371c9d4SSatish Balay     N = header[2];
139408401ef6SPierre Jolivet     PetscCheck(M >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix row size (%" PetscInt_FMT ") in file is negative", M);
139508401ef6SPierre Jolivet     PetscCheck(N >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix column size (%" PetscInt_FMT ") in file is negative", N);
13968491ab44SLisandro Dalcin     nz = header[3];
1397aed4548fSBarry Smith     PetscCheck(nz == MATRIX_BINARY_FORMAT_DENSE || nz >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Unknown matrix format %" PetscInt_FMT " in file", nz);
1398aabbc4fbSShri Abhyankar   } else {
13999566063dSJacob Faibussowitsch     PetscCall(MatGetSize(mat, &M, &N));
1400aed4548fSBarry 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");
14018491ab44SLisandro Dalcin     nz = MATRIX_BINARY_FORMAT_DENSE;
1402e6324fbbSBarry Smith   }
1403aabbc4fbSShri Abhyankar 
14048491ab44SLisandro Dalcin   /* setup global sizes if not set */
14058491ab44SLisandro Dalcin   if (mat->rmap->N < 0) mat->rmap->N = M;
14068491ab44SLisandro Dalcin   if (mat->cmap->N < 0) mat->cmap->N = N;
14079566063dSJacob Faibussowitsch   PetscCall(MatSetUp(mat));
14088491ab44SLisandro Dalcin   /* check if global sizes are correct */
14099566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat, &rows, &cols));
1410aed4548fSBarry 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);
1411aabbc4fbSShri Abhyankar 
14129566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat, NULL, &N));
14139566063dSJacob Faibussowitsch   PetscCall(MatGetLocalSize(mat, &m, NULL));
14149566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(mat, &v));
14159566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(mat, &lda));
14168491ab44SLisandro Dalcin   if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense format */
14173e1d7bceSPierre Jolivet     PetscCount nnz = (size_t)m * N;
14188491ab44SLisandro Dalcin     /* read in matrix values */
14199566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nnz, &vwork));
14209566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR));
14218491ab44SLisandro Dalcin     /* store values in column major order */
14228491ab44SLisandro Dalcin     for (j = 0; j < N; j++)
14233e1d7bceSPierre Jolivet       for (i = 0; i < m; i++) v[i + (size_t)lda * j] = vwork[(size_t)i * N + j];
14249566063dSJacob Faibussowitsch     PetscCall(PetscFree(vwork));
14258491ab44SLisandro Dalcin   } else { /* matrix in file is sparse format */
14268491ab44SLisandro Dalcin     PetscInt nnz = 0, *rlens, *icols;
14278491ab44SLisandro Dalcin     /* read in row lengths */
14289566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(m, &rlens));
14299566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer, rlens, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT));
14308491ab44SLisandro Dalcin     for (i = 0; i < m; i++) nnz += rlens[i];
14318491ab44SLisandro Dalcin     /* read in column indices and values */
14329566063dSJacob Faibussowitsch     PetscCall(PetscMalloc2(nnz, &icols, nnz, &vwork));
14339566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer, icols, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT));
14349566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR));
14358491ab44SLisandro Dalcin     /* store values in column major order */
14368491ab44SLisandro Dalcin     for (k = 0, i = 0; i < m; i++)
14379371c9d4SSatish Balay       for (j = 0; j < rlens[i]; j++, k++) v[i + lda * icols[k]] = vwork[k];
14389566063dSJacob Faibussowitsch     PetscCall(PetscFree(rlens));
14399566063dSJacob Faibussowitsch     PetscCall(PetscFree2(icols, vwork));
1440aabbc4fbSShri Abhyankar   }
14419566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(mat, &v));
14429566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY));
14439566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY));
14443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1445aabbc4fbSShri Abhyankar }
1446aabbc4fbSShri Abhyankar 
MatLoad_SeqDense(Mat newMat,PetscViewer viewer)144766976f2fSJacob Faibussowitsch static PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer)
1448d71ae5a4SJacob Faibussowitsch {
1449eb91f321SVaclav Hapla   PetscBool isbinary, ishdf5;
1450eb91f321SVaclav Hapla 
1451eb91f321SVaclav Hapla   PetscFunctionBegin;
1452eb91f321SVaclav Hapla   PetscValidHeaderSpecific(newMat, MAT_CLASSID, 1);
1453eb91f321SVaclav Hapla   PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2);
1454eb91f321SVaclav Hapla   /* force binary viewer to load .info file if it has not yet done so */
14559566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
14569566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
14579566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5));
1458eb91f321SVaclav Hapla   if (isbinary) {
14599566063dSJacob Faibussowitsch     PetscCall(MatLoad_Dense_Binary(newMat, viewer));
1460eb91f321SVaclav Hapla   } else if (ishdf5) {
1461eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5)
14629566063dSJacob Faibussowitsch     PetscCall(MatLoad_Dense_HDF5(newMat, viewer));
1463eb91f321SVaclav Hapla #else
1464eb91f321SVaclav Hapla     SETERRQ(PetscObjectComm((PetscObject)newMat), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5");
1465eb91f321SVaclav Hapla #endif
1466eb91f321SVaclav Hapla   } else {
146798921bdaSJacob 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);
1468eb91f321SVaclav Hapla   }
14693ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1470eb91f321SVaclav Hapla }
1471eb91f321SVaclav Hapla 
MatView_SeqDense_ASCII(Mat A,PetscViewer viewer)1472d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_ASCII(Mat A, PetscViewer viewer)
1473d71ae5a4SJacob Faibussowitsch {
1474932b0c3eSLois Curfman McInnes   Mat_SeqDense     *a = (Mat_SeqDense *)A->data;
147513f74950SBarry Smith   PetscInt          i, j;
14762dcb1b2aSMatthew Knepley   const char       *name;
1477ca15aa20SStefano Zampini   PetscScalar      *v, *av;
1478f3ef73ceSBarry Smith   PetscViewerFormat format;
14795f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX)
1480ace3abfcSBarry Smith   PetscBool allreal = PETSC_TRUE;
14815f481a85SSatish Balay #endif
1482932b0c3eSLois Curfman McInnes 
14833a40ed3dSBarry Smith   PetscFunctionBegin;
14849566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&av));
14859566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
1486456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
14873ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS); /* do nothing for now */
1488fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
14899566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
1490d0f46423SBarry Smith     for (i = 0; i < A->rmap->n; i++) {
1491ca15aa20SStefano Zampini       v = av + i;
14929566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "row %" PetscInt_FMT ":", i));
1493d0f46423SBarry Smith       for (j = 0; j < A->cmap->n; j++) {
1494aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1495329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
14969566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g + %g i) ", j, (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v)));
1497329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
14989566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)PetscRealPart(*v)));
14996831982aSBarry Smith         }
150080cd9d93SLois Curfman McInnes #else
150148a46eb9SPierre Jolivet         if (*v) PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)*v));
150280cd9d93SLois Curfman McInnes #endif
15031b807ce4Svictorle         v += a->lda;
150480cd9d93SLois Curfman McInnes       }
15059566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
150680cd9d93SLois Curfman McInnes     }
15079566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
15083a40ed3dSBarry Smith   } else {
15099566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE));
1510aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
151147989497SBarry Smith     /* determine if matrix has all real values */
1512bcd8d3a4SJose E. Roman     for (j = 0; j < A->cmap->n; j++) {
1513bcd8d3a4SJose E. Roman       v = av + j * a->lda;
1514bcd8d3a4SJose E. Roman       for (i = 0; i < A->rmap->n; i++) {
15159371c9d4SSatish Balay         if (PetscImaginaryPart(v[i])) {
15169371c9d4SSatish Balay           allreal = PETSC_FALSE;
15179371c9d4SSatish Balay           break;
15189371c9d4SSatish Balay         }
151947989497SBarry Smith       }
1520bcd8d3a4SJose E. Roman     }
152147989497SBarry Smith #endif
1522fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
15239566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetName((PetscObject)A, &name));
15249566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%% Size = %" PetscInt_FMT " %" PetscInt_FMT " \n", A->rmap->n, A->cmap->n));
15259566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%s = zeros(%" PetscInt_FMT ",%" PetscInt_FMT ");\n", name, A->rmap->n, A->cmap->n));
15269566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "%s = [\n", name));
1527ffac6cdbSBarry Smith     }
1528ffac6cdbSBarry Smith 
1529d0f46423SBarry Smith     for (i = 0; i < A->rmap->n; i++) {
1530ca15aa20SStefano Zampini       v = av + i;
1531d0f46423SBarry Smith       for (j = 0; j < A->cmap->n; j++) {
1532aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
153347989497SBarry Smith         if (allreal) {
15349566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)PetscRealPart(*v)));
153547989497SBarry Smith         } else {
15369566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e + %18.16ei ", (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v)));
153747989497SBarry Smith         }
1538289bc588SBarry Smith #else
15399566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)*v));
1540289bc588SBarry Smith #endif
15411b807ce4Svictorle         v += a->lda;
1542289bc588SBarry Smith       }
15439566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer, "\n"));
1544289bc588SBarry Smith     }
154548a46eb9SPierre Jolivet     if (format == PETSC_VIEWER_ASCII_MATLAB) PetscCall(PetscViewerASCIIPrintf(viewer, "];\n"));
15469566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE));
1547da3a660dSBarry Smith   }
15489566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&av));
15499566063dSJacob Faibussowitsch   PetscCall(PetscViewerFlush(viewer));
15503ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1551289bc588SBarry Smith }
1552289bc588SBarry Smith 
15539804daf3SBarry Smith #include <petscdraw.h>
MatView_SeqDense_Draw_Zoom(PetscDraw draw,void * Aa)1554d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw, void *Aa)
1555d71ae5a4SJacob Faibussowitsch {
1556f1af5d2fSBarry Smith   Mat                A = (Mat)Aa;
1557383922c3SLisandro Dalcin   PetscInt           m = A->rmap->n, n = A->cmap->n, i, j;
1558383922c3SLisandro Dalcin   int                color = PETSC_DRAW_WHITE;
1559ca15aa20SStefano Zampini   const PetscScalar *v;
1560b0a32e0cSBarry Smith   PetscViewer        viewer;
1561b05fc000SLisandro Dalcin   PetscReal          xl, yl, xr, yr, x_l, x_r, y_l, y_r;
1562f3ef73ceSBarry Smith   PetscViewerFormat  format;
1563f1af5d2fSBarry Smith 
1564f1af5d2fSBarry Smith   PetscFunctionBegin;
15659566063dSJacob Faibussowitsch   PetscCall(PetscObjectQuery((PetscObject)A, "Zoomviewer", (PetscObject *)&viewer));
15669566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer, &format));
15679566063dSJacob Faibussowitsch   PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr));
1568f1af5d2fSBarry Smith 
1569f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
15709566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &v));
1571fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
1572d0609cedSBarry Smith     PetscDrawCollectiveBegin(draw);
1573f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
1574f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
15759371c9d4SSatish Balay       x_l = j;
15769371c9d4SSatish Balay       x_r = x_l + 1.0;
1577f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1578f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1579f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1580ca15aa20SStefano Zampini         if (PetscRealPart(v[j * m + i]) > 0.) color = PETSC_DRAW_RED;
1581ca15aa20SStefano Zampini         else if (PetscRealPart(v[j * m + i]) < 0.) color = PETSC_DRAW_BLUE;
1582ca15aa20SStefano Zampini         else continue;
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   } else {
1588f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
1589f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
1590b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1591b05fc000SLisandro Dalcin     PetscDraw popup;
1592b05fc000SLisandro Dalcin 
1593f1af5d2fSBarry Smith     for (i = 0; i < m * n; i++) {
1594f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
1595f1af5d2fSBarry Smith     }
1596383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
15979566063dSJacob Faibussowitsch     PetscCall(PetscDrawGetPopup(draw, &popup));
15989566063dSJacob Faibussowitsch     PetscCall(PetscDrawScalePopup(popup, minv, maxv));
1599383922c3SLisandro Dalcin 
1600d0609cedSBarry Smith     PetscDrawCollectiveBegin(draw);
1601f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
1602f1af5d2fSBarry Smith       x_l = j;
1603f1af5d2fSBarry Smith       x_r = x_l + 1.0;
1604f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1605f1af5d2fSBarry Smith         y_l   = m - i - 1.0;
1606f1af5d2fSBarry Smith         y_r   = y_l + 1.0;
1607b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(v[j * m + i]), minv, maxv);
16089566063dSJacob Faibussowitsch         PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color));
1609f1af5d2fSBarry Smith       }
1610f1af5d2fSBarry Smith     }
1611d0609cedSBarry Smith     PetscDrawCollectiveEnd(draw);
1612f1af5d2fSBarry Smith   }
16139566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &v));
16143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1615f1af5d2fSBarry Smith }
1616f1af5d2fSBarry Smith 
MatView_SeqDense_Draw(Mat A,PetscViewer viewer)1617d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw(Mat A, PetscViewer viewer)
1618d71ae5a4SJacob Faibussowitsch {
1619b0a32e0cSBarry Smith   PetscDraw draw;
1620ace3abfcSBarry Smith   PetscBool isnull;
1621329f5518SBarry Smith   PetscReal xr, yr, xl, yl, h, w;
1622f1af5d2fSBarry Smith 
1623f1af5d2fSBarry Smith   PetscFunctionBegin;
16249566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw));
16259566063dSJacob Faibussowitsch   PetscCall(PetscDrawIsNull(draw, &isnull));
16263ba16761SJacob Faibussowitsch   if (isnull) PetscFunctionReturn(PETSC_SUCCESS);
1627f1af5d2fSBarry Smith 
16289371c9d4SSatish Balay   xr = A->cmap->n;
16299371c9d4SSatish Balay   yr = A->rmap->n;
16309371c9d4SSatish Balay   h  = yr / 10.0;
16319371c9d4SSatish Balay   w  = xr / 10.0;
16329371c9d4SSatish Balay   xr += w;
16339371c9d4SSatish Balay   yr += h;
16349371c9d4SSatish Balay   xl = -w;
16359371c9d4SSatish Balay   yl = -h;
16369566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetCoordinates(draw, xl, yl, xr, yr));
16379566063dSJacob Faibussowitsch   PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", (PetscObject)viewer));
16389566063dSJacob Faibussowitsch   PetscCall(PetscDrawZoom(draw, MatView_SeqDense_Draw_Zoom, A));
16399566063dSJacob Faibussowitsch   PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", NULL));
16409566063dSJacob Faibussowitsch   PetscCall(PetscDrawSave(draw));
16413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1642f1af5d2fSBarry Smith }
1643f1af5d2fSBarry Smith 
MatView_SeqDense(Mat A,PetscViewer viewer)1644d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_SeqDense(Mat A, PetscViewer viewer)
1645d71ae5a4SJacob Faibussowitsch {
16469f196a02SMartin Diehl   PetscBool isascii, isbinary, isdraw;
1647932b0c3eSLois Curfman McInnes 
16483a40ed3dSBarry Smith   PetscFunctionBegin;
16499f196a02SMartin Diehl   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii));
16509566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary));
16519566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw));
16529f196a02SMartin Diehl   if (isascii) PetscCall(MatView_SeqDense_ASCII(A, viewer));
16531baa6e33SBarry Smith   else if (isbinary) PetscCall(MatView_Dense_Binary(A, viewer));
16541baa6e33SBarry Smith   else if (isdraw) PetscCall(MatView_SeqDense_Draw(A, viewer));
16553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1656932b0c3eSLois Curfman McInnes }
1657289bc588SBarry Smith 
MatDensePlaceArray_SeqDense(Mat A,const PetscScalar * array)1658d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A, const PetscScalar *array)
1659d71ae5a4SJacob Faibussowitsch {
1660d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
1661d3042a70SBarry Smith 
1662d3042a70SBarry Smith   PetscFunctionBegin;
166328b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
166428b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
16656635c364SPierre Jolivet   PetscCheck(!a->unplacedarray, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseResetArray() first");
1666d3042a70SBarry Smith   a->unplacedarray       = a->v;
1667d3042a70SBarry Smith   a->unplaced_user_alloc = a->user_alloc;
1668d3042a70SBarry Smith   a->v                   = (PetscScalar *)array;
1669637a0070SStefano Zampini   a->user_alloc          = PETSC_TRUE;
167047d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
1671c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1672ca15aa20SStefano Zampini #endif
16733ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1674d3042a70SBarry Smith }
1675d3042a70SBarry Smith 
MatDenseResetArray_SeqDense(Mat A)1676d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseResetArray_SeqDense(Mat A)
1677d71ae5a4SJacob Faibussowitsch {
1678d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
1679d3042a70SBarry Smith 
1680d3042a70SBarry Smith   PetscFunctionBegin;
168128b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
168228b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
1683d3042a70SBarry Smith   a->v             = a->unplacedarray;
1684d3042a70SBarry Smith   a->user_alloc    = a->unplaced_user_alloc;
1685d3042a70SBarry Smith   a->unplacedarray = NULL;
168647d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
1687c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1688ca15aa20SStefano Zampini #endif
16893ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1690d3042a70SBarry Smith }
1691d3042a70SBarry Smith 
MatDenseReplaceArray_SeqDense(Mat A,const PetscScalar * array)1692d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A, const PetscScalar *array)
1693d71ae5a4SJacob Faibussowitsch {
1694d5ea218eSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
1695d5ea218eSStefano Zampini 
1696d5ea218eSStefano Zampini   PetscFunctionBegin;
169728b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
169828b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
16999566063dSJacob Faibussowitsch   if (!a->user_alloc) PetscCall(PetscFree(a->v));
1700d5ea218eSStefano Zampini   a->v          = (PetscScalar *)array;
1701d5ea218eSStefano Zampini   a->user_alloc = PETSC_FALSE;
170247d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
1703d5ea218eSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
1704d5ea218eSStefano Zampini #endif
17053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1706d5ea218eSStefano Zampini }
1707d5ea218eSStefano Zampini 
MatDestroy_SeqDense(Mat mat)1708d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDestroy_SeqDense(Mat mat)
1709d71ae5a4SJacob Faibussowitsch {
1710ec8511deSBarry Smith   Mat_SeqDense *l = (Mat_SeqDense *)mat->data;
171190f02eecSBarry Smith 
17123a40ed3dSBarry Smith   PetscFunctionBegin;
17133ba16761SJacob Faibussowitsch   PetscCall(PetscLogObjectState((PetscObject)mat, "Rows %" PetscInt_FMT " Cols %" PetscInt_FMT, mat->rmap->n, mat->cmap->n));
1714f4f49eeaSPierre Jolivet   PetscCall(VecDestroy(&l->qrrhs));
17159566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->tau));
17169566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->pivots));
17179566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->fwork));
17189566063dSJacob Faibussowitsch   if (!l->user_alloc) PetscCall(PetscFree(l->v));
17199566063dSJacob Faibussowitsch   if (!l->unplaced_user_alloc) PetscCall(PetscFree(l->unplacedarray));
172028b400f6SJacob Faibussowitsch   PetscCheck(!l->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
172128b400f6SJacob Faibussowitsch   PetscCheck(!l->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
17229566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&l->cvec));
17239566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&l->cmat));
17249566063dSJacob Faibussowitsch   PetscCall(PetscFree(mat->data));
1725dbd8c25aSHong Zhang 
17269566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)mat, NULL));
17279566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactor_C", NULL));
17282e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorSymbolic_C", NULL));
17292e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorNumeric_C", NULL));
17309566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetLDA_C", NULL));
17319566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseSetLDA_C", NULL));
17329566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArray_C", NULL));
17339566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArray_C", NULL));
17349566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDensePlaceArray_C", NULL));
17359566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseResetArray_C", NULL));
17369566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseReplaceArray_C", NULL));
17379566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayRead_C", NULL));
17389566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayRead_C", NULL));
17399566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayWrite_C", NULL));
17409566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayWrite_C", NULL));
17419566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqaij_C", NULL));
17428baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
17439566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_elemental_C", NULL));
17448baccfbdSHong Zhang #endif
1745d1a032dbSPierre Jolivet #if defined(PETSC_HAVE_SCALAPACK) && (defined(PETSC_USE_REAL_SINGLE) || defined(PETSC_USE_REAL_DOUBLE))
17469566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_scalapack_C", NULL));
1747d24d4204SJose E. Roman #endif
17482bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
17499566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensecuda_C", NULL));
17509566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", NULL));
17519566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdense_C", NULL));
17522e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensecuda_C", NULL));
17532bf066beSStefano Zampini #endif
175447d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP)
175547d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensehip_C", NULL));
175647d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensehip_seqdensehip_C", NULL));
175747d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensehip_seqdense_C", NULL));
175847d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensehip_C", NULL));
175947d993e7Ssuyashtn #endif
17609566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatSeqDenseSetPreallocation_C", NULL));
17619566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqaij_seqdense_C", NULL));
17629566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdense_C", NULL));
17639566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqbaij_seqdense_C", NULL));
17649566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqsbaij_seqdense_C", NULL));
176552c5f739Sprj- 
17669566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumn_C", NULL));
17679566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumn_C", NULL));
17689566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVec_C", NULL));
17699566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVec_C", NULL));
17709566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecRead_C", NULL));
17719566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecRead_C", NULL));
17729566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecWrite_C", NULL));
17739566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecWrite_C", NULL));
17749566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetSubMatrix_C", NULL));
17759566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreSubMatrix_C", NULL));
1776d016bddeSToby Isaac   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatMultColumnRange_C", NULL));
17770be0d8bdSHansol Suh   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatMultAddColumnRange_C", NULL));
17780be0d8bdSHansol Suh   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatMultHermitianTransposeColumnRange_C", NULL));
17790be0d8bdSHansol Suh   PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatMultHermitianTransposeAddColumnRange_C", NULL));
17803ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1781289bc588SBarry Smith }
1782289bc588SBarry Smith 
MatTranspose_SeqDense(Mat A,MatReuse reuse,Mat * matout)1783d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatTranspose_SeqDense(Mat A, MatReuse reuse, Mat *matout)
1784d71ae5a4SJacob Faibussowitsch {
1785c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
17866536e3caSStefano Zampini   PetscInt      k, j, m = A->rmap->n, M = mat->lda, n = A->cmap->n;
178787828ca2SBarry Smith   PetscScalar  *v, tmp;
178848b35521SBarry Smith 
17893a40ed3dSBarry Smith   PetscFunctionBegin;
17907fb60732SBarry Smith   if (reuse == MAT_REUSE_MATRIX) PetscCall(MatTransposeCheckNonzeroState_Private(A, *matout));
17916536e3caSStefano Zampini   if (reuse == MAT_INPLACE_MATRIX) {
17926536e3caSStefano Zampini     if (m == n) { /* in place transpose */
17939566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(A, &v));
1794d3e5ee88SLois Curfman McInnes       for (j = 0; j < m; j++) {
1795289bc588SBarry Smith         for (k = 0; k < j; k++) {
17961b807ce4Svictorle           tmp          = v[j + k * M];
17971b807ce4Svictorle           v[j + k * M] = v[k + j * M];
17981b807ce4Svictorle           v[k + j * M] = tmp;
1799289bc588SBarry Smith         }
1800289bc588SBarry Smith       }
18019566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArray(A, &v));
18026536e3caSStefano Zampini     } else { /* reuse memory, temporary allocates new memory */
18036536e3caSStefano Zampini       PetscScalar *v2;
18046536e3caSStefano Zampini       PetscLayout  tmplayout;
18056536e3caSStefano Zampini 
18069566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1((size_t)m * n, &v2));
18079566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(A, &v));
18086536e3caSStefano Zampini       for (j = 0; j < n; j++) {
18096536e3caSStefano Zampini         for (k = 0; k < m; k++) v2[j + (size_t)k * n] = v[k + (size_t)j * M];
18106536e3caSStefano Zampini       }
18119566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(v, v2, (size_t)m * n));
18129566063dSJacob Faibussowitsch       PetscCall(PetscFree(v2));
18139566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArray(A, &v));
18146536e3caSStefano Zampini       /* cleanup size dependent quantities */
18159566063dSJacob Faibussowitsch       PetscCall(VecDestroy(&mat->cvec));
18169566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&mat->cmat));
18179566063dSJacob Faibussowitsch       PetscCall(PetscFree(mat->pivots));
18189566063dSJacob Faibussowitsch       PetscCall(PetscFree(mat->fwork));
18196536e3caSStefano Zampini       /* swap row/col layouts */
18206497c311SBarry Smith       PetscCall(PetscBLASIntCast(n, &mat->lda));
18216536e3caSStefano Zampini       tmplayout = A->rmap;
18226536e3caSStefano Zampini       A->rmap   = A->cmap;
18236536e3caSStefano Zampini       A->cmap   = tmplayout;
18246536e3caSStefano Zampini     }
18253a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1826d3e5ee88SLois Curfman McInnes     Mat           tmat;
1827ec8511deSBarry Smith     Mat_SeqDense *tmatd;
182887828ca2SBarry Smith     PetscScalar  *v2;
1829af36a384SStefano Zampini     PetscInt      M2;
1830ea709b57SSatish Balay 
18316536e3caSStefano Zampini     if (reuse == MAT_INITIAL_MATRIX) {
18329566063dSJacob Faibussowitsch       PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &tmat));
18339566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(tmat, A->cmap->n, A->rmap->n, A->cmap->n, A->rmap->n));
18349566063dSJacob Faibussowitsch       PetscCall(MatSetType(tmat, ((PetscObject)A)->type_name));
18359566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSetPreallocation(tmat, NULL));
1836ca15aa20SStefano Zampini     } else tmat = *matout;
1837ca15aa20SStefano Zampini 
18389566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&v));
18399566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArray(tmat, &v2));
1840ec8511deSBarry Smith     tmatd = (Mat_SeqDense *)tmat->data;
1841ca15aa20SStefano Zampini     M2    = tmatd->lda;
1842d3e5ee88SLois Curfman McInnes     for (j = 0; j < n; j++) {
1843af36a384SStefano Zampini       for (k = 0; k < m; k++) v2[j + k * M2] = v[k + j * M];
1844d3e5ee88SLois Curfman McInnes     }
18459566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(tmat, &v2));
18469566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&v));
18479566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(tmat, MAT_FINAL_ASSEMBLY));
18489566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(tmat, MAT_FINAL_ASSEMBLY));
18496536e3caSStefano Zampini     *matout = tmat;
185048b35521SBarry Smith   }
18513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1852289bc588SBarry Smith }
1853289bc588SBarry Smith 
MatEqual_SeqDense(Mat A1,Mat A2,PetscBool * flg)1854d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatEqual_SeqDense(Mat A1, Mat A2, PetscBool *flg)
1855d71ae5a4SJacob Faibussowitsch {
1856c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat1 = (Mat_SeqDense *)A1->data;
1857c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat2 = (Mat_SeqDense *)A2->data;
1858ca15aa20SStefano Zampini   PetscInt           i;
1859ca15aa20SStefano Zampini   const PetscScalar *v1, *v2;
18609ea5d5aeSSatish Balay 
18613a40ed3dSBarry Smith   PetscFunctionBegin;
18629371c9d4SSatish Balay   if (A1->rmap->n != A2->rmap->n) {
18639371c9d4SSatish Balay     *flg = PETSC_FALSE;
18643ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
18659371c9d4SSatish Balay   }
18669371c9d4SSatish Balay   if (A1->cmap->n != A2->cmap->n) {
18679371c9d4SSatish Balay     *flg = PETSC_FALSE;
18683ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
18699371c9d4SSatish Balay   }
18709566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A1, &v1));
18719566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A2, &v2));
1872ca15aa20SStefano Zampini   for (i = 0; i < A1->cmap->n; i++) {
18739566063dSJacob Faibussowitsch     PetscCall(PetscArraycmp(v1, v2, A1->rmap->n, flg));
18743ba16761SJacob Faibussowitsch     if (*flg == PETSC_FALSE) PetscFunctionReturn(PETSC_SUCCESS);
1875ca15aa20SStefano Zampini     v1 += mat1->lda;
1876ca15aa20SStefano Zampini     v2 += mat2->lda;
18771b807ce4Svictorle   }
18789566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A1, &v1));
18799566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A2, &v2));
188077c4ece6SBarry Smith   *flg = PETSC_TRUE;
18813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1882289bc588SBarry Smith }
1883289bc588SBarry Smith 
MatGetDiagonal_SeqDense(Mat A,Vec v)188414277c92SJacob Faibussowitsch PetscErrorCode MatGetDiagonal_SeqDense(Mat A, Vec v)
1885d71ae5a4SJacob Faibussowitsch {
1886c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
188713f74950SBarry Smith   PetscInt           i, n, len;
1888ca15aa20SStefano Zampini   PetscScalar       *x;
1889ca15aa20SStefano Zampini   const PetscScalar *vv;
189044cd7ae7SLois Curfman McInnes 
18913a40ed3dSBarry Smith   PetscFunctionBegin;
18929566063dSJacob Faibussowitsch   PetscCall(VecGetSize(v, &n));
18939566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
1894d0f46423SBarry Smith   len = PetscMin(A->rmap->n, A->cmap->n);
18959566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &vv));
189608401ef6SPierre Jolivet   PetscCheck(n == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming mat and vec");
1897ad540459SPierre Jolivet   for (i = 0; i < len; i++) x[i] = vv[i * mat->lda + i];
18989566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &vv));
18999566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
19003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1901289bc588SBarry Smith }
1902289bc588SBarry Smith 
MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr)1903d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDiagonalScale_SeqDense(Mat A, Vec ll, Vec rr)
1904d71ae5a4SJacob Faibussowitsch {
1905c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense *)A->data;
1906f1ceaac6SMatthew G. Knepley   const PetscScalar *l, *r;
1907ca15aa20SStefano Zampini   PetscScalar        x, *v, *vv;
1908d0f46423SBarry Smith   PetscInt           i, j, m = A->rmap->n, n = A->cmap->n;
190955659b69SBarry Smith 
19103a40ed3dSBarry Smith   PetscFunctionBegin;
19119566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &vv));
191228988994SBarry Smith   if (ll) {
19139566063dSJacob Faibussowitsch     PetscCall(VecGetSize(ll, &m));
19149566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ll, &l));
191508401ef6SPierre Jolivet     PetscCheck(m == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Left scaling vec wrong size");
1916da3a660dSBarry Smith     for (i = 0; i < m; i++) {
1917da3a660dSBarry Smith       x = l[i];
1918ca15aa20SStefano Zampini       v = vv + i;
19199371c9d4SSatish Balay       for (j = 0; j < n; j++) {
19209371c9d4SSatish Balay         (*v) *= x;
19219371c9d4SSatish Balay         v += mat->lda;
19229371c9d4SSatish Balay       }
1923da3a660dSBarry Smith     }
19249566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ll, &l));
19259566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0 * n * m));
1926da3a660dSBarry Smith   }
192728988994SBarry Smith   if (rr) {
19289566063dSJacob Faibussowitsch     PetscCall(VecGetSize(rr, &n));
19299566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(rr, &r));
193008401ef6SPierre Jolivet     PetscCheck(n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Right scaling vec wrong size");
1931da3a660dSBarry Smith     for (i = 0; i < n; i++) {
1932da3a660dSBarry Smith       x = r[i];
1933ca15aa20SStefano Zampini       v = vv + i * mat->lda;
19342205254eSKarl Rupp       for (j = 0; j < m; j++) (*v++) *= x;
1935da3a660dSBarry Smith     }
19369566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(rr, &r));
19379566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0 * n * m));
1938da3a660dSBarry Smith   }
19399566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &vv));
19403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1941289bc588SBarry Smith }
1942289bc588SBarry Smith 
MatNorm_SeqDense(Mat A,NormType type,PetscReal * nrm)1943d71ae5a4SJacob Faibussowitsch PetscErrorCode MatNorm_SeqDense(Mat A, NormType type, PetscReal *nrm)
1944d71ae5a4SJacob Faibussowitsch {
1945c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
1946ca15aa20SStefano Zampini   PetscScalar  *v, *vv;
1947329f5518SBarry Smith   PetscReal     sum = 0.0;
194875f6d85dSStefano Zampini   PetscInt      lda, m = A->rmap->n, i, j;
194955659b69SBarry Smith 
19503a40ed3dSBarry Smith   PetscFunctionBegin;
19519566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&vv));
19529566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(A, &lda));
1953ca15aa20SStefano Zampini   v = vv;
1954289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1955a5ce6ee0Svictorle     if (lda > m) {
1956d0f46423SBarry Smith       for (j = 0; j < A->cmap->n; j++) {
1957ca15aa20SStefano Zampini         v = vv + j * lda;
1958a5ce6ee0Svictorle         for (i = 0; i < m; i++) {
19599371c9d4SSatish Balay           sum += PetscRealPart(PetscConj(*v) * (*v));
19609371c9d4SSatish Balay           v++;
1961a5ce6ee0Svictorle         }
1962a5ce6ee0Svictorle       }
1963a5ce6ee0Svictorle     } else {
1964570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1965570b7f6dSBarry Smith       PetscBLASInt one = 1, cnt = A->cmap->n * A->rmap->n;
1966792fecdfSBarry Smith       PetscCallBLAS("BLASnrm2", *nrm = BLASnrm2_(&cnt, v, &one));
1967570b7f6dSBarry Smith     }
1968570b7f6dSBarry Smith #else
1969d0f46423SBarry Smith       for (i = 0; i < A->cmap->n * A->rmap->n; i++) {
19709371c9d4SSatish Balay         sum += PetscRealPart(PetscConj(*v) * (*v));
19719371c9d4SSatish Balay         v++;
1972289bc588SBarry Smith       }
1973a5ce6ee0Svictorle     }
19748f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1975570b7f6dSBarry Smith #endif
19769566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0 * A->cmap->n * A->rmap->n));
19773a40ed3dSBarry Smith   } else if (type == NORM_1) {
1978064f8208SBarry Smith     *nrm = 0.0;
1979d0f46423SBarry Smith     for (j = 0; j < A->cmap->n; j++) {
1980ca15aa20SStefano Zampini       v   = vv + j * mat->lda;
1981289bc588SBarry Smith       sum = 0.0;
1982d0f46423SBarry Smith       for (i = 0; i < A->rmap->n; i++) {
19839371c9d4SSatish Balay         sum += PetscAbsScalar(*v);
19849371c9d4SSatish Balay         v++;
1985289bc588SBarry Smith       }
1986064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1987289bc588SBarry Smith     }
19889566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n));
19893a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1990064f8208SBarry Smith     *nrm = 0.0;
1991d0f46423SBarry Smith     for (j = 0; j < A->rmap->n; j++) {
1992ca15aa20SStefano Zampini       v   = vv + j;
1993289bc588SBarry Smith       sum = 0.0;
1994d0f46423SBarry Smith       for (i = 0; i < A->cmap->n; i++) {
19959371c9d4SSatish Balay         sum += PetscAbsScalar(*v);
19969371c9d4SSatish Balay         v += mat->lda;
1997289bc588SBarry Smith       }
1998064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1999289bc588SBarry Smith     }
20009566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n));
2001e7e72b3dSBarry Smith   } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "No two norm");
20029566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&vv));
20033ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2004289bc588SBarry Smith }
2005289bc588SBarry Smith 
MatSetOption_SeqDense(Mat A,MatOption op,PetscBool flg)2006d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetOption_SeqDense(Mat A, MatOption op, PetscBool flg)
2007d71ae5a4SJacob Faibussowitsch {
2008c0bbcb79SLois Curfman McInnes   Mat_SeqDense *aij = (Mat_SeqDense *)A->data;
200967e560aaSBarry Smith 
20103a40ed3dSBarry Smith   PetscFunctionBegin;
2011b5a2b587SKris Buschelman   switch (op) {
2012d71ae5a4SJacob Faibussowitsch   case MAT_ROW_ORIENTED:
2013d71ae5a4SJacob Faibussowitsch     aij->roworiented = flg;
2014d71ae5a4SJacob Faibussowitsch     break;
2015d71ae5a4SJacob Faibussowitsch   default:
2016888c827cSStefano Zampini     break;
20173a40ed3dSBarry Smith   }
20183ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2019289bc588SBarry Smith }
2020289bc588SBarry Smith 
MatZeroEntries_SeqDense(Mat A)2021d71ae5a4SJacob Faibussowitsch PetscErrorCode MatZeroEntries_SeqDense(Mat A)
2022d71ae5a4SJacob Faibussowitsch {
2023ec8511deSBarry Smith   Mat_SeqDense *l   = (Mat_SeqDense *)A->data;
20243d8925e7SStefano Zampini   PetscInt      lda = l->lda, m = A->rmap->n, n = A->cmap->n, j;
2025ca15aa20SStefano Zampini   PetscScalar  *v;
20263a40ed3dSBarry Smith 
20273a40ed3dSBarry Smith   PetscFunctionBegin;
20289566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(A, &v));
2029a5ce6ee0Svictorle   if (lda > m) {
203048a46eb9SPierre Jolivet     for (j = 0; j < n; j++) PetscCall(PetscArrayzero(v + j * lda, m));
2031a5ce6ee0Svictorle   } else {
20329566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(v, PetscInt64Mult(m, n)));
2033a5ce6ee0Svictorle   }
20349566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(A, &v));
20353ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20366f0a148fSBarry Smith }
20376f0a148fSBarry Smith 
MatZeroRows_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)2038d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatZeroRows_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b)
2039d71ae5a4SJacob Faibussowitsch {
2040ec8511deSBarry Smith   Mat_SeqDense      *l = (Mat_SeqDense *)A->data;
2041b9679d65SBarry Smith   PetscInt           m = l->lda, n = A->cmap->n, i, j;
2042ca15aa20SStefano Zampini   PetscScalar       *slot, *bb, *v;
204397b48c8fSBarry Smith   const PetscScalar *xx;
204455659b69SBarry Smith 
20453a40ed3dSBarry Smith   PetscFunctionBegin;
204676bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
2047b9679d65SBarry Smith     for (i = 0; i < N; i++) {
204808401ef6SPierre Jolivet       PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed");
204908401ef6SPierre 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);
2050b9679d65SBarry Smith     }
205176bd3646SJed Brown   }
20523ba16761SJacob Faibussowitsch   if (!N) PetscFunctionReturn(PETSC_SUCCESS);
2053b9679d65SBarry Smith 
2054dd8e379bSPierre Jolivet   /* fix right-hand side if needed */
205597b48c8fSBarry Smith   if (x && b) {
20569566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(x, &xx));
20579566063dSJacob Faibussowitsch     PetscCall(VecGetArray(b, &bb));
20582205254eSKarl Rupp     for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]];
20599566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(x, &xx));
20609566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(b, &bb));
206197b48c8fSBarry Smith   }
206297b48c8fSBarry Smith 
20639566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
20646f0a148fSBarry Smith   for (i = 0; i < N; i++) {
2065ca15aa20SStefano Zampini     slot = v + rows[i];
20669371c9d4SSatish Balay     for (j = 0; j < n; j++) {
20679371c9d4SSatish Balay       *slot = 0.0;
20689371c9d4SSatish Balay       slot += m;
20699371c9d4SSatish Balay     }
20706f0a148fSBarry Smith   }
2071f4df32b1SMatthew Knepley   if (diag != 0.0) {
207208401ef6SPierre Jolivet     PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices");
20736f0a148fSBarry Smith     for (i = 0; i < N; i++) {
2074ca15aa20SStefano Zampini       slot  = v + (m + 1) * rows[i];
2075f4df32b1SMatthew Knepley       *slot = diag;
20766f0a148fSBarry Smith     }
20776f0a148fSBarry Smith   }
20789566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
20793ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
20806f0a148fSBarry Smith }
2081557bce09SLois Curfman McInnes 
MatDenseGetLDA_SeqDense(Mat A,PetscInt * lda)2082d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A, PetscInt *lda)
2083d71ae5a4SJacob Faibussowitsch {
208449a6ff4bSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
208549a6ff4bSBarry Smith 
208649a6ff4bSBarry Smith   PetscFunctionBegin;
208749a6ff4bSBarry Smith   *lda = mat->lda;
20883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
208949a6ff4bSBarry Smith }
209049a6ff4bSBarry Smith 
MatDenseGetArray_SeqDense(Mat A,PetscScalar ** array)2091d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArray_SeqDense(Mat A, PetscScalar **array)
2092d71ae5a4SJacob Faibussowitsch {
2093c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
20943a40ed3dSBarry Smith 
20953a40ed3dSBarry Smith   PetscFunctionBegin;
209628b400f6SJacob Faibussowitsch   PetscCheck(!mat->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
209764e87e97SBarry Smith   *array = mat->v;
20983ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
209964e87e97SBarry Smith }
21000754003eSLois Curfman McInnes 
MatDenseRestoreArray_SeqDense(Mat A,PetscScalar ** array)2101d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A, PetscScalar **array)
2102d71ae5a4SJacob Faibussowitsch {
21033a40ed3dSBarry Smith   PetscFunctionBegin;
210475f6d85dSStefano Zampini   if (array) *array = NULL;
21053ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2106ff14e315SSatish Balay }
21070754003eSLois Curfman McInnes 
21080f74d2c1SSatish Balay /*@
210911a5261eSBarry Smith   MatDenseGetLDA - gets the leading dimension of the array returned from `MatDenseGetArray()`
211049a6ff4bSBarry Smith 
21112ef1f0ffSBarry Smith   Not Collective
211249a6ff4bSBarry Smith 
211349a6ff4bSBarry Smith   Input Parameter:
2114fe59aa6dSJacob Faibussowitsch . A - a `MATDENSE` or `MATDENSECUDA` matrix
211549a6ff4bSBarry Smith 
211649a6ff4bSBarry Smith   Output Parameter:
211749a6ff4bSBarry Smith . lda - the leading dimension
211849a6ff4bSBarry Smith 
211949a6ff4bSBarry Smith   Level: intermediate
212049a6ff4bSBarry Smith 
21211cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseSetLDA()`
212249a6ff4bSBarry Smith @*/
MatDenseGetLDA(Mat A,PetscInt * lda)2123d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetLDA(Mat A, PetscInt *lda)
2124d71ae5a4SJacob Faibussowitsch {
212549a6ff4bSBarry Smith   PetscFunctionBegin;
2126d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
21274f572ea9SToby Isaac   PetscAssertPointer(lda, 2);
212875f6d85dSStefano Zampini   MatCheckPreallocated(A, 1);
2129cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetLDA_C", (Mat, PetscInt *), (A, lda));
21303ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
213149a6ff4bSBarry Smith }
213249a6ff4bSBarry Smith 
21330f74d2c1SSatish Balay /*@
213411a5261eSBarry Smith   MatDenseSetLDA - Sets the leading dimension of the array used by the `MATDENSE` matrix
2135ad16ce7aSStefano Zampini 
21362323109cSBarry Smith   Collective if the matrix layouts have not yet been setup
2137ad16ce7aSStefano Zampini 
2138d8d19677SJose E. Roman   Input Parameters:
2139fe59aa6dSJacob Faibussowitsch + A   - a `MATDENSE` or `MATDENSECUDA` matrix
2140ad16ce7aSStefano Zampini - lda - the leading dimension
2141ad16ce7aSStefano Zampini 
2142ad16ce7aSStefano Zampini   Level: intermediate
2143ad16ce7aSStefano Zampini 
21441cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetLDA()`
2145ad16ce7aSStefano Zampini @*/
MatDenseSetLDA(Mat A,PetscInt lda)2146d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA(Mat A, PetscInt lda)
2147d71ae5a4SJacob Faibussowitsch {
2148ad16ce7aSStefano Zampini   PetscFunctionBegin;
2149ad16ce7aSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2150cac4c232SBarry Smith   PetscTryMethod(A, "MatDenseSetLDA_C", (Mat, PetscInt), (A, lda));
21513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2152ad16ce7aSStefano Zampini }
2153ad16ce7aSStefano Zampini 
2154ad16ce7aSStefano Zampini /*@C
215511a5261eSBarry Smith   MatDenseGetArray - gives read-write access to the array where the data for a `MATDENSE` matrix is stored
215673a71a0fSBarry Smith 
2157c3339decSBarry Smith   Logically Collective
215873a71a0fSBarry Smith 
215973a71a0fSBarry Smith   Input Parameter:
2160fe59aa6dSJacob Faibussowitsch . A - a dense matrix
216173a71a0fSBarry Smith 
216273a71a0fSBarry Smith   Output Parameter:
216373a71a0fSBarry Smith . array - pointer to the data
216473a71a0fSBarry Smith 
216573a71a0fSBarry Smith   Level: intermediate
216673a71a0fSBarry Smith 
21671cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
216873a71a0fSBarry Smith @*/
MatDenseGetArray(Mat A,PetscScalar * array[])2169ce78bad3SBarry Smith PetscErrorCode MatDenseGetArray(Mat A, PetscScalar *array[]) PeNS
2170d71ae5a4SJacob Faibussowitsch {
217173a71a0fSBarry Smith   PetscFunctionBegin;
2172d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
21734f572ea9SToby Isaac   PetscAssertPointer(array, 2);
2174cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array));
21753ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
217673a71a0fSBarry Smith }
217773a71a0fSBarry Smith 
2178dec5eb66SMatthew G Knepley /*@C
217911a5261eSBarry Smith   MatDenseRestoreArray - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArray()`
218073a71a0fSBarry Smith 
2181c3339decSBarry Smith   Logically Collective
21828572280aSBarry Smith 
21838572280aSBarry Smith   Input Parameters:
2184fe59aa6dSJacob Faibussowitsch + A     - a dense matrix
21852ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`)
21868572280aSBarry Smith 
21878572280aSBarry Smith   Level: intermediate
21888572280aSBarry Smith 
21891cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
21908572280aSBarry Smith @*/
MatDenseRestoreArray(Mat A,PetscScalar * array[])2191ce78bad3SBarry Smith PetscErrorCode MatDenseRestoreArray(Mat A, PetscScalar *array[]) PeNS
2192d71ae5a4SJacob Faibussowitsch {
21938572280aSBarry Smith   PetscFunctionBegin;
2194d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
21954f572ea9SToby Isaac   if (array) PetscAssertPointer(array, 2);
2196cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array));
21979566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)A));
219847d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
2199637a0070SStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
2200637a0070SStefano Zampini #endif
22013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22028572280aSBarry Smith }
22038572280aSBarry Smith 
22048572280aSBarry Smith /*@C
220511a5261eSBarry Smith   MatDenseGetArrayRead - gives read-only access to the array where the data for a `MATDENSE` matrix is stored
22068572280aSBarry Smith 
2207fb850c59SBarry Smith   Not Collective
22088572280aSBarry Smith 
22098572280aSBarry Smith   Input Parameter:
2210fe59aa6dSJacob Faibussowitsch . A - a dense matrix
22118572280aSBarry Smith 
22128572280aSBarry Smith   Output Parameter:
22138572280aSBarry Smith . array - pointer to the data
22148572280aSBarry Smith 
22158572280aSBarry Smith   Level: intermediate
22168572280aSBarry Smith 
22171cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
22188572280aSBarry Smith @*/
MatDenseGetArrayRead(Mat A,const PetscScalar * array[])2219ce78bad3SBarry Smith PetscErrorCode MatDenseGetArrayRead(Mat A, const PetscScalar *array[]) PeNS
2220d71ae5a4SJacob Faibussowitsch {
22218572280aSBarry Smith   PetscFunctionBegin;
2222d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
22234f572ea9SToby Isaac   PetscAssertPointer(array, 2);
22245c0db29aSPierre Jolivet   PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array));
22253ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22268572280aSBarry Smith }
22278572280aSBarry Smith 
22288572280aSBarry Smith /*@C
222911a5261eSBarry Smith   MatDenseRestoreArrayRead - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayRead()`
22308572280aSBarry Smith 
2231fb850c59SBarry Smith   Not Collective
223273a71a0fSBarry Smith 
223373a71a0fSBarry Smith   Input Parameters:
2234fe59aa6dSJacob Faibussowitsch + A     - a dense matrix
22352ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`)
223673a71a0fSBarry Smith 
223773a71a0fSBarry Smith   Level: intermediate
223873a71a0fSBarry Smith 
22391cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
224073a71a0fSBarry Smith @*/
MatDenseRestoreArrayRead(Mat A,const PetscScalar * array[])2241ce78bad3SBarry Smith PetscErrorCode MatDenseRestoreArrayRead(Mat A, const PetscScalar *array[]) PeNS
2242d71ae5a4SJacob Faibussowitsch {
224373a71a0fSBarry Smith   PetscFunctionBegin;
2244d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
22454f572ea9SToby Isaac   if (array) PetscAssertPointer(array, 2);
22465c0db29aSPierre Jolivet   PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array));
22473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
224873a71a0fSBarry Smith }
224973a71a0fSBarry Smith 
22506947451fSStefano Zampini /*@C
225111a5261eSBarry Smith   MatDenseGetArrayWrite - gives write-only access to the array where the data for a `MATDENSE` matrix is stored
22526947451fSStefano Zampini 
2253fb850c59SBarry Smith   Not Collective
22546947451fSStefano Zampini 
22556947451fSStefano Zampini   Input Parameter:
2256fe59aa6dSJacob Faibussowitsch . A - a dense matrix
22576947451fSStefano Zampini 
22586947451fSStefano Zampini   Output Parameter:
22596947451fSStefano Zampini . array - pointer to the data
22606947451fSStefano Zampini 
22616947451fSStefano Zampini   Level: intermediate
22626947451fSStefano Zampini 
22631cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`
22646947451fSStefano Zampini @*/
MatDenseGetArrayWrite(Mat A,PetscScalar * array[])2265ce78bad3SBarry Smith PetscErrorCode MatDenseGetArrayWrite(Mat A, PetscScalar *array[]) PeNS
2266d71ae5a4SJacob Faibussowitsch {
22676947451fSStefano Zampini   PetscFunctionBegin;
2268d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
22694f572ea9SToby Isaac   PetscAssertPointer(array, 2);
2270cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array));
22713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22726947451fSStefano Zampini }
22736947451fSStefano Zampini 
22746947451fSStefano Zampini /*@C
227511a5261eSBarry Smith   MatDenseRestoreArrayWrite - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayWrite()`
22766947451fSStefano Zampini 
2277fb850c59SBarry Smith   Not Collective
22786947451fSStefano Zampini 
22796947451fSStefano Zampini   Input Parameters:
2280fe59aa6dSJacob Faibussowitsch + A     - a dense matrix
22812ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`)
22826947451fSStefano Zampini 
22836947451fSStefano Zampini   Level: intermediate
22846947451fSStefano Zampini 
22851cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`
22866947451fSStefano Zampini @*/
MatDenseRestoreArrayWrite(Mat A,PetscScalar * array[])2287ce78bad3SBarry Smith PetscErrorCode MatDenseRestoreArrayWrite(Mat A, PetscScalar *array[]) PeNS
2288d71ae5a4SJacob Faibussowitsch {
22896947451fSStefano Zampini   PetscFunctionBegin;
2290d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
22914f572ea9SToby Isaac   if (array) PetscAssertPointer(array, 2);
2292cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array));
22939566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)A));
229447d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
22956947451fSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
22966947451fSStefano Zampini #endif
22973ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
22986947451fSStefano Zampini }
22996947451fSStefano Zampini 
2300cd3f9d89SJunchao Zhang /*@C
2301cd3f9d89SJunchao Zhang   MatDenseGetArrayAndMemType - gives read-write access to the array where the data for a `MATDENSE` matrix is stored
2302cd3f9d89SJunchao Zhang 
2303cd3f9d89SJunchao Zhang   Logically Collective
2304cd3f9d89SJunchao Zhang 
2305cd3f9d89SJunchao Zhang   Input Parameter:
2306fe59aa6dSJacob Faibussowitsch . A - a dense matrix
2307cd3f9d89SJunchao Zhang 
2308cd3f9d89SJunchao Zhang   Output Parameters:
2309cd3f9d89SJunchao Zhang + array - pointer to the data
2310cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer
2311cd3f9d89SJunchao Zhang 
2312cd3f9d89SJunchao Zhang   Level: intermediate
2313cd3f9d89SJunchao Zhang 
2314fb850c59SBarry Smith   Note:
23152ef1f0ffSBarry Smith   If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc.,
23162ef1f0ffSBarry Smith   an array on device is always returned and is guaranteed to contain the matrix's latest data.
23172ef1f0ffSBarry Smith 
23181cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayAndMemType()`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArrayWriteAndMemType()`, `MatDenseGetArrayRead()`,
2319cd3f9d89SJunchao Zhang    `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()`
2320cd3f9d89SJunchao Zhang @*/
MatDenseGetArrayAndMemType(Mat A,PetscScalar * array[],PetscMemType * mtype)23215d83a8b1SBarry Smith PetscErrorCode MatDenseGetArrayAndMemType(Mat A, PetscScalar *array[], PetscMemType *mtype)
2322cd3f9d89SJunchao Zhang {
2323cd3f9d89SJunchao Zhang   PetscBool isMPI;
2324cd3f9d89SJunchao Zhang 
2325cd3f9d89SJunchao Zhang   PetscFunctionBegin;
2326cd3f9d89SJunchao Zhang   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
23274f572ea9SToby Isaac   PetscAssertPointer(array, 2);
2328e865de01SJunchao 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 */
2329cd3f9d89SJunchao Zhang   PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI));
2330cd3f9d89SJunchao Zhang   if (isMPI) {
2331cd3f9d89SJunchao Zhang     /* Dispatch here so that the code can be reused for all subclasses of MATDENSE */
2332cd3f9d89SJunchao Zhang     PetscCall(MatDenseGetArrayAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype));
2333cd3f9d89SJunchao Zhang   } else {
2334cd3f9d89SJunchao Zhang     PetscErrorCode (*fptr)(Mat, PetscScalar **, PetscMemType *);
23353ba16761SJacob Faibussowitsch 
23363ba16761SJacob Faibussowitsch     PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayAndMemType_C", &fptr));
2337cd3f9d89SJunchao Zhang     if (fptr) {
2338cd3f9d89SJunchao Zhang       PetscCall((*fptr)(A, array, mtype));
2339cd3f9d89SJunchao Zhang     } else {
2340cd3f9d89SJunchao Zhang       PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array));
2341cd3f9d89SJunchao Zhang       if (mtype) *mtype = PETSC_MEMTYPE_HOST;
2342cd3f9d89SJunchao Zhang     }
2343cd3f9d89SJunchao Zhang   }
23443ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2345cd3f9d89SJunchao Zhang }
2346cd3f9d89SJunchao Zhang 
2347cd3f9d89SJunchao Zhang /*@C
2348cd3f9d89SJunchao Zhang   MatDenseRestoreArrayAndMemType - returns access to the array that is obtained by `MatDenseGetArrayAndMemType()`
2349cd3f9d89SJunchao Zhang 
2350cd3f9d89SJunchao Zhang   Logically Collective
2351cd3f9d89SJunchao Zhang 
2352cd3f9d89SJunchao Zhang   Input Parameters:
2353fe59aa6dSJacob Faibussowitsch + A     - a dense matrix
2354cd3f9d89SJunchao Zhang - array - pointer to the data
2355cd3f9d89SJunchao Zhang 
2356cd3f9d89SJunchao Zhang   Level: intermediate
2357cd3f9d89SJunchao Zhang 
23581cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
2359cd3f9d89SJunchao Zhang @*/
MatDenseRestoreArrayAndMemType(Mat A,PetscScalar * array[])23605d83a8b1SBarry Smith PetscErrorCode MatDenseRestoreArrayAndMemType(Mat A, PetscScalar *array[])
2361cd3f9d89SJunchao Zhang {
2362cd3f9d89SJunchao Zhang   PetscBool isMPI;
2363cd3f9d89SJunchao Zhang 
2364cd3f9d89SJunchao Zhang   PetscFunctionBegin;
2365cd3f9d89SJunchao Zhang   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2366fd5c2d83SStefano Zampini   if (array) PetscAssertPointer(array, 2);
2367cd3f9d89SJunchao Zhang   PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI));
2368cd3f9d89SJunchao Zhang   if (isMPI) {
2369cd3f9d89SJunchao Zhang     PetscCall(MatDenseRestoreArrayAndMemType(((Mat_MPIDense *)A->data)->A, array));
2370cd3f9d89SJunchao Zhang   } else {
2371cd3f9d89SJunchao Zhang     PetscErrorCode (*fptr)(Mat, PetscScalar **);
23723ba16761SJacob Faibussowitsch 
23733ba16761SJacob Faibussowitsch     PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayAndMemType_C", &fptr));
2374cd3f9d89SJunchao Zhang     if (fptr) {
2375cd3f9d89SJunchao Zhang       PetscCall((*fptr)(A, array));
2376cd3f9d89SJunchao Zhang     } else {
2377cd3f9d89SJunchao Zhang       PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array));
2378cd3f9d89SJunchao Zhang     }
2379fd5c2d83SStefano Zampini     if (array) *array = NULL;
2380cd3f9d89SJunchao Zhang   }
2381cd3f9d89SJunchao Zhang   PetscCall(PetscObjectStateIncrease((PetscObject)A));
23823ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2383cd3f9d89SJunchao Zhang }
2384cd3f9d89SJunchao Zhang 
2385cd3f9d89SJunchao Zhang /*@C
2386cd3f9d89SJunchao Zhang   MatDenseGetArrayReadAndMemType - gives read-only access to the array where the data for a `MATDENSE` matrix is stored
2387cd3f9d89SJunchao Zhang 
2388cd3f9d89SJunchao Zhang   Logically Collective
2389cd3f9d89SJunchao Zhang 
2390cd3f9d89SJunchao Zhang   Input Parameter:
2391fe59aa6dSJacob Faibussowitsch . A - a dense matrix
2392cd3f9d89SJunchao Zhang 
2393cd3f9d89SJunchao Zhang   Output Parameters:
2394cd3f9d89SJunchao Zhang + array - pointer to the data
2395cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer
2396cd3f9d89SJunchao Zhang 
2397cd3f9d89SJunchao Zhang   Level: intermediate
2398cd3f9d89SJunchao Zhang 
2399fb850c59SBarry Smith   Note:
24002ef1f0ffSBarry Smith   If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc.,
24012ef1f0ffSBarry Smith   an array on device is always returned and is guaranteed to contain the matrix's latest data.
24022ef1f0ffSBarry Smith 
24031cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayReadAndMemType()`, `MatDenseGetArrayWriteAndMemType()`,
2404cd3f9d89SJunchao Zhang    `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()`
2405cd3f9d89SJunchao Zhang @*/
MatDenseGetArrayReadAndMemType(Mat A,const PetscScalar * array[],PetscMemType * mtype)24065d83a8b1SBarry Smith PetscErrorCode MatDenseGetArrayReadAndMemType(Mat A, const PetscScalar *array[], PetscMemType *mtype)
2407cd3f9d89SJunchao Zhang {
2408cd3f9d89SJunchao Zhang   PetscBool isMPI;
2409cd3f9d89SJunchao Zhang 
2410cd3f9d89SJunchao Zhang   PetscFunctionBegin;
2411cd3f9d89SJunchao Zhang   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
24124f572ea9SToby Isaac   PetscAssertPointer(array, 2);
2413e865de01SJunchao 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 */
2414cd3f9d89SJunchao Zhang   PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI));
2415cd3f9d89SJunchao Zhang   if (isMPI) { /* Dispatch here so that the code can be reused for all subclasses of MATDENSE */
2416cd3f9d89SJunchao Zhang     PetscCall(MatDenseGetArrayReadAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype));
2417cd3f9d89SJunchao Zhang   } else {
2418cd3f9d89SJunchao Zhang     PetscErrorCode (*fptr)(Mat, const PetscScalar **, PetscMemType *);
24193ba16761SJacob Faibussowitsch 
24203ba16761SJacob Faibussowitsch     PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayReadAndMemType_C", &fptr));
2421cd3f9d89SJunchao Zhang     if (fptr) {
2422cd3f9d89SJunchao Zhang       PetscCall((*fptr)(A, array, mtype));
2423cd3f9d89SJunchao Zhang     } else {
24245c0db29aSPierre Jolivet       PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array));
2425cd3f9d89SJunchao Zhang       if (mtype) *mtype = PETSC_MEMTYPE_HOST;
2426cd3f9d89SJunchao Zhang     }
2427cd3f9d89SJunchao Zhang   }
24283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2429cd3f9d89SJunchao Zhang }
2430cd3f9d89SJunchao Zhang 
2431cd3f9d89SJunchao Zhang /*@C
2432cd3f9d89SJunchao Zhang   MatDenseRestoreArrayReadAndMemType - returns access to the array that is obtained by `MatDenseGetArrayReadAndMemType()`
2433cd3f9d89SJunchao Zhang 
2434cd3f9d89SJunchao Zhang   Logically Collective
2435cd3f9d89SJunchao Zhang 
2436cd3f9d89SJunchao Zhang   Input Parameters:
2437fe59aa6dSJacob Faibussowitsch + A     - a dense matrix
2438cd3f9d89SJunchao Zhang - array - pointer to the data
2439cd3f9d89SJunchao Zhang 
2440cd3f9d89SJunchao Zhang   Level: intermediate
2441cd3f9d89SJunchao Zhang 
24421cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
2443cd3f9d89SJunchao Zhang @*/
MatDenseRestoreArrayReadAndMemType(Mat A,const PetscScalar * array[])24445d83a8b1SBarry Smith PetscErrorCode MatDenseRestoreArrayReadAndMemType(Mat A, const PetscScalar *array[])
2445cd3f9d89SJunchao Zhang {
2446cd3f9d89SJunchao Zhang   PetscBool isMPI;
2447cd3f9d89SJunchao Zhang 
2448cd3f9d89SJunchao Zhang   PetscFunctionBegin;
2449cd3f9d89SJunchao Zhang   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2450fd5c2d83SStefano Zampini   if (array) PetscAssertPointer(array, 2);
2451cd3f9d89SJunchao Zhang   PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI));
2452cd3f9d89SJunchao Zhang   if (isMPI) {
2453cd3f9d89SJunchao Zhang     PetscCall(MatDenseRestoreArrayReadAndMemType(((Mat_MPIDense *)A->data)->A, array));
2454cd3f9d89SJunchao Zhang   } else {
2455cd3f9d89SJunchao Zhang     PetscErrorCode (*fptr)(Mat, const PetscScalar **);
24563ba16761SJacob Faibussowitsch 
24573ba16761SJacob Faibussowitsch     PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayReadAndMemType_C", &fptr));
2458cd3f9d89SJunchao Zhang     if (fptr) {
2459cd3f9d89SJunchao Zhang       PetscCall((*fptr)(A, array));
2460cd3f9d89SJunchao Zhang     } else {
24615c0db29aSPierre Jolivet       PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array));
2462cd3f9d89SJunchao Zhang     }
2463fd5c2d83SStefano Zampini     if (array) *array = NULL;
2464cd3f9d89SJunchao Zhang   }
24653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2466cd3f9d89SJunchao Zhang }
2467cd3f9d89SJunchao Zhang 
2468cd3f9d89SJunchao Zhang /*@C
2469cd3f9d89SJunchao Zhang   MatDenseGetArrayWriteAndMemType - gives write-only access to the array where the data for a `MATDENSE` matrix is stored
2470cd3f9d89SJunchao Zhang 
2471cd3f9d89SJunchao Zhang   Logically Collective
2472cd3f9d89SJunchao Zhang 
2473cd3f9d89SJunchao Zhang   Input Parameter:
2474fe59aa6dSJacob Faibussowitsch . A - a dense matrix
2475cd3f9d89SJunchao Zhang 
2476cd3f9d89SJunchao Zhang   Output Parameters:
2477cd3f9d89SJunchao Zhang + array - pointer to the data
2478cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer
2479cd3f9d89SJunchao Zhang 
2480cd3f9d89SJunchao Zhang   Level: intermediate
2481cd3f9d89SJunchao Zhang 
2482fb850c59SBarry Smith   Note:
24832ef1f0ffSBarry Smith   If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc.,
24842ef1f0ffSBarry Smith   an array on device is always returned and is guaranteed to contain the matrix's latest data.
24852ef1f0ffSBarry Smith 
24861cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayWriteAndMemType()`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArrayRead()`,
2487cd3f9d89SJunchao Zhang   `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()`
2488cd3f9d89SJunchao Zhang @*/
MatDenseGetArrayWriteAndMemType(Mat A,PetscScalar * array[],PetscMemType * mtype)24895d83a8b1SBarry Smith PetscErrorCode MatDenseGetArrayWriteAndMemType(Mat A, PetscScalar *array[], PetscMemType *mtype)
2490cd3f9d89SJunchao Zhang {
2491cd3f9d89SJunchao Zhang   PetscBool isMPI;
2492cd3f9d89SJunchao Zhang 
2493cd3f9d89SJunchao Zhang   PetscFunctionBegin;
2494cd3f9d89SJunchao Zhang   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
24954f572ea9SToby Isaac   PetscAssertPointer(array, 2);
2496e865de01SJunchao 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 */
2497cd3f9d89SJunchao Zhang   PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI));
2498cd3f9d89SJunchao Zhang   if (isMPI) {
2499cd3f9d89SJunchao Zhang     PetscCall(MatDenseGetArrayWriteAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype));
2500cd3f9d89SJunchao Zhang   } else {
2501cd3f9d89SJunchao Zhang     PetscErrorCode (*fptr)(Mat, PetscScalar **, PetscMemType *);
25023ba16761SJacob Faibussowitsch 
25033ba16761SJacob Faibussowitsch     PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayWriteAndMemType_C", &fptr));
2504cd3f9d89SJunchao Zhang     if (fptr) {
2505cd3f9d89SJunchao Zhang       PetscCall((*fptr)(A, array, mtype));
2506cd3f9d89SJunchao Zhang     } else {
2507cd3f9d89SJunchao Zhang       PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array));
2508cd3f9d89SJunchao Zhang       if (mtype) *mtype = PETSC_MEMTYPE_HOST;
2509cd3f9d89SJunchao Zhang     }
2510cd3f9d89SJunchao Zhang   }
25113ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2512cd3f9d89SJunchao Zhang }
2513cd3f9d89SJunchao Zhang 
2514cd3f9d89SJunchao Zhang /*@C
2515cd3f9d89SJunchao Zhang   MatDenseRestoreArrayWriteAndMemType - returns access to the array that is obtained by `MatDenseGetArrayReadAndMemType()`
2516cd3f9d89SJunchao Zhang 
2517cd3f9d89SJunchao Zhang   Logically Collective
2518cd3f9d89SJunchao Zhang 
2519cd3f9d89SJunchao Zhang   Input Parameters:
2520fe59aa6dSJacob Faibussowitsch + A     - a dense matrix
2521cd3f9d89SJunchao Zhang - array - pointer to the data
2522cd3f9d89SJunchao Zhang 
2523cd3f9d89SJunchao Zhang   Level: intermediate
2524cd3f9d89SJunchao Zhang 
25251cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayWriteAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
2526cd3f9d89SJunchao Zhang @*/
MatDenseRestoreArrayWriteAndMemType(Mat A,PetscScalar * array[])25275d83a8b1SBarry Smith PetscErrorCode MatDenseRestoreArrayWriteAndMemType(Mat A, PetscScalar *array[])
2528cd3f9d89SJunchao Zhang {
2529cd3f9d89SJunchao Zhang   PetscBool isMPI;
2530cd3f9d89SJunchao Zhang 
2531cd3f9d89SJunchao Zhang   PetscFunctionBegin;
2532cd3f9d89SJunchao Zhang   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
2533fd5c2d83SStefano Zampini   if (array) PetscAssertPointer(array, 2);
2534cd3f9d89SJunchao Zhang   PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI));
2535cd3f9d89SJunchao Zhang   if (isMPI) {
2536cd3f9d89SJunchao Zhang     PetscCall(MatDenseRestoreArrayWriteAndMemType(((Mat_MPIDense *)A->data)->A, array));
2537cd3f9d89SJunchao Zhang   } else {
2538cd3f9d89SJunchao Zhang     PetscErrorCode (*fptr)(Mat, PetscScalar **);
25393ba16761SJacob Faibussowitsch 
25403ba16761SJacob Faibussowitsch     PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayWriteAndMemType_C", &fptr));
2541cd3f9d89SJunchao Zhang     if (fptr) {
2542cd3f9d89SJunchao Zhang       PetscCall((*fptr)(A, array));
2543cd3f9d89SJunchao Zhang     } else {
2544cd3f9d89SJunchao Zhang       PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array));
2545cd3f9d89SJunchao Zhang     }
2546fd5c2d83SStefano Zampini     if (array) *array = NULL;
2547cd3f9d89SJunchao Zhang   }
2548cd3f9d89SJunchao Zhang   PetscCall(PetscObjectStateIncrease((PetscObject)A));
25493ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2550cd3f9d89SJunchao Zhang }
2551cd3f9d89SJunchao Zhang 
MatCreateSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,MatReuse scall,Mat * B)2552d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A, IS isrow, IS iscol, MatReuse scall, Mat *B)
2553d71ae5a4SJacob Faibussowitsch {
2554c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense *)A->data;
2555bf5a80bcSToby Isaac   PetscInt        i, j, nrows, ncols, ldb;
25565d0c19d7SBarry Smith   const PetscInt *irow, *icol;
255787828ca2SBarry Smith   PetscScalar    *av, *bv, *v = mat->v;
25580754003eSLois Curfman McInnes   Mat             newmat;
25590754003eSLois Curfman McInnes 
25603a40ed3dSBarry Smith   PetscFunctionBegin;
25619566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(isrow, &irow));
25629566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(iscol, &icol));
25639566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(isrow, &nrows));
25649566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(iscol, &ncols));
25650754003eSLois Curfman McInnes 
2566182d2002SSatish Balay   /* Check submatrixcall */
2567182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
256813f74950SBarry Smith     PetscInt n_cols, n_rows;
25699566063dSJacob Faibussowitsch     PetscCall(MatGetSize(*B, &n_rows, &n_cols));
257021a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
2571f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
25729566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(*B, nrows, ncols, nrows, ncols));
257321a2c019SBarry Smith     }
2574182d2002SSatish Balay     newmat = *B;
2575182d2002SSatish Balay   } else {
25760754003eSLois Curfman McInnes     /* Create and fill new matrix */
25779566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &newmat));
25789566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(newmat, nrows, ncols, nrows, ncols));
25799566063dSJacob Faibussowitsch     PetscCall(MatSetType(newmat, ((PetscObject)A)->type_name));
25809566063dSJacob Faibussowitsch     PetscCall(MatSeqDenseSetPreallocation(newmat, NULL));
2581182d2002SSatish Balay   }
2582182d2002SSatish Balay 
2583182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
25849566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(newmat, &bv));
25859566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(newmat, &ldb));
2586182d2002SSatish Balay   for (i = 0; i < ncols; i++) {
25876de62eeeSBarry Smith     av = v + mat->lda * icol[i];
2588ca15aa20SStefano Zampini     for (j = 0; j < nrows; j++) bv[j] = av[irow[j]];
2589bf5a80bcSToby Isaac     bv += ldb;
25900754003eSLois Curfman McInnes   }
25919566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(newmat, &bv));
2592182d2002SSatish Balay 
2593182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
25949566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(newmat, MAT_FINAL_ASSEMBLY));
25959566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(newmat, MAT_FINAL_ASSEMBLY));
25960754003eSLois Curfman McInnes 
25970754003eSLois Curfman McInnes   /* Free work space */
25989566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(isrow, &irow));
25999566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(iscol, &icol));
2600182d2002SSatish Balay   *B = newmat;
26013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
26020754003eSLois Curfman McInnes }
26030754003eSLois Curfman McInnes 
MatCreateSubMatrices_SeqDense(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat * B[])2604d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A, PetscInt n, const IS irow[], const IS icol[], MatReuse scall, Mat *B[])
2605d71ae5a4SJacob Faibussowitsch {
260613f74950SBarry Smith   PetscInt i;
2607905e6a2fSBarry Smith 
26083a40ed3dSBarry Smith   PetscFunctionBegin;
260948a46eb9SPierre Jolivet   if (scall == MAT_INITIAL_MATRIX) PetscCall(PetscCalloc1(n, B));
2610905e6a2fSBarry Smith 
261148a46eb9SPierre Jolivet   for (i = 0; i < n; i++) PetscCall(MatCreateSubMatrix_SeqDense(A, irow[i], icol[i], scall, &(*B)[i]));
26123ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2613905e6a2fSBarry Smith }
2614905e6a2fSBarry Smith 
MatCopy_SeqDense(Mat A,Mat B,MatStructure str)2615d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCopy_SeqDense(Mat A, Mat B, MatStructure str)
2616d71ae5a4SJacob Faibussowitsch {
26174b0e389bSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data;
2618ca15aa20SStefano Zampini   const PetscScalar *va;
2619ca15aa20SStefano Zampini   PetscScalar       *vb;
2620d0f46423SBarry Smith   PetscInt           lda1 = a->lda, lda2 = b->lda, m = A->rmap->n, n = A->cmap->n, j;
26213a40ed3dSBarry Smith 
26223a40ed3dSBarry Smith   PetscFunctionBegin;
262333f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
262433f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
26259566063dSJacob Faibussowitsch     PetscCall(MatCopy_Basic(A, B, str));
26263ba16761SJacob Faibussowitsch     PetscFunctionReturn(PETSC_SUCCESS);
26273a40ed3dSBarry Smith   }
2628aed4548fSBarry Smith   PetscCheck(m == B->rmap->n && n == B->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "size(B) != size(A)");
26299566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &va));
26309566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(B, &vb));
2631a5ce6ee0Svictorle   if (lda1 > m || lda2 > m) {
263248a46eb9SPierre Jolivet     for (j = 0; j < n; j++) PetscCall(PetscArraycpy(vb + j * lda2, va + j * lda1, m));
2633a5ce6ee0Svictorle   } else {
26349566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(vb, va, A->rmap->n * A->cmap->n));
2635a5ce6ee0Svictorle   }
26369566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(B, &vb));
26379566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &va));
26389566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY));
26399566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY));
26403ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2641273d9f13SBarry Smith }
2642273d9f13SBarry Smith 
MatSetUp_SeqDense(Mat A)2643d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetUp_SeqDense(Mat A)
2644d71ae5a4SJacob Faibussowitsch {
2645273d9f13SBarry Smith   PetscFunctionBegin;
26469566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(A->rmap));
26479566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(A->cmap));
264848a46eb9SPierre Jolivet   if (!A->preallocated) PetscCall(MatSeqDenseSetPreallocation(A, NULL));
26493ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
26504b0e389bSBarry Smith }
26514b0e389bSBarry Smith 
MatConjugate_SeqDense(Mat A)26523853def2SToby Isaac PetscErrorCode MatConjugate_SeqDense(Mat A)
2653d71ae5a4SJacob Faibussowitsch {
26544396437dSToby Isaac   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
265506c5243aSJose E. Roman   PetscInt      i, j;
26564396437dSToby Isaac   PetscInt      min = PetscMin(A->rmap->n, A->cmap->n);
2657ca15aa20SStefano Zampini   PetscScalar  *aa;
2658ba337c44SJed Brown 
2659ba337c44SJed Brown   PetscFunctionBegin;
26609566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &aa));
2661*65d0d443SPierre Jolivet   for (j = 0; j < A->cmap->n; j++)
266206c5243aSJose E. Roman     for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscConj(aa[i + j * mat->lda]);
26639566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &aa));
26649371c9d4SSatish Balay   if (mat->tau)
26659371c9d4SSatish Balay     for (i = 0; i < min; i++) mat->tau[i] = PetscConj(mat->tau[i]);
26663ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2667ba337c44SJed Brown }
2668ba337c44SJed Brown 
MatRealPart_SeqDense(Mat A)2669d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRealPart_SeqDense(Mat A)
2670d71ae5a4SJacob Faibussowitsch {
267106c5243aSJose E. Roman   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
267206c5243aSJose E. Roman   PetscInt      i, j;
2673ca15aa20SStefano Zampini   PetscScalar  *aa;
2674ba337c44SJed Brown 
2675ba337c44SJed Brown   PetscFunctionBegin;
26769566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &aa));
267706c5243aSJose E. Roman   for (j = 0; j < A->cmap->n; j++) {
267806c5243aSJose E. Roman     for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscRealPart(aa[i + j * mat->lda]);
267906c5243aSJose E. Roman   }
26809566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &aa));
26813ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2682ba337c44SJed Brown }
2683ba337c44SJed Brown 
MatImaginaryPart_SeqDense(Mat A)2684d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatImaginaryPart_SeqDense(Mat A)
2685d71ae5a4SJacob Faibussowitsch {
268606c5243aSJose E. Roman   Mat_SeqDense *mat = (Mat_SeqDense *)A->data;
268706c5243aSJose E. Roman   PetscInt      i, j;
2688ca15aa20SStefano Zampini   PetscScalar  *aa;
2689ba337c44SJed Brown 
2690ba337c44SJed Brown   PetscFunctionBegin;
26919566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &aa));
269206c5243aSJose E. Roman   for (j = 0; j < A->cmap->n; j++) {
269306c5243aSJose E. Roman     for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscImaginaryPart(aa[i + j * mat->lda]);
269406c5243aSJose E. Roman   }
26959566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &aa));
26963ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2697ba337c44SJed Brown }
2698284134d9SBarry Smith 
MatMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)2699d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C)
2700d71ae5a4SJacob Faibussowitsch {
2701d0f46423SBarry Smith   PetscInt  m = A->rmap->n, n = B->cmap->n;
270247d993e7Ssuyashtn   PetscBool cisdense = PETSC_FALSE;
2703a9fe9ddaSSatish Balay 
2704ee16a9a1SHong Zhang   PetscFunctionBegin;
27059566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C, m, n, m, n));
270647d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA)
27079566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, ""));
270847d993e7Ssuyashtn #endif
270947d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP)
271047d993e7Ssuyashtn   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, ""));
271147d993e7Ssuyashtn #endif
27127a3c3d58SStefano Zampini   if (!cisdense) {
27137a3c3d58SStefano Zampini     PetscBool flg;
27147a3c3d58SStefano Zampini 
27159566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg));
27169566063dSJacob Faibussowitsch     PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE));
27177a3c3d58SStefano Zampini   }
27189566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
27193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2720ee16a9a1SHong Zhang }
2721a9fe9ddaSSatish Balay 
MatMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)2722d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C)
2723d71ae5a4SJacob Faibussowitsch {
27246718818eSStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data, *c = (Mat_SeqDense *)C->data;
27250805154bSBarry Smith   PetscBLASInt       m, n, k;
2726ca15aa20SStefano Zampini   const PetscScalar *av, *bv;
2727ca15aa20SStefano Zampini   PetscScalar       *cv;
2728a9fe9ddaSSatish Balay   PetscScalar        _DOne = 1.0, _DZero = 0.0;
2729a9fe9ddaSSatish Balay 
2730a9fe9ddaSSatish Balay   PetscFunctionBegin;
27319566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n, &m));
27329566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n, &n));
27339566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &k));
27343ba16761SJacob Faibussowitsch   if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS);
27359566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &av));
27369566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B, &bv));
27379566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C, &cv));
2738792fecdfSBarry Smith   PetscCallBLAS("BLASgemm", BLASgemm_("N", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda));
27399566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1)));
27409566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &av));
27419566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B, &bv));
27429566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C, &cv));
27433ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2744a9fe9ddaSSatish Balay }
2745a9fe9ddaSSatish Balay 
MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)2746d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C)
2747d71ae5a4SJacob Faibussowitsch {
274869f65d41SStefano Zampini   PetscInt  m = A->rmap->n, n = B->rmap->n;
274947d993e7Ssuyashtn   PetscBool cisdense = PETSC_FALSE;
275069f65d41SStefano Zampini 
275169f65d41SStefano Zampini   PetscFunctionBegin;
27529566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C, m, n, m, n));
275347d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA)
27549566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, ""));
275547d993e7Ssuyashtn #endif
275647d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP)
275747d993e7Ssuyashtn   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, ""));
275847d993e7Ssuyashtn #endif
27597a3c3d58SStefano Zampini   if (!cisdense) {
27607a3c3d58SStefano Zampini     PetscBool flg;
27617a3c3d58SStefano Zampini 
27629566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg));
27639566063dSJacob Faibussowitsch     PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE));
27647a3c3d58SStefano Zampini   }
27659566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
27663ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
276769f65d41SStefano Zampini }
276869f65d41SStefano Zampini 
MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)2769d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C)
2770d71ae5a4SJacob Faibussowitsch {
277169f65d41SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
277269f65d41SStefano Zampini   Mat_SeqDense      *b = (Mat_SeqDense *)B->data;
277369f65d41SStefano Zampini   Mat_SeqDense      *c = (Mat_SeqDense *)C->data;
27746718818eSStefano Zampini   const PetscScalar *av, *bv;
27756718818eSStefano Zampini   PetscScalar       *cv;
277669f65d41SStefano Zampini   PetscBLASInt       m, n, k;
277769f65d41SStefano Zampini   PetscScalar        _DOne = 1.0, _DZero = 0.0;
277869f65d41SStefano Zampini 
277969f65d41SStefano Zampini   PetscFunctionBegin;
27809566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n, &m));
27819566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n, &n));
27829566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n, &k));
27833ba16761SJacob Faibussowitsch   if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS);
27849566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &av));
27859566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B, &bv));
27869566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C, &cv));
2787792fecdfSBarry Smith   PetscCallBLAS("BLASgemm", BLASgemm_("N", "T", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda));
27889566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &av));
27899566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B, &bv));
27909566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C, &cv));
27919566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1)));
27923ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
279369f65d41SStefano Zampini }
279469f65d41SStefano Zampini 
MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)2795d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C)
2796d71ae5a4SJacob Faibussowitsch {
2797d0f46423SBarry Smith   PetscInt  m = A->cmap->n, n = B->cmap->n;
279847d993e7Ssuyashtn   PetscBool cisdense = PETSC_FALSE;
2799a9fe9ddaSSatish Balay 
2800ee16a9a1SHong Zhang   PetscFunctionBegin;
28019566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C, m, n, m, n));
280247d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA)
28039566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, ""));
280447d993e7Ssuyashtn #endif
280547d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP)
280647d993e7Ssuyashtn   PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, ""));
280747d993e7Ssuyashtn #endif
28087a3c3d58SStefano Zampini   if (!cisdense) {
28097a3c3d58SStefano Zampini     PetscBool flg;
28107a3c3d58SStefano Zampini 
28119566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg));
28129566063dSJacob Faibussowitsch     PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE));
28137a3c3d58SStefano Zampini   }
28149566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
28153ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2816ee16a9a1SHong Zhang }
2817a9fe9ddaSSatish Balay 
MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)2818d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C)
2819d71ae5a4SJacob Faibussowitsch {
2820a9fe9ddaSSatish Balay   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
2821a9fe9ddaSSatish Balay   Mat_SeqDense      *b = (Mat_SeqDense *)B->data;
2822a9fe9ddaSSatish Balay   Mat_SeqDense      *c = (Mat_SeqDense *)C->data;
28236718818eSStefano Zampini   const PetscScalar *av, *bv;
28246718818eSStefano Zampini   PetscScalar       *cv;
28250805154bSBarry Smith   PetscBLASInt       m, n, k;
2826a9fe9ddaSSatish Balay   PetscScalar        _DOne = 1.0, _DZero = 0.0;
2827a9fe9ddaSSatish Balay 
2828a9fe9ddaSSatish Balay   PetscFunctionBegin;
28299566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n, &m));
28309566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n, &n));
28319566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n, &k));
28323ba16761SJacob Faibussowitsch   if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS);
28339566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &av));
28349566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B, &bv));
28359566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C, &cv));
2836792fecdfSBarry Smith   PetscCallBLAS("BLASgemm", BLASgemm_("T", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda));
28379566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &av));
28389566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B, &bv));
28399566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C, &cv));
28409566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1)));
28413ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2842a9fe9ddaSSatish Balay }
2843985db425SBarry Smith 
MatProductSetFromOptions_SeqDense_AB(Mat C)2844d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C)
2845d71ae5a4SJacob Faibussowitsch {
28464222ddf1SHong Zhang   PetscFunctionBegin;
28474222ddf1SHong Zhang   C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense;
28484222ddf1SHong Zhang   C->ops->productsymbolic = MatProductSymbolic_AB;
28493ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
28504222ddf1SHong Zhang }
28514222ddf1SHong Zhang 
MatProductSetFromOptions_SeqDense_AtB(Mat C)2852d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C)
2853d71ae5a4SJacob Faibussowitsch {
28544222ddf1SHong Zhang   PetscFunctionBegin;
28554222ddf1SHong Zhang   C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense;
28564222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_AtB;
28573ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
28584222ddf1SHong Zhang }
28594222ddf1SHong Zhang 
MatProductSetFromOptions_SeqDense_ABt(Mat C)2860d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C)
2861d71ae5a4SJacob Faibussowitsch {
28624222ddf1SHong Zhang   PetscFunctionBegin;
28634222ddf1SHong Zhang   C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense;
28644222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_ABt;
28653ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
28664222ddf1SHong Zhang }
28674222ddf1SHong Zhang 
MatProductSetFromOptions_SeqDense(Mat C)2868d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C)
2869d71ae5a4SJacob Faibussowitsch {
28704222ddf1SHong Zhang   Mat_Product *product = C->product;
28714222ddf1SHong Zhang 
28724222ddf1SHong Zhang   PetscFunctionBegin;
28734222ddf1SHong Zhang   switch (product->type) {
2874d71ae5a4SJacob Faibussowitsch   case MATPRODUCT_AB:
2875d71ae5a4SJacob Faibussowitsch     PetscCall(MatProductSetFromOptions_SeqDense_AB(C));
2876d71ae5a4SJacob Faibussowitsch     break;
2877d71ae5a4SJacob Faibussowitsch   case MATPRODUCT_AtB:
2878d71ae5a4SJacob Faibussowitsch     PetscCall(MatProductSetFromOptions_SeqDense_AtB(C));
2879d71ae5a4SJacob Faibussowitsch     break;
2880d71ae5a4SJacob Faibussowitsch   case MATPRODUCT_ABt:
2881d71ae5a4SJacob Faibussowitsch     PetscCall(MatProductSetFromOptions_SeqDense_ABt(C));
2882d71ae5a4SJacob Faibussowitsch     break;
2883d71ae5a4SJacob Faibussowitsch   default:
2884d71ae5a4SJacob Faibussowitsch     break;
28854222ddf1SHong Zhang   }
28863ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
28874222ddf1SHong Zhang }
28884222ddf1SHong Zhang 
MatGetRowMax_SeqDense(Mat A,Vec v,PetscInt idx[])2889d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMax_SeqDense(Mat A, Vec v, PetscInt idx[])
2890d71ae5a4SJacob Faibussowitsch {
2891985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
2892d0f46423SBarry Smith   PetscInt           i, j, m = A->rmap->n, n = A->cmap->n, p;
2893985db425SBarry Smith   PetscScalar       *x;
2894ca15aa20SStefano Zampini   const PetscScalar *aa;
2895985db425SBarry Smith 
2896985db425SBarry Smith   PetscFunctionBegin;
289728b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
28989566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
28999566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v, &p));
29009566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
290108401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector");
2902985db425SBarry Smith   for (i = 0; i < m; i++) {
29039371c9d4SSatish Balay     x[i] = aa[i];
29049371c9d4SSatish Balay     if (idx) idx[i] = 0;
2905985db425SBarry Smith     for (j = 1; j < n; j++) {
29069371c9d4SSatish Balay       if (PetscRealPart(x[i]) < PetscRealPart(aa[i + a->lda * j])) {
29079371c9d4SSatish Balay         x[i] = aa[i + a->lda * j];
29089371c9d4SSatish Balay         if (idx) idx[i] = j;
29099371c9d4SSatish Balay       }
2910985db425SBarry Smith     }
2911985db425SBarry Smith   }
29129566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
29139566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
29143ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2915985db425SBarry Smith }
2916985db425SBarry Smith 
MatGetRowMaxAbs_SeqDense(Mat A,Vec v,PetscInt idx[])2917d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A, Vec v, PetscInt idx[])
2918d71ae5a4SJacob Faibussowitsch {
2919985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
2920d0f46423SBarry Smith   PetscInt           i, j, m = A->rmap->n, n = A->cmap->n, p;
2921985db425SBarry Smith   PetscScalar       *x;
2922985db425SBarry Smith   PetscReal          atmp;
2923ca15aa20SStefano Zampini   const PetscScalar *aa;
2924985db425SBarry Smith 
2925985db425SBarry Smith   PetscFunctionBegin;
292628b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
29279566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
29289566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v, &p));
29299566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
293008401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector");
2931985db425SBarry Smith   for (i = 0; i < m; i++) {
29329189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
2933985db425SBarry Smith     for (j = 1; j < n; j++) {
2934ca15aa20SStefano Zampini       atmp = PetscAbsScalar(aa[i + a->lda * j]);
29359371c9d4SSatish Balay       if (PetscAbsScalar(x[i]) < atmp) {
29369371c9d4SSatish Balay         x[i] = atmp;
29379371c9d4SSatish Balay         if (idx) idx[i] = j;
29389371c9d4SSatish Balay       }
2939985db425SBarry Smith     }
2940985db425SBarry Smith   }
29419566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
29429566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
29433ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2944985db425SBarry Smith }
2945985db425SBarry Smith 
MatGetRowMin_SeqDense(Mat A,Vec v,PetscInt idx[])2946d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMin_SeqDense(Mat A, Vec v, PetscInt idx[])
2947d71ae5a4SJacob Faibussowitsch {
2948985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
2949d0f46423SBarry Smith   PetscInt           i, j, m = A->rmap->n, n = A->cmap->n, p;
2950985db425SBarry Smith   PetscScalar       *x;
2951ca15aa20SStefano Zampini   const PetscScalar *aa;
2952985db425SBarry Smith 
2953985db425SBarry Smith   PetscFunctionBegin;
295428b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
29559566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
29569566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
29579566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v, &p));
295808401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector");
2959985db425SBarry Smith   for (i = 0; i < m; i++) {
29609371c9d4SSatish Balay     x[i] = aa[i];
29619371c9d4SSatish Balay     if (idx) idx[i] = 0;
2962985db425SBarry Smith     for (j = 1; j < n; j++) {
29639371c9d4SSatish Balay       if (PetscRealPart(x[i]) > PetscRealPart(aa[i + a->lda * j])) {
29649371c9d4SSatish Balay         x[i] = aa[i + a->lda * j];
29659371c9d4SSatish Balay         if (idx) idx[i] = j;
29669371c9d4SSatish Balay       }
2967985db425SBarry Smith     }
2968985db425SBarry Smith   }
29699566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
29709566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
29713ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2972985db425SBarry Smith }
2973985db425SBarry Smith 
MatGetColumnVector_SeqDense(Mat A,Vec v,PetscInt col)2974d71ae5a4SJacob Faibussowitsch PetscErrorCode MatGetColumnVector_SeqDense(Mat A, Vec v, PetscInt col)
2975d71ae5a4SJacob Faibussowitsch {
29768d0534beSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense *)A->data;
29778d0534beSBarry Smith   PetscScalar       *x;
2978ca15aa20SStefano Zampini   const PetscScalar *aa;
29798d0534beSBarry Smith 
29808d0534beSBarry Smith   PetscFunctionBegin;
298128b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
29829566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &aa));
29839566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v, &x));
29849566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(x, aa + col * a->lda, A->rmap->n));
29859566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v, &x));
29869566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &aa));
29873ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
29888d0534beSBarry Smith }
29898d0534beSBarry Smith 
MatGetColumnReductions_SeqDense(Mat A,PetscInt type,PetscReal * reductions)2990d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatGetColumnReductions_SeqDense(Mat A, PetscInt type, PetscReal *reductions)
2991d71ae5a4SJacob Faibussowitsch {
29920716a85fSBarry Smith   PetscInt           i, j, m, n;
29931683a169SBarry Smith   const PetscScalar *a;
29940716a85fSBarry Smith 
29950716a85fSBarry Smith   PetscFunctionBegin;
29969566063dSJacob Faibussowitsch   PetscCall(MatGetSize(A, &m, &n));
29979566063dSJacob Faibussowitsch   PetscCall(PetscArrayzero(reductions, n));
29989566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &a));
2999857cbf51SRichard Tran Mills   if (type == NORM_2) {
30000716a85fSBarry Smith     for (i = 0; i < n; i++) {
3001ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j] * a[j]);
300216cd844bSPierre Jolivet       a = PetscSafePointerPlusOffset(a, m);
30030716a85fSBarry Smith     }
3004857cbf51SRichard Tran Mills   } else if (type == NORM_1) {
30050716a85fSBarry Smith     for (i = 0; i < n; i++) {
3006ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j]);
300716cd844bSPierre Jolivet       a = PetscSafePointerPlusOffset(a, m);
30080716a85fSBarry Smith     }
3009857cbf51SRichard Tran Mills   } else if (type == NORM_INFINITY) {
30100716a85fSBarry Smith     for (i = 0; i < n; i++) {
3011ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] = PetscMax(PetscAbsScalar(a[j]), reductions[i]);
301216cd844bSPierre Jolivet       a = PetscSafePointerPlusOffset(a, m);
30130716a85fSBarry Smith     }
3014857cbf51SRichard Tran Mills   } else if (type == REDUCTION_SUM_REALPART || type == REDUCTION_MEAN_REALPART) {
3015a873a8cdSSam Reynolds     for (i = 0; i < n; i++) {
3016ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] += PetscRealPart(a[j]);
301716cd844bSPierre Jolivet       a = PetscSafePointerPlusOffset(a, m);
3018a873a8cdSSam Reynolds     }
3019857cbf51SRichard Tran Mills   } else if (type == REDUCTION_SUM_IMAGINARYPART || type == REDUCTION_MEAN_IMAGINARYPART) {
3020857cbf51SRichard Tran Mills     for (i = 0; i < n; i++) {
3021ad540459SPierre Jolivet       for (j = 0; j < m; j++) reductions[i] += PetscImaginaryPart(a[j]);
302216cd844bSPierre Jolivet       a = PetscSafePointerPlusOffset(a, m);
3023857cbf51SRichard Tran Mills     }
3024857cbf51SRichard Tran Mills   } else SETERRQ(PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Unknown reduction type");
30259566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &a));
3026857cbf51SRichard Tran Mills   if (type == NORM_2) {
3027a873a8cdSSam Reynolds     for (i = 0; i < n; i++) reductions[i] = PetscSqrtReal(reductions[i]);
3028857cbf51SRichard Tran Mills   } else if (type == REDUCTION_MEAN_REALPART || type == REDUCTION_MEAN_IMAGINARYPART) {
3029a873a8cdSSam Reynolds     for (i = 0; i < n; i++) reductions[i] /= m;
30300716a85fSBarry Smith   }
30313ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
30320716a85fSBarry Smith }
30330716a85fSBarry Smith 
MatSetRandom_SeqDense(Mat x,PetscRandom rctx)3034d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetRandom_SeqDense(Mat x, PetscRandom rctx)
3035d71ae5a4SJacob Faibussowitsch {
303673a71a0fSBarry Smith   PetscScalar *a;
3037637a0070SStefano Zampini   PetscInt     lda, m, n, i, j;
303873a71a0fSBarry Smith 
303973a71a0fSBarry Smith   PetscFunctionBegin;
30409566063dSJacob Faibussowitsch   PetscCall(MatGetSize(x, &m, &n));
30419566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(x, &lda));
30423faff063SStefano Zampini   PetscCall(MatDenseGetArrayWrite(x, &a));
3043637a0070SStefano Zampini   for (j = 0; j < n; j++) {
304448a46eb9SPierre Jolivet     for (i = 0; i < m; i++) PetscCall(PetscRandomGetValue(rctx, a + j * lda + i));
304573a71a0fSBarry Smith   }
30463faff063SStefano Zampini   PetscCall(MatDenseRestoreArrayWrite(x, &a));
30473ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
304873a71a0fSBarry Smith }
304973a71a0fSBarry Smith 
3050ca15aa20SStefano Zampini /* vals is not const */
MatDenseGetColumn_SeqDense(Mat A,PetscInt col,PetscScalar ** vals)3051d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A, PetscInt col, PetscScalar **vals)
3052d71ae5a4SJacob Faibussowitsch {
305386aefd0dSHong Zhang   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
3054ca15aa20SStefano Zampini   PetscScalar  *v;
305586aefd0dSHong Zhang 
305686aefd0dSHong Zhang   PetscFunctionBegin;
305728b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix");
30589566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &v));
3059ca15aa20SStefano Zampini   *vals = v + col * a->lda;
30609566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &v));
30613ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
306286aefd0dSHong Zhang }
306386aefd0dSHong Zhang 
MatDenseRestoreColumn_SeqDense(Mat A,PetscScalar ** vals)3064d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A, PetscScalar **vals)
3065d71ae5a4SJacob Faibussowitsch {
306686aefd0dSHong Zhang   PetscFunctionBegin;
3067742765d3SMatthew Knepley   if (vals) *vals = NULL; /* user cannot accidentally use the array later */
30683ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
306986aefd0dSHong Zhang }
3070abc3b08eSStefano Zampini 
3071a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqDense,
3072905e6a2fSBarry Smith                                        MatGetRow_SeqDense,
3073905e6a2fSBarry Smith                                        MatRestoreRow_SeqDense,
3074905e6a2fSBarry Smith                                        MatMult_SeqDense,
307597304618SKris Buschelman                                        /*  4*/ MatMultAdd_SeqDense,
30767c922b88SBarry Smith                                        MatMultTranspose_SeqDense,
30777c922b88SBarry Smith                                        MatMultTransposeAdd_SeqDense,
3078f4259b30SLisandro Dalcin                                        NULL,
3079f4259b30SLisandro Dalcin                                        NULL,
3080f4259b30SLisandro Dalcin                                        NULL,
3081f4259b30SLisandro Dalcin                                        /* 10*/ NULL,
3082905e6a2fSBarry Smith                                        MatLUFactor_SeqDense,
3083905e6a2fSBarry Smith                                        MatCholeskyFactor_SeqDense,
308441f059aeSBarry Smith                                        MatSOR_SeqDense,
3085ec8511deSBarry Smith                                        MatTranspose_SeqDense,
308697304618SKris Buschelman                                        /* 15*/ MatGetInfo_SeqDense,
3087905e6a2fSBarry Smith                                        MatEqual_SeqDense,
3088905e6a2fSBarry Smith                                        MatGetDiagonal_SeqDense,
3089905e6a2fSBarry Smith                                        MatDiagonalScale_SeqDense,
3090905e6a2fSBarry Smith                                        MatNorm_SeqDense,
3091b7103cf4SPierre Jolivet                                        /* 20*/ NULL,
3092b7103cf4SPierre Jolivet                                        NULL,
3093905e6a2fSBarry Smith                                        MatSetOption_SeqDense,
3094905e6a2fSBarry Smith                                        MatZeroEntries_SeqDense,
3095d519adbfSMatthew Knepley                                        /* 24*/ MatZeroRows_SeqDense,
3096f4259b30SLisandro Dalcin                                        NULL,
3097f4259b30SLisandro Dalcin                                        NULL,
3098f4259b30SLisandro Dalcin                                        NULL,
3099f4259b30SLisandro Dalcin                                        NULL,
31004994cf47SJed Brown                                        /* 29*/ MatSetUp_SeqDense,
3101f4259b30SLisandro Dalcin                                        NULL,
3102f4259b30SLisandro Dalcin                                        NULL,
3103f4259b30SLisandro Dalcin                                        NULL,
3104f4259b30SLisandro Dalcin                                        NULL,
3105d519adbfSMatthew Knepley                                        /* 34*/ MatDuplicate_SeqDense,
3106f4259b30SLisandro Dalcin                                        NULL,
3107f4259b30SLisandro Dalcin                                        NULL,
3108f4259b30SLisandro Dalcin                                        NULL,
3109f4259b30SLisandro Dalcin                                        NULL,
3110d519adbfSMatthew Knepley                                        /* 39*/ MatAXPY_SeqDense,
31117dae84e0SHong Zhang                                        MatCreateSubMatrices_SeqDense,
3112f4259b30SLisandro Dalcin                                        NULL,
31134b0e389bSBarry Smith                                        MatGetValues_SeqDense,
3114a5ae1ecdSBarry Smith                                        MatCopy_SeqDense,
3115d519adbfSMatthew Knepley                                        /* 44*/ MatGetRowMax_SeqDense,
3116a5ae1ecdSBarry Smith                                        MatScale_SeqDense,
31172f605a99SJose E. Roman                                        MatShift_SeqDense,
3118f4259b30SLisandro Dalcin                                        NULL,
31193f49a652SStefano Zampini                                        MatZeroRowsColumns_SeqDense,
312073a71a0fSBarry Smith                                        /* 49*/ MatSetRandom_SeqDense,
3121f4259b30SLisandro Dalcin                                        NULL,
3122f4259b30SLisandro Dalcin                                        NULL,
3123f4259b30SLisandro Dalcin                                        NULL,
3124f4259b30SLisandro Dalcin                                        NULL,
3125f4259b30SLisandro Dalcin                                        /* 54*/ NULL,
3126f4259b30SLisandro Dalcin                                        NULL,
3127f4259b30SLisandro Dalcin                                        NULL,
3128f4259b30SLisandro Dalcin                                        NULL,
3129f4259b30SLisandro Dalcin                                        NULL,
3130023c16fcSToby Isaac                                        /* 59*/ MatCreateSubMatrix_SeqDense,
3131e03a110bSBarry Smith                                        MatDestroy_SeqDense,
3132e03a110bSBarry Smith                                        MatView_SeqDense,
3133f4259b30SLisandro Dalcin                                        NULL,
3134f4259b30SLisandro Dalcin                                        NULL,
3135f4259b30SLisandro Dalcin                                        /* 64*/ NULL,
3136f4259b30SLisandro Dalcin                                        NULL,
3137f4259b30SLisandro Dalcin                                        NULL,
3138f4259b30SLisandro Dalcin                                        NULL,
31398bb0f5c6SPierre Jolivet                                        MatGetRowMaxAbs_SeqDense,
31408bb0f5c6SPierre Jolivet                                        /* 69*/ NULL,
3141f4259b30SLisandro Dalcin                                        NULL,
3142f4259b30SLisandro Dalcin                                        NULL,
3143f4259b30SLisandro Dalcin                                        NULL,
3144f4259b30SLisandro Dalcin                                        NULL,
3145f4259b30SLisandro Dalcin                                        /* 74*/ NULL,
3146f4259b30SLisandro Dalcin                                        NULL,
3147f4259b30SLisandro Dalcin                                        NULL,
3148f4259b30SLisandro Dalcin                                        NULL,
31498bb0f5c6SPierre Jolivet                                        MatLoad_SeqDense,
31508bb0f5c6SPierre Jolivet                                        /* 79*/ MatIsSymmetric_SeqDense,
31511cbb95d3SBarry Smith                                        MatIsHermitian_SeqDense,
3152f4259b30SLisandro Dalcin                                        NULL,
3153f4259b30SLisandro Dalcin                                        NULL,
3154f4259b30SLisandro Dalcin                                        NULL,
31558bb0f5c6SPierre Jolivet                                        /* 84*/ NULL,
3156a9fe9ddaSSatish Balay                                        MatMatMultNumeric_SeqDense_SeqDense,
3157f4259b30SLisandro Dalcin                                        NULL,
3158f4259b30SLisandro Dalcin                                        NULL,
315969f65d41SStefano Zampini                                        MatMatTransposeMultNumeric_SeqDense_SeqDense,
31608bb0f5c6SPierre Jolivet                                        /* 89*/ NULL,
31618bb0f5c6SPierre Jolivet                                        MatProductSetFromOptions_SeqDense,
3162f4259b30SLisandro Dalcin                                        NULL,
3163f4259b30SLisandro Dalcin                                        NULL,
3164ba337c44SJed Brown                                        MatConjugate_SeqDense,
31658bb0f5c6SPierre Jolivet                                        /* 94*/ NULL,
3166f4259b30SLisandro Dalcin                                        NULL,
3167ba337c44SJed Brown                                        MatRealPart_SeqDense,
3168ba337c44SJed Brown                                        MatImaginaryPart_SeqDense,
3169f4259b30SLisandro Dalcin                                        NULL,
31708bb0f5c6SPierre Jolivet                                        /* 99*/ NULL,
31718bb0f5c6SPierre Jolivet                                        NULL,
31728bb0f5c6SPierre Jolivet                                        NULL,
31738bb0f5c6SPierre Jolivet                                        MatGetRowMin_SeqDense,
31748bb0f5c6SPierre Jolivet                                        MatGetColumnVector_SeqDense,
3175421480d9SBarry Smith                                        /*104*/ NULL,
31768bb0f5c6SPierre Jolivet                                        NULL,
31778bb0f5c6SPierre Jolivet                                        NULL,
31788bb0f5c6SPierre Jolivet                                        NULL,
3179f4259b30SLisandro Dalcin                                        NULL,
3180f4259b30SLisandro Dalcin                                        /*109*/ NULL,
3181f4259b30SLisandro Dalcin                                        NULL,
31828bb0f5c6SPierre Jolivet                                        MatMultHermitianTranspose_SeqDense,
31838bb0f5c6SPierre Jolivet                                        MatMultHermitianTransposeAdd_SeqDense,
3184f4259b30SLisandro Dalcin                                        NULL,
3185421480d9SBarry Smith                                        /*114*/ NULL,
31868bb0f5c6SPierre Jolivet                                        MatGetColumnReductions_SeqDense,
3187f4259b30SLisandro Dalcin                                        NULL,
3188f4259b30SLisandro Dalcin                                        NULL,
3189421480d9SBarry Smith                                        NULL,
3190f4259b30SLisandro Dalcin                                        /*119*/ NULL,
3191f4259b30SLisandro Dalcin                                        NULL,
31928bb0f5c6SPierre Jolivet                                        MatTransposeMatMultNumeric_SeqDense_SeqDense,
3193f4259b30SLisandro Dalcin                                        NULL,
3194421480d9SBarry Smith                                        NULL,
3195f4259b30SLisandro Dalcin                                        /*124*/ NULL,
31968bb0f5c6SPierre Jolivet                                        NULL,
3197f4259b30SLisandro Dalcin                                        NULL,
3198f4259b30SLisandro Dalcin                                        NULL,
3199f4259b30SLisandro Dalcin                                        NULL,
3200f4259b30SLisandro Dalcin                                        /*129*/ NULL,
32018bb0f5c6SPierre Jolivet                                        MatCreateMPIMatConcatenateSeqMat_SeqDense,
3202f4259b30SLisandro Dalcin                                        NULL,
3203f4259b30SLisandro Dalcin                                        NULL,
3204421480d9SBarry Smith                                        NULL,
3205f4259b30SLisandro Dalcin                                        /*134*/ NULL,
3206f4259b30SLisandro Dalcin                                        NULL,
3207f4259b30SLisandro Dalcin                                        NULL,
3208f4259b30SLisandro Dalcin                                        NULL,
3209f4259b30SLisandro Dalcin                                        NULL,
3210f4259b30SLisandro Dalcin                                        /*139*/ NULL,
3211f4259b30SLisandro Dalcin                                        NULL,
3212f4259b30SLisandro Dalcin                                        NULL,
321303db1824SAlex Lindsay                                        NULL,
3214dec0b466SHong Zhang                                        NULL};
321590ace30eSBarry Smith 
32165d83a8b1SBarry Smith /*@
321711a5261eSBarry Smith   MatCreateSeqDense - Creates a `MATSEQDENSE` that
3218fb850c59SBarry Smith   is stored in column major order (the usual Fortran format).
3219289bc588SBarry Smith 
3220d083f849SBarry Smith   Collective
3221db81eaa0SLois Curfman McInnes 
322220563c6bSBarry Smith   Input Parameters:
322311a5261eSBarry Smith + comm - MPI communicator, set to `PETSC_COMM_SELF`
32240c775827SLois Curfman McInnes . m    - number of rows
322518f449edSLois Curfman McInnes . n    - number of columns
32262ef1f0ffSBarry Smith - data - optional location of matrix data in column major order.  Use `NULL` for PETSc
3227dfc5480cSLois Curfman McInnes          to control all matrix memory allocation.
322820563c6bSBarry Smith 
322920563c6bSBarry Smith   Output Parameter:
323044cd7ae7SLois Curfman McInnes . A - the matrix
323120563c6bSBarry Smith 
32322ef1f0ffSBarry Smith   Level: intermediate
32332ef1f0ffSBarry Smith 
323411a5261eSBarry Smith   Note:
323518f449edSLois Curfman McInnes   The data input variable is intended primarily for Fortran programmers
323618f449edSLois Curfman McInnes   who wish to allocate their own matrix memory space.  Most users should
32372ef1f0ffSBarry Smith   set `data` = `NULL`.
323818f449edSLois Curfman McInnes 
3239fb850c59SBarry Smith   Developer Note:
3240fb850c59SBarry Smith   Many of the matrix operations for this variant use the BLAS and LAPACK routines.
3241fb850c59SBarry Smith 
32421cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()`
324320563c6bSBarry Smith @*/
MatCreateSeqDense(MPI_Comm comm,PetscInt m,PetscInt n,PetscScalar data[],Mat * A)32445d83a8b1SBarry Smith PetscErrorCode MatCreateSeqDense(MPI_Comm comm, PetscInt m, PetscInt n, PetscScalar data[], Mat *A)
3245d71ae5a4SJacob Faibussowitsch {
32463a40ed3dSBarry Smith   PetscFunctionBegin;
32479566063dSJacob Faibussowitsch   PetscCall(MatCreate(comm, A));
32489566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*A, m, n, m, n));
32499566063dSJacob Faibussowitsch   PetscCall(MatSetType(*A, MATSEQDENSE));
32509566063dSJacob Faibussowitsch   PetscCall(MatSeqDenseSetPreallocation(*A, data));
32513ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3252273d9f13SBarry Smith }
3253273d9f13SBarry Smith 
32545d83a8b1SBarry Smith /*@
325511a5261eSBarry Smith   MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements of a `MATSEQDENSE` matrix
3256273d9f13SBarry Smith 
3257d083f849SBarry Smith   Collective
3258273d9f13SBarry Smith 
3259273d9f13SBarry Smith   Input Parameters:
32601c4f3114SJed Brown + B    - the matrix
32612ef1f0ffSBarry Smith - data - the array (or `NULL`)
32622ef1f0ffSBarry Smith 
32632ef1f0ffSBarry Smith   Level: intermediate
3264273d9f13SBarry Smith 
326511a5261eSBarry Smith   Note:
3266273d9f13SBarry Smith   The data input variable is intended primarily for Fortran programmers
3267273d9f13SBarry Smith   who wish to allocate their own matrix memory space.  Most users should
3268284134d9SBarry Smith   need not call this routine.
3269273d9f13SBarry Smith 
32701cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()`, `MatDenseSetLDA()`
3271273d9f13SBarry Smith @*/
MatSeqDenseSetPreallocation(Mat B,PetscScalar data[])3272d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation(Mat B, PetscScalar data[])
3273d71ae5a4SJacob Faibussowitsch {
3274a23d5eceSKris Buschelman   PetscFunctionBegin;
3275d5ea218eSStefano Zampini   PetscValidHeaderSpecific(B, MAT_CLASSID, 1);
3276cac4c232SBarry Smith   PetscTryMethod(B, "MatSeqDenseSetPreallocation_C", (Mat, PetscScalar[]), (B, data));
32773ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3278a23d5eceSKris Buschelman }
3279a23d5eceSKris Buschelman 
MatSeqDenseSetPreallocation_SeqDense(Mat B,PetscScalar * data)3280d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation_SeqDense(Mat B, PetscScalar *data)
3281d71ae5a4SJacob Faibussowitsch {
3282ad16ce7aSStefano Zampini   Mat_SeqDense *b = (Mat_SeqDense *)B->data;
3283273d9f13SBarry Smith 
3284273d9f13SBarry Smith   PetscFunctionBegin;
328528b400f6SJacob Faibussowitsch   PetscCheck(!b->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
3286273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
3287a868139aSShri Abhyankar 
32889566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(B->rmap));
32899566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(B->cmap));
329034ef9618SShri Abhyankar 
32916497c311SBarry Smith   if (b->lda <= 0) PetscCall(PetscBLASIntCast(B->rmap->n, &b->lda));
329286d161a7SShri Abhyankar 
32939e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
32949566063dSJacob Faibussowitsch     if (!b->user_alloc) PetscCall(PetscFree(b->v));
32959566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1((size_t)b->lda * B->cmap->n, &b->v));
32962205254eSKarl Rupp 
32979e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
3298273d9f13SBarry Smith   } else { /* user-allocated storage */
32999566063dSJacob Faibussowitsch     if (!b->user_alloc) PetscCall(PetscFree(b->v));
3300273d9f13SBarry Smith     b->v          = data;
3301273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
3302273d9f13SBarry Smith   }
33030450473dSBarry Smith   B->assembled = PETSC_TRUE;
33043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3305273d9f13SBarry Smith }
3306273d9f13SBarry Smith 
330765b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
MatConvert_SeqDense_Elemental(Mat A,MatType newtype,MatReuse reuse,Mat * newmat)3308d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype, MatReuse reuse, Mat *newmat)
3309d71ae5a4SJacob Faibussowitsch {
3310d77f618aSHong Zhang   Mat                mat_elemental;
33111683a169SBarry Smith   const PetscScalar *array;
33121683a169SBarry Smith   PetscScalar       *v_colwise;
3313d77f618aSHong Zhang   PetscInt           M = A->rmap->N, N = A->cmap->N, i, j, k, *rows, *cols;
3314d77f618aSHong Zhang 
33158baccfbdSHong Zhang   PetscFunctionBegin;
33169566063dSJacob Faibussowitsch   PetscCall(PetscMalloc3(M * N, &v_colwise, M, &rows, N, &cols));
33179566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &array));
3318d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
3319d77f618aSHong Zhang   k = 0;
3320d77f618aSHong Zhang   for (j = 0; j < N; j++) {
3321d77f618aSHong Zhang     cols[j] = j;
3322ad540459SPierre Jolivet     for (i = 0; i < M; i++) v_colwise[j * M + i] = array[k++];
3323d77f618aSHong Zhang   }
3324ad540459SPierre Jolivet   for (i = 0; i < M; i++) rows[i] = i;
33259566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &array));
3326d77f618aSHong Zhang 
33279566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental));
33289566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(mat_elemental, PETSC_DECIDE, PETSC_DECIDE, M, N));
33299566063dSJacob Faibussowitsch   PetscCall(MatSetType(mat_elemental, MATELEMENTAL));
33309566063dSJacob Faibussowitsch   PetscCall(MatSetUp(mat_elemental));
3331d77f618aSHong Zhang 
3332d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
33339566063dSJacob Faibussowitsch   PetscCall(MatSetValues(mat_elemental, M, rows, N, cols, v_colwise, ADD_VALUES));
33349566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY));
33359566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY));
33369566063dSJacob Faibussowitsch   PetscCall(PetscFree3(v_colwise, rows, cols));
3337d77f618aSHong Zhang 
3338511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
33399566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A, &mat_elemental));
3340d77f618aSHong Zhang   } else {
3341d77f618aSHong Zhang     *newmat = mat_elemental;
3342d77f618aSHong Zhang   }
33433ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
33448baccfbdSHong Zhang }
334565b80a83SHong Zhang #endif
33468baccfbdSHong Zhang 
MatDenseSetLDA_SeqDense(Mat B,PetscInt lda)3347d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA_SeqDense(Mat B, PetscInt lda)
3348d71ae5a4SJacob Faibussowitsch {
33491b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense *)B->data;
33507422da62SJose E. Roman   PetscBool     data;
335121a2c019SBarry Smith 
33521b807ce4Svictorle   PetscFunctionBegin;
3353835f2295SStefano Zampini   data = (B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE;
3354aed4548fSBarry Smith   PetscCheck(b->user_alloc || !data || b->lda == lda, PETSC_COMM_SELF, PETSC_ERR_ORDER, "LDA cannot be changed after allocation of internal storage");
335508401ef6SPierre 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);
33566497c311SBarry Smith   PetscCall(PetscBLASIntCast(lda, &b->lda));
33573ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
33581b807ce4Svictorle }
33591b807ce4Svictorle 
MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat * outmat)3360d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm, Mat inmat, PetscInt n, MatReuse scall, Mat *outmat)
3361d71ae5a4SJacob Faibussowitsch {
3362d528f656SJakub Kruzik   PetscFunctionBegin;
33639566063dSJacob Faibussowitsch   PetscCall(MatCreateMPIMatConcatenateSeqMat_MPIDense(comm, inmat, n, scall, outmat));
33643ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3365d528f656SJakub Kruzik }
3366d528f656SJakub Kruzik 
MatDenseCreateColumnVec_Private(Mat A,Vec * v)3367d16ceb75SStefano Zampini PetscErrorCode MatDenseCreateColumnVec_Private(Mat A, Vec *v)
3368d16ceb75SStefano Zampini {
3369d16ceb75SStefano Zampini   PetscBool   isstd, iskok, iscuda, iship;
3370d16ceb75SStefano Zampini   PetscMPIInt size;
3371d16ceb75SStefano Zampini #if PetscDefined(HAVE_CUDA) || PetscDefined(HAVE_HIP)
3372d16ceb75SStefano Zampini   /* we pass the data of A, to prevent allocating needless GPU memory the first time VecCUPMPlaceArray is called. */
3373d16ceb75SStefano Zampini   const PetscScalar *a;
3374d16ceb75SStefano Zampini #endif
3375d16ceb75SStefano Zampini 
3376d16ceb75SStefano Zampini   PetscFunctionBegin;
3377d16ceb75SStefano Zampini   *v = NULL;
3378d16ceb75SStefano Zampini   PetscCall(PetscStrcmpAny(A->defaultvectype, &isstd, VECSTANDARD, VECSEQ, VECMPI, ""));
3379d16ceb75SStefano Zampini   PetscCall(PetscStrcmpAny(A->defaultvectype, &iskok, VECKOKKOS, VECSEQKOKKOS, VECMPIKOKKOS, ""));
3380d16ceb75SStefano Zampini   PetscCall(PetscStrcmpAny(A->defaultvectype, &iscuda, VECCUDA, VECSEQCUDA, VECMPICUDA, ""));
3381d16ceb75SStefano Zampini   PetscCall(PetscStrcmpAny(A->defaultvectype, &iship, VECHIP, VECSEQHIP, VECMPIHIP, ""));
3382d16ceb75SStefano Zampini   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A), &size));
3383d16ceb75SStefano Zampini   if (isstd) {
3384d16ceb75SStefano Zampini     if (size > 1) PetscCall(VecCreateMPIWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, v));
3385d16ceb75SStefano Zampini     else PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, v));
3386d16ceb75SStefano Zampini   } else if (iskok) {
3387d16ceb75SStefano Zampini     PetscCheck(PetscDefined(HAVE_KOKKOS_KERNELS), PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Reconfigure using KOKKOS kernels support");
3388d16ceb75SStefano Zampini #if PetscDefined(HAVE_KOKKOS_KERNELS)
3389d16ceb75SStefano Zampini     if (size > 1) PetscCall(VecCreateMPIKokkosWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, v));
3390d16ceb75SStefano Zampini     else PetscCall(VecCreateSeqKokkosWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, v));
3391d16ceb75SStefano Zampini #endif
3392d16ceb75SStefano Zampini   } else if (iscuda) {
3393d16ceb75SStefano Zampini     PetscCheck(PetscDefined(HAVE_CUDA), PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Reconfigure using CUDA support");
3394d16ceb75SStefano Zampini #if PetscDefined(HAVE_CUDA)
3395d16ceb75SStefano Zampini     PetscCall(MatDenseCUDAGetArrayRead(A, &a));
3396d16ceb75SStefano Zampini     if (size > 1) PetscCall(VecCreateMPICUDAWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, a, v));
3397d16ceb75SStefano Zampini     else PetscCall(VecCreateSeqCUDAWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, a, v));
3398d16ceb75SStefano Zampini #endif
3399d16ceb75SStefano Zampini   } else if (iship) {
3400d16ceb75SStefano Zampini     PetscCheck(PetscDefined(HAVE_HIP), PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Reconfigure using HIP support");
3401d16ceb75SStefano Zampini #if PetscDefined(HAVE_HIP)
3402d16ceb75SStefano Zampini     PetscCall(MatDenseHIPGetArrayRead(A, &a));
3403d16ceb75SStefano Zampini     if (size > 1) PetscCall(VecCreateMPIHIPWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, a, v));
3404d16ceb75SStefano Zampini     else PetscCall(VecCreateSeqHIPWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, a, v));
3405d16ceb75SStefano Zampini #endif
3406d16ceb75SStefano Zampini   }
3407d16ceb75SStefano Zampini   PetscCheck(*v, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Not coded for type %s", A->defaultvectype);
3408d16ceb75SStefano Zampini   PetscFunctionReturn(PETSC_SUCCESS);
3409d16ceb75SStefano Zampini }
3410d16ceb75SStefano Zampini 
MatDenseGetColumnVec_SeqDense(Mat A,PetscInt col,Vec * v)3411d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A, PetscInt col, Vec *v)
3412d71ae5a4SJacob Faibussowitsch {
34136947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
34146947451fSStefano Zampini 
34156947451fSStefano Zampini   PetscFunctionBegin;
341628b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
341728b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
3418d16ceb75SStefano Zampini   if (!a->cvec) PetscCall(MatDenseCreateColumnVec_Private(A, &a->cvec));
34196947451fSStefano Zampini   a->vecinuse = col + 1;
34209566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, (PetscScalar **)&a->ptrinuse));
34219566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda));
34226947451fSStefano Zampini   *v = a->cvec;
34233ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
34246947451fSStefano Zampini }
34256947451fSStefano Zampini 
MatDenseRestoreColumnVec_SeqDense(Mat A,PetscInt col,Vec * v)3426d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A, PetscInt col, Vec *v)
3427d71ae5a4SJacob Faibussowitsch {
34286947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
34296947451fSStefano Zampini 
34306947451fSStefano Zampini   PetscFunctionBegin;
343128b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first");
343228b400f6SJacob Faibussowitsch   PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector");
34334186a4bbSPierre Jolivet   VecCheckAssembled(a->cvec);
34346947451fSStefano Zampini   a->vecinuse = 0;
34359566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, (PetscScalar **)&a->ptrinuse));
34369566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
343775f6d85dSStefano Zampini   if (v) *v = NULL;
34383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
34396947451fSStefano Zampini }
34406947451fSStefano Zampini 
MatDenseGetColumnVecRead_SeqDense(Mat A,PetscInt col,Vec * v)3441d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v)
3442d71ae5a4SJacob Faibussowitsch {
34436947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
34446947451fSStefano Zampini 
34456947451fSStefano Zampini   PetscFunctionBegin;
344628b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
344728b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
3448d16ceb75SStefano Zampini   if (!a->cvec) PetscCall(MatDenseCreateColumnVec_Private(A, &a->cvec));
34496947451fSStefano Zampini   a->vecinuse = col + 1;
34509566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A, &a->ptrinuse));
34518e3a54c0SPierre Jolivet   PetscCall(VecPlaceArray(a->cvec, PetscSafePointerPlusOffset(a->ptrinuse, (size_t)col * (size_t)a->lda)));
34529566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(a->cvec));
34536947451fSStefano Zampini   *v = a->cvec;
34543ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
34556947451fSStefano Zampini }
34566947451fSStefano Zampini 
MatDenseRestoreColumnVecRead_SeqDense(Mat A,PetscInt col,Vec * v)3457d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v)
3458d71ae5a4SJacob Faibussowitsch {
34596947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
34606947451fSStefano Zampini 
34616947451fSStefano Zampini   PetscFunctionBegin;
346228b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first");
346328b400f6SJacob Faibussowitsch   PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector");
34644186a4bbSPierre Jolivet   VecCheckAssembled(a->cvec);
34656947451fSStefano Zampini   a->vecinuse = 0;
34669566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A, &a->ptrinuse));
34679566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(a->cvec));
34689566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
346975f6d85dSStefano Zampini   if (v) *v = NULL;
34703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
34716947451fSStefano Zampini }
34726947451fSStefano Zampini 
MatDenseGetColumnVecWrite_SeqDense(Mat A,PetscInt col,Vec * v)3473d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v)
3474d71ae5a4SJacob Faibussowitsch {
34756947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
34766947451fSStefano Zampini 
34776947451fSStefano Zampini   PetscFunctionBegin;
347828b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
347928b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
3480d16ceb75SStefano Zampini   if (!a->cvec) PetscCall(MatDenseCreateColumnVec_Private(A, &a->cvec));
34816947451fSStefano Zampini   a->vecinuse = col + 1;
34829566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(A, (PetscScalar **)&a->ptrinuse));
34838e3a54c0SPierre Jolivet   PetscCall(VecPlaceArray(a->cvec, PetscSafePointerPlusOffset(a->ptrinuse, (size_t)col * (size_t)a->lda)));
34846947451fSStefano Zampini   *v = a->cvec;
34853ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
34866947451fSStefano Zampini }
34876947451fSStefano Zampini 
MatDenseRestoreColumnVecWrite_SeqDense(Mat A,PetscInt col,Vec * v)3488d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v)
3489d71ae5a4SJacob Faibussowitsch {
34906947451fSStefano Zampini   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
34916947451fSStefano Zampini 
34926947451fSStefano Zampini   PetscFunctionBegin;
349328b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first");
349428b400f6SJacob Faibussowitsch   PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector");
34954186a4bbSPierre Jolivet   VecCheckAssembled(a->cvec);
34966947451fSStefano Zampini   a->vecinuse = 0;
34979566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(A, (PetscScalar **)&a->ptrinuse));
34989566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
349975f6d85dSStefano Zampini   if (v) *v = NULL;
35003ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
35016947451fSStefano Zampini }
35026947451fSStefano Zampini 
MatDenseGetSubMatrix_SeqDense(Mat A,PetscInt rbegin,PetscInt rend,PetscInt cbegin,PetscInt cend,Mat * v)3503d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v)
3504d71ae5a4SJacob Faibussowitsch {
35055ea7661aSPierre Jolivet   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
35065ea7661aSPierre Jolivet 
35075ea7661aSPierre Jolivet   PetscFunctionBegin;
350828b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first");
350928b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first");
3510a2748737SPierre Jolivet   if (a->cmat && (cend - cbegin != a->cmat->cmap->N || rend - rbegin != a->cmat->rmap->N)) PetscCall(MatDestroy(&a->cmat));
35115ea7661aSPierre Jolivet   if (!a->cmat) {
35128e3a54c0SPierre Jolivet     PetscCall(MatCreateDense(PetscObjectComm((PetscObject)A), rend - rbegin, PETSC_DECIDE, rend - rbegin, cend - cbegin, PetscSafePointerPlusOffset(a->v, rbegin + (size_t)cbegin * a->lda), &a->cmat));
35135ea7661aSPierre Jolivet   } else {
35148e3a54c0SPierre Jolivet     PetscCall(MatDensePlaceArray(a->cmat, PetscSafePointerPlusOffset(a->v, rbegin + (size_t)cbegin * a->lda)));
35155ea7661aSPierre Jolivet   }
35169566063dSJacob Faibussowitsch   PetscCall(MatDenseSetLDA(a->cmat, a->lda));
35175ea7661aSPierre Jolivet   a->matinuse = cbegin + 1;
35185ea7661aSPierre Jolivet   *v          = a->cmat;
351947d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
352075f6d85dSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
352175f6d85dSStefano Zampini #endif
35223ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
35235ea7661aSPierre Jolivet }
35245ea7661aSPierre Jolivet 
MatDenseRestoreSubMatrix_SeqDense(Mat A,Mat * v)3525d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A, Mat *v)
3526d71ae5a4SJacob Faibussowitsch {
35275ea7661aSPierre Jolivet   Mat_SeqDense *a = (Mat_SeqDense *)A->data;
35285ea7661aSPierre Jolivet 
35295ea7661aSPierre Jolivet   PetscFunctionBegin;
353028b400f6SJacob Faibussowitsch   PetscCheck(a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetSubMatrix() first");
353128b400f6SJacob Faibussowitsch   PetscCheck(a->cmat, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column matrix");
353208401ef6SPierre Jolivet   PetscCheck(*v == a->cmat, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not the matrix obtained from MatDenseGetSubMatrix()");
35335ea7661aSPierre Jolivet   a->matinuse = 0;
35349566063dSJacob Faibussowitsch   PetscCall(MatDenseResetArray(a->cmat));
3535beb1828fSPierre Jolivet   *v = NULL;
353647d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP)
35373faff063SStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
35383faff063SStefano Zampini #endif
35393ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
35405ea7661aSPierre Jolivet }
35415ea7661aSPierre Jolivet 
35420bad9183SKris Buschelman /*MC
3543fafad747SKris Buschelman    MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices.
35440bad9183SKris Buschelman 
35452ef1f0ffSBarry Smith    Options Database Key:
354611a5261eSBarry Smith . -mat_type seqdense - sets the matrix type to `MATSEQDENSE` during a call to `MatSetFromOptions()`
35470bad9183SKris Buschelman 
35480bad9183SKris Buschelman   Level: beginner
35490bad9183SKris Buschelman 
35501cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreateSeqDense()`
35510bad9183SKris Buschelman M*/
MatCreate_SeqDense(Mat B)3552d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreate_SeqDense(Mat B)
3553d71ae5a4SJacob Faibussowitsch {
3554273d9f13SBarry Smith   Mat_SeqDense *b;
35557c334f02SBarry Smith   PetscMPIInt   size;
3556273d9f13SBarry Smith 
3557273d9f13SBarry Smith   PetscFunctionBegin;
35589566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)B), &size));
355908401ef6SPierre Jolivet   PetscCheck(size <= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Comm must be of size 1");
356055659b69SBarry Smith 
35614dfa11a4SJacob Faibussowitsch   PetscCall(PetscNew(&b));
356244cd7ae7SLois Curfman McInnes   B->data   = (void *)b;
3563aea10558SJacob Faibussowitsch   B->ops[0] = MatOps_Values;
356418f449edSLois Curfman McInnes 
3565273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
35664e220ebcSLois Curfman McInnes 
35679566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatQRFactor_C", MatQRFactor_SeqDense));
35689566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetLDA_C", MatDenseGetLDA_SeqDense));
35699566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseSetLDA_C", MatDenseSetLDA_SeqDense));
35709566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArray_C", MatDenseGetArray_SeqDense));
35719566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArray_C", MatDenseRestoreArray_SeqDense));
35729566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDensePlaceArray_C", MatDensePlaceArray_SeqDense));
35739566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseResetArray_C", MatDenseResetArray_SeqDense));
35749566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseReplaceArray_C", MatDenseReplaceArray_SeqDense));
35759566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayRead_C", MatDenseGetArray_SeqDense));
35769566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayRead_C", MatDenseRestoreArray_SeqDense));
35779566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayWrite_C", MatDenseGetArray_SeqDense));
35789566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayWrite_C", MatDenseRestoreArray_SeqDense));
35799566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqaij_C", MatConvert_SeqDense_SeqAIJ));
35808baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
35819566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_elemental_C", MatConvert_SeqDense_Elemental));
35828baccfbdSHong Zhang #endif
3583d1a032dbSPierre Jolivet #if defined(PETSC_HAVE_SCALAPACK) && (defined(PETSC_USE_REAL_SINGLE) || defined(PETSC_USE_REAL_DOUBLE))
35849566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_scalapack_C", MatConvert_Dense_ScaLAPACK));
3585d24d4204SJose E. Roman #endif
35862bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
35879566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensecuda_C", MatConvert_SeqDense_SeqDenseCUDA));
35889566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", MatProductSetFromOptions_SeqDense));
35899566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdense_C", MatProductSetFromOptions_SeqDense));
35909566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensecuda_C", MatProductSetFromOptions_SeqDense));
35912bf066beSStefano Zampini #endif
359247d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP)
359347d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensehip_C", MatConvert_SeqDense_SeqDenseHIP));
359447d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensehip_seqdensehip_C", MatProductSetFromOptions_SeqDense));
359547d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensehip_seqdense_C", MatProductSetFromOptions_SeqDense));
359647d993e7Ssuyashtn   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensehip_C", MatProductSetFromOptions_SeqDense));
359747d993e7Ssuyashtn #endif
35989566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSeqDenseSetPreallocation_C", MatSeqDenseSetPreallocation_SeqDense));
35999566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqaij_seqdense_C", MatProductSetFromOptions_SeqAIJ_SeqDense));
36009566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdense_C", MatProductSetFromOptions_SeqDense));
36019566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense));
36029566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqsbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense));
360396e6d5c4SRichard Tran Mills 
36049566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumn_C", MatDenseGetColumn_SeqDense));
36059566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumn_C", MatDenseRestoreColumn_SeqDense));
36069566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVec_C", MatDenseGetColumnVec_SeqDense));
36079566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVec_C", MatDenseRestoreColumnVec_SeqDense));
36089566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecRead_C", MatDenseGetColumnVecRead_SeqDense));
36099566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecRead_C", MatDenseRestoreColumnVecRead_SeqDense));
36109566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecWrite_C", MatDenseGetColumnVecWrite_SeqDense));
36119566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecWrite_C", MatDenseRestoreColumnVecWrite_SeqDense));
36129566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetSubMatrix_C", MatDenseGetSubMatrix_SeqDense));
36139566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreSubMatrix_C", MatDenseRestoreSubMatrix_SeqDense));
3614d016bddeSToby Isaac   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatMultColumnRange_C", MatMultColumnRange_SeqDense));
36150be0d8bdSHansol Suh   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatMultAddColumnRange_C", MatMultAddColumnRange_SeqDense));
36160be0d8bdSHansol Suh   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatMultHermitianTransposeColumnRange_C", MatMultHermitianTransposeColumnRange_SeqDense));
36170be0d8bdSHansol Suh   PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatMultHermitianTransposeAddColumnRange_C", MatMultHermitianTransposeAddColumnRange_SeqDense));
36189566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)B, MATSEQDENSE));
36193ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
3620289bc588SBarry Smith }
362186aefd0dSHong Zhang 
362286aefd0dSHong Zhang /*@C
362311a5261eSBarry 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.
362486aefd0dSHong Zhang 
362586aefd0dSHong Zhang   Not Collective
362686aefd0dSHong Zhang 
36275ea7661aSPierre Jolivet   Input Parameters:
3628fe59aa6dSJacob Faibussowitsch + A   - a `MATSEQDENSE` or `MATMPIDENSE` matrix
362986aefd0dSHong Zhang - col - column index
363086aefd0dSHong Zhang 
363186aefd0dSHong Zhang   Output Parameter:
363286aefd0dSHong Zhang . vals - pointer to the data
363386aefd0dSHong Zhang 
363486aefd0dSHong Zhang   Level: intermediate
363586aefd0dSHong Zhang 
363611a5261eSBarry Smith   Note:
363711a5261eSBarry Smith   Use `MatDenseGetColumnVec()` to get access to a column of a `MATDENSE` treated as a `Vec`
363811a5261eSBarry Smith 
36391cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreColumn()`, `MatDenseGetColumnVec()`
364086aefd0dSHong Zhang @*/
MatDenseGetColumn(Mat A,PetscInt col,PetscScalar * vals[])36415d83a8b1SBarry Smith PetscErrorCode MatDenseGetColumn(Mat A, PetscInt col, PetscScalar *vals[])
3642d71ae5a4SJacob Faibussowitsch {
364386aefd0dSHong Zhang   PetscFunctionBegin;
3644d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
3645d5ea218eSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
36464f572ea9SToby Isaac   PetscAssertPointer(vals, 3);
3647cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumn_C", (Mat, PetscInt, PetscScalar **), (A, col, vals));
36483ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
364986aefd0dSHong Zhang }
365086aefd0dSHong Zhang 
365186aefd0dSHong Zhang /*@C
365211a5261eSBarry Smith   MatDenseRestoreColumn - returns access to a column of a `MATDENSE` matrix which is returned by `MatDenseGetColumn()`.
365386aefd0dSHong Zhang 
365486aefd0dSHong Zhang   Not Collective
365586aefd0dSHong Zhang 
3656742765d3SMatthew Knepley   Input Parameters:
3657fe59aa6dSJacob Faibussowitsch + A    - a `MATSEQDENSE` or `MATMPIDENSE` matrix
36582ef1f0ffSBarry Smith - vals - pointer to the data (may be `NULL`)
365986aefd0dSHong Zhang 
366086aefd0dSHong Zhang   Level: intermediate
366186aefd0dSHong Zhang 
36621cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetColumn()`
366386aefd0dSHong Zhang @*/
MatDenseRestoreColumn(Mat A,PetscScalar * vals[])36645d83a8b1SBarry Smith PetscErrorCode MatDenseRestoreColumn(Mat A, PetscScalar *vals[])
3665d71ae5a4SJacob Faibussowitsch {
366686aefd0dSHong Zhang   PetscFunctionBegin;
3667d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
36684f572ea9SToby Isaac   PetscAssertPointer(vals, 2);
3669cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumn_C", (Mat, PetscScalar **), (A, vals));
36703ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
367186aefd0dSHong Zhang }
36726947451fSStefano Zampini 
36730f74d2c1SSatish Balay /*@
367411a5261eSBarry Smith   MatDenseGetColumnVec - Gives read-write access to a column of a `MATDENSE` matrix, represented as a `Vec`.
36756947451fSStefano Zampini 
36766947451fSStefano Zampini   Collective
36776947451fSStefano Zampini 
36785ea7661aSPierre Jolivet   Input Parameters:
3679fe59aa6dSJacob Faibussowitsch + A   - the `Mat` object
36806947451fSStefano Zampini - col - the column index
36816947451fSStefano Zampini 
36826947451fSStefano Zampini   Output Parameter:
36836947451fSStefano Zampini . v - the vector
36846947451fSStefano Zampini 
36852ef1f0ffSBarry Smith   Level: intermediate
36862ef1f0ffSBarry Smith 
36876947451fSStefano Zampini   Notes:
368811a5261eSBarry Smith   The vector is owned by PETSc. Users need to call `MatDenseRestoreColumnVec()` when the vector is no longer needed.
368911a5261eSBarry Smith 
369011a5261eSBarry Smith   Use `MatDenseGetColumnVecRead()` to obtain read-only access or `MatDenseGetColumnVecWrite()` for write-only access.
36916947451fSStefano Zampini 
36921cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`, `MatDenseGetColumn()`
36936947451fSStefano Zampini @*/
MatDenseGetColumnVec(Mat A,PetscInt col,Vec * v)3694d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec(Mat A, PetscInt col, Vec *v)
3695d71ae5a4SJacob Faibussowitsch {
36966947451fSStefano Zampini   PetscFunctionBegin;
36976947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
36986947451fSStefano Zampini   PetscValidType(A, 1);
36996947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
37004f572ea9SToby Isaac   PetscAssertPointer(v, 3);
370128b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
37022cf15c64SPierre 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);
3703cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v));
37043ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
37056947451fSStefano Zampini }
37066947451fSStefano Zampini 
37070f74d2c1SSatish Balay /*@
3708fb850c59SBarry Smith   MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from `MatDenseGetColumnVec()`.
37096947451fSStefano Zampini 
37106947451fSStefano Zampini   Collective
37116947451fSStefano Zampini 
37125ea7661aSPierre Jolivet   Input Parameters:
3713fb850c59SBarry Smith + A   - the `Mat` object
37146947451fSStefano Zampini . col - the column index
3715fb850c59SBarry Smith - v   - the `Vec` object (may be `NULL`)
37166947451fSStefano Zampini 
37176947451fSStefano Zampini   Level: intermediate
37186947451fSStefano Zampini 
37191cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
37206947451fSStefano Zampini @*/
MatDenseRestoreColumnVec(Mat A,PetscInt col,Vec * v)3721d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec(Mat A, PetscInt col, Vec *v)
3722d71ae5a4SJacob Faibussowitsch {
37236947451fSStefano Zampini   PetscFunctionBegin;
37246947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
37256947451fSStefano Zampini   PetscValidType(A, 1);
37266947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
3727beb1828fSPierre Jolivet   if (v) PetscValidHeaderSpecific(*v, VEC_CLASSID, 3);
372808401ef6SPierre Jolivet   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
37292cf15c64SPierre 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);
3730cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v));
37313ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
37326947451fSStefano Zampini }
37336947451fSStefano Zampini 
37340f74d2c1SSatish Balay /*@
3735fb850c59SBarry Smith   MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a `Vec`.
37366947451fSStefano Zampini 
37376947451fSStefano Zampini   Collective
37386947451fSStefano Zampini 
37395ea7661aSPierre Jolivet   Input Parameters:
3740fe59aa6dSJacob Faibussowitsch + A   - the `Mat` object
37416947451fSStefano Zampini - col - the column index
37426947451fSStefano Zampini 
37436947451fSStefano Zampini   Output Parameter:
37446947451fSStefano Zampini . v - the vector
37456947451fSStefano Zampini 
37462ef1f0ffSBarry Smith   Level: intermediate
37472ef1f0ffSBarry Smith 
37486947451fSStefano Zampini   Notes:
37496947451fSStefano Zampini   The vector is owned by PETSc and users cannot modify it.
375011a5261eSBarry Smith 
37512ef1f0ffSBarry Smith   Users need to call `MatDenseRestoreColumnVecRead()` when the vector is no longer needed.
375211a5261eSBarry Smith 
37532ef1f0ffSBarry Smith   Use `MatDenseGetColumnVec()` to obtain read-write access or `MatDenseGetColumnVecWrite()` for write-only access.
37546947451fSStefano Zampini 
37551cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
37566947451fSStefano Zampini @*/
MatDenseGetColumnVecRead(Mat A,PetscInt col,Vec * v)3757d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead(Mat A, PetscInt col, Vec *v)
3758d71ae5a4SJacob Faibussowitsch {
37596947451fSStefano Zampini   PetscFunctionBegin;
37606947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
37616947451fSStefano Zampini   PetscValidType(A, 1);
37626947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
37634f572ea9SToby Isaac   PetscAssertPointer(v, 3);
376428b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
37652cf15c64SPierre 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);
3766cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v));
37673ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
37686947451fSStefano Zampini }
37696947451fSStefano Zampini 
37700f74d2c1SSatish Balay /*@
3771fb850c59SBarry Smith   MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from `MatDenseGetColumnVecRead()`.
37726947451fSStefano Zampini 
37736947451fSStefano Zampini   Collective
37746947451fSStefano Zampini 
37755ea7661aSPierre Jolivet   Input Parameters:
3776fe59aa6dSJacob Faibussowitsch + A   - the `Mat` object
37776947451fSStefano Zampini . col - the column index
3778fb850c59SBarry Smith - v   - the `Vec` object (may be `NULL`)
37796947451fSStefano Zampini 
37806947451fSStefano Zampini   Level: intermediate
37816947451fSStefano Zampini 
37821cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecWrite()`
37836947451fSStefano Zampini @*/
MatDenseRestoreColumnVecRead(Mat A,PetscInt col,Vec * v)3784d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead(Mat A, PetscInt col, Vec *v)
3785d71ae5a4SJacob Faibussowitsch {
37866947451fSStefano Zampini   PetscFunctionBegin;
37876947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
37886947451fSStefano Zampini   PetscValidType(A, 1);
37896947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
3790beb1828fSPierre Jolivet   if (v) PetscValidHeaderSpecific(*v, VEC_CLASSID, 3);
379108401ef6SPierre Jolivet   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
37922cf15c64SPierre 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);
3793cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v));
37943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
37956947451fSStefano Zampini }
37966947451fSStefano Zampini 
37970f74d2c1SSatish Balay /*@
3798fb850c59SBarry Smith   MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a `Vec`.
37996947451fSStefano Zampini 
38006947451fSStefano Zampini   Collective
38016947451fSStefano Zampini 
38025ea7661aSPierre Jolivet   Input Parameters:
3803fe59aa6dSJacob Faibussowitsch + A   - the `Mat` object
38046947451fSStefano Zampini - col - the column index
38056947451fSStefano Zampini 
38066947451fSStefano Zampini   Output Parameter:
38076947451fSStefano Zampini . v - the vector
38086947451fSStefano Zampini 
38096947451fSStefano Zampini   Level: intermediate
38106947451fSStefano Zampini 
38112ef1f0ffSBarry Smith   Notes:
38122ef1f0ffSBarry Smith   The vector is owned by PETSc. Users need to call `MatDenseRestoreColumnVecWrite()` when the vector is no longer needed.
38132ef1f0ffSBarry Smith 
38142ef1f0ffSBarry Smith   Use `MatDenseGetColumnVec()` to obtain read-write access or `MatDenseGetColumnVecRead()` for read-only access.
38152ef1f0ffSBarry Smith 
38161cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
38176947451fSStefano Zampini @*/
MatDenseGetColumnVecWrite(Mat A,PetscInt col,Vec * v)3818d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite(Mat A, PetscInt col, Vec *v)
3819d71ae5a4SJacob Faibussowitsch {
38206947451fSStefano Zampini   PetscFunctionBegin;
38216947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
38226947451fSStefano Zampini   PetscValidType(A, 1);
38236947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
38244f572ea9SToby Isaac   PetscAssertPointer(v, 3);
382528b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
3826aed4548fSBarry 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);
3827cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseGetColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v));
38283ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
38296947451fSStefano Zampini }
38306947451fSStefano Zampini 
38310f74d2c1SSatish Balay /*@
3832fb850c59SBarry Smith   MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from `MatDenseGetColumnVecWrite()`.
38336947451fSStefano Zampini 
38346947451fSStefano Zampini   Collective
38356947451fSStefano Zampini 
38365ea7661aSPierre Jolivet   Input Parameters:
3837fe59aa6dSJacob Faibussowitsch + A   - the `Mat` object
38386947451fSStefano Zampini . col - the column index
38392ef1f0ffSBarry Smith - v   - the `Vec` object (may be `NULL`)
38406947451fSStefano Zampini 
38416947451fSStefano Zampini   Level: intermediate
38426947451fSStefano Zampini 
38431cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`
38446947451fSStefano Zampini @*/
MatDenseRestoreColumnVecWrite(Mat A,PetscInt col,Vec * v)3845d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A, PetscInt col, Vec *v)
3846d71ae5a4SJacob Faibussowitsch {
38476947451fSStefano Zampini   PetscFunctionBegin;
38486947451fSStefano Zampini   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
38496947451fSStefano Zampini   PetscValidType(A, 1);
38506947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A, col, 2);
3851beb1828fSPierre Jolivet   if (v) PetscValidHeaderSpecific(*v, VEC_CLASSID, 3);
385208401ef6SPierre Jolivet   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
3853aed4548fSBarry 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);
3854cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v));
38553ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
38566947451fSStefano Zampini }
38575ea7661aSPierre Jolivet 
38580f74d2c1SSatish Balay /*@
3859fb850c59SBarry Smith   MatDenseGetSubMatrix - Gives access to a block of rows and columns of a dense matrix, represented as a `Mat`.
38605ea7661aSPierre Jolivet 
38615ea7661aSPierre Jolivet   Collective
38625ea7661aSPierre Jolivet 
38635ea7661aSPierre Jolivet   Input Parameters:
3864fb850c59SBarry Smith + A      - the `Mat` object
38652ef1f0ffSBarry Smith . rbegin - the first global row index in the block (if `PETSC_DECIDE`, is 0)
38662ef1f0ffSBarry Smith . rend   - the global row index past the last one in the block (if `PETSC_DECIDE`, is `M`)
38672ef1f0ffSBarry Smith . cbegin - the first global column index in the block (if `PETSC_DECIDE`, is 0)
38682ef1f0ffSBarry Smith - cend   - the global column index past the last one in the block (if `PETSC_DECIDE`, is `N`)
38695ea7661aSPierre Jolivet 
38705ea7661aSPierre Jolivet   Output Parameter:
38715ea7661aSPierre Jolivet . v - the matrix
38725ea7661aSPierre Jolivet 
38735ea7661aSPierre Jolivet   Level: intermediate
38745ea7661aSPierre Jolivet 
38752ef1f0ffSBarry Smith   Notes:
38762ef1f0ffSBarry Smith   The matrix is owned by PETSc. Users need to call `MatDenseRestoreSubMatrix()` when the matrix is no longer needed.
38772ef1f0ffSBarry Smith 
38782ef1f0ffSBarry 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.
38792ef1f0ffSBarry Smith 
38801cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreSubMatrix()`
38815ea7661aSPierre Jolivet @*/
MatDenseGetSubMatrix(Mat A,PetscInt rbegin,PetscInt rend,PetscInt cbegin,PetscInt cend,Mat * v)3882d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v)
3883d71ae5a4SJacob Faibussowitsch {
38845ea7661aSPierre Jolivet   PetscFunctionBegin;
38855ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
38865ea7661aSPierre Jolivet   PetscValidType(A, 1);
3887a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, rbegin, 2);
3888a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, rend, 3);
3889a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, cbegin, 4);
3890a2748737SPierre Jolivet   PetscValidLogicalCollectiveInt(A, cend, 5);
38914f572ea9SToby Isaac   PetscAssertPointer(v, 6);
3892a2748737SPierre Jolivet   if (rbegin == PETSC_DECIDE) rbegin = 0;
3893a2748737SPierre Jolivet   if (rend == PETSC_DECIDE) rend = A->rmap->N;
3894a2748737SPierre Jolivet   if (cbegin == PETSC_DECIDE) cbegin = 0;
3895a2748737SPierre Jolivet   if (cend == PETSC_DECIDE) cend = A->cmap->N;
389628b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated");
3897a2748737SPierre 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);
3898a2748737SPierre 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);
3899a2748737SPierre 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);
3900a2748737SPierre 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);
3901a2748737SPierre Jolivet   PetscUseMethod(A, "MatDenseGetSubMatrix_C", (Mat, PetscInt, PetscInt, PetscInt, PetscInt, Mat *), (A, rbegin, rend, cbegin, cend, v));
39023ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
39035ea7661aSPierre Jolivet }
39045ea7661aSPierre Jolivet 
39050f74d2c1SSatish Balay /*@
3906fb850c59SBarry Smith   MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from `MatDenseGetSubMatrix()`.
39075ea7661aSPierre Jolivet 
39085ea7661aSPierre Jolivet   Collective
39095ea7661aSPierre Jolivet 
39105ea7661aSPierre Jolivet   Input Parameters:
3911fe59aa6dSJacob Faibussowitsch + A - the `Mat` object
3912beb1828fSPierre Jolivet - v - the `Mat` object (cannot be `NULL`)
39135ea7661aSPierre Jolivet 
39145ea7661aSPierre Jolivet   Level: intermediate
39155ea7661aSPierre Jolivet 
39161cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseGetSubMatrix()`
39175ea7661aSPierre Jolivet @*/
MatDenseRestoreSubMatrix(Mat A,Mat * v)3918d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix(Mat A, Mat *v)
3919d71ae5a4SJacob Faibussowitsch {
39205ea7661aSPierre Jolivet   PetscFunctionBegin;
39215ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
39225ea7661aSPierre Jolivet   PetscValidType(A, 1);
39234f572ea9SToby Isaac   PetscAssertPointer(v, 2);
3924beb1828fSPierre Jolivet   PetscValidHeaderSpecific(*v, MAT_CLASSID, 2);
3925cac4c232SBarry Smith   PetscUseMethod(A, "MatDenseRestoreSubMatrix_C", (Mat, Mat *), (A, v));
39263ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
39275ea7661aSPierre Jolivet }
39288a9c020eSBarry Smith 
39298a9c020eSBarry Smith #include <petscblaslapack.h>
39308a9c020eSBarry Smith #include <petsc/private/kernels/blockinvert.h>
39318a9c020eSBarry Smith 
MatSeqDenseInvert(Mat A)3932d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseInvert(Mat A)
3933d71ae5a4SJacob Faibussowitsch {
3934d63b1753SJacob Faibussowitsch   PetscInt        m;
39358a9c020eSBarry Smith   const PetscReal shift = 0.0;
3936d63b1753SJacob Faibussowitsch   PetscBool       allowzeropivot, zeropivotdetected = PETSC_FALSE;
3937d63b1753SJacob Faibussowitsch   PetscScalar    *values;
39388a9c020eSBarry Smith 
39398a9c020eSBarry Smith   PetscFunctionBegin;
3940d63b1753SJacob Faibussowitsch   PetscValidHeaderSpecific(A, MAT_CLASSID, 1);
3941d63b1753SJacob Faibussowitsch   PetscCall(MatDenseGetArray(A, &values));
3942d63b1753SJacob Faibussowitsch   PetscCall(MatGetLocalSize(A, &m, NULL));
3943d63b1753SJacob Faibussowitsch   allowzeropivot = PetscNot(A->erroriffailure);
39448a9c020eSBarry Smith   /* factor and invert each block */
3945d63b1753SJacob Faibussowitsch   switch (m) {
3946d71ae5a4SJacob Faibussowitsch   case 1:
3947d71ae5a4SJacob Faibussowitsch     values[0] = (PetscScalar)1.0 / (values[0] + shift);
3948d71ae5a4SJacob Faibussowitsch     break;
39498a9c020eSBarry Smith   case 2:
39508a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_2(values, shift, allowzeropivot, &zeropivotdetected));
39518a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
39528a9c020eSBarry Smith     break;
39538a9c020eSBarry Smith   case 3:
39548a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_3(values, shift, allowzeropivot, &zeropivotdetected));
39558a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
39568a9c020eSBarry Smith     break;
39578a9c020eSBarry Smith   case 4:
39588a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_4(values, shift, allowzeropivot, &zeropivotdetected));
39598a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
39608a9c020eSBarry Smith     break;
39619371c9d4SSatish Balay   case 5: {
39628a9c020eSBarry Smith     PetscScalar work[25];
39638a9c020eSBarry Smith     PetscInt    ipvt[5];
39648a9c020eSBarry Smith 
39658a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_5(values, ipvt, work, shift, allowzeropivot, &zeropivotdetected));
39668a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
39679371c9d4SSatish Balay   } break;
39688a9c020eSBarry Smith   case 6:
39698a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_6(values, shift, allowzeropivot, &zeropivotdetected));
39708a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
39718a9c020eSBarry Smith     break;
39728a9c020eSBarry Smith   case 7:
39738a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_7(values, shift, allowzeropivot, &zeropivotdetected));
39748a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
39758a9c020eSBarry Smith     break;
39769371c9d4SSatish Balay   default: {
39778a9c020eSBarry Smith     PetscInt    *v_pivots, *IJ, j;
39788a9c020eSBarry Smith     PetscScalar *v_work;
39798a9c020eSBarry Smith 
3980d63b1753SJacob Faibussowitsch     PetscCall(PetscMalloc3(m, &v_work, m, &v_pivots, m, &IJ));
3981d63b1753SJacob Faibussowitsch     for (j = 0; j < m; j++) IJ[j] = j;
3982d63b1753SJacob Faibussowitsch     PetscCall(PetscKernel_A_gets_inverse_A(m, values, v_pivots, v_work, allowzeropivot, &zeropivotdetected));
39838a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
39848a9c020eSBarry Smith     PetscCall(PetscFree3(v_work, v_pivots, IJ));
39858a9c020eSBarry Smith   }
39868a9c020eSBarry Smith   }
3987d63b1753SJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A, &values));
39883ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
39898a9c020eSBarry Smith }
3990