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 417d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_Cholesky(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T) 418d71ae5a4SJacob Faibussowitsch { 4194396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4204396437dSToby Isaac PetscBLASInt info; 4214396437dSToby Isaac 4224396437dSToby Isaac PetscFunctionBegin; 423b94d7dedSBarry Smith if (A->spd == PETSC_BOOL3_TRUE) { 4249566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A)); 4259566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 426792fecdfSBarry Smith PetscCallBLAS("LAPACKpotrs", LAPACKpotrs_("L", &m, &nrhs, mat->v, &mat->lda, x, &m, &info)); 4279566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 428835f2295SStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "POTRS Bad solve %" PetscBLASInt_FMT, info); 4299566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A)); 430a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX) 431b94d7dedSBarry Smith } else if (A->hermitian == PETSC_BOOL3_TRUE) { 4329566063dSJacob Faibussowitsch if (T) PetscCall(MatConjugate_SeqDense(A)); 4339566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 434792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrs", LAPACKhetrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info)); 4359566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 436835f2295SStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "HETRS Bad solve %" PetscBLASInt_FMT, info); 4379566063dSJacob Faibussowitsch if (T) PetscCall(MatConjugate_SeqDense(A)); 438a49dc2a2SStefano Zampini #endif 439a49dc2a2SStefano Zampini } else { /* symmetric case */ 4409566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 441792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrs", LAPACKsytrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info)); 4429566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 443835f2295SStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "SYTRS Bad solve %" PetscBLASInt_FMT, info); 444a49dc2a2SStefano Zampini } 4459566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m))); 4463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4474396437dSToby Isaac } 44885e2c93fSHong Zhang 449d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k) 450d71ae5a4SJacob Faibussowitsch { 4514396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4524396437dSToby Isaac PetscBLASInt info; 4534396437dSToby Isaac char trans; 4544396437dSToby Isaac 4554396437dSToby Isaac PetscFunctionBegin; 4564905a7bcSToby Isaac if (PetscDefined(USE_COMPLEX)) { 4574905a7bcSToby Isaac trans = 'C'; 4584905a7bcSToby Isaac } else { 4594905a7bcSToby Isaac trans = 'T'; 4604905a7bcSToby Isaac } 4619566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 46205fcb23eSStefano Zampini { /* lwork depends on the number of right-hand sides */ 46305fcb23eSStefano Zampini PetscBLASInt nlfwork, lfwork = -1; 46405fcb23eSStefano Zampini PetscScalar fwork; 46505fcb23eSStefano Zampini 466792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info)); 46705fcb23eSStefano Zampini nlfwork = (PetscBLASInt)PetscRealPart(fwork); 46805fcb23eSStefano Zampini if (nlfwork > mat->lfwork) { 46905fcb23eSStefano Zampini mat->lfwork = nlfwork; 47005fcb23eSStefano Zampini PetscCall(PetscFree(mat->fwork)); 47105fcb23eSStefano Zampini PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 47205fcb23eSStefano Zampini } 47305fcb23eSStefano Zampini } 474792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info)); 4759566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 476835f2295SStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %" PetscBLASInt_FMT, info); 4779566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 478792fecdfSBarry Smith PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "N", "N", &mat->rank, &nrhs, mat->v, &mat->lda, x, &ldx, &info)); 4799566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 480835f2295SStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %" PetscBLASInt_FMT, info); 4814905a7bcSToby Isaac for (PetscInt j = 0; j < nrhs; j++) { 482ad540459SPierre Jolivet for (PetscInt i = mat->rank; i < k; i++) x[j * ldx + i] = 0.; 4834905a7bcSToby Isaac } 4849566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank)))); 4853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4864905a7bcSToby Isaac } 4874905a7bcSToby Isaac 488d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k) 489d71ae5a4SJacob Faibussowitsch { 4904396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4914396437dSToby Isaac PetscBLASInt info; 4924396437dSToby Isaac 4934396437dSToby Isaac PetscFunctionBegin; 4944396437dSToby Isaac if (A->rmap->n == A->cmap->n && mat->rank == A->rmap->n) { 4959566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 496792fecdfSBarry Smith PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "T", "N", &m, &nrhs, mat->v, &mat->lda, x, &ldx, &info)); 4979566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 498835f2295SStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %" PetscBLASInt_FMT, info); 4999566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A)); 50005fcb23eSStefano Zampini { /* lwork depends on the number of right-hand sides */ 50105fcb23eSStefano Zampini PetscBLASInt nlfwork, lfwork = -1; 50205fcb23eSStefano Zampini PetscScalar fwork; 50305fcb23eSStefano Zampini 504792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info)); 50505fcb23eSStefano Zampini nlfwork = (PetscBLASInt)PetscRealPart(fwork); 50605fcb23eSStefano Zampini if (nlfwork > mat->lfwork) { 50705fcb23eSStefano Zampini mat->lfwork = nlfwork; 50805fcb23eSStefano Zampini PetscCall(PetscFree(mat->fwork)); 50905fcb23eSStefano Zampini PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 51005fcb23eSStefano Zampini } 51105fcb23eSStefano Zampini } 5129566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 513792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info)); 5149566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 515835f2295SStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %" PetscBLASInt_FMT, info); 5169566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A)); 5174396437dSToby Isaac } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "QR factored matrix cannot be used for transpose solve"); 5189566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank)))); 5193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5204396437dSToby Isaac } 5214396437dSToby Isaac 522d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_SetUp(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k) 523d71ae5a4SJacob Faibussowitsch { 5244396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 5254905a7bcSToby Isaac PetscScalar *y; 5264905a7bcSToby Isaac PetscBLASInt m = 0, k = 0; 5274905a7bcSToby Isaac 5284905a7bcSToby Isaac PetscFunctionBegin; 5299566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 5309566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 5314905a7bcSToby Isaac if (k < m) { 5329566063dSJacob Faibussowitsch PetscCall(VecCopy(xx, mat->qrrhs)); 5339566063dSJacob Faibussowitsch PetscCall(VecGetArray(mat->qrrhs, &y)); 5344905a7bcSToby Isaac } else { 5359566063dSJacob Faibussowitsch PetscCall(VecCopy(xx, yy)); 5369566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &y)); 5374905a7bcSToby Isaac } 5384396437dSToby Isaac *_y = y; 5394396437dSToby Isaac *_k = k; 5404396437dSToby Isaac *_m = m; 5413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5424396437dSToby Isaac } 5434396437dSToby Isaac 544d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_TearDown(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k) 545d71ae5a4SJacob Faibussowitsch { 5464396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 54742e9364cSSatish Balay PetscScalar *y = NULL; 5484396437dSToby Isaac PetscBLASInt m, k; 5494396437dSToby Isaac 5504396437dSToby Isaac PetscFunctionBegin; 5514396437dSToby Isaac y = *_y; 5524396437dSToby Isaac *_y = NULL; 5534396437dSToby Isaac k = *_k; 5544396437dSToby Isaac m = *_m; 5554905a7bcSToby Isaac if (k < m) { 5564905a7bcSToby Isaac PetscScalar *yv; 5579566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &yv)); 5589566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(yv, y, k)); 5599566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &yv)); 5609566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(mat->qrrhs, &y)); 5614905a7bcSToby Isaac } else { 5629566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &y)); 5634905a7bcSToby Isaac } 5643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5654905a7bcSToby Isaac } 5664905a7bcSToby Isaac 567d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_LU(Mat A, Vec xx, Vec yy) 568d71ae5a4SJacob Faibussowitsch { 56942e9364cSSatish Balay PetscScalar *y = NULL; 57042e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 5714396437dSToby Isaac 5724396437dSToby Isaac PetscFunctionBegin; 5739566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 5749566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_FALSE)); 5759566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 5763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5774396437dSToby Isaac } 5784396437dSToby Isaac 579d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_LU(Mat A, Vec xx, Vec yy) 580d71ae5a4SJacob Faibussowitsch { 58142e9364cSSatish Balay PetscScalar *y = NULL; 58242e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 5834396437dSToby Isaac 5844396437dSToby Isaac PetscFunctionBegin; 5859566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 5869566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_TRUE)); 5879566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 5883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5894396437dSToby Isaac } 5904396437dSToby Isaac 591d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Cholesky(Mat A, Vec xx, Vec yy) 592d71ae5a4SJacob Faibussowitsch { 593e54beecaSStefano Zampini PetscScalar *y = NULL; 594e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 5954396437dSToby Isaac 5964396437dSToby Isaac PetscFunctionBegin; 5979566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 5989566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_FALSE)); 5999566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6014396437dSToby Isaac } 6024396437dSToby Isaac 603d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_Cholesky(Mat A, Vec xx, Vec yy) 604d71ae5a4SJacob Faibussowitsch { 605e54beecaSStefano Zampini PetscScalar *y = NULL; 606e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 6074396437dSToby Isaac 6084396437dSToby Isaac PetscFunctionBegin; 6099566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6109566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_TRUE)); 6119566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6134396437dSToby Isaac } 6144396437dSToby Isaac 615d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_QR(Mat A, Vec xx, Vec yy) 616d71ae5a4SJacob Faibussowitsch { 617e54beecaSStefano Zampini PetscScalar *y = NULL; 618e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 6194396437dSToby Isaac 6204396437dSToby Isaac PetscFunctionBegin; 6219566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6229566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k)); 6239566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6254396437dSToby Isaac } 6264396437dSToby Isaac 627d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_QR(Mat A, Vec xx, Vec yy) 628d71ae5a4SJacob Faibussowitsch { 62942e9364cSSatish Balay PetscScalar *y = NULL; 63042e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 6314396437dSToby Isaac 6324396437dSToby Isaac PetscFunctionBegin; 6339566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6349566063dSJacob Faibussowitsch PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k)); 6359566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6374396437dSToby Isaac } 6384396437dSToby Isaac 639d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_SetUp(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k) 640d71ae5a4SJacob Faibussowitsch { 6414905a7bcSToby Isaac const PetscScalar *b; 6424396437dSToby Isaac PetscScalar *y; 643bf5a80bcSToby Isaac PetscInt n, _ldb, _ldx; 644bf5a80bcSToby Isaac PetscBLASInt nrhs = 0, m = 0, k = 0, ldb = 0, ldx = 0, ldy = 0; 6454905a7bcSToby Isaac 6464905a7bcSToby Isaac PetscFunctionBegin; 6479371c9d4SSatish Balay *_ldy = 0; 6489371c9d4SSatish Balay *_m = 0; 6499371c9d4SSatish Balay *_nrhs = 0; 6509371c9d4SSatish Balay *_k = 0; 6519371c9d4SSatish Balay *_y = NULL; 6529566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 6539566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 6549566063dSJacob Faibussowitsch PetscCall(MatGetSize(B, NULL, &n)); 6559566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(n, &nrhs)); 6569566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(B, &_ldb)); 6579566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldb, &ldb)); 6589566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(X, &_ldx)); 6599566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldx, &ldx)); 660bf5a80bcSToby Isaac if (ldx < m) { 6619566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &b)); 6629566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nrhs * m, &y)); 663bf5a80bcSToby Isaac if (ldb == m) { 6649566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(y, b, ldb * nrhs)); 6654905a7bcSToby Isaac } else { 66648a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * m], &b[j * ldb], m)); 6674905a7bcSToby Isaac } 668bf5a80bcSToby Isaac ldy = m; 6699566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &b)); 6704905a7bcSToby Isaac } else { 671bf5a80bcSToby Isaac if (ldb == ldx) { 6729566063dSJacob Faibussowitsch PetscCall(MatCopy(B, X, SAME_NONZERO_PATTERN)); 6739566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &y)); 6744905a7bcSToby Isaac } else { 6759566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &y)); 6769566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &b)); 67748a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * ldx], &b[j * ldb], m)); 6789566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &b)); 6794905a7bcSToby Isaac } 680bf5a80bcSToby Isaac ldy = ldx; 6814905a7bcSToby Isaac } 6824396437dSToby Isaac *_y = y; 683bf5a80bcSToby Isaac *_ldy = ldy; 6844396437dSToby Isaac *_k = k; 6854396437dSToby Isaac *_m = m; 6864396437dSToby Isaac *_nrhs = nrhs; 6873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6884396437dSToby Isaac } 6894396437dSToby Isaac 690d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_TearDown(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k) 691d71ae5a4SJacob Faibussowitsch { 6924396437dSToby Isaac PetscScalar *y; 693bf5a80bcSToby Isaac PetscInt _ldx; 694bf5a80bcSToby Isaac PetscBLASInt k, ldy, nrhs, ldx = 0; 6954396437dSToby Isaac 6964396437dSToby Isaac PetscFunctionBegin; 6974396437dSToby Isaac y = *_y; 6984396437dSToby Isaac *_y = NULL; 6994396437dSToby Isaac k = *_k; 700bf5a80bcSToby Isaac ldy = *_ldy; 7014396437dSToby Isaac nrhs = *_nrhs; 7029566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(X, &_ldx)); 7039566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldx, &ldx)); 704bf5a80bcSToby Isaac if (ldx != ldy) { 7054905a7bcSToby Isaac PetscScalar *xv; 7069566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &xv)); 70748a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&xv[j * ldx], &y[j * ldy], k)); 7089566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(X, &xv)); 7099566063dSJacob Faibussowitsch PetscCall(PetscFree(y)); 7104905a7bcSToby Isaac } else { 7119566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(X, &y)); 7124905a7bcSToby Isaac } 7133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 71485e2c93fSHong Zhang } 71585e2c93fSHong Zhang 716d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_LU(Mat A, Mat B, Mat X) 717d71ae5a4SJacob Faibussowitsch { 7184396437dSToby Isaac PetscScalar *y; 719bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7204396437dSToby Isaac 7214396437dSToby Isaac PetscFunctionBegin; 7229566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7239566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_FALSE)); 7249566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7264396437dSToby Isaac } 7274396437dSToby Isaac 728d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_LU(Mat A, Mat B, Mat X) 729d71ae5a4SJacob Faibussowitsch { 7304396437dSToby Isaac PetscScalar *y; 731bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7324396437dSToby Isaac 7334396437dSToby Isaac PetscFunctionBegin; 7349566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7359566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_TRUE)); 7369566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7384396437dSToby Isaac } 7394396437dSToby Isaac 740d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_Cholesky(Mat A, Mat B, Mat X) 741d71ae5a4SJacob Faibussowitsch { 7424396437dSToby Isaac PetscScalar *y; 743bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7444396437dSToby Isaac 7454396437dSToby Isaac PetscFunctionBegin; 7469566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7479566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_FALSE)); 7489566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7504396437dSToby Isaac } 7514396437dSToby Isaac 752d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_Cholesky(Mat A, Mat B, Mat X) 753d71ae5a4SJacob Faibussowitsch { 7544396437dSToby Isaac PetscScalar *y; 755bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7564396437dSToby Isaac 7574396437dSToby Isaac PetscFunctionBegin; 7589566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7599566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_TRUE)); 7609566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7624396437dSToby Isaac } 7634396437dSToby Isaac 764d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_QR(Mat A, Mat B, Mat X) 765d71ae5a4SJacob Faibussowitsch { 7664396437dSToby Isaac PetscScalar *y; 767bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7684396437dSToby Isaac 7694396437dSToby Isaac PetscFunctionBegin; 7709566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7719566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k)); 7729566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7744396437dSToby Isaac } 7754396437dSToby Isaac 776d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_QR(Mat A, Mat B, Mat X) 777d71ae5a4SJacob Faibussowitsch { 7784396437dSToby Isaac PetscScalar *y; 779bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7804396437dSToby Isaac 7814396437dSToby Isaac PetscFunctionBegin; 7829566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7839566063dSJacob Faibussowitsch PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k)); 7849566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7864396437dSToby Isaac } 7874396437dSToby Isaac 788db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots, 789db4efbfdSBarry Smith rather than put it in the Mat->row slot.*/ 790d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLUFactor_SeqDense(Mat A, IS row, IS col, const MatFactorInfo *minfo) 791d71ae5a4SJacob Faibussowitsch { 792db4efbfdSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 793db4efbfdSBarry Smith PetscBLASInt n, m, info; 794db4efbfdSBarry Smith 795db4efbfdSBarry Smith PetscFunctionBegin; 7969566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 7979566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 7984dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); } 7993ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 8009566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 801792fecdfSBarry Smith PetscCallBLAS("LAPACKgetrf", LAPACKgetrf_(&m, &n, mat->v, &mat->lda, mat->pivots, &info)); 8029566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 8038e57ea43SSatish Balay 804835f2295SStefano Zampini PetscCheck(info >= 0, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to LU factorization %" PetscBLASInt_FMT, info); 805835f2295SStefano Zampini PetscCheck(info <= 0, PETSC_COMM_SELF, PETSC_ERR_MAT_LU_ZRPVT, "Bad LU factorization %" PetscBLASInt_FMT, info); 8068208b9aeSStefano Zampini 8074396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_LU; 8084396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_LU; 8094396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_LU; 8104396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_LU; 811d5f3da31SBarry Smith A->factortype = MAT_FACTOR_LU; 812db4efbfdSBarry Smith 8139566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 8149566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 815f6224b95SHong Zhang 8169566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((2.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3)); 8173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 818db4efbfdSBarry Smith } 819db4efbfdSBarry Smith 820d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) 821d71ae5a4SJacob Faibussowitsch { 8224396437dSToby Isaac MatFactorInfo info; 8234396437dSToby Isaac 8244396437dSToby Isaac PetscFunctionBegin; 8259566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 826dbbe0bcdSBarry Smith PetscUseTypeMethod(fact, lufactor, NULL, NULL, &info); 8273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8284396437dSToby Isaac } 8294396437dSToby Isaac 830d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, IS col, 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 */ 840d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCholeskyFactor_SeqDense(Mat A, IS perm, const MatFactorInfo *factinfo) 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 900d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) 901d71ae5a4SJacob Faibussowitsch { 902db4efbfdSBarry Smith MatFactorInfo info; 903db4efbfdSBarry Smith 904db4efbfdSBarry Smith PetscFunctionBegin; 905db4efbfdSBarry Smith info.fill = 1.0; 9062205254eSKarl Rupp 9079566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 908dbbe0bcdSBarry Smith PetscUseTypeMethod(fact, choleskyfactor, NULL, &info); 9093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 910db4efbfdSBarry Smith } 911db4efbfdSBarry Smith 912d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info) 913d71ae5a4SJacob Faibussowitsch { 914db4efbfdSBarry Smith PetscFunctionBegin; 915c3ef05f6SHong Zhang fact->assembled = PETSC_TRUE; 9161bbcc794SSatish Balay fact->preallocated = PETSC_TRUE; 917719d5645SBarry Smith fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense; 9183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 919db4efbfdSBarry Smith } 920db4efbfdSBarry Smith 921d71ae5a4SJacob Faibussowitsch PetscErrorCode MatQRFactor_SeqDense(Mat A, IS col, const MatFactorInfo *minfo) 922d71ae5a4SJacob Faibussowitsch { 9234905a7bcSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 9244905a7bcSToby Isaac PetscBLASInt n, m, info, min, max; 9254905a7bcSToby Isaac 9264905a7bcSToby Isaac PetscFunctionBegin; 9279566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 9289566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 9294396437dSToby Isaac max = PetscMax(m, n); 9304396437dSToby Isaac min = PetscMin(m, n); 9314dfa11a4SJacob Faibussowitsch if (!mat->tau) { PetscCall(PetscMalloc1(min, &mat->tau)); } 9324dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(n, &mat->pivots)); } 933f4f49eeaSPierre Jolivet if (!mat->qrrhs) PetscCall(MatCreateVecs(A, NULL, &mat->qrrhs)); 9343ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 9354905a7bcSToby Isaac if (!mat->fwork) { 9364905a7bcSToby Isaac PetscScalar dummy; 9374905a7bcSToby Isaac 9384905a7bcSToby Isaac mat->lfwork = -1; 9399566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 940792fecdfSBarry Smith PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, &dummy, &mat->lfwork, &info)); 9419566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 9426497c311SBarry Smith PetscCall(PetscBLASIntCast((PetscCount)(PetscRealPart(dummy)), &mat->lfwork)); 9439566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 9444905a7bcSToby Isaac } 9459566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 946792fecdfSBarry Smith PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, mat->fwork, &mat->lfwork, &info)); 9479566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 948835f2295SStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to QR factorization %" PetscBLASInt_FMT, info); 9494905a7bcSToby 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 9504905a7bcSToby Isaac mat->rank = min; 9514905a7bcSToby Isaac 9524396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_QR; 9534396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_QR; 9544905a7bcSToby Isaac A->factortype = MAT_FACTOR_QR; 9554905a7bcSToby Isaac if (m == n) { 9564396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_QR; 9574396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_QR; 9584905a7bcSToby Isaac } 9594905a7bcSToby Isaac 9609566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 9619566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 9624905a7bcSToby Isaac 9639566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * min * min * (max - min / 3.0))); 9643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9654905a7bcSToby Isaac } 9664905a7bcSToby Isaac 967d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatQRFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) 968d71ae5a4SJacob Faibussowitsch { 9694905a7bcSToby Isaac MatFactorInfo info; 9704905a7bcSToby Isaac 9714905a7bcSToby Isaac PetscFunctionBegin; 9724905a7bcSToby Isaac info.fill = 1.0; 9734905a7bcSToby Isaac 9749566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 975cac4c232SBarry Smith PetscUseMethod(fact, "MatQRFactor_C", (Mat, IS, const MatFactorInfo *), (fact, NULL, &info)); 9763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9774905a7bcSToby Isaac } 9784905a7bcSToby Isaac 979d71ae5a4SJacob Faibussowitsch PetscErrorCode MatQRFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info) 980d71ae5a4SJacob Faibussowitsch { 9814905a7bcSToby Isaac PetscFunctionBegin; 9824905a7bcSToby Isaac fact->assembled = PETSC_TRUE; 9834905a7bcSToby Isaac fact->preallocated = PETSC_TRUE; 9849566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)fact, "MatQRFactorNumeric_C", MatQRFactorNumeric_SeqDense)); 9853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9864905a7bcSToby Isaac } 9874905a7bcSToby Isaac 988ca15aa20SStefano Zampini /* uses LAPACK */ 989d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A, MatFactorType ftype, Mat *fact) 990d71ae5a4SJacob Faibussowitsch { 991db4efbfdSBarry Smith PetscFunctionBegin; 9929566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), fact)); 9939566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*fact, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n)); 9949566063dSJacob Faibussowitsch PetscCall(MatSetType(*fact, MATDENSE)); 99566e17bc3SBarry Smith (*fact)->trivialsymbolic = PETSC_TRUE; 9962a350339SBarry Smith if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU) { 997db4efbfdSBarry Smith (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense; 9982a350339SBarry Smith (*fact)->ops->ilufactorsymbolic = MatLUFactorSymbolic_SeqDense; 999bf5a80bcSToby Isaac } else if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) { 1000db4efbfdSBarry Smith (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense; 1001bf5a80bcSToby Isaac } else if (ftype == MAT_FACTOR_QR) { 1002f4f49eeaSPierre Jolivet PetscCall(PetscObjectComposeFunction((PetscObject)*fact, "MatQRFactorSymbolic_C", MatQRFactorSymbolic_SeqDense)); 1003db4efbfdSBarry Smith } 1004d5f3da31SBarry Smith (*fact)->factortype = ftype; 100500c67f3bSHong Zhang 10069566063dSJacob Faibussowitsch PetscCall(PetscFree((*fact)->solvertype)); 10079566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &(*fact)->solvertype)); 10089566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_LU])); 10099566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ILU])); 10109566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_CHOLESKY])); 10119566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ICC])); 10123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1013db4efbfdSBarry Smith } 1014db4efbfdSBarry Smith 1015d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSOR_SeqDense(Mat A, Vec bb, PetscReal omega, MatSORType flag, PetscReal shift, PetscInt its, PetscInt lits, Vec xx) 1016d71ae5a4SJacob Faibussowitsch { 1017c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1018d9ca1df4SBarry Smith PetscScalar *x, *v = mat->v, zero = 0.0, xt; 1019d9ca1df4SBarry Smith const PetscScalar *b; 1020d0f46423SBarry Smith PetscInt m = A->rmap->n, i; 102123fff9afSBarry Smith PetscBLASInt o = 1, bm = 0; 1022289bc588SBarry Smith 10233a40ed3dSBarry Smith PetscFunctionBegin; 102447d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 102508401ef6SPierre Jolivet PetscCheck(A->offloadmask != PETSC_OFFLOAD_GPU, PETSC_COMM_SELF, PETSC_ERR_SUP, "Not implemented"); 1026ca15aa20SStefano Zampini #endif 1027422a814eSBarry Smith if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */ 10289566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(m, &bm)); 1029289bc588SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 10303bffc371SBarry Smith /* this is a hack fix, should have another version without the second BLASdotu */ 10319566063dSJacob Faibussowitsch PetscCall(VecSet(xx, zero)); 1032289bc588SBarry Smith } 10339566063dSJacob Faibussowitsch PetscCall(VecGetArray(xx, &x)); 10349566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(bb, &b)); 1035b965ef7fSBarry Smith its = its * lits; 103608401ef6SPierre 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); 1037289bc588SBarry Smith while (its--) { 1038fccaa45eSBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 1039289bc588SBarry Smith for (i = 0; i < m; i++) { 1040792fecdfSBarry Smith PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o)); 1041883424caSPierre Jolivet x[i] = (1. - omega) * x[i] + (xt + v[i + i * m] * x[i]) * omega / (v[i + i * m] + shift); 1042289bc588SBarry Smith } 1043289bc588SBarry Smith } 1044fccaa45eSBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 1045289bc588SBarry Smith for (i = m - 1; i >= 0; i--) { 1046792fecdfSBarry Smith PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o)); 1047883424caSPierre Jolivet x[i] = (1. - omega) * x[i] + (xt + v[i + i * m] * x[i]) * omega / (v[i + i * m] + shift); 1048289bc588SBarry Smith } 1049289bc588SBarry Smith } 1050289bc588SBarry Smith } 10519566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(bb, &b)); 10529566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(xx, &x)); 10533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1054289bc588SBarry Smith } 1055289bc588SBarry Smith 10560be0d8bdSHansol Suh static PetscErrorCode MatMultColumnRangeKernel_SeqDense(Mat A, Vec xx, Vec yy, PetscInt c_start, PetscInt c_end, PetscBool trans, PetscBool herm) 1057d71ae5a4SJacob Faibussowitsch { 1058c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1059d9ca1df4SBarry Smith PetscScalar *y, _DOne = 1.0, _DZero = 0.0; 10600805154bSBarry Smith PetscBLASInt m, n, _One = 1; 1061d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 10623a40ed3dSBarry Smith 10633a40ed3dSBarry Smith PetscFunctionBegin; 10649566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 10650be0d8bdSHansol Suh PetscCall(PetscBLASIntCast(c_end - c_start, &n)); 10669566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 10679566063dSJacob Faibussowitsch PetscCall(VecGetArrayWrite(yy, &y)); 10680be0d8bdSHansol Suh if (!m || !n) { 10695ac36cfcSBarry Smith PetscBLASInt i; 1070459e8d23SBlanca Mellado Pinto if (trans) 1071459e8d23SBlanca Mellado Pinto for (i = 0; i < n; i++) y[i] = 0.0; 1072459e8d23SBlanca Mellado Pinto else 10735ac36cfcSBarry Smith for (i = 0; i < m; i++) y[i] = 0.0; 10745ac36cfcSBarry Smith } else { 1075459e8d23SBlanca Mellado Pinto if (trans) { 10760be0d8bdSHansol Suh if (herm) PetscCallBLAS("BLASgemv", BLASgemv_("C", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x, &_One, &_DZero, y + c_start, &_One)); 10770be0d8bdSHansol Suh else PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x, &_One, &_DZero, y + c_start, &_One)); 1078459e8d23SBlanca Mellado Pinto } else { 10790be0d8bdSHansol Suh PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x + c_start, &_One, &_DZero, y, &_One)); 1080459e8d23SBlanca Mellado Pinto } 10810be0d8bdSHansol Suh PetscCall(PetscLogFlops(2.0 * m * n - n)); 10825ac36cfcSBarry Smith } 10839566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 10849566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayWrite(yy, &y)); 10853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1086289bc588SBarry Smith } 10876ee01492SSatish Balay 10880be0d8bdSHansol Suh PetscErrorCode MatMultHermitianTransposeColumnRange_SeqDense(Mat A, Vec xx, Vec yy, PetscInt c_start, PetscInt c_end) 10890be0d8bdSHansol Suh { 10900be0d8bdSHansol Suh PetscFunctionBegin; 10910be0d8bdSHansol Suh PetscCall(MatMultColumnRangeKernel_SeqDense(A, xx, yy, c_start, c_end, PETSC_TRUE, PETSC_TRUE)); 10920be0d8bdSHansol Suh PetscFunctionReturn(PETSC_SUCCESS); 10930be0d8bdSHansol Suh } 10940be0d8bdSHansol Suh 1095459e8d23SBlanca Mellado Pinto PetscErrorCode MatMult_SeqDense(Mat A, Vec xx, Vec yy) 1096459e8d23SBlanca Mellado Pinto { 1097459e8d23SBlanca Mellado Pinto PetscFunctionBegin; 10980be0d8bdSHansol Suh PetscCall(MatMultColumnRangeKernel_SeqDense(A, xx, yy, 0, A->cmap->n, PETSC_FALSE, PETSC_FALSE)); 1099459e8d23SBlanca Mellado Pinto PetscFunctionReturn(PETSC_SUCCESS); 1100459e8d23SBlanca Mellado Pinto } 1101459e8d23SBlanca Mellado Pinto 1102459e8d23SBlanca Mellado Pinto PetscErrorCode MatMultTranspose_SeqDense(Mat A, Vec xx, Vec yy) 1103459e8d23SBlanca Mellado Pinto { 1104459e8d23SBlanca Mellado Pinto PetscFunctionBegin; 11050be0d8bdSHansol Suh PetscCall(MatMultColumnRangeKernel_SeqDense(A, xx, yy, 0, A->cmap->n, PETSC_TRUE, PETSC_FALSE)); 1106459e8d23SBlanca Mellado Pinto PetscFunctionReturn(PETSC_SUCCESS); 1107459e8d23SBlanca Mellado Pinto } 1108459e8d23SBlanca Mellado Pinto 1109459e8d23SBlanca Mellado Pinto PetscErrorCode MatMultHermitianTranspose_SeqDense(Mat A, Vec xx, Vec yy) 1110459e8d23SBlanca Mellado Pinto { 1111459e8d23SBlanca Mellado Pinto PetscFunctionBegin; 11120be0d8bdSHansol Suh PetscCall(MatMultColumnRangeKernel_SeqDense(A, xx, yy, 0, A->cmap->n, PETSC_TRUE, PETSC_TRUE)); 1113459e8d23SBlanca Mellado Pinto PetscFunctionReturn(PETSC_SUCCESS); 1114459e8d23SBlanca Mellado Pinto } 1115459e8d23SBlanca Mellado Pinto 11160be0d8bdSHansol Suh static PetscErrorCode MatMultAddColumnRangeKernel_SeqDense(Mat A, Vec xx, Vec zz, Vec yy, PetscInt c_start, PetscInt c_end, PetscBool trans, PetscBool herm) 1117d71ae5a4SJacob Faibussowitsch { 1118c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1119d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 1120d9ca1df4SBarry Smith PetscScalar *y, _DOne = 1.0; 11210805154bSBarry Smith PetscBLASInt m, n, _One = 1; 11223a40ed3dSBarry Smith 11233a40ed3dSBarry Smith PetscFunctionBegin; 11249566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 11250be0d8bdSHansol Suh PetscCall(PetscBLASIntCast(c_end - c_start, &n)); 11269566063dSJacob Faibussowitsch PetscCall(VecCopy(zz, yy)); 11270be0d8bdSHansol Suh if (!m || !n) PetscFunctionReturn(PETSC_SUCCESS); 11289566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &y)); 1129459e8d23SBlanca Mellado Pinto PetscCall(VecGetArrayRead(xx, &x)); 1130459e8d23SBlanca Mellado Pinto if (trans) { 11310be0d8bdSHansol Suh if (herm) PetscCallBLAS("BLASgemv", BLASgemv_("C", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x, &_One, &_DOne, y + c_start, &_One)); 11320be0d8bdSHansol Suh else PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x, &_One, &_DOne, y + c_start, &_One)); 1133459e8d23SBlanca Mellado Pinto } else { 11340be0d8bdSHansol Suh PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x + c_start, &_One, &_DOne, y, &_One)); 1135459e8d23SBlanca Mellado Pinto } 11369566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 11379566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &y)); 11380be0d8bdSHansol Suh PetscCall(PetscLogFlops(2.0 * m * n)); 11390be0d8bdSHansol Suh PetscFunctionReturn(PETSC_SUCCESS); 11400be0d8bdSHansol Suh } 11410be0d8bdSHansol Suh 11420be0d8bdSHansol Suh PetscErrorCode MatMultAddColumnRange_SeqDense(Mat A, Vec xx, Vec zz, Vec yy, PetscInt c_start, PetscInt c_end) 11430be0d8bdSHansol Suh { 11440be0d8bdSHansol Suh PetscFunctionBegin; 11450be0d8bdSHansol Suh PetscCall(MatMultAddColumnRangeKernel_SeqDense(A, xx, zz, yy, c_start, c_end, PETSC_FALSE, PETSC_FALSE)); 11460be0d8bdSHansol Suh PetscFunctionReturn(PETSC_SUCCESS); 11470be0d8bdSHansol Suh } 11480be0d8bdSHansol Suh 11490be0d8bdSHansol Suh PetscErrorCode MatMultHermitianTransposeAddColumnRange_SeqDense(Mat A, Vec xx, Vec zz, Vec yy, PetscInt c_start, PetscInt c_end) 11500be0d8bdSHansol Suh { 11510be0d8bdSHansol Suh PetscFunctionBegin; 11520be0d8bdSHansol Suh PetscMPIInt rank; 11530be0d8bdSHansol Suh PetscCallMPI(MPI_Comm_rank(MPI_COMM_WORLD, &rank)); 11540be0d8bdSHansol Suh PetscCall(MatMultAddColumnRangeKernel_SeqDense(A, xx, zz, yy, c_start, c_end, PETSC_TRUE, PETSC_TRUE)); 11553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1156289bc588SBarry Smith } 11576ee01492SSatish Balay 1158459e8d23SBlanca Mellado Pinto PetscErrorCode MatMultAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) 1159459e8d23SBlanca Mellado Pinto { 1160459e8d23SBlanca Mellado Pinto PetscFunctionBegin; 11610be0d8bdSHansol Suh PetscCall(MatMultAddColumnRangeKernel_SeqDense(A, xx, zz, yy, 0, A->cmap->n, PETSC_FALSE, PETSC_FALSE)); 1162459e8d23SBlanca Mellado Pinto PetscFunctionReturn(PETSC_SUCCESS); 1163459e8d23SBlanca Mellado Pinto } 1164459e8d23SBlanca Mellado Pinto 1165d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) 1166d71ae5a4SJacob Faibussowitsch { 11673a40ed3dSBarry Smith PetscFunctionBegin; 11680be0d8bdSHansol Suh PetscCall(MatMultAddColumnRangeKernel_SeqDense(A, xx, zz, yy, 0, A->cmap->n, PETSC_TRUE, PETSC_FALSE)); 1169459e8d23SBlanca Mellado Pinto PetscFunctionReturn(PETSC_SUCCESS); 1170459e8d23SBlanca Mellado Pinto } 1171459e8d23SBlanca Mellado Pinto 1172459e8d23SBlanca Mellado Pinto PetscErrorCode MatMultHermitianTransposeAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) 1173459e8d23SBlanca Mellado Pinto { 1174459e8d23SBlanca Mellado Pinto PetscFunctionBegin; 11750be0d8bdSHansol Suh PetscCall(MatMultAddColumnRangeKernel_SeqDense(A, xx, zz, yy, 0, A->cmap->n, PETSC_TRUE, PETSC_TRUE)); 11763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1177289bc588SBarry Smith } 1178289bc588SBarry Smith 1179d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals) 1180d71ae5a4SJacob Faibussowitsch { 1181c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 118213f74950SBarry Smith PetscInt i; 118367e560aaSBarry Smith 11843a40ed3dSBarry Smith PetscFunctionBegin; 1185c3e1b152SPierre Jolivet if (ncols) *ncols = A->cmap->n; 1186289bc588SBarry Smith if (cols) { 11879566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->cmap->n, cols)); 1188d0f46423SBarry Smith for (i = 0; i < A->cmap->n; i++) (*cols)[i] = i; 1189289bc588SBarry Smith } 1190289bc588SBarry Smith if (vals) { 1191ca15aa20SStefano Zampini const PetscScalar *v; 1192ca15aa20SStefano Zampini 11939566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 11949566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->cmap->n, vals)); 1195ca15aa20SStefano Zampini v += row; 11969371c9d4SSatish Balay for (i = 0; i < A->cmap->n; i++) { 11979371c9d4SSatish Balay (*vals)[i] = *v; 11989371c9d4SSatish Balay v += mat->lda; 11999371c9d4SSatish Balay } 12009566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 1201289bc588SBarry Smith } 12023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1203289bc588SBarry Smith } 12046ee01492SSatish Balay 1205d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRestoreRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals) 1206d71ae5a4SJacob Faibussowitsch { 1207606d414cSSatish Balay PetscFunctionBegin; 12089566063dSJacob Faibussowitsch if (cols) PetscCall(PetscFree(*cols)); 12099566063dSJacob Faibussowitsch if (vals) PetscCall(PetscFree(*vals)); 12103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1211289bc588SBarry Smith } 12122ef1f0ffSBarry Smith 1213d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], const PetscScalar v[], InsertMode addv) 1214d71ae5a4SJacob Faibussowitsch { 1215c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1216ca15aa20SStefano Zampini PetscScalar *av; 121713f74950SBarry Smith PetscInt i, j, idx = 0; 121847d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1219c70f7ee4SJunchao Zhang PetscOffloadMask oldf; 1220ca15aa20SStefano Zampini #endif 1221d6dfbf8fSBarry Smith 12223a40ed3dSBarry Smith PetscFunctionBegin; 12239566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &av)); 1224289bc588SBarry Smith if (!mat->roworiented) { 1225dbb450caSBarry Smith if (addv == INSERT_VALUES) { 1226289bc588SBarry Smith for (j = 0; j < n; j++) { 12279371c9d4SSatish Balay if (indexn[j] < 0) { 12289371c9d4SSatish Balay idx += m; 12299371c9d4SSatish Balay continue; 12309371c9d4SSatish Balay } 12316bdcaf15SBarry 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); 1232289bc588SBarry Smith for (i = 0; i < m; i++) { 12339371c9d4SSatish Balay if (indexm[i] < 0) { 12349371c9d4SSatish Balay idx++; 12359371c9d4SSatish Balay continue; 12369371c9d4SSatish Balay } 12376bdcaf15SBarry Smith PetscCheck(indexm[i] < A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Row too large: row %" PetscInt_FMT " max %" PetscInt_FMT, indexm[i], A->rmap->n - 1); 12388c4a67a0SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] = v ? v[idx++] : (idx++, 0.0); 1239289bc588SBarry Smith } 1240289bc588SBarry Smith } 12410be0d8bdSHansol Suh } else { 1242289bc588SBarry Smith for (j = 0; j < n; j++) { 12439371c9d4SSatish Balay if (indexn[j] < 0) { 12449371c9d4SSatish Balay idx += m; 12459371c9d4SSatish Balay continue; 12469371c9d4SSatish Balay } 12476bdcaf15SBarry 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); 1248289bc588SBarry Smith for (i = 0; i < m; i++) { 12499371c9d4SSatish Balay if (indexm[i] < 0) { 12509371c9d4SSatish Balay idx++; 12519371c9d4SSatish Balay continue; 12529371c9d4SSatish Balay } 12536bdcaf15SBarry Smith PetscCheck(indexm[i] < A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Row too large: row %" PetscInt_FMT " max %" PetscInt_FMT, indexm[i], A->rmap->n - 1); 12548c4a67a0SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] += v ? v[idx++] : (idx++, 0.0); 1255289bc588SBarry Smith } 1256289bc588SBarry Smith } 1257289bc588SBarry Smith } 12583a40ed3dSBarry Smith } else { 1259dbb450caSBarry Smith if (addv == INSERT_VALUES) { 1260e8d4e0b9SBarry Smith for (i = 0; i < m; i++) { 12619371c9d4SSatish Balay if (indexm[i] < 0) { 12629371c9d4SSatish Balay idx += n; 12639371c9d4SSatish Balay continue; 12649371c9d4SSatish Balay } 12656bdcaf15SBarry 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); 1266e8d4e0b9SBarry Smith for (j = 0; j < n; j++) { 12679371c9d4SSatish Balay if (indexn[j] < 0) { 12689371c9d4SSatish Balay idx++; 12699371c9d4SSatish Balay continue; 12709371c9d4SSatish Balay } 12716bdcaf15SBarry 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); 12728c4a67a0SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] = v ? v[idx++] : (idx++, 0.0); 1273e8d4e0b9SBarry Smith } 1274e8d4e0b9SBarry Smith } 12750be0d8bdSHansol Suh } else { 1276289bc588SBarry Smith for (i = 0; i < m; i++) { 12779371c9d4SSatish Balay if (indexm[i] < 0) { 12789371c9d4SSatish Balay idx += n; 12799371c9d4SSatish Balay continue; 12809371c9d4SSatish Balay } 12816bdcaf15SBarry 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); 1282289bc588SBarry Smith for (j = 0; j < n; j++) { 12839371c9d4SSatish Balay if (indexn[j] < 0) { 12849371c9d4SSatish Balay idx++; 12859371c9d4SSatish Balay continue; 12869371c9d4SSatish Balay } 12876bdcaf15SBarry 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); 12888c4a67a0SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] += v ? v[idx++] : (idx++, 0.0); 1289289bc588SBarry Smith } 1290289bc588SBarry Smith } 1291289bc588SBarry Smith } 1292e8d4e0b9SBarry Smith } 1293ca15aa20SStefano Zampini /* hack to prevent unneeded copy to the GPU while returning the array */ 129447d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1295c70f7ee4SJunchao Zhang oldf = A->offloadmask; 1296c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_GPU; 1297ca15aa20SStefano Zampini #endif 12989566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &av)); 129947d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1300c70f7ee4SJunchao Zhang A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU); 1301ca15aa20SStefano Zampini #endif 13023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1303289bc588SBarry Smith } 1304e8d4e0b9SBarry Smith 1305d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], PetscScalar v[]) 1306d71ae5a4SJacob Faibussowitsch { 1307ae80bb75SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1308ca15aa20SStefano Zampini const PetscScalar *vv; 130913f74950SBarry Smith PetscInt i, j; 1310ae80bb75SLois Curfman McInnes 13113a40ed3dSBarry Smith PetscFunctionBegin; 13129566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &vv)); 1313ae80bb75SLois Curfman McInnes /* row-oriented output */ 1314ae80bb75SLois Curfman McInnes for (i = 0; i < m; i++) { 13159371c9d4SSatish Balay if (indexm[i] < 0) { 13169371c9d4SSatish Balay v += n; 13179371c9d4SSatish Balay continue; 13189371c9d4SSatish Balay } 131908401ef6SPierre 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); 1320ae80bb75SLois Curfman McInnes for (j = 0; j < n; j++) { 13219371c9d4SSatish Balay if (indexn[j] < 0) { 13229371c9d4SSatish Balay v++; 13239371c9d4SSatish Balay continue; 13249371c9d4SSatish Balay } 132508401ef6SPierre 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); 1326ca15aa20SStefano Zampini *v++ = vv[indexn[j] * mat->lda + indexm[i]]; 1327ae80bb75SLois Curfman McInnes } 1328ae80bb75SLois Curfman McInnes } 13299566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &vv)); 13303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1331ae80bb75SLois Curfman McInnes } 1332ae80bb75SLois Curfman McInnes 1333d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_Dense_Binary(Mat mat, PetscViewer viewer) 1334d71ae5a4SJacob Faibussowitsch { 13358491ab44SLisandro Dalcin PetscBool skipHeader; 13368491ab44SLisandro Dalcin PetscViewerFormat format; 13373e1d7bceSPierre Jolivet PetscInt header[4], M, N, m, lda, i, j; 13383e1d7bceSPierre Jolivet PetscCount k; 13398491ab44SLisandro Dalcin const PetscScalar *v; 13408491ab44SLisandro Dalcin PetscScalar *vwork; 1341aabbc4fbSShri Abhyankar 1342aabbc4fbSShri Abhyankar PetscFunctionBegin; 13439566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 13449566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader)); 13459566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 13468491ab44SLisandro Dalcin if (skipHeader) format = PETSC_VIEWER_NATIVE; 1347aabbc4fbSShri Abhyankar 13489566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &M, &N)); 13498491ab44SLisandro Dalcin 13508491ab44SLisandro Dalcin /* write matrix header */ 13519371c9d4SSatish Balay header[0] = MAT_FILE_CLASSID; 13529371c9d4SSatish Balay header[1] = M; 13539371c9d4SSatish Balay header[2] = N; 13548491ab44SLisandro Dalcin header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M * N; 13559566063dSJacob Faibussowitsch if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer, header, 4, PETSC_INT)); 13568491ab44SLisandro Dalcin 13579566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mat, &m, NULL)); 13588491ab44SLisandro Dalcin if (format != PETSC_VIEWER_NATIVE) { 13598491ab44SLisandro Dalcin PetscInt nnz = m * N, *iwork; 13608491ab44SLisandro Dalcin /* store row lengths for each row */ 13619566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz, &iwork)); 13628491ab44SLisandro Dalcin for (i = 0; i < m; i++) iwork[i] = N; 13639566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 13648491ab44SLisandro Dalcin /* store column indices (zero start index) */ 13658491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 13669371c9d4SSatish Balay for (j = 0; j < N; j++, k++) iwork[k] = j; 13679566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 13689566063dSJacob Faibussowitsch PetscCall(PetscFree(iwork)); 13698491ab44SLisandro Dalcin } 13708491ab44SLisandro Dalcin /* store matrix values as a dense matrix in row major order */ 13719566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m * N, &vwork)); 13729566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(mat, &v)); 13739566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(mat, &lda)); 13748491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 13753e1d7bceSPierre Jolivet for (j = 0; j < N; j++, k++) vwork[k] = v[i + (size_t)lda * j]; 13769566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(mat, &v)); 13779566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, vwork, m * N, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 13789566063dSJacob Faibussowitsch PetscCall(PetscFree(vwork)); 13793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13808491ab44SLisandro Dalcin } 13818491ab44SLisandro Dalcin 1382d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLoad_Dense_Binary(Mat mat, PetscViewer viewer) 1383d71ae5a4SJacob Faibussowitsch { 13848491ab44SLisandro Dalcin PetscBool skipHeader; 13858491ab44SLisandro Dalcin PetscInt header[4], M, N, m, nz, lda, i, j, k; 13868491ab44SLisandro Dalcin PetscInt rows, cols; 13878491ab44SLisandro Dalcin PetscScalar *v, *vwork; 13888491ab44SLisandro Dalcin 13898491ab44SLisandro Dalcin PetscFunctionBegin; 13909566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 13919566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader)); 13928491ab44SLisandro Dalcin 13938491ab44SLisandro Dalcin if (!skipHeader) { 13949566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, header, 4, NULL, PETSC_INT)); 139508401ef6SPierre Jolivet PetscCheck(header[0] == MAT_FILE_CLASSID, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Not a matrix object in file"); 13969371c9d4SSatish Balay M = header[1]; 13979371c9d4SSatish Balay N = header[2]; 139808401ef6SPierre Jolivet PetscCheck(M >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix row size (%" PetscInt_FMT ") in file is negative", M); 139908401ef6SPierre Jolivet PetscCheck(N >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix column size (%" PetscInt_FMT ") in file is negative", N); 14008491ab44SLisandro Dalcin nz = header[3]; 1401aed4548fSBarry Smith PetscCheck(nz == MATRIX_BINARY_FORMAT_DENSE || nz >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Unknown matrix format %" PetscInt_FMT " in file", nz); 1402aabbc4fbSShri Abhyankar } else { 14039566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &M, &N)); 1404aed4548fSBarry 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"); 14058491ab44SLisandro Dalcin nz = MATRIX_BINARY_FORMAT_DENSE; 1406e6324fbbSBarry Smith } 1407aabbc4fbSShri Abhyankar 14088491ab44SLisandro Dalcin /* setup global sizes if not set */ 14098491ab44SLisandro Dalcin if (mat->rmap->N < 0) mat->rmap->N = M; 14108491ab44SLisandro Dalcin if (mat->cmap->N < 0) mat->cmap->N = N; 14119566063dSJacob Faibussowitsch PetscCall(MatSetUp(mat)); 14128491ab44SLisandro Dalcin /* check if global sizes are correct */ 14139566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &rows, &cols)); 1414aed4548fSBarry 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); 1415aabbc4fbSShri Abhyankar 14169566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, NULL, &N)); 14179566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mat, &m, NULL)); 14189566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(mat, &v)); 14199566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(mat, &lda)); 14208491ab44SLisandro Dalcin if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense format */ 14213e1d7bceSPierre Jolivet PetscCount nnz = (size_t)m * N; 14228491ab44SLisandro Dalcin /* read in matrix values */ 14239566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz, &vwork)); 14249566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 14258491ab44SLisandro Dalcin /* store values in column major order */ 14268491ab44SLisandro Dalcin for (j = 0; j < N; j++) 14273e1d7bceSPierre Jolivet for (i = 0; i < m; i++) v[i + (size_t)lda * j] = vwork[(size_t)i * N + j]; 14289566063dSJacob Faibussowitsch PetscCall(PetscFree(vwork)); 14298491ab44SLisandro Dalcin } else { /* matrix in file is sparse format */ 14308491ab44SLisandro Dalcin PetscInt nnz = 0, *rlens, *icols; 14318491ab44SLisandro Dalcin /* read in row lengths */ 14329566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m, &rlens)); 14339566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, rlens, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 14348491ab44SLisandro Dalcin for (i = 0; i < m; i++) nnz += rlens[i]; 14358491ab44SLisandro Dalcin /* read in column indices and values */ 14369566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(nnz, &icols, nnz, &vwork)); 14379566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, icols, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 14389566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 14398491ab44SLisandro Dalcin /* store values in column major order */ 14408491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 14419371c9d4SSatish Balay for (j = 0; j < rlens[i]; j++, k++) v[i + lda * icols[k]] = vwork[k]; 14429566063dSJacob Faibussowitsch PetscCall(PetscFree(rlens)); 14439566063dSJacob Faibussowitsch PetscCall(PetscFree2(icols, vwork)); 1444aabbc4fbSShri Abhyankar } 14459566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(mat, &v)); 14469566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY)); 14479566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY)); 14483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1449aabbc4fbSShri Abhyankar } 1450aabbc4fbSShri Abhyankar 145166976f2fSJacob Faibussowitsch static PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer) 1452d71ae5a4SJacob Faibussowitsch { 1453eb91f321SVaclav Hapla PetscBool isbinary, ishdf5; 1454eb91f321SVaclav Hapla 1455eb91f321SVaclav Hapla PetscFunctionBegin; 1456eb91f321SVaclav Hapla PetscValidHeaderSpecific(newMat, MAT_CLASSID, 1); 1457eb91f321SVaclav Hapla PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1458eb91f321SVaclav Hapla /* force binary viewer to load .info file if it has not yet done so */ 14599566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 14609566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 14619566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5)); 1462eb91f321SVaclav Hapla if (isbinary) { 14639566063dSJacob Faibussowitsch PetscCall(MatLoad_Dense_Binary(newMat, viewer)); 1464eb91f321SVaclav Hapla } else if (ishdf5) { 1465eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5) 14669566063dSJacob Faibussowitsch PetscCall(MatLoad_Dense_HDF5(newMat, viewer)); 1467eb91f321SVaclav Hapla #else 1468eb91f321SVaclav Hapla SETERRQ(PetscObjectComm((PetscObject)newMat), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1469eb91f321SVaclav Hapla #endif 1470eb91f321SVaclav Hapla } else { 147198921bdaSJacob 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); 1472eb91f321SVaclav Hapla } 14733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1474eb91f321SVaclav Hapla } 1475eb91f321SVaclav Hapla 1476d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_ASCII(Mat A, PetscViewer viewer) 1477d71ae5a4SJacob Faibussowitsch { 1478932b0c3eSLois Curfman McInnes Mat_SeqDense *a = (Mat_SeqDense *)A->data; 147913f74950SBarry Smith PetscInt i, j; 14802dcb1b2aSMatthew Knepley const char *name; 1481ca15aa20SStefano Zampini PetscScalar *v, *av; 1482f3ef73ceSBarry Smith PetscViewerFormat format; 14835f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX) 1484ace3abfcSBarry Smith PetscBool allreal = PETSC_TRUE; 14855f481a85SSatish Balay #endif 1486932b0c3eSLois Curfman McInnes 14873a40ed3dSBarry Smith PetscFunctionBegin; 14889566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&av)); 14899566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 1490456192e2SBarry Smith if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 14913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); /* do nothing for now */ 1492fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 14939566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE)); 1494d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 1495ca15aa20SStefano Zampini v = av + i; 14969566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "row %" PetscInt_FMT ":", i)); 1497d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1498aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 1499329f5518SBarry Smith if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) { 15009566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g + %g i) ", j, (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v))); 1501329f5518SBarry Smith } else if (PetscRealPart(*v)) { 15029566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)PetscRealPart(*v))); 15036831982aSBarry Smith } 150480cd9d93SLois Curfman McInnes #else 150548a46eb9SPierre Jolivet if (*v) PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)*v)); 150680cd9d93SLois Curfman McInnes #endif 15071b807ce4Svictorle v += a->lda; 150880cd9d93SLois Curfman McInnes } 15099566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 151080cd9d93SLois Curfman McInnes } 15119566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE)); 15123a40ed3dSBarry Smith } else { 15139566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE)); 1514aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 151547989497SBarry Smith /* determine if matrix has all real values */ 1516bcd8d3a4SJose E. Roman for (j = 0; j < A->cmap->n; j++) { 1517bcd8d3a4SJose E. Roman v = av + j * a->lda; 1518bcd8d3a4SJose E. Roman for (i = 0; i < A->rmap->n; i++) { 15199371c9d4SSatish Balay if (PetscImaginaryPart(v[i])) { 15209371c9d4SSatish Balay allreal = PETSC_FALSE; 15219371c9d4SSatish Balay break; 15229371c9d4SSatish Balay } 152347989497SBarry Smith } 1524bcd8d3a4SJose E. Roman } 152547989497SBarry Smith #endif 1526fb9695e5SSatish Balay if (format == PETSC_VIEWER_ASCII_MATLAB) { 15279566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)A, &name)); 15289566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%% Size = %" PetscInt_FMT " %" PetscInt_FMT " \n", A->rmap->n, A->cmap->n)); 15299566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%s = zeros(%" PetscInt_FMT ",%" PetscInt_FMT ");\n", name, A->rmap->n, A->cmap->n)); 15309566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%s = [\n", name)); 1531ffac6cdbSBarry Smith } 1532ffac6cdbSBarry Smith 1533d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 1534ca15aa20SStefano Zampini v = av + i; 1535d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1536aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 153747989497SBarry Smith if (allreal) { 15389566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)PetscRealPart(*v))); 153947989497SBarry Smith } else { 15409566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e + %18.16ei ", (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v))); 154147989497SBarry Smith } 1542289bc588SBarry Smith #else 15439566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)*v)); 1544289bc588SBarry Smith #endif 15451b807ce4Svictorle v += a->lda; 1546289bc588SBarry Smith } 15479566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 1548289bc588SBarry Smith } 154948a46eb9SPierre Jolivet if (format == PETSC_VIEWER_ASCII_MATLAB) PetscCall(PetscViewerASCIIPrintf(viewer, "];\n")); 15509566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE)); 1551da3a660dSBarry Smith } 15529566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&av)); 15539566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer)); 15543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1555289bc588SBarry Smith } 1556289bc588SBarry Smith 15579804daf3SBarry Smith #include <petscdraw.h> 1558d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw, void *Aa) 1559d71ae5a4SJacob Faibussowitsch { 1560f1af5d2fSBarry Smith Mat A = (Mat)Aa; 1561383922c3SLisandro Dalcin PetscInt m = A->rmap->n, n = A->cmap->n, i, j; 1562383922c3SLisandro Dalcin int color = PETSC_DRAW_WHITE; 1563ca15aa20SStefano Zampini const PetscScalar *v; 1564b0a32e0cSBarry Smith PetscViewer viewer; 1565b05fc000SLisandro Dalcin PetscReal xl, yl, xr, yr, x_l, x_r, y_l, y_r; 1566f3ef73ceSBarry Smith PetscViewerFormat format; 1567f1af5d2fSBarry Smith 1568f1af5d2fSBarry Smith PetscFunctionBegin; 15699566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)A, "Zoomviewer", (PetscObject *)&viewer)); 15709566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 15719566063dSJacob Faibussowitsch PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr)); 1572f1af5d2fSBarry Smith 1573f1af5d2fSBarry Smith /* Loop over matrix elements drawing boxes */ 15749566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 1575fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 1576d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 1577f1af5d2fSBarry Smith /* Blue for negative and Red for positive */ 1578f1af5d2fSBarry Smith for (j = 0; j < n; j++) { 15799371c9d4SSatish Balay x_l = j; 15809371c9d4SSatish Balay x_r = x_l + 1.0; 1581f1af5d2fSBarry Smith for (i = 0; i < m; i++) { 1582f1af5d2fSBarry Smith y_l = m - i - 1.0; 1583f1af5d2fSBarry Smith y_r = y_l + 1.0; 1584ca15aa20SStefano Zampini if (PetscRealPart(v[j * m + i]) > 0.) color = PETSC_DRAW_RED; 1585ca15aa20SStefano Zampini else if (PetscRealPart(v[j * m + i]) < 0.) color = PETSC_DRAW_BLUE; 1586ca15aa20SStefano Zampini else continue; 15879566063dSJacob Faibussowitsch PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color)); 1588f1af5d2fSBarry Smith } 1589f1af5d2fSBarry Smith } 1590d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 1591f1af5d2fSBarry Smith } else { 1592f1af5d2fSBarry Smith /* use contour shading to indicate magnitude of values */ 1593f1af5d2fSBarry Smith /* first determine max of all nonzero values */ 1594b05fc000SLisandro Dalcin PetscReal minv = 0.0, maxv = 0.0; 1595b05fc000SLisandro Dalcin PetscDraw popup; 1596b05fc000SLisandro Dalcin 1597f1af5d2fSBarry Smith for (i = 0; i < m * n; i++) { 1598f1af5d2fSBarry Smith if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]); 1599f1af5d2fSBarry Smith } 1600383922c3SLisandro Dalcin if (minv >= maxv) maxv = minv + PETSC_SMALL; 16019566063dSJacob Faibussowitsch PetscCall(PetscDrawGetPopup(draw, &popup)); 16029566063dSJacob Faibussowitsch PetscCall(PetscDrawScalePopup(popup, minv, maxv)); 1603383922c3SLisandro Dalcin 1604d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 1605f1af5d2fSBarry Smith for (j = 0; j < n; j++) { 1606f1af5d2fSBarry Smith x_l = j; 1607f1af5d2fSBarry Smith x_r = x_l + 1.0; 1608f1af5d2fSBarry Smith for (i = 0; i < m; i++) { 1609f1af5d2fSBarry Smith y_l = m - i - 1.0; 1610f1af5d2fSBarry Smith y_r = y_l + 1.0; 1611b05fc000SLisandro Dalcin color = PetscDrawRealToColor(PetscAbsScalar(v[j * m + i]), minv, maxv); 16129566063dSJacob Faibussowitsch PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color)); 1613f1af5d2fSBarry Smith } 1614f1af5d2fSBarry Smith } 1615d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 1616f1af5d2fSBarry Smith } 16179566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 16183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1619f1af5d2fSBarry Smith } 1620f1af5d2fSBarry Smith 1621d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw(Mat A, PetscViewer viewer) 1622d71ae5a4SJacob Faibussowitsch { 1623b0a32e0cSBarry Smith PetscDraw draw; 1624ace3abfcSBarry Smith PetscBool isnull; 1625329f5518SBarry Smith PetscReal xr, yr, xl, yl, h, w; 1626f1af5d2fSBarry Smith 1627f1af5d2fSBarry Smith PetscFunctionBegin; 16289566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 16299566063dSJacob Faibussowitsch PetscCall(PetscDrawIsNull(draw, &isnull)); 16303ba16761SJacob Faibussowitsch if (isnull) PetscFunctionReturn(PETSC_SUCCESS); 1631f1af5d2fSBarry Smith 16329371c9d4SSatish Balay xr = A->cmap->n; 16339371c9d4SSatish Balay yr = A->rmap->n; 16349371c9d4SSatish Balay h = yr / 10.0; 16359371c9d4SSatish Balay w = xr / 10.0; 16369371c9d4SSatish Balay xr += w; 16379371c9d4SSatish Balay yr += h; 16389371c9d4SSatish Balay xl = -w; 16399371c9d4SSatish Balay yl = -h; 16409566063dSJacob Faibussowitsch PetscCall(PetscDrawSetCoordinates(draw, xl, yl, xr, yr)); 16419566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", (PetscObject)viewer)); 16429566063dSJacob Faibussowitsch PetscCall(PetscDrawZoom(draw, MatView_SeqDense_Draw_Zoom, A)); 16439566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", NULL)); 16449566063dSJacob Faibussowitsch PetscCall(PetscDrawSave(draw)); 16453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1646f1af5d2fSBarry Smith } 1647f1af5d2fSBarry Smith 1648d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_SeqDense(Mat A, PetscViewer viewer) 1649d71ae5a4SJacob Faibussowitsch { 1650ace3abfcSBarry Smith PetscBool iascii, isbinary, isdraw; 1651932b0c3eSLois Curfman McInnes 16523a40ed3dSBarry Smith PetscFunctionBegin; 16539566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 16549566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 16559566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 16561baa6e33SBarry Smith if (iascii) PetscCall(MatView_SeqDense_ASCII(A, viewer)); 16571baa6e33SBarry Smith else if (isbinary) PetscCall(MatView_Dense_Binary(A, viewer)); 16581baa6e33SBarry Smith else if (isdraw) PetscCall(MatView_SeqDense_Draw(A, viewer)); 16593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1660932b0c3eSLois Curfman McInnes } 1661289bc588SBarry Smith 1662d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A, const PetscScalar *array) 1663d71ae5a4SJacob Faibussowitsch { 1664d3042a70SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1665d3042a70SBarry Smith 1666d3042a70SBarry Smith PetscFunctionBegin; 166728b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 166828b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 16696635c364SPierre Jolivet PetscCheck(!a->unplacedarray, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseResetArray() first"); 1670d3042a70SBarry Smith a->unplacedarray = a->v; 1671d3042a70SBarry Smith a->unplaced_user_alloc = a->user_alloc; 1672d3042a70SBarry Smith a->v = (PetscScalar *)array; 1673637a0070SStefano Zampini a->user_alloc = PETSC_TRUE; 167447d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1675c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_CPU; 1676ca15aa20SStefano Zampini #endif 16773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1678d3042a70SBarry Smith } 1679d3042a70SBarry Smith 1680d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseResetArray_SeqDense(Mat A) 1681d71ae5a4SJacob Faibussowitsch { 1682d3042a70SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1683d3042a70SBarry Smith 1684d3042a70SBarry Smith PetscFunctionBegin; 168528b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 168628b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 1687d3042a70SBarry Smith a->v = a->unplacedarray; 1688d3042a70SBarry Smith a->user_alloc = a->unplaced_user_alloc; 1689d3042a70SBarry Smith a->unplacedarray = NULL; 169047d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1691c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_CPU; 1692ca15aa20SStefano Zampini #endif 16933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1694d3042a70SBarry Smith } 1695d3042a70SBarry Smith 1696d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A, const PetscScalar *array) 1697d71ae5a4SJacob Faibussowitsch { 1698d5ea218eSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1699d5ea218eSStefano Zampini 1700d5ea218eSStefano Zampini PetscFunctionBegin; 170128b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 170228b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 17039566063dSJacob Faibussowitsch if (!a->user_alloc) PetscCall(PetscFree(a->v)); 1704d5ea218eSStefano Zampini a->v = (PetscScalar *)array; 1705d5ea218eSStefano Zampini a->user_alloc = PETSC_FALSE; 170647d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1707d5ea218eSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 1708d5ea218eSStefano Zampini #endif 17093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1710d5ea218eSStefano Zampini } 1711d5ea218eSStefano Zampini 1712d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDestroy_SeqDense(Mat mat) 1713d71ae5a4SJacob Faibussowitsch { 1714ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)mat->data; 171590f02eecSBarry Smith 17163a40ed3dSBarry Smith PetscFunctionBegin; 17173ba16761SJacob Faibussowitsch PetscCall(PetscLogObjectState((PetscObject)mat, "Rows %" PetscInt_FMT " Cols %" PetscInt_FMT, mat->rmap->n, mat->cmap->n)); 1718f4f49eeaSPierre Jolivet PetscCall(VecDestroy(&l->qrrhs)); 17199566063dSJacob Faibussowitsch PetscCall(PetscFree(l->tau)); 17209566063dSJacob Faibussowitsch PetscCall(PetscFree(l->pivots)); 17219566063dSJacob Faibussowitsch PetscCall(PetscFree(l->fwork)); 17229566063dSJacob Faibussowitsch if (!l->user_alloc) PetscCall(PetscFree(l->v)); 17239566063dSJacob Faibussowitsch if (!l->unplaced_user_alloc) PetscCall(PetscFree(l->unplacedarray)); 172428b400f6SJacob Faibussowitsch PetscCheck(!l->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 172528b400f6SJacob Faibussowitsch PetscCheck(!l->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 17269566063dSJacob Faibussowitsch PetscCall(VecDestroy(&l->cvec)); 17279566063dSJacob Faibussowitsch PetscCall(MatDestroy(&l->cmat)); 17289566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->data)); 1729dbd8c25aSHong Zhang 17309566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)mat, NULL)); 17319566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactor_C", NULL)); 17322e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorSymbolic_C", NULL)); 17332e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorNumeric_C", NULL)); 17349566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetLDA_C", NULL)); 17359566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseSetLDA_C", NULL)); 17369566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArray_C", NULL)); 17379566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArray_C", NULL)); 17389566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDensePlaceArray_C", NULL)); 17399566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseResetArray_C", NULL)); 17409566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseReplaceArray_C", NULL)); 17419566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayRead_C", NULL)); 17429566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayRead_C", NULL)); 17439566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayWrite_C", NULL)); 17449566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayWrite_C", NULL)); 17459566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqaij_C", NULL)); 17468baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 17479566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_elemental_C", NULL)); 17488baccfbdSHong Zhang #endif 1749d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 17509566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_scalapack_C", NULL)); 1751d24d4204SJose E. Roman #endif 17522bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA) 17539566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensecuda_C", NULL)); 17549566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", NULL)); 17559566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdense_C", NULL)); 17562e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensecuda_C", NULL)); 17572bf066beSStefano Zampini #endif 175847d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 175947d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensehip_C", NULL)); 176047d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensehip_seqdensehip_C", NULL)); 176147d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensehip_seqdense_C", NULL)); 176247d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensehip_C", NULL)); 176347d993e7Ssuyashtn #endif 17649566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatSeqDenseSetPreallocation_C", NULL)); 17659566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqaij_seqdense_C", NULL)); 17669566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdense_C", NULL)); 17679566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqbaij_seqdense_C", NULL)); 17689566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqsbaij_seqdense_C", NULL)); 176952c5f739Sprj- 17709566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumn_C", NULL)); 17719566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumn_C", NULL)); 17729566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVec_C", NULL)); 17739566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVec_C", NULL)); 17749566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecRead_C", NULL)); 17759566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecRead_C", NULL)); 17769566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecWrite_C", NULL)); 17779566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecWrite_C", NULL)); 17789566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetSubMatrix_C", NULL)); 17799566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreSubMatrix_C", NULL)); 17800be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatMultAddColumnRange_C", NULL)); 17810be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatMultHermitianTransposeColumnRange_C", NULL)); 17820be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatMultHermitianTransposeAddColumnRange_C", NULL)); 17833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1784289bc588SBarry Smith } 1785289bc588SBarry Smith 1786d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatTranspose_SeqDense(Mat A, MatReuse reuse, Mat *matout) 1787d71ae5a4SJacob Faibussowitsch { 1788c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 17896536e3caSStefano Zampini PetscInt k, j, m = A->rmap->n, M = mat->lda, n = A->cmap->n; 179087828ca2SBarry Smith PetscScalar *v, tmp; 179148b35521SBarry Smith 17923a40ed3dSBarry Smith PetscFunctionBegin; 17937fb60732SBarry Smith if (reuse == MAT_REUSE_MATRIX) PetscCall(MatTransposeCheckNonzeroState_Private(A, *matout)); 17946536e3caSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 17956536e3caSStefano Zampini if (m == n) { /* in place transpose */ 17969566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 1797d3e5ee88SLois Curfman McInnes for (j = 0; j < m; j++) { 1798289bc588SBarry Smith for (k = 0; k < j; k++) { 17991b807ce4Svictorle tmp = v[j + k * M]; 18001b807ce4Svictorle v[j + k * M] = v[k + j * M]; 18011b807ce4Svictorle v[k + j * M] = tmp; 1802289bc588SBarry Smith } 1803289bc588SBarry Smith } 18049566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 18056536e3caSStefano Zampini } else { /* reuse memory, temporary allocates new memory */ 18066536e3caSStefano Zampini PetscScalar *v2; 18076536e3caSStefano Zampini PetscLayout tmplayout; 18086536e3caSStefano Zampini 18099566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((size_t)m * n, &v2)); 18109566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 18116536e3caSStefano Zampini for (j = 0; j < n; j++) { 18126536e3caSStefano Zampini for (k = 0; k < m; k++) v2[j + (size_t)k * n] = v[k + (size_t)j * M]; 18136536e3caSStefano Zampini } 18149566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(v, v2, (size_t)m * n)); 18159566063dSJacob Faibussowitsch PetscCall(PetscFree(v2)); 18169566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 18176536e3caSStefano Zampini /* cleanup size dependent quantities */ 18189566063dSJacob Faibussowitsch PetscCall(VecDestroy(&mat->cvec)); 18199566063dSJacob Faibussowitsch PetscCall(MatDestroy(&mat->cmat)); 18209566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->pivots)); 18219566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->fwork)); 18226536e3caSStefano Zampini /* swap row/col layouts */ 18236497c311SBarry Smith PetscCall(PetscBLASIntCast(n, &mat->lda)); 18246536e3caSStefano Zampini tmplayout = A->rmap; 18256536e3caSStefano Zampini A->rmap = A->cmap; 18266536e3caSStefano Zampini A->cmap = tmplayout; 18276536e3caSStefano Zampini } 18283a40ed3dSBarry Smith } else { /* out-of-place transpose */ 1829d3e5ee88SLois Curfman McInnes Mat tmat; 1830ec8511deSBarry Smith Mat_SeqDense *tmatd; 183187828ca2SBarry Smith PetscScalar *v2; 1832af36a384SStefano Zampini PetscInt M2; 1833ea709b57SSatish Balay 18346536e3caSStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 18359566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &tmat)); 18369566063dSJacob Faibussowitsch PetscCall(MatSetSizes(tmat, A->cmap->n, A->rmap->n, A->cmap->n, A->rmap->n)); 18379566063dSJacob Faibussowitsch PetscCall(MatSetType(tmat, ((PetscObject)A)->type_name)); 18389566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(tmat, NULL)); 1839ca15aa20SStefano Zampini } else tmat = *matout; 1840ca15aa20SStefano Zampini 18419566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&v)); 18429566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(tmat, &v2)); 1843ec8511deSBarry Smith tmatd = (Mat_SeqDense *)tmat->data; 1844ca15aa20SStefano Zampini M2 = tmatd->lda; 1845d3e5ee88SLois Curfman McInnes for (j = 0; j < n; j++) { 1846af36a384SStefano Zampini for (k = 0; k < m; k++) v2[j + k * M2] = v[k + j * M]; 1847d3e5ee88SLois Curfman McInnes } 18489566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(tmat, &v2)); 18499566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&v)); 18509566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(tmat, MAT_FINAL_ASSEMBLY)); 18519566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(tmat, MAT_FINAL_ASSEMBLY)); 18526536e3caSStefano Zampini *matout = tmat; 185348b35521SBarry Smith } 18543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1855289bc588SBarry Smith } 1856289bc588SBarry Smith 1857d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatEqual_SeqDense(Mat A1, Mat A2, PetscBool *flg) 1858d71ae5a4SJacob Faibussowitsch { 1859c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat1 = (Mat_SeqDense *)A1->data; 1860c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat2 = (Mat_SeqDense *)A2->data; 1861ca15aa20SStefano Zampini PetscInt i; 1862ca15aa20SStefano Zampini const PetscScalar *v1, *v2; 18639ea5d5aeSSatish Balay 18643a40ed3dSBarry Smith PetscFunctionBegin; 18659371c9d4SSatish Balay if (A1->rmap->n != A2->rmap->n) { 18669371c9d4SSatish Balay *flg = PETSC_FALSE; 18673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18689371c9d4SSatish Balay } 18699371c9d4SSatish Balay if (A1->cmap->n != A2->cmap->n) { 18709371c9d4SSatish Balay *flg = PETSC_FALSE; 18713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18729371c9d4SSatish Balay } 18739566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A1, &v1)); 18749566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A2, &v2)); 1875ca15aa20SStefano Zampini for (i = 0; i < A1->cmap->n; i++) { 18769566063dSJacob Faibussowitsch PetscCall(PetscArraycmp(v1, v2, A1->rmap->n, flg)); 18773ba16761SJacob Faibussowitsch if (*flg == PETSC_FALSE) PetscFunctionReturn(PETSC_SUCCESS); 1878ca15aa20SStefano Zampini v1 += mat1->lda; 1879ca15aa20SStefano Zampini v2 += mat2->lda; 18801b807ce4Svictorle } 18819566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A1, &v1)); 18829566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A2, &v2)); 188377c4ece6SBarry Smith *flg = PETSC_TRUE; 18843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1885289bc588SBarry Smith } 1886289bc588SBarry Smith 188714277c92SJacob Faibussowitsch PetscErrorCode MatGetDiagonal_SeqDense(Mat A, Vec v) 1888d71ae5a4SJacob Faibussowitsch { 1889c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 189013f74950SBarry Smith PetscInt i, n, len; 1891ca15aa20SStefano Zampini PetscScalar *x; 1892ca15aa20SStefano Zampini const PetscScalar *vv; 189344cd7ae7SLois Curfman McInnes 18943a40ed3dSBarry Smith PetscFunctionBegin; 18959566063dSJacob Faibussowitsch PetscCall(VecGetSize(v, &n)); 18969566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 1897d0f46423SBarry Smith len = PetscMin(A->rmap->n, A->cmap->n); 18989566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &vv)); 189908401ef6SPierre Jolivet PetscCheck(n == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming mat and vec"); 1900ad540459SPierre Jolivet for (i = 0; i < len; i++) x[i] = vv[i * mat->lda + i]; 19019566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &vv)); 19029566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 19033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1904289bc588SBarry Smith } 1905289bc588SBarry Smith 1906d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDiagonalScale_SeqDense(Mat A, Vec ll, Vec rr) 1907d71ae5a4SJacob Faibussowitsch { 1908c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1909f1ceaac6SMatthew G. Knepley const PetscScalar *l, *r; 1910ca15aa20SStefano Zampini PetscScalar x, *v, *vv; 1911d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n; 191255659b69SBarry Smith 19133a40ed3dSBarry Smith PetscFunctionBegin; 19149566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &vv)); 191528988994SBarry Smith if (ll) { 19169566063dSJacob Faibussowitsch PetscCall(VecGetSize(ll, &m)); 19179566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(ll, &l)); 191808401ef6SPierre Jolivet PetscCheck(m == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Left scaling vec wrong size"); 1919da3a660dSBarry Smith for (i = 0; i < m; i++) { 1920da3a660dSBarry Smith x = l[i]; 1921ca15aa20SStefano Zampini v = vv + i; 19229371c9d4SSatish Balay for (j = 0; j < n; j++) { 19239371c9d4SSatish Balay (*v) *= x; 19249371c9d4SSatish Balay v += mat->lda; 19259371c9d4SSatish Balay } 1926da3a660dSBarry Smith } 19279566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(ll, &l)); 19289566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * n * m)); 1929da3a660dSBarry Smith } 193028988994SBarry Smith if (rr) { 19319566063dSJacob Faibussowitsch PetscCall(VecGetSize(rr, &n)); 19329566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(rr, &r)); 193308401ef6SPierre Jolivet PetscCheck(n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Right scaling vec wrong size"); 1934da3a660dSBarry Smith for (i = 0; i < n; i++) { 1935da3a660dSBarry Smith x = r[i]; 1936ca15aa20SStefano Zampini v = vv + i * mat->lda; 19372205254eSKarl Rupp for (j = 0; j < m; j++) (*v++) *= x; 1938da3a660dSBarry Smith } 19399566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(rr, &r)); 19409566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * n * m)); 1941da3a660dSBarry Smith } 19429566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &vv)); 19433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1944289bc588SBarry Smith } 1945289bc588SBarry Smith 1946d71ae5a4SJacob Faibussowitsch PetscErrorCode MatNorm_SeqDense(Mat A, NormType type, PetscReal *nrm) 1947d71ae5a4SJacob Faibussowitsch { 1948c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1949ca15aa20SStefano Zampini PetscScalar *v, *vv; 1950329f5518SBarry Smith PetscReal sum = 0.0; 195175f6d85dSStefano Zampini PetscInt lda, m = A->rmap->n, i, j; 195255659b69SBarry Smith 19533a40ed3dSBarry Smith PetscFunctionBegin; 19549566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&vv)); 19559566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(A, &lda)); 1956ca15aa20SStefano Zampini v = vv; 1957289bc588SBarry Smith if (type == NORM_FROBENIUS) { 1958a5ce6ee0Svictorle if (lda > m) { 1959d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1960ca15aa20SStefano Zampini v = vv + j * lda; 1961a5ce6ee0Svictorle for (i = 0; i < m; i++) { 19629371c9d4SSatish Balay sum += PetscRealPart(PetscConj(*v) * (*v)); 19639371c9d4SSatish Balay v++; 1964a5ce6ee0Svictorle } 1965a5ce6ee0Svictorle } 1966a5ce6ee0Svictorle } else { 1967570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16) 1968570b7f6dSBarry Smith PetscBLASInt one = 1, cnt = A->cmap->n * A->rmap->n; 1969792fecdfSBarry Smith PetscCallBLAS("BLASnrm2", *nrm = BLASnrm2_(&cnt, v, &one)); 1970570b7f6dSBarry Smith } 1971570b7f6dSBarry Smith #else 1972d0f46423SBarry Smith for (i = 0; i < A->cmap->n * A->rmap->n; i++) { 19739371c9d4SSatish Balay sum += PetscRealPart(PetscConj(*v) * (*v)); 19749371c9d4SSatish Balay v++; 1975289bc588SBarry Smith } 1976a5ce6ee0Svictorle } 19778f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 1978570b7f6dSBarry Smith #endif 19799566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->cmap->n * A->rmap->n)); 19803a40ed3dSBarry Smith } else if (type == NORM_1) { 1981064f8208SBarry Smith *nrm = 0.0; 1982d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1983ca15aa20SStefano Zampini v = vv + j * mat->lda; 1984289bc588SBarry Smith sum = 0.0; 1985d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 19869371c9d4SSatish Balay sum += PetscAbsScalar(*v); 19879371c9d4SSatish Balay v++; 1988289bc588SBarry Smith } 1989064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 1990289bc588SBarry Smith } 19919566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n)); 19923a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 1993064f8208SBarry Smith *nrm = 0.0; 1994d0f46423SBarry Smith for (j = 0; j < A->rmap->n; j++) { 1995ca15aa20SStefano Zampini v = vv + j; 1996289bc588SBarry Smith sum = 0.0; 1997d0f46423SBarry Smith for (i = 0; i < A->cmap->n; i++) { 19989371c9d4SSatish Balay sum += PetscAbsScalar(*v); 19999371c9d4SSatish Balay v += mat->lda; 2000289bc588SBarry Smith } 2001064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 2002289bc588SBarry Smith } 20039566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n)); 2004e7e72b3dSBarry Smith } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "No two norm"); 20059566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&vv)); 20063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2007289bc588SBarry Smith } 2008289bc588SBarry Smith 2009d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetOption_SeqDense(Mat A, MatOption op, PetscBool flg) 2010d71ae5a4SJacob Faibussowitsch { 2011c0bbcb79SLois Curfman McInnes Mat_SeqDense *aij = (Mat_SeqDense *)A->data; 201267e560aaSBarry Smith 20133a40ed3dSBarry Smith PetscFunctionBegin; 2014b5a2b587SKris Buschelman switch (op) { 2015d71ae5a4SJacob Faibussowitsch case MAT_ROW_ORIENTED: 2016d71ae5a4SJacob Faibussowitsch aij->roworiented = flg; 2017d71ae5a4SJacob Faibussowitsch break; 2018d71ae5a4SJacob Faibussowitsch default: 2019888c827cSStefano Zampini break; 20203a40ed3dSBarry Smith } 20213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2022289bc588SBarry Smith } 2023289bc588SBarry Smith 2024d71ae5a4SJacob Faibussowitsch PetscErrorCode MatZeroEntries_SeqDense(Mat A) 2025d71ae5a4SJacob Faibussowitsch { 2026ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)A->data; 20273d8925e7SStefano Zampini PetscInt lda = l->lda, m = A->rmap->n, n = A->cmap->n, j; 2028ca15aa20SStefano Zampini PetscScalar *v; 20293a40ed3dSBarry Smith 20303a40ed3dSBarry Smith PetscFunctionBegin; 20319566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(A, &v)); 2032a5ce6ee0Svictorle if (lda > m) { 203348a46eb9SPierre Jolivet for (j = 0; j < n; j++) PetscCall(PetscArrayzero(v + j * lda, m)); 2034a5ce6ee0Svictorle } else { 20359566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(v, PetscInt64Mult(m, n))); 2036a5ce6ee0Svictorle } 20379566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(A, &v)); 20383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 20396f0a148fSBarry Smith } 20406f0a148fSBarry Smith 2041d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatZeroRows_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) 2042d71ae5a4SJacob Faibussowitsch { 2043ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)A->data; 2044b9679d65SBarry Smith PetscInt m = l->lda, n = A->cmap->n, i, j; 2045ca15aa20SStefano Zampini PetscScalar *slot, *bb, *v; 204697b48c8fSBarry Smith const PetscScalar *xx; 204755659b69SBarry Smith 20483a40ed3dSBarry Smith PetscFunctionBegin; 204976bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 2050b9679d65SBarry Smith for (i = 0; i < N; i++) { 205108401ef6SPierre Jolivet PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed"); 205208401ef6SPierre 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); 2053b9679d65SBarry Smith } 205476bd3646SJed Brown } 20553ba16761SJacob Faibussowitsch if (!N) PetscFunctionReturn(PETSC_SUCCESS); 2056b9679d65SBarry Smith 2057dd8e379bSPierre Jolivet /* fix right-hand side if needed */ 205897b48c8fSBarry Smith if (x && b) { 20599566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 20609566063dSJacob Faibussowitsch PetscCall(VecGetArray(b, &bb)); 20612205254eSKarl Rupp for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]]; 20629566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 20639566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(b, &bb)); 206497b48c8fSBarry Smith } 206597b48c8fSBarry Smith 20669566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 20676f0a148fSBarry Smith for (i = 0; i < N; i++) { 2068ca15aa20SStefano Zampini slot = v + rows[i]; 20699371c9d4SSatish Balay for (j = 0; j < n; j++) { 20709371c9d4SSatish Balay *slot = 0.0; 20719371c9d4SSatish Balay slot += m; 20729371c9d4SSatish Balay } 20736f0a148fSBarry Smith } 2074f4df32b1SMatthew Knepley if (diag != 0.0) { 207508401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices"); 20766f0a148fSBarry Smith for (i = 0; i < N; i++) { 2077ca15aa20SStefano Zampini slot = v + (m + 1) * rows[i]; 2078f4df32b1SMatthew Knepley *slot = diag; 20796f0a148fSBarry Smith } 20806f0a148fSBarry Smith } 20819566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 20823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 20836f0a148fSBarry Smith } 2084557bce09SLois Curfman McInnes 2085d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A, PetscInt *lda) 2086d71ae5a4SJacob Faibussowitsch { 208749a6ff4bSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 208849a6ff4bSBarry Smith 208949a6ff4bSBarry Smith PetscFunctionBegin; 209049a6ff4bSBarry Smith *lda = mat->lda; 20913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 209249a6ff4bSBarry Smith } 209349a6ff4bSBarry Smith 2094d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArray_SeqDense(Mat A, PetscScalar **array) 2095d71ae5a4SJacob Faibussowitsch { 2096c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 20973a40ed3dSBarry Smith 20983a40ed3dSBarry Smith PetscFunctionBegin; 209928b400f6SJacob Faibussowitsch PetscCheck(!mat->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 210064e87e97SBarry Smith *array = mat->v; 21013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 210264e87e97SBarry Smith } 21030754003eSLois Curfman McInnes 2104d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A, PetscScalar **array) 2105d71ae5a4SJacob Faibussowitsch { 21063a40ed3dSBarry Smith PetscFunctionBegin; 210775f6d85dSStefano Zampini if (array) *array = NULL; 21083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2109ff14e315SSatish Balay } 21100754003eSLois Curfman McInnes 21110f74d2c1SSatish Balay /*@ 211211a5261eSBarry Smith MatDenseGetLDA - gets the leading dimension of the array returned from `MatDenseGetArray()` 211349a6ff4bSBarry Smith 21142ef1f0ffSBarry Smith Not Collective 211549a6ff4bSBarry Smith 211649a6ff4bSBarry Smith Input Parameter: 2117fe59aa6dSJacob Faibussowitsch . A - a `MATDENSE` or `MATDENSECUDA` matrix 211849a6ff4bSBarry Smith 211949a6ff4bSBarry Smith Output Parameter: 212049a6ff4bSBarry Smith . lda - the leading dimension 212149a6ff4bSBarry Smith 212249a6ff4bSBarry Smith Level: intermediate 212349a6ff4bSBarry Smith 21241cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseSetLDA()` 212549a6ff4bSBarry Smith @*/ 2126d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetLDA(Mat A, PetscInt *lda) 2127d71ae5a4SJacob Faibussowitsch { 212849a6ff4bSBarry Smith PetscFunctionBegin; 2129d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 21304f572ea9SToby Isaac PetscAssertPointer(lda, 2); 213175f6d85dSStefano Zampini MatCheckPreallocated(A, 1); 2132cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetLDA_C", (Mat, PetscInt *), (A, lda)); 21333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 213449a6ff4bSBarry Smith } 213549a6ff4bSBarry Smith 21360f74d2c1SSatish Balay /*@ 213711a5261eSBarry Smith MatDenseSetLDA - Sets the leading dimension of the array used by the `MATDENSE` matrix 2138ad16ce7aSStefano Zampini 21392323109cSBarry Smith Collective if the matrix layouts have not yet been setup 2140ad16ce7aSStefano Zampini 2141d8d19677SJose E. Roman Input Parameters: 2142fe59aa6dSJacob Faibussowitsch + A - a `MATDENSE` or `MATDENSECUDA` matrix 2143ad16ce7aSStefano Zampini - lda - the leading dimension 2144ad16ce7aSStefano Zampini 2145ad16ce7aSStefano Zampini Level: intermediate 2146ad16ce7aSStefano Zampini 21471cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetLDA()` 2148ad16ce7aSStefano Zampini @*/ 2149d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA(Mat A, PetscInt lda) 2150d71ae5a4SJacob Faibussowitsch { 2151ad16ce7aSStefano Zampini PetscFunctionBegin; 2152ad16ce7aSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2153cac4c232SBarry Smith PetscTryMethod(A, "MatDenseSetLDA_C", (Mat, PetscInt), (A, lda)); 21543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2155ad16ce7aSStefano Zampini } 2156ad16ce7aSStefano Zampini 2157ad16ce7aSStefano Zampini /*@C 215811a5261eSBarry Smith MatDenseGetArray - gives read-write access to the array where the data for a `MATDENSE` matrix is stored 215973a71a0fSBarry Smith 2160c3339decSBarry Smith Logically Collective 216173a71a0fSBarry Smith 216273a71a0fSBarry Smith Input Parameter: 2163fe59aa6dSJacob Faibussowitsch . A - a dense matrix 216473a71a0fSBarry Smith 216573a71a0fSBarry Smith Output Parameter: 216673a71a0fSBarry Smith . array - pointer to the data 216773a71a0fSBarry Smith 216873a71a0fSBarry Smith Level: intermediate 216973a71a0fSBarry Smith 21701cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 217173a71a0fSBarry Smith @*/ 2172ce78bad3SBarry Smith PetscErrorCode MatDenseGetArray(Mat A, PetscScalar *array[]) PeNS 2173d71ae5a4SJacob Faibussowitsch { 217473a71a0fSBarry Smith PetscFunctionBegin; 2175d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 21764f572ea9SToby Isaac PetscAssertPointer(array, 2); 2177cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array)); 21783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 217973a71a0fSBarry Smith } 218073a71a0fSBarry Smith 2181dec5eb66SMatthew G Knepley /*@C 218211a5261eSBarry Smith MatDenseRestoreArray - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArray()` 218373a71a0fSBarry Smith 2184c3339decSBarry Smith Logically Collective 21858572280aSBarry Smith 21868572280aSBarry Smith Input Parameters: 2187fe59aa6dSJacob Faibussowitsch + A - a dense matrix 21882ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`) 21898572280aSBarry Smith 21908572280aSBarry Smith Level: intermediate 21918572280aSBarry Smith 21921cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 21938572280aSBarry Smith @*/ 2194ce78bad3SBarry Smith PetscErrorCode MatDenseRestoreArray(Mat A, PetscScalar *array[]) PeNS 2195d71ae5a4SJacob Faibussowitsch { 21968572280aSBarry Smith PetscFunctionBegin; 2197d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 21984f572ea9SToby Isaac if (array) PetscAssertPointer(array, 2); 2199cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array)); 22009566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)A)); 220147d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 2202637a0070SStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 2203637a0070SStefano Zampini #endif 22043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22058572280aSBarry Smith } 22068572280aSBarry Smith 22078572280aSBarry Smith /*@C 220811a5261eSBarry Smith MatDenseGetArrayRead - gives read-only access to the array where the data for a `MATDENSE` matrix is stored 22098572280aSBarry Smith 2210fb850c59SBarry Smith Not Collective 22118572280aSBarry Smith 22128572280aSBarry Smith Input Parameter: 2213fe59aa6dSJacob Faibussowitsch . A - a dense matrix 22148572280aSBarry Smith 22158572280aSBarry Smith Output Parameter: 22168572280aSBarry Smith . array - pointer to the data 22178572280aSBarry Smith 22188572280aSBarry Smith Level: intermediate 22198572280aSBarry Smith 22201cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 22218572280aSBarry Smith @*/ 2222ce78bad3SBarry Smith PetscErrorCode MatDenseGetArrayRead(Mat A, const PetscScalar *array[]) PeNS 2223d71ae5a4SJacob Faibussowitsch { 22248572280aSBarry Smith PetscFunctionBegin; 2225d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22264f572ea9SToby Isaac PetscAssertPointer(array, 2); 22275c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 22283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22298572280aSBarry Smith } 22308572280aSBarry Smith 22318572280aSBarry Smith /*@C 223211a5261eSBarry Smith MatDenseRestoreArrayRead - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayRead()` 22338572280aSBarry Smith 2234fb850c59SBarry Smith Not Collective 223573a71a0fSBarry Smith 223673a71a0fSBarry Smith Input Parameters: 2237fe59aa6dSJacob Faibussowitsch + A - a dense matrix 22382ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`) 223973a71a0fSBarry Smith 224073a71a0fSBarry Smith Level: intermediate 224173a71a0fSBarry Smith 22421cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 224373a71a0fSBarry Smith @*/ 2244ce78bad3SBarry Smith PetscErrorCode MatDenseRestoreArrayRead(Mat A, const PetscScalar *array[]) PeNS 2245d71ae5a4SJacob Faibussowitsch { 224673a71a0fSBarry Smith PetscFunctionBegin; 2247d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22484f572ea9SToby Isaac if (array) PetscAssertPointer(array, 2); 22495c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 22503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 225173a71a0fSBarry Smith } 225273a71a0fSBarry Smith 22536947451fSStefano Zampini /*@C 225411a5261eSBarry Smith MatDenseGetArrayWrite - gives write-only access to the array where the data for a `MATDENSE` matrix is stored 22556947451fSStefano Zampini 2256fb850c59SBarry Smith Not Collective 22576947451fSStefano Zampini 22586947451fSStefano Zampini Input Parameter: 2259fe59aa6dSJacob Faibussowitsch . A - a dense matrix 22606947451fSStefano Zampini 22616947451fSStefano Zampini Output Parameter: 22626947451fSStefano Zampini . array - pointer to the data 22636947451fSStefano Zampini 22646947451fSStefano Zampini Level: intermediate 22656947451fSStefano Zampini 22661cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()` 22676947451fSStefano Zampini @*/ 2268ce78bad3SBarry Smith PetscErrorCode MatDenseGetArrayWrite(Mat A, PetscScalar *array[]) PeNS 2269d71ae5a4SJacob Faibussowitsch { 22706947451fSStefano Zampini PetscFunctionBegin; 2271d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22724f572ea9SToby Isaac PetscAssertPointer(array, 2); 2273cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array)); 22743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22756947451fSStefano Zampini } 22766947451fSStefano Zampini 22776947451fSStefano Zampini /*@C 227811a5261eSBarry Smith MatDenseRestoreArrayWrite - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayWrite()` 22796947451fSStefano Zampini 2280fb850c59SBarry Smith Not Collective 22816947451fSStefano Zampini 22826947451fSStefano Zampini Input Parameters: 2283fe59aa6dSJacob Faibussowitsch + A - a dense matrix 22842ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`) 22856947451fSStefano Zampini 22866947451fSStefano Zampini Level: intermediate 22876947451fSStefano Zampini 22881cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()` 22896947451fSStefano Zampini @*/ 2290ce78bad3SBarry Smith PetscErrorCode MatDenseRestoreArrayWrite(Mat A, PetscScalar *array[]) PeNS 2291d71ae5a4SJacob Faibussowitsch { 22926947451fSStefano Zampini PetscFunctionBegin; 2293d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22944f572ea9SToby Isaac if (array) PetscAssertPointer(array, 2); 2295cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array)); 22969566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)A)); 229747d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 22986947451fSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 22996947451fSStefano Zampini #endif 23003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23016947451fSStefano Zampini } 23026947451fSStefano Zampini 2303cd3f9d89SJunchao Zhang /*@C 2304cd3f9d89SJunchao Zhang MatDenseGetArrayAndMemType - gives read-write access to the array where the data for a `MATDENSE` matrix is stored 2305cd3f9d89SJunchao Zhang 2306cd3f9d89SJunchao Zhang Logically Collective 2307cd3f9d89SJunchao Zhang 2308cd3f9d89SJunchao Zhang Input Parameter: 2309fe59aa6dSJacob Faibussowitsch . A - a dense matrix 2310cd3f9d89SJunchao Zhang 2311cd3f9d89SJunchao Zhang Output Parameters: 2312cd3f9d89SJunchao Zhang + array - pointer to the data 2313cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer 2314cd3f9d89SJunchao Zhang 2315cd3f9d89SJunchao Zhang Level: intermediate 2316cd3f9d89SJunchao Zhang 2317fb850c59SBarry Smith Note: 23182ef1f0ffSBarry Smith If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc., 23192ef1f0ffSBarry Smith an array on device is always returned and is guaranteed to contain the matrix's latest data. 23202ef1f0ffSBarry Smith 23211cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayAndMemType()`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArrayWriteAndMemType()`, `MatDenseGetArrayRead()`, 2322cd3f9d89SJunchao Zhang `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()` 2323cd3f9d89SJunchao Zhang @*/ 23245d83a8b1SBarry Smith PetscErrorCode MatDenseGetArrayAndMemType(Mat A, PetscScalar *array[], PetscMemType *mtype) 2325cd3f9d89SJunchao Zhang { 2326cd3f9d89SJunchao Zhang PetscBool isMPI; 2327cd3f9d89SJunchao Zhang 2328cd3f9d89SJunchao Zhang PetscFunctionBegin; 2329cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 23304f572ea9SToby Isaac PetscAssertPointer(array, 2); 2331e865de01SJunchao 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 */ 2332cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2333cd3f9d89SJunchao Zhang if (isMPI) { 2334cd3f9d89SJunchao Zhang /* Dispatch here so that the code can be reused for all subclasses of MATDENSE */ 2335cd3f9d89SJunchao Zhang PetscCall(MatDenseGetArrayAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype)); 2336cd3f9d89SJunchao Zhang } else { 2337cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **, PetscMemType *); 23383ba16761SJacob Faibussowitsch 23393ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayAndMemType_C", &fptr)); 2340cd3f9d89SJunchao Zhang if (fptr) { 2341cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array, mtype)); 2342cd3f9d89SJunchao Zhang } else { 2343cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array)); 2344cd3f9d89SJunchao Zhang if (mtype) *mtype = PETSC_MEMTYPE_HOST; 2345cd3f9d89SJunchao Zhang } 2346cd3f9d89SJunchao Zhang } 23473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2348cd3f9d89SJunchao Zhang } 2349cd3f9d89SJunchao Zhang 2350cd3f9d89SJunchao Zhang /*@C 2351cd3f9d89SJunchao Zhang MatDenseRestoreArrayAndMemType - returns access to the array that is obtained by `MatDenseGetArrayAndMemType()` 2352cd3f9d89SJunchao Zhang 2353cd3f9d89SJunchao Zhang Logically Collective 2354cd3f9d89SJunchao Zhang 2355cd3f9d89SJunchao Zhang Input Parameters: 2356fe59aa6dSJacob Faibussowitsch + A - a dense matrix 2357cd3f9d89SJunchao Zhang - array - pointer to the data 2358cd3f9d89SJunchao Zhang 2359cd3f9d89SJunchao Zhang Level: intermediate 2360cd3f9d89SJunchao Zhang 23611cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 2362cd3f9d89SJunchao Zhang @*/ 23635d83a8b1SBarry Smith PetscErrorCode MatDenseRestoreArrayAndMemType(Mat A, PetscScalar *array[]) 2364cd3f9d89SJunchao Zhang { 2365cd3f9d89SJunchao Zhang PetscBool isMPI; 2366cd3f9d89SJunchao Zhang 2367cd3f9d89SJunchao Zhang PetscFunctionBegin; 2368cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 23694f572ea9SToby Isaac PetscAssertPointer(array, 2); 2370cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2371cd3f9d89SJunchao Zhang if (isMPI) { 2372cd3f9d89SJunchao Zhang PetscCall(MatDenseRestoreArrayAndMemType(((Mat_MPIDense *)A->data)->A, array)); 2373cd3f9d89SJunchao Zhang } else { 2374cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **); 23753ba16761SJacob Faibussowitsch 23763ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayAndMemType_C", &fptr)); 2377cd3f9d89SJunchao Zhang if (fptr) { 2378cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array)); 2379cd3f9d89SJunchao Zhang } else { 2380cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array)); 2381cd3f9d89SJunchao Zhang } 2382cd3f9d89SJunchao Zhang *array = NULL; 2383cd3f9d89SJunchao Zhang } 2384cd3f9d89SJunchao Zhang PetscCall(PetscObjectStateIncrease((PetscObject)A)); 23853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2386cd3f9d89SJunchao Zhang } 2387cd3f9d89SJunchao Zhang 2388cd3f9d89SJunchao Zhang /*@C 2389cd3f9d89SJunchao Zhang MatDenseGetArrayReadAndMemType - gives read-only access to the array where the data for a `MATDENSE` matrix is stored 2390cd3f9d89SJunchao Zhang 2391cd3f9d89SJunchao Zhang Logically Collective 2392cd3f9d89SJunchao Zhang 2393cd3f9d89SJunchao Zhang Input Parameter: 2394fe59aa6dSJacob Faibussowitsch . A - a dense matrix 2395cd3f9d89SJunchao Zhang 2396cd3f9d89SJunchao Zhang Output Parameters: 2397cd3f9d89SJunchao Zhang + array - pointer to the data 2398cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer 2399cd3f9d89SJunchao Zhang 2400cd3f9d89SJunchao Zhang Level: intermediate 2401cd3f9d89SJunchao Zhang 2402fb850c59SBarry Smith Note: 24032ef1f0ffSBarry Smith If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc., 24042ef1f0ffSBarry Smith an array on device is always returned and is guaranteed to contain the matrix's latest data. 24052ef1f0ffSBarry Smith 24061cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayReadAndMemType()`, `MatDenseGetArrayWriteAndMemType()`, 2407cd3f9d89SJunchao Zhang `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()` 2408cd3f9d89SJunchao Zhang @*/ 24095d83a8b1SBarry Smith PetscErrorCode MatDenseGetArrayReadAndMemType(Mat A, const PetscScalar *array[], PetscMemType *mtype) 2410cd3f9d89SJunchao Zhang { 2411cd3f9d89SJunchao Zhang PetscBool isMPI; 2412cd3f9d89SJunchao Zhang 2413cd3f9d89SJunchao Zhang PetscFunctionBegin; 2414cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 24154f572ea9SToby Isaac PetscAssertPointer(array, 2); 2416e865de01SJunchao 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 */ 2417cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2418cd3f9d89SJunchao Zhang if (isMPI) { /* Dispatch here so that the code can be reused for all subclasses of MATDENSE */ 2419cd3f9d89SJunchao Zhang PetscCall(MatDenseGetArrayReadAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype)); 2420cd3f9d89SJunchao Zhang } else { 2421cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, const PetscScalar **, PetscMemType *); 24223ba16761SJacob Faibussowitsch 24233ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayReadAndMemType_C", &fptr)); 2424cd3f9d89SJunchao Zhang if (fptr) { 2425cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array, mtype)); 2426cd3f9d89SJunchao Zhang } else { 24275c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 2428cd3f9d89SJunchao Zhang if (mtype) *mtype = PETSC_MEMTYPE_HOST; 2429cd3f9d89SJunchao Zhang } 2430cd3f9d89SJunchao Zhang } 24313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2432cd3f9d89SJunchao Zhang } 2433cd3f9d89SJunchao Zhang 2434cd3f9d89SJunchao Zhang /*@C 2435cd3f9d89SJunchao Zhang MatDenseRestoreArrayReadAndMemType - returns access to the array that is obtained by `MatDenseGetArrayReadAndMemType()` 2436cd3f9d89SJunchao Zhang 2437cd3f9d89SJunchao Zhang Logically Collective 2438cd3f9d89SJunchao Zhang 2439cd3f9d89SJunchao Zhang Input Parameters: 2440fe59aa6dSJacob Faibussowitsch + A - a dense matrix 2441cd3f9d89SJunchao Zhang - array - pointer to the data 2442cd3f9d89SJunchao Zhang 2443cd3f9d89SJunchao Zhang Level: intermediate 2444cd3f9d89SJunchao Zhang 24451cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 2446cd3f9d89SJunchao Zhang @*/ 24475d83a8b1SBarry Smith PetscErrorCode MatDenseRestoreArrayReadAndMemType(Mat A, const PetscScalar *array[]) 2448cd3f9d89SJunchao Zhang { 2449cd3f9d89SJunchao Zhang PetscBool isMPI; 2450cd3f9d89SJunchao Zhang 2451cd3f9d89SJunchao Zhang PetscFunctionBegin; 2452cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 24534f572ea9SToby Isaac PetscAssertPointer(array, 2); 2454cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2455cd3f9d89SJunchao Zhang if (isMPI) { 2456cd3f9d89SJunchao Zhang PetscCall(MatDenseRestoreArrayReadAndMemType(((Mat_MPIDense *)A->data)->A, array)); 2457cd3f9d89SJunchao Zhang } else { 2458cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, const PetscScalar **); 24593ba16761SJacob Faibussowitsch 24603ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayReadAndMemType_C", &fptr)); 2461cd3f9d89SJunchao Zhang if (fptr) { 2462cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array)); 2463cd3f9d89SJunchao Zhang } else { 24645c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 2465cd3f9d89SJunchao Zhang } 2466cd3f9d89SJunchao Zhang *array = NULL; 2467cd3f9d89SJunchao Zhang } 24683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2469cd3f9d89SJunchao Zhang } 2470cd3f9d89SJunchao Zhang 2471cd3f9d89SJunchao Zhang /*@C 2472cd3f9d89SJunchao Zhang MatDenseGetArrayWriteAndMemType - gives write-only access to the array where the data for a `MATDENSE` matrix is stored 2473cd3f9d89SJunchao Zhang 2474cd3f9d89SJunchao Zhang Logically Collective 2475cd3f9d89SJunchao Zhang 2476cd3f9d89SJunchao Zhang Input Parameter: 2477fe59aa6dSJacob Faibussowitsch . A - a dense matrix 2478cd3f9d89SJunchao Zhang 2479cd3f9d89SJunchao Zhang Output Parameters: 2480cd3f9d89SJunchao Zhang + array - pointer to the data 2481cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer 2482cd3f9d89SJunchao Zhang 2483cd3f9d89SJunchao Zhang Level: intermediate 2484cd3f9d89SJunchao Zhang 2485fb850c59SBarry Smith Note: 24862ef1f0ffSBarry Smith If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc., 24872ef1f0ffSBarry Smith an array on device is always returned and is guaranteed to contain the matrix's latest data. 24882ef1f0ffSBarry Smith 24891cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayWriteAndMemType()`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArrayRead()`, 2490cd3f9d89SJunchao Zhang `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()` 2491cd3f9d89SJunchao Zhang @*/ 24925d83a8b1SBarry Smith PetscErrorCode MatDenseGetArrayWriteAndMemType(Mat A, PetscScalar *array[], PetscMemType *mtype) 2493cd3f9d89SJunchao Zhang { 2494cd3f9d89SJunchao Zhang PetscBool isMPI; 2495cd3f9d89SJunchao Zhang 2496cd3f9d89SJunchao Zhang PetscFunctionBegin; 2497cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 24984f572ea9SToby Isaac PetscAssertPointer(array, 2); 2499e865de01SJunchao 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 */ 2500cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2501cd3f9d89SJunchao Zhang if (isMPI) { 2502cd3f9d89SJunchao Zhang PetscCall(MatDenseGetArrayWriteAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype)); 2503cd3f9d89SJunchao Zhang } else { 2504cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **, PetscMemType *); 25053ba16761SJacob Faibussowitsch 25063ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayWriteAndMemType_C", &fptr)); 2507cd3f9d89SJunchao Zhang if (fptr) { 2508cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array, mtype)); 2509cd3f9d89SJunchao Zhang } else { 2510cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array)); 2511cd3f9d89SJunchao Zhang if (mtype) *mtype = PETSC_MEMTYPE_HOST; 2512cd3f9d89SJunchao Zhang } 2513cd3f9d89SJunchao Zhang } 25143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2515cd3f9d89SJunchao Zhang } 2516cd3f9d89SJunchao Zhang 2517cd3f9d89SJunchao Zhang /*@C 2518cd3f9d89SJunchao Zhang MatDenseRestoreArrayWriteAndMemType - returns access to the array that is obtained by `MatDenseGetArrayReadAndMemType()` 2519cd3f9d89SJunchao Zhang 2520cd3f9d89SJunchao Zhang Logically Collective 2521cd3f9d89SJunchao Zhang 2522cd3f9d89SJunchao Zhang Input Parameters: 2523fe59aa6dSJacob Faibussowitsch + A - a dense matrix 2524cd3f9d89SJunchao Zhang - array - pointer to the data 2525cd3f9d89SJunchao Zhang 2526cd3f9d89SJunchao Zhang Level: intermediate 2527cd3f9d89SJunchao Zhang 25281cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayWriteAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 2529cd3f9d89SJunchao Zhang @*/ 25305d83a8b1SBarry Smith PetscErrorCode MatDenseRestoreArrayWriteAndMemType(Mat A, PetscScalar *array[]) 2531cd3f9d89SJunchao Zhang { 2532cd3f9d89SJunchao Zhang PetscBool isMPI; 2533cd3f9d89SJunchao Zhang 2534cd3f9d89SJunchao Zhang PetscFunctionBegin; 2535cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 25364f572ea9SToby Isaac PetscAssertPointer(array, 2); 2537cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2538cd3f9d89SJunchao Zhang if (isMPI) { 2539cd3f9d89SJunchao Zhang PetscCall(MatDenseRestoreArrayWriteAndMemType(((Mat_MPIDense *)A->data)->A, array)); 2540cd3f9d89SJunchao Zhang } else { 2541cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **); 25423ba16761SJacob Faibussowitsch 25433ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayWriteAndMemType_C", &fptr)); 2544cd3f9d89SJunchao Zhang if (fptr) { 2545cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array)); 2546cd3f9d89SJunchao Zhang } else { 2547cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array)); 2548cd3f9d89SJunchao Zhang } 2549cd3f9d89SJunchao Zhang *array = NULL; 2550cd3f9d89SJunchao Zhang } 2551cd3f9d89SJunchao Zhang PetscCall(PetscObjectStateIncrease((PetscObject)A)); 25523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2553cd3f9d89SJunchao Zhang } 2554cd3f9d89SJunchao Zhang 2555d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A, IS isrow, IS iscol, MatReuse scall, Mat *B) 2556d71ae5a4SJacob Faibussowitsch { 2557c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 2558bf5a80bcSToby Isaac PetscInt i, j, nrows, ncols, ldb; 25595d0c19d7SBarry Smith const PetscInt *irow, *icol; 256087828ca2SBarry Smith PetscScalar *av, *bv, *v = mat->v; 25610754003eSLois Curfman McInnes Mat newmat; 25620754003eSLois Curfman McInnes 25633a40ed3dSBarry Smith PetscFunctionBegin; 25649566063dSJacob Faibussowitsch PetscCall(ISGetIndices(isrow, &irow)); 25659566063dSJacob Faibussowitsch PetscCall(ISGetIndices(iscol, &icol)); 25669566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(isrow, &nrows)); 25679566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(iscol, &ncols)); 25680754003eSLois Curfman McInnes 2569182d2002SSatish Balay /* Check submatrixcall */ 2570182d2002SSatish Balay if (scall == MAT_REUSE_MATRIX) { 257113f74950SBarry Smith PetscInt n_cols, n_rows; 25729566063dSJacob Faibussowitsch PetscCall(MatGetSize(*B, &n_rows, &n_cols)); 257321a2c019SBarry Smith if (n_rows != nrows || n_cols != ncols) { 2574f746d493SDmitry Karpeev /* resize the result matrix to match number of requested rows/columns */ 25759566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*B, nrows, ncols, nrows, ncols)); 257621a2c019SBarry Smith } 2577182d2002SSatish Balay newmat = *B; 2578182d2002SSatish Balay } else { 25790754003eSLois Curfman McInnes /* Create and fill new matrix */ 25809566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &newmat)); 25819566063dSJacob Faibussowitsch PetscCall(MatSetSizes(newmat, nrows, ncols, nrows, ncols)); 25829566063dSJacob Faibussowitsch PetscCall(MatSetType(newmat, ((PetscObject)A)->type_name)); 25839566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(newmat, NULL)); 2584182d2002SSatish Balay } 2585182d2002SSatish Balay 2586182d2002SSatish Balay /* Now extract the data pointers and do the copy,column at a time */ 25879566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(newmat, &bv)); 25889566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(newmat, &ldb)); 2589182d2002SSatish Balay for (i = 0; i < ncols; i++) { 25906de62eeeSBarry Smith av = v + mat->lda * icol[i]; 2591ca15aa20SStefano Zampini for (j = 0; j < nrows; j++) bv[j] = av[irow[j]]; 2592bf5a80bcSToby Isaac bv += ldb; 25930754003eSLois Curfman McInnes } 25949566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(newmat, &bv)); 2595182d2002SSatish Balay 2596182d2002SSatish Balay /* Assemble the matrices so that the correct flags are set */ 25979566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(newmat, MAT_FINAL_ASSEMBLY)); 25989566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(newmat, MAT_FINAL_ASSEMBLY)); 25990754003eSLois Curfman McInnes 26000754003eSLois Curfman McInnes /* Free work space */ 26019566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(isrow, &irow)); 26029566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(iscol, &icol)); 2603182d2002SSatish Balay *B = newmat; 26043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26050754003eSLois Curfman McInnes } 26060754003eSLois Curfman McInnes 2607d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A, PetscInt n, const IS irow[], const IS icol[], MatReuse scall, Mat *B[]) 2608d71ae5a4SJacob Faibussowitsch { 260913f74950SBarry Smith PetscInt i; 2610905e6a2fSBarry Smith 26113a40ed3dSBarry Smith PetscFunctionBegin; 261248a46eb9SPierre Jolivet if (scall == MAT_INITIAL_MATRIX) PetscCall(PetscCalloc1(n, B)); 2613905e6a2fSBarry Smith 261448a46eb9SPierre Jolivet for (i = 0; i < n; i++) PetscCall(MatCreateSubMatrix_SeqDense(A, irow[i], icol[i], scall, &(*B)[i])); 26153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2616905e6a2fSBarry Smith } 2617905e6a2fSBarry Smith 2618d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCopy_SeqDense(Mat A, Mat B, MatStructure str) 2619d71ae5a4SJacob Faibussowitsch { 26204b0e389bSBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data; 2621ca15aa20SStefano Zampini const PetscScalar *va; 2622ca15aa20SStefano Zampini PetscScalar *vb; 2623d0f46423SBarry Smith PetscInt lda1 = a->lda, lda2 = b->lda, m = A->rmap->n, n = A->cmap->n, j; 26243a40ed3dSBarry Smith 26253a40ed3dSBarry Smith PetscFunctionBegin; 262633f4a19fSKris Buschelman /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */ 262733f4a19fSKris Buschelman if (A->ops->copy != B->ops->copy) { 26289566063dSJacob Faibussowitsch PetscCall(MatCopy_Basic(A, B, str)); 26293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26303a40ed3dSBarry Smith } 2631aed4548fSBarry Smith PetscCheck(m == B->rmap->n && n == B->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "size(B) != size(A)"); 26329566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &va)); 26339566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(B, &vb)); 2634a5ce6ee0Svictorle if (lda1 > m || lda2 > m) { 263548a46eb9SPierre Jolivet for (j = 0; j < n; j++) PetscCall(PetscArraycpy(vb + j * lda2, va + j * lda1, m)); 2636a5ce6ee0Svictorle } else { 26379566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(vb, va, A->rmap->n * A->cmap->n)); 2638a5ce6ee0Svictorle } 26399566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(B, &vb)); 26409566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &va)); 26419566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 26429566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 26433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2644273d9f13SBarry Smith } 2645273d9f13SBarry Smith 2646d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetUp_SeqDense(Mat A) 2647d71ae5a4SJacob Faibussowitsch { 2648273d9f13SBarry Smith PetscFunctionBegin; 26499566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 26509566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 265148a46eb9SPierre Jolivet if (!A->preallocated) PetscCall(MatSeqDenseSetPreallocation(A, NULL)); 26523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26534b0e389bSBarry Smith } 26544b0e389bSBarry Smith 2655*3853def2SToby Isaac PetscErrorCode MatConjugate_SeqDense(Mat A) 2656d71ae5a4SJacob Faibussowitsch { 26574396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 265806c5243aSJose E. Roman PetscInt i, j; 26594396437dSToby Isaac PetscInt min = PetscMin(A->rmap->n, A->cmap->n); 2660ca15aa20SStefano Zampini PetscScalar *aa; 2661ba337c44SJed Brown 2662ba337c44SJed Brown PetscFunctionBegin; 26639566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 266406c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 266506c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscConj(aa[i + j * mat->lda]); 266606c5243aSJose E. Roman } 26679566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 26689371c9d4SSatish Balay if (mat->tau) 26699371c9d4SSatish Balay for (i = 0; i < min; i++) mat->tau[i] = PetscConj(mat->tau[i]); 26703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2671ba337c44SJed Brown } 2672ba337c44SJed Brown 2673d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRealPart_SeqDense(Mat A) 2674d71ae5a4SJacob Faibussowitsch { 267506c5243aSJose E. Roman Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 267606c5243aSJose E. Roman PetscInt i, j; 2677ca15aa20SStefano Zampini PetscScalar *aa; 2678ba337c44SJed Brown 2679ba337c44SJed Brown PetscFunctionBegin; 26809566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 268106c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 268206c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscRealPart(aa[i + j * mat->lda]); 268306c5243aSJose E. Roman } 26849566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 26853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2686ba337c44SJed Brown } 2687ba337c44SJed Brown 2688d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatImaginaryPart_SeqDense(Mat A) 2689d71ae5a4SJacob Faibussowitsch { 269006c5243aSJose E. Roman Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 269106c5243aSJose E. Roman PetscInt i, j; 2692ca15aa20SStefano Zampini PetscScalar *aa; 2693ba337c44SJed Brown 2694ba337c44SJed Brown PetscFunctionBegin; 26959566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 269606c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 269706c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscImaginaryPart(aa[i + j * mat->lda]); 269806c5243aSJose E. Roman } 26999566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 27003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2701ba337c44SJed Brown } 2702284134d9SBarry Smith 2703d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2704d71ae5a4SJacob Faibussowitsch { 2705d0f46423SBarry Smith PetscInt m = A->rmap->n, n = B->cmap->n; 270647d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 2707a9fe9ddaSSatish Balay 2708ee16a9a1SHong Zhang PetscFunctionBegin; 27099566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 271047d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 27119566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 271247d993e7Ssuyashtn #endif 271347d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 271447d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 271547d993e7Ssuyashtn #endif 27167a3c3d58SStefano Zampini if (!cisdense) { 27177a3c3d58SStefano Zampini PetscBool flg; 27187a3c3d58SStefano Zampini 27199566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 27209566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 27217a3c3d58SStefano Zampini } 27229566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 27233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2724ee16a9a1SHong Zhang } 2725a9fe9ddaSSatish Balay 2726d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2727d71ae5a4SJacob Faibussowitsch { 27286718818eSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data, *c = (Mat_SeqDense *)C->data; 27290805154bSBarry Smith PetscBLASInt m, n, k; 2730ca15aa20SStefano Zampini const PetscScalar *av, *bv; 2731ca15aa20SStefano Zampini PetscScalar *cv; 2732a9fe9ddaSSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 2733a9fe9ddaSSatish Balay 2734a9fe9ddaSSatish Balay PetscFunctionBegin; 27359566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 27369566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 27379566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 27383ba16761SJacob Faibussowitsch if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS); 27399566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 27409566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 27419566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2742792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("N", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 27439566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 27449566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 27459566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 27469566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 27473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2748a9fe9ddaSSatish Balay } 2749a9fe9ddaSSatish Balay 2750d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2751d71ae5a4SJacob Faibussowitsch { 275269f65d41SStefano Zampini PetscInt m = A->rmap->n, n = B->rmap->n; 275347d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 275469f65d41SStefano Zampini 275569f65d41SStefano Zampini PetscFunctionBegin; 27569566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 275747d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 27589566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 275947d993e7Ssuyashtn #endif 276047d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 276147d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 276247d993e7Ssuyashtn #endif 27637a3c3d58SStefano Zampini if (!cisdense) { 27647a3c3d58SStefano Zampini PetscBool flg; 27657a3c3d58SStefano Zampini 27669566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 27679566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 27687a3c3d58SStefano Zampini } 27699566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 27703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 277169f65d41SStefano Zampini } 277269f65d41SStefano Zampini 2773d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2774d71ae5a4SJacob Faibussowitsch { 277569f65d41SStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 277669f65d41SStefano Zampini Mat_SeqDense *b = (Mat_SeqDense *)B->data; 277769f65d41SStefano Zampini Mat_SeqDense *c = (Mat_SeqDense *)C->data; 27786718818eSStefano Zampini const PetscScalar *av, *bv; 27796718818eSStefano Zampini PetscScalar *cv; 278069f65d41SStefano Zampini PetscBLASInt m, n, k; 278169f65d41SStefano Zampini PetscScalar _DOne = 1.0, _DZero = 0.0; 278269f65d41SStefano Zampini 278369f65d41SStefano Zampini PetscFunctionBegin; 27849566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 27859566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 27869566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 27873ba16761SJacob Faibussowitsch if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS); 27889566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 27899566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 27909566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2791792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("N", "T", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 27929566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 27939566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 27949566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 27959566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 27963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 279769f65d41SStefano Zampini } 279869f65d41SStefano Zampini 2799d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2800d71ae5a4SJacob Faibussowitsch { 2801d0f46423SBarry Smith PetscInt m = A->cmap->n, n = B->cmap->n; 280247d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 2803a9fe9ddaSSatish Balay 2804ee16a9a1SHong Zhang PetscFunctionBegin; 28059566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 280647d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 28079566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 280847d993e7Ssuyashtn #endif 280947d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 281047d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 281147d993e7Ssuyashtn #endif 28127a3c3d58SStefano Zampini if (!cisdense) { 28137a3c3d58SStefano Zampini PetscBool flg; 28147a3c3d58SStefano Zampini 28159566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 28169566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 28177a3c3d58SStefano Zampini } 28189566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 28193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2820ee16a9a1SHong Zhang } 2821a9fe9ddaSSatish Balay 2822d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2823d71ae5a4SJacob Faibussowitsch { 2824a9fe9ddaSSatish Balay Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2825a9fe9ddaSSatish Balay Mat_SeqDense *b = (Mat_SeqDense *)B->data; 2826a9fe9ddaSSatish Balay Mat_SeqDense *c = (Mat_SeqDense *)C->data; 28276718818eSStefano Zampini const PetscScalar *av, *bv; 28286718818eSStefano Zampini PetscScalar *cv; 28290805154bSBarry Smith PetscBLASInt m, n, k; 2830a9fe9ddaSSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 2831a9fe9ddaSSatish Balay 2832a9fe9ddaSSatish Balay PetscFunctionBegin; 28339566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 28349566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 28359566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &k)); 28363ba16761SJacob Faibussowitsch if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS); 28379566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 28389566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 28399566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2840792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("T", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 28419566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 28429566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 28439566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 28449566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 28453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2846a9fe9ddaSSatish Balay } 2847985db425SBarry Smith 2848d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C) 2849d71ae5a4SJacob Faibussowitsch { 28504222ddf1SHong Zhang PetscFunctionBegin; 28514222ddf1SHong Zhang C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense; 28524222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AB; 28533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28544222ddf1SHong Zhang } 28554222ddf1SHong Zhang 2856d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C) 2857d71ae5a4SJacob Faibussowitsch { 28584222ddf1SHong Zhang PetscFunctionBegin; 28594222ddf1SHong Zhang C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense; 28604222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AtB; 28613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28624222ddf1SHong Zhang } 28634222ddf1SHong Zhang 2864d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C) 2865d71ae5a4SJacob Faibussowitsch { 28664222ddf1SHong Zhang PetscFunctionBegin; 28674222ddf1SHong Zhang C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense; 28684222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_ABt; 28693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28704222ddf1SHong Zhang } 28714222ddf1SHong Zhang 2872d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C) 2873d71ae5a4SJacob Faibussowitsch { 28744222ddf1SHong Zhang Mat_Product *product = C->product; 28754222ddf1SHong Zhang 28764222ddf1SHong Zhang PetscFunctionBegin; 28774222ddf1SHong Zhang switch (product->type) { 2878d71ae5a4SJacob Faibussowitsch case MATPRODUCT_AB: 2879d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_AB(C)); 2880d71ae5a4SJacob Faibussowitsch break; 2881d71ae5a4SJacob Faibussowitsch case MATPRODUCT_AtB: 2882d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_AtB(C)); 2883d71ae5a4SJacob Faibussowitsch break; 2884d71ae5a4SJacob Faibussowitsch case MATPRODUCT_ABt: 2885d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_ABt(C)); 2886d71ae5a4SJacob Faibussowitsch break; 2887d71ae5a4SJacob Faibussowitsch default: 2888d71ae5a4SJacob Faibussowitsch break; 28894222ddf1SHong Zhang } 28903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28914222ddf1SHong Zhang } 28924222ddf1SHong Zhang 2893d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMax_SeqDense(Mat A, Vec v, PetscInt idx[]) 2894d71ae5a4SJacob Faibussowitsch { 2895985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2896d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2897985db425SBarry Smith PetscScalar *x; 2898ca15aa20SStefano Zampini const PetscScalar *aa; 2899985db425SBarry Smith 2900985db425SBarry Smith PetscFunctionBegin; 290128b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29029566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29039566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 29049566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 290508401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2906985db425SBarry Smith for (i = 0; i < m; i++) { 29079371c9d4SSatish Balay x[i] = aa[i]; 29089371c9d4SSatish Balay if (idx) idx[i] = 0; 2909985db425SBarry Smith for (j = 1; j < n; j++) { 29109371c9d4SSatish Balay if (PetscRealPart(x[i]) < PetscRealPart(aa[i + a->lda * j])) { 29119371c9d4SSatish Balay x[i] = aa[i + a->lda * j]; 29129371c9d4SSatish Balay if (idx) idx[i] = j; 29139371c9d4SSatish Balay } 2914985db425SBarry Smith } 2915985db425SBarry Smith } 29169566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 29179566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 29183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2919985db425SBarry Smith } 2920985db425SBarry Smith 2921d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A, Vec v, PetscInt idx[]) 2922d71ae5a4SJacob Faibussowitsch { 2923985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2924d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2925985db425SBarry Smith PetscScalar *x; 2926985db425SBarry Smith PetscReal atmp; 2927ca15aa20SStefano Zampini const PetscScalar *aa; 2928985db425SBarry Smith 2929985db425SBarry Smith PetscFunctionBegin; 293028b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29319566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29329566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 29339566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 293408401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2935985db425SBarry Smith for (i = 0; i < m; i++) { 29369189402eSHong Zhang x[i] = PetscAbsScalar(aa[i]); 2937985db425SBarry Smith for (j = 1; j < n; j++) { 2938ca15aa20SStefano Zampini atmp = PetscAbsScalar(aa[i + a->lda * j]); 29399371c9d4SSatish Balay if (PetscAbsScalar(x[i]) < atmp) { 29409371c9d4SSatish Balay x[i] = atmp; 29419371c9d4SSatish Balay if (idx) idx[i] = j; 29429371c9d4SSatish Balay } 2943985db425SBarry Smith } 2944985db425SBarry Smith } 29459566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 29469566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 29473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2948985db425SBarry Smith } 2949985db425SBarry Smith 2950d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMin_SeqDense(Mat A, Vec v, PetscInt idx[]) 2951d71ae5a4SJacob Faibussowitsch { 2952985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2953d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2954985db425SBarry Smith PetscScalar *x; 2955ca15aa20SStefano Zampini const PetscScalar *aa; 2956985db425SBarry Smith 2957985db425SBarry Smith PetscFunctionBegin; 295828b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29599566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 29609566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29619566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 296208401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2963985db425SBarry Smith for (i = 0; i < m; i++) { 29649371c9d4SSatish Balay x[i] = aa[i]; 29659371c9d4SSatish Balay if (idx) idx[i] = 0; 2966985db425SBarry Smith for (j = 1; j < n; j++) { 29679371c9d4SSatish Balay if (PetscRealPart(x[i]) > PetscRealPart(aa[i + a->lda * j])) { 29689371c9d4SSatish Balay x[i] = aa[i + a->lda * j]; 29699371c9d4SSatish Balay if (idx) idx[i] = j; 29709371c9d4SSatish Balay } 2971985db425SBarry Smith } 2972985db425SBarry Smith } 29739566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 29749566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 29753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2976985db425SBarry Smith } 2977985db425SBarry Smith 2978d71ae5a4SJacob Faibussowitsch PetscErrorCode MatGetColumnVector_SeqDense(Mat A, Vec v, PetscInt col) 2979d71ae5a4SJacob Faibussowitsch { 29808d0534beSBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 29818d0534beSBarry Smith PetscScalar *x; 2982ca15aa20SStefano Zampini const PetscScalar *aa; 29838d0534beSBarry Smith 29848d0534beSBarry Smith PetscFunctionBegin; 298528b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29869566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 29879566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29889566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(x, aa + col * a->lda, A->rmap->n)); 29899566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 29909566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 29913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29928d0534beSBarry Smith } 29938d0534beSBarry Smith 2994d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatGetColumnReductions_SeqDense(Mat A, PetscInt type, PetscReal *reductions) 2995d71ae5a4SJacob Faibussowitsch { 29960716a85fSBarry Smith PetscInt i, j, m, n; 29971683a169SBarry Smith const PetscScalar *a; 29980716a85fSBarry Smith 29990716a85fSBarry Smith PetscFunctionBegin; 30009566063dSJacob Faibussowitsch PetscCall(MatGetSize(A, &m, &n)); 30019566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(reductions, n)); 30029566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &a)); 3003857cbf51SRichard Tran Mills if (type == NORM_2) { 30040716a85fSBarry Smith for (i = 0; i < n; i++) { 3005ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j] * a[j]); 300616cd844bSPierre Jolivet a = PetscSafePointerPlusOffset(a, m); 30070716a85fSBarry Smith } 3008857cbf51SRichard Tran Mills } else if (type == NORM_1) { 30090716a85fSBarry Smith for (i = 0; i < n; i++) { 3010ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j]); 301116cd844bSPierre Jolivet a = PetscSafePointerPlusOffset(a, m); 30120716a85fSBarry Smith } 3013857cbf51SRichard Tran Mills } else if (type == NORM_INFINITY) { 30140716a85fSBarry Smith for (i = 0; i < n; i++) { 3015ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] = PetscMax(PetscAbsScalar(a[j]), reductions[i]); 301616cd844bSPierre Jolivet a = PetscSafePointerPlusOffset(a, m); 30170716a85fSBarry Smith } 3018857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_REALPART || type == REDUCTION_MEAN_REALPART) { 3019a873a8cdSSam Reynolds for (i = 0; i < n; i++) { 3020ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscRealPart(a[j]); 302116cd844bSPierre Jolivet a = PetscSafePointerPlusOffset(a, m); 3022a873a8cdSSam Reynolds } 3023857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_IMAGINARYPART || type == REDUCTION_MEAN_IMAGINARYPART) { 3024857cbf51SRichard Tran Mills for (i = 0; i < n; i++) { 3025ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscImaginaryPart(a[j]); 302616cd844bSPierre Jolivet a = PetscSafePointerPlusOffset(a, m); 3027857cbf51SRichard Tran Mills } 3028857cbf51SRichard Tran Mills } else SETERRQ(PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Unknown reduction type"); 30299566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &a)); 3030857cbf51SRichard Tran Mills if (type == NORM_2) { 3031a873a8cdSSam Reynolds for (i = 0; i < n; i++) reductions[i] = PetscSqrtReal(reductions[i]); 3032857cbf51SRichard Tran Mills } else if (type == REDUCTION_MEAN_REALPART || type == REDUCTION_MEAN_IMAGINARYPART) { 3033a873a8cdSSam Reynolds for (i = 0; i < n; i++) reductions[i] /= m; 30340716a85fSBarry Smith } 30353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30360716a85fSBarry Smith } 30370716a85fSBarry Smith 3038d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetRandom_SeqDense(Mat x, PetscRandom rctx) 3039d71ae5a4SJacob Faibussowitsch { 304073a71a0fSBarry Smith PetscScalar *a; 3041637a0070SStefano Zampini PetscInt lda, m, n, i, j; 304273a71a0fSBarry Smith 304373a71a0fSBarry Smith PetscFunctionBegin; 30449566063dSJacob Faibussowitsch PetscCall(MatGetSize(x, &m, &n)); 30459566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(x, &lda)); 30463faff063SStefano Zampini PetscCall(MatDenseGetArrayWrite(x, &a)); 3047637a0070SStefano Zampini for (j = 0; j < n; j++) { 304848a46eb9SPierre Jolivet for (i = 0; i < m; i++) PetscCall(PetscRandomGetValue(rctx, a + j * lda + i)); 304973a71a0fSBarry Smith } 30503faff063SStefano Zampini PetscCall(MatDenseRestoreArrayWrite(x, &a)); 30513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 305273a71a0fSBarry Smith } 305373a71a0fSBarry Smith 3054d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A, PetscBool *missing, PetscInt *d) 3055d71ae5a4SJacob Faibussowitsch { 30563b49f96aSBarry Smith PetscFunctionBegin; 30573b49f96aSBarry Smith *missing = PETSC_FALSE; 30583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30593b49f96aSBarry Smith } 306073a71a0fSBarry Smith 3061ca15aa20SStefano Zampini /* vals is not const */ 3062d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A, PetscInt col, PetscScalar **vals) 3063d71ae5a4SJacob Faibussowitsch { 306486aefd0dSHong Zhang Mat_SeqDense *a = (Mat_SeqDense *)A->data; 3065ca15aa20SStefano Zampini PetscScalar *v; 306686aefd0dSHong Zhang 306786aefd0dSHong Zhang PetscFunctionBegin; 306828b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 30699566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 3070ca15aa20SStefano Zampini *vals = v + col * a->lda; 30719566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 30723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 307386aefd0dSHong Zhang } 307486aefd0dSHong Zhang 3075d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A, PetscScalar **vals) 3076d71ae5a4SJacob Faibussowitsch { 307786aefd0dSHong Zhang PetscFunctionBegin; 3078742765d3SMatthew Knepley if (vals) *vals = NULL; /* user cannot accidentally use the array later */ 30793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 308086aefd0dSHong Zhang } 3081abc3b08eSStefano Zampini 3082a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqDense, 3083905e6a2fSBarry Smith MatGetRow_SeqDense, 3084905e6a2fSBarry Smith MatRestoreRow_SeqDense, 3085905e6a2fSBarry Smith MatMult_SeqDense, 308697304618SKris Buschelman /* 4*/ MatMultAdd_SeqDense, 30877c922b88SBarry Smith MatMultTranspose_SeqDense, 30887c922b88SBarry Smith MatMultTransposeAdd_SeqDense, 3089f4259b30SLisandro Dalcin NULL, 3090f4259b30SLisandro Dalcin NULL, 3091f4259b30SLisandro Dalcin NULL, 3092f4259b30SLisandro Dalcin /* 10*/ NULL, 3093905e6a2fSBarry Smith MatLUFactor_SeqDense, 3094905e6a2fSBarry Smith MatCholeskyFactor_SeqDense, 309541f059aeSBarry Smith MatSOR_SeqDense, 3096ec8511deSBarry Smith MatTranspose_SeqDense, 309797304618SKris Buschelman /* 15*/ MatGetInfo_SeqDense, 3098905e6a2fSBarry Smith MatEqual_SeqDense, 3099905e6a2fSBarry Smith MatGetDiagonal_SeqDense, 3100905e6a2fSBarry Smith MatDiagonalScale_SeqDense, 3101905e6a2fSBarry Smith MatNorm_SeqDense, 3102b7103cf4SPierre Jolivet /* 20*/ NULL, 3103b7103cf4SPierre Jolivet NULL, 3104905e6a2fSBarry Smith MatSetOption_SeqDense, 3105905e6a2fSBarry Smith MatZeroEntries_SeqDense, 3106d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqDense, 3107f4259b30SLisandro Dalcin NULL, 3108f4259b30SLisandro Dalcin NULL, 3109f4259b30SLisandro Dalcin NULL, 3110f4259b30SLisandro Dalcin NULL, 31114994cf47SJed Brown /* 29*/ MatSetUp_SeqDense, 3112f4259b30SLisandro Dalcin NULL, 3113f4259b30SLisandro Dalcin NULL, 3114f4259b30SLisandro Dalcin NULL, 3115f4259b30SLisandro Dalcin NULL, 3116d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqDense, 3117f4259b30SLisandro Dalcin NULL, 3118f4259b30SLisandro Dalcin NULL, 3119f4259b30SLisandro Dalcin NULL, 3120f4259b30SLisandro Dalcin NULL, 3121d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqDense, 31227dae84e0SHong Zhang MatCreateSubMatrices_SeqDense, 3123f4259b30SLisandro Dalcin NULL, 31244b0e389bSBarry Smith MatGetValues_SeqDense, 3125a5ae1ecdSBarry Smith MatCopy_SeqDense, 3126d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqDense, 3127a5ae1ecdSBarry Smith MatScale_SeqDense, 31282f605a99SJose E. Roman MatShift_SeqDense, 3129f4259b30SLisandro Dalcin NULL, 31303f49a652SStefano Zampini MatZeroRowsColumns_SeqDense, 313173a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqDense, 3132f4259b30SLisandro Dalcin NULL, 3133f4259b30SLisandro Dalcin NULL, 3134f4259b30SLisandro Dalcin NULL, 3135f4259b30SLisandro Dalcin NULL, 3136f4259b30SLisandro Dalcin /* 54*/ NULL, 3137f4259b30SLisandro Dalcin NULL, 3138f4259b30SLisandro Dalcin NULL, 3139f4259b30SLisandro Dalcin NULL, 3140f4259b30SLisandro Dalcin NULL, 3141023c16fcSToby Isaac /* 59*/ MatCreateSubMatrix_SeqDense, 3142e03a110bSBarry Smith MatDestroy_SeqDense, 3143e03a110bSBarry Smith MatView_SeqDense, 3144f4259b30SLisandro Dalcin NULL, 3145f4259b30SLisandro Dalcin NULL, 3146f4259b30SLisandro Dalcin /* 64*/ NULL, 3147f4259b30SLisandro Dalcin NULL, 3148f4259b30SLisandro Dalcin NULL, 3149f4259b30SLisandro Dalcin NULL, 3150f4259b30SLisandro Dalcin NULL, 3151d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqDense, 3152f4259b30SLisandro Dalcin NULL, 3153f4259b30SLisandro Dalcin NULL, 3154f4259b30SLisandro Dalcin NULL, 3155f4259b30SLisandro Dalcin NULL, 3156f4259b30SLisandro Dalcin /* 74*/ NULL, 3157f4259b30SLisandro Dalcin NULL, 3158f4259b30SLisandro Dalcin NULL, 3159f4259b30SLisandro Dalcin NULL, 3160f4259b30SLisandro Dalcin NULL, 3161f4259b30SLisandro Dalcin /* 79*/ NULL, 3162f4259b30SLisandro Dalcin NULL, 3163f4259b30SLisandro Dalcin NULL, 3164f4259b30SLisandro Dalcin NULL, 31655bba2384SShri Abhyankar /* 83*/ MatLoad_SeqDense, 3166637a0070SStefano Zampini MatIsSymmetric_SeqDense, 31671cbb95d3SBarry Smith MatIsHermitian_SeqDense, 3168f4259b30SLisandro Dalcin NULL, 3169f4259b30SLisandro Dalcin NULL, 3170f4259b30SLisandro Dalcin NULL, 3171f4259b30SLisandro Dalcin /* 89*/ NULL, 3172f4259b30SLisandro Dalcin NULL, 3173a9fe9ddaSSatish Balay MatMatMultNumeric_SeqDense_SeqDense, 3174f4259b30SLisandro Dalcin NULL, 3175f4259b30SLisandro Dalcin NULL, 3176f4259b30SLisandro Dalcin /* 94*/ NULL, 3177f4259b30SLisandro Dalcin NULL, 3178f4259b30SLisandro Dalcin NULL, 317969f65d41SStefano Zampini MatMatTransposeMultNumeric_SeqDense_SeqDense, 3180f4259b30SLisandro Dalcin NULL, 31814222ddf1SHong Zhang /* 99*/ MatProductSetFromOptions_SeqDense, 3182f4259b30SLisandro Dalcin NULL, 3183f4259b30SLisandro Dalcin NULL, 3184ba337c44SJed Brown MatConjugate_SeqDense, 3185f4259b30SLisandro Dalcin NULL, 3186f4259b30SLisandro Dalcin /*104*/ NULL, 3187ba337c44SJed Brown MatRealPart_SeqDense, 3188ba337c44SJed Brown MatImaginaryPart_SeqDense, 3189f4259b30SLisandro Dalcin NULL, 3190f4259b30SLisandro Dalcin NULL, 3191f4259b30SLisandro Dalcin /*109*/ NULL, 3192f4259b30SLisandro Dalcin NULL, 31938d0534beSBarry Smith MatGetRowMin_SeqDense, 3194aabbc4fbSShri Abhyankar MatGetColumnVector_SeqDense, 31953b49f96aSBarry Smith MatMissingDiagonal_SeqDense, 3196f4259b30SLisandro Dalcin /*114*/ NULL, 3197f4259b30SLisandro Dalcin NULL, 3198f4259b30SLisandro Dalcin NULL, 3199f4259b30SLisandro Dalcin NULL, 3200f4259b30SLisandro Dalcin NULL, 3201f4259b30SLisandro Dalcin /*119*/ NULL, 3202f4259b30SLisandro Dalcin NULL, 3203459e8d23SBlanca Mellado Pinto MatMultHermitianTranspose_SeqDense, 3204459e8d23SBlanca Mellado Pinto MatMultHermitianTransposeAdd_SeqDense, 3205f4259b30SLisandro Dalcin NULL, 3206f4259b30SLisandro Dalcin /*124*/ NULL, 3207a873a8cdSSam Reynolds MatGetColumnReductions_SeqDense, 3208f4259b30SLisandro Dalcin NULL, 3209f4259b30SLisandro Dalcin NULL, 3210f4259b30SLisandro Dalcin NULL, 3211f4259b30SLisandro Dalcin /*129*/ NULL, 3212f4259b30SLisandro Dalcin NULL, 3213f4259b30SLisandro Dalcin NULL, 321475648e8dSHong Zhang MatTransposeMatMultNumeric_SeqDense_SeqDense, 3215f4259b30SLisandro Dalcin NULL, 3216f4259b30SLisandro Dalcin /*134*/ NULL, 3217f4259b30SLisandro Dalcin NULL, 3218f4259b30SLisandro Dalcin NULL, 3219f4259b30SLisandro Dalcin NULL, 3220f4259b30SLisandro Dalcin NULL, 3221f4259b30SLisandro Dalcin /*139*/ NULL, 3222f4259b30SLisandro Dalcin NULL, 3223f4259b30SLisandro Dalcin NULL, 3224f4259b30SLisandro Dalcin NULL, 3225f4259b30SLisandro Dalcin NULL, 32264222ddf1SHong Zhang MatCreateMPIMatConcatenateSeqMat_SeqDense, 3227f4259b30SLisandro Dalcin /*145*/ NULL, 3228f4259b30SLisandro Dalcin NULL, 322999a7f59eSMark Adams NULL, 323099a7f59eSMark Adams NULL, 32317fb60732SBarry Smith NULL, 3232dec0b466SHong Zhang /*150*/ NULL, 3233eede4a3fSMark Adams NULL, 32344cc2b5b5SPierre Jolivet NULL, 323542ce410bSJunchao Zhang NULL, 323642ce410bSJunchao Zhang NULL, 3237fe1fc275SAlexander /*155*/ NULL, 3238dec0b466SHong Zhang NULL}; 323990ace30eSBarry Smith 32405d83a8b1SBarry Smith /*@ 324111a5261eSBarry Smith MatCreateSeqDense - Creates a `MATSEQDENSE` that 3242fb850c59SBarry Smith is stored in column major order (the usual Fortran format). 3243289bc588SBarry Smith 3244d083f849SBarry Smith Collective 3245db81eaa0SLois Curfman McInnes 324620563c6bSBarry Smith Input Parameters: 324711a5261eSBarry Smith + comm - MPI communicator, set to `PETSC_COMM_SELF` 32480c775827SLois Curfman McInnes . m - number of rows 324918f449edSLois Curfman McInnes . n - number of columns 32502ef1f0ffSBarry Smith - data - optional location of matrix data in column major order. Use `NULL` for PETSc 3251dfc5480cSLois Curfman McInnes to control all matrix memory allocation. 325220563c6bSBarry Smith 325320563c6bSBarry Smith Output Parameter: 325444cd7ae7SLois Curfman McInnes . A - the matrix 325520563c6bSBarry Smith 32562ef1f0ffSBarry Smith Level: intermediate 32572ef1f0ffSBarry Smith 325811a5261eSBarry Smith Note: 325918f449edSLois Curfman McInnes The data input variable is intended primarily for Fortran programmers 326018f449edSLois Curfman McInnes who wish to allocate their own matrix memory space. Most users should 32612ef1f0ffSBarry Smith set `data` = `NULL`. 326218f449edSLois Curfman McInnes 3263fb850c59SBarry Smith Developer Note: 3264fb850c59SBarry Smith Many of the matrix operations for this variant use the BLAS and LAPACK routines. 3265fb850c59SBarry Smith 32661cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()` 326720563c6bSBarry Smith @*/ 32685d83a8b1SBarry Smith PetscErrorCode MatCreateSeqDense(MPI_Comm comm, PetscInt m, PetscInt n, PetscScalar data[], Mat *A) 3269d71ae5a4SJacob Faibussowitsch { 32703a40ed3dSBarry Smith PetscFunctionBegin; 32719566063dSJacob Faibussowitsch PetscCall(MatCreate(comm, A)); 32729566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*A, m, n, m, n)); 32739566063dSJacob Faibussowitsch PetscCall(MatSetType(*A, MATSEQDENSE)); 32749566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(*A, data)); 32753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3276273d9f13SBarry Smith } 3277273d9f13SBarry Smith 32785d83a8b1SBarry Smith /*@ 327911a5261eSBarry Smith MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements of a `MATSEQDENSE` matrix 3280273d9f13SBarry Smith 3281d083f849SBarry Smith Collective 3282273d9f13SBarry Smith 3283273d9f13SBarry Smith Input Parameters: 32841c4f3114SJed Brown + B - the matrix 32852ef1f0ffSBarry Smith - data - the array (or `NULL`) 32862ef1f0ffSBarry Smith 32872ef1f0ffSBarry Smith Level: intermediate 3288273d9f13SBarry Smith 328911a5261eSBarry Smith Note: 3290273d9f13SBarry Smith The data input variable is intended primarily for Fortran programmers 3291273d9f13SBarry Smith who wish to allocate their own matrix memory space. Most users should 3292284134d9SBarry Smith need not call this routine. 3293273d9f13SBarry Smith 32941cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()`, `MatDenseSetLDA()` 3295273d9f13SBarry Smith @*/ 3296d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation(Mat B, PetscScalar data[]) 3297d71ae5a4SJacob Faibussowitsch { 3298a23d5eceSKris Buschelman PetscFunctionBegin; 3299d5ea218eSStefano Zampini PetscValidHeaderSpecific(B, MAT_CLASSID, 1); 3300cac4c232SBarry Smith PetscTryMethod(B, "MatSeqDenseSetPreallocation_C", (Mat, PetscScalar[]), (B, data)); 33013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3302a23d5eceSKris Buschelman } 3303a23d5eceSKris Buschelman 3304d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation_SeqDense(Mat B, PetscScalar *data) 3305d71ae5a4SJacob Faibussowitsch { 3306ad16ce7aSStefano Zampini Mat_SeqDense *b = (Mat_SeqDense *)B->data; 3307273d9f13SBarry Smith 3308273d9f13SBarry Smith PetscFunctionBegin; 330928b400f6SJacob Faibussowitsch PetscCheck(!b->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3310273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 3311a868139aSShri Abhyankar 33129566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(B->rmap)); 33139566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(B->cmap)); 331434ef9618SShri Abhyankar 33156497c311SBarry Smith if (b->lda <= 0) PetscCall(PetscBLASIntCast(B->rmap->n, &b->lda)); 331686d161a7SShri Abhyankar 33179e8f95c4SLisandro Dalcin if (!data) { /* petsc-allocated storage */ 33189566063dSJacob Faibussowitsch if (!b->user_alloc) PetscCall(PetscFree(b->v)); 33199566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((size_t)b->lda * B->cmap->n, &b->v)); 33202205254eSKarl Rupp 33219e8f95c4SLisandro Dalcin b->user_alloc = PETSC_FALSE; 3322273d9f13SBarry Smith } else { /* user-allocated storage */ 33239566063dSJacob Faibussowitsch if (!b->user_alloc) PetscCall(PetscFree(b->v)); 3324273d9f13SBarry Smith b->v = data; 3325273d9f13SBarry Smith b->user_alloc = PETSC_TRUE; 3326273d9f13SBarry Smith } 33270450473dSBarry Smith B->assembled = PETSC_TRUE; 33283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3329273d9f13SBarry Smith } 3330273d9f13SBarry Smith 333165b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 3332d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) 3333d71ae5a4SJacob Faibussowitsch { 3334d77f618aSHong Zhang Mat mat_elemental; 33351683a169SBarry Smith const PetscScalar *array; 33361683a169SBarry Smith PetscScalar *v_colwise; 3337d77f618aSHong Zhang PetscInt M = A->rmap->N, N = A->cmap->N, i, j, k, *rows, *cols; 3338d77f618aSHong Zhang 33398baccfbdSHong Zhang PetscFunctionBegin; 33409566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(M * N, &v_colwise, M, &rows, N, &cols)); 33419566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &array)); 3342d77f618aSHong Zhang /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */ 3343d77f618aSHong Zhang k = 0; 3344d77f618aSHong Zhang for (j = 0; j < N; j++) { 3345d77f618aSHong Zhang cols[j] = j; 3346ad540459SPierre Jolivet for (i = 0; i < M; i++) v_colwise[j * M + i] = array[k++]; 3347d77f618aSHong Zhang } 3348ad540459SPierre Jolivet for (i = 0; i < M; i++) rows[i] = i; 33499566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &array)); 3350d77f618aSHong Zhang 33519566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental)); 33529566063dSJacob Faibussowitsch PetscCall(MatSetSizes(mat_elemental, PETSC_DECIDE, PETSC_DECIDE, M, N)); 33539566063dSJacob Faibussowitsch PetscCall(MatSetType(mat_elemental, MATELEMENTAL)); 33549566063dSJacob Faibussowitsch PetscCall(MatSetUp(mat_elemental)); 3355d77f618aSHong Zhang 3356d77f618aSHong Zhang /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */ 33579566063dSJacob Faibussowitsch PetscCall(MatSetValues(mat_elemental, M, rows, N, cols, v_colwise, ADD_VALUES)); 33589566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY)); 33599566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY)); 33609566063dSJacob Faibussowitsch PetscCall(PetscFree3(v_colwise, rows, cols)); 3361d77f618aSHong Zhang 3362511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 33639566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A, &mat_elemental)); 3364d77f618aSHong Zhang } else { 3365d77f618aSHong Zhang *newmat = mat_elemental; 3366d77f618aSHong Zhang } 33673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 33688baccfbdSHong Zhang } 336965b80a83SHong Zhang #endif 33708baccfbdSHong Zhang 3371d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA_SeqDense(Mat B, PetscInt lda) 3372d71ae5a4SJacob Faibussowitsch { 33731b807ce4Svictorle Mat_SeqDense *b = (Mat_SeqDense *)B->data; 33747422da62SJose E. Roman PetscBool data; 337521a2c019SBarry Smith 33761b807ce4Svictorle PetscFunctionBegin; 3377835f2295SStefano Zampini data = (B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE; 3378aed4548fSBarry Smith PetscCheck(b->user_alloc || !data || b->lda == lda, PETSC_COMM_SELF, PETSC_ERR_ORDER, "LDA cannot be changed after allocation of internal storage"); 337908401ef6SPierre 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); 33806497c311SBarry Smith PetscCall(PetscBLASIntCast(lda, &b->lda)); 33813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 33821b807ce4Svictorle } 33831b807ce4Svictorle 3384d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm, Mat inmat, PetscInt n, MatReuse scall, Mat *outmat) 3385d71ae5a4SJacob Faibussowitsch { 3386d528f656SJakub Kruzik PetscFunctionBegin; 33879566063dSJacob Faibussowitsch PetscCall(MatCreateMPIMatConcatenateSeqMat_MPIDense(comm, inmat, n, scall, outmat)); 33883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3389d528f656SJakub Kruzik } 3390d528f656SJakub Kruzik 3391d16ceb75SStefano Zampini PetscErrorCode MatDenseCreateColumnVec_Private(Mat A, Vec *v) 3392d16ceb75SStefano Zampini { 3393d16ceb75SStefano Zampini PetscBool isstd, iskok, iscuda, iship; 3394d16ceb75SStefano Zampini PetscMPIInt size; 3395d16ceb75SStefano Zampini #if PetscDefined(HAVE_CUDA) || PetscDefined(HAVE_HIP) 3396d16ceb75SStefano Zampini /* we pass the data of A, to prevent allocating needless GPU memory the first time VecCUPMPlaceArray is called. */ 3397d16ceb75SStefano Zampini const PetscScalar *a; 3398d16ceb75SStefano Zampini #endif 3399d16ceb75SStefano Zampini 3400d16ceb75SStefano Zampini PetscFunctionBegin; 3401d16ceb75SStefano Zampini *v = NULL; 3402d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &isstd, VECSTANDARD, VECSEQ, VECMPI, "")); 3403d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &iskok, VECKOKKOS, VECSEQKOKKOS, VECMPIKOKKOS, "")); 3404d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &iscuda, VECCUDA, VECSEQCUDA, VECMPICUDA, "")); 3405d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &iship, VECHIP, VECSEQHIP, VECMPIHIP, "")); 3406d16ceb75SStefano Zampini PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A), &size)); 3407d16ceb75SStefano Zampini if (isstd) { 3408d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPIWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, v)); 3409d16ceb75SStefano Zampini else PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, v)); 3410d16ceb75SStefano Zampini } else if (iskok) { 3411d16ceb75SStefano Zampini PetscCheck(PetscDefined(HAVE_KOKKOS_KERNELS), PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Reconfigure using KOKKOS kernels support"); 3412d16ceb75SStefano Zampini #if PetscDefined(HAVE_KOKKOS_KERNELS) 3413d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPIKokkosWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, v)); 3414d16ceb75SStefano Zampini else PetscCall(VecCreateSeqKokkosWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, v)); 3415d16ceb75SStefano Zampini #endif 3416d16ceb75SStefano Zampini } else if (iscuda) { 3417d16ceb75SStefano Zampini PetscCheck(PetscDefined(HAVE_CUDA), PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Reconfigure using CUDA support"); 3418d16ceb75SStefano Zampini #if PetscDefined(HAVE_CUDA) 3419d16ceb75SStefano Zampini PetscCall(MatDenseCUDAGetArrayRead(A, &a)); 3420d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPICUDAWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, a, v)); 3421d16ceb75SStefano Zampini else PetscCall(VecCreateSeqCUDAWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, a, v)); 3422d16ceb75SStefano Zampini #endif 3423d16ceb75SStefano Zampini } else if (iship) { 3424d16ceb75SStefano Zampini PetscCheck(PetscDefined(HAVE_HIP), PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Reconfigure using HIP support"); 3425d16ceb75SStefano Zampini #if PetscDefined(HAVE_HIP) 3426d16ceb75SStefano Zampini PetscCall(MatDenseHIPGetArrayRead(A, &a)); 3427d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPIHIPWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, a, v)); 3428d16ceb75SStefano Zampini else PetscCall(VecCreateSeqHIPWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, a, v)); 3429d16ceb75SStefano Zampini #endif 3430d16ceb75SStefano Zampini } 3431d16ceb75SStefano Zampini PetscCheck(*v, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Not coded for type %s", A->defaultvectype); 3432d16ceb75SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 3433d16ceb75SStefano Zampini } 3434d16ceb75SStefano Zampini 3435d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A, PetscInt col, Vec *v) 3436d71ae5a4SJacob Faibussowitsch { 34376947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34386947451fSStefano Zampini 34396947451fSStefano Zampini PetscFunctionBegin; 344028b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 344128b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3442d16ceb75SStefano Zampini if (!a->cvec) PetscCall(MatDenseCreateColumnVec_Private(A, &a->cvec)); 34436947451fSStefano Zampini a->vecinuse = col + 1; 34449566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, (PetscScalar **)&a->ptrinuse)); 34459566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda)); 34466947451fSStefano Zampini *v = a->cvec; 34473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34486947451fSStefano Zampini } 34496947451fSStefano Zampini 3450d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A, PetscInt col, Vec *v) 3451d71ae5a4SJacob Faibussowitsch { 34526947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34536947451fSStefano Zampini 34546947451fSStefano Zampini PetscFunctionBegin; 345528b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 345628b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 34574186a4bbSPierre Jolivet VecCheckAssembled(a->cvec); 34586947451fSStefano Zampini a->vecinuse = 0; 34599566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, (PetscScalar **)&a->ptrinuse)); 34609566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 346175f6d85dSStefano Zampini if (v) *v = NULL; 34623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34636947451fSStefano Zampini } 34646947451fSStefano Zampini 3465d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v) 3466d71ae5a4SJacob Faibussowitsch { 34676947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34686947451fSStefano Zampini 34696947451fSStefano Zampini PetscFunctionBegin; 347028b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 347128b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3472d16ceb75SStefano Zampini if (!a->cvec) PetscCall(MatDenseCreateColumnVec_Private(A, &a->cvec)); 34736947451fSStefano Zampini a->vecinuse = col + 1; 34749566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &a->ptrinuse)); 34758e3a54c0SPierre Jolivet PetscCall(VecPlaceArray(a->cvec, PetscSafePointerPlusOffset(a->ptrinuse, (size_t)col * (size_t)a->lda))); 34769566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(a->cvec)); 34776947451fSStefano Zampini *v = a->cvec; 34783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34796947451fSStefano Zampini } 34806947451fSStefano Zampini 3481d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v) 3482d71ae5a4SJacob Faibussowitsch { 34836947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34846947451fSStefano Zampini 34856947451fSStefano Zampini PetscFunctionBegin; 348628b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 348728b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 34884186a4bbSPierre Jolivet VecCheckAssembled(a->cvec); 34896947451fSStefano Zampini a->vecinuse = 0; 34909566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &a->ptrinuse)); 34919566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(a->cvec)); 34929566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 349375f6d85dSStefano Zampini if (v) *v = NULL; 34943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34956947451fSStefano Zampini } 34966947451fSStefano Zampini 3497d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v) 3498d71ae5a4SJacob Faibussowitsch { 34996947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35006947451fSStefano Zampini 35016947451fSStefano Zampini PetscFunctionBegin; 350228b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 350328b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3504d16ceb75SStefano Zampini if (!a->cvec) PetscCall(MatDenseCreateColumnVec_Private(A, &a->cvec)); 35056947451fSStefano Zampini a->vecinuse = col + 1; 35069566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(A, (PetscScalar **)&a->ptrinuse)); 35078e3a54c0SPierre Jolivet PetscCall(VecPlaceArray(a->cvec, PetscSafePointerPlusOffset(a->ptrinuse, (size_t)col * (size_t)a->lda))); 35086947451fSStefano Zampini *v = a->cvec; 35093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35106947451fSStefano Zampini } 35116947451fSStefano Zampini 3512d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v) 3513d71ae5a4SJacob Faibussowitsch { 35146947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35156947451fSStefano Zampini 35166947451fSStefano Zampini PetscFunctionBegin; 351728b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 351828b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 35194186a4bbSPierre Jolivet VecCheckAssembled(a->cvec); 35206947451fSStefano Zampini a->vecinuse = 0; 35219566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(A, (PetscScalar **)&a->ptrinuse)); 35229566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 352375f6d85dSStefano Zampini if (v) *v = NULL; 35243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35256947451fSStefano Zampini } 35266947451fSStefano Zampini 3527d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) 3528d71ae5a4SJacob Faibussowitsch { 35295ea7661aSPierre Jolivet Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35305ea7661aSPierre Jolivet 35315ea7661aSPierre Jolivet PetscFunctionBegin; 353228b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 353328b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3534a2748737SPierre Jolivet if (a->cmat && (cend - cbegin != a->cmat->cmap->N || rend - rbegin != a->cmat->rmap->N)) PetscCall(MatDestroy(&a->cmat)); 35355ea7661aSPierre Jolivet if (!a->cmat) { 35368e3a54c0SPierre 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)); 35375ea7661aSPierre Jolivet } else { 35388e3a54c0SPierre Jolivet PetscCall(MatDensePlaceArray(a->cmat, PetscSafePointerPlusOffset(a->v, rbegin + (size_t)cbegin * a->lda))); 35395ea7661aSPierre Jolivet } 35409566063dSJacob Faibussowitsch PetscCall(MatDenseSetLDA(a->cmat, a->lda)); 35415ea7661aSPierre Jolivet a->matinuse = cbegin + 1; 35425ea7661aSPierre Jolivet *v = a->cmat; 354347d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 354475f6d85dSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 354575f6d85dSStefano Zampini #endif 35463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35475ea7661aSPierre Jolivet } 35485ea7661aSPierre Jolivet 3549d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A, Mat *v) 3550d71ae5a4SJacob Faibussowitsch { 35515ea7661aSPierre Jolivet Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35525ea7661aSPierre Jolivet 35535ea7661aSPierre Jolivet PetscFunctionBegin; 355428b400f6SJacob Faibussowitsch PetscCheck(a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetSubMatrix() first"); 355528b400f6SJacob Faibussowitsch PetscCheck(a->cmat, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column matrix"); 355608401ef6SPierre Jolivet PetscCheck(*v == a->cmat, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not the matrix obtained from MatDenseGetSubMatrix()"); 35575ea7661aSPierre Jolivet a->matinuse = 0; 35589566063dSJacob Faibussowitsch PetscCall(MatDenseResetArray(a->cmat)); 3559742765d3SMatthew Knepley if (v) *v = NULL; 356047d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 35613faff063SStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 35623faff063SStefano Zampini #endif 35633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35645ea7661aSPierre Jolivet } 35655ea7661aSPierre Jolivet 35660bad9183SKris Buschelman /*MC 3567fafad747SKris Buschelman MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices. 35680bad9183SKris Buschelman 35692ef1f0ffSBarry Smith Options Database Key: 357011a5261eSBarry Smith . -mat_type seqdense - sets the matrix type to `MATSEQDENSE` during a call to `MatSetFromOptions()` 35710bad9183SKris Buschelman 35720bad9183SKris Buschelman Level: beginner 35730bad9183SKris Buschelman 35741cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreateSeqDense()` 35750bad9183SKris Buschelman M*/ 3576d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreate_SeqDense(Mat B) 3577d71ae5a4SJacob Faibussowitsch { 3578273d9f13SBarry Smith Mat_SeqDense *b; 35797c334f02SBarry Smith PetscMPIInt size; 3580273d9f13SBarry Smith 3581273d9f13SBarry Smith PetscFunctionBegin; 35829566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)B), &size)); 358308401ef6SPierre Jolivet PetscCheck(size <= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Comm must be of size 1"); 358455659b69SBarry Smith 35854dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&b)); 358644cd7ae7SLois Curfman McInnes B->data = (void *)b; 3587aea10558SJacob Faibussowitsch B->ops[0] = MatOps_Values; 358818f449edSLois Curfman McInnes 3589273d9f13SBarry Smith b->roworiented = PETSC_TRUE; 35904e220ebcSLois Curfman McInnes 35919566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatQRFactor_C", MatQRFactor_SeqDense)); 35929566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetLDA_C", MatDenseGetLDA_SeqDense)); 35939566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseSetLDA_C", MatDenseSetLDA_SeqDense)); 35949566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArray_C", MatDenseGetArray_SeqDense)); 35959566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArray_C", MatDenseRestoreArray_SeqDense)); 35969566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDensePlaceArray_C", MatDensePlaceArray_SeqDense)); 35979566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseResetArray_C", MatDenseResetArray_SeqDense)); 35989566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseReplaceArray_C", MatDenseReplaceArray_SeqDense)); 35999566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayRead_C", MatDenseGetArray_SeqDense)); 36009566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayRead_C", MatDenseRestoreArray_SeqDense)); 36019566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayWrite_C", MatDenseGetArray_SeqDense)); 36029566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayWrite_C", MatDenseRestoreArray_SeqDense)); 36039566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqaij_C", MatConvert_SeqDense_SeqAIJ)); 36048baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 36059566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_elemental_C", MatConvert_SeqDense_Elemental)); 36068baccfbdSHong Zhang #endif 3607d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 36089566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_scalapack_C", MatConvert_Dense_ScaLAPACK)); 3609d24d4204SJose E. Roman #endif 36102bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA) 36119566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensecuda_C", MatConvert_SeqDense_SeqDenseCUDA)); 36129566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", MatProductSetFromOptions_SeqDense)); 36139566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdense_C", MatProductSetFromOptions_SeqDense)); 36149566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensecuda_C", MatProductSetFromOptions_SeqDense)); 36152bf066beSStefano Zampini #endif 361647d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 361747d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensehip_C", MatConvert_SeqDense_SeqDenseHIP)); 361847d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensehip_seqdensehip_C", MatProductSetFromOptions_SeqDense)); 361947d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensehip_seqdense_C", MatProductSetFromOptions_SeqDense)); 362047d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensehip_C", MatProductSetFromOptions_SeqDense)); 362147d993e7Ssuyashtn #endif 36229566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSeqDenseSetPreallocation_C", MatSeqDenseSetPreallocation_SeqDense)); 36239566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqaij_seqdense_C", MatProductSetFromOptions_SeqAIJ_SeqDense)); 36249566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdense_C", MatProductSetFromOptions_SeqDense)); 36259566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense)); 36269566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqsbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense)); 362796e6d5c4SRichard Tran Mills 36289566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumn_C", MatDenseGetColumn_SeqDense)); 36299566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumn_C", MatDenseRestoreColumn_SeqDense)); 36309566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVec_C", MatDenseGetColumnVec_SeqDense)); 36319566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVec_C", MatDenseRestoreColumnVec_SeqDense)); 36329566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecRead_C", MatDenseGetColumnVecRead_SeqDense)); 36339566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecRead_C", MatDenseRestoreColumnVecRead_SeqDense)); 36349566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecWrite_C", MatDenseGetColumnVecWrite_SeqDense)); 36359566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecWrite_C", MatDenseRestoreColumnVecWrite_SeqDense)); 36369566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetSubMatrix_C", MatDenseGetSubMatrix_SeqDense)); 36379566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreSubMatrix_C", MatDenseRestoreSubMatrix_SeqDense)); 36380be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatMultAddColumnRange_C", MatMultAddColumnRange_SeqDense)); 36390be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatMultHermitianTransposeColumnRange_C", MatMultHermitianTransposeColumnRange_SeqDense)); 36400be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatMultHermitianTransposeAddColumnRange_C", MatMultHermitianTransposeAddColumnRange_SeqDense)); 36419566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)B, MATSEQDENSE)); 36423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3643289bc588SBarry Smith } 364486aefd0dSHong Zhang 364586aefd0dSHong Zhang /*@C 364611a5261eSBarry 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. 364786aefd0dSHong Zhang 364886aefd0dSHong Zhang Not Collective 364986aefd0dSHong Zhang 36505ea7661aSPierre Jolivet Input Parameters: 3651fe59aa6dSJacob Faibussowitsch + A - a `MATSEQDENSE` or `MATMPIDENSE` matrix 365286aefd0dSHong Zhang - col - column index 365386aefd0dSHong Zhang 365486aefd0dSHong Zhang Output Parameter: 365586aefd0dSHong Zhang . vals - pointer to the data 365686aefd0dSHong Zhang 365786aefd0dSHong Zhang Level: intermediate 365886aefd0dSHong Zhang 365911a5261eSBarry Smith Note: 366011a5261eSBarry Smith Use `MatDenseGetColumnVec()` to get access to a column of a `MATDENSE` treated as a `Vec` 366111a5261eSBarry Smith 36621cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreColumn()`, `MatDenseGetColumnVec()` 366386aefd0dSHong Zhang @*/ 36645d83a8b1SBarry Smith PetscErrorCode MatDenseGetColumn(Mat A, PetscInt col, PetscScalar *vals[]) 3665d71ae5a4SJacob Faibussowitsch { 366686aefd0dSHong Zhang PetscFunctionBegin; 3667d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3668d5ea218eSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 36694f572ea9SToby Isaac PetscAssertPointer(vals, 3); 3670cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumn_C", (Mat, PetscInt, PetscScalar **), (A, col, vals)); 36713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 367286aefd0dSHong Zhang } 367386aefd0dSHong Zhang 367486aefd0dSHong Zhang /*@C 367511a5261eSBarry Smith MatDenseRestoreColumn - returns access to a column of a `MATDENSE` matrix which is returned by `MatDenseGetColumn()`. 367686aefd0dSHong Zhang 367786aefd0dSHong Zhang Not Collective 367886aefd0dSHong Zhang 3679742765d3SMatthew Knepley Input Parameters: 3680fe59aa6dSJacob Faibussowitsch + A - a `MATSEQDENSE` or `MATMPIDENSE` matrix 36812ef1f0ffSBarry Smith - vals - pointer to the data (may be `NULL`) 368286aefd0dSHong Zhang 368386aefd0dSHong Zhang Level: intermediate 368486aefd0dSHong Zhang 36851cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetColumn()` 368686aefd0dSHong Zhang @*/ 36875d83a8b1SBarry Smith PetscErrorCode MatDenseRestoreColumn(Mat A, PetscScalar *vals[]) 3688d71ae5a4SJacob Faibussowitsch { 368986aefd0dSHong Zhang PetscFunctionBegin; 3690d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 36914f572ea9SToby Isaac PetscAssertPointer(vals, 2); 3692cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumn_C", (Mat, PetscScalar **), (A, vals)); 36933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 369486aefd0dSHong Zhang } 36956947451fSStefano Zampini 36960f74d2c1SSatish Balay /*@ 369711a5261eSBarry Smith MatDenseGetColumnVec - Gives read-write access to a column of a `MATDENSE` matrix, represented as a `Vec`. 36986947451fSStefano Zampini 36996947451fSStefano Zampini Collective 37006947451fSStefano Zampini 37015ea7661aSPierre Jolivet Input Parameters: 3702fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 37036947451fSStefano Zampini - col - the column index 37046947451fSStefano Zampini 37056947451fSStefano Zampini Output Parameter: 37066947451fSStefano Zampini . v - the vector 37076947451fSStefano Zampini 37082ef1f0ffSBarry Smith Level: intermediate 37092ef1f0ffSBarry Smith 37106947451fSStefano Zampini Notes: 371111a5261eSBarry Smith The vector is owned by PETSc. Users need to call `MatDenseRestoreColumnVec()` when the vector is no longer needed. 371211a5261eSBarry Smith 371311a5261eSBarry Smith Use `MatDenseGetColumnVecRead()` to obtain read-only access or `MatDenseGetColumnVecWrite()` for write-only access. 37146947451fSStefano Zampini 37151cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`, `MatDenseGetColumn()` 37166947451fSStefano Zampini @*/ 3717d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec(Mat A, PetscInt col, Vec *v) 3718d71ae5a4SJacob Faibussowitsch { 37196947451fSStefano Zampini PetscFunctionBegin; 37206947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 37216947451fSStefano Zampini PetscValidType(A, 1); 37226947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 37234f572ea9SToby Isaac PetscAssertPointer(v, 3); 372428b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 37252cf15c64SPierre 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); 3726cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v)); 37273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37286947451fSStefano Zampini } 37296947451fSStefano Zampini 37300f74d2c1SSatish Balay /*@ 3731fb850c59SBarry Smith MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from `MatDenseGetColumnVec()`. 37326947451fSStefano Zampini 37336947451fSStefano Zampini Collective 37346947451fSStefano Zampini 37355ea7661aSPierre Jolivet Input Parameters: 3736fb850c59SBarry Smith + A - the `Mat` object 37376947451fSStefano Zampini . col - the column index 3738fb850c59SBarry Smith - v - the `Vec` object (may be `NULL`) 37396947451fSStefano Zampini 37406947451fSStefano Zampini Level: intermediate 37416947451fSStefano Zampini 37421cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 37436947451fSStefano Zampini @*/ 3744d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec(Mat A, PetscInt col, Vec *v) 3745d71ae5a4SJacob Faibussowitsch { 37466947451fSStefano Zampini PetscFunctionBegin; 37476947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 37486947451fSStefano Zampini PetscValidType(A, 1); 37496947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 375008401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 37512cf15c64SPierre 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); 3752cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v)); 37533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37546947451fSStefano Zampini } 37556947451fSStefano Zampini 37560f74d2c1SSatish Balay /*@ 3757fb850c59SBarry Smith MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a `Vec`. 37586947451fSStefano Zampini 37596947451fSStefano Zampini Collective 37606947451fSStefano Zampini 37615ea7661aSPierre Jolivet Input Parameters: 3762fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 37636947451fSStefano Zampini - col - the column index 37646947451fSStefano Zampini 37656947451fSStefano Zampini Output Parameter: 37666947451fSStefano Zampini . v - the vector 37676947451fSStefano Zampini 37682ef1f0ffSBarry Smith Level: intermediate 37692ef1f0ffSBarry Smith 37706947451fSStefano Zampini Notes: 37716947451fSStefano Zampini The vector is owned by PETSc and users cannot modify it. 377211a5261eSBarry Smith 37732ef1f0ffSBarry Smith Users need to call `MatDenseRestoreColumnVecRead()` when the vector is no longer needed. 377411a5261eSBarry Smith 37752ef1f0ffSBarry Smith Use `MatDenseGetColumnVec()` to obtain read-write access or `MatDenseGetColumnVecWrite()` for write-only access. 37766947451fSStefano Zampini 37771cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 37786947451fSStefano Zampini @*/ 3779d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead(Mat A, PetscInt col, Vec *v) 3780d71ae5a4SJacob Faibussowitsch { 37816947451fSStefano Zampini PetscFunctionBegin; 37826947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 37836947451fSStefano Zampini PetscValidType(A, 1); 37846947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 37854f572ea9SToby Isaac PetscAssertPointer(v, 3); 378628b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 37872cf15c64SPierre 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); 3788cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v)); 37893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37906947451fSStefano Zampini } 37916947451fSStefano Zampini 37920f74d2c1SSatish Balay /*@ 3793fb850c59SBarry Smith MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from `MatDenseGetColumnVecRead()`. 37946947451fSStefano Zampini 37956947451fSStefano Zampini Collective 37966947451fSStefano Zampini 37975ea7661aSPierre Jolivet Input Parameters: 3798fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 37996947451fSStefano Zampini . col - the column index 3800fb850c59SBarry Smith - v - the `Vec` object (may be `NULL`) 38016947451fSStefano Zampini 38026947451fSStefano Zampini Level: intermediate 38036947451fSStefano Zampini 38041cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecWrite()` 38056947451fSStefano Zampini @*/ 3806d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead(Mat A, PetscInt col, Vec *v) 3807d71ae5a4SJacob Faibussowitsch { 38086947451fSStefano Zampini PetscFunctionBegin; 38096947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38106947451fSStefano Zampini PetscValidType(A, 1); 38116947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 381208401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 38132cf15c64SPierre 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); 3814cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v)); 38153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38166947451fSStefano Zampini } 38176947451fSStefano Zampini 38180f74d2c1SSatish Balay /*@ 3819fb850c59SBarry Smith MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a `Vec`. 38206947451fSStefano Zampini 38216947451fSStefano Zampini Collective 38226947451fSStefano Zampini 38235ea7661aSPierre Jolivet Input Parameters: 3824fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 38256947451fSStefano Zampini - col - the column index 38266947451fSStefano Zampini 38276947451fSStefano Zampini Output Parameter: 38286947451fSStefano Zampini . v - the vector 38296947451fSStefano Zampini 38306947451fSStefano Zampini Level: intermediate 38316947451fSStefano Zampini 38322ef1f0ffSBarry Smith Notes: 38332ef1f0ffSBarry Smith The vector is owned by PETSc. Users need to call `MatDenseRestoreColumnVecWrite()` when the vector is no longer needed. 38342ef1f0ffSBarry Smith 38352ef1f0ffSBarry Smith Use `MatDenseGetColumnVec()` to obtain read-write access or `MatDenseGetColumnVecRead()` for read-only access. 38362ef1f0ffSBarry Smith 38371cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 38386947451fSStefano Zampini @*/ 3839d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite(Mat A, PetscInt col, Vec *v) 3840d71ae5a4SJacob Faibussowitsch { 38416947451fSStefano Zampini PetscFunctionBegin; 38426947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38436947451fSStefano Zampini PetscValidType(A, 1); 38446947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 38454f572ea9SToby Isaac PetscAssertPointer(v, 3); 384628b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3847aed4548fSBarry 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); 3848cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v)); 38493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38506947451fSStefano Zampini } 38516947451fSStefano Zampini 38520f74d2c1SSatish Balay /*@ 3853fb850c59SBarry Smith MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from `MatDenseGetColumnVecWrite()`. 38546947451fSStefano Zampini 38556947451fSStefano Zampini Collective 38566947451fSStefano Zampini 38575ea7661aSPierre Jolivet Input Parameters: 3858fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 38596947451fSStefano Zampini . col - the column index 38602ef1f0ffSBarry Smith - v - the `Vec` object (may be `NULL`) 38616947451fSStefano Zampini 38626947451fSStefano Zampini Level: intermediate 38636947451fSStefano Zampini 38641cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()` 38656947451fSStefano Zampini @*/ 3866d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A, PetscInt col, Vec *v) 3867d71ae5a4SJacob Faibussowitsch { 38686947451fSStefano Zampini PetscFunctionBegin; 38696947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38706947451fSStefano Zampini PetscValidType(A, 1); 38716947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 387208401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3873aed4548fSBarry 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); 3874cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v)); 38753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38766947451fSStefano Zampini } 38775ea7661aSPierre Jolivet 38780f74d2c1SSatish Balay /*@ 3879fb850c59SBarry Smith MatDenseGetSubMatrix - Gives access to a block of rows and columns of a dense matrix, represented as a `Mat`. 38805ea7661aSPierre Jolivet 38815ea7661aSPierre Jolivet Collective 38825ea7661aSPierre Jolivet 38835ea7661aSPierre Jolivet Input Parameters: 3884fb850c59SBarry Smith + A - the `Mat` object 38852ef1f0ffSBarry Smith . rbegin - the first global row index in the block (if `PETSC_DECIDE`, is 0) 38862ef1f0ffSBarry Smith . rend - the global row index past the last one in the block (if `PETSC_DECIDE`, is `M`) 38872ef1f0ffSBarry Smith . cbegin - the first global column index in the block (if `PETSC_DECIDE`, is 0) 38882ef1f0ffSBarry Smith - cend - the global column index past the last one in the block (if `PETSC_DECIDE`, is `N`) 38895ea7661aSPierre Jolivet 38905ea7661aSPierre Jolivet Output Parameter: 38915ea7661aSPierre Jolivet . v - the matrix 38925ea7661aSPierre Jolivet 38935ea7661aSPierre Jolivet Level: intermediate 38945ea7661aSPierre Jolivet 38952ef1f0ffSBarry Smith Notes: 38962ef1f0ffSBarry Smith The matrix is owned by PETSc. Users need to call `MatDenseRestoreSubMatrix()` when the matrix is no longer needed. 38972ef1f0ffSBarry Smith 38982ef1f0ffSBarry 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. 38992ef1f0ffSBarry Smith 39001cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreSubMatrix()` 39015ea7661aSPierre Jolivet @*/ 3902d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) 3903d71ae5a4SJacob Faibussowitsch { 39045ea7661aSPierre Jolivet PetscFunctionBegin; 39055ea7661aSPierre Jolivet PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 39065ea7661aSPierre Jolivet PetscValidType(A, 1); 3907a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, rbegin, 2); 3908a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, rend, 3); 3909a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, cbegin, 4); 3910a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, cend, 5); 39114f572ea9SToby Isaac PetscAssertPointer(v, 6); 3912a2748737SPierre Jolivet if (rbegin == PETSC_DECIDE) rbegin = 0; 3913a2748737SPierre Jolivet if (rend == PETSC_DECIDE) rend = A->rmap->N; 3914a2748737SPierre Jolivet if (cbegin == PETSC_DECIDE) cbegin = 0; 3915a2748737SPierre Jolivet if (cend == PETSC_DECIDE) cend = A->cmap->N; 391628b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3917a2748737SPierre 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); 3918a2748737SPierre 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); 3919a2748737SPierre 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); 3920a2748737SPierre 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); 3921a2748737SPierre Jolivet PetscUseMethod(A, "MatDenseGetSubMatrix_C", (Mat, PetscInt, PetscInt, PetscInt, PetscInt, Mat *), (A, rbegin, rend, cbegin, cend, v)); 39223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 39235ea7661aSPierre Jolivet } 39245ea7661aSPierre Jolivet 39250f74d2c1SSatish Balay /*@ 3926fb850c59SBarry Smith MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from `MatDenseGetSubMatrix()`. 39275ea7661aSPierre Jolivet 39285ea7661aSPierre Jolivet Collective 39295ea7661aSPierre Jolivet 39305ea7661aSPierre Jolivet Input Parameters: 3931fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 39322ef1f0ffSBarry Smith - v - the `Mat` object (may be `NULL`) 39335ea7661aSPierre Jolivet 39345ea7661aSPierre Jolivet Level: intermediate 39355ea7661aSPierre Jolivet 39361cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseGetSubMatrix()` 39375ea7661aSPierre Jolivet @*/ 3938d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix(Mat A, Mat *v) 3939d71ae5a4SJacob Faibussowitsch { 39405ea7661aSPierre Jolivet PetscFunctionBegin; 39415ea7661aSPierre Jolivet PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 39425ea7661aSPierre Jolivet PetscValidType(A, 1); 39434f572ea9SToby Isaac PetscAssertPointer(v, 2); 3944cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreSubMatrix_C", (Mat, Mat *), (A, v)); 39453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 39465ea7661aSPierre Jolivet } 39478a9c020eSBarry Smith 39488a9c020eSBarry Smith #include <petscblaslapack.h> 39498a9c020eSBarry Smith #include <petsc/private/kernels/blockinvert.h> 39508a9c020eSBarry Smith 3951d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseInvert(Mat A) 3952d71ae5a4SJacob Faibussowitsch { 3953d63b1753SJacob Faibussowitsch PetscInt m; 39548a9c020eSBarry Smith const PetscReal shift = 0.0; 3955d63b1753SJacob Faibussowitsch PetscBool allowzeropivot, zeropivotdetected = PETSC_FALSE; 3956d63b1753SJacob Faibussowitsch PetscScalar *values; 39578a9c020eSBarry Smith 39588a9c020eSBarry Smith PetscFunctionBegin; 3959d63b1753SJacob Faibussowitsch PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3960d63b1753SJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &values)); 3961d63b1753SJacob Faibussowitsch PetscCall(MatGetLocalSize(A, &m, NULL)); 3962d63b1753SJacob Faibussowitsch allowzeropivot = PetscNot(A->erroriffailure); 39638a9c020eSBarry Smith /* factor and invert each block */ 3964d63b1753SJacob Faibussowitsch switch (m) { 3965d71ae5a4SJacob Faibussowitsch case 1: 3966d71ae5a4SJacob Faibussowitsch values[0] = (PetscScalar)1.0 / (values[0] + shift); 3967d71ae5a4SJacob Faibussowitsch break; 39688a9c020eSBarry Smith case 2: 39698a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_2(values, shift, allowzeropivot, &zeropivotdetected)); 39708a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39718a9c020eSBarry Smith break; 39728a9c020eSBarry Smith case 3: 39738a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_3(values, shift, allowzeropivot, &zeropivotdetected)); 39748a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39758a9c020eSBarry Smith break; 39768a9c020eSBarry Smith case 4: 39778a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_4(values, shift, allowzeropivot, &zeropivotdetected)); 39788a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39798a9c020eSBarry Smith break; 39809371c9d4SSatish Balay case 5: { 39818a9c020eSBarry Smith PetscScalar work[25]; 39828a9c020eSBarry Smith PetscInt ipvt[5]; 39838a9c020eSBarry Smith 39848a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_5(values, ipvt, work, shift, allowzeropivot, &zeropivotdetected)); 39858a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39869371c9d4SSatish Balay } break; 39878a9c020eSBarry Smith case 6: 39888a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_6(values, shift, allowzeropivot, &zeropivotdetected)); 39898a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39908a9c020eSBarry Smith break; 39918a9c020eSBarry Smith case 7: 39928a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_7(values, shift, allowzeropivot, &zeropivotdetected)); 39938a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39948a9c020eSBarry Smith break; 39959371c9d4SSatish Balay default: { 39968a9c020eSBarry Smith PetscInt *v_pivots, *IJ, j; 39978a9c020eSBarry Smith PetscScalar *v_work; 39988a9c020eSBarry Smith 3999d63b1753SJacob Faibussowitsch PetscCall(PetscMalloc3(m, &v_work, m, &v_pivots, m, &IJ)); 4000d63b1753SJacob Faibussowitsch for (j = 0; j < m; j++) IJ[j] = j; 4001d63b1753SJacob Faibussowitsch PetscCall(PetscKernel_A_gets_inverse_A(m, values, v_pivots, v_work, allowzeropivot, &zeropivotdetected)); 40028a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 40038a9c020eSBarry Smith PetscCall(PetscFree3(v_work, v_pivots, IJ)); 40048a9c020eSBarry Smith } 40058a9c020eSBarry Smith } 4006d63b1753SJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &values)); 40073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 40088a9c020eSBarry Smith } 4009