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.*/ 79097b17b2cSPierre Jolivet PetscErrorCode MatLUFactor_SeqDense(Mat A, IS row, IS col, PETSC_UNUSED 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 82097b17b2cSPierre Jolivet static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info) 821d71ae5a4SJacob Faibussowitsch { 8224396437dSToby Isaac PetscFunctionBegin; 8239566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 82497b17b2cSPierre Jolivet PetscUseTypeMethod(fact, lufactor, NULL, NULL, info); 8253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8264396437dSToby Isaac } 8274396437dSToby Isaac 82897b17b2cSPierre Jolivet PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, IS col, PETSC_UNUSED const MatFactorInfo *info) 829d71ae5a4SJacob Faibussowitsch { 8304396437dSToby Isaac PetscFunctionBegin; 8314396437dSToby Isaac fact->preallocated = PETSC_TRUE; 8324396437dSToby Isaac fact->assembled = PETSC_TRUE; 8334396437dSToby Isaac fact->ops->lufactornumeric = MatLUFactorNumeric_SeqDense; 8343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8354396437dSToby Isaac } 8364396437dSToby Isaac 837a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */ 83897b17b2cSPierre Jolivet PetscErrorCode MatCholeskyFactor_SeqDense(Mat A, IS perm, PETSC_UNUSED const MatFactorInfo *minfo) 839d71ae5a4SJacob Faibussowitsch { 840db4efbfdSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 841c5df96a5SBarry Smith PetscBLASInt info, n; 842db4efbfdSBarry Smith 843db4efbfdSBarry Smith PetscFunctionBegin; 8449566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 8453ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 846b94d7dedSBarry Smith if (A->spd == PETSC_BOOL3_TRUE) { 8479566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 848792fecdfSBarry Smith PetscCallBLAS("LAPACKpotrf", LAPACKpotrf_("L", &n, mat->v, &mat->lda, &info)); 8499566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 850a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX) 851b94d7dedSBarry Smith } else if (A->hermitian == PETSC_BOOL3_TRUE) { 852789736e1SBarry Smith if (!mat->pivots) PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); 853a49dc2a2SStefano Zampini if (!mat->fwork) { 854a49dc2a2SStefano Zampini PetscScalar dummy; 855a49dc2a2SStefano Zampini 856a49dc2a2SStefano Zampini mat->lfwork = -1; 8579566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 858792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info)); 8599566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 86007c83e99SJose E. Roman PetscCall(PetscBLASIntCast((PetscCount)(PetscRealPart(dummy)), &mat->lfwork)); 8619566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 862a49dc2a2SStefano Zampini } 8639566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 864792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info)); 8659566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 866a49dc2a2SStefano Zampini #endif 867a49dc2a2SStefano Zampini } else { /* symmetric case */ 868789736e1SBarry Smith if (!mat->pivots) PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); 869a49dc2a2SStefano Zampini if (!mat->fwork) { 870a49dc2a2SStefano Zampini PetscScalar dummy; 871a49dc2a2SStefano Zampini 872a49dc2a2SStefano Zampini mat->lfwork = -1; 8739566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 874792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info)); 8759566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 8766497c311SBarry Smith PetscCall(PetscBLASIntCast((PetscCount)(PetscRealPart(dummy)), &mat->lfwork)); 8779566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 878a49dc2a2SStefano Zampini } 8799566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 880792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info)); 8819566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 882a49dc2a2SStefano Zampini } 883835f2295SStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad factorization: zero pivot in row %" PetscBLASInt_FMT, info - 1); 8848208b9aeSStefano Zampini 8854396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_Cholesky; 8864396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_Cholesky; 8874396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_Cholesky; 8884396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_Cholesky; 889d5f3da31SBarry Smith A->factortype = MAT_FACTOR_CHOLESKY; 8902205254eSKarl Rupp 8919566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 8929566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 893f6224b95SHong Zhang 8949566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0)); 8953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 896db4efbfdSBarry Smith } 897db4efbfdSBarry Smith 89897b17b2cSPierre Jolivet static PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info) 899d71ae5a4SJacob Faibussowitsch { 900db4efbfdSBarry Smith PetscFunctionBegin; 9019566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 90297b17b2cSPierre Jolivet PetscUseTypeMethod(fact, choleskyfactor, NULL, info); 9033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 904db4efbfdSBarry Smith } 905db4efbfdSBarry Smith 906d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info) 907d71ae5a4SJacob Faibussowitsch { 908db4efbfdSBarry Smith PetscFunctionBegin; 909c3ef05f6SHong Zhang fact->assembled = PETSC_TRUE; 9101bbcc794SSatish Balay fact->preallocated = PETSC_TRUE; 911719d5645SBarry Smith fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense; 9123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 913db4efbfdSBarry Smith } 914db4efbfdSBarry Smith 91597b17b2cSPierre Jolivet PetscErrorCode MatQRFactor_SeqDense(Mat A, IS col, PETSC_UNUSED const MatFactorInfo *minfo) 916d71ae5a4SJacob Faibussowitsch { 9174905a7bcSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 9184905a7bcSToby Isaac PetscBLASInt n, m, info, min, max; 9194905a7bcSToby Isaac 9204905a7bcSToby Isaac PetscFunctionBegin; 9219566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 9229566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 9234396437dSToby Isaac max = PetscMax(m, n); 9244396437dSToby Isaac min = PetscMin(m, n); 925789736e1SBarry Smith if (!mat->tau) PetscCall(PetscMalloc1(min, &mat->tau)); 926789736e1SBarry Smith if (!mat->pivots) PetscCall(PetscMalloc1(n, &mat->pivots)); 927f4f49eeaSPierre Jolivet if (!mat->qrrhs) PetscCall(MatCreateVecs(A, NULL, &mat->qrrhs)); 9283ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 9294905a7bcSToby Isaac if (!mat->fwork) { 9304905a7bcSToby Isaac PetscScalar dummy; 9314905a7bcSToby Isaac 9324905a7bcSToby Isaac mat->lfwork = -1; 9339566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 934792fecdfSBarry Smith PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, &dummy, &mat->lfwork, &info)); 9359566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 9366497c311SBarry Smith PetscCall(PetscBLASIntCast((PetscCount)(PetscRealPart(dummy)), &mat->lfwork)); 9379566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 9384905a7bcSToby Isaac } 9399566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 940792fecdfSBarry Smith PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, mat->fwork, &mat->lfwork, &info)); 9419566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 942835f2295SStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to QR factorization %" PetscBLASInt_FMT, info); 9434905a7bcSToby 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 9444905a7bcSToby Isaac mat->rank = min; 9454905a7bcSToby Isaac 9464396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_QR; 9474396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_QR; 9484905a7bcSToby Isaac A->factortype = MAT_FACTOR_QR; 9494905a7bcSToby Isaac if (m == n) { 9504396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_QR; 9514396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_QR; 9524905a7bcSToby Isaac } 9534905a7bcSToby Isaac 9549566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 9559566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 9564905a7bcSToby Isaac 9579566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * min * min * (max - min / 3.0))); 9583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9594905a7bcSToby Isaac } 9604905a7bcSToby Isaac 96197b17b2cSPierre Jolivet static PetscErrorCode MatQRFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info) 962d71ae5a4SJacob Faibussowitsch { 9634905a7bcSToby Isaac PetscFunctionBegin; 9649566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 96597b17b2cSPierre Jolivet PetscUseMethod(fact, "MatQRFactor_C", (Mat, IS, const MatFactorInfo *), (fact, NULL, info)); 9663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9674905a7bcSToby Isaac } 9684905a7bcSToby Isaac 969d71ae5a4SJacob Faibussowitsch PetscErrorCode MatQRFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info) 970d71ae5a4SJacob Faibussowitsch { 9714905a7bcSToby Isaac PetscFunctionBegin; 9724905a7bcSToby Isaac fact->assembled = PETSC_TRUE; 9734905a7bcSToby Isaac fact->preallocated = PETSC_TRUE; 9749566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)fact, "MatQRFactorNumeric_C", MatQRFactorNumeric_SeqDense)); 9753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9764905a7bcSToby Isaac } 9774905a7bcSToby Isaac 978ca15aa20SStefano Zampini /* uses LAPACK */ 979d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A, MatFactorType ftype, Mat *fact) 980d71ae5a4SJacob Faibussowitsch { 981db4efbfdSBarry Smith PetscFunctionBegin; 9829566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), fact)); 9839566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*fact, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n)); 9849566063dSJacob Faibussowitsch PetscCall(MatSetType(*fact, MATDENSE)); 98566e17bc3SBarry Smith (*fact)->trivialsymbolic = PETSC_TRUE; 9862a350339SBarry Smith if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU) { 987db4efbfdSBarry Smith (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense; 9882a350339SBarry Smith (*fact)->ops->ilufactorsymbolic = MatLUFactorSymbolic_SeqDense; 989bf5a80bcSToby Isaac } else if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) { 990db4efbfdSBarry Smith (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense; 991bf5a80bcSToby Isaac } else if (ftype == MAT_FACTOR_QR) { 992f4f49eeaSPierre Jolivet PetscCall(PetscObjectComposeFunction((PetscObject)*fact, "MatQRFactorSymbolic_C", MatQRFactorSymbolic_SeqDense)); 993db4efbfdSBarry Smith } 994d5f3da31SBarry Smith (*fact)->factortype = ftype; 99500c67f3bSHong Zhang 9969566063dSJacob Faibussowitsch PetscCall(PetscFree((*fact)->solvertype)); 9979566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &(*fact)->solvertype)); 9989566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_LU])); 9999566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ILU])); 10009566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_CHOLESKY])); 10019566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ICC])); 10023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1003db4efbfdSBarry Smith } 1004db4efbfdSBarry Smith 1005d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSOR_SeqDense(Mat A, Vec bb, PetscReal omega, MatSORType flag, PetscReal shift, PetscInt its, PetscInt lits, Vec xx) 1006d71ae5a4SJacob Faibussowitsch { 1007c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1008d9ca1df4SBarry Smith PetscScalar *x, *v = mat->v, zero = 0.0, xt; 1009d9ca1df4SBarry Smith const PetscScalar *b; 1010d0f46423SBarry Smith PetscInt m = A->rmap->n, i; 101123fff9afSBarry Smith PetscBLASInt o = 1, bm = 0; 1012289bc588SBarry Smith 10133a40ed3dSBarry Smith PetscFunctionBegin; 101447d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 101508401ef6SPierre Jolivet PetscCheck(A->offloadmask != PETSC_OFFLOAD_GPU, PETSC_COMM_SELF, PETSC_ERR_SUP, "Not implemented"); 1016ca15aa20SStefano Zampini #endif 1017422a814eSBarry Smith if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */ 10189566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(m, &bm)); 1019289bc588SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 10203bffc371SBarry Smith /* this is a hack fix, should have another version without the second BLASdotu */ 10219566063dSJacob Faibussowitsch PetscCall(VecSet(xx, zero)); 1022289bc588SBarry Smith } 10239566063dSJacob Faibussowitsch PetscCall(VecGetArray(xx, &x)); 10249566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(bb, &b)); 1025b965ef7fSBarry Smith its = its * lits; 102608401ef6SPierre 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); 1027289bc588SBarry Smith while (its--) { 1028fccaa45eSBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 1029289bc588SBarry Smith for (i = 0; i < m; i++) { 1030792fecdfSBarry Smith PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o)); 1031883424caSPierre Jolivet x[i] = (1. - omega) * x[i] + (xt + v[i + i * m] * x[i]) * omega / (v[i + i * m] + shift); 1032289bc588SBarry Smith } 1033289bc588SBarry Smith } 1034fccaa45eSBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 1035289bc588SBarry Smith for (i = m - 1; i >= 0; i--) { 1036792fecdfSBarry Smith PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o)); 1037883424caSPierre Jolivet x[i] = (1. - omega) * x[i] + (xt + v[i + i * m] * x[i]) * omega / (v[i + i * m] + shift); 1038289bc588SBarry Smith } 1039289bc588SBarry Smith } 1040289bc588SBarry Smith } 10419566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(bb, &b)); 10429566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(xx, &x)); 10433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1044289bc588SBarry Smith } 1045289bc588SBarry Smith 1046d016bddeSToby Isaac PETSC_INTERN PetscErrorCode MatMultColumnRangeKernel_SeqDense(Mat A, Vec xx, Vec yy, PetscInt c_start, PetscInt c_end, PetscBool trans, PetscBool herm) 1047d71ae5a4SJacob Faibussowitsch { 1048c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1049d9ca1df4SBarry Smith PetscScalar *y, _DOne = 1.0, _DZero = 0.0; 10500805154bSBarry Smith PetscBLASInt m, n, _One = 1; 1051d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 10523a40ed3dSBarry Smith 10533a40ed3dSBarry Smith PetscFunctionBegin; 10549566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 10550be0d8bdSHansol Suh PetscCall(PetscBLASIntCast(c_end - c_start, &n)); 10569566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 10579566063dSJacob Faibussowitsch PetscCall(VecGetArrayWrite(yy, &y)); 10580be0d8bdSHansol Suh if (!m || !n) { 10595ac36cfcSBarry Smith PetscBLASInt i; 1060459e8d23SBlanca Mellado Pinto if (trans) 1061459e8d23SBlanca Mellado Pinto for (i = 0; i < n; i++) y[i] = 0.0; 1062459e8d23SBlanca Mellado Pinto else 10635ac36cfcSBarry Smith for (i = 0; i < m; i++) y[i] = 0.0; 10645ac36cfcSBarry Smith } else { 1065459e8d23SBlanca Mellado Pinto if (trans) { 10660be0d8bdSHansol Suh if (herm) PetscCallBLAS("BLASgemv", BLASgemv_("C", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x, &_One, &_DZero, y + c_start, &_One)); 10670be0d8bdSHansol Suh else PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x, &_One, &_DZero, y + c_start, &_One)); 1068459e8d23SBlanca Mellado Pinto } else { 10690be0d8bdSHansol Suh PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x + c_start, &_One, &_DZero, y, &_One)); 1070459e8d23SBlanca Mellado Pinto } 10710be0d8bdSHansol Suh PetscCall(PetscLogFlops(2.0 * m * n - n)); 10725ac36cfcSBarry Smith } 10739566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 10749566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayWrite(yy, &y)); 10753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1076289bc588SBarry Smith } 10776ee01492SSatish Balay 10780be0d8bdSHansol Suh PetscErrorCode MatMultHermitianTransposeColumnRange_SeqDense(Mat A, Vec xx, Vec yy, PetscInt c_start, PetscInt c_end) 10790be0d8bdSHansol Suh { 10800be0d8bdSHansol Suh PetscFunctionBegin; 10810be0d8bdSHansol Suh PetscCall(MatMultColumnRangeKernel_SeqDense(A, xx, yy, c_start, c_end, PETSC_TRUE, PETSC_TRUE)); 10820be0d8bdSHansol Suh PetscFunctionReturn(PETSC_SUCCESS); 10830be0d8bdSHansol Suh } 10840be0d8bdSHansol Suh 1085459e8d23SBlanca Mellado Pinto PetscErrorCode MatMult_SeqDense(Mat A, Vec xx, Vec yy) 1086459e8d23SBlanca Mellado Pinto { 1087459e8d23SBlanca Mellado Pinto PetscFunctionBegin; 10880be0d8bdSHansol Suh PetscCall(MatMultColumnRangeKernel_SeqDense(A, xx, yy, 0, A->cmap->n, PETSC_FALSE, PETSC_FALSE)); 1089459e8d23SBlanca Mellado Pinto PetscFunctionReturn(PETSC_SUCCESS); 1090459e8d23SBlanca Mellado Pinto } 1091459e8d23SBlanca Mellado Pinto 1092459e8d23SBlanca Mellado Pinto PetscErrorCode MatMultTranspose_SeqDense(Mat A, Vec xx, Vec yy) 1093459e8d23SBlanca Mellado Pinto { 1094459e8d23SBlanca Mellado Pinto PetscFunctionBegin; 10950be0d8bdSHansol Suh PetscCall(MatMultColumnRangeKernel_SeqDense(A, xx, yy, 0, A->cmap->n, PETSC_TRUE, PETSC_FALSE)); 1096459e8d23SBlanca Mellado Pinto PetscFunctionReturn(PETSC_SUCCESS); 1097459e8d23SBlanca Mellado Pinto } 1098459e8d23SBlanca Mellado Pinto 1099459e8d23SBlanca Mellado Pinto PetscErrorCode MatMultHermitianTranspose_SeqDense(Mat A, Vec xx, Vec yy) 1100459e8d23SBlanca Mellado Pinto { 1101459e8d23SBlanca Mellado Pinto PetscFunctionBegin; 11020be0d8bdSHansol Suh PetscCall(MatMultColumnRangeKernel_SeqDense(A, xx, yy, 0, A->cmap->n, PETSC_TRUE, PETSC_TRUE)); 1103459e8d23SBlanca Mellado Pinto PetscFunctionReturn(PETSC_SUCCESS); 1104459e8d23SBlanca Mellado Pinto } 1105459e8d23SBlanca Mellado Pinto 1106d016bddeSToby Isaac PETSC_INTERN PetscErrorCode MatMultAddColumnRangeKernel_SeqDense(Mat A, Vec xx, Vec zz, Vec yy, PetscInt c_start, PetscInt c_end, PetscBool trans, PetscBool herm) 1107d71ae5a4SJacob Faibussowitsch { 1108c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1109d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 1110d9ca1df4SBarry Smith PetscScalar *y, _DOne = 1.0; 11110805154bSBarry Smith PetscBLASInt m, n, _One = 1; 11123a40ed3dSBarry Smith 11133a40ed3dSBarry Smith PetscFunctionBegin; 11149566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 11150be0d8bdSHansol Suh PetscCall(PetscBLASIntCast(c_end - c_start, &n)); 11169566063dSJacob Faibussowitsch PetscCall(VecCopy(zz, yy)); 11170be0d8bdSHansol Suh if (!m || !n) PetscFunctionReturn(PETSC_SUCCESS); 11189566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &y)); 1119459e8d23SBlanca Mellado Pinto PetscCall(VecGetArrayRead(xx, &x)); 1120459e8d23SBlanca Mellado Pinto if (trans) { 11210be0d8bdSHansol Suh if (herm) PetscCallBLAS("BLASgemv", BLASgemv_("C", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x, &_One, &_DOne, y + c_start, &_One)); 11220be0d8bdSHansol Suh else PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x, &_One, &_DOne, y + c_start, &_One)); 1123459e8d23SBlanca Mellado Pinto } else { 11240be0d8bdSHansol Suh PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x + c_start, &_One, &_DOne, y, &_One)); 1125459e8d23SBlanca Mellado Pinto } 11269566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 11279566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &y)); 11280be0d8bdSHansol Suh PetscCall(PetscLogFlops(2.0 * m * n)); 11290be0d8bdSHansol Suh PetscFunctionReturn(PETSC_SUCCESS); 11300be0d8bdSHansol Suh } 11310be0d8bdSHansol Suh 1132d016bddeSToby Isaac PetscErrorCode MatMultColumnRange_SeqDense(Mat A, Vec xx, Vec yy, PetscInt c_start, PetscInt c_end) 1133d016bddeSToby Isaac { 1134d016bddeSToby Isaac PetscFunctionBegin; 1135d016bddeSToby Isaac PetscCall(MatMultColumnRangeKernel_SeqDense(A, xx, yy, c_start, c_end, PETSC_FALSE, PETSC_FALSE)); 1136d016bddeSToby Isaac PetscFunctionReturn(PETSC_SUCCESS); 1137d016bddeSToby Isaac } 1138d016bddeSToby Isaac 11390be0d8bdSHansol Suh PetscErrorCode MatMultAddColumnRange_SeqDense(Mat A, Vec xx, Vec zz, Vec yy, PetscInt c_start, PetscInt c_end) 11400be0d8bdSHansol Suh { 11410be0d8bdSHansol Suh PetscFunctionBegin; 11420be0d8bdSHansol Suh PetscCall(MatMultAddColumnRangeKernel_SeqDense(A, xx, zz, yy, c_start, c_end, PETSC_FALSE, PETSC_FALSE)); 11430be0d8bdSHansol Suh PetscFunctionReturn(PETSC_SUCCESS); 11440be0d8bdSHansol Suh } 11450be0d8bdSHansol Suh 11460be0d8bdSHansol Suh PetscErrorCode MatMultHermitianTransposeAddColumnRange_SeqDense(Mat A, Vec xx, Vec zz, Vec yy, PetscInt c_start, PetscInt c_end) 11470be0d8bdSHansol Suh { 11480be0d8bdSHansol Suh PetscFunctionBegin; 11490be0d8bdSHansol Suh PetscMPIInt rank; 11500be0d8bdSHansol Suh PetscCallMPI(MPI_Comm_rank(MPI_COMM_WORLD, &rank)); 11510be0d8bdSHansol Suh PetscCall(MatMultAddColumnRangeKernel_SeqDense(A, xx, zz, yy, c_start, c_end, PETSC_TRUE, PETSC_TRUE)); 11523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1153289bc588SBarry Smith } 11546ee01492SSatish Balay 1155459e8d23SBlanca Mellado Pinto PetscErrorCode MatMultAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) 1156459e8d23SBlanca Mellado Pinto { 1157459e8d23SBlanca Mellado Pinto PetscFunctionBegin; 11580be0d8bdSHansol Suh PetscCall(MatMultAddColumnRangeKernel_SeqDense(A, xx, zz, yy, 0, A->cmap->n, PETSC_FALSE, PETSC_FALSE)); 1159459e8d23SBlanca Mellado Pinto PetscFunctionReturn(PETSC_SUCCESS); 1160459e8d23SBlanca Mellado Pinto } 1161459e8d23SBlanca Mellado Pinto 1162d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) 1163d71ae5a4SJacob Faibussowitsch { 11643a40ed3dSBarry Smith PetscFunctionBegin; 11650be0d8bdSHansol Suh PetscCall(MatMultAddColumnRangeKernel_SeqDense(A, xx, zz, yy, 0, A->cmap->n, PETSC_TRUE, PETSC_FALSE)); 1166459e8d23SBlanca Mellado Pinto PetscFunctionReturn(PETSC_SUCCESS); 1167459e8d23SBlanca Mellado Pinto } 1168459e8d23SBlanca Mellado Pinto 1169459e8d23SBlanca Mellado Pinto PetscErrorCode MatMultHermitianTransposeAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) 1170459e8d23SBlanca Mellado Pinto { 1171459e8d23SBlanca Mellado Pinto PetscFunctionBegin; 11720be0d8bdSHansol Suh PetscCall(MatMultAddColumnRangeKernel_SeqDense(A, xx, zz, yy, 0, A->cmap->n, PETSC_TRUE, PETSC_TRUE)); 11733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1174289bc588SBarry Smith } 1175289bc588SBarry Smith 1176d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals) 1177d71ae5a4SJacob Faibussowitsch { 1178c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 117913f74950SBarry Smith PetscInt i; 118067e560aaSBarry Smith 11813a40ed3dSBarry Smith PetscFunctionBegin; 1182c3e1b152SPierre Jolivet if (ncols) *ncols = A->cmap->n; 1183289bc588SBarry Smith if (cols) { 11849566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->cmap->n, cols)); 1185d0f46423SBarry Smith for (i = 0; i < A->cmap->n; i++) (*cols)[i] = i; 1186289bc588SBarry Smith } 1187289bc588SBarry Smith if (vals) { 1188ca15aa20SStefano Zampini const PetscScalar *v; 1189ca15aa20SStefano Zampini 11909566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 11919566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->cmap->n, vals)); 1192ca15aa20SStefano Zampini v += row; 11939371c9d4SSatish Balay for (i = 0; i < A->cmap->n; i++) { 11949371c9d4SSatish Balay (*vals)[i] = *v; 11959371c9d4SSatish Balay v += mat->lda; 11969371c9d4SSatish Balay } 11979566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 1198289bc588SBarry Smith } 11993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1200289bc588SBarry Smith } 12016ee01492SSatish Balay 1202d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRestoreRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals) 1203d71ae5a4SJacob Faibussowitsch { 1204606d414cSSatish Balay PetscFunctionBegin; 12059566063dSJacob Faibussowitsch if (cols) PetscCall(PetscFree(*cols)); 12069566063dSJacob Faibussowitsch if (vals) PetscCall(PetscFree(*vals)); 12073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1208289bc588SBarry Smith } 12092ef1f0ffSBarry Smith 1210d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], const PetscScalar v[], InsertMode addv) 1211d71ae5a4SJacob Faibussowitsch { 1212c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1213ca15aa20SStefano Zampini PetscScalar *av; 121413f74950SBarry Smith PetscInt i, j, idx = 0; 121547d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1216c70f7ee4SJunchao Zhang PetscOffloadMask oldf; 1217ca15aa20SStefano Zampini #endif 1218d6dfbf8fSBarry Smith 12193a40ed3dSBarry Smith PetscFunctionBegin; 12209566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &av)); 1221289bc588SBarry Smith if (!mat->roworiented) { 1222dbb450caSBarry Smith if (addv == INSERT_VALUES) { 1223289bc588SBarry Smith for (j = 0; j < n; j++) { 12249371c9d4SSatish Balay if (indexn[j] < 0) { 12259371c9d4SSatish Balay idx += m; 12269371c9d4SSatish Balay continue; 12279371c9d4SSatish Balay } 12286bdcaf15SBarry 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); 1229289bc588SBarry Smith for (i = 0; i < m; i++) { 12309371c9d4SSatish Balay if (indexm[i] < 0) { 12319371c9d4SSatish Balay idx++; 12329371c9d4SSatish Balay continue; 12339371c9d4SSatish Balay } 12346bdcaf15SBarry 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); 12358c4a67a0SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] = v ? v[idx++] : (idx++, 0.0); 1236289bc588SBarry Smith } 1237289bc588SBarry Smith } 12380be0d8bdSHansol Suh } else { 1239289bc588SBarry Smith for (j = 0; j < n; j++) { 12409371c9d4SSatish Balay if (indexn[j] < 0) { 12419371c9d4SSatish Balay idx += m; 12429371c9d4SSatish Balay continue; 12439371c9d4SSatish Balay } 12446bdcaf15SBarry 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); 1245289bc588SBarry Smith for (i = 0; i < m; i++) { 12469371c9d4SSatish Balay if (indexm[i] < 0) { 12479371c9d4SSatish Balay idx++; 12489371c9d4SSatish Balay continue; 12499371c9d4SSatish Balay } 12506bdcaf15SBarry 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); 12518c4a67a0SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] += v ? v[idx++] : (idx++, 0.0); 1252289bc588SBarry Smith } 1253289bc588SBarry Smith } 1254289bc588SBarry Smith } 12553a40ed3dSBarry Smith } else { 1256dbb450caSBarry Smith if (addv == INSERT_VALUES) { 1257e8d4e0b9SBarry Smith for (i = 0; i < m; i++) { 12589371c9d4SSatish Balay if (indexm[i] < 0) { 12599371c9d4SSatish Balay idx += n; 12609371c9d4SSatish Balay continue; 12619371c9d4SSatish Balay } 12626bdcaf15SBarry 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); 1263e8d4e0b9SBarry Smith for (j = 0; j < n; j++) { 12649371c9d4SSatish Balay if (indexn[j] < 0) { 12659371c9d4SSatish Balay idx++; 12669371c9d4SSatish Balay continue; 12679371c9d4SSatish Balay } 12686bdcaf15SBarry 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); 12698c4a67a0SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] = v ? v[idx++] : (idx++, 0.0); 1270e8d4e0b9SBarry Smith } 1271e8d4e0b9SBarry Smith } 12720be0d8bdSHansol Suh } else { 1273289bc588SBarry Smith for (i = 0; i < m; i++) { 12749371c9d4SSatish Balay if (indexm[i] < 0) { 12759371c9d4SSatish Balay idx += n; 12769371c9d4SSatish Balay continue; 12779371c9d4SSatish Balay } 12786bdcaf15SBarry 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); 1279289bc588SBarry Smith for (j = 0; j < n; j++) { 12809371c9d4SSatish Balay if (indexn[j] < 0) { 12819371c9d4SSatish Balay idx++; 12829371c9d4SSatish Balay continue; 12839371c9d4SSatish Balay } 12846bdcaf15SBarry 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); 12858c4a67a0SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] += v ? v[idx++] : (idx++, 0.0); 1286289bc588SBarry Smith } 1287289bc588SBarry Smith } 1288289bc588SBarry Smith } 1289e8d4e0b9SBarry Smith } 1290ca15aa20SStefano Zampini /* hack to prevent unneeded copy to the GPU while returning the array */ 129147d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1292c70f7ee4SJunchao Zhang oldf = A->offloadmask; 1293c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_GPU; 1294ca15aa20SStefano Zampini #endif 12959566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &av)); 129647d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1297c70f7ee4SJunchao Zhang A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU); 1298ca15aa20SStefano Zampini #endif 12993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1300289bc588SBarry Smith } 1301e8d4e0b9SBarry Smith 1302d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], PetscScalar v[]) 1303d71ae5a4SJacob Faibussowitsch { 1304ae80bb75SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1305ca15aa20SStefano Zampini const PetscScalar *vv; 130613f74950SBarry Smith PetscInt i, j; 1307ae80bb75SLois Curfman McInnes 13083a40ed3dSBarry Smith PetscFunctionBegin; 13099566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &vv)); 1310ae80bb75SLois Curfman McInnes /* row-oriented output */ 1311ae80bb75SLois Curfman McInnes for (i = 0; i < m; i++) { 13129371c9d4SSatish Balay if (indexm[i] < 0) { 13139371c9d4SSatish Balay v += n; 13149371c9d4SSatish Balay continue; 13159371c9d4SSatish Balay } 131608401ef6SPierre 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); 1317ae80bb75SLois Curfman McInnes for (j = 0; j < n; j++) { 13189371c9d4SSatish Balay if (indexn[j] < 0) { 13199371c9d4SSatish Balay v++; 13209371c9d4SSatish Balay continue; 13219371c9d4SSatish Balay } 132208401ef6SPierre 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); 1323ca15aa20SStefano Zampini *v++ = vv[indexn[j] * mat->lda + indexm[i]]; 1324ae80bb75SLois Curfman McInnes } 1325ae80bb75SLois Curfman McInnes } 13269566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &vv)); 13273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1328ae80bb75SLois Curfman McInnes } 1329ae80bb75SLois Curfman McInnes 1330d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_Dense_Binary(Mat mat, PetscViewer viewer) 1331d71ae5a4SJacob Faibussowitsch { 13328491ab44SLisandro Dalcin PetscBool skipHeader; 13338491ab44SLisandro Dalcin PetscViewerFormat format; 13343e1d7bceSPierre Jolivet PetscInt header[4], M, N, m, lda, i, j; 13353e1d7bceSPierre Jolivet PetscCount k; 13368491ab44SLisandro Dalcin const PetscScalar *v; 13378491ab44SLisandro Dalcin PetscScalar *vwork; 1338aabbc4fbSShri Abhyankar 1339aabbc4fbSShri Abhyankar PetscFunctionBegin; 13409566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 13419566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader)); 13429566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 13438491ab44SLisandro Dalcin if (skipHeader) format = PETSC_VIEWER_NATIVE; 1344aabbc4fbSShri Abhyankar 13459566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &M, &N)); 13468491ab44SLisandro Dalcin 13478491ab44SLisandro Dalcin /* write matrix header */ 13489371c9d4SSatish Balay header[0] = MAT_FILE_CLASSID; 13499371c9d4SSatish Balay header[1] = M; 13509371c9d4SSatish Balay header[2] = N; 13518491ab44SLisandro Dalcin header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M * N; 13529566063dSJacob Faibussowitsch if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer, header, 4, PETSC_INT)); 13538491ab44SLisandro Dalcin 13549566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mat, &m, NULL)); 13558491ab44SLisandro Dalcin if (format != PETSC_VIEWER_NATIVE) { 13568491ab44SLisandro Dalcin PetscInt nnz = m * N, *iwork; 13578491ab44SLisandro Dalcin /* store row lengths for each row */ 13589566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz, &iwork)); 13598491ab44SLisandro Dalcin for (i = 0; i < m; i++) iwork[i] = N; 13609566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 13618491ab44SLisandro Dalcin /* store column indices (zero start index) */ 13628491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 13639371c9d4SSatish Balay for (j = 0; j < N; j++, k++) iwork[k] = j; 13649566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 13659566063dSJacob Faibussowitsch PetscCall(PetscFree(iwork)); 13668491ab44SLisandro Dalcin } 13678491ab44SLisandro Dalcin /* store matrix values as a dense matrix in row major order */ 13689566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m * N, &vwork)); 13699566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(mat, &v)); 13709566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(mat, &lda)); 13718491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 13723e1d7bceSPierre Jolivet for (j = 0; j < N; j++, k++) vwork[k] = v[i + (size_t)lda * j]; 13739566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(mat, &v)); 13749566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, vwork, m * N, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 13759566063dSJacob Faibussowitsch PetscCall(PetscFree(vwork)); 13763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13778491ab44SLisandro Dalcin } 13788491ab44SLisandro Dalcin 1379d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLoad_Dense_Binary(Mat mat, PetscViewer viewer) 1380d71ae5a4SJacob Faibussowitsch { 13818491ab44SLisandro Dalcin PetscBool skipHeader; 13828491ab44SLisandro Dalcin PetscInt header[4], M, N, m, nz, lda, i, j, k; 13838491ab44SLisandro Dalcin PetscInt rows, cols; 13848491ab44SLisandro Dalcin PetscScalar *v, *vwork; 13858491ab44SLisandro Dalcin 13868491ab44SLisandro Dalcin PetscFunctionBegin; 13879566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 13889566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader)); 13898491ab44SLisandro Dalcin 13908491ab44SLisandro Dalcin if (!skipHeader) { 13919566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, header, 4, NULL, PETSC_INT)); 139208401ef6SPierre Jolivet PetscCheck(header[0] == MAT_FILE_CLASSID, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Not a matrix object in file"); 13939371c9d4SSatish Balay M = header[1]; 13949371c9d4SSatish Balay N = header[2]; 139508401ef6SPierre Jolivet PetscCheck(M >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix row size (%" PetscInt_FMT ") in file is negative", M); 139608401ef6SPierre Jolivet PetscCheck(N >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix column size (%" PetscInt_FMT ") in file is negative", N); 13978491ab44SLisandro Dalcin nz = header[3]; 1398aed4548fSBarry Smith PetscCheck(nz == MATRIX_BINARY_FORMAT_DENSE || nz >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Unknown matrix format %" PetscInt_FMT " in file", nz); 1399aabbc4fbSShri Abhyankar } else { 14009566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &M, &N)); 1401aed4548fSBarry 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"); 14028491ab44SLisandro Dalcin nz = MATRIX_BINARY_FORMAT_DENSE; 1403e6324fbbSBarry Smith } 1404aabbc4fbSShri Abhyankar 14058491ab44SLisandro Dalcin /* setup global sizes if not set */ 14068491ab44SLisandro Dalcin if (mat->rmap->N < 0) mat->rmap->N = M; 14078491ab44SLisandro Dalcin if (mat->cmap->N < 0) mat->cmap->N = N; 14089566063dSJacob Faibussowitsch PetscCall(MatSetUp(mat)); 14098491ab44SLisandro Dalcin /* check if global sizes are correct */ 14109566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &rows, &cols)); 1411aed4548fSBarry 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); 1412aabbc4fbSShri Abhyankar 14139566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, NULL, &N)); 14149566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mat, &m, NULL)); 14159566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(mat, &v)); 14169566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(mat, &lda)); 14178491ab44SLisandro Dalcin if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense format */ 14183e1d7bceSPierre Jolivet PetscCount nnz = (size_t)m * N; 14198491ab44SLisandro Dalcin /* read in matrix values */ 14209566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz, &vwork)); 14219566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 14228491ab44SLisandro Dalcin /* store values in column major order */ 14238491ab44SLisandro Dalcin for (j = 0; j < N; j++) 14243e1d7bceSPierre Jolivet for (i = 0; i < m; i++) v[i + (size_t)lda * j] = vwork[(size_t)i * N + j]; 14259566063dSJacob Faibussowitsch PetscCall(PetscFree(vwork)); 14268491ab44SLisandro Dalcin } else { /* matrix in file is sparse format */ 14278491ab44SLisandro Dalcin PetscInt nnz = 0, *rlens, *icols; 14288491ab44SLisandro Dalcin /* read in row lengths */ 14299566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m, &rlens)); 14309566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, rlens, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 14318491ab44SLisandro Dalcin for (i = 0; i < m; i++) nnz += rlens[i]; 14328491ab44SLisandro Dalcin /* read in column indices and values */ 14339566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(nnz, &icols, nnz, &vwork)); 14349566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, icols, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 14359566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 14368491ab44SLisandro Dalcin /* store values in column major order */ 14378491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 14389371c9d4SSatish Balay for (j = 0; j < rlens[i]; j++, k++) v[i + lda * icols[k]] = vwork[k]; 14399566063dSJacob Faibussowitsch PetscCall(PetscFree(rlens)); 14409566063dSJacob Faibussowitsch PetscCall(PetscFree2(icols, vwork)); 1441aabbc4fbSShri Abhyankar } 14429566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(mat, &v)); 14439566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY)); 14449566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY)); 14453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1446aabbc4fbSShri Abhyankar } 1447aabbc4fbSShri Abhyankar 144866976f2fSJacob Faibussowitsch static PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer) 1449d71ae5a4SJacob Faibussowitsch { 1450eb91f321SVaclav Hapla PetscBool isbinary, ishdf5; 1451eb91f321SVaclav Hapla 1452eb91f321SVaclav Hapla PetscFunctionBegin; 1453eb91f321SVaclav Hapla PetscValidHeaderSpecific(newMat, MAT_CLASSID, 1); 1454eb91f321SVaclav Hapla PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1455eb91f321SVaclav Hapla /* force binary viewer to load .info file if it has not yet done so */ 14569566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 14579566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 14589566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5)); 1459eb91f321SVaclav Hapla if (isbinary) { 14609566063dSJacob Faibussowitsch PetscCall(MatLoad_Dense_Binary(newMat, viewer)); 1461eb91f321SVaclav Hapla } else if (ishdf5) { 1462eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5) 14639566063dSJacob Faibussowitsch PetscCall(MatLoad_Dense_HDF5(newMat, viewer)); 1464eb91f321SVaclav Hapla #else 1465eb91f321SVaclav Hapla SETERRQ(PetscObjectComm((PetscObject)newMat), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1466eb91f321SVaclav Hapla #endif 1467eb91f321SVaclav Hapla } else { 146898921bdaSJacob 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); 1469eb91f321SVaclav Hapla } 14703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1471eb91f321SVaclav Hapla } 1472eb91f321SVaclav Hapla 1473d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_ASCII(Mat A, PetscViewer viewer) 1474d71ae5a4SJacob Faibussowitsch { 1475932b0c3eSLois Curfman McInnes Mat_SeqDense *a = (Mat_SeqDense *)A->data; 147613f74950SBarry Smith PetscInt i, j; 14772dcb1b2aSMatthew Knepley const char *name; 1478ca15aa20SStefano Zampini PetscScalar *v, *av; 1479f3ef73ceSBarry Smith PetscViewerFormat format; 14805f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX) 1481ace3abfcSBarry Smith PetscBool allreal = PETSC_TRUE; 14825f481a85SSatish Balay #endif 1483932b0c3eSLois Curfman McInnes 14843a40ed3dSBarry Smith PetscFunctionBegin; 14859566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&av)); 14869566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 1487456192e2SBarry Smith if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 14883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); /* do nothing for now */ 1489fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 14909566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE)); 1491d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 1492ca15aa20SStefano Zampini v = av + i; 14939566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "row %" PetscInt_FMT ":", i)); 1494d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1495aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 1496329f5518SBarry Smith if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) { 14979566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g + %g i) ", j, (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v))); 1498329f5518SBarry Smith } else if (PetscRealPart(*v)) { 14999566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)PetscRealPart(*v))); 15006831982aSBarry Smith } 150180cd9d93SLois Curfman McInnes #else 150248a46eb9SPierre Jolivet if (*v) PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)*v)); 150380cd9d93SLois Curfman McInnes #endif 15041b807ce4Svictorle v += a->lda; 150580cd9d93SLois Curfman McInnes } 15069566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 150780cd9d93SLois Curfman McInnes } 15089566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE)); 15093a40ed3dSBarry Smith } else { 15109566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE)); 1511aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 151247989497SBarry Smith /* determine if matrix has all real values */ 1513bcd8d3a4SJose E. Roman for (j = 0; j < A->cmap->n; j++) { 1514bcd8d3a4SJose E. Roman v = av + j * a->lda; 1515bcd8d3a4SJose E. Roman for (i = 0; i < A->rmap->n; i++) { 15169371c9d4SSatish Balay if (PetscImaginaryPart(v[i])) { 15179371c9d4SSatish Balay allreal = PETSC_FALSE; 15189371c9d4SSatish Balay break; 15199371c9d4SSatish Balay } 152047989497SBarry Smith } 1521bcd8d3a4SJose E. Roman } 152247989497SBarry Smith #endif 1523fb9695e5SSatish Balay if (format == PETSC_VIEWER_ASCII_MATLAB) { 15249566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)A, &name)); 15259566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%% Size = %" PetscInt_FMT " %" PetscInt_FMT " \n", A->rmap->n, A->cmap->n)); 15269566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%s = zeros(%" PetscInt_FMT ",%" PetscInt_FMT ");\n", name, A->rmap->n, A->cmap->n)); 15279566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%s = [\n", name)); 1528ffac6cdbSBarry Smith } 1529ffac6cdbSBarry Smith 1530d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 1531ca15aa20SStefano Zampini v = av + i; 1532d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1533aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 153447989497SBarry Smith if (allreal) { 15359566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)PetscRealPart(*v))); 153647989497SBarry Smith } else { 15379566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e + %18.16ei ", (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v))); 153847989497SBarry Smith } 1539289bc588SBarry Smith #else 15409566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)*v)); 1541289bc588SBarry Smith #endif 15421b807ce4Svictorle v += a->lda; 1543289bc588SBarry Smith } 15449566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 1545289bc588SBarry Smith } 154648a46eb9SPierre Jolivet if (format == PETSC_VIEWER_ASCII_MATLAB) PetscCall(PetscViewerASCIIPrintf(viewer, "];\n")); 15479566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE)); 1548da3a660dSBarry Smith } 15499566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&av)); 15509566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer)); 15513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1552289bc588SBarry Smith } 1553289bc588SBarry Smith 15549804daf3SBarry Smith #include <petscdraw.h> 1555d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw, void *Aa) 1556d71ae5a4SJacob Faibussowitsch { 1557f1af5d2fSBarry Smith Mat A = (Mat)Aa; 1558383922c3SLisandro Dalcin PetscInt m = A->rmap->n, n = A->cmap->n, i, j; 1559383922c3SLisandro Dalcin int color = PETSC_DRAW_WHITE; 1560ca15aa20SStefano Zampini const PetscScalar *v; 1561b0a32e0cSBarry Smith PetscViewer viewer; 1562b05fc000SLisandro Dalcin PetscReal xl, yl, xr, yr, x_l, x_r, y_l, y_r; 1563f3ef73ceSBarry Smith PetscViewerFormat format; 1564f1af5d2fSBarry Smith 1565f1af5d2fSBarry Smith PetscFunctionBegin; 15669566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)A, "Zoomviewer", (PetscObject *)&viewer)); 15679566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 15689566063dSJacob Faibussowitsch PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr)); 1569f1af5d2fSBarry Smith 1570f1af5d2fSBarry Smith /* Loop over matrix elements drawing boxes */ 15719566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 1572fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 1573d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 1574f1af5d2fSBarry Smith /* Blue for negative and Red for positive */ 1575f1af5d2fSBarry Smith for (j = 0; j < n; j++) { 15769371c9d4SSatish Balay x_l = j; 15779371c9d4SSatish Balay x_r = x_l + 1.0; 1578f1af5d2fSBarry Smith for (i = 0; i < m; i++) { 1579f1af5d2fSBarry Smith y_l = m - i - 1.0; 1580f1af5d2fSBarry Smith y_r = y_l + 1.0; 1581ca15aa20SStefano Zampini if (PetscRealPart(v[j * m + i]) > 0.) color = PETSC_DRAW_RED; 1582ca15aa20SStefano Zampini else if (PetscRealPart(v[j * m + i]) < 0.) color = PETSC_DRAW_BLUE; 1583ca15aa20SStefano Zampini else continue; 15849566063dSJacob Faibussowitsch PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color)); 1585f1af5d2fSBarry Smith } 1586f1af5d2fSBarry Smith } 1587d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 1588f1af5d2fSBarry Smith } else { 1589f1af5d2fSBarry Smith /* use contour shading to indicate magnitude of values */ 1590f1af5d2fSBarry Smith /* first determine max of all nonzero values */ 1591b05fc000SLisandro Dalcin PetscReal minv = 0.0, maxv = 0.0; 1592b05fc000SLisandro Dalcin PetscDraw popup; 1593b05fc000SLisandro Dalcin 1594f1af5d2fSBarry Smith for (i = 0; i < m * n; i++) { 1595f1af5d2fSBarry Smith if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]); 1596f1af5d2fSBarry Smith } 1597383922c3SLisandro Dalcin if (minv >= maxv) maxv = minv + PETSC_SMALL; 15989566063dSJacob Faibussowitsch PetscCall(PetscDrawGetPopup(draw, &popup)); 15999566063dSJacob Faibussowitsch PetscCall(PetscDrawScalePopup(popup, minv, maxv)); 1600383922c3SLisandro Dalcin 1601d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 1602f1af5d2fSBarry Smith for (j = 0; j < n; j++) { 1603f1af5d2fSBarry Smith x_l = j; 1604f1af5d2fSBarry Smith x_r = x_l + 1.0; 1605f1af5d2fSBarry Smith for (i = 0; i < m; i++) { 1606f1af5d2fSBarry Smith y_l = m - i - 1.0; 1607f1af5d2fSBarry Smith y_r = y_l + 1.0; 1608b05fc000SLisandro Dalcin color = PetscDrawRealToColor(PetscAbsScalar(v[j * m + i]), minv, maxv); 16099566063dSJacob Faibussowitsch PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color)); 1610f1af5d2fSBarry Smith } 1611f1af5d2fSBarry Smith } 1612d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 1613f1af5d2fSBarry Smith } 16149566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 16153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1616f1af5d2fSBarry Smith } 1617f1af5d2fSBarry Smith 1618d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw(Mat A, PetscViewer viewer) 1619d71ae5a4SJacob Faibussowitsch { 1620b0a32e0cSBarry Smith PetscDraw draw; 1621ace3abfcSBarry Smith PetscBool isnull; 1622329f5518SBarry Smith PetscReal xr, yr, xl, yl, h, w; 1623f1af5d2fSBarry Smith 1624f1af5d2fSBarry Smith PetscFunctionBegin; 16259566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 16269566063dSJacob Faibussowitsch PetscCall(PetscDrawIsNull(draw, &isnull)); 16273ba16761SJacob Faibussowitsch if (isnull) PetscFunctionReturn(PETSC_SUCCESS); 1628f1af5d2fSBarry Smith 16299371c9d4SSatish Balay xr = A->cmap->n; 16309371c9d4SSatish Balay yr = A->rmap->n; 16319371c9d4SSatish Balay h = yr / 10.0; 16329371c9d4SSatish Balay w = xr / 10.0; 16339371c9d4SSatish Balay xr += w; 16349371c9d4SSatish Balay yr += h; 16359371c9d4SSatish Balay xl = -w; 16369371c9d4SSatish Balay yl = -h; 16379566063dSJacob Faibussowitsch PetscCall(PetscDrawSetCoordinates(draw, xl, yl, xr, yr)); 16389566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", (PetscObject)viewer)); 16399566063dSJacob Faibussowitsch PetscCall(PetscDrawZoom(draw, MatView_SeqDense_Draw_Zoom, A)); 16409566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", NULL)); 16419566063dSJacob Faibussowitsch PetscCall(PetscDrawSave(draw)); 16423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1643f1af5d2fSBarry Smith } 1644f1af5d2fSBarry Smith 1645d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_SeqDense(Mat A, PetscViewer viewer) 1646d71ae5a4SJacob Faibussowitsch { 1647*9f196a02SMartin Diehl PetscBool isascii, isbinary, isdraw; 1648932b0c3eSLois Curfman McInnes 16493a40ed3dSBarry Smith PetscFunctionBegin; 1650*9f196a02SMartin Diehl PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isascii)); 16519566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 16529566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 1653*9f196a02SMartin Diehl if (isascii) PetscCall(MatView_SeqDense_ASCII(A, viewer)); 16541baa6e33SBarry Smith else if (isbinary) PetscCall(MatView_Dense_Binary(A, viewer)); 16551baa6e33SBarry Smith else if (isdraw) PetscCall(MatView_SeqDense_Draw(A, viewer)); 16563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1657932b0c3eSLois Curfman McInnes } 1658289bc588SBarry Smith 1659d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A, const PetscScalar *array) 1660d71ae5a4SJacob Faibussowitsch { 1661d3042a70SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1662d3042a70SBarry Smith 1663d3042a70SBarry Smith PetscFunctionBegin; 166428b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 166528b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 16666635c364SPierre Jolivet PetscCheck(!a->unplacedarray, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseResetArray() first"); 1667d3042a70SBarry Smith a->unplacedarray = a->v; 1668d3042a70SBarry Smith a->unplaced_user_alloc = a->user_alloc; 1669d3042a70SBarry Smith a->v = (PetscScalar *)array; 1670637a0070SStefano Zampini a->user_alloc = PETSC_TRUE; 167147d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1672c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_CPU; 1673ca15aa20SStefano Zampini #endif 16743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1675d3042a70SBarry Smith } 1676d3042a70SBarry Smith 1677d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseResetArray_SeqDense(Mat A) 1678d71ae5a4SJacob Faibussowitsch { 1679d3042a70SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1680d3042a70SBarry Smith 1681d3042a70SBarry Smith PetscFunctionBegin; 168228b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 168328b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 1684d3042a70SBarry Smith a->v = a->unplacedarray; 1685d3042a70SBarry Smith a->user_alloc = a->unplaced_user_alloc; 1686d3042a70SBarry Smith a->unplacedarray = NULL; 168747d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1688c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_CPU; 1689ca15aa20SStefano Zampini #endif 16903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1691d3042a70SBarry Smith } 1692d3042a70SBarry Smith 1693d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A, const PetscScalar *array) 1694d71ae5a4SJacob Faibussowitsch { 1695d5ea218eSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1696d5ea218eSStefano Zampini 1697d5ea218eSStefano Zampini PetscFunctionBegin; 169828b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 169928b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 17009566063dSJacob Faibussowitsch if (!a->user_alloc) PetscCall(PetscFree(a->v)); 1701d5ea218eSStefano Zampini a->v = (PetscScalar *)array; 1702d5ea218eSStefano Zampini a->user_alloc = PETSC_FALSE; 170347d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1704d5ea218eSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 1705d5ea218eSStefano Zampini #endif 17063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1707d5ea218eSStefano Zampini } 1708d5ea218eSStefano Zampini 1709d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDestroy_SeqDense(Mat mat) 1710d71ae5a4SJacob Faibussowitsch { 1711ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)mat->data; 171290f02eecSBarry Smith 17133a40ed3dSBarry Smith PetscFunctionBegin; 17143ba16761SJacob Faibussowitsch PetscCall(PetscLogObjectState((PetscObject)mat, "Rows %" PetscInt_FMT " Cols %" PetscInt_FMT, mat->rmap->n, mat->cmap->n)); 1715f4f49eeaSPierre Jolivet PetscCall(VecDestroy(&l->qrrhs)); 17169566063dSJacob Faibussowitsch PetscCall(PetscFree(l->tau)); 17179566063dSJacob Faibussowitsch PetscCall(PetscFree(l->pivots)); 17189566063dSJacob Faibussowitsch PetscCall(PetscFree(l->fwork)); 17199566063dSJacob Faibussowitsch if (!l->user_alloc) PetscCall(PetscFree(l->v)); 17209566063dSJacob Faibussowitsch if (!l->unplaced_user_alloc) PetscCall(PetscFree(l->unplacedarray)); 172128b400f6SJacob Faibussowitsch PetscCheck(!l->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 172228b400f6SJacob Faibussowitsch PetscCheck(!l->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 17239566063dSJacob Faibussowitsch PetscCall(VecDestroy(&l->cvec)); 17249566063dSJacob Faibussowitsch PetscCall(MatDestroy(&l->cmat)); 17259566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->data)); 1726dbd8c25aSHong Zhang 17279566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)mat, NULL)); 17289566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactor_C", NULL)); 17292e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorSymbolic_C", NULL)); 17302e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorNumeric_C", NULL)); 17319566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetLDA_C", NULL)); 17329566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseSetLDA_C", NULL)); 17339566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArray_C", NULL)); 17349566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArray_C", NULL)); 17359566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDensePlaceArray_C", NULL)); 17369566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseResetArray_C", NULL)); 17379566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseReplaceArray_C", NULL)); 17389566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayRead_C", NULL)); 17399566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayRead_C", NULL)); 17409566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayWrite_C", NULL)); 17419566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayWrite_C", NULL)); 17429566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqaij_C", NULL)); 17438baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 17449566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_elemental_C", NULL)); 17458baccfbdSHong Zhang #endif 1746d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 17479566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_scalapack_C", NULL)); 1748d24d4204SJose E. Roman #endif 17492bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA) 17509566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensecuda_C", NULL)); 17519566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", NULL)); 17529566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdense_C", NULL)); 17532e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensecuda_C", NULL)); 17542bf066beSStefano Zampini #endif 175547d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 175647d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensehip_C", NULL)); 175747d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensehip_seqdensehip_C", NULL)); 175847d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensehip_seqdense_C", NULL)); 175947d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensehip_C", NULL)); 176047d993e7Ssuyashtn #endif 17619566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatSeqDenseSetPreallocation_C", NULL)); 17629566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqaij_seqdense_C", NULL)); 17639566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdense_C", NULL)); 17649566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqbaij_seqdense_C", NULL)); 17659566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqsbaij_seqdense_C", NULL)); 176652c5f739Sprj- 17679566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumn_C", NULL)); 17689566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumn_C", NULL)); 17699566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVec_C", NULL)); 17709566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVec_C", NULL)); 17719566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecRead_C", NULL)); 17729566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecRead_C", NULL)); 17739566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecWrite_C", NULL)); 17749566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecWrite_C", NULL)); 17759566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetSubMatrix_C", NULL)); 17769566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreSubMatrix_C", NULL)); 1777d016bddeSToby Isaac PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatMultColumnRange_C", NULL)); 17780be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatMultAddColumnRange_C", NULL)); 17790be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatMultHermitianTransposeColumnRange_C", NULL)); 17800be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatMultHermitianTransposeAddColumnRange_C", NULL)); 17813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1782289bc588SBarry Smith } 1783289bc588SBarry Smith 1784d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatTranspose_SeqDense(Mat A, MatReuse reuse, Mat *matout) 1785d71ae5a4SJacob Faibussowitsch { 1786c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 17876536e3caSStefano Zampini PetscInt k, j, m = A->rmap->n, M = mat->lda, n = A->cmap->n; 178887828ca2SBarry Smith PetscScalar *v, tmp; 178948b35521SBarry Smith 17903a40ed3dSBarry Smith PetscFunctionBegin; 17917fb60732SBarry Smith if (reuse == MAT_REUSE_MATRIX) PetscCall(MatTransposeCheckNonzeroState_Private(A, *matout)); 17926536e3caSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 17936536e3caSStefano Zampini if (m == n) { /* in place transpose */ 17949566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 1795d3e5ee88SLois Curfman McInnes for (j = 0; j < m; j++) { 1796289bc588SBarry Smith for (k = 0; k < j; k++) { 17971b807ce4Svictorle tmp = v[j + k * M]; 17981b807ce4Svictorle v[j + k * M] = v[k + j * M]; 17991b807ce4Svictorle v[k + j * M] = tmp; 1800289bc588SBarry Smith } 1801289bc588SBarry Smith } 18029566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 18036536e3caSStefano Zampini } else { /* reuse memory, temporary allocates new memory */ 18046536e3caSStefano Zampini PetscScalar *v2; 18056536e3caSStefano Zampini PetscLayout tmplayout; 18066536e3caSStefano Zampini 18079566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((size_t)m * n, &v2)); 18089566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 18096536e3caSStefano Zampini for (j = 0; j < n; j++) { 18106536e3caSStefano Zampini for (k = 0; k < m; k++) v2[j + (size_t)k * n] = v[k + (size_t)j * M]; 18116536e3caSStefano Zampini } 18129566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(v, v2, (size_t)m * n)); 18139566063dSJacob Faibussowitsch PetscCall(PetscFree(v2)); 18149566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 18156536e3caSStefano Zampini /* cleanup size dependent quantities */ 18169566063dSJacob Faibussowitsch PetscCall(VecDestroy(&mat->cvec)); 18179566063dSJacob Faibussowitsch PetscCall(MatDestroy(&mat->cmat)); 18189566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->pivots)); 18199566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->fwork)); 18206536e3caSStefano Zampini /* swap row/col layouts */ 18216497c311SBarry Smith PetscCall(PetscBLASIntCast(n, &mat->lda)); 18226536e3caSStefano Zampini tmplayout = A->rmap; 18236536e3caSStefano Zampini A->rmap = A->cmap; 18246536e3caSStefano Zampini A->cmap = tmplayout; 18256536e3caSStefano Zampini } 18263a40ed3dSBarry Smith } else { /* out-of-place transpose */ 1827d3e5ee88SLois Curfman McInnes Mat tmat; 1828ec8511deSBarry Smith Mat_SeqDense *tmatd; 182987828ca2SBarry Smith PetscScalar *v2; 1830af36a384SStefano Zampini PetscInt M2; 1831ea709b57SSatish Balay 18326536e3caSStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 18339566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &tmat)); 18349566063dSJacob Faibussowitsch PetscCall(MatSetSizes(tmat, A->cmap->n, A->rmap->n, A->cmap->n, A->rmap->n)); 18359566063dSJacob Faibussowitsch PetscCall(MatSetType(tmat, ((PetscObject)A)->type_name)); 18369566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(tmat, NULL)); 1837ca15aa20SStefano Zampini } else tmat = *matout; 1838ca15aa20SStefano Zampini 18399566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&v)); 18409566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(tmat, &v2)); 1841ec8511deSBarry Smith tmatd = (Mat_SeqDense *)tmat->data; 1842ca15aa20SStefano Zampini M2 = tmatd->lda; 1843d3e5ee88SLois Curfman McInnes for (j = 0; j < n; j++) { 1844af36a384SStefano Zampini for (k = 0; k < m; k++) v2[j + k * M2] = v[k + j * M]; 1845d3e5ee88SLois Curfman McInnes } 18469566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(tmat, &v2)); 18479566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&v)); 18489566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(tmat, MAT_FINAL_ASSEMBLY)); 18499566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(tmat, MAT_FINAL_ASSEMBLY)); 18506536e3caSStefano Zampini *matout = tmat; 185148b35521SBarry Smith } 18523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1853289bc588SBarry Smith } 1854289bc588SBarry Smith 1855d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatEqual_SeqDense(Mat A1, Mat A2, PetscBool *flg) 1856d71ae5a4SJacob Faibussowitsch { 1857c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat1 = (Mat_SeqDense *)A1->data; 1858c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat2 = (Mat_SeqDense *)A2->data; 1859ca15aa20SStefano Zampini PetscInt i; 1860ca15aa20SStefano Zampini const PetscScalar *v1, *v2; 18619ea5d5aeSSatish Balay 18623a40ed3dSBarry Smith PetscFunctionBegin; 18639371c9d4SSatish Balay if (A1->rmap->n != A2->rmap->n) { 18649371c9d4SSatish Balay *flg = PETSC_FALSE; 18653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18669371c9d4SSatish Balay } 18679371c9d4SSatish Balay if (A1->cmap->n != A2->cmap->n) { 18689371c9d4SSatish Balay *flg = PETSC_FALSE; 18693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18709371c9d4SSatish Balay } 18719566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A1, &v1)); 18729566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A2, &v2)); 1873ca15aa20SStefano Zampini for (i = 0; i < A1->cmap->n; i++) { 18749566063dSJacob Faibussowitsch PetscCall(PetscArraycmp(v1, v2, A1->rmap->n, flg)); 18753ba16761SJacob Faibussowitsch if (*flg == PETSC_FALSE) PetscFunctionReturn(PETSC_SUCCESS); 1876ca15aa20SStefano Zampini v1 += mat1->lda; 1877ca15aa20SStefano Zampini v2 += mat2->lda; 18781b807ce4Svictorle } 18799566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A1, &v1)); 18809566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A2, &v2)); 188177c4ece6SBarry Smith *flg = PETSC_TRUE; 18823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1883289bc588SBarry Smith } 1884289bc588SBarry Smith 188514277c92SJacob Faibussowitsch PetscErrorCode MatGetDiagonal_SeqDense(Mat A, Vec v) 1886d71ae5a4SJacob Faibussowitsch { 1887c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 188813f74950SBarry Smith PetscInt i, n, len; 1889ca15aa20SStefano Zampini PetscScalar *x; 1890ca15aa20SStefano Zampini const PetscScalar *vv; 189144cd7ae7SLois Curfman McInnes 18923a40ed3dSBarry Smith PetscFunctionBegin; 18939566063dSJacob Faibussowitsch PetscCall(VecGetSize(v, &n)); 18949566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 1895d0f46423SBarry Smith len = PetscMin(A->rmap->n, A->cmap->n); 18969566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &vv)); 189708401ef6SPierre Jolivet PetscCheck(n == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming mat and vec"); 1898ad540459SPierre Jolivet for (i = 0; i < len; i++) x[i] = vv[i * mat->lda + i]; 18999566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &vv)); 19009566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 19013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1902289bc588SBarry Smith } 1903289bc588SBarry Smith 1904d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDiagonalScale_SeqDense(Mat A, Vec ll, Vec rr) 1905d71ae5a4SJacob Faibussowitsch { 1906c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1907f1ceaac6SMatthew G. Knepley const PetscScalar *l, *r; 1908ca15aa20SStefano Zampini PetscScalar x, *v, *vv; 1909d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n; 191055659b69SBarry Smith 19113a40ed3dSBarry Smith PetscFunctionBegin; 19129566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &vv)); 191328988994SBarry Smith if (ll) { 19149566063dSJacob Faibussowitsch PetscCall(VecGetSize(ll, &m)); 19159566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(ll, &l)); 191608401ef6SPierre Jolivet PetscCheck(m == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Left scaling vec wrong size"); 1917da3a660dSBarry Smith for (i = 0; i < m; i++) { 1918da3a660dSBarry Smith x = l[i]; 1919ca15aa20SStefano Zampini v = vv + i; 19209371c9d4SSatish Balay for (j = 0; j < n; j++) { 19219371c9d4SSatish Balay (*v) *= x; 19229371c9d4SSatish Balay v += mat->lda; 19239371c9d4SSatish Balay } 1924da3a660dSBarry Smith } 19259566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(ll, &l)); 19269566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * n * m)); 1927da3a660dSBarry Smith } 192828988994SBarry Smith if (rr) { 19299566063dSJacob Faibussowitsch PetscCall(VecGetSize(rr, &n)); 19309566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(rr, &r)); 193108401ef6SPierre Jolivet PetscCheck(n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Right scaling vec wrong size"); 1932da3a660dSBarry Smith for (i = 0; i < n; i++) { 1933da3a660dSBarry Smith x = r[i]; 1934ca15aa20SStefano Zampini v = vv + i * mat->lda; 19352205254eSKarl Rupp for (j = 0; j < m; j++) (*v++) *= x; 1936da3a660dSBarry Smith } 19379566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(rr, &r)); 19389566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * n * m)); 1939da3a660dSBarry Smith } 19409566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &vv)); 19413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1942289bc588SBarry Smith } 1943289bc588SBarry Smith 1944d71ae5a4SJacob Faibussowitsch PetscErrorCode MatNorm_SeqDense(Mat A, NormType type, PetscReal *nrm) 1945d71ae5a4SJacob Faibussowitsch { 1946c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1947ca15aa20SStefano Zampini PetscScalar *v, *vv; 1948329f5518SBarry Smith PetscReal sum = 0.0; 194975f6d85dSStefano Zampini PetscInt lda, m = A->rmap->n, i, j; 195055659b69SBarry Smith 19513a40ed3dSBarry Smith PetscFunctionBegin; 19529566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&vv)); 19539566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(A, &lda)); 1954ca15aa20SStefano Zampini v = vv; 1955289bc588SBarry Smith if (type == NORM_FROBENIUS) { 1956a5ce6ee0Svictorle if (lda > m) { 1957d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1958ca15aa20SStefano Zampini v = vv + j * lda; 1959a5ce6ee0Svictorle for (i = 0; i < m; i++) { 19609371c9d4SSatish Balay sum += PetscRealPart(PetscConj(*v) * (*v)); 19619371c9d4SSatish Balay v++; 1962a5ce6ee0Svictorle } 1963a5ce6ee0Svictorle } 1964a5ce6ee0Svictorle } else { 1965570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16) 1966570b7f6dSBarry Smith PetscBLASInt one = 1, cnt = A->cmap->n * A->rmap->n; 1967792fecdfSBarry Smith PetscCallBLAS("BLASnrm2", *nrm = BLASnrm2_(&cnt, v, &one)); 1968570b7f6dSBarry Smith } 1969570b7f6dSBarry Smith #else 1970d0f46423SBarry Smith for (i = 0; i < A->cmap->n * A->rmap->n; i++) { 19719371c9d4SSatish Balay sum += PetscRealPart(PetscConj(*v) * (*v)); 19729371c9d4SSatish Balay v++; 1973289bc588SBarry Smith } 1974a5ce6ee0Svictorle } 19758f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 1976570b7f6dSBarry Smith #endif 19779566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->cmap->n * A->rmap->n)); 19783a40ed3dSBarry Smith } else if (type == NORM_1) { 1979064f8208SBarry Smith *nrm = 0.0; 1980d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1981ca15aa20SStefano Zampini v = vv + j * mat->lda; 1982289bc588SBarry Smith sum = 0.0; 1983d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 19849371c9d4SSatish Balay sum += PetscAbsScalar(*v); 19859371c9d4SSatish Balay v++; 1986289bc588SBarry Smith } 1987064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 1988289bc588SBarry Smith } 19899566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n)); 19903a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 1991064f8208SBarry Smith *nrm = 0.0; 1992d0f46423SBarry Smith for (j = 0; j < A->rmap->n; j++) { 1993ca15aa20SStefano Zampini v = vv + j; 1994289bc588SBarry Smith sum = 0.0; 1995d0f46423SBarry Smith for (i = 0; i < A->cmap->n; i++) { 19969371c9d4SSatish Balay sum += PetscAbsScalar(*v); 19979371c9d4SSatish Balay v += mat->lda; 1998289bc588SBarry Smith } 1999064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 2000289bc588SBarry Smith } 20019566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n)); 2002e7e72b3dSBarry Smith } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "No two norm"); 20039566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&vv)); 20043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2005289bc588SBarry Smith } 2006289bc588SBarry Smith 2007d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetOption_SeqDense(Mat A, MatOption op, PetscBool flg) 2008d71ae5a4SJacob Faibussowitsch { 2009c0bbcb79SLois Curfman McInnes Mat_SeqDense *aij = (Mat_SeqDense *)A->data; 201067e560aaSBarry Smith 20113a40ed3dSBarry Smith PetscFunctionBegin; 2012b5a2b587SKris Buschelman switch (op) { 2013d71ae5a4SJacob Faibussowitsch case MAT_ROW_ORIENTED: 2014d71ae5a4SJacob Faibussowitsch aij->roworiented = flg; 2015d71ae5a4SJacob Faibussowitsch break; 2016d71ae5a4SJacob Faibussowitsch default: 2017888c827cSStefano Zampini break; 20183a40ed3dSBarry Smith } 20193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2020289bc588SBarry Smith } 2021289bc588SBarry Smith 2022d71ae5a4SJacob Faibussowitsch PetscErrorCode MatZeroEntries_SeqDense(Mat A) 2023d71ae5a4SJacob Faibussowitsch { 2024ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)A->data; 20253d8925e7SStefano Zampini PetscInt lda = l->lda, m = A->rmap->n, n = A->cmap->n, j; 2026ca15aa20SStefano Zampini PetscScalar *v; 20273a40ed3dSBarry Smith 20283a40ed3dSBarry Smith PetscFunctionBegin; 20299566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(A, &v)); 2030a5ce6ee0Svictorle if (lda > m) { 203148a46eb9SPierre Jolivet for (j = 0; j < n; j++) PetscCall(PetscArrayzero(v + j * lda, m)); 2032a5ce6ee0Svictorle } else { 20339566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(v, PetscInt64Mult(m, n))); 2034a5ce6ee0Svictorle } 20359566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(A, &v)); 20363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 20376f0a148fSBarry Smith } 20386f0a148fSBarry Smith 2039d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatZeroRows_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) 2040d71ae5a4SJacob Faibussowitsch { 2041ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)A->data; 2042b9679d65SBarry Smith PetscInt m = l->lda, n = A->cmap->n, i, j; 2043ca15aa20SStefano Zampini PetscScalar *slot, *bb, *v; 204497b48c8fSBarry Smith const PetscScalar *xx; 204555659b69SBarry Smith 20463a40ed3dSBarry Smith PetscFunctionBegin; 204776bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 2048b9679d65SBarry Smith for (i = 0; i < N; i++) { 204908401ef6SPierre Jolivet PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed"); 205008401ef6SPierre 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); 2051b9679d65SBarry Smith } 205276bd3646SJed Brown } 20533ba16761SJacob Faibussowitsch if (!N) PetscFunctionReturn(PETSC_SUCCESS); 2054b9679d65SBarry Smith 2055dd8e379bSPierre Jolivet /* fix right-hand side if needed */ 205697b48c8fSBarry Smith if (x && b) { 20579566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 20589566063dSJacob Faibussowitsch PetscCall(VecGetArray(b, &bb)); 20592205254eSKarl Rupp for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]]; 20609566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 20619566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(b, &bb)); 206297b48c8fSBarry Smith } 206397b48c8fSBarry Smith 20649566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 20656f0a148fSBarry Smith for (i = 0; i < N; i++) { 2066ca15aa20SStefano Zampini slot = v + rows[i]; 20679371c9d4SSatish Balay for (j = 0; j < n; j++) { 20689371c9d4SSatish Balay *slot = 0.0; 20699371c9d4SSatish Balay slot += m; 20709371c9d4SSatish Balay } 20716f0a148fSBarry Smith } 2072f4df32b1SMatthew Knepley if (diag != 0.0) { 207308401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices"); 20746f0a148fSBarry Smith for (i = 0; i < N; i++) { 2075ca15aa20SStefano Zampini slot = v + (m + 1) * rows[i]; 2076f4df32b1SMatthew Knepley *slot = diag; 20776f0a148fSBarry Smith } 20786f0a148fSBarry Smith } 20799566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 20803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 20816f0a148fSBarry Smith } 2082557bce09SLois Curfman McInnes 2083d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A, PetscInt *lda) 2084d71ae5a4SJacob Faibussowitsch { 208549a6ff4bSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 208649a6ff4bSBarry Smith 208749a6ff4bSBarry Smith PetscFunctionBegin; 208849a6ff4bSBarry Smith *lda = mat->lda; 20893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 209049a6ff4bSBarry Smith } 209149a6ff4bSBarry Smith 2092d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArray_SeqDense(Mat A, PetscScalar **array) 2093d71ae5a4SJacob Faibussowitsch { 2094c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 20953a40ed3dSBarry Smith 20963a40ed3dSBarry Smith PetscFunctionBegin; 209728b400f6SJacob Faibussowitsch PetscCheck(!mat->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 209864e87e97SBarry Smith *array = mat->v; 20993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 210064e87e97SBarry Smith } 21010754003eSLois Curfman McInnes 2102d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A, PetscScalar **array) 2103d71ae5a4SJacob Faibussowitsch { 21043a40ed3dSBarry Smith PetscFunctionBegin; 210575f6d85dSStefano Zampini if (array) *array = NULL; 21063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2107ff14e315SSatish Balay } 21080754003eSLois Curfman McInnes 21090f74d2c1SSatish Balay /*@ 211011a5261eSBarry Smith MatDenseGetLDA - gets the leading dimension of the array returned from `MatDenseGetArray()` 211149a6ff4bSBarry Smith 21122ef1f0ffSBarry Smith Not Collective 211349a6ff4bSBarry Smith 211449a6ff4bSBarry Smith Input Parameter: 2115fe59aa6dSJacob Faibussowitsch . A - a `MATDENSE` or `MATDENSECUDA` matrix 211649a6ff4bSBarry Smith 211749a6ff4bSBarry Smith Output Parameter: 211849a6ff4bSBarry Smith . lda - the leading dimension 211949a6ff4bSBarry Smith 212049a6ff4bSBarry Smith Level: intermediate 212149a6ff4bSBarry Smith 21221cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseSetLDA()` 212349a6ff4bSBarry Smith @*/ 2124d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetLDA(Mat A, PetscInt *lda) 2125d71ae5a4SJacob Faibussowitsch { 212649a6ff4bSBarry Smith PetscFunctionBegin; 2127d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 21284f572ea9SToby Isaac PetscAssertPointer(lda, 2); 212975f6d85dSStefano Zampini MatCheckPreallocated(A, 1); 2130cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetLDA_C", (Mat, PetscInt *), (A, lda)); 21313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 213249a6ff4bSBarry Smith } 213349a6ff4bSBarry Smith 21340f74d2c1SSatish Balay /*@ 213511a5261eSBarry Smith MatDenseSetLDA - Sets the leading dimension of the array used by the `MATDENSE` matrix 2136ad16ce7aSStefano Zampini 21372323109cSBarry Smith Collective if the matrix layouts have not yet been setup 2138ad16ce7aSStefano Zampini 2139d8d19677SJose E. Roman Input Parameters: 2140fe59aa6dSJacob Faibussowitsch + A - a `MATDENSE` or `MATDENSECUDA` matrix 2141ad16ce7aSStefano Zampini - lda - the leading dimension 2142ad16ce7aSStefano Zampini 2143ad16ce7aSStefano Zampini Level: intermediate 2144ad16ce7aSStefano Zampini 21451cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetLDA()` 2146ad16ce7aSStefano Zampini @*/ 2147d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA(Mat A, PetscInt lda) 2148d71ae5a4SJacob Faibussowitsch { 2149ad16ce7aSStefano Zampini PetscFunctionBegin; 2150ad16ce7aSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2151cac4c232SBarry Smith PetscTryMethod(A, "MatDenseSetLDA_C", (Mat, PetscInt), (A, lda)); 21523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2153ad16ce7aSStefano Zampini } 2154ad16ce7aSStefano Zampini 2155ad16ce7aSStefano Zampini /*@C 215611a5261eSBarry Smith MatDenseGetArray - gives read-write access to the array where the data for a `MATDENSE` matrix is stored 215773a71a0fSBarry Smith 2158c3339decSBarry Smith Logically Collective 215973a71a0fSBarry Smith 216073a71a0fSBarry Smith Input Parameter: 2161fe59aa6dSJacob Faibussowitsch . A - a dense matrix 216273a71a0fSBarry Smith 216373a71a0fSBarry Smith Output Parameter: 216473a71a0fSBarry Smith . array - pointer to the data 216573a71a0fSBarry Smith 216673a71a0fSBarry Smith Level: intermediate 216773a71a0fSBarry Smith 21681cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 216973a71a0fSBarry Smith @*/ 2170ce78bad3SBarry Smith PetscErrorCode MatDenseGetArray(Mat A, PetscScalar *array[]) PeNS 2171d71ae5a4SJacob Faibussowitsch { 217273a71a0fSBarry Smith PetscFunctionBegin; 2173d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 21744f572ea9SToby Isaac PetscAssertPointer(array, 2); 2175cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array)); 21763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 217773a71a0fSBarry Smith } 217873a71a0fSBarry Smith 2179dec5eb66SMatthew G Knepley /*@C 218011a5261eSBarry Smith MatDenseRestoreArray - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArray()` 218173a71a0fSBarry Smith 2182c3339decSBarry Smith Logically Collective 21838572280aSBarry Smith 21848572280aSBarry Smith Input Parameters: 2185fe59aa6dSJacob Faibussowitsch + A - a dense matrix 21862ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`) 21878572280aSBarry Smith 21888572280aSBarry Smith Level: intermediate 21898572280aSBarry Smith 21901cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 21918572280aSBarry Smith @*/ 2192ce78bad3SBarry Smith PetscErrorCode MatDenseRestoreArray(Mat A, PetscScalar *array[]) PeNS 2193d71ae5a4SJacob Faibussowitsch { 21948572280aSBarry Smith PetscFunctionBegin; 2195d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 21964f572ea9SToby Isaac if (array) PetscAssertPointer(array, 2); 2197cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array)); 21989566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)A)); 219947d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 2200637a0070SStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 2201637a0070SStefano Zampini #endif 22023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22038572280aSBarry Smith } 22048572280aSBarry Smith 22058572280aSBarry Smith /*@C 220611a5261eSBarry Smith MatDenseGetArrayRead - gives read-only access to the array where the data for a `MATDENSE` matrix is stored 22078572280aSBarry Smith 2208fb850c59SBarry Smith Not Collective 22098572280aSBarry Smith 22108572280aSBarry Smith Input Parameter: 2211fe59aa6dSJacob Faibussowitsch . A - a dense matrix 22128572280aSBarry Smith 22138572280aSBarry Smith Output Parameter: 22148572280aSBarry Smith . array - pointer to the data 22158572280aSBarry Smith 22168572280aSBarry Smith Level: intermediate 22178572280aSBarry Smith 22181cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 22198572280aSBarry Smith @*/ 2220ce78bad3SBarry Smith PetscErrorCode MatDenseGetArrayRead(Mat A, const PetscScalar *array[]) PeNS 2221d71ae5a4SJacob Faibussowitsch { 22228572280aSBarry Smith PetscFunctionBegin; 2223d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22244f572ea9SToby Isaac PetscAssertPointer(array, 2); 22255c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 22263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22278572280aSBarry Smith } 22288572280aSBarry Smith 22298572280aSBarry Smith /*@C 223011a5261eSBarry Smith MatDenseRestoreArrayRead - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayRead()` 22318572280aSBarry Smith 2232fb850c59SBarry Smith Not Collective 223373a71a0fSBarry Smith 223473a71a0fSBarry Smith Input Parameters: 2235fe59aa6dSJacob Faibussowitsch + A - a dense matrix 22362ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`) 223773a71a0fSBarry Smith 223873a71a0fSBarry Smith Level: intermediate 223973a71a0fSBarry Smith 22401cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 224173a71a0fSBarry Smith @*/ 2242ce78bad3SBarry Smith PetscErrorCode MatDenseRestoreArrayRead(Mat A, const PetscScalar *array[]) PeNS 2243d71ae5a4SJacob Faibussowitsch { 224473a71a0fSBarry Smith PetscFunctionBegin; 2245d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22464f572ea9SToby Isaac if (array) PetscAssertPointer(array, 2); 22475c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 22483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 224973a71a0fSBarry Smith } 225073a71a0fSBarry Smith 22516947451fSStefano Zampini /*@C 225211a5261eSBarry Smith MatDenseGetArrayWrite - gives write-only access to the array where the data for a `MATDENSE` matrix is stored 22536947451fSStefano Zampini 2254fb850c59SBarry Smith Not Collective 22556947451fSStefano Zampini 22566947451fSStefano Zampini Input Parameter: 2257fe59aa6dSJacob Faibussowitsch . A - a dense matrix 22586947451fSStefano Zampini 22596947451fSStefano Zampini Output Parameter: 22606947451fSStefano Zampini . array - pointer to the data 22616947451fSStefano Zampini 22626947451fSStefano Zampini Level: intermediate 22636947451fSStefano Zampini 22641cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()` 22656947451fSStefano Zampini @*/ 2266ce78bad3SBarry Smith PetscErrorCode MatDenseGetArrayWrite(Mat A, PetscScalar *array[]) PeNS 2267d71ae5a4SJacob Faibussowitsch { 22686947451fSStefano Zampini PetscFunctionBegin; 2269d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22704f572ea9SToby Isaac PetscAssertPointer(array, 2); 2271cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array)); 22723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22736947451fSStefano Zampini } 22746947451fSStefano Zampini 22756947451fSStefano Zampini /*@C 227611a5261eSBarry Smith MatDenseRestoreArrayWrite - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayWrite()` 22776947451fSStefano Zampini 2278fb850c59SBarry Smith Not Collective 22796947451fSStefano Zampini 22806947451fSStefano Zampini Input Parameters: 2281fe59aa6dSJacob Faibussowitsch + A - a dense matrix 22822ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`) 22836947451fSStefano Zampini 22846947451fSStefano Zampini Level: intermediate 22856947451fSStefano Zampini 22861cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()` 22876947451fSStefano Zampini @*/ 2288ce78bad3SBarry Smith PetscErrorCode MatDenseRestoreArrayWrite(Mat A, PetscScalar *array[]) PeNS 2289d71ae5a4SJacob Faibussowitsch { 22906947451fSStefano Zampini PetscFunctionBegin; 2291d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22924f572ea9SToby Isaac if (array) PetscAssertPointer(array, 2); 2293cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array)); 22949566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)A)); 229547d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 22966947451fSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 22976947451fSStefano Zampini #endif 22983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22996947451fSStefano Zampini } 23006947451fSStefano Zampini 2301cd3f9d89SJunchao Zhang /*@C 2302cd3f9d89SJunchao Zhang MatDenseGetArrayAndMemType - gives read-write access to the array where the data for a `MATDENSE` matrix is stored 2303cd3f9d89SJunchao Zhang 2304cd3f9d89SJunchao Zhang Logically Collective 2305cd3f9d89SJunchao Zhang 2306cd3f9d89SJunchao Zhang Input Parameter: 2307fe59aa6dSJacob Faibussowitsch . A - a dense matrix 2308cd3f9d89SJunchao Zhang 2309cd3f9d89SJunchao Zhang Output Parameters: 2310cd3f9d89SJunchao Zhang + array - pointer to the data 2311cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer 2312cd3f9d89SJunchao Zhang 2313cd3f9d89SJunchao Zhang Level: intermediate 2314cd3f9d89SJunchao Zhang 2315fb850c59SBarry Smith Note: 23162ef1f0ffSBarry Smith If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc., 23172ef1f0ffSBarry Smith an array on device is always returned and is guaranteed to contain the matrix's latest data. 23182ef1f0ffSBarry Smith 23191cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayAndMemType()`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArrayWriteAndMemType()`, `MatDenseGetArrayRead()`, 2320cd3f9d89SJunchao Zhang `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()` 2321cd3f9d89SJunchao Zhang @*/ 23225d83a8b1SBarry Smith PetscErrorCode MatDenseGetArrayAndMemType(Mat A, PetscScalar *array[], PetscMemType *mtype) 2323cd3f9d89SJunchao Zhang { 2324cd3f9d89SJunchao Zhang PetscBool isMPI; 2325cd3f9d89SJunchao Zhang 2326cd3f9d89SJunchao Zhang PetscFunctionBegin; 2327cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 23284f572ea9SToby Isaac PetscAssertPointer(array, 2); 2329e865de01SJunchao 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 */ 2330cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2331cd3f9d89SJunchao Zhang if (isMPI) { 2332cd3f9d89SJunchao Zhang /* Dispatch here so that the code can be reused for all subclasses of MATDENSE */ 2333cd3f9d89SJunchao Zhang PetscCall(MatDenseGetArrayAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype)); 2334cd3f9d89SJunchao Zhang } else { 2335cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **, PetscMemType *); 23363ba16761SJacob Faibussowitsch 23373ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayAndMemType_C", &fptr)); 2338cd3f9d89SJunchao Zhang if (fptr) { 2339cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array, mtype)); 2340cd3f9d89SJunchao Zhang } else { 2341cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array)); 2342cd3f9d89SJunchao Zhang if (mtype) *mtype = PETSC_MEMTYPE_HOST; 2343cd3f9d89SJunchao Zhang } 2344cd3f9d89SJunchao Zhang } 23453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2346cd3f9d89SJunchao Zhang } 2347cd3f9d89SJunchao Zhang 2348cd3f9d89SJunchao Zhang /*@C 2349cd3f9d89SJunchao Zhang MatDenseRestoreArrayAndMemType - returns access to the array that is obtained by `MatDenseGetArrayAndMemType()` 2350cd3f9d89SJunchao Zhang 2351cd3f9d89SJunchao Zhang Logically Collective 2352cd3f9d89SJunchao Zhang 2353cd3f9d89SJunchao Zhang Input Parameters: 2354fe59aa6dSJacob Faibussowitsch + A - a dense matrix 2355cd3f9d89SJunchao Zhang - array - pointer to the data 2356cd3f9d89SJunchao Zhang 2357cd3f9d89SJunchao Zhang Level: intermediate 2358cd3f9d89SJunchao Zhang 23591cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 2360cd3f9d89SJunchao Zhang @*/ 23615d83a8b1SBarry Smith PetscErrorCode MatDenseRestoreArrayAndMemType(Mat A, PetscScalar *array[]) 2362cd3f9d89SJunchao Zhang { 2363cd3f9d89SJunchao Zhang PetscBool isMPI; 2364cd3f9d89SJunchao Zhang 2365cd3f9d89SJunchao Zhang PetscFunctionBegin; 2366cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2367fd5c2d83SStefano Zampini if (array) PetscAssertPointer(array, 2); 2368cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2369cd3f9d89SJunchao Zhang if (isMPI) { 2370cd3f9d89SJunchao Zhang PetscCall(MatDenseRestoreArrayAndMemType(((Mat_MPIDense *)A->data)->A, array)); 2371cd3f9d89SJunchao Zhang } else { 2372cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **); 23733ba16761SJacob Faibussowitsch 23743ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayAndMemType_C", &fptr)); 2375cd3f9d89SJunchao Zhang if (fptr) { 2376cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array)); 2377cd3f9d89SJunchao Zhang } else { 2378cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array)); 2379cd3f9d89SJunchao Zhang } 2380fd5c2d83SStefano Zampini if (array) *array = NULL; 2381cd3f9d89SJunchao Zhang } 2382cd3f9d89SJunchao Zhang PetscCall(PetscObjectStateIncrease((PetscObject)A)); 23833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2384cd3f9d89SJunchao Zhang } 2385cd3f9d89SJunchao Zhang 2386cd3f9d89SJunchao Zhang /*@C 2387cd3f9d89SJunchao Zhang MatDenseGetArrayReadAndMemType - gives read-only access to the array where the data for a `MATDENSE` matrix is stored 2388cd3f9d89SJunchao Zhang 2389cd3f9d89SJunchao Zhang Logically Collective 2390cd3f9d89SJunchao Zhang 2391cd3f9d89SJunchao Zhang Input Parameter: 2392fe59aa6dSJacob Faibussowitsch . A - a dense matrix 2393cd3f9d89SJunchao Zhang 2394cd3f9d89SJunchao Zhang Output Parameters: 2395cd3f9d89SJunchao Zhang + array - pointer to the data 2396cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer 2397cd3f9d89SJunchao Zhang 2398cd3f9d89SJunchao Zhang Level: intermediate 2399cd3f9d89SJunchao Zhang 2400fb850c59SBarry Smith Note: 24012ef1f0ffSBarry Smith If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc., 24022ef1f0ffSBarry Smith an array on device is always returned and is guaranteed to contain the matrix's latest data. 24032ef1f0ffSBarry Smith 24041cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayReadAndMemType()`, `MatDenseGetArrayWriteAndMemType()`, 2405cd3f9d89SJunchao Zhang `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()` 2406cd3f9d89SJunchao Zhang @*/ 24075d83a8b1SBarry Smith PetscErrorCode MatDenseGetArrayReadAndMemType(Mat A, const PetscScalar *array[], PetscMemType *mtype) 2408cd3f9d89SJunchao Zhang { 2409cd3f9d89SJunchao Zhang PetscBool isMPI; 2410cd3f9d89SJunchao Zhang 2411cd3f9d89SJunchao Zhang PetscFunctionBegin; 2412cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 24134f572ea9SToby Isaac PetscAssertPointer(array, 2); 2414e865de01SJunchao 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 */ 2415cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2416cd3f9d89SJunchao Zhang if (isMPI) { /* Dispatch here so that the code can be reused for all subclasses of MATDENSE */ 2417cd3f9d89SJunchao Zhang PetscCall(MatDenseGetArrayReadAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype)); 2418cd3f9d89SJunchao Zhang } else { 2419cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, const PetscScalar **, PetscMemType *); 24203ba16761SJacob Faibussowitsch 24213ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayReadAndMemType_C", &fptr)); 2422cd3f9d89SJunchao Zhang if (fptr) { 2423cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array, mtype)); 2424cd3f9d89SJunchao Zhang } else { 24255c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 2426cd3f9d89SJunchao Zhang if (mtype) *mtype = PETSC_MEMTYPE_HOST; 2427cd3f9d89SJunchao Zhang } 2428cd3f9d89SJunchao Zhang } 24293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2430cd3f9d89SJunchao Zhang } 2431cd3f9d89SJunchao Zhang 2432cd3f9d89SJunchao Zhang /*@C 2433cd3f9d89SJunchao Zhang MatDenseRestoreArrayReadAndMemType - returns access to the array that is obtained by `MatDenseGetArrayReadAndMemType()` 2434cd3f9d89SJunchao Zhang 2435cd3f9d89SJunchao Zhang Logically Collective 2436cd3f9d89SJunchao Zhang 2437cd3f9d89SJunchao Zhang Input Parameters: 2438fe59aa6dSJacob Faibussowitsch + A - a dense matrix 2439cd3f9d89SJunchao Zhang - array - pointer to the data 2440cd3f9d89SJunchao Zhang 2441cd3f9d89SJunchao Zhang Level: intermediate 2442cd3f9d89SJunchao Zhang 24431cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 2444cd3f9d89SJunchao Zhang @*/ 24455d83a8b1SBarry Smith PetscErrorCode MatDenseRestoreArrayReadAndMemType(Mat A, const PetscScalar *array[]) 2446cd3f9d89SJunchao Zhang { 2447cd3f9d89SJunchao Zhang PetscBool isMPI; 2448cd3f9d89SJunchao Zhang 2449cd3f9d89SJunchao Zhang PetscFunctionBegin; 2450cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2451fd5c2d83SStefano Zampini if (array) PetscAssertPointer(array, 2); 2452cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2453cd3f9d89SJunchao Zhang if (isMPI) { 2454cd3f9d89SJunchao Zhang PetscCall(MatDenseRestoreArrayReadAndMemType(((Mat_MPIDense *)A->data)->A, array)); 2455cd3f9d89SJunchao Zhang } else { 2456cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, const PetscScalar **); 24573ba16761SJacob Faibussowitsch 24583ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayReadAndMemType_C", &fptr)); 2459cd3f9d89SJunchao Zhang if (fptr) { 2460cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array)); 2461cd3f9d89SJunchao Zhang } else { 24625c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 2463cd3f9d89SJunchao Zhang } 2464fd5c2d83SStefano Zampini if (array) *array = NULL; 2465cd3f9d89SJunchao Zhang } 24663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2467cd3f9d89SJunchao Zhang } 2468cd3f9d89SJunchao Zhang 2469cd3f9d89SJunchao Zhang /*@C 2470cd3f9d89SJunchao Zhang MatDenseGetArrayWriteAndMemType - gives write-only access to the array where the data for a `MATDENSE` matrix is stored 2471cd3f9d89SJunchao Zhang 2472cd3f9d89SJunchao Zhang Logically Collective 2473cd3f9d89SJunchao Zhang 2474cd3f9d89SJunchao Zhang Input Parameter: 2475fe59aa6dSJacob Faibussowitsch . A - a dense matrix 2476cd3f9d89SJunchao Zhang 2477cd3f9d89SJunchao Zhang Output Parameters: 2478cd3f9d89SJunchao Zhang + array - pointer to the data 2479cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer 2480cd3f9d89SJunchao Zhang 2481cd3f9d89SJunchao Zhang Level: intermediate 2482cd3f9d89SJunchao Zhang 2483fb850c59SBarry Smith Note: 24842ef1f0ffSBarry Smith If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc., 24852ef1f0ffSBarry Smith an array on device is always returned and is guaranteed to contain the matrix's latest data. 24862ef1f0ffSBarry Smith 24871cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayWriteAndMemType()`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArrayRead()`, 2488cd3f9d89SJunchao Zhang `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()` 2489cd3f9d89SJunchao Zhang @*/ 24905d83a8b1SBarry Smith PetscErrorCode MatDenseGetArrayWriteAndMemType(Mat A, PetscScalar *array[], PetscMemType *mtype) 2491cd3f9d89SJunchao Zhang { 2492cd3f9d89SJunchao Zhang PetscBool isMPI; 2493cd3f9d89SJunchao Zhang 2494cd3f9d89SJunchao Zhang PetscFunctionBegin; 2495cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 24964f572ea9SToby Isaac PetscAssertPointer(array, 2); 2497e865de01SJunchao 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 */ 2498cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2499cd3f9d89SJunchao Zhang if (isMPI) { 2500cd3f9d89SJunchao Zhang PetscCall(MatDenseGetArrayWriteAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype)); 2501cd3f9d89SJunchao Zhang } else { 2502cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **, PetscMemType *); 25033ba16761SJacob Faibussowitsch 25043ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayWriteAndMemType_C", &fptr)); 2505cd3f9d89SJunchao Zhang if (fptr) { 2506cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array, mtype)); 2507cd3f9d89SJunchao Zhang } else { 2508cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array)); 2509cd3f9d89SJunchao Zhang if (mtype) *mtype = PETSC_MEMTYPE_HOST; 2510cd3f9d89SJunchao Zhang } 2511cd3f9d89SJunchao Zhang } 25123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2513cd3f9d89SJunchao Zhang } 2514cd3f9d89SJunchao Zhang 2515cd3f9d89SJunchao Zhang /*@C 2516cd3f9d89SJunchao Zhang MatDenseRestoreArrayWriteAndMemType - returns access to the array that is obtained by `MatDenseGetArrayReadAndMemType()` 2517cd3f9d89SJunchao Zhang 2518cd3f9d89SJunchao Zhang Logically Collective 2519cd3f9d89SJunchao Zhang 2520cd3f9d89SJunchao Zhang Input Parameters: 2521fe59aa6dSJacob Faibussowitsch + A - a dense matrix 2522cd3f9d89SJunchao Zhang - array - pointer to the data 2523cd3f9d89SJunchao Zhang 2524cd3f9d89SJunchao Zhang Level: intermediate 2525cd3f9d89SJunchao Zhang 25261cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayWriteAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 2527cd3f9d89SJunchao Zhang @*/ 25285d83a8b1SBarry Smith PetscErrorCode MatDenseRestoreArrayWriteAndMemType(Mat A, PetscScalar *array[]) 2529cd3f9d89SJunchao Zhang { 2530cd3f9d89SJunchao Zhang PetscBool isMPI; 2531cd3f9d89SJunchao Zhang 2532cd3f9d89SJunchao Zhang PetscFunctionBegin; 2533cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2534fd5c2d83SStefano Zampini if (array) PetscAssertPointer(array, 2); 2535cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2536cd3f9d89SJunchao Zhang if (isMPI) { 2537cd3f9d89SJunchao Zhang PetscCall(MatDenseRestoreArrayWriteAndMemType(((Mat_MPIDense *)A->data)->A, array)); 2538cd3f9d89SJunchao Zhang } else { 2539cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **); 25403ba16761SJacob Faibussowitsch 25413ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayWriteAndMemType_C", &fptr)); 2542cd3f9d89SJunchao Zhang if (fptr) { 2543cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array)); 2544cd3f9d89SJunchao Zhang } else { 2545cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array)); 2546cd3f9d89SJunchao Zhang } 2547fd5c2d83SStefano Zampini if (array) *array = NULL; 2548cd3f9d89SJunchao Zhang } 2549cd3f9d89SJunchao Zhang PetscCall(PetscObjectStateIncrease((PetscObject)A)); 25503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2551cd3f9d89SJunchao Zhang } 2552cd3f9d89SJunchao Zhang 2553d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A, IS isrow, IS iscol, MatReuse scall, Mat *B) 2554d71ae5a4SJacob Faibussowitsch { 2555c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 2556bf5a80bcSToby Isaac PetscInt i, j, nrows, ncols, ldb; 25575d0c19d7SBarry Smith const PetscInt *irow, *icol; 255887828ca2SBarry Smith PetscScalar *av, *bv, *v = mat->v; 25590754003eSLois Curfman McInnes Mat newmat; 25600754003eSLois Curfman McInnes 25613a40ed3dSBarry Smith PetscFunctionBegin; 25629566063dSJacob Faibussowitsch PetscCall(ISGetIndices(isrow, &irow)); 25639566063dSJacob Faibussowitsch PetscCall(ISGetIndices(iscol, &icol)); 25649566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(isrow, &nrows)); 25659566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(iscol, &ncols)); 25660754003eSLois Curfman McInnes 2567182d2002SSatish Balay /* Check submatrixcall */ 2568182d2002SSatish Balay if (scall == MAT_REUSE_MATRIX) { 256913f74950SBarry Smith PetscInt n_cols, n_rows; 25709566063dSJacob Faibussowitsch PetscCall(MatGetSize(*B, &n_rows, &n_cols)); 257121a2c019SBarry Smith if (n_rows != nrows || n_cols != ncols) { 2572f746d493SDmitry Karpeev /* resize the result matrix to match number of requested rows/columns */ 25739566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*B, nrows, ncols, nrows, ncols)); 257421a2c019SBarry Smith } 2575182d2002SSatish Balay newmat = *B; 2576182d2002SSatish Balay } else { 25770754003eSLois Curfman McInnes /* Create and fill new matrix */ 25789566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &newmat)); 25799566063dSJacob Faibussowitsch PetscCall(MatSetSizes(newmat, nrows, ncols, nrows, ncols)); 25809566063dSJacob Faibussowitsch PetscCall(MatSetType(newmat, ((PetscObject)A)->type_name)); 25819566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(newmat, NULL)); 2582182d2002SSatish Balay } 2583182d2002SSatish Balay 2584182d2002SSatish Balay /* Now extract the data pointers and do the copy,column at a time */ 25859566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(newmat, &bv)); 25869566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(newmat, &ldb)); 2587182d2002SSatish Balay for (i = 0; i < ncols; i++) { 25886de62eeeSBarry Smith av = v + mat->lda * icol[i]; 2589ca15aa20SStefano Zampini for (j = 0; j < nrows; j++) bv[j] = av[irow[j]]; 2590bf5a80bcSToby Isaac bv += ldb; 25910754003eSLois Curfman McInnes } 25929566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(newmat, &bv)); 2593182d2002SSatish Balay 2594182d2002SSatish Balay /* Assemble the matrices so that the correct flags are set */ 25959566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(newmat, MAT_FINAL_ASSEMBLY)); 25969566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(newmat, MAT_FINAL_ASSEMBLY)); 25970754003eSLois Curfman McInnes 25980754003eSLois Curfman McInnes /* Free work space */ 25999566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(isrow, &irow)); 26009566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(iscol, &icol)); 2601182d2002SSatish Balay *B = newmat; 26023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26030754003eSLois Curfman McInnes } 26040754003eSLois Curfman McInnes 2605d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A, PetscInt n, const IS irow[], const IS icol[], MatReuse scall, Mat *B[]) 2606d71ae5a4SJacob Faibussowitsch { 260713f74950SBarry Smith PetscInt i; 2608905e6a2fSBarry Smith 26093a40ed3dSBarry Smith PetscFunctionBegin; 261048a46eb9SPierre Jolivet if (scall == MAT_INITIAL_MATRIX) PetscCall(PetscCalloc1(n, B)); 2611905e6a2fSBarry Smith 261248a46eb9SPierre Jolivet for (i = 0; i < n; i++) PetscCall(MatCreateSubMatrix_SeqDense(A, irow[i], icol[i], scall, &(*B)[i])); 26133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2614905e6a2fSBarry Smith } 2615905e6a2fSBarry Smith 2616d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCopy_SeqDense(Mat A, Mat B, MatStructure str) 2617d71ae5a4SJacob Faibussowitsch { 26184b0e389bSBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data; 2619ca15aa20SStefano Zampini const PetscScalar *va; 2620ca15aa20SStefano Zampini PetscScalar *vb; 2621d0f46423SBarry Smith PetscInt lda1 = a->lda, lda2 = b->lda, m = A->rmap->n, n = A->cmap->n, j; 26223a40ed3dSBarry Smith 26233a40ed3dSBarry Smith PetscFunctionBegin; 262433f4a19fSKris Buschelman /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */ 262533f4a19fSKris Buschelman if (A->ops->copy != B->ops->copy) { 26269566063dSJacob Faibussowitsch PetscCall(MatCopy_Basic(A, B, str)); 26273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26283a40ed3dSBarry Smith } 2629aed4548fSBarry Smith PetscCheck(m == B->rmap->n && n == B->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "size(B) != size(A)"); 26309566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &va)); 26319566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(B, &vb)); 2632a5ce6ee0Svictorle if (lda1 > m || lda2 > m) { 263348a46eb9SPierre Jolivet for (j = 0; j < n; j++) PetscCall(PetscArraycpy(vb + j * lda2, va + j * lda1, m)); 2634a5ce6ee0Svictorle } else { 26359566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(vb, va, A->rmap->n * A->cmap->n)); 2636a5ce6ee0Svictorle } 26379566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(B, &vb)); 26389566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &va)); 26399566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 26409566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 26413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2642273d9f13SBarry Smith } 2643273d9f13SBarry Smith 2644d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetUp_SeqDense(Mat A) 2645d71ae5a4SJacob Faibussowitsch { 2646273d9f13SBarry Smith PetscFunctionBegin; 26479566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 26489566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 264948a46eb9SPierre Jolivet if (!A->preallocated) PetscCall(MatSeqDenseSetPreallocation(A, NULL)); 26503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26514b0e389bSBarry Smith } 26524b0e389bSBarry Smith 26533853def2SToby Isaac PetscErrorCode MatConjugate_SeqDense(Mat A) 2654d71ae5a4SJacob Faibussowitsch { 26554396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 265606c5243aSJose E. Roman PetscInt i, j; 26574396437dSToby Isaac PetscInt min = PetscMin(A->rmap->n, A->cmap->n); 2658ca15aa20SStefano Zampini PetscScalar *aa; 2659ba337c44SJed Brown 2660ba337c44SJed Brown PetscFunctionBegin; 26619566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 266206c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 266306c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscConj(aa[i + j * mat->lda]); 266406c5243aSJose E. Roman } 26659566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 26669371c9d4SSatish Balay if (mat->tau) 26679371c9d4SSatish Balay for (i = 0; i < min; i++) mat->tau[i] = PetscConj(mat->tau[i]); 26683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2669ba337c44SJed Brown } 2670ba337c44SJed Brown 2671d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRealPart_SeqDense(Mat A) 2672d71ae5a4SJacob Faibussowitsch { 267306c5243aSJose E. Roman Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 267406c5243aSJose E. Roman PetscInt i, j; 2675ca15aa20SStefano Zampini PetscScalar *aa; 2676ba337c44SJed Brown 2677ba337c44SJed Brown PetscFunctionBegin; 26789566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 267906c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 268006c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscRealPart(aa[i + j * mat->lda]); 268106c5243aSJose E. Roman } 26829566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 26833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2684ba337c44SJed Brown } 2685ba337c44SJed Brown 2686d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatImaginaryPart_SeqDense(Mat A) 2687d71ae5a4SJacob Faibussowitsch { 268806c5243aSJose E. Roman Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 268906c5243aSJose E. Roman PetscInt i, j; 2690ca15aa20SStefano Zampini PetscScalar *aa; 2691ba337c44SJed Brown 2692ba337c44SJed Brown PetscFunctionBegin; 26939566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 269406c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 269506c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscImaginaryPart(aa[i + j * mat->lda]); 269606c5243aSJose E. Roman } 26979566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 26983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2699ba337c44SJed Brown } 2700284134d9SBarry Smith 2701d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2702d71ae5a4SJacob Faibussowitsch { 2703d0f46423SBarry Smith PetscInt m = A->rmap->n, n = B->cmap->n; 270447d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 2705a9fe9ddaSSatish Balay 2706ee16a9a1SHong Zhang PetscFunctionBegin; 27079566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 270847d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 27099566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 271047d993e7Ssuyashtn #endif 271147d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 271247d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 271347d993e7Ssuyashtn #endif 27147a3c3d58SStefano Zampini if (!cisdense) { 27157a3c3d58SStefano Zampini PetscBool flg; 27167a3c3d58SStefano Zampini 27179566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 27189566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 27197a3c3d58SStefano Zampini } 27209566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 27213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2722ee16a9a1SHong Zhang } 2723a9fe9ddaSSatish Balay 2724d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2725d71ae5a4SJacob Faibussowitsch { 27266718818eSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data, *c = (Mat_SeqDense *)C->data; 27270805154bSBarry Smith PetscBLASInt m, n, k; 2728ca15aa20SStefano Zampini const PetscScalar *av, *bv; 2729ca15aa20SStefano Zampini PetscScalar *cv; 2730a9fe9ddaSSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 2731a9fe9ddaSSatish Balay 2732a9fe9ddaSSatish Balay PetscFunctionBegin; 27339566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 27349566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 27359566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 27363ba16761SJacob Faibussowitsch if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS); 27379566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 27389566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 27399566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2740792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("N", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 27419566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 27429566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 27439566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 27449566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 27453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2746a9fe9ddaSSatish Balay } 2747a9fe9ddaSSatish Balay 2748d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2749d71ae5a4SJacob Faibussowitsch { 275069f65d41SStefano Zampini PetscInt m = A->rmap->n, n = B->rmap->n; 275147d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 275269f65d41SStefano Zampini 275369f65d41SStefano Zampini PetscFunctionBegin; 27549566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 275547d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 27569566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 275747d993e7Ssuyashtn #endif 275847d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 275947d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 276047d993e7Ssuyashtn #endif 27617a3c3d58SStefano Zampini if (!cisdense) { 27627a3c3d58SStefano Zampini PetscBool flg; 27637a3c3d58SStefano Zampini 27649566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 27659566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 27667a3c3d58SStefano Zampini } 27679566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 27683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 276969f65d41SStefano Zampini } 277069f65d41SStefano Zampini 2771d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2772d71ae5a4SJacob Faibussowitsch { 277369f65d41SStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 277469f65d41SStefano Zampini Mat_SeqDense *b = (Mat_SeqDense *)B->data; 277569f65d41SStefano Zampini Mat_SeqDense *c = (Mat_SeqDense *)C->data; 27766718818eSStefano Zampini const PetscScalar *av, *bv; 27776718818eSStefano Zampini PetscScalar *cv; 277869f65d41SStefano Zampini PetscBLASInt m, n, k; 277969f65d41SStefano Zampini PetscScalar _DOne = 1.0, _DZero = 0.0; 278069f65d41SStefano Zampini 278169f65d41SStefano Zampini PetscFunctionBegin; 27829566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 27839566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 27849566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 27853ba16761SJacob Faibussowitsch if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS); 27869566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 27879566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 27889566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2789792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("N", "T", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 27909566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 27919566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 27929566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 27939566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 27943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 279569f65d41SStefano Zampini } 279669f65d41SStefano Zampini 2797d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2798d71ae5a4SJacob Faibussowitsch { 2799d0f46423SBarry Smith PetscInt m = A->cmap->n, n = B->cmap->n; 280047d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 2801a9fe9ddaSSatish Balay 2802ee16a9a1SHong Zhang PetscFunctionBegin; 28039566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 280447d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 28059566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 280647d993e7Ssuyashtn #endif 280747d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 280847d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 280947d993e7Ssuyashtn #endif 28107a3c3d58SStefano Zampini if (!cisdense) { 28117a3c3d58SStefano Zampini PetscBool flg; 28127a3c3d58SStefano Zampini 28139566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 28149566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 28157a3c3d58SStefano Zampini } 28169566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 28173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2818ee16a9a1SHong Zhang } 2819a9fe9ddaSSatish Balay 2820d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2821d71ae5a4SJacob Faibussowitsch { 2822a9fe9ddaSSatish Balay Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2823a9fe9ddaSSatish Balay Mat_SeqDense *b = (Mat_SeqDense *)B->data; 2824a9fe9ddaSSatish Balay Mat_SeqDense *c = (Mat_SeqDense *)C->data; 28256718818eSStefano Zampini const PetscScalar *av, *bv; 28266718818eSStefano Zampini PetscScalar *cv; 28270805154bSBarry Smith PetscBLASInt m, n, k; 2828a9fe9ddaSSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 2829a9fe9ddaSSatish Balay 2830a9fe9ddaSSatish Balay PetscFunctionBegin; 28319566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 28329566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 28339566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &k)); 28343ba16761SJacob Faibussowitsch if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS); 28359566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 28369566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 28379566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2838792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("T", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 28399566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 28409566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 28419566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 28429566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 28433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2844a9fe9ddaSSatish Balay } 2845985db425SBarry Smith 2846d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C) 2847d71ae5a4SJacob Faibussowitsch { 28484222ddf1SHong Zhang PetscFunctionBegin; 28494222ddf1SHong Zhang C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense; 28504222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AB; 28513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28524222ddf1SHong Zhang } 28534222ddf1SHong Zhang 2854d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C) 2855d71ae5a4SJacob Faibussowitsch { 28564222ddf1SHong Zhang PetscFunctionBegin; 28574222ddf1SHong Zhang C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense; 28584222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AtB; 28593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28604222ddf1SHong Zhang } 28614222ddf1SHong Zhang 2862d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C) 2863d71ae5a4SJacob Faibussowitsch { 28644222ddf1SHong Zhang PetscFunctionBegin; 28654222ddf1SHong Zhang C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense; 28664222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_ABt; 28673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28684222ddf1SHong Zhang } 28694222ddf1SHong Zhang 2870d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C) 2871d71ae5a4SJacob Faibussowitsch { 28724222ddf1SHong Zhang Mat_Product *product = C->product; 28734222ddf1SHong Zhang 28744222ddf1SHong Zhang PetscFunctionBegin; 28754222ddf1SHong Zhang switch (product->type) { 2876d71ae5a4SJacob Faibussowitsch case MATPRODUCT_AB: 2877d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_AB(C)); 2878d71ae5a4SJacob Faibussowitsch break; 2879d71ae5a4SJacob Faibussowitsch case MATPRODUCT_AtB: 2880d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_AtB(C)); 2881d71ae5a4SJacob Faibussowitsch break; 2882d71ae5a4SJacob Faibussowitsch case MATPRODUCT_ABt: 2883d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_ABt(C)); 2884d71ae5a4SJacob Faibussowitsch break; 2885d71ae5a4SJacob Faibussowitsch default: 2886d71ae5a4SJacob Faibussowitsch break; 28874222ddf1SHong Zhang } 28883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28894222ddf1SHong Zhang } 28904222ddf1SHong Zhang 2891d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMax_SeqDense(Mat A, Vec v, PetscInt idx[]) 2892d71ae5a4SJacob Faibussowitsch { 2893985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2894d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2895985db425SBarry Smith PetscScalar *x; 2896ca15aa20SStefano Zampini const PetscScalar *aa; 2897985db425SBarry Smith 2898985db425SBarry Smith PetscFunctionBegin; 289928b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29009566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29019566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 29029566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 290308401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2904985db425SBarry Smith for (i = 0; i < m; i++) { 29059371c9d4SSatish Balay x[i] = aa[i]; 29069371c9d4SSatish Balay if (idx) idx[i] = 0; 2907985db425SBarry Smith for (j = 1; j < n; j++) { 29089371c9d4SSatish Balay if (PetscRealPart(x[i]) < PetscRealPart(aa[i + a->lda * j])) { 29099371c9d4SSatish Balay x[i] = aa[i + a->lda * j]; 29109371c9d4SSatish Balay if (idx) idx[i] = j; 29119371c9d4SSatish Balay } 2912985db425SBarry Smith } 2913985db425SBarry Smith } 29149566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 29159566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 29163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2917985db425SBarry Smith } 2918985db425SBarry Smith 2919d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A, Vec v, PetscInt idx[]) 2920d71ae5a4SJacob Faibussowitsch { 2921985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2922d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2923985db425SBarry Smith PetscScalar *x; 2924985db425SBarry Smith PetscReal atmp; 2925ca15aa20SStefano Zampini const PetscScalar *aa; 2926985db425SBarry Smith 2927985db425SBarry Smith PetscFunctionBegin; 292828b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29299566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29309566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 29319566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 293208401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2933985db425SBarry Smith for (i = 0; i < m; i++) { 29349189402eSHong Zhang x[i] = PetscAbsScalar(aa[i]); 2935985db425SBarry Smith for (j = 1; j < n; j++) { 2936ca15aa20SStefano Zampini atmp = PetscAbsScalar(aa[i + a->lda * j]); 29379371c9d4SSatish Balay if (PetscAbsScalar(x[i]) < atmp) { 29389371c9d4SSatish Balay x[i] = atmp; 29399371c9d4SSatish Balay if (idx) idx[i] = j; 29409371c9d4SSatish Balay } 2941985db425SBarry Smith } 2942985db425SBarry Smith } 29439566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 29449566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 29453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2946985db425SBarry Smith } 2947985db425SBarry Smith 2948d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMin_SeqDense(Mat A, Vec v, PetscInt idx[]) 2949d71ae5a4SJacob Faibussowitsch { 2950985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2951d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2952985db425SBarry Smith PetscScalar *x; 2953ca15aa20SStefano Zampini const PetscScalar *aa; 2954985db425SBarry Smith 2955985db425SBarry Smith PetscFunctionBegin; 295628b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29579566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 29589566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29599566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 296008401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2961985db425SBarry Smith for (i = 0; i < m; i++) { 29629371c9d4SSatish Balay x[i] = aa[i]; 29639371c9d4SSatish Balay if (idx) idx[i] = 0; 2964985db425SBarry Smith for (j = 1; j < n; j++) { 29659371c9d4SSatish Balay if (PetscRealPart(x[i]) > PetscRealPart(aa[i + a->lda * j])) { 29669371c9d4SSatish Balay x[i] = aa[i + a->lda * j]; 29679371c9d4SSatish Balay if (idx) idx[i] = j; 29689371c9d4SSatish Balay } 2969985db425SBarry Smith } 2970985db425SBarry Smith } 29719566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 29729566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 29733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2974985db425SBarry Smith } 2975985db425SBarry Smith 2976d71ae5a4SJacob Faibussowitsch PetscErrorCode MatGetColumnVector_SeqDense(Mat A, Vec v, PetscInt col) 2977d71ae5a4SJacob Faibussowitsch { 29788d0534beSBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 29798d0534beSBarry Smith PetscScalar *x; 2980ca15aa20SStefano Zampini const PetscScalar *aa; 29818d0534beSBarry Smith 29828d0534beSBarry Smith PetscFunctionBegin; 298328b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29849566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 29859566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29869566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(x, aa + col * a->lda, A->rmap->n)); 29879566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 29889566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 29893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29908d0534beSBarry Smith } 29918d0534beSBarry Smith 2992d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatGetColumnReductions_SeqDense(Mat A, PetscInt type, PetscReal *reductions) 2993d71ae5a4SJacob Faibussowitsch { 29940716a85fSBarry Smith PetscInt i, j, m, n; 29951683a169SBarry Smith const PetscScalar *a; 29960716a85fSBarry Smith 29970716a85fSBarry Smith PetscFunctionBegin; 29989566063dSJacob Faibussowitsch PetscCall(MatGetSize(A, &m, &n)); 29999566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(reductions, n)); 30009566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &a)); 3001857cbf51SRichard Tran Mills if (type == NORM_2) { 30020716a85fSBarry Smith for (i = 0; i < n; i++) { 3003ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j] * a[j]); 300416cd844bSPierre Jolivet a = PetscSafePointerPlusOffset(a, m); 30050716a85fSBarry Smith } 3006857cbf51SRichard Tran Mills } else if (type == NORM_1) { 30070716a85fSBarry Smith for (i = 0; i < n; i++) { 3008ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j]); 300916cd844bSPierre Jolivet a = PetscSafePointerPlusOffset(a, m); 30100716a85fSBarry Smith } 3011857cbf51SRichard Tran Mills } else if (type == NORM_INFINITY) { 30120716a85fSBarry Smith for (i = 0; i < n; i++) { 3013ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] = PetscMax(PetscAbsScalar(a[j]), reductions[i]); 301416cd844bSPierre Jolivet a = PetscSafePointerPlusOffset(a, m); 30150716a85fSBarry Smith } 3016857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_REALPART || type == REDUCTION_MEAN_REALPART) { 3017a873a8cdSSam Reynolds for (i = 0; i < n; i++) { 3018ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscRealPart(a[j]); 301916cd844bSPierre Jolivet a = PetscSafePointerPlusOffset(a, m); 3020a873a8cdSSam Reynolds } 3021857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_IMAGINARYPART || type == REDUCTION_MEAN_IMAGINARYPART) { 3022857cbf51SRichard Tran Mills for (i = 0; i < n; i++) { 3023ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscImaginaryPart(a[j]); 302416cd844bSPierre Jolivet a = PetscSafePointerPlusOffset(a, m); 3025857cbf51SRichard Tran Mills } 3026857cbf51SRichard Tran Mills } else SETERRQ(PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Unknown reduction type"); 30279566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &a)); 3028857cbf51SRichard Tran Mills if (type == NORM_2) { 3029a873a8cdSSam Reynolds for (i = 0; i < n; i++) reductions[i] = PetscSqrtReal(reductions[i]); 3030857cbf51SRichard Tran Mills } else if (type == REDUCTION_MEAN_REALPART || type == REDUCTION_MEAN_IMAGINARYPART) { 3031a873a8cdSSam Reynolds for (i = 0; i < n; i++) reductions[i] /= m; 30320716a85fSBarry Smith } 30333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30340716a85fSBarry Smith } 30350716a85fSBarry Smith 3036d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetRandom_SeqDense(Mat x, PetscRandom rctx) 3037d71ae5a4SJacob Faibussowitsch { 303873a71a0fSBarry Smith PetscScalar *a; 3039637a0070SStefano Zampini PetscInt lda, m, n, i, j; 304073a71a0fSBarry Smith 304173a71a0fSBarry Smith PetscFunctionBegin; 30429566063dSJacob Faibussowitsch PetscCall(MatGetSize(x, &m, &n)); 30439566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(x, &lda)); 30443faff063SStefano Zampini PetscCall(MatDenseGetArrayWrite(x, &a)); 3045637a0070SStefano Zampini for (j = 0; j < n; j++) { 304648a46eb9SPierre Jolivet for (i = 0; i < m; i++) PetscCall(PetscRandomGetValue(rctx, a + j * lda + i)); 304773a71a0fSBarry Smith } 30483faff063SStefano Zampini PetscCall(MatDenseRestoreArrayWrite(x, &a)); 30493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 305073a71a0fSBarry Smith } 305173a71a0fSBarry Smith 3052d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A, PetscBool *missing, PetscInt *d) 3053d71ae5a4SJacob Faibussowitsch { 30543b49f96aSBarry Smith PetscFunctionBegin; 30553b49f96aSBarry Smith *missing = PETSC_FALSE; 30563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30573b49f96aSBarry Smith } 305873a71a0fSBarry Smith 3059ca15aa20SStefano Zampini /* vals is not const */ 3060d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A, PetscInt col, PetscScalar **vals) 3061d71ae5a4SJacob Faibussowitsch { 306286aefd0dSHong Zhang Mat_SeqDense *a = (Mat_SeqDense *)A->data; 3063ca15aa20SStefano Zampini PetscScalar *v; 306486aefd0dSHong Zhang 306586aefd0dSHong Zhang PetscFunctionBegin; 306628b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 30679566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 3068ca15aa20SStefano Zampini *vals = v + col * a->lda; 30699566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 30703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 307186aefd0dSHong Zhang } 307286aefd0dSHong Zhang 3073d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A, PetscScalar **vals) 3074d71ae5a4SJacob Faibussowitsch { 307586aefd0dSHong Zhang PetscFunctionBegin; 3076742765d3SMatthew Knepley if (vals) *vals = NULL; /* user cannot accidentally use the array later */ 30773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 307886aefd0dSHong Zhang } 3079abc3b08eSStefano Zampini 3080a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqDense, 3081905e6a2fSBarry Smith MatGetRow_SeqDense, 3082905e6a2fSBarry Smith MatRestoreRow_SeqDense, 3083905e6a2fSBarry Smith MatMult_SeqDense, 308497304618SKris Buschelman /* 4*/ MatMultAdd_SeqDense, 30857c922b88SBarry Smith MatMultTranspose_SeqDense, 30867c922b88SBarry Smith MatMultTransposeAdd_SeqDense, 3087f4259b30SLisandro Dalcin NULL, 3088f4259b30SLisandro Dalcin NULL, 3089f4259b30SLisandro Dalcin NULL, 3090f4259b30SLisandro Dalcin /* 10*/ NULL, 3091905e6a2fSBarry Smith MatLUFactor_SeqDense, 3092905e6a2fSBarry Smith MatCholeskyFactor_SeqDense, 309341f059aeSBarry Smith MatSOR_SeqDense, 3094ec8511deSBarry Smith MatTranspose_SeqDense, 309597304618SKris Buschelman /* 15*/ MatGetInfo_SeqDense, 3096905e6a2fSBarry Smith MatEqual_SeqDense, 3097905e6a2fSBarry Smith MatGetDiagonal_SeqDense, 3098905e6a2fSBarry Smith MatDiagonalScale_SeqDense, 3099905e6a2fSBarry Smith MatNorm_SeqDense, 3100b7103cf4SPierre Jolivet /* 20*/ NULL, 3101b7103cf4SPierre Jolivet NULL, 3102905e6a2fSBarry Smith MatSetOption_SeqDense, 3103905e6a2fSBarry Smith MatZeroEntries_SeqDense, 3104d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqDense, 3105f4259b30SLisandro Dalcin NULL, 3106f4259b30SLisandro Dalcin NULL, 3107f4259b30SLisandro Dalcin NULL, 3108f4259b30SLisandro Dalcin NULL, 31094994cf47SJed Brown /* 29*/ MatSetUp_SeqDense, 3110f4259b30SLisandro Dalcin NULL, 3111f4259b30SLisandro Dalcin NULL, 3112f4259b30SLisandro Dalcin NULL, 3113f4259b30SLisandro Dalcin NULL, 3114d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqDense, 3115f4259b30SLisandro Dalcin NULL, 3116f4259b30SLisandro Dalcin NULL, 3117f4259b30SLisandro Dalcin NULL, 3118f4259b30SLisandro Dalcin NULL, 3119d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqDense, 31207dae84e0SHong Zhang MatCreateSubMatrices_SeqDense, 3121f4259b30SLisandro Dalcin NULL, 31224b0e389bSBarry Smith MatGetValues_SeqDense, 3123a5ae1ecdSBarry Smith MatCopy_SeqDense, 3124d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqDense, 3125a5ae1ecdSBarry Smith MatScale_SeqDense, 31262f605a99SJose E. Roman MatShift_SeqDense, 3127f4259b30SLisandro Dalcin NULL, 31283f49a652SStefano Zampini MatZeroRowsColumns_SeqDense, 312973a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqDense, 3130f4259b30SLisandro Dalcin NULL, 3131f4259b30SLisandro Dalcin NULL, 3132f4259b30SLisandro Dalcin NULL, 3133f4259b30SLisandro Dalcin NULL, 3134f4259b30SLisandro Dalcin /* 54*/ NULL, 3135f4259b30SLisandro Dalcin NULL, 3136f4259b30SLisandro Dalcin NULL, 3137f4259b30SLisandro Dalcin NULL, 3138f4259b30SLisandro Dalcin NULL, 3139023c16fcSToby Isaac /* 59*/ MatCreateSubMatrix_SeqDense, 3140e03a110bSBarry Smith MatDestroy_SeqDense, 3141e03a110bSBarry Smith MatView_SeqDense, 3142f4259b30SLisandro Dalcin NULL, 3143f4259b30SLisandro Dalcin NULL, 3144f4259b30SLisandro Dalcin /* 64*/ NULL, 3145f4259b30SLisandro Dalcin NULL, 3146f4259b30SLisandro Dalcin NULL, 3147f4259b30SLisandro Dalcin NULL, 31488bb0f5c6SPierre Jolivet MatGetRowMaxAbs_SeqDense, 31498bb0f5c6SPierre Jolivet /* 69*/ NULL, 3150f4259b30SLisandro Dalcin NULL, 3151f4259b30SLisandro Dalcin NULL, 3152f4259b30SLisandro Dalcin NULL, 3153f4259b30SLisandro Dalcin NULL, 3154f4259b30SLisandro Dalcin /* 74*/ NULL, 3155f4259b30SLisandro Dalcin NULL, 3156f4259b30SLisandro Dalcin NULL, 3157f4259b30SLisandro Dalcin NULL, 31588bb0f5c6SPierre Jolivet MatLoad_SeqDense, 31598bb0f5c6SPierre Jolivet /* 79*/ MatIsSymmetric_SeqDense, 31601cbb95d3SBarry Smith MatIsHermitian_SeqDense, 3161f4259b30SLisandro Dalcin NULL, 3162f4259b30SLisandro Dalcin NULL, 3163f4259b30SLisandro Dalcin NULL, 31648bb0f5c6SPierre Jolivet /* 84*/ NULL, 3165a9fe9ddaSSatish Balay MatMatMultNumeric_SeqDense_SeqDense, 3166f4259b30SLisandro Dalcin NULL, 3167f4259b30SLisandro Dalcin NULL, 316869f65d41SStefano Zampini MatMatTransposeMultNumeric_SeqDense_SeqDense, 31698bb0f5c6SPierre Jolivet /* 89*/ NULL, 31708bb0f5c6SPierre Jolivet MatProductSetFromOptions_SeqDense, 3171f4259b30SLisandro Dalcin NULL, 3172f4259b30SLisandro Dalcin NULL, 3173ba337c44SJed Brown MatConjugate_SeqDense, 31748bb0f5c6SPierre Jolivet /* 94*/ NULL, 3175f4259b30SLisandro Dalcin NULL, 3176ba337c44SJed Brown MatRealPart_SeqDense, 3177ba337c44SJed Brown MatImaginaryPart_SeqDense, 3178f4259b30SLisandro Dalcin NULL, 31798bb0f5c6SPierre Jolivet /* 99*/ NULL, 31808bb0f5c6SPierre Jolivet NULL, 31818bb0f5c6SPierre Jolivet NULL, 31828bb0f5c6SPierre Jolivet MatGetRowMin_SeqDense, 31838bb0f5c6SPierre Jolivet MatGetColumnVector_SeqDense, 31848bb0f5c6SPierre Jolivet /*104*/ MatMissingDiagonal_SeqDense, 31858bb0f5c6SPierre Jolivet NULL, 31868bb0f5c6SPierre Jolivet NULL, 31878bb0f5c6SPierre Jolivet NULL, 3188f4259b30SLisandro Dalcin NULL, 3189f4259b30SLisandro Dalcin /*109*/ NULL, 3190f4259b30SLisandro Dalcin NULL, 31918bb0f5c6SPierre Jolivet NULL, 31928bb0f5c6SPierre Jolivet MatMultHermitianTranspose_SeqDense, 31938bb0f5c6SPierre Jolivet MatMultHermitianTransposeAdd_SeqDense, 3194f4259b30SLisandro Dalcin /*114*/ NULL, 3195f4259b30SLisandro Dalcin NULL, 31968bb0f5c6SPierre Jolivet MatGetColumnReductions_SeqDense, 3197f4259b30SLisandro Dalcin NULL, 3198f4259b30SLisandro Dalcin NULL, 3199f4259b30SLisandro Dalcin /*119*/ NULL, 3200f4259b30SLisandro Dalcin NULL, 32018bb0f5c6SPierre Jolivet NULL, 32028bb0f5c6SPierre Jolivet MatTransposeMatMultNumeric_SeqDense_SeqDense, 3203f4259b30SLisandro Dalcin NULL, 3204f4259b30SLisandro Dalcin /*124*/ NULL, 32058bb0f5c6SPierre Jolivet NULL, 3206f4259b30SLisandro Dalcin NULL, 3207f4259b30SLisandro Dalcin NULL, 3208f4259b30SLisandro Dalcin NULL, 3209f4259b30SLisandro Dalcin /*129*/ NULL, 3210f4259b30SLisandro Dalcin NULL, 32118bb0f5c6SPierre Jolivet MatCreateMPIMatConcatenateSeqMat_SeqDense, 3212f4259b30SLisandro Dalcin NULL, 3213f4259b30SLisandro Dalcin NULL, 3214f4259b30SLisandro Dalcin /*134*/ NULL, 3215f4259b30SLisandro Dalcin NULL, 3216f4259b30SLisandro Dalcin NULL, 3217f4259b30SLisandro Dalcin NULL, 3218f4259b30SLisandro Dalcin NULL, 3219f4259b30SLisandro Dalcin /*139*/ NULL, 3220f4259b30SLisandro Dalcin NULL, 3221f4259b30SLisandro Dalcin NULL, 322203db1824SAlex Lindsay NULL, 3223dec0b466SHong Zhang NULL}; 322490ace30eSBarry Smith 32255d83a8b1SBarry Smith /*@ 322611a5261eSBarry Smith MatCreateSeqDense - Creates a `MATSEQDENSE` that 3227fb850c59SBarry Smith is stored in column major order (the usual Fortran format). 3228289bc588SBarry Smith 3229d083f849SBarry Smith Collective 3230db81eaa0SLois Curfman McInnes 323120563c6bSBarry Smith Input Parameters: 323211a5261eSBarry Smith + comm - MPI communicator, set to `PETSC_COMM_SELF` 32330c775827SLois Curfman McInnes . m - number of rows 323418f449edSLois Curfman McInnes . n - number of columns 32352ef1f0ffSBarry Smith - data - optional location of matrix data in column major order. Use `NULL` for PETSc 3236dfc5480cSLois Curfman McInnes to control all matrix memory allocation. 323720563c6bSBarry Smith 323820563c6bSBarry Smith Output Parameter: 323944cd7ae7SLois Curfman McInnes . A - the matrix 324020563c6bSBarry Smith 32412ef1f0ffSBarry Smith Level: intermediate 32422ef1f0ffSBarry Smith 324311a5261eSBarry Smith Note: 324418f449edSLois Curfman McInnes The data input variable is intended primarily for Fortran programmers 324518f449edSLois Curfman McInnes who wish to allocate their own matrix memory space. Most users should 32462ef1f0ffSBarry Smith set `data` = `NULL`. 324718f449edSLois Curfman McInnes 3248fb850c59SBarry Smith Developer Note: 3249fb850c59SBarry Smith Many of the matrix operations for this variant use the BLAS and LAPACK routines. 3250fb850c59SBarry Smith 32511cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()` 325220563c6bSBarry Smith @*/ 32535d83a8b1SBarry Smith PetscErrorCode MatCreateSeqDense(MPI_Comm comm, PetscInt m, PetscInt n, PetscScalar data[], Mat *A) 3254d71ae5a4SJacob Faibussowitsch { 32553a40ed3dSBarry Smith PetscFunctionBegin; 32569566063dSJacob Faibussowitsch PetscCall(MatCreate(comm, A)); 32579566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*A, m, n, m, n)); 32589566063dSJacob Faibussowitsch PetscCall(MatSetType(*A, MATSEQDENSE)); 32599566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(*A, data)); 32603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3261273d9f13SBarry Smith } 3262273d9f13SBarry Smith 32635d83a8b1SBarry Smith /*@ 326411a5261eSBarry Smith MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements of a `MATSEQDENSE` matrix 3265273d9f13SBarry Smith 3266d083f849SBarry Smith Collective 3267273d9f13SBarry Smith 3268273d9f13SBarry Smith Input Parameters: 32691c4f3114SJed Brown + B - the matrix 32702ef1f0ffSBarry Smith - data - the array (or `NULL`) 32712ef1f0ffSBarry Smith 32722ef1f0ffSBarry Smith Level: intermediate 3273273d9f13SBarry Smith 327411a5261eSBarry Smith Note: 3275273d9f13SBarry Smith The data input variable is intended primarily for Fortran programmers 3276273d9f13SBarry Smith who wish to allocate their own matrix memory space. Most users should 3277284134d9SBarry Smith need not call this routine. 3278273d9f13SBarry Smith 32791cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()`, `MatDenseSetLDA()` 3280273d9f13SBarry Smith @*/ 3281d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation(Mat B, PetscScalar data[]) 3282d71ae5a4SJacob Faibussowitsch { 3283a23d5eceSKris Buschelman PetscFunctionBegin; 3284d5ea218eSStefano Zampini PetscValidHeaderSpecific(B, MAT_CLASSID, 1); 3285cac4c232SBarry Smith PetscTryMethod(B, "MatSeqDenseSetPreallocation_C", (Mat, PetscScalar[]), (B, data)); 32863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3287a23d5eceSKris Buschelman } 3288a23d5eceSKris Buschelman 3289d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation_SeqDense(Mat B, PetscScalar *data) 3290d71ae5a4SJacob Faibussowitsch { 3291ad16ce7aSStefano Zampini Mat_SeqDense *b = (Mat_SeqDense *)B->data; 3292273d9f13SBarry Smith 3293273d9f13SBarry Smith PetscFunctionBegin; 329428b400f6SJacob Faibussowitsch PetscCheck(!b->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3295273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 3296a868139aSShri Abhyankar 32979566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(B->rmap)); 32989566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(B->cmap)); 329934ef9618SShri Abhyankar 33006497c311SBarry Smith if (b->lda <= 0) PetscCall(PetscBLASIntCast(B->rmap->n, &b->lda)); 330186d161a7SShri Abhyankar 33029e8f95c4SLisandro Dalcin if (!data) { /* petsc-allocated storage */ 33039566063dSJacob Faibussowitsch if (!b->user_alloc) PetscCall(PetscFree(b->v)); 33049566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((size_t)b->lda * B->cmap->n, &b->v)); 33052205254eSKarl Rupp 33069e8f95c4SLisandro Dalcin b->user_alloc = PETSC_FALSE; 3307273d9f13SBarry Smith } else { /* user-allocated storage */ 33089566063dSJacob Faibussowitsch if (!b->user_alloc) PetscCall(PetscFree(b->v)); 3309273d9f13SBarry Smith b->v = data; 3310273d9f13SBarry Smith b->user_alloc = PETSC_TRUE; 3311273d9f13SBarry Smith } 33120450473dSBarry Smith B->assembled = PETSC_TRUE; 33133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3314273d9f13SBarry Smith } 3315273d9f13SBarry Smith 331665b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 3317d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) 3318d71ae5a4SJacob Faibussowitsch { 3319d77f618aSHong Zhang Mat mat_elemental; 33201683a169SBarry Smith const PetscScalar *array; 33211683a169SBarry Smith PetscScalar *v_colwise; 3322d77f618aSHong Zhang PetscInt M = A->rmap->N, N = A->cmap->N, i, j, k, *rows, *cols; 3323d77f618aSHong Zhang 33248baccfbdSHong Zhang PetscFunctionBegin; 33259566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(M * N, &v_colwise, M, &rows, N, &cols)); 33269566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &array)); 3327d77f618aSHong Zhang /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */ 3328d77f618aSHong Zhang k = 0; 3329d77f618aSHong Zhang for (j = 0; j < N; j++) { 3330d77f618aSHong Zhang cols[j] = j; 3331ad540459SPierre Jolivet for (i = 0; i < M; i++) v_colwise[j * M + i] = array[k++]; 3332d77f618aSHong Zhang } 3333ad540459SPierre Jolivet for (i = 0; i < M; i++) rows[i] = i; 33349566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &array)); 3335d77f618aSHong Zhang 33369566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental)); 33379566063dSJacob Faibussowitsch PetscCall(MatSetSizes(mat_elemental, PETSC_DECIDE, PETSC_DECIDE, M, N)); 33389566063dSJacob Faibussowitsch PetscCall(MatSetType(mat_elemental, MATELEMENTAL)); 33399566063dSJacob Faibussowitsch PetscCall(MatSetUp(mat_elemental)); 3340d77f618aSHong Zhang 3341d77f618aSHong Zhang /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */ 33429566063dSJacob Faibussowitsch PetscCall(MatSetValues(mat_elemental, M, rows, N, cols, v_colwise, ADD_VALUES)); 33439566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY)); 33449566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY)); 33459566063dSJacob Faibussowitsch PetscCall(PetscFree3(v_colwise, rows, cols)); 3346d77f618aSHong Zhang 3347511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 33489566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A, &mat_elemental)); 3349d77f618aSHong Zhang } else { 3350d77f618aSHong Zhang *newmat = mat_elemental; 3351d77f618aSHong Zhang } 33523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 33538baccfbdSHong Zhang } 335465b80a83SHong Zhang #endif 33558baccfbdSHong Zhang 3356d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA_SeqDense(Mat B, PetscInt lda) 3357d71ae5a4SJacob Faibussowitsch { 33581b807ce4Svictorle Mat_SeqDense *b = (Mat_SeqDense *)B->data; 33597422da62SJose E. Roman PetscBool data; 336021a2c019SBarry Smith 33611b807ce4Svictorle PetscFunctionBegin; 3362835f2295SStefano Zampini data = (B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE; 3363aed4548fSBarry Smith PetscCheck(b->user_alloc || !data || b->lda == lda, PETSC_COMM_SELF, PETSC_ERR_ORDER, "LDA cannot be changed after allocation of internal storage"); 336408401ef6SPierre 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); 33656497c311SBarry Smith PetscCall(PetscBLASIntCast(lda, &b->lda)); 33663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 33671b807ce4Svictorle } 33681b807ce4Svictorle 3369d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm, Mat inmat, PetscInt n, MatReuse scall, Mat *outmat) 3370d71ae5a4SJacob Faibussowitsch { 3371d528f656SJakub Kruzik PetscFunctionBegin; 33729566063dSJacob Faibussowitsch PetscCall(MatCreateMPIMatConcatenateSeqMat_MPIDense(comm, inmat, n, scall, outmat)); 33733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3374d528f656SJakub Kruzik } 3375d528f656SJakub Kruzik 3376d16ceb75SStefano Zampini PetscErrorCode MatDenseCreateColumnVec_Private(Mat A, Vec *v) 3377d16ceb75SStefano Zampini { 3378d16ceb75SStefano Zampini PetscBool isstd, iskok, iscuda, iship; 3379d16ceb75SStefano Zampini PetscMPIInt size; 3380d16ceb75SStefano Zampini #if PetscDefined(HAVE_CUDA) || PetscDefined(HAVE_HIP) 3381d16ceb75SStefano Zampini /* we pass the data of A, to prevent allocating needless GPU memory the first time VecCUPMPlaceArray is called. */ 3382d16ceb75SStefano Zampini const PetscScalar *a; 3383d16ceb75SStefano Zampini #endif 3384d16ceb75SStefano Zampini 3385d16ceb75SStefano Zampini PetscFunctionBegin; 3386d16ceb75SStefano Zampini *v = NULL; 3387d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &isstd, VECSTANDARD, VECSEQ, VECMPI, "")); 3388d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &iskok, VECKOKKOS, VECSEQKOKKOS, VECMPIKOKKOS, "")); 3389d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &iscuda, VECCUDA, VECSEQCUDA, VECMPICUDA, "")); 3390d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &iship, VECHIP, VECSEQHIP, VECMPIHIP, "")); 3391d16ceb75SStefano Zampini PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A), &size)); 3392d16ceb75SStefano Zampini if (isstd) { 3393d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPIWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, v)); 3394d16ceb75SStefano Zampini else PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, v)); 3395d16ceb75SStefano Zampini } else if (iskok) { 3396d16ceb75SStefano Zampini PetscCheck(PetscDefined(HAVE_KOKKOS_KERNELS), PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Reconfigure using KOKKOS kernels support"); 3397d16ceb75SStefano Zampini #if PetscDefined(HAVE_KOKKOS_KERNELS) 3398d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPIKokkosWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, v)); 3399d16ceb75SStefano Zampini else PetscCall(VecCreateSeqKokkosWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, v)); 3400d16ceb75SStefano Zampini #endif 3401d16ceb75SStefano Zampini } else if (iscuda) { 3402d16ceb75SStefano Zampini PetscCheck(PetscDefined(HAVE_CUDA), PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Reconfigure using CUDA support"); 3403d16ceb75SStefano Zampini #if PetscDefined(HAVE_CUDA) 3404d16ceb75SStefano Zampini PetscCall(MatDenseCUDAGetArrayRead(A, &a)); 3405d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPICUDAWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, a, v)); 3406d16ceb75SStefano Zampini else PetscCall(VecCreateSeqCUDAWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, a, v)); 3407d16ceb75SStefano Zampini #endif 3408d16ceb75SStefano Zampini } else if (iship) { 3409d16ceb75SStefano Zampini PetscCheck(PetscDefined(HAVE_HIP), PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Reconfigure using HIP support"); 3410d16ceb75SStefano Zampini #if PetscDefined(HAVE_HIP) 3411d16ceb75SStefano Zampini PetscCall(MatDenseHIPGetArrayRead(A, &a)); 3412d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPIHIPWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, a, v)); 3413d16ceb75SStefano Zampini else PetscCall(VecCreateSeqHIPWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, a, v)); 3414d16ceb75SStefano Zampini #endif 3415d16ceb75SStefano Zampini } 3416d16ceb75SStefano Zampini PetscCheck(*v, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Not coded for type %s", A->defaultvectype); 3417d16ceb75SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 3418d16ceb75SStefano Zampini } 3419d16ceb75SStefano Zampini 3420d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A, PetscInt col, Vec *v) 3421d71ae5a4SJacob Faibussowitsch { 34226947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34236947451fSStefano Zampini 34246947451fSStefano Zampini PetscFunctionBegin; 342528b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 342628b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3427d16ceb75SStefano Zampini if (!a->cvec) PetscCall(MatDenseCreateColumnVec_Private(A, &a->cvec)); 34286947451fSStefano Zampini a->vecinuse = col + 1; 34299566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, (PetscScalar **)&a->ptrinuse)); 34309566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda)); 34316947451fSStefano Zampini *v = a->cvec; 34323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34336947451fSStefano Zampini } 34346947451fSStefano Zampini 3435d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec_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 MatDenseGetColumnVec() first"); 344128b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 34424186a4bbSPierre Jolivet VecCheckAssembled(a->cvec); 34436947451fSStefano Zampini a->vecinuse = 0; 34449566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, (PetscScalar **)&a->ptrinuse)); 34459566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 344675f6d85dSStefano Zampini if (v) *v = NULL; 34473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34486947451fSStefano Zampini } 34496947451fSStefano Zampini 3450d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead_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 MatDenseRestoreColumnVec() first"); 345628b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3457d16ceb75SStefano Zampini if (!a->cvec) PetscCall(MatDenseCreateColumnVec_Private(A, &a->cvec)); 34586947451fSStefano Zampini a->vecinuse = col + 1; 34599566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &a->ptrinuse)); 34608e3a54c0SPierre Jolivet PetscCall(VecPlaceArray(a->cvec, PetscSafePointerPlusOffset(a->ptrinuse, (size_t)col * (size_t)a->lda))); 34619566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(a->cvec)); 34626947451fSStefano Zampini *v = a->cvec; 34633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34646947451fSStefano Zampini } 34656947451fSStefano Zampini 3466d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v) 3467d71ae5a4SJacob Faibussowitsch { 34686947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34696947451fSStefano Zampini 34706947451fSStefano Zampini PetscFunctionBegin; 347128b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 347228b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 34734186a4bbSPierre Jolivet VecCheckAssembled(a->cvec); 34746947451fSStefano Zampini a->vecinuse = 0; 34759566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &a->ptrinuse)); 34769566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(a->cvec)); 34779566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 347875f6d85dSStefano Zampini if (v) *v = NULL; 34793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34806947451fSStefano Zampini } 34816947451fSStefano Zampini 3482d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v) 3483d71ae5a4SJacob Faibussowitsch { 34846947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34856947451fSStefano Zampini 34866947451fSStefano Zampini PetscFunctionBegin; 348728b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 348828b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3489d16ceb75SStefano Zampini if (!a->cvec) PetscCall(MatDenseCreateColumnVec_Private(A, &a->cvec)); 34906947451fSStefano Zampini a->vecinuse = col + 1; 34919566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(A, (PetscScalar **)&a->ptrinuse)); 34928e3a54c0SPierre Jolivet PetscCall(VecPlaceArray(a->cvec, PetscSafePointerPlusOffset(a->ptrinuse, (size_t)col * (size_t)a->lda))); 34936947451fSStefano Zampini *v = a->cvec; 34943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34956947451fSStefano Zampini } 34966947451fSStefano Zampini 3497d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite_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 MatDenseGetColumnVec() first"); 350328b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 35044186a4bbSPierre Jolivet VecCheckAssembled(a->cvec); 35056947451fSStefano Zampini a->vecinuse = 0; 35069566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(A, (PetscScalar **)&a->ptrinuse)); 35079566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 350875f6d85dSStefano Zampini if (v) *v = NULL; 35093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35106947451fSStefano Zampini } 35116947451fSStefano Zampini 3512d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) 3513d71ae5a4SJacob Faibussowitsch { 35145ea7661aSPierre Jolivet Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35155ea7661aSPierre Jolivet 35165ea7661aSPierre Jolivet PetscFunctionBegin; 351728b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 351828b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3519a2748737SPierre Jolivet if (a->cmat && (cend - cbegin != a->cmat->cmap->N || rend - rbegin != a->cmat->rmap->N)) PetscCall(MatDestroy(&a->cmat)); 35205ea7661aSPierre Jolivet if (!a->cmat) { 35218e3a54c0SPierre 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)); 35225ea7661aSPierre Jolivet } else { 35238e3a54c0SPierre Jolivet PetscCall(MatDensePlaceArray(a->cmat, PetscSafePointerPlusOffset(a->v, rbegin + (size_t)cbegin * a->lda))); 35245ea7661aSPierre Jolivet } 35259566063dSJacob Faibussowitsch PetscCall(MatDenseSetLDA(a->cmat, a->lda)); 35265ea7661aSPierre Jolivet a->matinuse = cbegin + 1; 35275ea7661aSPierre Jolivet *v = a->cmat; 352847d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 352975f6d85dSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 353075f6d85dSStefano Zampini #endif 35313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35325ea7661aSPierre Jolivet } 35335ea7661aSPierre Jolivet 3534d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A, Mat *v) 3535d71ae5a4SJacob Faibussowitsch { 35365ea7661aSPierre Jolivet Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35375ea7661aSPierre Jolivet 35385ea7661aSPierre Jolivet PetscFunctionBegin; 353928b400f6SJacob Faibussowitsch PetscCheck(a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetSubMatrix() first"); 354028b400f6SJacob Faibussowitsch PetscCheck(a->cmat, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column matrix"); 354108401ef6SPierre Jolivet PetscCheck(*v == a->cmat, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not the matrix obtained from MatDenseGetSubMatrix()"); 35425ea7661aSPierre Jolivet a->matinuse = 0; 35439566063dSJacob Faibussowitsch PetscCall(MatDenseResetArray(a->cmat)); 3544742765d3SMatthew Knepley if (v) *v = NULL; 354547d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 35463faff063SStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 35473faff063SStefano Zampini #endif 35483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35495ea7661aSPierre Jolivet } 35505ea7661aSPierre Jolivet 35510bad9183SKris Buschelman /*MC 3552fafad747SKris Buschelman MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices. 35530bad9183SKris Buschelman 35542ef1f0ffSBarry Smith Options Database Key: 355511a5261eSBarry Smith . -mat_type seqdense - sets the matrix type to `MATSEQDENSE` during a call to `MatSetFromOptions()` 35560bad9183SKris Buschelman 35570bad9183SKris Buschelman Level: beginner 35580bad9183SKris Buschelman 35591cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreateSeqDense()` 35600bad9183SKris Buschelman M*/ 3561d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreate_SeqDense(Mat B) 3562d71ae5a4SJacob Faibussowitsch { 3563273d9f13SBarry Smith Mat_SeqDense *b; 35647c334f02SBarry Smith PetscMPIInt size; 3565273d9f13SBarry Smith 3566273d9f13SBarry Smith PetscFunctionBegin; 35679566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)B), &size)); 356808401ef6SPierre Jolivet PetscCheck(size <= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Comm must be of size 1"); 356955659b69SBarry Smith 35704dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&b)); 357144cd7ae7SLois Curfman McInnes B->data = (void *)b; 3572aea10558SJacob Faibussowitsch B->ops[0] = MatOps_Values; 357318f449edSLois Curfman McInnes 3574273d9f13SBarry Smith b->roworiented = PETSC_TRUE; 35754e220ebcSLois Curfman McInnes 35769566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatQRFactor_C", MatQRFactor_SeqDense)); 35779566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetLDA_C", MatDenseGetLDA_SeqDense)); 35789566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseSetLDA_C", MatDenseSetLDA_SeqDense)); 35799566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArray_C", MatDenseGetArray_SeqDense)); 35809566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArray_C", MatDenseRestoreArray_SeqDense)); 35819566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDensePlaceArray_C", MatDensePlaceArray_SeqDense)); 35829566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseResetArray_C", MatDenseResetArray_SeqDense)); 35839566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseReplaceArray_C", MatDenseReplaceArray_SeqDense)); 35849566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayRead_C", MatDenseGetArray_SeqDense)); 35859566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayRead_C", MatDenseRestoreArray_SeqDense)); 35869566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayWrite_C", MatDenseGetArray_SeqDense)); 35879566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayWrite_C", MatDenseRestoreArray_SeqDense)); 35889566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqaij_C", MatConvert_SeqDense_SeqAIJ)); 35898baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 35909566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_elemental_C", MatConvert_SeqDense_Elemental)); 35918baccfbdSHong Zhang #endif 3592d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 35939566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_scalapack_C", MatConvert_Dense_ScaLAPACK)); 3594d24d4204SJose E. Roman #endif 35952bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA) 35969566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensecuda_C", MatConvert_SeqDense_SeqDenseCUDA)); 35979566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", MatProductSetFromOptions_SeqDense)); 35989566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdense_C", MatProductSetFromOptions_SeqDense)); 35999566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensecuda_C", MatProductSetFromOptions_SeqDense)); 36002bf066beSStefano Zampini #endif 360147d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 360247d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensehip_C", MatConvert_SeqDense_SeqDenseHIP)); 360347d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensehip_seqdensehip_C", MatProductSetFromOptions_SeqDense)); 360447d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensehip_seqdense_C", MatProductSetFromOptions_SeqDense)); 360547d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensehip_C", MatProductSetFromOptions_SeqDense)); 360647d993e7Ssuyashtn #endif 36079566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSeqDenseSetPreallocation_C", MatSeqDenseSetPreallocation_SeqDense)); 36089566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqaij_seqdense_C", MatProductSetFromOptions_SeqAIJ_SeqDense)); 36099566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdense_C", MatProductSetFromOptions_SeqDense)); 36109566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense)); 36119566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqsbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense)); 361296e6d5c4SRichard Tran Mills 36139566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumn_C", MatDenseGetColumn_SeqDense)); 36149566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumn_C", MatDenseRestoreColumn_SeqDense)); 36159566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVec_C", MatDenseGetColumnVec_SeqDense)); 36169566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVec_C", MatDenseRestoreColumnVec_SeqDense)); 36179566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecRead_C", MatDenseGetColumnVecRead_SeqDense)); 36189566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecRead_C", MatDenseRestoreColumnVecRead_SeqDense)); 36199566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecWrite_C", MatDenseGetColumnVecWrite_SeqDense)); 36209566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecWrite_C", MatDenseRestoreColumnVecWrite_SeqDense)); 36219566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetSubMatrix_C", MatDenseGetSubMatrix_SeqDense)); 36229566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreSubMatrix_C", MatDenseRestoreSubMatrix_SeqDense)); 3623d016bddeSToby Isaac PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatMultColumnRange_C", MatMultColumnRange_SeqDense)); 36240be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatMultAddColumnRange_C", MatMultAddColumnRange_SeqDense)); 36250be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatMultHermitianTransposeColumnRange_C", MatMultHermitianTransposeColumnRange_SeqDense)); 36260be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatMultHermitianTransposeAddColumnRange_C", MatMultHermitianTransposeAddColumnRange_SeqDense)); 36279566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)B, MATSEQDENSE)); 36283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3629289bc588SBarry Smith } 363086aefd0dSHong Zhang 363186aefd0dSHong Zhang /*@C 363211a5261eSBarry 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. 363386aefd0dSHong Zhang 363486aefd0dSHong Zhang Not Collective 363586aefd0dSHong Zhang 36365ea7661aSPierre Jolivet Input Parameters: 3637fe59aa6dSJacob Faibussowitsch + A - a `MATSEQDENSE` or `MATMPIDENSE` matrix 363886aefd0dSHong Zhang - col - column index 363986aefd0dSHong Zhang 364086aefd0dSHong Zhang Output Parameter: 364186aefd0dSHong Zhang . vals - pointer to the data 364286aefd0dSHong Zhang 364386aefd0dSHong Zhang Level: intermediate 364486aefd0dSHong Zhang 364511a5261eSBarry Smith Note: 364611a5261eSBarry Smith Use `MatDenseGetColumnVec()` to get access to a column of a `MATDENSE` treated as a `Vec` 364711a5261eSBarry Smith 36481cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreColumn()`, `MatDenseGetColumnVec()` 364986aefd0dSHong Zhang @*/ 36505d83a8b1SBarry Smith PetscErrorCode MatDenseGetColumn(Mat A, PetscInt col, PetscScalar *vals[]) 3651d71ae5a4SJacob Faibussowitsch { 365286aefd0dSHong Zhang PetscFunctionBegin; 3653d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3654d5ea218eSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 36554f572ea9SToby Isaac PetscAssertPointer(vals, 3); 3656cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumn_C", (Mat, PetscInt, PetscScalar **), (A, col, vals)); 36573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 365886aefd0dSHong Zhang } 365986aefd0dSHong Zhang 366086aefd0dSHong Zhang /*@C 366111a5261eSBarry Smith MatDenseRestoreColumn - returns access to a column of a `MATDENSE` matrix which is returned by `MatDenseGetColumn()`. 366286aefd0dSHong Zhang 366386aefd0dSHong Zhang Not Collective 366486aefd0dSHong Zhang 3665742765d3SMatthew Knepley Input Parameters: 3666fe59aa6dSJacob Faibussowitsch + A - a `MATSEQDENSE` or `MATMPIDENSE` matrix 36672ef1f0ffSBarry Smith - vals - pointer to the data (may be `NULL`) 366886aefd0dSHong Zhang 366986aefd0dSHong Zhang Level: intermediate 367086aefd0dSHong Zhang 36711cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetColumn()` 367286aefd0dSHong Zhang @*/ 36735d83a8b1SBarry Smith PetscErrorCode MatDenseRestoreColumn(Mat A, PetscScalar *vals[]) 3674d71ae5a4SJacob Faibussowitsch { 367586aefd0dSHong Zhang PetscFunctionBegin; 3676d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 36774f572ea9SToby Isaac PetscAssertPointer(vals, 2); 3678cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumn_C", (Mat, PetscScalar **), (A, vals)); 36793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 368086aefd0dSHong Zhang } 36816947451fSStefano Zampini 36820f74d2c1SSatish Balay /*@ 368311a5261eSBarry Smith MatDenseGetColumnVec - Gives read-write access to a column of a `MATDENSE` matrix, represented as a `Vec`. 36846947451fSStefano Zampini 36856947451fSStefano Zampini Collective 36866947451fSStefano Zampini 36875ea7661aSPierre Jolivet Input Parameters: 3688fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 36896947451fSStefano Zampini - col - the column index 36906947451fSStefano Zampini 36916947451fSStefano Zampini Output Parameter: 36926947451fSStefano Zampini . v - the vector 36936947451fSStefano Zampini 36942ef1f0ffSBarry Smith Level: intermediate 36952ef1f0ffSBarry Smith 36966947451fSStefano Zampini Notes: 369711a5261eSBarry Smith The vector is owned by PETSc. Users need to call `MatDenseRestoreColumnVec()` when the vector is no longer needed. 369811a5261eSBarry Smith 369911a5261eSBarry Smith Use `MatDenseGetColumnVecRead()` to obtain read-only access or `MatDenseGetColumnVecWrite()` for write-only access. 37006947451fSStefano Zampini 37011cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`, `MatDenseGetColumn()` 37026947451fSStefano Zampini @*/ 3703d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec(Mat A, PetscInt col, Vec *v) 3704d71ae5a4SJacob Faibussowitsch { 37056947451fSStefano Zampini PetscFunctionBegin; 37066947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 37076947451fSStefano Zampini PetscValidType(A, 1); 37086947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 37094f572ea9SToby Isaac PetscAssertPointer(v, 3); 371028b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 37112cf15c64SPierre 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); 3712cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v)); 37133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37146947451fSStefano Zampini } 37156947451fSStefano Zampini 37160f74d2c1SSatish Balay /*@ 3717fb850c59SBarry Smith MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from `MatDenseGetColumnVec()`. 37186947451fSStefano Zampini 37196947451fSStefano Zampini Collective 37206947451fSStefano Zampini 37215ea7661aSPierre Jolivet Input Parameters: 3722fb850c59SBarry Smith + A - the `Mat` object 37236947451fSStefano Zampini . col - the column index 3724fb850c59SBarry Smith - v - the `Vec` object (may be `NULL`) 37256947451fSStefano Zampini 37266947451fSStefano Zampini Level: intermediate 37276947451fSStefano Zampini 37281cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 37296947451fSStefano Zampini @*/ 3730d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec(Mat A, PetscInt col, Vec *v) 3731d71ae5a4SJacob Faibussowitsch { 37326947451fSStefano Zampini PetscFunctionBegin; 37336947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 37346947451fSStefano Zampini PetscValidType(A, 1); 37356947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 373608401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 37372cf15c64SPierre 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); 3738cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v)); 37393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37406947451fSStefano Zampini } 37416947451fSStefano Zampini 37420f74d2c1SSatish Balay /*@ 3743fb850c59SBarry Smith MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a `Vec`. 37446947451fSStefano Zampini 37456947451fSStefano Zampini Collective 37466947451fSStefano Zampini 37475ea7661aSPierre Jolivet Input Parameters: 3748fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 37496947451fSStefano Zampini - col - the column index 37506947451fSStefano Zampini 37516947451fSStefano Zampini Output Parameter: 37526947451fSStefano Zampini . v - the vector 37536947451fSStefano Zampini 37542ef1f0ffSBarry Smith Level: intermediate 37552ef1f0ffSBarry Smith 37566947451fSStefano Zampini Notes: 37576947451fSStefano Zampini The vector is owned by PETSc and users cannot modify it. 375811a5261eSBarry Smith 37592ef1f0ffSBarry Smith Users need to call `MatDenseRestoreColumnVecRead()` when the vector is no longer needed. 376011a5261eSBarry Smith 37612ef1f0ffSBarry Smith Use `MatDenseGetColumnVec()` to obtain read-write access or `MatDenseGetColumnVecWrite()` for write-only access. 37626947451fSStefano Zampini 37631cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 37646947451fSStefano Zampini @*/ 3765d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead(Mat A, PetscInt col, Vec *v) 3766d71ae5a4SJacob Faibussowitsch { 37676947451fSStefano Zampini PetscFunctionBegin; 37686947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 37696947451fSStefano Zampini PetscValidType(A, 1); 37706947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 37714f572ea9SToby Isaac PetscAssertPointer(v, 3); 377228b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 37732cf15c64SPierre 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); 3774cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v)); 37753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37766947451fSStefano Zampini } 37776947451fSStefano Zampini 37780f74d2c1SSatish Balay /*@ 3779fb850c59SBarry Smith MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from `MatDenseGetColumnVecRead()`. 37806947451fSStefano Zampini 37816947451fSStefano Zampini Collective 37826947451fSStefano Zampini 37835ea7661aSPierre Jolivet Input Parameters: 3784fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 37856947451fSStefano Zampini . col - the column index 3786fb850c59SBarry Smith - v - the `Vec` object (may be `NULL`) 37876947451fSStefano Zampini 37886947451fSStefano Zampini Level: intermediate 37896947451fSStefano Zampini 37901cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecWrite()` 37916947451fSStefano Zampini @*/ 3792d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead(Mat A, PetscInt col, Vec *v) 3793d71ae5a4SJacob Faibussowitsch { 37946947451fSStefano Zampini PetscFunctionBegin; 37956947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 37966947451fSStefano Zampini PetscValidType(A, 1); 37976947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 379808401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 37992cf15c64SPierre 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); 3800cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v)); 38013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38026947451fSStefano Zampini } 38036947451fSStefano Zampini 38040f74d2c1SSatish Balay /*@ 3805fb850c59SBarry Smith MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a `Vec`. 38066947451fSStefano Zampini 38076947451fSStefano Zampini Collective 38086947451fSStefano Zampini 38095ea7661aSPierre Jolivet Input Parameters: 3810fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 38116947451fSStefano Zampini - col - the column index 38126947451fSStefano Zampini 38136947451fSStefano Zampini Output Parameter: 38146947451fSStefano Zampini . v - the vector 38156947451fSStefano Zampini 38166947451fSStefano Zampini Level: intermediate 38176947451fSStefano Zampini 38182ef1f0ffSBarry Smith Notes: 38192ef1f0ffSBarry Smith The vector is owned by PETSc. Users need to call `MatDenseRestoreColumnVecWrite()` when the vector is no longer needed. 38202ef1f0ffSBarry Smith 38212ef1f0ffSBarry Smith Use `MatDenseGetColumnVec()` to obtain read-write access or `MatDenseGetColumnVecRead()` for read-only access. 38222ef1f0ffSBarry Smith 38231cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 38246947451fSStefano Zampini @*/ 3825d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite(Mat A, PetscInt col, Vec *v) 3826d71ae5a4SJacob Faibussowitsch { 38276947451fSStefano Zampini PetscFunctionBegin; 38286947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38296947451fSStefano Zampini PetscValidType(A, 1); 38306947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 38314f572ea9SToby Isaac PetscAssertPointer(v, 3); 383228b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3833aed4548fSBarry 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); 3834cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v)); 38353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38366947451fSStefano Zampini } 38376947451fSStefano Zampini 38380f74d2c1SSatish Balay /*@ 3839fb850c59SBarry Smith MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from `MatDenseGetColumnVecWrite()`. 38406947451fSStefano Zampini 38416947451fSStefano Zampini Collective 38426947451fSStefano Zampini 38435ea7661aSPierre Jolivet Input Parameters: 3844fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 38456947451fSStefano Zampini . col - the column index 38462ef1f0ffSBarry Smith - v - the `Vec` object (may be `NULL`) 38476947451fSStefano Zampini 38486947451fSStefano Zampini Level: intermediate 38496947451fSStefano Zampini 38501cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()` 38516947451fSStefano Zampini @*/ 3852d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A, PetscInt col, Vec *v) 3853d71ae5a4SJacob Faibussowitsch { 38546947451fSStefano Zampini PetscFunctionBegin; 38556947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38566947451fSStefano Zampini PetscValidType(A, 1); 38576947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 385808401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3859aed4548fSBarry 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); 3860cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v)); 38613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38626947451fSStefano Zampini } 38635ea7661aSPierre Jolivet 38640f74d2c1SSatish Balay /*@ 3865fb850c59SBarry Smith MatDenseGetSubMatrix - Gives access to a block of rows and columns of a dense matrix, represented as a `Mat`. 38665ea7661aSPierre Jolivet 38675ea7661aSPierre Jolivet Collective 38685ea7661aSPierre Jolivet 38695ea7661aSPierre Jolivet Input Parameters: 3870fb850c59SBarry Smith + A - the `Mat` object 38712ef1f0ffSBarry Smith . rbegin - the first global row index in the block (if `PETSC_DECIDE`, is 0) 38722ef1f0ffSBarry Smith . rend - the global row index past the last one in the block (if `PETSC_DECIDE`, is `M`) 38732ef1f0ffSBarry Smith . cbegin - the first global column index in the block (if `PETSC_DECIDE`, is 0) 38742ef1f0ffSBarry Smith - cend - the global column index past the last one in the block (if `PETSC_DECIDE`, is `N`) 38755ea7661aSPierre Jolivet 38765ea7661aSPierre Jolivet Output Parameter: 38775ea7661aSPierre Jolivet . v - the matrix 38785ea7661aSPierre Jolivet 38795ea7661aSPierre Jolivet Level: intermediate 38805ea7661aSPierre Jolivet 38812ef1f0ffSBarry Smith Notes: 38822ef1f0ffSBarry Smith The matrix is owned by PETSc. Users need to call `MatDenseRestoreSubMatrix()` when the matrix is no longer needed. 38832ef1f0ffSBarry Smith 38842ef1f0ffSBarry 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. 38852ef1f0ffSBarry Smith 38861cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreSubMatrix()` 38875ea7661aSPierre Jolivet @*/ 3888d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) 3889d71ae5a4SJacob Faibussowitsch { 38905ea7661aSPierre Jolivet PetscFunctionBegin; 38915ea7661aSPierre Jolivet PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38925ea7661aSPierre Jolivet PetscValidType(A, 1); 3893a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, rbegin, 2); 3894a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, rend, 3); 3895a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, cbegin, 4); 3896a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, cend, 5); 38974f572ea9SToby Isaac PetscAssertPointer(v, 6); 3898a2748737SPierre Jolivet if (rbegin == PETSC_DECIDE) rbegin = 0; 3899a2748737SPierre Jolivet if (rend == PETSC_DECIDE) rend = A->rmap->N; 3900a2748737SPierre Jolivet if (cbegin == PETSC_DECIDE) cbegin = 0; 3901a2748737SPierre Jolivet if (cend == PETSC_DECIDE) cend = A->cmap->N; 390228b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3903a2748737SPierre 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); 3904a2748737SPierre 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); 3905a2748737SPierre 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); 3906a2748737SPierre 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); 3907a2748737SPierre Jolivet PetscUseMethod(A, "MatDenseGetSubMatrix_C", (Mat, PetscInt, PetscInt, PetscInt, PetscInt, Mat *), (A, rbegin, rend, cbegin, cend, v)); 39083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 39095ea7661aSPierre Jolivet } 39105ea7661aSPierre Jolivet 39110f74d2c1SSatish Balay /*@ 3912fb850c59SBarry Smith MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from `MatDenseGetSubMatrix()`. 39135ea7661aSPierre Jolivet 39145ea7661aSPierre Jolivet Collective 39155ea7661aSPierre Jolivet 39165ea7661aSPierre Jolivet Input Parameters: 3917fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 39182ef1f0ffSBarry Smith - v - the `Mat` object (may be `NULL`) 39195ea7661aSPierre Jolivet 39205ea7661aSPierre Jolivet Level: intermediate 39215ea7661aSPierre Jolivet 39221cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseGetSubMatrix()` 39235ea7661aSPierre Jolivet @*/ 3924d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix(Mat A, Mat *v) 3925d71ae5a4SJacob Faibussowitsch { 39265ea7661aSPierre Jolivet PetscFunctionBegin; 39275ea7661aSPierre Jolivet PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 39285ea7661aSPierre Jolivet PetscValidType(A, 1); 39294f572ea9SToby Isaac PetscAssertPointer(v, 2); 3930cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreSubMatrix_C", (Mat, Mat *), (A, v)); 39313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 39325ea7661aSPierre Jolivet } 39338a9c020eSBarry Smith 39348a9c020eSBarry Smith #include <petscblaslapack.h> 39358a9c020eSBarry Smith #include <petsc/private/kernels/blockinvert.h> 39368a9c020eSBarry Smith 3937d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseInvert(Mat A) 3938d71ae5a4SJacob Faibussowitsch { 3939d63b1753SJacob Faibussowitsch PetscInt m; 39408a9c020eSBarry Smith const PetscReal shift = 0.0; 3941d63b1753SJacob Faibussowitsch PetscBool allowzeropivot, zeropivotdetected = PETSC_FALSE; 3942d63b1753SJacob Faibussowitsch PetscScalar *values; 39438a9c020eSBarry Smith 39448a9c020eSBarry Smith PetscFunctionBegin; 3945d63b1753SJacob Faibussowitsch PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3946d63b1753SJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &values)); 3947d63b1753SJacob Faibussowitsch PetscCall(MatGetLocalSize(A, &m, NULL)); 3948d63b1753SJacob Faibussowitsch allowzeropivot = PetscNot(A->erroriffailure); 39498a9c020eSBarry Smith /* factor and invert each block */ 3950d63b1753SJacob Faibussowitsch switch (m) { 3951d71ae5a4SJacob Faibussowitsch case 1: 3952d71ae5a4SJacob Faibussowitsch values[0] = (PetscScalar)1.0 / (values[0] + shift); 3953d71ae5a4SJacob Faibussowitsch break; 39548a9c020eSBarry Smith case 2: 39558a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_2(values, shift, allowzeropivot, &zeropivotdetected)); 39568a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39578a9c020eSBarry Smith break; 39588a9c020eSBarry Smith case 3: 39598a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_3(values, shift, allowzeropivot, &zeropivotdetected)); 39608a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39618a9c020eSBarry Smith break; 39628a9c020eSBarry Smith case 4: 39638a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_4(values, shift, allowzeropivot, &zeropivotdetected)); 39648a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39658a9c020eSBarry Smith break; 39669371c9d4SSatish Balay case 5: { 39678a9c020eSBarry Smith PetscScalar work[25]; 39688a9c020eSBarry Smith PetscInt ipvt[5]; 39698a9c020eSBarry Smith 39708a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_5(values, ipvt, work, shift, allowzeropivot, &zeropivotdetected)); 39718a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39729371c9d4SSatish Balay } break; 39738a9c020eSBarry Smith case 6: 39748a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_6(values, shift, allowzeropivot, &zeropivotdetected)); 39758a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39768a9c020eSBarry Smith break; 39778a9c020eSBarry Smith case 7: 39788a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_7(values, shift, allowzeropivot, &zeropivotdetected)); 39798a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39808a9c020eSBarry Smith break; 39819371c9d4SSatish Balay default: { 39828a9c020eSBarry Smith PetscInt *v_pivots, *IJ, j; 39838a9c020eSBarry Smith PetscScalar *v_work; 39848a9c020eSBarry Smith 3985d63b1753SJacob Faibussowitsch PetscCall(PetscMalloc3(m, &v_work, m, &v_pivots, m, &IJ)); 3986d63b1753SJacob Faibussowitsch for (j = 0; j < m; j++) IJ[j] = j; 3987d63b1753SJacob Faibussowitsch PetscCall(PetscKernel_A_gets_inverse_A(m, values, v_pivots, v_work, allowzeropivot, &zeropivotdetected)); 39888a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39898a9c020eSBarry Smith PetscCall(PetscFree3(v_work, v_pivots, IJ)); 39908a9c020eSBarry Smith } 39918a9c020eSBarry Smith } 3992d63b1753SJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &values)); 39933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 39948a9c020eSBarry Smith } 3995