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