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 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 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 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 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 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 232511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 2339566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A, &B)); 2346d4ec7b0SPierre Jolivet } else if (reuse != MAT_REUSE_MATRIX) *newmat = B; 2353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2366a63e612SBarry Smith } 2376a63e612SBarry Smith 238d71ae5a4SJacob Faibussowitsch PetscErrorCode MatAXPY_SeqDense(Mat Y, PetscScalar alpha, Mat X, MatStructure str) 239d71ae5a4SJacob Faibussowitsch { 2401987afe7SBarry Smith Mat_SeqDense *x = (Mat_SeqDense *)X->data, *y = (Mat_SeqDense *)Y->data; 241ca15aa20SStefano Zampini const PetscScalar *xv; 242ca15aa20SStefano Zampini PetscScalar *yv; 24323fff9afSBarry Smith PetscBLASInt N, m, ldax = 0, lday = 0, one = 1; 2443a40ed3dSBarry Smith 2453a40ed3dSBarry Smith PetscFunctionBegin; 2469566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(X, &xv)); 2479566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(Y, &yv)); 2489566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(X->rmap->n * X->cmap->n, &N)); 2499566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(X->rmap->n, &m)); 2509566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(x->lda, &ldax)); 2519566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(y->lda, &lday)); 252a5ce6ee0Svictorle if (ldax > m || lday > m) { 2538e3a54c0SPierre 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)); 254a5ce6ee0Svictorle } else { 255792fecdfSBarry Smith PetscCallBLAS("BLASaxpy", BLASaxpy_(&N, &alpha, xv, &one, yv, &one)); 256a5ce6ee0Svictorle } 2579566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(X, &xv)); 2589566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(Y, &yv)); 2599566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(PetscMax(2.0 * N - 1, 0))); 2603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2611987afe7SBarry Smith } 2621987afe7SBarry Smith 263d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetInfo_SeqDense(Mat A, MatInfoType flag, MatInfo *info) 264d71ae5a4SJacob Faibussowitsch { 265ca15aa20SStefano Zampini PetscLogDouble N = A->rmap->n * A->cmap->n; 2663a40ed3dSBarry Smith 2673a40ed3dSBarry Smith PetscFunctionBegin; 2684e220ebcSLois Curfman McInnes info->block_size = 1.0; 269ca15aa20SStefano Zampini info->nz_allocated = N; 270ca15aa20SStefano Zampini info->nz_used = N; 271ca15aa20SStefano Zampini info->nz_unneeded = 0; 272ca15aa20SStefano Zampini info->assemblies = A->num_ass; 2734e220ebcSLois Curfman McInnes info->mallocs = 0; 2744dfa11a4SJacob Faibussowitsch info->memory = 0; /* REVIEW ME */ 2754e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 2764e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 2774e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 2783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 279289bc588SBarry Smith } 280289bc588SBarry Smith 281d71ae5a4SJacob Faibussowitsch PetscErrorCode MatScale_SeqDense(Mat A, PetscScalar alpha) 282d71ae5a4SJacob Faibussowitsch { 283273d9f13SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 284ca15aa20SStefano Zampini PetscScalar *v; 28523fff9afSBarry Smith PetscBLASInt one = 1, j, nz, lda = 0; 28680cd9d93SLois Curfman McInnes 2873a40ed3dSBarry Smith PetscFunctionBegin; 2889566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 2899566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(a->lda, &lda)); 290d0f46423SBarry Smith if (lda > A->rmap->n) { 2919566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &nz)); 29248a46eb9SPierre Jolivet for (j = 0; j < A->cmap->n; j++) PetscCallBLAS("BLASscal", BLASscal_(&nz, &alpha, v + j * lda, &one)); 293a5ce6ee0Svictorle } else { 2949566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n * A->cmap->n, &nz)); 295792fecdfSBarry Smith PetscCallBLAS("BLASscal", BLASscal_(&nz, &alpha, v, &one)); 296a5ce6ee0Svictorle } 29704cbc005SJose E. Roman PetscCall(PetscLogFlops(A->rmap->n * A->cmap->n)); 2989566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 2993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30080cd9d93SLois Curfman McInnes } 30180cd9d93SLois Curfman McInnes 302d71ae5a4SJacob Faibussowitsch PetscErrorCode MatShift_SeqDense(Mat A, PetscScalar alpha) 303d71ae5a4SJacob Faibussowitsch { 3042f605a99SJose E. Roman Mat_SeqDense *a = (Mat_SeqDense *)A->data; 3052f605a99SJose E. Roman PetscScalar *v; 3062f605a99SJose E. Roman PetscInt j, k; 3072f605a99SJose E. Roman 3082f605a99SJose E. Roman PetscFunctionBegin; 3092f605a99SJose E. Roman PetscCall(MatDenseGetArray(A, &v)); 3102f605a99SJose E. Roman k = PetscMin(A->rmap->n, A->cmap->n); 3112f605a99SJose E. Roman for (j = 0; j < k; j++) v[j + j * a->lda] += alpha; 3122f605a99SJose E. Roman PetscCall(PetscLogFlops(k)); 3132f605a99SJose E. Roman PetscCall(MatDenseRestoreArray(A, &v)); 3143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3152f605a99SJose E. Roman } 3162f605a99SJose E. Roman 317d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatIsHermitian_SeqDense(Mat A, PetscReal rtol, PetscBool *fl) 318d71ae5a4SJacob Faibussowitsch { 3191cbb95d3SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 320ca15aa20SStefano Zampini PetscInt i, j, m = A->rmap->n, N = a->lda; 321ca15aa20SStefano Zampini const PetscScalar *v; 3221cbb95d3SBarry Smith 3231cbb95d3SBarry Smith PetscFunctionBegin; 3241cbb95d3SBarry Smith *fl = PETSC_FALSE; 3253ba16761SJacob Faibussowitsch if (A->rmap->n != A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 3269566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 3271cbb95d3SBarry Smith for (i = 0; i < m; i++) { 328ca15aa20SStefano Zampini for (j = i; j < m; j++) { 329ad540459SPierre Jolivet if (PetscAbsScalar(v[i + j * N] - PetscConj(v[j + i * N])) > rtol) goto restore; 3301cbb95d3SBarry Smith } 331637a0070SStefano Zampini } 3321cbb95d3SBarry Smith *fl = PETSC_TRUE; 333637a0070SStefano Zampini restore: 3349566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 3353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 336637a0070SStefano Zampini } 337637a0070SStefano Zampini 338d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatIsSymmetric_SeqDense(Mat A, PetscReal rtol, PetscBool *fl) 339d71ae5a4SJacob Faibussowitsch { 340637a0070SStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 341637a0070SStefano Zampini PetscInt i, j, m = A->rmap->n, N = a->lda; 342637a0070SStefano Zampini const PetscScalar *v; 343637a0070SStefano Zampini 344637a0070SStefano Zampini PetscFunctionBegin; 345637a0070SStefano Zampini *fl = PETSC_FALSE; 3463ba16761SJacob Faibussowitsch if (A->rmap->n != A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 3479566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 348637a0070SStefano Zampini for (i = 0; i < m; i++) { 349637a0070SStefano Zampini for (j = i; j < m; j++) { 350ad540459SPierre Jolivet if (PetscAbsScalar(v[i + j * N] - v[j + i * N]) > rtol) goto restore; 351637a0070SStefano Zampini } 352637a0070SStefano Zampini } 353637a0070SStefano Zampini *fl = PETSC_TRUE; 354637a0070SStefano Zampini restore: 3559566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 3563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3571cbb95d3SBarry Smith } 3581cbb95d3SBarry Smith 359d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi, Mat A, MatDuplicateOption cpvalues) 360d71ae5a4SJacob Faibussowitsch { 361ca15aa20SStefano Zampini Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 362835f2295SStefano Zampini PetscInt lda = mat->lda, j, m, nlda = lda; 36375f6d85dSStefano Zampini PetscBool isdensecpu; 364b24902e0SBarry Smith 365b24902e0SBarry Smith PetscFunctionBegin; 3669566063dSJacob Faibussowitsch PetscCall(PetscLayoutReference(A->rmap, &newi->rmap)); 3679566063dSJacob Faibussowitsch PetscCall(PetscLayoutReference(A->cmap, &newi->cmap)); 36823fc5dcaSStefano Zampini if (cpvalues == MAT_SHARE_NONZERO_PATTERN) { /* propagate LDA */ 3699566063dSJacob Faibussowitsch PetscCall(MatDenseSetLDA(newi, lda)); 37023fc5dcaSStefano Zampini } 3719566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)newi, MATSEQDENSE, &isdensecpu)); 3729566063dSJacob Faibussowitsch if (isdensecpu) PetscCall(MatSeqDenseSetPreallocation(newi, NULL)); 373b24902e0SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 374ca15aa20SStefano Zampini const PetscScalar *av; 375ca15aa20SStefano Zampini PetscScalar *v; 376ca15aa20SStefano Zampini 3779566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 3789566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(newi, &v)); 3799566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(newi, &nlda)); 380d0f46423SBarry Smith m = A->rmap->n; 38123fc5dcaSStefano Zampini if (lda > m || nlda > m) { 3828e3a54c0SPierre Jolivet for (j = 0; j < A->cmap->n; j++) PetscCall(PetscArraycpy(PetscSafePointerPlusOffset(v, j * nlda), PetscSafePointerPlusOffset(av, j * lda), m)); 383b24902e0SBarry Smith } else { 3849566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(v, av, A->rmap->n * A->cmap->n)); 385b24902e0SBarry Smith } 3869566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(newi, &v)); 3879566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 388c956ced0SPierre Jolivet PetscCall(MatPropagateSymmetryOptions(A, newi)); 389b24902e0SBarry Smith } 3903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 391b24902e0SBarry Smith } 392b24902e0SBarry Smith 393d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDuplicate_SeqDense(Mat A, MatDuplicateOption cpvalues, Mat *newmat) 394d71ae5a4SJacob Faibussowitsch { 3953a40ed3dSBarry Smith PetscFunctionBegin; 3969566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), newmat)); 3979566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*newmat, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n)); 3989566063dSJacob Faibussowitsch PetscCall(MatSetType(*newmat, ((PetscObject)A)->type_name)); 3999566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(*newmat, A, cpvalues)); 4003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 401b24902e0SBarry Smith } 402b24902e0SBarry Smith 403d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_LU(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T) 404d71ae5a4SJacob Faibussowitsch { 405c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4064396437dSToby Isaac PetscBLASInt info; 40767e560aaSBarry Smith 4083a40ed3dSBarry Smith PetscFunctionBegin; 4099566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 410792fecdfSBarry Smith PetscCallBLAS("LAPACKgetrs", LAPACKgetrs_(T ? "T" : "N", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info)); 4119566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 412835f2295SStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "GETRS - Bad solve %" PetscBLASInt_FMT, info); 4139566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m))); 4143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4154396437dSToby Isaac } 4164396437dSToby Isaac 4174396437dSToby Isaac static PetscErrorCode MatConjugate_SeqDense(Mat); 4184396437dSToby Isaac 419d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_Cholesky(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T) 420d71ae5a4SJacob Faibussowitsch { 4214396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4224396437dSToby Isaac PetscBLASInt info; 4234396437dSToby Isaac 4244396437dSToby Isaac PetscFunctionBegin; 425b94d7dedSBarry Smith if (A->spd == PETSC_BOOL3_TRUE) { 4269566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A)); 4279566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 428792fecdfSBarry Smith PetscCallBLAS("LAPACKpotrs", LAPACKpotrs_("L", &m, &nrhs, mat->v, &mat->lda, x, &m, &info)); 4299566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 430835f2295SStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "POTRS Bad solve %" PetscBLASInt_FMT, info); 4319566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A)); 432a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX) 433b94d7dedSBarry Smith } else if (A->hermitian == PETSC_BOOL3_TRUE) { 4349566063dSJacob Faibussowitsch if (T) PetscCall(MatConjugate_SeqDense(A)); 4359566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 436792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrs", LAPACKhetrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info)); 4379566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 438835f2295SStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "HETRS Bad solve %" PetscBLASInt_FMT, info); 4399566063dSJacob Faibussowitsch if (T) PetscCall(MatConjugate_SeqDense(A)); 440a49dc2a2SStefano Zampini #endif 441a49dc2a2SStefano Zampini } else { /* symmetric case */ 4429566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 443792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrs", LAPACKsytrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info)); 4449566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 445835f2295SStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "SYTRS Bad solve %" PetscBLASInt_FMT, info); 446a49dc2a2SStefano Zampini } 4479566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m))); 4483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4494396437dSToby Isaac } 45085e2c93fSHong Zhang 451d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k) 452d71ae5a4SJacob Faibussowitsch { 4534396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4544396437dSToby Isaac PetscBLASInt info; 4554396437dSToby Isaac char trans; 4564396437dSToby Isaac 4574396437dSToby Isaac PetscFunctionBegin; 4584905a7bcSToby Isaac if (PetscDefined(USE_COMPLEX)) { 4594905a7bcSToby Isaac trans = 'C'; 4604905a7bcSToby Isaac } else { 4614905a7bcSToby Isaac trans = 'T'; 4624905a7bcSToby Isaac } 4639566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 46405fcb23eSStefano Zampini { /* lwork depends on the number of right-hand sides */ 46505fcb23eSStefano Zampini PetscBLASInt nlfwork, lfwork = -1; 46605fcb23eSStefano Zampini PetscScalar fwork; 46705fcb23eSStefano Zampini 468792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info)); 46905fcb23eSStefano Zampini nlfwork = (PetscBLASInt)PetscRealPart(fwork); 47005fcb23eSStefano Zampini if (nlfwork > mat->lfwork) { 47105fcb23eSStefano Zampini mat->lfwork = nlfwork; 47205fcb23eSStefano Zampini PetscCall(PetscFree(mat->fwork)); 47305fcb23eSStefano Zampini PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 47405fcb23eSStefano Zampini } 47505fcb23eSStefano Zampini } 476792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info)); 4779566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 478835f2295SStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %" PetscBLASInt_FMT, info); 4799566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 480792fecdfSBarry Smith PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "N", "N", &mat->rank, &nrhs, mat->v, &mat->lda, x, &ldx, &info)); 4819566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 482835f2295SStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %" PetscBLASInt_FMT, info); 4834905a7bcSToby Isaac for (PetscInt j = 0; j < nrhs; j++) { 484ad540459SPierre Jolivet for (PetscInt i = mat->rank; i < k; i++) x[j * ldx + i] = 0.; 4854905a7bcSToby Isaac } 4869566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank)))); 4873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4884905a7bcSToby Isaac } 4894905a7bcSToby Isaac 490d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k) 491d71ae5a4SJacob Faibussowitsch { 4924396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4934396437dSToby Isaac PetscBLASInt info; 4944396437dSToby Isaac 4954396437dSToby Isaac PetscFunctionBegin; 4964396437dSToby Isaac if (A->rmap->n == A->cmap->n && mat->rank == A->rmap->n) { 4979566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 498792fecdfSBarry Smith PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "T", "N", &m, &nrhs, mat->v, &mat->lda, x, &ldx, &info)); 4999566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 500835f2295SStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %" PetscBLASInt_FMT, info); 5019566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A)); 50205fcb23eSStefano Zampini { /* lwork depends on the number of right-hand sides */ 50305fcb23eSStefano Zampini PetscBLASInt nlfwork, lfwork = -1; 50405fcb23eSStefano Zampini PetscScalar fwork; 50505fcb23eSStefano Zampini 506792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info)); 50705fcb23eSStefano Zampini nlfwork = (PetscBLASInt)PetscRealPart(fwork); 50805fcb23eSStefano Zampini if (nlfwork > mat->lfwork) { 50905fcb23eSStefano Zampini mat->lfwork = nlfwork; 51005fcb23eSStefano Zampini PetscCall(PetscFree(mat->fwork)); 51105fcb23eSStefano Zampini PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 51205fcb23eSStefano Zampini } 51305fcb23eSStefano Zampini } 5149566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 515792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info)); 5169566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 517835f2295SStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %" PetscBLASInt_FMT, info); 5189566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A)); 5194396437dSToby Isaac } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "QR factored matrix cannot be used for transpose solve"); 5209566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank)))); 5213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5224396437dSToby Isaac } 5234396437dSToby Isaac 524d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_SetUp(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k) 525d71ae5a4SJacob Faibussowitsch { 5264396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 5274905a7bcSToby Isaac PetscScalar *y; 5284905a7bcSToby Isaac PetscBLASInt m = 0, k = 0; 5294905a7bcSToby Isaac 5304905a7bcSToby Isaac PetscFunctionBegin; 5319566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 5329566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 5334905a7bcSToby Isaac if (k < m) { 5349566063dSJacob Faibussowitsch PetscCall(VecCopy(xx, mat->qrrhs)); 5359566063dSJacob Faibussowitsch PetscCall(VecGetArray(mat->qrrhs, &y)); 5364905a7bcSToby Isaac } else { 5379566063dSJacob Faibussowitsch PetscCall(VecCopy(xx, yy)); 5389566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &y)); 5394905a7bcSToby Isaac } 5404396437dSToby Isaac *_y = y; 5414396437dSToby Isaac *_k = k; 5424396437dSToby Isaac *_m = m; 5433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5444396437dSToby Isaac } 5454396437dSToby Isaac 546d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_TearDown(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k) 547d71ae5a4SJacob Faibussowitsch { 5484396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 54942e9364cSSatish Balay PetscScalar *y = NULL; 5504396437dSToby Isaac PetscBLASInt m, k; 5514396437dSToby Isaac 5524396437dSToby Isaac PetscFunctionBegin; 5534396437dSToby Isaac y = *_y; 5544396437dSToby Isaac *_y = NULL; 5554396437dSToby Isaac k = *_k; 5564396437dSToby Isaac m = *_m; 5574905a7bcSToby Isaac if (k < m) { 5584905a7bcSToby Isaac PetscScalar *yv; 5599566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &yv)); 5609566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(yv, y, k)); 5619566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &yv)); 5629566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(mat->qrrhs, &y)); 5634905a7bcSToby Isaac } else { 5649566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &y)); 5654905a7bcSToby Isaac } 5663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5674905a7bcSToby Isaac } 5684905a7bcSToby Isaac 569d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_LU(Mat A, Vec xx, Vec yy) 570d71ae5a4SJacob Faibussowitsch { 57142e9364cSSatish Balay PetscScalar *y = NULL; 57242e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 5734396437dSToby Isaac 5744396437dSToby Isaac PetscFunctionBegin; 5759566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 5769566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_FALSE)); 5779566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 5783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5794396437dSToby Isaac } 5804396437dSToby Isaac 581d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_LU(Mat A, Vec xx, Vec yy) 582d71ae5a4SJacob Faibussowitsch { 58342e9364cSSatish Balay PetscScalar *y = NULL; 58442e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 5854396437dSToby Isaac 5864396437dSToby Isaac PetscFunctionBegin; 5879566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 5889566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_TRUE)); 5899566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 5903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5914396437dSToby Isaac } 5924396437dSToby Isaac 593d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Cholesky(Mat A, Vec xx, Vec yy) 594d71ae5a4SJacob Faibussowitsch { 595e54beecaSStefano Zampini PetscScalar *y = NULL; 596e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 5974396437dSToby Isaac 5984396437dSToby Isaac PetscFunctionBegin; 5999566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6009566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_FALSE)); 6019566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6034396437dSToby Isaac } 6044396437dSToby Isaac 605d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_Cholesky(Mat A, Vec xx, Vec yy) 606d71ae5a4SJacob Faibussowitsch { 607e54beecaSStefano Zampini PetscScalar *y = NULL; 608e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 6094396437dSToby Isaac 6104396437dSToby Isaac PetscFunctionBegin; 6119566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6129566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_TRUE)); 6139566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6154396437dSToby Isaac } 6164396437dSToby Isaac 617d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_QR(Mat A, Vec xx, Vec yy) 618d71ae5a4SJacob Faibussowitsch { 619e54beecaSStefano Zampini PetscScalar *y = NULL; 620e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 6214396437dSToby Isaac 6224396437dSToby Isaac PetscFunctionBegin; 6239566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6249566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k)); 6259566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6274396437dSToby Isaac } 6284396437dSToby Isaac 629d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_QR(Mat A, Vec xx, Vec yy) 630d71ae5a4SJacob Faibussowitsch { 63142e9364cSSatish Balay PetscScalar *y = NULL; 63242e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 6334396437dSToby Isaac 6344396437dSToby Isaac PetscFunctionBegin; 6359566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6369566063dSJacob Faibussowitsch PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k)); 6379566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6394396437dSToby Isaac } 6404396437dSToby Isaac 641d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_SetUp(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k) 642d71ae5a4SJacob Faibussowitsch { 6434905a7bcSToby Isaac const PetscScalar *b; 6444396437dSToby Isaac PetscScalar *y; 645bf5a80bcSToby Isaac PetscInt n, _ldb, _ldx; 646bf5a80bcSToby Isaac PetscBLASInt nrhs = 0, m = 0, k = 0, ldb = 0, ldx = 0, ldy = 0; 6474905a7bcSToby Isaac 6484905a7bcSToby Isaac PetscFunctionBegin; 6499371c9d4SSatish Balay *_ldy = 0; 6509371c9d4SSatish Balay *_m = 0; 6519371c9d4SSatish Balay *_nrhs = 0; 6529371c9d4SSatish Balay *_k = 0; 6539371c9d4SSatish Balay *_y = NULL; 6549566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 6559566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 6569566063dSJacob Faibussowitsch PetscCall(MatGetSize(B, NULL, &n)); 6579566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(n, &nrhs)); 6589566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(B, &_ldb)); 6599566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldb, &ldb)); 6609566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(X, &_ldx)); 6619566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldx, &ldx)); 662bf5a80bcSToby Isaac if (ldx < m) { 6639566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &b)); 6649566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nrhs * m, &y)); 665bf5a80bcSToby Isaac if (ldb == m) { 6669566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(y, b, ldb * nrhs)); 6674905a7bcSToby Isaac } else { 66848a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * m], &b[j * ldb], m)); 6694905a7bcSToby Isaac } 670bf5a80bcSToby Isaac ldy = m; 6719566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &b)); 6724905a7bcSToby Isaac } else { 673bf5a80bcSToby Isaac if (ldb == ldx) { 6749566063dSJacob Faibussowitsch PetscCall(MatCopy(B, X, SAME_NONZERO_PATTERN)); 6759566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &y)); 6764905a7bcSToby Isaac } else { 6779566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &y)); 6789566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &b)); 67948a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * ldx], &b[j * ldb], m)); 6809566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &b)); 6814905a7bcSToby Isaac } 682bf5a80bcSToby Isaac ldy = ldx; 6834905a7bcSToby Isaac } 6844396437dSToby Isaac *_y = y; 685bf5a80bcSToby Isaac *_ldy = ldy; 6864396437dSToby Isaac *_k = k; 6874396437dSToby Isaac *_m = m; 6884396437dSToby Isaac *_nrhs = nrhs; 6893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6904396437dSToby Isaac } 6914396437dSToby Isaac 692d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_TearDown(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k) 693d71ae5a4SJacob Faibussowitsch { 6944396437dSToby Isaac PetscScalar *y; 695bf5a80bcSToby Isaac PetscInt _ldx; 696bf5a80bcSToby Isaac PetscBLASInt k, ldy, nrhs, ldx = 0; 6974396437dSToby Isaac 6984396437dSToby Isaac PetscFunctionBegin; 6994396437dSToby Isaac y = *_y; 7004396437dSToby Isaac *_y = NULL; 7014396437dSToby Isaac k = *_k; 702bf5a80bcSToby Isaac ldy = *_ldy; 7034396437dSToby Isaac nrhs = *_nrhs; 7049566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(X, &_ldx)); 7059566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldx, &ldx)); 706bf5a80bcSToby Isaac if (ldx != ldy) { 7074905a7bcSToby Isaac PetscScalar *xv; 7089566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &xv)); 70948a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&xv[j * ldx], &y[j * ldy], k)); 7109566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(X, &xv)); 7119566063dSJacob Faibussowitsch PetscCall(PetscFree(y)); 7124905a7bcSToby Isaac } else { 7139566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(X, &y)); 7144905a7bcSToby Isaac } 7153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 71685e2c93fSHong Zhang } 71785e2c93fSHong Zhang 718d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_LU(Mat A, Mat B, Mat X) 719d71ae5a4SJacob Faibussowitsch { 7204396437dSToby Isaac PetscScalar *y; 721bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7224396437dSToby Isaac 7234396437dSToby Isaac PetscFunctionBegin; 7249566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7259566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_FALSE)); 7269566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7284396437dSToby Isaac } 7294396437dSToby Isaac 730d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_LU(Mat A, Mat B, Mat X) 731d71ae5a4SJacob Faibussowitsch { 7324396437dSToby Isaac PetscScalar *y; 733bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7344396437dSToby Isaac 7354396437dSToby Isaac PetscFunctionBegin; 7369566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7379566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_TRUE)); 7389566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7404396437dSToby Isaac } 7414396437dSToby Isaac 742d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_Cholesky(Mat A, Mat B, Mat X) 743d71ae5a4SJacob Faibussowitsch { 7444396437dSToby Isaac PetscScalar *y; 745bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7464396437dSToby Isaac 7474396437dSToby Isaac PetscFunctionBegin; 7489566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7499566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_FALSE)); 7509566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7524396437dSToby Isaac } 7534396437dSToby Isaac 754d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_Cholesky(Mat A, Mat B, Mat X) 755d71ae5a4SJacob Faibussowitsch { 7564396437dSToby Isaac PetscScalar *y; 757bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7584396437dSToby Isaac 7594396437dSToby Isaac PetscFunctionBegin; 7609566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7619566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_TRUE)); 7629566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7644396437dSToby Isaac } 7654396437dSToby Isaac 766d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_QR(Mat A, Mat B, Mat X) 767d71ae5a4SJacob Faibussowitsch { 7684396437dSToby Isaac PetscScalar *y; 769bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7704396437dSToby Isaac 7714396437dSToby Isaac PetscFunctionBegin; 7729566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7739566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k)); 7749566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7764396437dSToby Isaac } 7774396437dSToby Isaac 778d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_QR(Mat A, Mat B, Mat X) 779d71ae5a4SJacob Faibussowitsch { 7804396437dSToby Isaac PetscScalar *y; 781bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7824396437dSToby Isaac 7834396437dSToby Isaac PetscFunctionBegin; 7849566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7859566063dSJacob Faibussowitsch PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k)); 7869566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7884396437dSToby Isaac } 7894396437dSToby Isaac 790db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots, 791db4efbfdSBarry Smith rather than put it in the Mat->row slot.*/ 792*97b17b2cSPierre Jolivet PetscErrorCode MatLUFactor_SeqDense(Mat A, IS row, IS col, PETSC_UNUSED const MatFactorInfo *minfo) 793d71ae5a4SJacob Faibussowitsch { 794db4efbfdSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 795db4efbfdSBarry Smith PetscBLASInt n, m, info; 796db4efbfdSBarry Smith 797db4efbfdSBarry Smith PetscFunctionBegin; 7989566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 7999566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 8004dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); } 8013ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 8029566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 803792fecdfSBarry Smith PetscCallBLAS("LAPACKgetrf", LAPACKgetrf_(&m, &n, mat->v, &mat->lda, mat->pivots, &info)); 8049566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 8058e57ea43SSatish Balay 806835f2295SStefano Zampini PetscCheck(info >= 0, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to LU factorization %" PetscBLASInt_FMT, info); 807835f2295SStefano Zampini PetscCheck(info <= 0, PETSC_COMM_SELF, PETSC_ERR_MAT_LU_ZRPVT, "Bad LU factorization %" PetscBLASInt_FMT, info); 8088208b9aeSStefano Zampini 8094396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_LU; 8104396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_LU; 8114396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_LU; 8124396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_LU; 813d5f3da31SBarry Smith A->factortype = MAT_FACTOR_LU; 814db4efbfdSBarry Smith 8159566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 8169566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 817f6224b95SHong Zhang 8189566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((2.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3)); 8193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 820db4efbfdSBarry Smith } 821db4efbfdSBarry Smith 822*97b17b2cSPierre Jolivet static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info) 823d71ae5a4SJacob Faibussowitsch { 8244396437dSToby Isaac PetscFunctionBegin; 8259566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 826*97b17b2cSPierre Jolivet PetscUseTypeMethod(fact, lufactor, NULL, NULL, info); 8273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8284396437dSToby Isaac } 8294396437dSToby Isaac 830*97b17b2cSPierre Jolivet PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, IS col, PETSC_UNUSED const MatFactorInfo *info) 831d71ae5a4SJacob Faibussowitsch { 8324396437dSToby Isaac PetscFunctionBegin; 8334396437dSToby Isaac fact->preallocated = PETSC_TRUE; 8344396437dSToby Isaac fact->assembled = PETSC_TRUE; 8354396437dSToby Isaac fact->ops->lufactornumeric = MatLUFactorNumeric_SeqDense; 8363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8374396437dSToby Isaac } 8384396437dSToby Isaac 839a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */ 840*97b17b2cSPierre Jolivet PetscErrorCode MatCholeskyFactor_SeqDense(Mat A, IS perm, PETSC_UNUSED const MatFactorInfo *minfo) 841d71ae5a4SJacob Faibussowitsch { 842db4efbfdSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 843c5df96a5SBarry Smith PetscBLASInt info, n; 844db4efbfdSBarry Smith 845db4efbfdSBarry Smith PetscFunctionBegin; 8469566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 8473ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 848b94d7dedSBarry Smith if (A->spd == PETSC_BOOL3_TRUE) { 8499566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 850792fecdfSBarry Smith PetscCallBLAS("LAPACKpotrf", LAPACKpotrf_("L", &n, mat->v, &mat->lda, &info)); 8519566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 852a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX) 853b94d7dedSBarry Smith } else if (A->hermitian == PETSC_BOOL3_TRUE) { 8544dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); } 855a49dc2a2SStefano Zampini if (!mat->fwork) { 856a49dc2a2SStefano Zampini PetscScalar dummy; 857a49dc2a2SStefano Zampini 858a49dc2a2SStefano Zampini mat->lfwork = -1; 8599566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 860792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info)); 8619566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 86207c83e99SJose E. Roman PetscCall(PetscBLASIntCast((PetscCount)(PetscRealPart(dummy)), &mat->lfwork)); 8639566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 864a49dc2a2SStefano Zampini } 8659566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 866792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info)); 8679566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 868a49dc2a2SStefano Zampini #endif 869a49dc2a2SStefano Zampini } else { /* symmetric case */ 8704dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); } 871a49dc2a2SStefano Zampini if (!mat->fwork) { 872a49dc2a2SStefano Zampini PetscScalar dummy; 873a49dc2a2SStefano Zampini 874a49dc2a2SStefano Zampini mat->lfwork = -1; 8759566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 876792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info)); 8779566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 8786497c311SBarry Smith PetscCall(PetscBLASIntCast((PetscCount)(PetscRealPart(dummy)), &mat->lfwork)); 8799566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 880a49dc2a2SStefano Zampini } 8819566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 882792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info)); 8839566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 884a49dc2a2SStefano Zampini } 885835f2295SStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad factorization: zero pivot in row %" PetscBLASInt_FMT, info - 1); 8868208b9aeSStefano Zampini 8874396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_Cholesky; 8884396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_Cholesky; 8894396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_Cholesky; 8904396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_Cholesky; 891d5f3da31SBarry Smith A->factortype = MAT_FACTOR_CHOLESKY; 8922205254eSKarl Rupp 8939566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 8949566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 895f6224b95SHong Zhang 8969566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0)); 8973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 898db4efbfdSBarry Smith } 899db4efbfdSBarry Smith 900*97b17b2cSPierre Jolivet static PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info) 901d71ae5a4SJacob Faibussowitsch { 902db4efbfdSBarry Smith PetscFunctionBegin; 9039566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 904*97b17b2cSPierre Jolivet PetscUseTypeMethod(fact, choleskyfactor, NULL, info); 9053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 906db4efbfdSBarry Smith } 907db4efbfdSBarry Smith 908d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info) 909d71ae5a4SJacob Faibussowitsch { 910db4efbfdSBarry Smith PetscFunctionBegin; 911c3ef05f6SHong Zhang fact->assembled = PETSC_TRUE; 9121bbcc794SSatish Balay fact->preallocated = PETSC_TRUE; 913719d5645SBarry Smith fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense; 9143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 915db4efbfdSBarry Smith } 916db4efbfdSBarry Smith 917*97b17b2cSPierre Jolivet PetscErrorCode MatQRFactor_SeqDense(Mat A, IS col, PETSC_UNUSED const MatFactorInfo *minfo) 918d71ae5a4SJacob Faibussowitsch { 9194905a7bcSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 9204905a7bcSToby Isaac PetscBLASInt n, m, info, min, max; 9214905a7bcSToby Isaac 9224905a7bcSToby Isaac PetscFunctionBegin; 9239566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 9249566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 9254396437dSToby Isaac max = PetscMax(m, n); 9264396437dSToby Isaac min = PetscMin(m, n); 9274dfa11a4SJacob Faibussowitsch if (!mat->tau) { PetscCall(PetscMalloc1(min, &mat->tau)); } 9284dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(n, &mat->pivots)); } 929f4f49eeaSPierre Jolivet if (!mat->qrrhs) PetscCall(MatCreateVecs(A, NULL, &mat->qrrhs)); 9303ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 9314905a7bcSToby Isaac if (!mat->fwork) { 9324905a7bcSToby Isaac PetscScalar dummy; 9334905a7bcSToby Isaac 9344905a7bcSToby Isaac mat->lfwork = -1; 9359566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 936792fecdfSBarry Smith PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, &dummy, &mat->lfwork, &info)); 9379566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 9386497c311SBarry Smith PetscCall(PetscBLASIntCast((PetscCount)(PetscRealPart(dummy)), &mat->lfwork)); 9399566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 9404905a7bcSToby Isaac } 9419566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 942792fecdfSBarry Smith PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, mat->fwork, &mat->lfwork, &info)); 9439566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 944835f2295SStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to QR factorization %" PetscBLASInt_FMT, info); 9454905a7bcSToby 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 9464905a7bcSToby Isaac mat->rank = min; 9474905a7bcSToby Isaac 9484396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_QR; 9494396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_QR; 9504905a7bcSToby Isaac A->factortype = MAT_FACTOR_QR; 9514905a7bcSToby Isaac if (m == n) { 9524396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_QR; 9534396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_QR; 9544905a7bcSToby Isaac } 9554905a7bcSToby Isaac 9569566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 9579566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 9584905a7bcSToby Isaac 9599566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * min * min * (max - min / 3.0))); 9603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9614905a7bcSToby Isaac } 9624905a7bcSToby Isaac 963*97b17b2cSPierre Jolivet static PetscErrorCode MatQRFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info) 964d71ae5a4SJacob Faibussowitsch { 9654905a7bcSToby Isaac PetscFunctionBegin; 9669566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 967*97b17b2cSPierre Jolivet PetscUseMethod(fact, "MatQRFactor_C", (Mat, IS, const MatFactorInfo *), (fact, NULL, info)); 9683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9694905a7bcSToby Isaac } 9704905a7bcSToby Isaac 971d71ae5a4SJacob Faibussowitsch PetscErrorCode MatQRFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info) 972d71ae5a4SJacob Faibussowitsch { 9734905a7bcSToby Isaac PetscFunctionBegin; 9744905a7bcSToby Isaac fact->assembled = PETSC_TRUE; 9754905a7bcSToby Isaac fact->preallocated = PETSC_TRUE; 9769566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)fact, "MatQRFactorNumeric_C", MatQRFactorNumeric_SeqDense)); 9773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9784905a7bcSToby Isaac } 9794905a7bcSToby Isaac 980ca15aa20SStefano Zampini /* uses LAPACK */ 981d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A, MatFactorType ftype, Mat *fact) 982d71ae5a4SJacob Faibussowitsch { 983db4efbfdSBarry Smith PetscFunctionBegin; 9849566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), fact)); 9859566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*fact, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n)); 9869566063dSJacob Faibussowitsch PetscCall(MatSetType(*fact, MATDENSE)); 98766e17bc3SBarry Smith (*fact)->trivialsymbolic = PETSC_TRUE; 9882a350339SBarry Smith if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU) { 989db4efbfdSBarry Smith (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense; 9902a350339SBarry Smith (*fact)->ops->ilufactorsymbolic = MatLUFactorSymbolic_SeqDense; 991bf5a80bcSToby Isaac } else if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) { 992db4efbfdSBarry Smith (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense; 993bf5a80bcSToby Isaac } else if (ftype == MAT_FACTOR_QR) { 994f4f49eeaSPierre Jolivet PetscCall(PetscObjectComposeFunction((PetscObject)*fact, "MatQRFactorSymbolic_C", MatQRFactorSymbolic_SeqDense)); 995db4efbfdSBarry Smith } 996d5f3da31SBarry Smith (*fact)->factortype = ftype; 99700c67f3bSHong Zhang 9989566063dSJacob Faibussowitsch PetscCall(PetscFree((*fact)->solvertype)); 9999566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &(*fact)->solvertype)); 10009566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_LU])); 10019566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ILU])); 10029566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_CHOLESKY])); 10039566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ICC])); 10043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1005db4efbfdSBarry Smith } 1006db4efbfdSBarry Smith 1007d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSOR_SeqDense(Mat A, Vec bb, PetscReal omega, MatSORType flag, PetscReal shift, PetscInt its, PetscInt lits, Vec xx) 1008d71ae5a4SJacob Faibussowitsch { 1009c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1010d9ca1df4SBarry Smith PetscScalar *x, *v = mat->v, zero = 0.0, xt; 1011d9ca1df4SBarry Smith const PetscScalar *b; 1012d0f46423SBarry Smith PetscInt m = A->rmap->n, i; 101323fff9afSBarry Smith PetscBLASInt o = 1, bm = 0; 1014289bc588SBarry Smith 10153a40ed3dSBarry Smith PetscFunctionBegin; 101647d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 101708401ef6SPierre Jolivet PetscCheck(A->offloadmask != PETSC_OFFLOAD_GPU, PETSC_COMM_SELF, PETSC_ERR_SUP, "Not implemented"); 1018ca15aa20SStefano Zampini #endif 1019422a814eSBarry Smith if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */ 10209566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(m, &bm)); 1021289bc588SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 10223bffc371SBarry Smith /* this is a hack fix, should have another version without the second BLASdotu */ 10239566063dSJacob Faibussowitsch PetscCall(VecSet(xx, zero)); 1024289bc588SBarry Smith } 10259566063dSJacob Faibussowitsch PetscCall(VecGetArray(xx, &x)); 10269566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(bb, &b)); 1027b965ef7fSBarry Smith its = its * lits; 102808401ef6SPierre 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); 1029289bc588SBarry Smith while (its--) { 1030fccaa45eSBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 1031289bc588SBarry Smith for (i = 0; i < m; i++) { 1032792fecdfSBarry Smith PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o)); 1033883424caSPierre Jolivet x[i] = (1. - omega) * x[i] + (xt + v[i + i * m] * x[i]) * omega / (v[i + i * m] + shift); 1034289bc588SBarry Smith } 1035289bc588SBarry Smith } 1036fccaa45eSBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 1037289bc588SBarry Smith for (i = m - 1; i >= 0; i--) { 1038792fecdfSBarry Smith PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o)); 1039883424caSPierre Jolivet x[i] = (1. - omega) * x[i] + (xt + v[i + i * m] * x[i]) * omega / (v[i + i * m] + shift); 1040289bc588SBarry Smith } 1041289bc588SBarry Smith } 1042289bc588SBarry Smith } 10439566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(bb, &b)); 10449566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(xx, &x)); 10453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1046289bc588SBarry Smith } 1047289bc588SBarry Smith 10480be0d8bdSHansol Suh static PetscErrorCode MatMultColumnRangeKernel_SeqDense(Mat A, Vec xx, Vec yy, PetscInt c_start, PetscInt c_end, PetscBool trans, PetscBool herm) 1049d71ae5a4SJacob Faibussowitsch { 1050c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1051d9ca1df4SBarry Smith PetscScalar *y, _DOne = 1.0, _DZero = 0.0; 10520805154bSBarry Smith PetscBLASInt m, n, _One = 1; 1053d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 10543a40ed3dSBarry Smith 10553a40ed3dSBarry Smith PetscFunctionBegin; 10569566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 10570be0d8bdSHansol Suh PetscCall(PetscBLASIntCast(c_end - c_start, &n)); 10589566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 10599566063dSJacob Faibussowitsch PetscCall(VecGetArrayWrite(yy, &y)); 10600be0d8bdSHansol Suh if (!m || !n) { 10615ac36cfcSBarry Smith PetscBLASInt i; 1062459e8d23SBlanca Mellado Pinto if (trans) 1063459e8d23SBlanca Mellado Pinto for (i = 0; i < n; i++) y[i] = 0.0; 1064459e8d23SBlanca Mellado Pinto else 10655ac36cfcSBarry Smith for (i = 0; i < m; i++) y[i] = 0.0; 10665ac36cfcSBarry Smith } else { 1067459e8d23SBlanca Mellado Pinto if (trans) { 10680be0d8bdSHansol Suh if (herm) PetscCallBLAS("BLASgemv", BLASgemv_("C", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x, &_One, &_DZero, y + c_start, &_One)); 10690be0d8bdSHansol Suh else PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x, &_One, &_DZero, y + c_start, &_One)); 1070459e8d23SBlanca Mellado Pinto } else { 10710be0d8bdSHansol Suh PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x + c_start, &_One, &_DZero, y, &_One)); 1072459e8d23SBlanca Mellado Pinto } 10730be0d8bdSHansol Suh PetscCall(PetscLogFlops(2.0 * m * n - n)); 10745ac36cfcSBarry Smith } 10759566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 10769566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayWrite(yy, &y)); 10773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1078289bc588SBarry Smith } 10796ee01492SSatish Balay 10800be0d8bdSHansol Suh PetscErrorCode MatMultHermitianTransposeColumnRange_SeqDense(Mat A, Vec xx, Vec yy, PetscInt c_start, PetscInt c_end) 10810be0d8bdSHansol Suh { 10820be0d8bdSHansol Suh PetscFunctionBegin; 10830be0d8bdSHansol Suh PetscCall(MatMultColumnRangeKernel_SeqDense(A, xx, yy, c_start, c_end, PETSC_TRUE, PETSC_TRUE)); 10840be0d8bdSHansol Suh PetscFunctionReturn(PETSC_SUCCESS); 10850be0d8bdSHansol Suh } 10860be0d8bdSHansol Suh 1087459e8d23SBlanca Mellado Pinto PetscErrorCode MatMult_SeqDense(Mat A, Vec xx, Vec yy) 1088459e8d23SBlanca Mellado Pinto { 1089459e8d23SBlanca Mellado Pinto PetscFunctionBegin; 10900be0d8bdSHansol Suh PetscCall(MatMultColumnRangeKernel_SeqDense(A, xx, yy, 0, A->cmap->n, PETSC_FALSE, PETSC_FALSE)); 1091459e8d23SBlanca Mellado Pinto PetscFunctionReturn(PETSC_SUCCESS); 1092459e8d23SBlanca Mellado Pinto } 1093459e8d23SBlanca Mellado Pinto 1094459e8d23SBlanca Mellado Pinto PetscErrorCode MatMultTranspose_SeqDense(Mat A, Vec xx, Vec yy) 1095459e8d23SBlanca Mellado Pinto { 1096459e8d23SBlanca Mellado Pinto PetscFunctionBegin; 10970be0d8bdSHansol Suh PetscCall(MatMultColumnRangeKernel_SeqDense(A, xx, yy, 0, A->cmap->n, PETSC_TRUE, PETSC_FALSE)); 1098459e8d23SBlanca Mellado Pinto PetscFunctionReturn(PETSC_SUCCESS); 1099459e8d23SBlanca Mellado Pinto } 1100459e8d23SBlanca Mellado Pinto 1101459e8d23SBlanca Mellado Pinto PetscErrorCode MatMultHermitianTranspose_SeqDense(Mat A, Vec xx, Vec yy) 1102459e8d23SBlanca Mellado Pinto { 1103459e8d23SBlanca Mellado Pinto PetscFunctionBegin; 11040be0d8bdSHansol Suh PetscCall(MatMultColumnRangeKernel_SeqDense(A, xx, yy, 0, A->cmap->n, PETSC_TRUE, PETSC_TRUE)); 1105459e8d23SBlanca Mellado Pinto PetscFunctionReturn(PETSC_SUCCESS); 1106459e8d23SBlanca Mellado Pinto } 1107459e8d23SBlanca Mellado Pinto 11080be0d8bdSHansol Suh static PetscErrorCode MatMultAddColumnRangeKernel_SeqDense(Mat A, Vec xx, Vec zz, Vec yy, PetscInt c_start, PetscInt c_end, PetscBool trans, PetscBool herm) 1109d71ae5a4SJacob Faibussowitsch { 1110c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1111d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 1112d9ca1df4SBarry Smith PetscScalar *y, _DOne = 1.0; 11130805154bSBarry Smith PetscBLASInt m, n, _One = 1; 11143a40ed3dSBarry Smith 11153a40ed3dSBarry Smith PetscFunctionBegin; 11169566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 11170be0d8bdSHansol Suh PetscCall(PetscBLASIntCast(c_end - c_start, &n)); 11189566063dSJacob Faibussowitsch PetscCall(VecCopy(zz, yy)); 11190be0d8bdSHansol Suh if (!m || !n) PetscFunctionReturn(PETSC_SUCCESS); 11209566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &y)); 1121459e8d23SBlanca Mellado Pinto PetscCall(VecGetArrayRead(xx, &x)); 1122459e8d23SBlanca Mellado Pinto if (trans) { 11230be0d8bdSHansol Suh if (herm) PetscCallBLAS("BLASgemv", BLASgemv_("C", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x, &_One, &_DOne, y + c_start, &_One)); 11240be0d8bdSHansol Suh else PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x, &_One, &_DOne, y + c_start, &_One)); 1125459e8d23SBlanca Mellado Pinto } else { 11260be0d8bdSHansol Suh PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x + c_start, &_One, &_DOne, y, &_One)); 1127459e8d23SBlanca Mellado Pinto } 11289566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 11299566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &y)); 11300be0d8bdSHansol Suh PetscCall(PetscLogFlops(2.0 * m * n)); 11310be0d8bdSHansol Suh PetscFunctionReturn(PETSC_SUCCESS); 11320be0d8bdSHansol Suh } 11330be0d8bdSHansol Suh 11340be0d8bdSHansol Suh PetscErrorCode MatMultAddColumnRange_SeqDense(Mat A, Vec xx, Vec zz, Vec yy, PetscInt c_start, PetscInt c_end) 11350be0d8bdSHansol Suh { 11360be0d8bdSHansol Suh PetscFunctionBegin; 11370be0d8bdSHansol Suh PetscCall(MatMultAddColumnRangeKernel_SeqDense(A, xx, zz, yy, c_start, c_end, PETSC_FALSE, PETSC_FALSE)); 11380be0d8bdSHansol Suh PetscFunctionReturn(PETSC_SUCCESS); 11390be0d8bdSHansol Suh } 11400be0d8bdSHansol Suh 11410be0d8bdSHansol Suh PetscErrorCode MatMultHermitianTransposeAddColumnRange_SeqDense(Mat A, Vec xx, Vec zz, Vec yy, PetscInt c_start, PetscInt c_end) 11420be0d8bdSHansol Suh { 11430be0d8bdSHansol Suh PetscFunctionBegin; 11440be0d8bdSHansol Suh PetscMPIInt rank; 11450be0d8bdSHansol Suh PetscCallMPI(MPI_Comm_rank(MPI_COMM_WORLD, &rank)); 11460be0d8bdSHansol Suh PetscCall(MatMultAddColumnRangeKernel_SeqDense(A, xx, zz, yy, c_start, c_end, PETSC_TRUE, PETSC_TRUE)); 11473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1148289bc588SBarry Smith } 11496ee01492SSatish Balay 1150459e8d23SBlanca Mellado Pinto PetscErrorCode MatMultAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) 1151459e8d23SBlanca Mellado Pinto { 1152459e8d23SBlanca Mellado Pinto PetscFunctionBegin; 11530be0d8bdSHansol Suh PetscCall(MatMultAddColumnRangeKernel_SeqDense(A, xx, zz, yy, 0, A->cmap->n, PETSC_FALSE, PETSC_FALSE)); 1154459e8d23SBlanca Mellado Pinto PetscFunctionReturn(PETSC_SUCCESS); 1155459e8d23SBlanca Mellado Pinto } 1156459e8d23SBlanca Mellado Pinto 1157d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) 1158d71ae5a4SJacob Faibussowitsch { 11593a40ed3dSBarry Smith PetscFunctionBegin; 11600be0d8bdSHansol Suh PetscCall(MatMultAddColumnRangeKernel_SeqDense(A, xx, zz, yy, 0, A->cmap->n, PETSC_TRUE, PETSC_FALSE)); 1161459e8d23SBlanca Mellado Pinto PetscFunctionReturn(PETSC_SUCCESS); 1162459e8d23SBlanca Mellado Pinto } 1163459e8d23SBlanca Mellado Pinto 1164459e8d23SBlanca Mellado Pinto PetscErrorCode MatMultHermitianTransposeAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) 1165459e8d23SBlanca Mellado Pinto { 1166459e8d23SBlanca Mellado Pinto PetscFunctionBegin; 11670be0d8bdSHansol Suh PetscCall(MatMultAddColumnRangeKernel_SeqDense(A, xx, zz, yy, 0, A->cmap->n, PETSC_TRUE, PETSC_TRUE)); 11683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1169289bc588SBarry Smith } 1170289bc588SBarry Smith 1171d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals) 1172d71ae5a4SJacob Faibussowitsch { 1173c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 117413f74950SBarry Smith PetscInt i; 117567e560aaSBarry Smith 11763a40ed3dSBarry Smith PetscFunctionBegin; 1177c3e1b152SPierre Jolivet if (ncols) *ncols = A->cmap->n; 1178289bc588SBarry Smith if (cols) { 11799566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->cmap->n, cols)); 1180d0f46423SBarry Smith for (i = 0; i < A->cmap->n; i++) (*cols)[i] = i; 1181289bc588SBarry Smith } 1182289bc588SBarry Smith if (vals) { 1183ca15aa20SStefano Zampini const PetscScalar *v; 1184ca15aa20SStefano Zampini 11859566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 11869566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->cmap->n, vals)); 1187ca15aa20SStefano Zampini v += row; 11889371c9d4SSatish Balay for (i = 0; i < A->cmap->n; i++) { 11899371c9d4SSatish Balay (*vals)[i] = *v; 11909371c9d4SSatish Balay v += mat->lda; 11919371c9d4SSatish Balay } 11929566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 1193289bc588SBarry Smith } 11943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1195289bc588SBarry Smith } 11966ee01492SSatish Balay 1197d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRestoreRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals) 1198d71ae5a4SJacob Faibussowitsch { 1199606d414cSSatish Balay PetscFunctionBegin; 12009566063dSJacob Faibussowitsch if (cols) PetscCall(PetscFree(*cols)); 12019566063dSJacob Faibussowitsch if (vals) PetscCall(PetscFree(*vals)); 12023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1203289bc588SBarry Smith } 12042ef1f0ffSBarry Smith 1205d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], const PetscScalar v[], InsertMode addv) 1206d71ae5a4SJacob Faibussowitsch { 1207c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1208ca15aa20SStefano Zampini PetscScalar *av; 120913f74950SBarry Smith PetscInt i, j, idx = 0; 121047d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1211c70f7ee4SJunchao Zhang PetscOffloadMask oldf; 1212ca15aa20SStefano Zampini #endif 1213d6dfbf8fSBarry Smith 12143a40ed3dSBarry Smith PetscFunctionBegin; 12159566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &av)); 1216289bc588SBarry Smith if (!mat->roworiented) { 1217dbb450caSBarry Smith if (addv == INSERT_VALUES) { 1218289bc588SBarry Smith for (j = 0; j < n; j++) { 12199371c9d4SSatish Balay if (indexn[j] < 0) { 12209371c9d4SSatish Balay idx += m; 12219371c9d4SSatish Balay continue; 12229371c9d4SSatish Balay } 12236bdcaf15SBarry Smith PetscCheck(indexn[j] < A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Column too large: col %" PetscInt_FMT " max %" PetscInt_FMT, indexn[j], A->cmap->n - 1); 1224289bc588SBarry Smith for (i = 0; i < m; i++) { 12259371c9d4SSatish Balay if (indexm[i] < 0) { 12269371c9d4SSatish Balay idx++; 12279371c9d4SSatish Balay continue; 12289371c9d4SSatish Balay } 12296bdcaf15SBarry Smith PetscCheck(indexm[i] < A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Row too large: row %" PetscInt_FMT " max %" PetscInt_FMT, indexm[i], A->rmap->n - 1); 12308c4a67a0SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] = v ? v[idx++] : (idx++, 0.0); 1231289bc588SBarry Smith } 1232289bc588SBarry Smith } 12330be0d8bdSHansol Suh } else { 1234289bc588SBarry Smith for (j = 0; j < n; j++) { 12359371c9d4SSatish Balay if (indexn[j] < 0) { 12369371c9d4SSatish Balay idx += m; 12379371c9d4SSatish Balay continue; 12389371c9d4SSatish Balay } 12396bdcaf15SBarry Smith PetscCheck(indexn[j] < A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Column too large: col %" PetscInt_FMT " max %" PetscInt_FMT, indexn[j], A->cmap->n - 1); 1240289bc588SBarry Smith for (i = 0; i < m; i++) { 12419371c9d4SSatish Balay if (indexm[i] < 0) { 12429371c9d4SSatish Balay idx++; 12439371c9d4SSatish Balay continue; 12449371c9d4SSatish Balay } 12456bdcaf15SBarry Smith PetscCheck(indexm[i] < A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Row too large: row %" PetscInt_FMT " max %" PetscInt_FMT, indexm[i], A->rmap->n - 1); 12468c4a67a0SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] += v ? v[idx++] : (idx++, 0.0); 1247289bc588SBarry Smith } 1248289bc588SBarry Smith } 1249289bc588SBarry Smith } 12503a40ed3dSBarry Smith } else { 1251dbb450caSBarry Smith if (addv == INSERT_VALUES) { 1252e8d4e0b9SBarry Smith for (i = 0; i < m; i++) { 12539371c9d4SSatish Balay if (indexm[i] < 0) { 12549371c9d4SSatish Balay idx += n; 12559371c9d4SSatish Balay continue; 12569371c9d4SSatish Balay } 12576bdcaf15SBarry Smith PetscCheck(indexm[i] < A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Row too large: row %" PetscInt_FMT " max %" PetscInt_FMT, indexm[i], A->rmap->n - 1); 1258e8d4e0b9SBarry Smith for (j = 0; j < n; j++) { 12599371c9d4SSatish Balay if (indexn[j] < 0) { 12609371c9d4SSatish Balay idx++; 12619371c9d4SSatish Balay continue; 12629371c9d4SSatish Balay } 12636bdcaf15SBarry Smith PetscCheck(indexn[j] < A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Column too large: col %" PetscInt_FMT " max %" PetscInt_FMT, indexn[j], A->cmap->n - 1); 12648c4a67a0SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] = v ? v[idx++] : (idx++, 0.0); 1265e8d4e0b9SBarry Smith } 1266e8d4e0b9SBarry Smith } 12670be0d8bdSHansol Suh } else { 1268289bc588SBarry Smith for (i = 0; i < m; i++) { 12699371c9d4SSatish Balay if (indexm[i] < 0) { 12709371c9d4SSatish Balay idx += n; 12719371c9d4SSatish Balay continue; 12729371c9d4SSatish Balay } 12736bdcaf15SBarry Smith PetscCheck(indexm[i] < A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Row too large: row %" PetscInt_FMT " max %" PetscInt_FMT, indexm[i], A->rmap->n - 1); 1274289bc588SBarry Smith for (j = 0; j < n; j++) { 12759371c9d4SSatish Balay if (indexn[j] < 0) { 12769371c9d4SSatish Balay idx++; 12779371c9d4SSatish Balay continue; 12789371c9d4SSatish Balay } 12796bdcaf15SBarry Smith PetscCheck(indexn[j] < A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Column too large: col %" PetscInt_FMT " max %" PetscInt_FMT, indexn[j], A->cmap->n - 1); 12808c4a67a0SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] += v ? v[idx++] : (idx++, 0.0); 1281289bc588SBarry Smith } 1282289bc588SBarry Smith } 1283289bc588SBarry Smith } 1284e8d4e0b9SBarry Smith } 1285ca15aa20SStefano Zampini /* hack to prevent unneeded copy to the GPU while returning the array */ 128647d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1287c70f7ee4SJunchao Zhang oldf = A->offloadmask; 1288c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_GPU; 1289ca15aa20SStefano Zampini #endif 12909566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &av)); 129147d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1292c70f7ee4SJunchao Zhang A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU); 1293ca15aa20SStefano Zampini #endif 12943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1295289bc588SBarry Smith } 1296e8d4e0b9SBarry Smith 1297d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], PetscScalar v[]) 1298d71ae5a4SJacob Faibussowitsch { 1299ae80bb75SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1300ca15aa20SStefano Zampini const PetscScalar *vv; 130113f74950SBarry Smith PetscInt i, j; 1302ae80bb75SLois Curfman McInnes 13033a40ed3dSBarry Smith PetscFunctionBegin; 13049566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &vv)); 1305ae80bb75SLois Curfman McInnes /* row-oriented output */ 1306ae80bb75SLois Curfman McInnes for (i = 0; i < m; i++) { 13079371c9d4SSatish Balay if (indexm[i] < 0) { 13089371c9d4SSatish Balay v += n; 13099371c9d4SSatish Balay continue; 13109371c9d4SSatish Balay } 131108401ef6SPierre 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); 1312ae80bb75SLois Curfman McInnes for (j = 0; j < n; j++) { 13139371c9d4SSatish Balay if (indexn[j] < 0) { 13149371c9d4SSatish Balay v++; 13159371c9d4SSatish Balay continue; 13169371c9d4SSatish Balay } 131708401ef6SPierre 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); 1318ca15aa20SStefano Zampini *v++ = vv[indexn[j] * mat->lda + indexm[i]]; 1319ae80bb75SLois Curfman McInnes } 1320ae80bb75SLois Curfman McInnes } 13219566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &vv)); 13223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1323ae80bb75SLois Curfman McInnes } 1324ae80bb75SLois Curfman McInnes 1325d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_Dense_Binary(Mat mat, PetscViewer viewer) 1326d71ae5a4SJacob Faibussowitsch { 13278491ab44SLisandro Dalcin PetscBool skipHeader; 13288491ab44SLisandro Dalcin PetscViewerFormat format; 13293e1d7bceSPierre Jolivet PetscInt header[4], M, N, m, lda, i, j; 13303e1d7bceSPierre Jolivet PetscCount k; 13318491ab44SLisandro Dalcin const PetscScalar *v; 13328491ab44SLisandro Dalcin PetscScalar *vwork; 1333aabbc4fbSShri Abhyankar 1334aabbc4fbSShri Abhyankar PetscFunctionBegin; 13359566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 13369566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader)); 13379566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 13388491ab44SLisandro Dalcin if (skipHeader) format = PETSC_VIEWER_NATIVE; 1339aabbc4fbSShri Abhyankar 13409566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &M, &N)); 13418491ab44SLisandro Dalcin 13428491ab44SLisandro Dalcin /* write matrix header */ 13439371c9d4SSatish Balay header[0] = MAT_FILE_CLASSID; 13449371c9d4SSatish Balay header[1] = M; 13459371c9d4SSatish Balay header[2] = N; 13468491ab44SLisandro Dalcin header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M * N; 13479566063dSJacob Faibussowitsch if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer, header, 4, PETSC_INT)); 13488491ab44SLisandro Dalcin 13499566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mat, &m, NULL)); 13508491ab44SLisandro Dalcin if (format != PETSC_VIEWER_NATIVE) { 13518491ab44SLisandro Dalcin PetscInt nnz = m * N, *iwork; 13528491ab44SLisandro Dalcin /* store row lengths for each row */ 13539566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz, &iwork)); 13548491ab44SLisandro Dalcin for (i = 0; i < m; i++) iwork[i] = N; 13559566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 13568491ab44SLisandro Dalcin /* store column indices (zero start index) */ 13578491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 13589371c9d4SSatish Balay for (j = 0; j < N; j++, k++) iwork[k] = j; 13599566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 13609566063dSJacob Faibussowitsch PetscCall(PetscFree(iwork)); 13618491ab44SLisandro Dalcin } 13628491ab44SLisandro Dalcin /* store matrix values as a dense matrix in row major order */ 13639566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m * N, &vwork)); 13649566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(mat, &v)); 13659566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(mat, &lda)); 13668491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 13673e1d7bceSPierre Jolivet for (j = 0; j < N; j++, k++) vwork[k] = v[i + (size_t)lda * j]; 13689566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(mat, &v)); 13699566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, vwork, m * N, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 13709566063dSJacob Faibussowitsch PetscCall(PetscFree(vwork)); 13713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13728491ab44SLisandro Dalcin } 13738491ab44SLisandro Dalcin 1374d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLoad_Dense_Binary(Mat mat, PetscViewer viewer) 1375d71ae5a4SJacob Faibussowitsch { 13768491ab44SLisandro Dalcin PetscBool skipHeader; 13778491ab44SLisandro Dalcin PetscInt header[4], M, N, m, nz, lda, i, j, k; 13788491ab44SLisandro Dalcin PetscInt rows, cols; 13798491ab44SLisandro Dalcin PetscScalar *v, *vwork; 13808491ab44SLisandro Dalcin 13818491ab44SLisandro Dalcin PetscFunctionBegin; 13829566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 13839566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader)); 13848491ab44SLisandro Dalcin 13858491ab44SLisandro Dalcin if (!skipHeader) { 13869566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, header, 4, NULL, PETSC_INT)); 138708401ef6SPierre Jolivet PetscCheck(header[0] == MAT_FILE_CLASSID, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Not a matrix object in file"); 13889371c9d4SSatish Balay M = header[1]; 13899371c9d4SSatish Balay N = header[2]; 139008401ef6SPierre Jolivet PetscCheck(M >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix row size (%" PetscInt_FMT ") in file is negative", M); 139108401ef6SPierre Jolivet PetscCheck(N >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix column size (%" PetscInt_FMT ") in file is negative", N); 13928491ab44SLisandro Dalcin nz = header[3]; 1393aed4548fSBarry Smith PetscCheck(nz == MATRIX_BINARY_FORMAT_DENSE || nz >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Unknown matrix format %" PetscInt_FMT " in file", nz); 1394aabbc4fbSShri Abhyankar } else { 13959566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &M, &N)); 1396aed4548fSBarry 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"); 13978491ab44SLisandro Dalcin nz = MATRIX_BINARY_FORMAT_DENSE; 1398e6324fbbSBarry Smith } 1399aabbc4fbSShri Abhyankar 14008491ab44SLisandro Dalcin /* setup global sizes if not set */ 14018491ab44SLisandro Dalcin if (mat->rmap->N < 0) mat->rmap->N = M; 14028491ab44SLisandro Dalcin if (mat->cmap->N < 0) mat->cmap->N = N; 14039566063dSJacob Faibussowitsch PetscCall(MatSetUp(mat)); 14048491ab44SLisandro Dalcin /* check if global sizes are correct */ 14059566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &rows, &cols)); 1406aed4548fSBarry 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); 1407aabbc4fbSShri Abhyankar 14089566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, NULL, &N)); 14099566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mat, &m, NULL)); 14109566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(mat, &v)); 14119566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(mat, &lda)); 14128491ab44SLisandro Dalcin if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense format */ 14133e1d7bceSPierre Jolivet PetscCount nnz = (size_t)m * N; 14148491ab44SLisandro Dalcin /* read in matrix values */ 14159566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz, &vwork)); 14169566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 14178491ab44SLisandro Dalcin /* store values in column major order */ 14188491ab44SLisandro Dalcin for (j = 0; j < N; j++) 14193e1d7bceSPierre Jolivet for (i = 0; i < m; i++) v[i + (size_t)lda * j] = vwork[(size_t)i * N + j]; 14209566063dSJacob Faibussowitsch PetscCall(PetscFree(vwork)); 14218491ab44SLisandro Dalcin } else { /* matrix in file is sparse format */ 14228491ab44SLisandro Dalcin PetscInt nnz = 0, *rlens, *icols; 14238491ab44SLisandro Dalcin /* read in row lengths */ 14249566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m, &rlens)); 14259566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, rlens, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 14268491ab44SLisandro Dalcin for (i = 0; i < m; i++) nnz += rlens[i]; 14278491ab44SLisandro Dalcin /* read in column indices and values */ 14289566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(nnz, &icols, nnz, &vwork)); 14299566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, icols, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 14309566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 14318491ab44SLisandro Dalcin /* store values in column major order */ 14328491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 14339371c9d4SSatish Balay for (j = 0; j < rlens[i]; j++, k++) v[i + lda * icols[k]] = vwork[k]; 14349566063dSJacob Faibussowitsch PetscCall(PetscFree(rlens)); 14359566063dSJacob Faibussowitsch PetscCall(PetscFree2(icols, vwork)); 1436aabbc4fbSShri Abhyankar } 14379566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(mat, &v)); 14389566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY)); 14399566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY)); 14403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1441aabbc4fbSShri Abhyankar } 1442aabbc4fbSShri Abhyankar 144366976f2fSJacob Faibussowitsch static PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer) 1444d71ae5a4SJacob Faibussowitsch { 1445eb91f321SVaclav Hapla PetscBool isbinary, ishdf5; 1446eb91f321SVaclav Hapla 1447eb91f321SVaclav Hapla PetscFunctionBegin; 1448eb91f321SVaclav Hapla PetscValidHeaderSpecific(newMat, MAT_CLASSID, 1); 1449eb91f321SVaclav Hapla PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1450eb91f321SVaclav Hapla /* force binary viewer to load .info file if it has not yet done so */ 14519566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 14529566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 14539566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5)); 1454eb91f321SVaclav Hapla if (isbinary) { 14559566063dSJacob Faibussowitsch PetscCall(MatLoad_Dense_Binary(newMat, viewer)); 1456eb91f321SVaclav Hapla } else if (ishdf5) { 1457eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5) 14589566063dSJacob Faibussowitsch PetscCall(MatLoad_Dense_HDF5(newMat, viewer)); 1459eb91f321SVaclav Hapla #else 1460eb91f321SVaclav Hapla SETERRQ(PetscObjectComm((PetscObject)newMat), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1461eb91f321SVaclav Hapla #endif 1462eb91f321SVaclav Hapla } else { 146398921bdaSJacob 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); 1464eb91f321SVaclav Hapla } 14653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1466eb91f321SVaclav Hapla } 1467eb91f321SVaclav Hapla 1468d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_ASCII(Mat A, PetscViewer viewer) 1469d71ae5a4SJacob Faibussowitsch { 1470932b0c3eSLois Curfman McInnes Mat_SeqDense *a = (Mat_SeqDense *)A->data; 147113f74950SBarry Smith PetscInt i, j; 14722dcb1b2aSMatthew Knepley const char *name; 1473ca15aa20SStefano Zampini PetscScalar *v, *av; 1474f3ef73ceSBarry Smith PetscViewerFormat format; 14755f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX) 1476ace3abfcSBarry Smith PetscBool allreal = PETSC_TRUE; 14775f481a85SSatish Balay #endif 1478932b0c3eSLois Curfman McInnes 14793a40ed3dSBarry Smith PetscFunctionBegin; 14809566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&av)); 14819566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 1482456192e2SBarry Smith if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 14833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); /* do nothing for now */ 1484fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 14859566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE)); 1486d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 1487ca15aa20SStefano Zampini v = av + i; 14889566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "row %" PetscInt_FMT ":", i)); 1489d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1490aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 1491329f5518SBarry Smith if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) { 14929566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g + %g i) ", j, (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v))); 1493329f5518SBarry Smith } else if (PetscRealPart(*v)) { 14949566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)PetscRealPart(*v))); 14956831982aSBarry Smith } 149680cd9d93SLois Curfman McInnes #else 149748a46eb9SPierre Jolivet if (*v) PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)*v)); 149880cd9d93SLois Curfman McInnes #endif 14991b807ce4Svictorle v += a->lda; 150080cd9d93SLois Curfman McInnes } 15019566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 150280cd9d93SLois Curfman McInnes } 15039566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE)); 15043a40ed3dSBarry Smith } else { 15059566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE)); 1506aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 150747989497SBarry Smith /* determine if matrix has all real values */ 1508bcd8d3a4SJose E. Roman for (j = 0; j < A->cmap->n; j++) { 1509bcd8d3a4SJose E. Roman v = av + j * a->lda; 1510bcd8d3a4SJose E. Roman for (i = 0; i < A->rmap->n; i++) { 15119371c9d4SSatish Balay if (PetscImaginaryPart(v[i])) { 15129371c9d4SSatish Balay allreal = PETSC_FALSE; 15139371c9d4SSatish Balay break; 15149371c9d4SSatish Balay } 151547989497SBarry Smith } 1516bcd8d3a4SJose E. Roman } 151747989497SBarry Smith #endif 1518fb9695e5SSatish Balay if (format == PETSC_VIEWER_ASCII_MATLAB) { 15199566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)A, &name)); 15209566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%% Size = %" PetscInt_FMT " %" PetscInt_FMT " \n", A->rmap->n, A->cmap->n)); 15219566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%s = zeros(%" PetscInt_FMT ",%" PetscInt_FMT ");\n", name, A->rmap->n, A->cmap->n)); 15229566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%s = [\n", name)); 1523ffac6cdbSBarry Smith } 1524ffac6cdbSBarry Smith 1525d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 1526ca15aa20SStefano Zampini v = av + i; 1527d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1528aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 152947989497SBarry Smith if (allreal) { 15309566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)PetscRealPart(*v))); 153147989497SBarry Smith } else { 15329566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e + %18.16ei ", (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v))); 153347989497SBarry Smith } 1534289bc588SBarry Smith #else 15359566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)*v)); 1536289bc588SBarry Smith #endif 15371b807ce4Svictorle v += a->lda; 1538289bc588SBarry Smith } 15399566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 1540289bc588SBarry Smith } 154148a46eb9SPierre Jolivet if (format == PETSC_VIEWER_ASCII_MATLAB) PetscCall(PetscViewerASCIIPrintf(viewer, "];\n")); 15429566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE)); 1543da3a660dSBarry Smith } 15449566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&av)); 15459566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer)); 15463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1547289bc588SBarry Smith } 1548289bc588SBarry Smith 15499804daf3SBarry Smith #include <petscdraw.h> 1550d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw, void *Aa) 1551d71ae5a4SJacob Faibussowitsch { 1552f1af5d2fSBarry Smith Mat A = (Mat)Aa; 1553383922c3SLisandro Dalcin PetscInt m = A->rmap->n, n = A->cmap->n, i, j; 1554383922c3SLisandro Dalcin int color = PETSC_DRAW_WHITE; 1555ca15aa20SStefano Zampini const PetscScalar *v; 1556b0a32e0cSBarry Smith PetscViewer viewer; 1557b05fc000SLisandro Dalcin PetscReal xl, yl, xr, yr, x_l, x_r, y_l, y_r; 1558f3ef73ceSBarry Smith PetscViewerFormat format; 1559f1af5d2fSBarry Smith 1560f1af5d2fSBarry Smith PetscFunctionBegin; 15619566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)A, "Zoomviewer", (PetscObject *)&viewer)); 15629566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 15639566063dSJacob Faibussowitsch PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr)); 1564f1af5d2fSBarry Smith 1565f1af5d2fSBarry Smith /* Loop over matrix elements drawing boxes */ 15669566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 1567fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 1568d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 1569f1af5d2fSBarry Smith /* Blue for negative and Red for positive */ 1570f1af5d2fSBarry Smith for (j = 0; j < n; j++) { 15719371c9d4SSatish Balay x_l = j; 15729371c9d4SSatish Balay x_r = x_l + 1.0; 1573f1af5d2fSBarry Smith for (i = 0; i < m; i++) { 1574f1af5d2fSBarry Smith y_l = m - i - 1.0; 1575f1af5d2fSBarry Smith y_r = y_l + 1.0; 1576ca15aa20SStefano Zampini if (PetscRealPart(v[j * m + i]) > 0.) color = PETSC_DRAW_RED; 1577ca15aa20SStefano Zampini else if (PetscRealPart(v[j * m + i]) < 0.) color = PETSC_DRAW_BLUE; 1578ca15aa20SStefano Zampini else continue; 15799566063dSJacob Faibussowitsch PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color)); 1580f1af5d2fSBarry Smith } 1581f1af5d2fSBarry Smith } 1582d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 1583f1af5d2fSBarry Smith } else { 1584f1af5d2fSBarry Smith /* use contour shading to indicate magnitude of values */ 1585f1af5d2fSBarry Smith /* first determine max of all nonzero values */ 1586b05fc000SLisandro Dalcin PetscReal minv = 0.0, maxv = 0.0; 1587b05fc000SLisandro Dalcin PetscDraw popup; 1588b05fc000SLisandro Dalcin 1589f1af5d2fSBarry Smith for (i = 0; i < m * n; i++) { 1590f1af5d2fSBarry Smith if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]); 1591f1af5d2fSBarry Smith } 1592383922c3SLisandro Dalcin if (minv >= maxv) maxv = minv + PETSC_SMALL; 15939566063dSJacob Faibussowitsch PetscCall(PetscDrawGetPopup(draw, &popup)); 15949566063dSJacob Faibussowitsch PetscCall(PetscDrawScalePopup(popup, minv, maxv)); 1595383922c3SLisandro Dalcin 1596d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 1597f1af5d2fSBarry Smith for (j = 0; j < n; j++) { 1598f1af5d2fSBarry Smith x_l = j; 1599f1af5d2fSBarry Smith x_r = x_l + 1.0; 1600f1af5d2fSBarry Smith for (i = 0; i < m; i++) { 1601f1af5d2fSBarry Smith y_l = m - i - 1.0; 1602f1af5d2fSBarry Smith y_r = y_l + 1.0; 1603b05fc000SLisandro Dalcin color = PetscDrawRealToColor(PetscAbsScalar(v[j * m + i]), minv, maxv); 16049566063dSJacob Faibussowitsch PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color)); 1605f1af5d2fSBarry Smith } 1606f1af5d2fSBarry Smith } 1607d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 1608f1af5d2fSBarry Smith } 16099566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 16103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1611f1af5d2fSBarry Smith } 1612f1af5d2fSBarry Smith 1613d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw(Mat A, PetscViewer viewer) 1614d71ae5a4SJacob Faibussowitsch { 1615b0a32e0cSBarry Smith PetscDraw draw; 1616ace3abfcSBarry Smith PetscBool isnull; 1617329f5518SBarry Smith PetscReal xr, yr, xl, yl, h, w; 1618f1af5d2fSBarry Smith 1619f1af5d2fSBarry Smith PetscFunctionBegin; 16209566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 16219566063dSJacob Faibussowitsch PetscCall(PetscDrawIsNull(draw, &isnull)); 16223ba16761SJacob Faibussowitsch if (isnull) PetscFunctionReturn(PETSC_SUCCESS); 1623f1af5d2fSBarry Smith 16249371c9d4SSatish Balay xr = A->cmap->n; 16259371c9d4SSatish Balay yr = A->rmap->n; 16269371c9d4SSatish Balay h = yr / 10.0; 16279371c9d4SSatish Balay w = xr / 10.0; 16289371c9d4SSatish Balay xr += w; 16299371c9d4SSatish Balay yr += h; 16309371c9d4SSatish Balay xl = -w; 16319371c9d4SSatish Balay yl = -h; 16329566063dSJacob Faibussowitsch PetscCall(PetscDrawSetCoordinates(draw, xl, yl, xr, yr)); 16339566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", (PetscObject)viewer)); 16349566063dSJacob Faibussowitsch PetscCall(PetscDrawZoom(draw, MatView_SeqDense_Draw_Zoom, A)); 16359566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", NULL)); 16369566063dSJacob Faibussowitsch PetscCall(PetscDrawSave(draw)); 16373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1638f1af5d2fSBarry Smith } 1639f1af5d2fSBarry Smith 1640d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_SeqDense(Mat A, PetscViewer viewer) 1641d71ae5a4SJacob Faibussowitsch { 1642ace3abfcSBarry Smith PetscBool iascii, isbinary, isdraw; 1643932b0c3eSLois Curfman McInnes 16443a40ed3dSBarry Smith PetscFunctionBegin; 16459566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 16469566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 16479566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 16481baa6e33SBarry Smith if (iascii) PetscCall(MatView_SeqDense_ASCII(A, viewer)); 16491baa6e33SBarry Smith else if (isbinary) PetscCall(MatView_Dense_Binary(A, viewer)); 16501baa6e33SBarry Smith else if (isdraw) PetscCall(MatView_SeqDense_Draw(A, viewer)); 16513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1652932b0c3eSLois Curfman McInnes } 1653289bc588SBarry Smith 1654d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A, const PetscScalar *array) 1655d71ae5a4SJacob Faibussowitsch { 1656d3042a70SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1657d3042a70SBarry Smith 1658d3042a70SBarry Smith PetscFunctionBegin; 165928b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 166028b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 16616635c364SPierre Jolivet PetscCheck(!a->unplacedarray, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseResetArray() first"); 1662d3042a70SBarry Smith a->unplacedarray = a->v; 1663d3042a70SBarry Smith a->unplaced_user_alloc = a->user_alloc; 1664d3042a70SBarry Smith a->v = (PetscScalar *)array; 1665637a0070SStefano Zampini a->user_alloc = PETSC_TRUE; 166647d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1667c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_CPU; 1668ca15aa20SStefano Zampini #endif 16693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1670d3042a70SBarry Smith } 1671d3042a70SBarry Smith 1672d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseResetArray_SeqDense(Mat A) 1673d71ae5a4SJacob Faibussowitsch { 1674d3042a70SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1675d3042a70SBarry Smith 1676d3042a70SBarry Smith PetscFunctionBegin; 167728b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 167828b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 1679d3042a70SBarry Smith a->v = a->unplacedarray; 1680d3042a70SBarry Smith a->user_alloc = a->unplaced_user_alloc; 1681d3042a70SBarry Smith a->unplacedarray = NULL; 168247d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1683c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_CPU; 1684ca15aa20SStefano Zampini #endif 16853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1686d3042a70SBarry Smith } 1687d3042a70SBarry Smith 1688d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A, const PetscScalar *array) 1689d71ae5a4SJacob Faibussowitsch { 1690d5ea218eSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1691d5ea218eSStefano Zampini 1692d5ea218eSStefano Zampini PetscFunctionBegin; 169328b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 169428b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 16959566063dSJacob Faibussowitsch if (!a->user_alloc) PetscCall(PetscFree(a->v)); 1696d5ea218eSStefano Zampini a->v = (PetscScalar *)array; 1697d5ea218eSStefano Zampini a->user_alloc = PETSC_FALSE; 169847d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1699d5ea218eSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 1700d5ea218eSStefano Zampini #endif 17013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1702d5ea218eSStefano Zampini } 1703d5ea218eSStefano Zampini 1704d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDestroy_SeqDense(Mat mat) 1705d71ae5a4SJacob Faibussowitsch { 1706ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)mat->data; 170790f02eecSBarry Smith 17083a40ed3dSBarry Smith PetscFunctionBegin; 17093ba16761SJacob Faibussowitsch PetscCall(PetscLogObjectState((PetscObject)mat, "Rows %" PetscInt_FMT " Cols %" PetscInt_FMT, mat->rmap->n, mat->cmap->n)); 1710f4f49eeaSPierre Jolivet PetscCall(VecDestroy(&l->qrrhs)); 17119566063dSJacob Faibussowitsch PetscCall(PetscFree(l->tau)); 17129566063dSJacob Faibussowitsch PetscCall(PetscFree(l->pivots)); 17139566063dSJacob Faibussowitsch PetscCall(PetscFree(l->fwork)); 17149566063dSJacob Faibussowitsch if (!l->user_alloc) PetscCall(PetscFree(l->v)); 17159566063dSJacob Faibussowitsch if (!l->unplaced_user_alloc) PetscCall(PetscFree(l->unplacedarray)); 171628b400f6SJacob Faibussowitsch PetscCheck(!l->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 171728b400f6SJacob Faibussowitsch PetscCheck(!l->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 17189566063dSJacob Faibussowitsch PetscCall(VecDestroy(&l->cvec)); 17199566063dSJacob Faibussowitsch PetscCall(MatDestroy(&l->cmat)); 17209566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->data)); 1721dbd8c25aSHong Zhang 17229566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)mat, NULL)); 17239566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactor_C", NULL)); 17242e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorSymbolic_C", NULL)); 17252e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorNumeric_C", NULL)); 17269566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetLDA_C", NULL)); 17279566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseSetLDA_C", NULL)); 17289566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArray_C", NULL)); 17299566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArray_C", NULL)); 17309566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDensePlaceArray_C", NULL)); 17319566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseResetArray_C", NULL)); 17329566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseReplaceArray_C", NULL)); 17339566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayRead_C", NULL)); 17349566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayRead_C", NULL)); 17359566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayWrite_C", NULL)); 17369566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayWrite_C", NULL)); 17379566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqaij_C", NULL)); 17388baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 17399566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_elemental_C", NULL)); 17408baccfbdSHong Zhang #endif 1741d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 17429566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_scalapack_C", NULL)); 1743d24d4204SJose E. Roman #endif 17442bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA) 17459566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensecuda_C", NULL)); 17469566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", NULL)); 17479566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdense_C", NULL)); 17482e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensecuda_C", NULL)); 17492bf066beSStefano Zampini #endif 175047d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 175147d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensehip_C", NULL)); 175247d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensehip_seqdensehip_C", NULL)); 175347d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensehip_seqdense_C", NULL)); 175447d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensehip_C", NULL)); 175547d993e7Ssuyashtn #endif 17569566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatSeqDenseSetPreallocation_C", NULL)); 17579566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqaij_seqdense_C", NULL)); 17589566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdense_C", NULL)); 17599566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqbaij_seqdense_C", NULL)); 17609566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqsbaij_seqdense_C", NULL)); 176152c5f739Sprj- 17629566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumn_C", NULL)); 17639566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumn_C", NULL)); 17649566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVec_C", NULL)); 17659566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVec_C", NULL)); 17669566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecRead_C", NULL)); 17679566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecRead_C", NULL)); 17689566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecWrite_C", NULL)); 17699566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecWrite_C", NULL)); 17709566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetSubMatrix_C", NULL)); 17719566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreSubMatrix_C", NULL)); 17720be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatMultAddColumnRange_C", NULL)); 17730be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatMultHermitianTransposeColumnRange_C", NULL)); 17740be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatMultHermitianTransposeAddColumnRange_C", NULL)); 17753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1776289bc588SBarry Smith } 1777289bc588SBarry Smith 1778d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatTranspose_SeqDense(Mat A, MatReuse reuse, Mat *matout) 1779d71ae5a4SJacob Faibussowitsch { 1780c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 17816536e3caSStefano Zampini PetscInt k, j, m = A->rmap->n, M = mat->lda, n = A->cmap->n; 178287828ca2SBarry Smith PetscScalar *v, tmp; 178348b35521SBarry Smith 17843a40ed3dSBarry Smith PetscFunctionBegin; 17857fb60732SBarry Smith if (reuse == MAT_REUSE_MATRIX) PetscCall(MatTransposeCheckNonzeroState_Private(A, *matout)); 17866536e3caSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 17876536e3caSStefano Zampini if (m == n) { /* in place transpose */ 17889566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 1789d3e5ee88SLois Curfman McInnes for (j = 0; j < m; j++) { 1790289bc588SBarry Smith for (k = 0; k < j; k++) { 17911b807ce4Svictorle tmp = v[j + k * M]; 17921b807ce4Svictorle v[j + k * M] = v[k + j * M]; 17931b807ce4Svictorle v[k + j * M] = tmp; 1794289bc588SBarry Smith } 1795289bc588SBarry Smith } 17969566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 17976536e3caSStefano Zampini } else { /* reuse memory, temporary allocates new memory */ 17986536e3caSStefano Zampini PetscScalar *v2; 17996536e3caSStefano Zampini PetscLayout tmplayout; 18006536e3caSStefano Zampini 18019566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((size_t)m * n, &v2)); 18029566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 18036536e3caSStefano Zampini for (j = 0; j < n; j++) { 18046536e3caSStefano Zampini for (k = 0; k < m; k++) v2[j + (size_t)k * n] = v[k + (size_t)j * M]; 18056536e3caSStefano Zampini } 18069566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(v, v2, (size_t)m * n)); 18079566063dSJacob Faibussowitsch PetscCall(PetscFree(v2)); 18089566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 18096536e3caSStefano Zampini /* cleanup size dependent quantities */ 18109566063dSJacob Faibussowitsch PetscCall(VecDestroy(&mat->cvec)); 18119566063dSJacob Faibussowitsch PetscCall(MatDestroy(&mat->cmat)); 18129566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->pivots)); 18139566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->fwork)); 18146536e3caSStefano Zampini /* swap row/col layouts */ 18156497c311SBarry Smith PetscCall(PetscBLASIntCast(n, &mat->lda)); 18166536e3caSStefano Zampini tmplayout = A->rmap; 18176536e3caSStefano Zampini A->rmap = A->cmap; 18186536e3caSStefano Zampini A->cmap = tmplayout; 18196536e3caSStefano Zampini } 18203a40ed3dSBarry Smith } else { /* out-of-place transpose */ 1821d3e5ee88SLois Curfman McInnes Mat tmat; 1822ec8511deSBarry Smith Mat_SeqDense *tmatd; 182387828ca2SBarry Smith PetscScalar *v2; 1824af36a384SStefano Zampini PetscInt M2; 1825ea709b57SSatish Balay 18266536e3caSStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 18279566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &tmat)); 18289566063dSJacob Faibussowitsch PetscCall(MatSetSizes(tmat, A->cmap->n, A->rmap->n, A->cmap->n, A->rmap->n)); 18299566063dSJacob Faibussowitsch PetscCall(MatSetType(tmat, ((PetscObject)A)->type_name)); 18309566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(tmat, NULL)); 1831ca15aa20SStefano Zampini } else tmat = *matout; 1832ca15aa20SStefano Zampini 18339566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&v)); 18349566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(tmat, &v2)); 1835ec8511deSBarry Smith tmatd = (Mat_SeqDense *)tmat->data; 1836ca15aa20SStefano Zampini M2 = tmatd->lda; 1837d3e5ee88SLois Curfman McInnes for (j = 0; j < n; j++) { 1838af36a384SStefano Zampini for (k = 0; k < m; k++) v2[j + k * M2] = v[k + j * M]; 1839d3e5ee88SLois Curfman McInnes } 18409566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(tmat, &v2)); 18419566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&v)); 18429566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(tmat, MAT_FINAL_ASSEMBLY)); 18439566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(tmat, MAT_FINAL_ASSEMBLY)); 18446536e3caSStefano Zampini *matout = tmat; 184548b35521SBarry Smith } 18463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1847289bc588SBarry Smith } 1848289bc588SBarry Smith 1849d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatEqual_SeqDense(Mat A1, Mat A2, PetscBool *flg) 1850d71ae5a4SJacob Faibussowitsch { 1851c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat1 = (Mat_SeqDense *)A1->data; 1852c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat2 = (Mat_SeqDense *)A2->data; 1853ca15aa20SStefano Zampini PetscInt i; 1854ca15aa20SStefano Zampini const PetscScalar *v1, *v2; 18559ea5d5aeSSatish Balay 18563a40ed3dSBarry Smith PetscFunctionBegin; 18579371c9d4SSatish Balay if (A1->rmap->n != A2->rmap->n) { 18589371c9d4SSatish Balay *flg = PETSC_FALSE; 18593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18609371c9d4SSatish Balay } 18619371c9d4SSatish Balay if (A1->cmap->n != A2->cmap->n) { 18629371c9d4SSatish Balay *flg = PETSC_FALSE; 18633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18649371c9d4SSatish Balay } 18659566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A1, &v1)); 18669566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A2, &v2)); 1867ca15aa20SStefano Zampini for (i = 0; i < A1->cmap->n; i++) { 18689566063dSJacob Faibussowitsch PetscCall(PetscArraycmp(v1, v2, A1->rmap->n, flg)); 18693ba16761SJacob Faibussowitsch if (*flg == PETSC_FALSE) PetscFunctionReturn(PETSC_SUCCESS); 1870ca15aa20SStefano Zampini v1 += mat1->lda; 1871ca15aa20SStefano Zampini v2 += mat2->lda; 18721b807ce4Svictorle } 18739566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A1, &v1)); 18749566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A2, &v2)); 187577c4ece6SBarry Smith *flg = PETSC_TRUE; 18763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1877289bc588SBarry Smith } 1878289bc588SBarry Smith 187914277c92SJacob Faibussowitsch PetscErrorCode MatGetDiagonal_SeqDense(Mat A, Vec v) 1880d71ae5a4SJacob Faibussowitsch { 1881c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 188213f74950SBarry Smith PetscInt i, n, len; 1883ca15aa20SStefano Zampini PetscScalar *x; 1884ca15aa20SStefano Zampini const PetscScalar *vv; 188544cd7ae7SLois Curfman McInnes 18863a40ed3dSBarry Smith PetscFunctionBegin; 18879566063dSJacob Faibussowitsch PetscCall(VecGetSize(v, &n)); 18889566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 1889d0f46423SBarry Smith len = PetscMin(A->rmap->n, A->cmap->n); 18909566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &vv)); 189108401ef6SPierre Jolivet PetscCheck(n == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming mat and vec"); 1892ad540459SPierre Jolivet for (i = 0; i < len; i++) x[i] = vv[i * mat->lda + i]; 18939566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &vv)); 18949566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 18953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1896289bc588SBarry Smith } 1897289bc588SBarry Smith 1898d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDiagonalScale_SeqDense(Mat A, Vec ll, Vec rr) 1899d71ae5a4SJacob Faibussowitsch { 1900c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1901f1ceaac6SMatthew G. Knepley const PetscScalar *l, *r; 1902ca15aa20SStefano Zampini PetscScalar x, *v, *vv; 1903d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n; 190455659b69SBarry Smith 19053a40ed3dSBarry Smith PetscFunctionBegin; 19069566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &vv)); 190728988994SBarry Smith if (ll) { 19089566063dSJacob Faibussowitsch PetscCall(VecGetSize(ll, &m)); 19099566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(ll, &l)); 191008401ef6SPierre Jolivet PetscCheck(m == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Left scaling vec wrong size"); 1911da3a660dSBarry Smith for (i = 0; i < m; i++) { 1912da3a660dSBarry Smith x = l[i]; 1913ca15aa20SStefano Zampini v = vv + i; 19149371c9d4SSatish Balay for (j = 0; j < n; j++) { 19159371c9d4SSatish Balay (*v) *= x; 19169371c9d4SSatish Balay v += mat->lda; 19179371c9d4SSatish Balay } 1918da3a660dSBarry Smith } 19199566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(ll, &l)); 19209566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * n * m)); 1921da3a660dSBarry Smith } 192228988994SBarry Smith if (rr) { 19239566063dSJacob Faibussowitsch PetscCall(VecGetSize(rr, &n)); 19249566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(rr, &r)); 192508401ef6SPierre Jolivet PetscCheck(n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Right scaling vec wrong size"); 1926da3a660dSBarry Smith for (i = 0; i < n; i++) { 1927da3a660dSBarry Smith x = r[i]; 1928ca15aa20SStefano Zampini v = vv + i * mat->lda; 19292205254eSKarl Rupp for (j = 0; j < m; j++) (*v++) *= x; 1930da3a660dSBarry Smith } 19319566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(rr, &r)); 19329566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * n * m)); 1933da3a660dSBarry Smith } 19349566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &vv)); 19353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1936289bc588SBarry Smith } 1937289bc588SBarry Smith 1938d71ae5a4SJacob Faibussowitsch PetscErrorCode MatNorm_SeqDense(Mat A, NormType type, PetscReal *nrm) 1939d71ae5a4SJacob Faibussowitsch { 1940c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1941ca15aa20SStefano Zampini PetscScalar *v, *vv; 1942329f5518SBarry Smith PetscReal sum = 0.0; 194375f6d85dSStefano Zampini PetscInt lda, m = A->rmap->n, i, j; 194455659b69SBarry Smith 19453a40ed3dSBarry Smith PetscFunctionBegin; 19469566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&vv)); 19479566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(A, &lda)); 1948ca15aa20SStefano Zampini v = vv; 1949289bc588SBarry Smith if (type == NORM_FROBENIUS) { 1950a5ce6ee0Svictorle if (lda > m) { 1951d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1952ca15aa20SStefano Zampini v = vv + j * lda; 1953a5ce6ee0Svictorle for (i = 0; i < m; i++) { 19549371c9d4SSatish Balay sum += PetscRealPart(PetscConj(*v) * (*v)); 19559371c9d4SSatish Balay v++; 1956a5ce6ee0Svictorle } 1957a5ce6ee0Svictorle } 1958a5ce6ee0Svictorle } else { 1959570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16) 1960570b7f6dSBarry Smith PetscBLASInt one = 1, cnt = A->cmap->n * A->rmap->n; 1961792fecdfSBarry Smith PetscCallBLAS("BLASnrm2", *nrm = BLASnrm2_(&cnt, v, &one)); 1962570b7f6dSBarry Smith } 1963570b7f6dSBarry Smith #else 1964d0f46423SBarry Smith for (i = 0; i < A->cmap->n * A->rmap->n; i++) { 19659371c9d4SSatish Balay sum += PetscRealPart(PetscConj(*v) * (*v)); 19669371c9d4SSatish Balay v++; 1967289bc588SBarry Smith } 1968a5ce6ee0Svictorle } 19698f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 1970570b7f6dSBarry Smith #endif 19719566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->cmap->n * A->rmap->n)); 19723a40ed3dSBarry Smith } else if (type == NORM_1) { 1973064f8208SBarry Smith *nrm = 0.0; 1974d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1975ca15aa20SStefano Zampini v = vv + j * mat->lda; 1976289bc588SBarry Smith sum = 0.0; 1977d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 19789371c9d4SSatish Balay sum += PetscAbsScalar(*v); 19799371c9d4SSatish Balay v++; 1980289bc588SBarry Smith } 1981064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 1982289bc588SBarry Smith } 19839566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n)); 19843a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 1985064f8208SBarry Smith *nrm = 0.0; 1986d0f46423SBarry Smith for (j = 0; j < A->rmap->n; j++) { 1987ca15aa20SStefano Zampini v = vv + j; 1988289bc588SBarry Smith sum = 0.0; 1989d0f46423SBarry Smith for (i = 0; i < A->cmap->n; i++) { 19909371c9d4SSatish Balay sum += PetscAbsScalar(*v); 19919371c9d4SSatish Balay v += mat->lda; 1992289bc588SBarry Smith } 1993064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 1994289bc588SBarry Smith } 19959566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n)); 1996e7e72b3dSBarry Smith } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "No two norm"); 19979566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&vv)); 19983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1999289bc588SBarry Smith } 2000289bc588SBarry Smith 2001d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetOption_SeqDense(Mat A, MatOption op, PetscBool flg) 2002d71ae5a4SJacob Faibussowitsch { 2003c0bbcb79SLois Curfman McInnes Mat_SeqDense *aij = (Mat_SeqDense *)A->data; 200467e560aaSBarry Smith 20053a40ed3dSBarry Smith PetscFunctionBegin; 2006b5a2b587SKris Buschelman switch (op) { 2007d71ae5a4SJacob Faibussowitsch case MAT_ROW_ORIENTED: 2008d71ae5a4SJacob Faibussowitsch aij->roworiented = flg; 2009d71ae5a4SJacob Faibussowitsch break; 2010d71ae5a4SJacob Faibussowitsch default: 2011888c827cSStefano Zampini break; 20123a40ed3dSBarry Smith } 20133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2014289bc588SBarry Smith } 2015289bc588SBarry Smith 2016d71ae5a4SJacob Faibussowitsch PetscErrorCode MatZeroEntries_SeqDense(Mat A) 2017d71ae5a4SJacob Faibussowitsch { 2018ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)A->data; 20193d8925e7SStefano Zampini PetscInt lda = l->lda, m = A->rmap->n, n = A->cmap->n, j; 2020ca15aa20SStefano Zampini PetscScalar *v; 20213a40ed3dSBarry Smith 20223a40ed3dSBarry Smith PetscFunctionBegin; 20239566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(A, &v)); 2024a5ce6ee0Svictorle if (lda > m) { 202548a46eb9SPierre Jolivet for (j = 0; j < n; j++) PetscCall(PetscArrayzero(v + j * lda, m)); 2026a5ce6ee0Svictorle } else { 20279566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(v, PetscInt64Mult(m, n))); 2028a5ce6ee0Svictorle } 20299566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(A, &v)); 20303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 20316f0a148fSBarry Smith } 20326f0a148fSBarry Smith 2033d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatZeroRows_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) 2034d71ae5a4SJacob Faibussowitsch { 2035ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)A->data; 2036b9679d65SBarry Smith PetscInt m = l->lda, n = A->cmap->n, i, j; 2037ca15aa20SStefano Zampini PetscScalar *slot, *bb, *v; 203897b48c8fSBarry Smith const PetscScalar *xx; 203955659b69SBarry Smith 20403a40ed3dSBarry Smith PetscFunctionBegin; 204176bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 2042b9679d65SBarry Smith for (i = 0; i < N; i++) { 204308401ef6SPierre Jolivet PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed"); 204408401ef6SPierre 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); 2045b9679d65SBarry Smith } 204676bd3646SJed Brown } 20473ba16761SJacob Faibussowitsch if (!N) PetscFunctionReturn(PETSC_SUCCESS); 2048b9679d65SBarry Smith 2049dd8e379bSPierre Jolivet /* fix right-hand side if needed */ 205097b48c8fSBarry Smith if (x && b) { 20519566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 20529566063dSJacob Faibussowitsch PetscCall(VecGetArray(b, &bb)); 20532205254eSKarl Rupp for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]]; 20549566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 20559566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(b, &bb)); 205697b48c8fSBarry Smith } 205797b48c8fSBarry Smith 20589566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 20596f0a148fSBarry Smith for (i = 0; i < N; i++) { 2060ca15aa20SStefano Zampini slot = v + rows[i]; 20619371c9d4SSatish Balay for (j = 0; j < n; j++) { 20629371c9d4SSatish Balay *slot = 0.0; 20639371c9d4SSatish Balay slot += m; 20649371c9d4SSatish Balay } 20656f0a148fSBarry Smith } 2066f4df32b1SMatthew Knepley if (diag != 0.0) { 206708401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices"); 20686f0a148fSBarry Smith for (i = 0; i < N; i++) { 2069ca15aa20SStefano Zampini slot = v + (m + 1) * rows[i]; 2070f4df32b1SMatthew Knepley *slot = diag; 20716f0a148fSBarry Smith } 20726f0a148fSBarry Smith } 20739566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 20743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 20756f0a148fSBarry Smith } 2076557bce09SLois Curfman McInnes 2077d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A, PetscInt *lda) 2078d71ae5a4SJacob Faibussowitsch { 207949a6ff4bSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 208049a6ff4bSBarry Smith 208149a6ff4bSBarry Smith PetscFunctionBegin; 208249a6ff4bSBarry Smith *lda = mat->lda; 20833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 208449a6ff4bSBarry Smith } 208549a6ff4bSBarry Smith 2086d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArray_SeqDense(Mat A, PetscScalar **array) 2087d71ae5a4SJacob Faibussowitsch { 2088c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 20893a40ed3dSBarry Smith 20903a40ed3dSBarry Smith PetscFunctionBegin; 209128b400f6SJacob Faibussowitsch PetscCheck(!mat->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 209264e87e97SBarry Smith *array = mat->v; 20933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 209464e87e97SBarry Smith } 20950754003eSLois Curfman McInnes 2096d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A, PetscScalar **array) 2097d71ae5a4SJacob Faibussowitsch { 20983a40ed3dSBarry Smith PetscFunctionBegin; 209975f6d85dSStefano Zampini if (array) *array = NULL; 21003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2101ff14e315SSatish Balay } 21020754003eSLois Curfman McInnes 21030f74d2c1SSatish Balay /*@ 210411a5261eSBarry Smith MatDenseGetLDA - gets the leading dimension of the array returned from `MatDenseGetArray()` 210549a6ff4bSBarry Smith 21062ef1f0ffSBarry Smith Not Collective 210749a6ff4bSBarry Smith 210849a6ff4bSBarry Smith Input Parameter: 2109fe59aa6dSJacob Faibussowitsch . A - a `MATDENSE` or `MATDENSECUDA` matrix 211049a6ff4bSBarry Smith 211149a6ff4bSBarry Smith Output Parameter: 211249a6ff4bSBarry Smith . lda - the leading dimension 211349a6ff4bSBarry Smith 211449a6ff4bSBarry Smith Level: intermediate 211549a6ff4bSBarry Smith 21161cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseSetLDA()` 211749a6ff4bSBarry Smith @*/ 2118d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetLDA(Mat A, PetscInt *lda) 2119d71ae5a4SJacob Faibussowitsch { 212049a6ff4bSBarry Smith PetscFunctionBegin; 2121d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 21224f572ea9SToby Isaac PetscAssertPointer(lda, 2); 212375f6d85dSStefano Zampini MatCheckPreallocated(A, 1); 2124cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetLDA_C", (Mat, PetscInt *), (A, lda)); 21253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 212649a6ff4bSBarry Smith } 212749a6ff4bSBarry Smith 21280f74d2c1SSatish Balay /*@ 212911a5261eSBarry Smith MatDenseSetLDA - Sets the leading dimension of the array used by the `MATDENSE` matrix 2130ad16ce7aSStefano Zampini 21312323109cSBarry Smith Collective if the matrix layouts have not yet been setup 2132ad16ce7aSStefano Zampini 2133d8d19677SJose E. Roman Input Parameters: 2134fe59aa6dSJacob Faibussowitsch + A - a `MATDENSE` or `MATDENSECUDA` matrix 2135ad16ce7aSStefano Zampini - lda - the leading dimension 2136ad16ce7aSStefano Zampini 2137ad16ce7aSStefano Zampini Level: intermediate 2138ad16ce7aSStefano Zampini 21391cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetLDA()` 2140ad16ce7aSStefano Zampini @*/ 2141d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA(Mat A, PetscInt lda) 2142d71ae5a4SJacob Faibussowitsch { 2143ad16ce7aSStefano Zampini PetscFunctionBegin; 2144ad16ce7aSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2145cac4c232SBarry Smith PetscTryMethod(A, "MatDenseSetLDA_C", (Mat, PetscInt), (A, lda)); 21463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2147ad16ce7aSStefano Zampini } 2148ad16ce7aSStefano Zampini 2149ad16ce7aSStefano Zampini /*@C 215011a5261eSBarry Smith MatDenseGetArray - gives read-write access to the array where the data for a `MATDENSE` matrix is stored 215173a71a0fSBarry Smith 2152c3339decSBarry Smith Logically Collective 215373a71a0fSBarry Smith 215473a71a0fSBarry Smith Input Parameter: 2155fe59aa6dSJacob Faibussowitsch . A - a dense matrix 215673a71a0fSBarry Smith 215773a71a0fSBarry Smith Output Parameter: 215873a71a0fSBarry Smith . array - pointer to the data 215973a71a0fSBarry Smith 216073a71a0fSBarry Smith Level: intermediate 216173a71a0fSBarry Smith 21621cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 216373a71a0fSBarry Smith @*/ 2164ce78bad3SBarry Smith PetscErrorCode MatDenseGetArray(Mat A, PetscScalar *array[]) PeNS 2165d71ae5a4SJacob Faibussowitsch { 216673a71a0fSBarry Smith PetscFunctionBegin; 2167d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 21684f572ea9SToby Isaac PetscAssertPointer(array, 2); 2169cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array)); 21703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 217173a71a0fSBarry Smith } 217273a71a0fSBarry Smith 2173dec5eb66SMatthew G Knepley /*@C 217411a5261eSBarry Smith MatDenseRestoreArray - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArray()` 217573a71a0fSBarry Smith 2176c3339decSBarry Smith Logically Collective 21778572280aSBarry Smith 21788572280aSBarry Smith Input Parameters: 2179fe59aa6dSJacob Faibussowitsch + A - a dense matrix 21802ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`) 21818572280aSBarry Smith 21828572280aSBarry Smith Level: intermediate 21838572280aSBarry Smith 21841cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 21858572280aSBarry Smith @*/ 2186ce78bad3SBarry Smith PetscErrorCode MatDenseRestoreArray(Mat A, PetscScalar *array[]) PeNS 2187d71ae5a4SJacob Faibussowitsch { 21888572280aSBarry Smith PetscFunctionBegin; 2189d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 21904f572ea9SToby Isaac if (array) PetscAssertPointer(array, 2); 2191cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array)); 21929566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)A)); 219347d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 2194637a0070SStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 2195637a0070SStefano Zampini #endif 21963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 21978572280aSBarry Smith } 21988572280aSBarry Smith 21998572280aSBarry Smith /*@C 220011a5261eSBarry Smith MatDenseGetArrayRead - gives read-only access to the array where the data for a `MATDENSE` matrix is stored 22018572280aSBarry Smith 2202fb850c59SBarry Smith Not Collective 22038572280aSBarry Smith 22048572280aSBarry Smith Input Parameter: 2205fe59aa6dSJacob Faibussowitsch . A - a dense matrix 22068572280aSBarry Smith 22078572280aSBarry Smith Output Parameter: 22088572280aSBarry Smith . array - pointer to the data 22098572280aSBarry Smith 22108572280aSBarry Smith Level: intermediate 22118572280aSBarry Smith 22121cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 22138572280aSBarry Smith @*/ 2214ce78bad3SBarry Smith PetscErrorCode MatDenseGetArrayRead(Mat A, const PetscScalar *array[]) PeNS 2215d71ae5a4SJacob Faibussowitsch { 22168572280aSBarry Smith PetscFunctionBegin; 2217d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22184f572ea9SToby Isaac PetscAssertPointer(array, 2); 22195c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 22203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22218572280aSBarry Smith } 22228572280aSBarry Smith 22238572280aSBarry Smith /*@C 222411a5261eSBarry Smith MatDenseRestoreArrayRead - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayRead()` 22258572280aSBarry Smith 2226fb850c59SBarry Smith Not Collective 222773a71a0fSBarry Smith 222873a71a0fSBarry Smith Input Parameters: 2229fe59aa6dSJacob Faibussowitsch + A - a dense matrix 22302ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`) 223173a71a0fSBarry Smith 223273a71a0fSBarry Smith Level: intermediate 223373a71a0fSBarry Smith 22341cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 223573a71a0fSBarry Smith @*/ 2236ce78bad3SBarry Smith PetscErrorCode MatDenseRestoreArrayRead(Mat A, const PetscScalar *array[]) PeNS 2237d71ae5a4SJacob Faibussowitsch { 223873a71a0fSBarry Smith PetscFunctionBegin; 2239d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22404f572ea9SToby Isaac if (array) PetscAssertPointer(array, 2); 22415c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 22423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 224373a71a0fSBarry Smith } 224473a71a0fSBarry Smith 22456947451fSStefano Zampini /*@C 224611a5261eSBarry Smith MatDenseGetArrayWrite - gives write-only access to the array where the data for a `MATDENSE` matrix is stored 22476947451fSStefano Zampini 2248fb850c59SBarry Smith Not Collective 22496947451fSStefano Zampini 22506947451fSStefano Zampini Input Parameter: 2251fe59aa6dSJacob Faibussowitsch . A - a dense matrix 22526947451fSStefano Zampini 22536947451fSStefano Zampini Output Parameter: 22546947451fSStefano Zampini . array - pointer to the data 22556947451fSStefano Zampini 22566947451fSStefano Zampini Level: intermediate 22576947451fSStefano Zampini 22581cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()` 22596947451fSStefano Zampini @*/ 2260ce78bad3SBarry Smith PetscErrorCode MatDenseGetArrayWrite(Mat A, PetscScalar *array[]) PeNS 2261d71ae5a4SJacob Faibussowitsch { 22626947451fSStefano Zampini PetscFunctionBegin; 2263d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22644f572ea9SToby Isaac PetscAssertPointer(array, 2); 2265cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array)); 22663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22676947451fSStefano Zampini } 22686947451fSStefano Zampini 22696947451fSStefano Zampini /*@C 227011a5261eSBarry Smith MatDenseRestoreArrayWrite - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayWrite()` 22716947451fSStefano Zampini 2272fb850c59SBarry Smith Not Collective 22736947451fSStefano Zampini 22746947451fSStefano Zampini Input Parameters: 2275fe59aa6dSJacob Faibussowitsch + A - a dense matrix 22762ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`) 22776947451fSStefano Zampini 22786947451fSStefano Zampini Level: intermediate 22796947451fSStefano Zampini 22801cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()` 22816947451fSStefano Zampini @*/ 2282ce78bad3SBarry Smith PetscErrorCode MatDenseRestoreArrayWrite(Mat A, PetscScalar *array[]) PeNS 2283d71ae5a4SJacob Faibussowitsch { 22846947451fSStefano Zampini PetscFunctionBegin; 2285d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22864f572ea9SToby Isaac if (array) PetscAssertPointer(array, 2); 2287cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array)); 22889566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)A)); 228947d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 22906947451fSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 22916947451fSStefano Zampini #endif 22923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22936947451fSStefano Zampini } 22946947451fSStefano Zampini 2295cd3f9d89SJunchao Zhang /*@C 2296cd3f9d89SJunchao Zhang MatDenseGetArrayAndMemType - gives read-write access to the array where the data for a `MATDENSE` matrix is stored 2297cd3f9d89SJunchao Zhang 2298cd3f9d89SJunchao Zhang Logically Collective 2299cd3f9d89SJunchao Zhang 2300cd3f9d89SJunchao Zhang Input Parameter: 2301fe59aa6dSJacob Faibussowitsch . A - a dense matrix 2302cd3f9d89SJunchao Zhang 2303cd3f9d89SJunchao Zhang Output Parameters: 2304cd3f9d89SJunchao Zhang + array - pointer to the data 2305cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer 2306cd3f9d89SJunchao Zhang 2307cd3f9d89SJunchao Zhang Level: intermediate 2308cd3f9d89SJunchao Zhang 2309fb850c59SBarry Smith Note: 23102ef1f0ffSBarry Smith If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc., 23112ef1f0ffSBarry Smith an array on device is always returned and is guaranteed to contain the matrix's latest data. 23122ef1f0ffSBarry Smith 23131cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayAndMemType()`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArrayWriteAndMemType()`, `MatDenseGetArrayRead()`, 2314cd3f9d89SJunchao Zhang `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()` 2315cd3f9d89SJunchao Zhang @*/ 23165d83a8b1SBarry Smith PetscErrorCode MatDenseGetArrayAndMemType(Mat A, PetscScalar *array[], PetscMemType *mtype) 2317cd3f9d89SJunchao Zhang { 2318cd3f9d89SJunchao Zhang PetscBool isMPI; 2319cd3f9d89SJunchao Zhang 2320cd3f9d89SJunchao Zhang PetscFunctionBegin; 2321cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 23224f572ea9SToby Isaac PetscAssertPointer(array, 2); 2323e865de01SJunchao 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 */ 2324cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2325cd3f9d89SJunchao Zhang if (isMPI) { 2326cd3f9d89SJunchao Zhang /* Dispatch here so that the code can be reused for all subclasses of MATDENSE */ 2327cd3f9d89SJunchao Zhang PetscCall(MatDenseGetArrayAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype)); 2328cd3f9d89SJunchao Zhang } else { 2329cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **, PetscMemType *); 23303ba16761SJacob Faibussowitsch 23313ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayAndMemType_C", &fptr)); 2332cd3f9d89SJunchao Zhang if (fptr) { 2333cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array, mtype)); 2334cd3f9d89SJunchao Zhang } else { 2335cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array)); 2336cd3f9d89SJunchao Zhang if (mtype) *mtype = PETSC_MEMTYPE_HOST; 2337cd3f9d89SJunchao Zhang } 2338cd3f9d89SJunchao Zhang } 23393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2340cd3f9d89SJunchao Zhang } 2341cd3f9d89SJunchao Zhang 2342cd3f9d89SJunchao Zhang /*@C 2343cd3f9d89SJunchao Zhang MatDenseRestoreArrayAndMemType - returns access to the array that is obtained by `MatDenseGetArrayAndMemType()` 2344cd3f9d89SJunchao Zhang 2345cd3f9d89SJunchao Zhang Logically Collective 2346cd3f9d89SJunchao Zhang 2347cd3f9d89SJunchao Zhang Input Parameters: 2348fe59aa6dSJacob Faibussowitsch + A - a dense matrix 2349cd3f9d89SJunchao Zhang - array - pointer to the data 2350cd3f9d89SJunchao Zhang 2351cd3f9d89SJunchao Zhang Level: intermediate 2352cd3f9d89SJunchao Zhang 23531cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 2354cd3f9d89SJunchao Zhang @*/ 23555d83a8b1SBarry Smith PetscErrorCode MatDenseRestoreArrayAndMemType(Mat A, PetscScalar *array[]) 2356cd3f9d89SJunchao Zhang { 2357cd3f9d89SJunchao Zhang PetscBool isMPI; 2358cd3f9d89SJunchao Zhang 2359cd3f9d89SJunchao Zhang PetscFunctionBegin; 2360cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2361fd5c2d83SStefano Zampini if (array) PetscAssertPointer(array, 2); 2362cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2363cd3f9d89SJunchao Zhang if (isMPI) { 2364cd3f9d89SJunchao Zhang PetscCall(MatDenseRestoreArrayAndMemType(((Mat_MPIDense *)A->data)->A, array)); 2365cd3f9d89SJunchao Zhang } else { 2366cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **); 23673ba16761SJacob Faibussowitsch 23683ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayAndMemType_C", &fptr)); 2369cd3f9d89SJunchao Zhang if (fptr) { 2370cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array)); 2371cd3f9d89SJunchao Zhang } else { 2372cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array)); 2373cd3f9d89SJunchao Zhang } 2374fd5c2d83SStefano Zampini if (array) *array = NULL; 2375cd3f9d89SJunchao Zhang } 2376cd3f9d89SJunchao Zhang PetscCall(PetscObjectStateIncrease((PetscObject)A)); 23773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2378cd3f9d89SJunchao Zhang } 2379cd3f9d89SJunchao Zhang 2380cd3f9d89SJunchao Zhang /*@C 2381cd3f9d89SJunchao Zhang MatDenseGetArrayReadAndMemType - gives read-only access to the array where the data for a `MATDENSE` matrix is stored 2382cd3f9d89SJunchao Zhang 2383cd3f9d89SJunchao Zhang Logically Collective 2384cd3f9d89SJunchao Zhang 2385cd3f9d89SJunchao Zhang Input Parameter: 2386fe59aa6dSJacob Faibussowitsch . A - a dense matrix 2387cd3f9d89SJunchao Zhang 2388cd3f9d89SJunchao Zhang Output Parameters: 2389cd3f9d89SJunchao Zhang + array - pointer to the data 2390cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer 2391cd3f9d89SJunchao Zhang 2392cd3f9d89SJunchao Zhang Level: intermediate 2393cd3f9d89SJunchao Zhang 2394fb850c59SBarry Smith Note: 23952ef1f0ffSBarry Smith If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc., 23962ef1f0ffSBarry Smith an array on device is always returned and is guaranteed to contain the matrix's latest data. 23972ef1f0ffSBarry Smith 23981cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayReadAndMemType()`, `MatDenseGetArrayWriteAndMemType()`, 2399cd3f9d89SJunchao Zhang `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()` 2400cd3f9d89SJunchao Zhang @*/ 24015d83a8b1SBarry Smith PetscErrorCode MatDenseGetArrayReadAndMemType(Mat A, const PetscScalar *array[], PetscMemType *mtype) 2402cd3f9d89SJunchao Zhang { 2403cd3f9d89SJunchao Zhang PetscBool isMPI; 2404cd3f9d89SJunchao Zhang 2405cd3f9d89SJunchao Zhang PetscFunctionBegin; 2406cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 24074f572ea9SToby Isaac PetscAssertPointer(array, 2); 2408e865de01SJunchao 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 */ 2409cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2410cd3f9d89SJunchao Zhang if (isMPI) { /* Dispatch here so that the code can be reused for all subclasses of MATDENSE */ 2411cd3f9d89SJunchao Zhang PetscCall(MatDenseGetArrayReadAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype)); 2412cd3f9d89SJunchao Zhang } else { 2413cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, const PetscScalar **, PetscMemType *); 24143ba16761SJacob Faibussowitsch 24153ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayReadAndMemType_C", &fptr)); 2416cd3f9d89SJunchao Zhang if (fptr) { 2417cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array, mtype)); 2418cd3f9d89SJunchao Zhang } else { 24195c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 2420cd3f9d89SJunchao Zhang if (mtype) *mtype = PETSC_MEMTYPE_HOST; 2421cd3f9d89SJunchao Zhang } 2422cd3f9d89SJunchao Zhang } 24233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2424cd3f9d89SJunchao Zhang } 2425cd3f9d89SJunchao Zhang 2426cd3f9d89SJunchao Zhang /*@C 2427cd3f9d89SJunchao Zhang MatDenseRestoreArrayReadAndMemType - returns access to the array that is obtained by `MatDenseGetArrayReadAndMemType()` 2428cd3f9d89SJunchao Zhang 2429cd3f9d89SJunchao Zhang Logically Collective 2430cd3f9d89SJunchao Zhang 2431cd3f9d89SJunchao Zhang Input Parameters: 2432fe59aa6dSJacob Faibussowitsch + A - a dense matrix 2433cd3f9d89SJunchao Zhang - array - pointer to the data 2434cd3f9d89SJunchao Zhang 2435cd3f9d89SJunchao Zhang Level: intermediate 2436cd3f9d89SJunchao Zhang 24371cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 2438cd3f9d89SJunchao Zhang @*/ 24395d83a8b1SBarry Smith PetscErrorCode MatDenseRestoreArrayReadAndMemType(Mat A, const PetscScalar *array[]) 2440cd3f9d89SJunchao Zhang { 2441cd3f9d89SJunchao Zhang PetscBool isMPI; 2442cd3f9d89SJunchao Zhang 2443cd3f9d89SJunchao Zhang PetscFunctionBegin; 2444cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2445fd5c2d83SStefano Zampini if (array) PetscAssertPointer(array, 2); 2446cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2447cd3f9d89SJunchao Zhang if (isMPI) { 2448cd3f9d89SJunchao Zhang PetscCall(MatDenseRestoreArrayReadAndMemType(((Mat_MPIDense *)A->data)->A, array)); 2449cd3f9d89SJunchao Zhang } else { 2450cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, const PetscScalar **); 24513ba16761SJacob Faibussowitsch 24523ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayReadAndMemType_C", &fptr)); 2453cd3f9d89SJunchao Zhang if (fptr) { 2454cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array)); 2455cd3f9d89SJunchao Zhang } else { 24565c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 2457cd3f9d89SJunchao Zhang } 2458fd5c2d83SStefano Zampini if (array) *array = NULL; 2459cd3f9d89SJunchao Zhang } 24603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2461cd3f9d89SJunchao Zhang } 2462cd3f9d89SJunchao Zhang 2463cd3f9d89SJunchao Zhang /*@C 2464cd3f9d89SJunchao Zhang MatDenseGetArrayWriteAndMemType - gives write-only access to the array where the data for a `MATDENSE` matrix is stored 2465cd3f9d89SJunchao Zhang 2466cd3f9d89SJunchao Zhang Logically Collective 2467cd3f9d89SJunchao Zhang 2468cd3f9d89SJunchao Zhang Input Parameter: 2469fe59aa6dSJacob Faibussowitsch . A - a dense matrix 2470cd3f9d89SJunchao Zhang 2471cd3f9d89SJunchao Zhang Output Parameters: 2472cd3f9d89SJunchao Zhang + array - pointer to the data 2473cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer 2474cd3f9d89SJunchao Zhang 2475cd3f9d89SJunchao Zhang Level: intermediate 2476cd3f9d89SJunchao Zhang 2477fb850c59SBarry Smith Note: 24782ef1f0ffSBarry Smith If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc., 24792ef1f0ffSBarry Smith an array on device is always returned and is guaranteed to contain the matrix's latest data. 24802ef1f0ffSBarry Smith 24811cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayWriteAndMemType()`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArrayRead()`, 2482cd3f9d89SJunchao Zhang `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()` 2483cd3f9d89SJunchao Zhang @*/ 24845d83a8b1SBarry Smith PetscErrorCode MatDenseGetArrayWriteAndMemType(Mat A, PetscScalar *array[], PetscMemType *mtype) 2485cd3f9d89SJunchao Zhang { 2486cd3f9d89SJunchao Zhang PetscBool isMPI; 2487cd3f9d89SJunchao Zhang 2488cd3f9d89SJunchao Zhang PetscFunctionBegin; 2489cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 24904f572ea9SToby Isaac PetscAssertPointer(array, 2); 2491e865de01SJunchao 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 */ 2492cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2493cd3f9d89SJunchao Zhang if (isMPI) { 2494cd3f9d89SJunchao Zhang PetscCall(MatDenseGetArrayWriteAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype)); 2495cd3f9d89SJunchao Zhang } else { 2496cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **, PetscMemType *); 24973ba16761SJacob Faibussowitsch 24983ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayWriteAndMemType_C", &fptr)); 2499cd3f9d89SJunchao Zhang if (fptr) { 2500cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array, mtype)); 2501cd3f9d89SJunchao Zhang } else { 2502cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array)); 2503cd3f9d89SJunchao Zhang if (mtype) *mtype = PETSC_MEMTYPE_HOST; 2504cd3f9d89SJunchao Zhang } 2505cd3f9d89SJunchao Zhang } 25063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2507cd3f9d89SJunchao Zhang } 2508cd3f9d89SJunchao Zhang 2509cd3f9d89SJunchao Zhang /*@C 2510cd3f9d89SJunchao Zhang MatDenseRestoreArrayWriteAndMemType - returns access to the array that is obtained by `MatDenseGetArrayReadAndMemType()` 2511cd3f9d89SJunchao Zhang 2512cd3f9d89SJunchao Zhang Logically Collective 2513cd3f9d89SJunchao Zhang 2514cd3f9d89SJunchao Zhang Input Parameters: 2515fe59aa6dSJacob Faibussowitsch + A - a dense matrix 2516cd3f9d89SJunchao Zhang - array - pointer to the data 2517cd3f9d89SJunchao Zhang 2518cd3f9d89SJunchao Zhang Level: intermediate 2519cd3f9d89SJunchao Zhang 25201cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayWriteAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 2521cd3f9d89SJunchao Zhang @*/ 25225d83a8b1SBarry Smith PetscErrorCode MatDenseRestoreArrayWriteAndMemType(Mat A, PetscScalar *array[]) 2523cd3f9d89SJunchao Zhang { 2524cd3f9d89SJunchao Zhang PetscBool isMPI; 2525cd3f9d89SJunchao Zhang 2526cd3f9d89SJunchao Zhang PetscFunctionBegin; 2527cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2528fd5c2d83SStefano Zampini if (array) PetscAssertPointer(array, 2); 2529cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2530cd3f9d89SJunchao Zhang if (isMPI) { 2531cd3f9d89SJunchao Zhang PetscCall(MatDenseRestoreArrayWriteAndMemType(((Mat_MPIDense *)A->data)->A, array)); 2532cd3f9d89SJunchao Zhang } else { 2533cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **); 25343ba16761SJacob Faibussowitsch 25353ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayWriteAndMemType_C", &fptr)); 2536cd3f9d89SJunchao Zhang if (fptr) { 2537cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array)); 2538cd3f9d89SJunchao Zhang } else { 2539cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array)); 2540cd3f9d89SJunchao Zhang } 2541fd5c2d83SStefano Zampini if (array) *array = NULL; 2542cd3f9d89SJunchao Zhang } 2543cd3f9d89SJunchao Zhang PetscCall(PetscObjectStateIncrease((PetscObject)A)); 25443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2545cd3f9d89SJunchao Zhang } 2546cd3f9d89SJunchao Zhang 2547d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A, IS isrow, IS iscol, MatReuse scall, Mat *B) 2548d71ae5a4SJacob Faibussowitsch { 2549c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 2550bf5a80bcSToby Isaac PetscInt i, j, nrows, ncols, ldb; 25515d0c19d7SBarry Smith const PetscInt *irow, *icol; 255287828ca2SBarry Smith PetscScalar *av, *bv, *v = mat->v; 25530754003eSLois Curfman McInnes Mat newmat; 25540754003eSLois Curfman McInnes 25553a40ed3dSBarry Smith PetscFunctionBegin; 25569566063dSJacob Faibussowitsch PetscCall(ISGetIndices(isrow, &irow)); 25579566063dSJacob Faibussowitsch PetscCall(ISGetIndices(iscol, &icol)); 25589566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(isrow, &nrows)); 25599566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(iscol, &ncols)); 25600754003eSLois Curfman McInnes 2561182d2002SSatish Balay /* Check submatrixcall */ 2562182d2002SSatish Balay if (scall == MAT_REUSE_MATRIX) { 256313f74950SBarry Smith PetscInt n_cols, n_rows; 25649566063dSJacob Faibussowitsch PetscCall(MatGetSize(*B, &n_rows, &n_cols)); 256521a2c019SBarry Smith if (n_rows != nrows || n_cols != ncols) { 2566f746d493SDmitry Karpeev /* resize the result matrix to match number of requested rows/columns */ 25679566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*B, nrows, ncols, nrows, ncols)); 256821a2c019SBarry Smith } 2569182d2002SSatish Balay newmat = *B; 2570182d2002SSatish Balay } else { 25710754003eSLois Curfman McInnes /* Create and fill new matrix */ 25729566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &newmat)); 25739566063dSJacob Faibussowitsch PetscCall(MatSetSizes(newmat, nrows, ncols, nrows, ncols)); 25749566063dSJacob Faibussowitsch PetscCall(MatSetType(newmat, ((PetscObject)A)->type_name)); 25759566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(newmat, NULL)); 2576182d2002SSatish Balay } 2577182d2002SSatish Balay 2578182d2002SSatish Balay /* Now extract the data pointers and do the copy,column at a time */ 25799566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(newmat, &bv)); 25809566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(newmat, &ldb)); 2581182d2002SSatish Balay for (i = 0; i < ncols; i++) { 25826de62eeeSBarry Smith av = v + mat->lda * icol[i]; 2583ca15aa20SStefano Zampini for (j = 0; j < nrows; j++) bv[j] = av[irow[j]]; 2584bf5a80bcSToby Isaac bv += ldb; 25850754003eSLois Curfman McInnes } 25869566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(newmat, &bv)); 2587182d2002SSatish Balay 2588182d2002SSatish Balay /* Assemble the matrices so that the correct flags are set */ 25899566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(newmat, MAT_FINAL_ASSEMBLY)); 25909566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(newmat, MAT_FINAL_ASSEMBLY)); 25910754003eSLois Curfman McInnes 25920754003eSLois Curfman McInnes /* Free work space */ 25939566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(isrow, &irow)); 25949566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(iscol, &icol)); 2595182d2002SSatish Balay *B = newmat; 25963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 25970754003eSLois Curfman McInnes } 25980754003eSLois Curfman McInnes 2599d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A, PetscInt n, const IS irow[], const IS icol[], MatReuse scall, Mat *B[]) 2600d71ae5a4SJacob Faibussowitsch { 260113f74950SBarry Smith PetscInt i; 2602905e6a2fSBarry Smith 26033a40ed3dSBarry Smith PetscFunctionBegin; 260448a46eb9SPierre Jolivet if (scall == MAT_INITIAL_MATRIX) PetscCall(PetscCalloc1(n, B)); 2605905e6a2fSBarry Smith 260648a46eb9SPierre Jolivet for (i = 0; i < n; i++) PetscCall(MatCreateSubMatrix_SeqDense(A, irow[i], icol[i], scall, &(*B)[i])); 26073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2608905e6a2fSBarry Smith } 2609905e6a2fSBarry Smith 2610d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCopy_SeqDense(Mat A, Mat B, MatStructure str) 2611d71ae5a4SJacob Faibussowitsch { 26124b0e389bSBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data; 2613ca15aa20SStefano Zampini const PetscScalar *va; 2614ca15aa20SStefano Zampini PetscScalar *vb; 2615d0f46423SBarry Smith PetscInt lda1 = a->lda, lda2 = b->lda, m = A->rmap->n, n = A->cmap->n, j; 26163a40ed3dSBarry Smith 26173a40ed3dSBarry Smith PetscFunctionBegin; 261833f4a19fSKris Buschelman /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */ 261933f4a19fSKris Buschelman if (A->ops->copy != B->ops->copy) { 26209566063dSJacob Faibussowitsch PetscCall(MatCopy_Basic(A, B, str)); 26213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26223a40ed3dSBarry Smith } 2623aed4548fSBarry Smith PetscCheck(m == B->rmap->n && n == B->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "size(B) != size(A)"); 26249566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &va)); 26259566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(B, &vb)); 2626a5ce6ee0Svictorle if (lda1 > m || lda2 > m) { 262748a46eb9SPierre Jolivet for (j = 0; j < n; j++) PetscCall(PetscArraycpy(vb + j * lda2, va + j * lda1, m)); 2628a5ce6ee0Svictorle } else { 26299566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(vb, va, A->rmap->n * A->cmap->n)); 2630a5ce6ee0Svictorle } 26319566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(B, &vb)); 26329566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &va)); 26339566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 26349566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 26353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2636273d9f13SBarry Smith } 2637273d9f13SBarry Smith 2638d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetUp_SeqDense(Mat A) 2639d71ae5a4SJacob Faibussowitsch { 2640273d9f13SBarry Smith PetscFunctionBegin; 26419566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 26429566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 264348a46eb9SPierre Jolivet if (!A->preallocated) PetscCall(MatSeqDenseSetPreallocation(A, NULL)); 26443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26454b0e389bSBarry Smith } 26464b0e389bSBarry Smith 2647d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatConjugate_SeqDense(Mat A) 2648d71ae5a4SJacob Faibussowitsch { 26494396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 265006c5243aSJose E. Roman PetscInt i, j; 26514396437dSToby Isaac PetscInt min = PetscMin(A->rmap->n, A->cmap->n); 2652ca15aa20SStefano Zampini PetscScalar *aa; 2653ba337c44SJed Brown 2654ba337c44SJed Brown PetscFunctionBegin; 26559566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 265606c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 265706c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscConj(aa[i + j * mat->lda]); 265806c5243aSJose E. Roman } 26599566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 26609371c9d4SSatish Balay if (mat->tau) 26619371c9d4SSatish Balay for (i = 0; i < min; i++) mat->tau[i] = PetscConj(mat->tau[i]); 26623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2663ba337c44SJed Brown } 2664ba337c44SJed Brown 2665d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRealPart_SeqDense(Mat A) 2666d71ae5a4SJacob Faibussowitsch { 266706c5243aSJose E. Roman Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 266806c5243aSJose E. Roman PetscInt i, j; 2669ca15aa20SStefano Zampini PetscScalar *aa; 2670ba337c44SJed Brown 2671ba337c44SJed Brown PetscFunctionBegin; 26729566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 267306c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 267406c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscRealPart(aa[i + j * mat->lda]); 267506c5243aSJose E. Roman } 26769566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 26773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2678ba337c44SJed Brown } 2679ba337c44SJed Brown 2680d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatImaginaryPart_SeqDense(Mat A) 2681d71ae5a4SJacob Faibussowitsch { 268206c5243aSJose E. Roman Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 268306c5243aSJose E. Roman PetscInt i, j; 2684ca15aa20SStefano Zampini PetscScalar *aa; 2685ba337c44SJed Brown 2686ba337c44SJed Brown PetscFunctionBegin; 26879566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 268806c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 268906c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscImaginaryPart(aa[i + j * mat->lda]); 269006c5243aSJose E. Roman } 26919566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 26923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2693ba337c44SJed Brown } 2694284134d9SBarry Smith 2695d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2696d71ae5a4SJacob Faibussowitsch { 2697d0f46423SBarry Smith PetscInt m = A->rmap->n, n = B->cmap->n; 269847d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 2699a9fe9ddaSSatish Balay 2700ee16a9a1SHong Zhang PetscFunctionBegin; 27019566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 270247d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 27039566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 270447d993e7Ssuyashtn #endif 270547d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 270647d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 270747d993e7Ssuyashtn #endif 27087a3c3d58SStefano Zampini if (!cisdense) { 27097a3c3d58SStefano Zampini PetscBool flg; 27107a3c3d58SStefano Zampini 27119566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 27129566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 27137a3c3d58SStefano Zampini } 27149566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 27153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2716ee16a9a1SHong Zhang } 2717a9fe9ddaSSatish Balay 2718d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2719d71ae5a4SJacob Faibussowitsch { 27206718818eSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data, *c = (Mat_SeqDense *)C->data; 27210805154bSBarry Smith PetscBLASInt m, n, k; 2722ca15aa20SStefano Zampini const PetscScalar *av, *bv; 2723ca15aa20SStefano Zampini PetscScalar *cv; 2724a9fe9ddaSSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 2725a9fe9ddaSSatish Balay 2726a9fe9ddaSSatish Balay PetscFunctionBegin; 27279566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 27289566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 27299566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 27303ba16761SJacob Faibussowitsch if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS); 27319566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 27329566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 27339566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2734792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("N", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 27359566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 27369566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 27379566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 27389566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 27393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2740a9fe9ddaSSatish Balay } 2741a9fe9ddaSSatish Balay 2742d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2743d71ae5a4SJacob Faibussowitsch { 274469f65d41SStefano Zampini PetscInt m = A->rmap->n, n = B->rmap->n; 274547d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 274669f65d41SStefano Zampini 274769f65d41SStefano Zampini PetscFunctionBegin; 27489566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 274947d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 27509566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 275147d993e7Ssuyashtn #endif 275247d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 275347d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 275447d993e7Ssuyashtn #endif 27557a3c3d58SStefano Zampini if (!cisdense) { 27567a3c3d58SStefano Zampini PetscBool flg; 27577a3c3d58SStefano Zampini 27589566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 27599566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 27607a3c3d58SStefano Zampini } 27619566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 27623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 276369f65d41SStefano Zampini } 276469f65d41SStefano Zampini 2765d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2766d71ae5a4SJacob Faibussowitsch { 276769f65d41SStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 276869f65d41SStefano Zampini Mat_SeqDense *b = (Mat_SeqDense *)B->data; 276969f65d41SStefano Zampini Mat_SeqDense *c = (Mat_SeqDense *)C->data; 27706718818eSStefano Zampini const PetscScalar *av, *bv; 27716718818eSStefano Zampini PetscScalar *cv; 277269f65d41SStefano Zampini PetscBLASInt m, n, k; 277369f65d41SStefano Zampini PetscScalar _DOne = 1.0, _DZero = 0.0; 277469f65d41SStefano Zampini 277569f65d41SStefano Zampini PetscFunctionBegin; 27769566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 27779566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 27789566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 27793ba16761SJacob Faibussowitsch if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS); 27809566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 27819566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 27829566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2783792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("N", "T", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 27849566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 27859566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 27869566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 27879566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 27883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 278969f65d41SStefano Zampini } 279069f65d41SStefano Zampini 2791d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2792d71ae5a4SJacob Faibussowitsch { 2793d0f46423SBarry Smith PetscInt m = A->cmap->n, n = B->cmap->n; 279447d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 2795a9fe9ddaSSatish Balay 2796ee16a9a1SHong Zhang PetscFunctionBegin; 27979566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 279847d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 27999566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 280047d993e7Ssuyashtn #endif 280147d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 280247d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 280347d993e7Ssuyashtn #endif 28047a3c3d58SStefano Zampini if (!cisdense) { 28057a3c3d58SStefano Zampini PetscBool flg; 28067a3c3d58SStefano Zampini 28079566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 28089566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 28097a3c3d58SStefano Zampini } 28109566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 28113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2812ee16a9a1SHong Zhang } 2813a9fe9ddaSSatish Balay 2814d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2815d71ae5a4SJacob Faibussowitsch { 2816a9fe9ddaSSatish Balay Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2817a9fe9ddaSSatish Balay Mat_SeqDense *b = (Mat_SeqDense *)B->data; 2818a9fe9ddaSSatish Balay Mat_SeqDense *c = (Mat_SeqDense *)C->data; 28196718818eSStefano Zampini const PetscScalar *av, *bv; 28206718818eSStefano Zampini PetscScalar *cv; 28210805154bSBarry Smith PetscBLASInt m, n, k; 2822a9fe9ddaSSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 2823a9fe9ddaSSatish Balay 2824a9fe9ddaSSatish Balay PetscFunctionBegin; 28259566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 28269566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 28279566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &k)); 28283ba16761SJacob Faibussowitsch if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS); 28299566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 28309566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 28319566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2832792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("T", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 28339566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 28349566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 28359566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 28369566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 28373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2838a9fe9ddaSSatish Balay } 2839985db425SBarry Smith 2840d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C) 2841d71ae5a4SJacob Faibussowitsch { 28424222ddf1SHong Zhang PetscFunctionBegin; 28434222ddf1SHong Zhang C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense; 28444222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AB; 28453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28464222ddf1SHong Zhang } 28474222ddf1SHong Zhang 2848d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C) 2849d71ae5a4SJacob Faibussowitsch { 28504222ddf1SHong Zhang PetscFunctionBegin; 28514222ddf1SHong Zhang C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense; 28524222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AtB; 28533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28544222ddf1SHong Zhang } 28554222ddf1SHong Zhang 2856d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C) 2857d71ae5a4SJacob Faibussowitsch { 28584222ddf1SHong Zhang PetscFunctionBegin; 28594222ddf1SHong Zhang C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense; 28604222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_ABt; 28613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28624222ddf1SHong Zhang } 28634222ddf1SHong Zhang 2864d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C) 2865d71ae5a4SJacob Faibussowitsch { 28664222ddf1SHong Zhang Mat_Product *product = C->product; 28674222ddf1SHong Zhang 28684222ddf1SHong Zhang PetscFunctionBegin; 28694222ddf1SHong Zhang switch (product->type) { 2870d71ae5a4SJacob Faibussowitsch case MATPRODUCT_AB: 2871d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_AB(C)); 2872d71ae5a4SJacob Faibussowitsch break; 2873d71ae5a4SJacob Faibussowitsch case MATPRODUCT_AtB: 2874d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_AtB(C)); 2875d71ae5a4SJacob Faibussowitsch break; 2876d71ae5a4SJacob Faibussowitsch case MATPRODUCT_ABt: 2877d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_ABt(C)); 2878d71ae5a4SJacob Faibussowitsch break; 2879d71ae5a4SJacob Faibussowitsch default: 2880d71ae5a4SJacob Faibussowitsch break; 28814222ddf1SHong Zhang } 28823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28834222ddf1SHong Zhang } 28844222ddf1SHong Zhang 2885d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMax_SeqDense(Mat A, Vec v, PetscInt idx[]) 2886d71ae5a4SJacob Faibussowitsch { 2887985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2888d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2889985db425SBarry Smith PetscScalar *x; 2890ca15aa20SStefano Zampini const PetscScalar *aa; 2891985db425SBarry Smith 2892985db425SBarry Smith PetscFunctionBegin; 289328b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 28949566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 28959566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 28969566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 289708401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2898985db425SBarry Smith for (i = 0; i < m; i++) { 28999371c9d4SSatish Balay x[i] = aa[i]; 29009371c9d4SSatish Balay if (idx) idx[i] = 0; 2901985db425SBarry Smith for (j = 1; j < n; j++) { 29029371c9d4SSatish Balay if (PetscRealPart(x[i]) < PetscRealPart(aa[i + a->lda * j])) { 29039371c9d4SSatish Balay x[i] = aa[i + a->lda * j]; 29049371c9d4SSatish Balay if (idx) idx[i] = j; 29059371c9d4SSatish Balay } 2906985db425SBarry Smith } 2907985db425SBarry Smith } 29089566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 29099566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 29103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2911985db425SBarry Smith } 2912985db425SBarry Smith 2913d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A, Vec v, PetscInt idx[]) 2914d71ae5a4SJacob Faibussowitsch { 2915985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2916d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2917985db425SBarry Smith PetscScalar *x; 2918985db425SBarry Smith PetscReal atmp; 2919ca15aa20SStefano Zampini const PetscScalar *aa; 2920985db425SBarry Smith 2921985db425SBarry Smith PetscFunctionBegin; 292228b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29239566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29249566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 29259566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 292608401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2927985db425SBarry Smith for (i = 0; i < m; i++) { 29289189402eSHong Zhang x[i] = PetscAbsScalar(aa[i]); 2929985db425SBarry Smith for (j = 1; j < n; j++) { 2930ca15aa20SStefano Zampini atmp = PetscAbsScalar(aa[i + a->lda * j]); 29319371c9d4SSatish Balay if (PetscAbsScalar(x[i]) < atmp) { 29329371c9d4SSatish Balay x[i] = atmp; 29339371c9d4SSatish Balay if (idx) idx[i] = j; 29349371c9d4SSatish Balay } 2935985db425SBarry Smith } 2936985db425SBarry Smith } 29379566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 29389566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 29393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2940985db425SBarry Smith } 2941985db425SBarry Smith 2942d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMin_SeqDense(Mat A, Vec v, PetscInt idx[]) 2943d71ae5a4SJacob Faibussowitsch { 2944985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2945d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2946985db425SBarry Smith PetscScalar *x; 2947ca15aa20SStefano Zampini const PetscScalar *aa; 2948985db425SBarry Smith 2949985db425SBarry Smith PetscFunctionBegin; 295028b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29519566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 29529566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29539566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 295408401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2955985db425SBarry Smith for (i = 0; i < m; i++) { 29569371c9d4SSatish Balay x[i] = aa[i]; 29579371c9d4SSatish Balay if (idx) idx[i] = 0; 2958985db425SBarry Smith for (j = 1; j < n; j++) { 29599371c9d4SSatish Balay if (PetscRealPart(x[i]) > PetscRealPart(aa[i + a->lda * j])) { 29609371c9d4SSatish Balay x[i] = aa[i + a->lda * j]; 29619371c9d4SSatish Balay if (idx) idx[i] = j; 29629371c9d4SSatish Balay } 2963985db425SBarry Smith } 2964985db425SBarry Smith } 29659566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 29669566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 29673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2968985db425SBarry Smith } 2969985db425SBarry Smith 2970d71ae5a4SJacob Faibussowitsch PetscErrorCode MatGetColumnVector_SeqDense(Mat A, Vec v, PetscInt col) 2971d71ae5a4SJacob Faibussowitsch { 29728d0534beSBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 29738d0534beSBarry Smith PetscScalar *x; 2974ca15aa20SStefano Zampini const PetscScalar *aa; 29758d0534beSBarry Smith 29768d0534beSBarry Smith PetscFunctionBegin; 297728b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29789566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 29799566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29809566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(x, aa + col * a->lda, A->rmap->n)); 29819566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 29829566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 29833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29848d0534beSBarry Smith } 29858d0534beSBarry Smith 2986d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatGetColumnReductions_SeqDense(Mat A, PetscInt type, PetscReal *reductions) 2987d71ae5a4SJacob Faibussowitsch { 29880716a85fSBarry Smith PetscInt i, j, m, n; 29891683a169SBarry Smith const PetscScalar *a; 29900716a85fSBarry Smith 29910716a85fSBarry Smith PetscFunctionBegin; 29929566063dSJacob Faibussowitsch PetscCall(MatGetSize(A, &m, &n)); 29939566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(reductions, n)); 29949566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &a)); 2995857cbf51SRichard Tran Mills if (type == NORM_2) { 29960716a85fSBarry Smith for (i = 0; i < n; i++) { 2997ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j] * a[j]); 299816cd844bSPierre Jolivet a = PetscSafePointerPlusOffset(a, m); 29990716a85fSBarry Smith } 3000857cbf51SRichard Tran Mills } else if (type == NORM_1) { 30010716a85fSBarry Smith for (i = 0; i < n; i++) { 3002ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j]); 300316cd844bSPierre Jolivet a = PetscSafePointerPlusOffset(a, m); 30040716a85fSBarry Smith } 3005857cbf51SRichard Tran Mills } else if (type == NORM_INFINITY) { 30060716a85fSBarry Smith for (i = 0; i < n; i++) { 3007ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] = PetscMax(PetscAbsScalar(a[j]), reductions[i]); 300816cd844bSPierre Jolivet a = PetscSafePointerPlusOffset(a, m); 30090716a85fSBarry Smith } 3010857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_REALPART || type == REDUCTION_MEAN_REALPART) { 3011a873a8cdSSam Reynolds for (i = 0; i < n; i++) { 3012ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscRealPart(a[j]); 301316cd844bSPierre Jolivet a = PetscSafePointerPlusOffset(a, m); 3014a873a8cdSSam Reynolds } 3015857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_IMAGINARYPART || type == REDUCTION_MEAN_IMAGINARYPART) { 3016857cbf51SRichard Tran Mills for (i = 0; i < n; i++) { 3017ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscImaginaryPart(a[j]); 301816cd844bSPierre Jolivet a = PetscSafePointerPlusOffset(a, m); 3019857cbf51SRichard Tran Mills } 3020857cbf51SRichard Tran Mills } else SETERRQ(PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Unknown reduction type"); 30219566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &a)); 3022857cbf51SRichard Tran Mills if (type == NORM_2) { 3023a873a8cdSSam Reynolds for (i = 0; i < n; i++) reductions[i] = PetscSqrtReal(reductions[i]); 3024857cbf51SRichard Tran Mills } else if (type == REDUCTION_MEAN_REALPART || type == REDUCTION_MEAN_IMAGINARYPART) { 3025a873a8cdSSam Reynolds for (i = 0; i < n; i++) reductions[i] /= m; 30260716a85fSBarry Smith } 30273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30280716a85fSBarry Smith } 30290716a85fSBarry Smith 3030d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetRandom_SeqDense(Mat x, PetscRandom rctx) 3031d71ae5a4SJacob Faibussowitsch { 303273a71a0fSBarry Smith PetscScalar *a; 3033637a0070SStefano Zampini PetscInt lda, m, n, i, j; 303473a71a0fSBarry Smith 303573a71a0fSBarry Smith PetscFunctionBegin; 30369566063dSJacob Faibussowitsch PetscCall(MatGetSize(x, &m, &n)); 30379566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(x, &lda)); 30383faff063SStefano Zampini PetscCall(MatDenseGetArrayWrite(x, &a)); 3039637a0070SStefano Zampini for (j = 0; j < n; j++) { 304048a46eb9SPierre Jolivet for (i = 0; i < m; i++) PetscCall(PetscRandomGetValue(rctx, a + j * lda + i)); 304173a71a0fSBarry Smith } 30423faff063SStefano Zampini PetscCall(MatDenseRestoreArrayWrite(x, &a)); 30433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 304473a71a0fSBarry Smith } 304573a71a0fSBarry Smith 3046d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A, PetscBool *missing, PetscInt *d) 3047d71ae5a4SJacob Faibussowitsch { 30483b49f96aSBarry Smith PetscFunctionBegin; 30493b49f96aSBarry Smith *missing = PETSC_FALSE; 30503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30513b49f96aSBarry Smith } 305273a71a0fSBarry Smith 3053ca15aa20SStefano Zampini /* vals is not const */ 3054d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A, PetscInt col, PetscScalar **vals) 3055d71ae5a4SJacob Faibussowitsch { 305686aefd0dSHong Zhang Mat_SeqDense *a = (Mat_SeqDense *)A->data; 3057ca15aa20SStefano Zampini PetscScalar *v; 305886aefd0dSHong Zhang 305986aefd0dSHong Zhang PetscFunctionBegin; 306028b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 30619566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 3062ca15aa20SStefano Zampini *vals = v + col * a->lda; 30639566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 30643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 306586aefd0dSHong Zhang } 306686aefd0dSHong Zhang 3067d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A, PetscScalar **vals) 3068d71ae5a4SJacob Faibussowitsch { 306986aefd0dSHong Zhang PetscFunctionBegin; 3070742765d3SMatthew Knepley if (vals) *vals = NULL; /* user cannot accidentally use the array later */ 30713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 307286aefd0dSHong Zhang } 3073abc3b08eSStefano Zampini 3074a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqDense, 3075905e6a2fSBarry Smith MatGetRow_SeqDense, 3076905e6a2fSBarry Smith MatRestoreRow_SeqDense, 3077905e6a2fSBarry Smith MatMult_SeqDense, 307897304618SKris Buschelman /* 4*/ MatMultAdd_SeqDense, 30797c922b88SBarry Smith MatMultTranspose_SeqDense, 30807c922b88SBarry Smith MatMultTransposeAdd_SeqDense, 3081f4259b30SLisandro Dalcin NULL, 3082f4259b30SLisandro Dalcin NULL, 3083f4259b30SLisandro Dalcin NULL, 3084f4259b30SLisandro Dalcin /* 10*/ NULL, 3085905e6a2fSBarry Smith MatLUFactor_SeqDense, 3086905e6a2fSBarry Smith MatCholeskyFactor_SeqDense, 308741f059aeSBarry Smith MatSOR_SeqDense, 3088ec8511deSBarry Smith MatTranspose_SeqDense, 308997304618SKris Buschelman /* 15*/ MatGetInfo_SeqDense, 3090905e6a2fSBarry Smith MatEqual_SeqDense, 3091905e6a2fSBarry Smith MatGetDiagonal_SeqDense, 3092905e6a2fSBarry Smith MatDiagonalScale_SeqDense, 3093905e6a2fSBarry Smith MatNorm_SeqDense, 3094b7103cf4SPierre Jolivet /* 20*/ NULL, 3095b7103cf4SPierre Jolivet NULL, 3096905e6a2fSBarry Smith MatSetOption_SeqDense, 3097905e6a2fSBarry Smith MatZeroEntries_SeqDense, 3098d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqDense, 3099f4259b30SLisandro Dalcin NULL, 3100f4259b30SLisandro Dalcin NULL, 3101f4259b30SLisandro Dalcin NULL, 3102f4259b30SLisandro Dalcin NULL, 31034994cf47SJed Brown /* 29*/ MatSetUp_SeqDense, 3104f4259b30SLisandro Dalcin NULL, 3105f4259b30SLisandro Dalcin NULL, 3106f4259b30SLisandro Dalcin NULL, 3107f4259b30SLisandro Dalcin NULL, 3108d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqDense, 3109f4259b30SLisandro Dalcin NULL, 3110f4259b30SLisandro Dalcin NULL, 3111f4259b30SLisandro Dalcin NULL, 3112f4259b30SLisandro Dalcin NULL, 3113d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqDense, 31147dae84e0SHong Zhang MatCreateSubMatrices_SeqDense, 3115f4259b30SLisandro Dalcin NULL, 31164b0e389bSBarry Smith MatGetValues_SeqDense, 3117a5ae1ecdSBarry Smith MatCopy_SeqDense, 3118d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqDense, 3119a5ae1ecdSBarry Smith MatScale_SeqDense, 31202f605a99SJose E. Roman MatShift_SeqDense, 3121f4259b30SLisandro Dalcin NULL, 31223f49a652SStefano Zampini MatZeroRowsColumns_SeqDense, 312373a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqDense, 3124f4259b30SLisandro Dalcin NULL, 3125f4259b30SLisandro Dalcin NULL, 3126f4259b30SLisandro Dalcin NULL, 3127f4259b30SLisandro Dalcin NULL, 3128f4259b30SLisandro Dalcin /* 54*/ NULL, 3129f4259b30SLisandro Dalcin NULL, 3130f4259b30SLisandro Dalcin NULL, 3131f4259b30SLisandro Dalcin NULL, 3132f4259b30SLisandro Dalcin NULL, 3133023c16fcSToby Isaac /* 59*/ MatCreateSubMatrix_SeqDense, 3134e03a110bSBarry Smith MatDestroy_SeqDense, 3135e03a110bSBarry Smith MatView_SeqDense, 3136f4259b30SLisandro Dalcin NULL, 3137f4259b30SLisandro Dalcin NULL, 3138f4259b30SLisandro Dalcin /* 64*/ NULL, 3139f4259b30SLisandro Dalcin NULL, 3140f4259b30SLisandro Dalcin NULL, 3141f4259b30SLisandro Dalcin NULL, 3142f4259b30SLisandro Dalcin NULL, 3143d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqDense, 3144f4259b30SLisandro Dalcin NULL, 3145f4259b30SLisandro Dalcin NULL, 3146f4259b30SLisandro Dalcin NULL, 3147f4259b30SLisandro Dalcin NULL, 3148f4259b30SLisandro Dalcin /* 74*/ NULL, 3149f4259b30SLisandro Dalcin NULL, 3150f4259b30SLisandro Dalcin NULL, 3151f4259b30SLisandro Dalcin NULL, 3152f4259b30SLisandro Dalcin NULL, 3153f4259b30SLisandro Dalcin /* 79*/ NULL, 3154f4259b30SLisandro Dalcin NULL, 3155f4259b30SLisandro Dalcin NULL, 3156f4259b30SLisandro Dalcin NULL, 31575bba2384SShri Abhyankar /* 83*/ MatLoad_SeqDense, 3158637a0070SStefano Zampini MatIsSymmetric_SeqDense, 31591cbb95d3SBarry Smith MatIsHermitian_SeqDense, 3160f4259b30SLisandro Dalcin NULL, 3161f4259b30SLisandro Dalcin NULL, 3162f4259b30SLisandro Dalcin NULL, 3163f4259b30SLisandro Dalcin /* 89*/ NULL, 3164f4259b30SLisandro Dalcin NULL, 3165a9fe9ddaSSatish Balay MatMatMultNumeric_SeqDense_SeqDense, 3166f4259b30SLisandro Dalcin NULL, 3167f4259b30SLisandro Dalcin NULL, 3168f4259b30SLisandro Dalcin /* 94*/ NULL, 3169f4259b30SLisandro Dalcin NULL, 3170f4259b30SLisandro Dalcin NULL, 317169f65d41SStefano Zampini MatMatTransposeMultNumeric_SeqDense_SeqDense, 3172f4259b30SLisandro Dalcin NULL, 31734222ddf1SHong Zhang /* 99*/ MatProductSetFromOptions_SeqDense, 3174f4259b30SLisandro Dalcin NULL, 3175f4259b30SLisandro Dalcin NULL, 3176ba337c44SJed Brown MatConjugate_SeqDense, 3177f4259b30SLisandro Dalcin NULL, 3178f4259b30SLisandro Dalcin /*104*/ NULL, 3179ba337c44SJed Brown MatRealPart_SeqDense, 3180ba337c44SJed Brown MatImaginaryPart_SeqDense, 3181f4259b30SLisandro Dalcin NULL, 3182f4259b30SLisandro Dalcin NULL, 3183f4259b30SLisandro Dalcin /*109*/ NULL, 3184f4259b30SLisandro Dalcin NULL, 31858d0534beSBarry Smith MatGetRowMin_SeqDense, 3186aabbc4fbSShri Abhyankar MatGetColumnVector_SeqDense, 31873b49f96aSBarry Smith MatMissingDiagonal_SeqDense, 3188f4259b30SLisandro Dalcin /*114*/ NULL, 3189f4259b30SLisandro Dalcin NULL, 3190f4259b30SLisandro Dalcin NULL, 3191f4259b30SLisandro Dalcin NULL, 3192f4259b30SLisandro Dalcin NULL, 3193f4259b30SLisandro Dalcin /*119*/ NULL, 3194f4259b30SLisandro Dalcin NULL, 3195459e8d23SBlanca Mellado Pinto MatMultHermitianTranspose_SeqDense, 3196459e8d23SBlanca Mellado Pinto MatMultHermitianTransposeAdd_SeqDense, 3197f4259b30SLisandro Dalcin NULL, 3198f4259b30SLisandro Dalcin /*124*/ NULL, 3199a873a8cdSSam Reynolds MatGetColumnReductions_SeqDense, 3200f4259b30SLisandro Dalcin NULL, 3201f4259b30SLisandro Dalcin NULL, 3202f4259b30SLisandro Dalcin NULL, 3203f4259b30SLisandro Dalcin /*129*/ NULL, 3204f4259b30SLisandro Dalcin NULL, 3205f4259b30SLisandro Dalcin NULL, 320675648e8dSHong Zhang MatTransposeMatMultNumeric_SeqDense_SeqDense, 3207f4259b30SLisandro Dalcin NULL, 3208f4259b30SLisandro Dalcin /*134*/ NULL, 3209f4259b30SLisandro Dalcin NULL, 3210f4259b30SLisandro Dalcin NULL, 3211f4259b30SLisandro Dalcin NULL, 3212f4259b30SLisandro Dalcin NULL, 3213f4259b30SLisandro Dalcin /*139*/ NULL, 3214f4259b30SLisandro Dalcin NULL, 3215f4259b30SLisandro Dalcin NULL, 3216f4259b30SLisandro Dalcin NULL, 3217f4259b30SLisandro Dalcin NULL, 32184222ddf1SHong Zhang MatCreateMPIMatConcatenateSeqMat_SeqDense, 3219f4259b30SLisandro Dalcin /*145*/ NULL, 3220f4259b30SLisandro Dalcin NULL, 322199a7f59eSMark Adams NULL, 322299a7f59eSMark Adams NULL, 32237fb60732SBarry Smith NULL, 3224dec0b466SHong Zhang /*150*/ NULL, 3225eede4a3fSMark Adams NULL, 32264cc2b5b5SPierre Jolivet NULL, 322742ce410bSJunchao Zhang NULL, 322842ce410bSJunchao Zhang NULL, 3229fe1fc275SAlexander /*155*/ NULL, 3230dec0b466SHong Zhang NULL}; 323190ace30eSBarry Smith 32325d83a8b1SBarry Smith /*@ 323311a5261eSBarry Smith MatCreateSeqDense - Creates a `MATSEQDENSE` that 3234fb850c59SBarry Smith is stored in column major order (the usual Fortran format). 3235289bc588SBarry Smith 3236d083f849SBarry Smith Collective 3237db81eaa0SLois Curfman McInnes 323820563c6bSBarry Smith Input Parameters: 323911a5261eSBarry Smith + comm - MPI communicator, set to `PETSC_COMM_SELF` 32400c775827SLois Curfman McInnes . m - number of rows 324118f449edSLois Curfman McInnes . n - number of columns 32422ef1f0ffSBarry Smith - data - optional location of matrix data in column major order. Use `NULL` for PETSc 3243dfc5480cSLois Curfman McInnes to control all matrix memory allocation. 324420563c6bSBarry Smith 324520563c6bSBarry Smith Output Parameter: 324644cd7ae7SLois Curfman McInnes . A - the matrix 324720563c6bSBarry Smith 32482ef1f0ffSBarry Smith Level: intermediate 32492ef1f0ffSBarry Smith 325011a5261eSBarry Smith Note: 325118f449edSLois Curfman McInnes The data input variable is intended primarily for Fortran programmers 325218f449edSLois Curfman McInnes who wish to allocate their own matrix memory space. Most users should 32532ef1f0ffSBarry Smith set `data` = `NULL`. 325418f449edSLois Curfman McInnes 3255fb850c59SBarry Smith Developer Note: 3256fb850c59SBarry Smith Many of the matrix operations for this variant use the BLAS and LAPACK routines. 3257fb850c59SBarry Smith 32581cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()` 325920563c6bSBarry Smith @*/ 32605d83a8b1SBarry Smith PetscErrorCode MatCreateSeqDense(MPI_Comm comm, PetscInt m, PetscInt n, PetscScalar data[], Mat *A) 3261d71ae5a4SJacob Faibussowitsch { 32623a40ed3dSBarry Smith PetscFunctionBegin; 32639566063dSJacob Faibussowitsch PetscCall(MatCreate(comm, A)); 32649566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*A, m, n, m, n)); 32659566063dSJacob Faibussowitsch PetscCall(MatSetType(*A, MATSEQDENSE)); 32669566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(*A, data)); 32673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3268273d9f13SBarry Smith } 3269273d9f13SBarry Smith 32705d83a8b1SBarry Smith /*@ 327111a5261eSBarry Smith MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements of a `MATSEQDENSE` matrix 3272273d9f13SBarry Smith 3273d083f849SBarry Smith Collective 3274273d9f13SBarry Smith 3275273d9f13SBarry Smith Input Parameters: 32761c4f3114SJed Brown + B - the matrix 32772ef1f0ffSBarry Smith - data - the array (or `NULL`) 32782ef1f0ffSBarry Smith 32792ef1f0ffSBarry Smith Level: intermediate 3280273d9f13SBarry Smith 328111a5261eSBarry Smith Note: 3282273d9f13SBarry Smith The data input variable is intended primarily for Fortran programmers 3283273d9f13SBarry Smith who wish to allocate their own matrix memory space. Most users should 3284284134d9SBarry Smith need not call this routine. 3285273d9f13SBarry Smith 32861cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()`, `MatDenseSetLDA()` 3287273d9f13SBarry Smith @*/ 3288d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation(Mat B, PetscScalar data[]) 3289d71ae5a4SJacob Faibussowitsch { 3290a23d5eceSKris Buschelman PetscFunctionBegin; 3291d5ea218eSStefano Zampini PetscValidHeaderSpecific(B, MAT_CLASSID, 1); 3292cac4c232SBarry Smith PetscTryMethod(B, "MatSeqDenseSetPreallocation_C", (Mat, PetscScalar[]), (B, data)); 32933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3294a23d5eceSKris Buschelman } 3295a23d5eceSKris Buschelman 3296d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation_SeqDense(Mat B, PetscScalar *data) 3297d71ae5a4SJacob Faibussowitsch { 3298ad16ce7aSStefano Zampini Mat_SeqDense *b = (Mat_SeqDense *)B->data; 3299273d9f13SBarry Smith 3300273d9f13SBarry Smith PetscFunctionBegin; 330128b400f6SJacob Faibussowitsch PetscCheck(!b->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3302273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 3303a868139aSShri Abhyankar 33049566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(B->rmap)); 33059566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(B->cmap)); 330634ef9618SShri Abhyankar 33076497c311SBarry Smith if (b->lda <= 0) PetscCall(PetscBLASIntCast(B->rmap->n, &b->lda)); 330886d161a7SShri Abhyankar 33099e8f95c4SLisandro Dalcin if (!data) { /* petsc-allocated storage */ 33109566063dSJacob Faibussowitsch if (!b->user_alloc) PetscCall(PetscFree(b->v)); 33119566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((size_t)b->lda * B->cmap->n, &b->v)); 33122205254eSKarl Rupp 33139e8f95c4SLisandro Dalcin b->user_alloc = PETSC_FALSE; 3314273d9f13SBarry Smith } else { /* user-allocated storage */ 33159566063dSJacob Faibussowitsch if (!b->user_alloc) PetscCall(PetscFree(b->v)); 3316273d9f13SBarry Smith b->v = data; 3317273d9f13SBarry Smith b->user_alloc = PETSC_TRUE; 3318273d9f13SBarry Smith } 33190450473dSBarry Smith B->assembled = PETSC_TRUE; 33203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3321273d9f13SBarry Smith } 3322273d9f13SBarry Smith 332365b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 3324d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) 3325d71ae5a4SJacob Faibussowitsch { 3326d77f618aSHong Zhang Mat mat_elemental; 33271683a169SBarry Smith const PetscScalar *array; 33281683a169SBarry Smith PetscScalar *v_colwise; 3329d77f618aSHong Zhang PetscInt M = A->rmap->N, N = A->cmap->N, i, j, k, *rows, *cols; 3330d77f618aSHong Zhang 33318baccfbdSHong Zhang PetscFunctionBegin; 33329566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(M * N, &v_colwise, M, &rows, N, &cols)); 33339566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &array)); 3334d77f618aSHong Zhang /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */ 3335d77f618aSHong Zhang k = 0; 3336d77f618aSHong Zhang for (j = 0; j < N; j++) { 3337d77f618aSHong Zhang cols[j] = j; 3338ad540459SPierre Jolivet for (i = 0; i < M; i++) v_colwise[j * M + i] = array[k++]; 3339d77f618aSHong Zhang } 3340ad540459SPierre Jolivet for (i = 0; i < M; i++) rows[i] = i; 33419566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &array)); 3342d77f618aSHong Zhang 33439566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental)); 33449566063dSJacob Faibussowitsch PetscCall(MatSetSizes(mat_elemental, PETSC_DECIDE, PETSC_DECIDE, M, N)); 33459566063dSJacob Faibussowitsch PetscCall(MatSetType(mat_elemental, MATELEMENTAL)); 33469566063dSJacob Faibussowitsch PetscCall(MatSetUp(mat_elemental)); 3347d77f618aSHong Zhang 3348d77f618aSHong Zhang /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */ 33499566063dSJacob Faibussowitsch PetscCall(MatSetValues(mat_elemental, M, rows, N, cols, v_colwise, ADD_VALUES)); 33509566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY)); 33519566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY)); 33529566063dSJacob Faibussowitsch PetscCall(PetscFree3(v_colwise, rows, cols)); 3353d77f618aSHong Zhang 3354511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 33559566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A, &mat_elemental)); 3356d77f618aSHong Zhang } else { 3357d77f618aSHong Zhang *newmat = mat_elemental; 3358d77f618aSHong Zhang } 33593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 33608baccfbdSHong Zhang } 336165b80a83SHong Zhang #endif 33628baccfbdSHong Zhang 3363d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA_SeqDense(Mat B, PetscInt lda) 3364d71ae5a4SJacob Faibussowitsch { 33651b807ce4Svictorle Mat_SeqDense *b = (Mat_SeqDense *)B->data; 33667422da62SJose E. Roman PetscBool data; 336721a2c019SBarry Smith 33681b807ce4Svictorle PetscFunctionBegin; 3369835f2295SStefano Zampini data = (B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE; 3370aed4548fSBarry Smith PetscCheck(b->user_alloc || !data || b->lda == lda, PETSC_COMM_SELF, PETSC_ERR_ORDER, "LDA cannot be changed after allocation of internal storage"); 337108401ef6SPierre 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); 33726497c311SBarry Smith PetscCall(PetscBLASIntCast(lda, &b->lda)); 33733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 33741b807ce4Svictorle } 33751b807ce4Svictorle 3376d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm, Mat inmat, PetscInt n, MatReuse scall, Mat *outmat) 3377d71ae5a4SJacob Faibussowitsch { 3378d528f656SJakub Kruzik PetscFunctionBegin; 33799566063dSJacob Faibussowitsch PetscCall(MatCreateMPIMatConcatenateSeqMat_MPIDense(comm, inmat, n, scall, outmat)); 33803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3381d528f656SJakub Kruzik } 3382d528f656SJakub Kruzik 3383d16ceb75SStefano Zampini PetscErrorCode MatDenseCreateColumnVec_Private(Mat A, Vec *v) 3384d16ceb75SStefano Zampini { 3385d16ceb75SStefano Zampini PetscBool isstd, iskok, iscuda, iship; 3386d16ceb75SStefano Zampini PetscMPIInt size; 3387d16ceb75SStefano Zampini #if PetscDefined(HAVE_CUDA) || PetscDefined(HAVE_HIP) 3388d16ceb75SStefano Zampini /* we pass the data of A, to prevent allocating needless GPU memory the first time VecCUPMPlaceArray is called. */ 3389d16ceb75SStefano Zampini const PetscScalar *a; 3390d16ceb75SStefano Zampini #endif 3391d16ceb75SStefano Zampini 3392d16ceb75SStefano Zampini PetscFunctionBegin; 3393d16ceb75SStefano Zampini *v = NULL; 3394d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &isstd, VECSTANDARD, VECSEQ, VECMPI, "")); 3395d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &iskok, VECKOKKOS, VECSEQKOKKOS, VECMPIKOKKOS, "")); 3396d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &iscuda, VECCUDA, VECSEQCUDA, VECMPICUDA, "")); 3397d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &iship, VECHIP, VECSEQHIP, VECMPIHIP, "")); 3398d16ceb75SStefano Zampini PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A), &size)); 3399d16ceb75SStefano Zampini if (isstd) { 3400d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPIWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, v)); 3401d16ceb75SStefano Zampini else PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, v)); 3402d16ceb75SStefano Zampini } else if (iskok) { 3403d16ceb75SStefano Zampini PetscCheck(PetscDefined(HAVE_KOKKOS_KERNELS), PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Reconfigure using KOKKOS kernels support"); 3404d16ceb75SStefano Zampini #if PetscDefined(HAVE_KOKKOS_KERNELS) 3405d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPIKokkosWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, v)); 3406d16ceb75SStefano Zampini else PetscCall(VecCreateSeqKokkosWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, v)); 3407d16ceb75SStefano Zampini #endif 3408d16ceb75SStefano Zampini } else if (iscuda) { 3409d16ceb75SStefano Zampini PetscCheck(PetscDefined(HAVE_CUDA), PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Reconfigure using CUDA support"); 3410d16ceb75SStefano Zampini #if PetscDefined(HAVE_CUDA) 3411d16ceb75SStefano Zampini PetscCall(MatDenseCUDAGetArrayRead(A, &a)); 3412d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPICUDAWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, a, v)); 3413d16ceb75SStefano Zampini else PetscCall(VecCreateSeqCUDAWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, a, v)); 3414d16ceb75SStefano Zampini #endif 3415d16ceb75SStefano Zampini } else if (iship) { 3416d16ceb75SStefano Zampini PetscCheck(PetscDefined(HAVE_HIP), PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Reconfigure using HIP support"); 3417d16ceb75SStefano Zampini #if PetscDefined(HAVE_HIP) 3418d16ceb75SStefano Zampini PetscCall(MatDenseHIPGetArrayRead(A, &a)); 3419d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPIHIPWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, a, v)); 3420d16ceb75SStefano Zampini else PetscCall(VecCreateSeqHIPWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, a, v)); 3421d16ceb75SStefano Zampini #endif 3422d16ceb75SStefano Zampini } 3423d16ceb75SStefano Zampini PetscCheck(*v, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Not coded for type %s", A->defaultvectype); 3424d16ceb75SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 3425d16ceb75SStefano Zampini } 3426d16ceb75SStefano Zampini 3427d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A, PetscInt col, Vec *v) 3428d71ae5a4SJacob Faibussowitsch { 34296947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34306947451fSStefano Zampini 34316947451fSStefano Zampini PetscFunctionBegin; 343228b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 343328b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3434d16ceb75SStefano Zampini if (!a->cvec) PetscCall(MatDenseCreateColumnVec_Private(A, &a->cvec)); 34356947451fSStefano Zampini a->vecinuse = col + 1; 34369566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, (PetscScalar **)&a->ptrinuse)); 34379566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda)); 34386947451fSStefano Zampini *v = a->cvec; 34393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34406947451fSStefano Zampini } 34416947451fSStefano Zampini 3442d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A, PetscInt col, Vec *v) 3443d71ae5a4SJacob Faibussowitsch { 34446947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34456947451fSStefano Zampini 34466947451fSStefano Zampini PetscFunctionBegin; 344728b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 344828b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 34494186a4bbSPierre Jolivet VecCheckAssembled(a->cvec); 34506947451fSStefano Zampini a->vecinuse = 0; 34519566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, (PetscScalar **)&a->ptrinuse)); 34529566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 345375f6d85dSStefano Zampini if (v) *v = NULL; 34543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34556947451fSStefano Zampini } 34566947451fSStefano Zampini 3457d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead_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 MatDenseRestoreColumnVec() first"); 346328b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3464d16ceb75SStefano Zampini if (!a->cvec) PetscCall(MatDenseCreateColumnVec_Private(A, &a->cvec)); 34656947451fSStefano Zampini a->vecinuse = col + 1; 34669566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &a->ptrinuse)); 34678e3a54c0SPierre Jolivet PetscCall(VecPlaceArray(a->cvec, PetscSafePointerPlusOffset(a->ptrinuse, (size_t)col * (size_t)a->lda))); 34689566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(a->cvec)); 34696947451fSStefano Zampini *v = a->cvec; 34703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34716947451fSStefano Zampini } 34726947451fSStefano Zampini 3473d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead_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 MatDenseGetColumnVec() first"); 347928b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 34804186a4bbSPierre Jolivet VecCheckAssembled(a->cvec); 34816947451fSStefano Zampini a->vecinuse = 0; 34829566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &a->ptrinuse)); 34839566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(a->cvec)); 34849566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 348575f6d85dSStefano Zampini if (v) *v = NULL; 34863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34876947451fSStefano Zampini } 34886947451fSStefano Zampini 3489d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v) 3490d71ae5a4SJacob Faibussowitsch { 34916947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34926947451fSStefano Zampini 34936947451fSStefano Zampini PetscFunctionBegin; 349428b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 349528b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3496d16ceb75SStefano Zampini if (!a->cvec) PetscCall(MatDenseCreateColumnVec_Private(A, &a->cvec)); 34976947451fSStefano Zampini a->vecinuse = col + 1; 34989566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(A, (PetscScalar **)&a->ptrinuse)); 34998e3a54c0SPierre Jolivet PetscCall(VecPlaceArray(a->cvec, PetscSafePointerPlusOffset(a->ptrinuse, (size_t)col * (size_t)a->lda))); 35006947451fSStefano Zampini *v = a->cvec; 35013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35026947451fSStefano Zampini } 35036947451fSStefano Zampini 3504d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v) 3505d71ae5a4SJacob Faibussowitsch { 35066947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35076947451fSStefano Zampini 35086947451fSStefano Zampini PetscFunctionBegin; 350928b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 351028b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 35114186a4bbSPierre Jolivet VecCheckAssembled(a->cvec); 35126947451fSStefano Zampini a->vecinuse = 0; 35139566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(A, (PetscScalar **)&a->ptrinuse)); 35149566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 351575f6d85dSStefano Zampini if (v) *v = NULL; 35163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35176947451fSStefano Zampini } 35186947451fSStefano Zampini 3519d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) 3520d71ae5a4SJacob Faibussowitsch { 35215ea7661aSPierre Jolivet Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35225ea7661aSPierre Jolivet 35235ea7661aSPierre Jolivet PetscFunctionBegin; 352428b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 352528b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3526a2748737SPierre Jolivet if (a->cmat && (cend - cbegin != a->cmat->cmap->N || rend - rbegin != a->cmat->rmap->N)) PetscCall(MatDestroy(&a->cmat)); 35275ea7661aSPierre Jolivet if (!a->cmat) { 35288e3a54c0SPierre 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)); 35295ea7661aSPierre Jolivet } else { 35308e3a54c0SPierre Jolivet PetscCall(MatDensePlaceArray(a->cmat, PetscSafePointerPlusOffset(a->v, rbegin + (size_t)cbegin * a->lda))); 35315ea7661aSPierre Jolivet } 35329566063dSJacob Faibussowitsch PetscCall(MatDenseSetLDA(a->cmat, a->lda)); 35335ea7661aSPierre Jolivet a->matinuse = cbegin + 1; 35345ea7661aSPierre Jolivet *v = a->cmat; 353547d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 353675f6d85dSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 353775f6d85dSStefano Zampini #endif 35383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35395ea7661aSPierre Jolivet } 35405ea7661aSPierre Jolivet 3541d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A, Mat *v) 3542d71ae5a4SJacob Faibussowitsch { 35435ea7661aSPierre Jolivet Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35445ea7661aSPierre Jolivet 35455ea7661aSPierre Jolivet PetscFunctionBegin; 354628b400f6SJacob Faibussowitsch PetscCheck(a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetSubMatrix() first"); 354728b400f6SJacob Faibussowitsch PetscCheck(a->cmat, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column matrix"); 354808401ef6SPierre Jolivet PetscCheck(*v == a->cmat, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not the matrix obtained from MatDenseGetSubMatrix()"); 35495ea7661aSPierre Jolivet a->matinuse = 0; 35509566063dSJacob Faibussowitsch PetscCall(MatDenseResetArray(a->cmat)); 3551742765d3SMatthew Knepley if (v) *v = NULL; 355247d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 35533faff063SStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 35543faff063SStefano Zampini #endif 35553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35565ea7661aSPierre Jolivet } 35575ea7661aSPierre Jolivet 35580bad9183SKris Buschelman /*MC 3559fafad747SKris Buschelman MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices. 35600bad9183SKris Buschelman 35612ef1f0ffSBarry Smith Options Database Key: 356211a5261eSBarry Smith . -mat_type seqdense - sets the matrix type to `MATSEQDENSE` during a call to `MatSetFromOptions()` 35630bad9183SKris Buschelman 35640bad9183SKris Buschelman Level: beginner 35650bad9183SKris Buschelman 35661cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreateSeqDense()` 35670bad9183SKris Buschelman M*/ 3568d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreate_SeqDense(Mat B) 3569d71ae5a4SJacob Faibussowitsch { 3570273d9f13SBarry Smith Mat_SeqDense *b; 35717c334f02SBarry Smith PetscMPIInt size; 3572273d9f13SBarry Smith 3573273d9f13SBarry Smith PetscFunctionBegin; 35749566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)B), &size)); 357508401ef6SPierre Jolivet PetscCheck(size <= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Comm must be of size 1"); 357655659b69SBarry Smith 35774dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&b)); 357844cd7ae7SLois Curfman McInnes B->data = (void *)b; 3579aea10558SJacob Faibussowitsch B->ops[0] = MatOps_Values; 358018f449edSLois Curfman McInnes 3581273d9f13SBarry Smith b->roworiented = PETSC_TRUE; 35824e220ebcSLois Curfman McInnes 35839566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatQRFactor_C", MatQRFactor_SeqDense)); 35849566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetLDA_C", MatDenseGetLDA_SeqDense)); 35859566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseSetLDA_C", MatDenseSetLDA_SeqDense)); 35869566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArray_C", MatDenseGetArray_SeqDense)); 35879566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArray_C", MatDenseRestoreArray_SeqDense)); 35889566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDensePlaceArray_C", MatDensePlaceArray_SeqDense)); 35899566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseResetArray_C", MatDenseResetArray_SeqDense)); 35909566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseReplaceArray_C", MatDenseReplaceArray_SeqDense)); 35919566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayRead_C", MatDenseGetArray_SeqDense)); 35929566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayRead_C", MatDenseRestoreArray_SeqDense)); 35939566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayWrite_C", MatDenseGetArray_SeqDense)); 35949566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayWrite_C", MatDenseRestoreArray_SeqDense)); 35959566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqaij_C", MatConvert_SeqDense_SeqAIJ)); 35968baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 35979566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_elemental_C", MatConvert_SeqDense_Elemental)); 35988baccfbdSHong Zhang #endif 3599d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 36009566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_scalapack_C", MatConvert_Dense_ScaLAPACK)); 3601d24d4204SJose E. Roman #endif 36022bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA) 36039566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensecuda_C", MatConvert_SeqDense_SeqDenseCUDA)); 36049566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", MatProductSetFromOptions_SeqDense)); 36059566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdense_C", MatProductSetFromOptions_SeqDense)); 36069566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensecuda_C", MatProductSetFromOptions_SeqDense)); 36072bf066beSStefano Zampini #endif 360847d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 360947d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensehip_C", MatConvert_SeqDense_SeqDenseHIP)); 361047d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensehip_seqdensehip_C", MatProductSetFromOptions_SeqDense)); 361147d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensehip_seqdense_C", MatProductSetFromOptions_SeqDense)); 361247d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensehip_C", MatProductSetFromOptions_SeqDense)); 361347d993e7Ssuyashtn #endif 36149566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSeqDenseSetPreallocation_C", MatSeqDenseSetPreallocation_SeqDense)); 36159566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqaij_seqdense_C", MatProductSetFromOptions_SeqAIJ_SeqDense)); 36169566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdense_C", MatProductSetFromOptions_SeqDense)); 36179566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense)); 36189566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqsbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense)); 361996e6d5c4SRichard Tran Mills 36209566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumn_C", MatDenseGetColumn_SeqDense)); 36219566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumn_C", MatDenseRestoreColumn_SeqDense)); 36229566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVec_C", MatDenseGetColumnVec_SeqDense)); 36239566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVec_C", MatDenseRestoreColumnVec_SeqDense)); 36249566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecRead_C", MatDenseGetColumnVecRead_SeqDense)); 36259566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecRead_C", MatDenseRestoreColumnVecRead_SeqDense)); 36269566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecWrite_C", MatDenseGetColumnVecWrite_SeqDense)); 36279566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecWrite_C", MatDenseRestoreColumnVecWrite_SeqDense)); 36289566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetSubMatrix_C", MatDenseGetSubMatrix_SeqDense)); 36299566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreSubMatrix_C", MatDenseRestoreSubMatrix_SeqDense)); 36300be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatMultAddColumnRange_C", MatMultAddColumnRange_SeqDense)); 36310be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatMultHermitianTransposeColumnRange_C", MatMultHermitianTransposeColumnRange_SeqDense)); 36320be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatMultHermitianTransposeAddColumnRange_C", MatMultHermitianTransposeAddColumnRange_SeqDense)); 36339566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)B, MATSEQDENSE)); 36343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3635289bc588SBarry Smith } 363686aefd0dSHong Zhang 363786aefd0dSHong Zhang /*@C 363811a5261eSBarry 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. 363986aefd0dSHong Zhang 364086aefd0dSHong Zhang Not Collective 364186aefd0dSHong Zhang 36425ea7661aSPierre Jolivet Input Parameters: 3643fe59aa6dSJacob Faibussowitsch + A - a `MATSEQDENSE` or `MATMPIDENSE` matrix 364486aefd0dSHong Zhang - col - column index 364586aefd0dSHong Zhang 364686aefd0dSHong Zhang Output Parameter: 364786aefd0dSHong Zhang . vals - pointer to the data 364886aefd0dSHong Zhang 364986aefd0dSHong Zhang Level: intermediate 365086aefd0dSHong Zhang 365111a5261eSBarry Smith Note: 365211a5261eSBarry Smith Use `MatDenseGetColumnVec()` to get access to a column of a `MATDENSE` treated as a `Vec` 365311a5261eSBarry Smith 36541cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreColumn()`, `MatDenseGetColumnVec()` 365586aefd0dSHong Zhang @*/ 36565d83a8b1SBarry Smith PetscErrorCode MatDenseGetColumn(Mat A, PetscInt col, PetscScalar *vals[]) 3657d71ae5a4SJacob Faibussowitsch { 365886aefd0dSHong Zhang PetscFunctionBegin; 3659d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3660d5ea218eSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 36614f572ea9SToby Isaac PetscAssertPointer(vals, 3); 3662cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumn_C", (Mat, PetscInt, PetscScalar **), (A, col, vals)); 36633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 366486aefd0dSHong Zhang } 366586aefd0dSHong Zhang 366686aefd0dSHong Zhang /*@C 366711a5261eSBarry Smith MatDenseRestoreColumn - returns access to a column of a `MATDENSE` matrix which is returned by `MatDenseGetColumn()`. 366886aefd0dSHong Zhang 366986aefd0dSHong Zhang Not Collective 367086aefd0dSHong Zhang 3671742765d3SMatthew Knepley Input Parameters: 3672fe59aa6dSJacob Faibussowitsch + A - a `MATSEQDENSE` or `MATMPIDENSE` matrix 36732ef1f0ffSBarry Smith - vals - pointer to the data (may be `NULL`) 367486aefd0dSHong Zhang 367586aefd0dSHong Zhang Level: intermediate 367686aefd0dSHong Zhang 36771cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetColumn()` 367886aefd0dSHong Zhang @*/ 36795d83a8b1SBarry Smith PetscErrorCode MatDenseRestoreColumn(Mat A, PetscScalar *vals[]) 3680d71ae5a4SJacob Faibussowitsch { 368186aefd0dSHong Zhang PetscFunctionBegin; 3682d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 36834f572ea9SToby Isaac PetscAssertPointer(vals, 2); 3684cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumn_C", (Mat, PetscScalar **), (A, vals)); 36853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 368686aefd0dSHong Zhang } 36876947451fSStefano Zampini 36880f74d2c1SSatish Balay /*@ 368911a5261eSBarry Smith MatDenseGetColumnVec - Gives read-write access to a column of a `MATDENSE` matrix, represented as a `Vec`. 36906947451fSStefano Zampini 36916947451fSStefano Zampini Collective 36926947451fSStefano Zampini 36935ea7661aSPierre Jolivet Input Parameters: 3694fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 36956947451fSStefano Zampini - col - the column index 36966947451fSStefano Zampini 36976947451fSStefano Zampini Output Parameter: 36986947451fSStefano Zampini . v - the vector 36996947451fSStefano Zampini 37002ef1f0ffSBarry Smith Level: intermediate 37012ef1f0ffSBarry Smith 37026947451fSStefano Zampini Notes: 370311a5261eSBarry Smith The vector is owned by PETSc. Users need to call `MatDenseRestoreColumnVec()` when the vector is no longer needed. 370411a5261eSBarry Smith 370511a5261eSBarry Smith Use `MatDenseGetColumnVecRead()` to obtain read-only access or `MatDenseGetColumnVecWrite()` for write-only access. 37066947451fSStefano Zampini 37071cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`, `MatDenseGetColumn()` 37086947451fSStefano Zampini @*/ 3709d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec(Mat A, PetscInt col, Vec *v) 3710d71ae5a4SJacob Faibussowitsch { 37116947451fSStefano Zampini PetscFunctionBegin; 37126947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 37136947451fSStefano Zampini PetscValidType(A, 1); 37146947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 37154f572ea9SToby Isaac PetscAssertPointer(v, 3); 371628b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 37172cf15c64SPierre 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); 3718cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v)); 37193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37206947451fSStefano Zampini } 37216947451fSStefano Zampini 37220f74d2c1SSatish Balay /*@ 3723fb850c59SBarry Smith MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from `MatDenseGetColumnVec()`. 37246947451fSStefano Zampini 37256947451fSStefano Zampini Collective 37266947451fSStefano Zampini 37275ea7661aSPierre Jolivet Input Parameters: 3728fb850c59SBarry Smith + A - the `Mat` object 37296947451fSStefano Zampini . col - the column index 3730fb850c59SBarry Smith - v - the `Vec` object (may be `NULL`) 37316947451fSStefano Zampini 37326947451fSStefano Zampini Level: intermediate 37336947451fSStefano Zampini 37341cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 37356947451fSStefano Zampini @*/ 3736d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec(Mat A, PetscInt col, Vec *v) 3737d71ae5a4SJacob Faibussowitsch { 37386947451fSStefano Zampini PetscFunctionBegin; 37396947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 37406947451fSStefano Zampini PetscValidType(A, 1); 37416947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 374208401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 37432cf15c64SPierre 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); 3744cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v)); 37453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37466947451fSStefano Zampini } 37476947451fSStefano Zampini 37480f74d2c1SSatish Balay /*@ 3749fb850c59SBarry Smith MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a `Vec`. 37506947451fSStefano Zampini 37516947451fSStefano Zampini Collective 37526947451fSStefano Zampini 37535ea7661aSPierre Jolivet Input Parameters: 3754fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 37556947451fSStefano Zampini - col - the column index 37566947451fSStefano Zampini 37576947451fSStefano Zampini Output Parameter: 37586947451fSStefano Zampini . v - the vector 37596947451fSStefano Zampini 37602ef1f0ffSBarry Smith Level: intermediate 37612ef1f0ffSBarry Smith 37626947451fSStefano Zampini Notes: 37636947451fSStefano Zampini The vector is owned by PETSc and users cannot modify it. 376411a5261eSBarry Smith 37652ef1f0ffSBarry Smith Users need to call `MatDenseRestoreColumnVecRead()` when the vector is no longer needed. 376611a5261eSBarry Smith 37672ef1f0ffSBarry Smith Use `MatDenseGetColumnVec()` to obtain read-write access or `MatDenseGetColumnVecWrite()` for write-only access. 37686947451fSStefano Zampini 37691cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 37706947451fSStefano Zampini @*/ 3771d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead(Mat A, PetscInt col, Vec *v) 3772d71ae5a4SJacob Faibussowitsch { 37736947451fSStefano Zampini PetscFunctionBegin; 37746947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 37756947451fSStefano Zampini PetscValidType(A, 1); 37766947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 37774f572ea9SToby Isaac PetscAssertPointer(v, 3); 377828b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 37792cf15c64SPierre 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); 3780cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v)); 37813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37826947451fSStefano Zampini } 37836947451fSStefano Zampini 37840f74d2c1SSatish Balay /*@ 3785fb850c59SBarry Smith MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from `MatDenseGetColumnVecRead()`. 37866947451fSStefano Zampini 37876947451fSStefano Zampini Collective 37886947451fSStefano Zampini 37895ea7661aSPierre Jolivet Input Parameters: 3790fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 37916947451fSStefano Zampini . col - the column index 3792fb850c59SBarry Smith - v - the `Vec` object (may be `NULL`) 37936947451fSStefano Zampini 37946947451fSStefano Zampini Level: intermediate 37956947451fSStefano Zampini 37961cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecWrite()` 37976947451fSStefano Zampini @*/ 3798d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead(Mat A, PetscInt col, Vec *v) 3799d71ae5a4SJacob Faibussowitsch { 38006947451fSStefano Zampini PetscFunctionBegin; 38016947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38026947451fSStefano Zampini PetscValidType(A, 1); 38036947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 380408401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 38052cf15c64SPierre 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); 3806cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v)); 38073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38086947451fSStefano Zampini } 38096947451fSStefano Zampini 38100f74d2c1SSatish Balay /*@ 3811fb850c59SBarry Smith MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a `Vec`. 38126947451fSStefano Zampini 38136947451fSStefano Zampini Collective 38146947451fSStefano Zampini 38155ea7661aSPierre Jolivet Input Parameters: 3816fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 38176947451fSStefano Zampini - col - the column index 38186947451fSStefano Zampini 38196947451fSStefano Zampini Output Parameter: 38206947451fSStefano Zampini . v - the vector 38216947451fSStefano Zampini 38226947451fSStefano Zampini Level: intermediate 38236947451fSStefano Zampini 38242ef1f0ffSBarry Smith Notes: 38252ef1f0ffSBarry Smith The vector is owned by PETSc. Users need to call `MatDenseRestoreColumnVecWrite()` when the vector is no longer needed. 38262ef1f0ffSBarry Smith 38272ef1f0ffSBarry Smith Use `MatDenseGetColumnVec()` to obtain read-write access or `MatDenseGetColumnVecRead()` for read-only access. 38282ef1f0ffSBarry Smith 38291cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 38306947451fSStefano Zampini @*/ 3831d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite(Mat A, PetscInt col, Vec *v) 3832d71ae5a4SJacob Faibussowitsch { 38336947451fSStefano Zampini PetscFunctionBegin; 38346947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38356947451fSStefano Zampini PetscValidType(A, 1); 38366947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 38374f572ea9SToby Isaac PetscAssertPointer(v, 3); 383828b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3839aed4548fSBarry 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); 3840cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v)); 38413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38426947451fSStefano Zampini } 38436947451fSStefano Zampini 38440f74d2c1SSatish Balay /*@ 3845fb850c59SBarry Smith MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from `MatDenseGetColumnVecWrite()`. 38466947451fSStefano Zampini 38476947451fSStefano Zampini Collective 38486947451fSStefano Zampini 38495ea7661aSPierre Jolivet Input Parameters: 3850fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 38516947451fSStefano Zampini . col - the column index 38522ef1f0ffSBarry Smith - v - the `Vec` object (may be `NULL`) 38536947451fSStefano Zampini 38546947451fSStefano Zampini Level: intermediate 38556947451fSStefano Zampini 38561cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()` 38576947451fSStefano Zampini @*/ 3858d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A, PetscInt col, Vec *v) 3859d71ae5a4SJacob Faibussowitsch { 38606947451fSStefano Zampini PetscFunctionBegin; 38616947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38626947451fSStefano Zampini PetscValidType(A, 1); 38636947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 386408401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3865aed4548fSBarry 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); 3866cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v)); 38673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38686947451fSStefano Zampini } 38695ea7661aSPierre Jolivet 38700f74d2c1SSatish Balay /*@ 3871fb850c59SBarry Smith MatDenseGetSubMatrix - Gives access to a block of rows and columns of a dense matrix, represented as a `Mat`. 38725ea7661aSPierre Jolivet 38735ea7661aSPierre Jolivet Collective 38745ea7661aSPierre Jolivet 38755ea7661aSPierre Jolivet Input Parameters: 3876fb850c59SBarry Smith + A - the `Mat` object 38772ef1f0ffSBarry Smith . rbegin - the first global row index in the block (if `PETSC_DECIDE`, is 0) 38782ef1f0ffSBarry Smith . rend - the global row index past the last one in the block (if `PETSC_DECIDE`, is `M`) 38792ef1f0ffSBarry Smith . cbegin - the first global column index in the block (if `PETSC_DECIDE`, is 0) 38802ef1f0ffSBarry Smith - cend - the global column index past the last one in the block (if `PETSC_DECIDE`, is `N`) 38815ea7661aSPierre Jolivet 38825ea7661aSPierre Jolivet Output Parameter: 38835ea7661aSPierre Jolivet . v - the matrix 38845ea7661aSPierre Jolivet 38855ea7661aSPierre Jolivet Level: intermediate 38865ea7661aSPierre Jolivet 38872ef1f0ffSBarry Smith Notes: 38882ef1f0ffSBarry Smith The matrix is owned by PETSc. Users need to call `MatDenseRestoreSubMatrix()` when the matrix is no longer needed. 38892ef1f0ffSBarry Smith 38902ef1f0ffSBarry 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. 38912ef1f0ffSBarry Smith 38921cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreSubMatrix()` 38935ea7661aSPierre Jolivet @*/ 3894d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) 3895d71ae5a4SJacob Faibussowitsch { 38965ea7661aSPierre Jolivet PetscFunctionBegin; 38975ea7661aSPierre Jolivet PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38985ea7661aSPierre Jolivet PetscValidType(A, 1); 3899a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, rbegin, 2); 3900a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, rend, 3); 3901a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, cbegin, 4); 3902a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, cend, 5); 39034f572ea9SToby Isaac PetscAssertPointer(v, 6); 3904a2748737SPierre Jolivet if (rbegin == PETSC_DECIDE) rbegin = 0; 3905a2748737SPierre Jolivet if (rend == PETSC_DECIDE) rend = A->rmap->N; 3906a2748737SPierre Jolivet if (cbegin == PETSC_DECIDE) cbegin = 0; 3907a2748737SPierre Jolivet if (cend == PETSC_DECIDE) cend = A->cmap->N; 390828b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3909a2748737SPierre 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); 3910a2748737SPierre 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); 3911a2748737SPierre 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); 3912a2748737SPierre 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); 3913a2748737SPierre Jolivet PetscUseMethod(A, "MatDenseGetSubMatrix_C", (Mat, PetscInt, PetscInt, PetscInt, PetscInt, Mat *), (A, rbegin, rend, cbegin, cend, v)); 39143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 39155ea7661aSPierre Jolivet } 39165ea7661aSPierre Jolivet 39170f74d2c1SSatish Balay /*@ 3918fb850c59SBarry Smith MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from `MatDenseGetSubMatrix()`. 39195ea7661aSPierre Jolivet 39205ea7661aSPierre Jolivet Collective 39215ea7661aSPierre Jolivet 39225ea7661aSPierre Jolivet Input Parameters: 3923fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 39242ef1f0ffSBarry Smith - v - the `Mat` object (may be `NULL`) 39255ea7661aSPierre Jolivet 39265ea7661aSPierre Jolivet Level: intermediate 39275ea7661aSPierre Jolivet 39281cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseGetSubMatrix()` 39295ea7661aSPierre Jolivet @*/ 3930d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix(Mat A, Mat *v) 3931d71ae5a4SJacob Faibussowitsch { 39325ea7661aSPierre Jolivet PetscFunctionBegin; 39335ea7661aSPierre Jolivet PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 39345ea7661aSPierre Jolivet PetscValidType(A, 1); 39354f572ea9SToby Isaac PetscAssertPointer(v, 2); 3936cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreSubMatrix_C", (Mat, Mat *), (A, v)); 39373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 39385ea7661aSPierre Jolivet } 39398a9c020eSBarry Smith 39408a9c020eSBarry Smith #include <petscblaslapack.h> 39418a9c020eSBarry Smith #include <petsc/private/kernels/blockinvert.h> 39428a9c020eSBarry Smith 3943d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseInvert(Mat A) 3944d71ae5a4SJacob Faibussowitsch { 3945d63b1753SJacob Faibussowitsch PetscInt m; 39468a9c020eSBarry Smith const PetscReal shift = 0.0; 3947d63b1753SJacob Faibussowitsch PetscBool allowzeropivot, zeropivotdetected = PETSC_FALSE; 3948d63b1753SJacob Faibussowitsch PetscScalar *values; 39498a9c020eSBarry Smith 39508a9c020eSBarry Smith PetscFunctionBegin; 3951d63b1753SJacob Faibussowitsch PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3952d63b1753SJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &values)); 3953d63b1753SJacob Faibussowitsch PetscCall(MatGetLocalSize(A, &m, NULL)); 3954d63b1753SJacob Faibussowitsch allowzeropivot = PetscNot(A->erroriffailure); 39558a9c020eSBarry Smith /* factor and invert each block */ 3956d63b1753SJacob Faibussowitsch switch (m) { 3957d71ae5a4SJacob Faibussowitsch case 1: 3958d71ae5a4SJacob Faibussowitsch values[0] = (PetscScalar)1.0 / (values[0] + shift); 3959d71ae5a4SJacob Faibussowitsch break; 39608a9c020eSBarry Smith case 2: 39618a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_2(values, shift, allowzeropivot, &zeropivotdetected)); 39628a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39638a9c020eSBarry Smith break; 39648a9c020eSBarry Smith case 3: 39658a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_3(values, shift, allowzeropivot, &zeropivotdetected)); 39668a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39678a9c020eSBarry Smith break; 39688a9c020eSBarry Smith case 4: 39698a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_4(values, shift, allowzeropivot, &zeropivotdetected)); 39708a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39718a9c020eSBarry Smith break; 39729371c9d4SSatish Balay case 5: { 39738a9c020eSBarry Smith PetscScalar work[25]; 39748a9c020eSBarry Smith PetscInt ipvt[5]; 39758a9c020eSBarry Smith 39768a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_5(values, ipvt, work, shift, allowzeropivot, &zeropivotdetected)); 39778a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39789371c9d4SSatish Balay } break; 39798a9c020eSBarry Smith case 6: 39808a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_6(values, shift, allowzeropivot, &zeropivotdetected)); 39818a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39828a9c020eSBarry Smith break; 39838a9c020eSBarry Smith case 7: 39848a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_7(values, shift, allowzeropivot, &zeropivotdetected)); 39858a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39868a9c020eSBarry Smith break; 39879371c9d4SSatish Balay default: { 39888a9c020eSBarry Smith PetscInt *v_pivots, *IJ, j; 39898a9c020eSBarry Smith PetscScalar *v_work; 39908a9c020eSBarry Smith 3991d63b1753SJacob Faibussowitsch PetscCall(PetscMalloc3(m, &v_work, m, &v_pivots, m, &IJ)); 3992d63b1753SJacob Faibussowitsch for (j = 0; j < m; j++) IJ[j] = j; 3993d63b1753SJacob Faibussowitsch PetscCall(PetscKernel_A_gets_inverse_A(m, values, v_pivots, v_work, allowzeropivot, &zeropivotdetected)); 39948a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39958a9c020eSBarry Smith PetscCall(PetscFree3(v_work, v_pivots, IJ)); 39968a9c020eSBarry Smith } 39978a9c020eSBarry Smith } 3998d63b1753SJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &values)); 39993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 40008a9c020eSBarry Smith } 4001