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> 11*4186a4bbSPierre 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 } 7628b400f6SJacob Faibussowitsch PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad Inversion: zero pivot in row %" PetscInt_FMT, (PetscInt)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; 36223fc5dcaSStefano Zampini PetscInt lda = (PetscInt)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)); 388b24902e0SBarry Smith } 3893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 390b24902e0SBarry Smith } 391b24902e0SBarry Smith 392d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDuplicate_SeqDense(Mat A, MatDuplicateOption cpvalues, Mat *newmat) 393d71ae5a4SJacob Faibussowitsch { 3943a40ed3dSBarry Smith PetscFunctionBegin; 3959566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), newmat)); 3969566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*newmat, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n)); 3979566063dSJacob Faibussowitsch PetscCall(MatSetType(*newmat, ((PetscObject)A)->type_name)); 3989566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(*newmat, A, cpvalues)); 3993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 400b24902e0SBarry Smith } 401b24902e0SBarry Smith 402d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_LU(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T) 403d71ae5a4SJacob Faibussowitsch { 404c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4054396437dSToby Isaac PetscBLASInt info; 40667e560aaSBarry Smith 4073a40ed3dSBarry Smith PetscFunctionBegin; 4089566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 409792fecdfSBarry Smith PetscCallBLAS("LAPACKgetrs", LAPACKgetrs_(T ? "T" : "N", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info)); 4109566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 41105fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "GETRS - Bad solve %d", (int)info); 4129566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m))); 4133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4144396437dSToby Isaac } 4154396437dSToby Isaac 4164396437dSToby Isaac static PetscErrorCode MatConjugate_SeqDense(Mat); 4174396437dSToby Isaac 418d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_Cholesky(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T) 419d71ae5a4SJacob Faibussowitsch { 4204396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4214396437dSToby Isaac PetscBLASInt info; 4224396437dSToby Isaac 4234396437dSToby Isaac PetscFunctionBegin; 424b94d7dedSBarry Smith if (A->spd == PETSC_BOOL3_TRUE) { 4259566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A)); 4269566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 427792fecdfSBarry Smith PetscCallBLAS("LAPACKpotrs", LAPACKpotrs_("L", &m, &nrhs, mat->v, &mat->lda, x, &m, &info)); 4289566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 42905fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "POTRS Bad solve %d", (int)info); 4309566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A)); 431a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX) 432b94d7dedSBarry Smith } else if (A->hermitian == PETSC_BOOL3_TRUE) { 4339566063dSJacob Faibussowitsch if (T) PetscCall(MatConjugate_SeqDense(A)); 4349566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 435792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrs", LAPACKhetrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info)); 4369566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 43705fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "HETRS Bad solve %d", (int)info); 4389566063dSJacob Faibussowitsch if (T) PetscCall(MatConjugate_SeqDense(A)); 439a49dc2a2SStefano Zampini #endif 440a49dc2a2SStefano Zampini } else { /* symmetric case */ 4419566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 442792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrs", LAPACKsytrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info)); 4439566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 44405fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "SYTRS Bad solve %d", (int)info); 445a49dc2a2SStefano Zampini } 4469566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m))); 4473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4484396437dSToby Isaac } 44985e2c93fSHong Zhang 450d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k) 451d71ae5a4SJacob Faibussowitsch { 4524396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4534396437dSToby Isaac PetscBLASInt info; 4544396437dSToby Isaac char trans; 4554396437dSToby Isaac 4564396437dSToby Isaac PetscFunctionBegin; 4574905a7bcSToby Isaac if (PetscDefined(USE_COMPLEX)) { 4584905a7bcSToby Isaac trans = 'C'; 4594905a7bcSToby Isaac } else { 4604905a7bcSToby Isaac trans = 'T'; 4614905a7bcSToby Isaac } 4629566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 46305fcb23eSStefano Zampini { /* lwork depends on the number of right-hand sides */ 46405fcb23eSStefano Zampini PetscBLASInt nlfwork, lfwork = -1; 46505fcb23eSStefano Zampini PetscScalar fwork; 46605fcb23eSStefano Zampini 467792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info)); 46805fcb23eSStefano Zampini nlfwork = (PetscBLASInt)PetscRealPart(fwork); 46905fcb23eSStefano Zampini if (nlfwork > mat->lfwork) { 47005fcb23eSStefano Zampini mat->lfwork = nlfwork; 47105fcb23eSStefano Zampini PetscCall(PetscFree(mat->fwork)); 47205fcb23eSStefano Zampini PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 47305fcb23eSStefano Zampini } 47405fcb23eSStefano Zampini } 475792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info)); 4769566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 47705fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %d", (int)info); 4789566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 479792fecdfSBarry Smith PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "N", "N", &mat->rank, &nrhs, mat->v, &mat->lda, x, &ldx, &info)); 4809566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 48105fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %d", (int)info); 4824905a7bcSToby Isaac for (PetscInt j = 0; j < nrhs; j++) { 483ad540459SPierre Jolivet for (PetscInt i = mat->rank; i < k; i++) x[j * ldx + i] = 0.; 4844905a7bcSToby Isaac } 4859566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank)))); 4863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4874905a7bcSToby Isaac } 4884905a7bcSToby Isaac 489d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k) 490d71ae5a4SJacob Faibussowitsch { 4914396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4924396437dSToby Isaac PetscBLASInt info; 4934396437dSToby Isaac 4944396437dSToby Isaac PetscFunctionBegin; 4954396437dSToby Isaac if (A->rmap->n == A->cmap->n && mat->rank == A->rmap->n) { 4969566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 497792fecdfSBarry Smith PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "T", "N", &m, &nrhs, mat->v, &mat->lda, x, &ldx, &info)); 4989566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 49905fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %d", (int)info); 5009566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A)); 50105fcb23eSStefano Zampini { /* lwork depends on the number of right-hand sides */ 50205fcb23eSStefano Zampini PetscBLASInt nlfwork, lfwork = -1; 50305fcb23eSStefano Zampini PetscScalar fwork; 50405fcb23eSStefano Zampini 505792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info)); 50605fcb23eSStefano Zampini nlfwork = (PetscBLASInt)PetscRealPart(fwork); 50705fcb23eSStefano Zampini if (nlfwork > mat->lfwork) { 50805fcb23eSStefano Zampini mat->lfwork = nlfwork; 50905fcb23eSStefano Zampini PetscCall(PetscFree(mat->fwork)); 51005fcb23eSStefano Zampini PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 51105fcb23eSStefano Zampini } 51205fcb23eSStefano Zampini } 5139566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 514792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info)); 5159566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 51605fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %d", (int)info); 5179566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A)); 5184396437dSToby Isaac } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "QR factored matrix cannot be used for transpose solve"); 5199566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank)))); 5203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5214396437dSToby Isaac } 5224396437dSToby Isaac 523d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_SetUp(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k) 524d71ae5a4SJacob Faibussowitsch { 5254396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 5264905a7bcSToby Isaac PetscScalar *y; 5274905a7bcSToby Isaac PetscBLASInt m = 0, k = 0; 5284905a7bcSToby Isaac 5294905a7bcSToby Isaac PetscFunctionBegin; 5309566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 5319566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 5324905a7bcSToby Isaac if (k < m) { 5339566063dSJacob Faibussowitsch PetscCall(VecCopy(xx, mat->qrrhs)); 5349566063dSJacob Faibussowitsch PetscCall(VecGetArray(mat->qrrhs, &y)); 5354905a7bcSToby Isaac } else { 5369566063dSJacob Faibussowitsch PetscCall(VecCopy(xx, yy)); 5379566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &y)); 5384905a7bcSToby Isaac } 5394396437dSToby Isaac *_y = y; 5404396437dSToby Isaac *_k = k; 5414396437dSToby Isaac *_m = m; 5423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5434396437dSToby Isaac } 5444396437dSToby Isaac 545d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_TearDown(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k) 546d71ae5a4SJacob Faibussowitsch { 5474396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 54842e9364cSSatish Balay PetscScalar *y = NULL; 5494396437dSToby Isaac PetscBLASInt m, k; 5504396437dSToby Isaac 5514396437dSToby Isaac PetscFunctionBegin; 5524396437dSToby Isaac y = *_y; 5534396437dSToby Isaac *_y = NULL; 5544396437dSToby Isaac k = *_k; 5554396437dSToby Isaac m = *_m; 5564905a7bcSToby Isaac if (k < m) { 5574905a7bcSToby Isaac PetscScalar *yv; 5589566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &yv)); 5599566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(yv, y, k)); 5609566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &yv)); 5619566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(mat->qrrhs, &y)); 5624905a7bcSToby Isaac } else { 5639566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &y)); 5644905a7bcSToby Isaac } 5653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5664905a7bcSToby Isaac } 5674905a7bcSToby Isaac 568d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_LU(Mat A, Vec xx, Vec yy) 569d71ae5a4SJacob Faibussowitsch { 57042e9364cSSatish Balay PetscScalar *y = NULL; 57142e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 5724396437dSToby Isaac 5734396437dSToby Isaac PetscFunctionBegin; 5749566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 5759566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_FALSE)); 5769566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 5773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5784396437dSToby Isaac } 5794396437dSToby Isaac 580d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_LU(Mat A, Vec xx, Vec yy) 581d71ae5a4SJacob Faibussowitsch { 58242e9364cSSatish Balay PetscScalar *y = NULL; 58342e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 5844396437dSToby Isaac 5854396437dSToby Isaac PetscFunctionBegin; 5869566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 5879566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_TRUE)); 5889566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 5893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5904396437dSToby Isaac } 5914396437dSToby Isaac 592d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Cholesky(Mat A, Vec xx, Vec yy) 593d71ae5a4SJacob Faibussowitsch { 594e54beecaSStefano Zampini PetscScalar *y = NULL; 595e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 5964396437dSToby Isaac 5974396437dSToby Isaac PetscFunctionBegin; 5989566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 5999566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_FALSE)); 6009566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6024396437dSToby Isaac } 6034396437dSToby Isaac 604d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_Cholesky(Mat A, Vec xx, Vec yy) 605d71ae5a4SJacob Faibussowitsch { 606e54beecaSStefano Zampini PetscScalar *y = NULL; 607e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 6084396437dSToby Isaac 6094396437dSToby Isaac PetscFunctionBegin; 6109566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6119566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_TRUE)); 6129566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6144396437dSToby Isaac } 6154396437dSToby Isaac 616d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_QR(Mat A, Vec xx, Vec yy) 617d71ae5a4SJacob Faibussowitsch { 618e54beecaSStefano Zampini PetscScalar *y = NULL; 619e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 6204396437dSToby Isaac 6214396437dSToby Isaac PetscFunctionBegin; 6229566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6239566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k)); 6249566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6264396437dSToby Isaac } 6274396437dSToby Isaac 628d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_QR(Mat A, Vec xx, Vec yy) 629d71ae5a4SJacob Faibussowitsch { 63042e9364cSSatish Balay PetscScalar *y = NULL; 63142e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 6324396437dSToby Isaac 6334396437dSToby Isaac PetscFunctionBegin; 6349566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6359566063dSJacob Faibussowitsch PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k)); 6369566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6384396437dSToby Isaac } 6394396437dSToby Isaac 640d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_SetUp(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k) 641d71ae5a4SJacob Faibussowitsch { 6424905a7bcSToby Isaac const PetscScalar *b; 6434396437dSToby Isaac PetscScalar *y; 644bf5a80bcSToby Isaac PetscInt n, _ldb, _ldx; 645bf5a80bcSToby Isaac PetscBLASInt nrhs = 0, m = 0, k = 0, ldb = 0, ldx = 0, ldy = 0; 6464905a7bcSToby Isaac 6474905a7bcSToby Isaac PetscFunctionBegin; 6489371c9d4SSatish Balay *_ldy = 0; 6499371c9d4SSatish Balay *_m = 0; 6509371c9d4SSatish Balay *_nrhs = 0; 6519371c9d4SSatish Balay *_k = 0; 6529371c9d4SSatish Balay *_y = NULL; 6539566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 6549566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 6559566063dSJacob Faibussowitsch PetscCall(MatGetSize(B, NULL, &n)); 6569566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(n, &nrhs)); 6579566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(B, &_ldb)); 6589566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldb, &ldb)); 6599566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(X, &_ldx)); 6609566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldx, &ldx)); 661bf5a80bcSToby Isaac if (ldx < m) { 6629566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &b)); 6639566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nrhs * m, &y)); 664bf5a80bcSToby Isaac if (ldb == m) { 6659566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(y, b, ldb * nrhs)); 6664905a7bcSToby Isaac } else { 66748a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * m], &b[j * ldb], m)); 6684905a7bcSToby Isaac } 669bf5a80bcSToby Isaac ldy = m; 6709566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &b)); 6714905a7bcSToby Isaac } else { 672bf5a80bcSToby Isaac if (ldb == ldx) { 6739566063dSJacob Faibussowitsch PetscCall(MatCopy(B, X, SAME_NONZERO_PATTERN)); 6749566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &y)); 6754905a7bcSToby Isaac } else { 6769566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &y)); 6779566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &b)); 67848a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * ldx], &b[j * ldb], m)); 6799566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &b)); 6804905a7bcSToby Isaac } 681bf5a80bcSToby Isaac ldy = ldx; 6824905a7bcSToby Isaac } 6834396437dSToby Isaac *_y = y; 684bf5a80bcSToby Isaac *_ldy = ldy; 6854396437dSToby Isaac *_k = k; 6864396437dSToby Isaac *_m = m; 6874396437dSToby Isaac *_nrhs = nrhs; 6883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6894396437dSToby Isaac } 6904396437dSToby Isaac 691d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_TearDown(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k) 692d71ae5a4SJacob Faibussowitsch { 6934396437dSToby Isaac PetscScalar *y; 694bf5a80bcSToby Isaac PetscInt _ldx; 695bf5a80bcSToby Isaac PetscBLASInt k, ldy, nrhs, ldx = 0; 6964396437dSToby Isaac 6974396437dSToby Isaac PetscFunctionBegin; 6984396437dSToby Isaac y = *_y; 6994396437dSToby Isaac *_y = NULL; 7004396437dSToby Isaac k = *_k; 701bf5a80bcSToby Isaac ldy = *_ldy; 7024396437dSToby Isaac nrhs = *_nrhs; 7039566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(X, &_ldx)); 7049566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldx, &ldx)); 705bf5a80bcSToby Isaac if (ldx != ldy) { 7064905a7bcSToby Isaac PetscScalar *xv; 7079566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &xv)); 70848a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&xv[j * ldx], &y[j * ldy], k)); 7099566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(X, &xv)); 7109566063dSJacob Faibussowitsch PetscCall(PetscFree(y)); 7114905a7bcSToby Isaac } else { 7129566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(X, &y)); 7134905a7bcSToby Isaac } 7143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 71585e2c93fSHong Zhang } 71685e2c93fSHong Zhang 717d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_LU(Mat A, Mat B, Mat X) 718d71ae5a4SJacob Faibussowitsch { 7194396437dSToby Isaac PetscScalar *y; 720bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7214396437dSToby Isaac 7224396437dSToby Isaac PetscFunctionBegin; 7239566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7249566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_FALSE)); 7259566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7274396437dSToby Isaac } 7284396437dSToby Isaac 729d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_LU(Mat A, Mat B, Mat X) 730d71ae5a4SJacob Faibussowitsch { 7314396437dSToby Isaac PetscScalar *y; 732bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7334396437dSToby Isaac 7344396437dSToby Isaac PetscFunctionBegin; 7359566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7369566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_TRUE)); 7379566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7394396437dSToby Isaac } 7404396437dSToby Isaac 741d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_Cholesky(Mat A, Mat B, Mat X) 742d71ae5a4SJacob Faibussowitsch { 7434396437dSToby Isaac PetscScalar *y; 744bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7454396437dSToby Isaac 7464396437dSToby Isaac PetscFunctionBegin; 7479566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7489566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_FALSE)); 7499566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7514396437dSToby Isaac } 7524396437dSToby Isaac 753d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_Cholesky(Mat A, Mat B, Mat X) 754d71ae5a4SJacob Faibussowitsch { 7554396437dSToby Isaac PetscScalar *y; 756bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7574396437dSToby Isaac 7584396437dSToby Isaac PetscFunctionBegin; 7599566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7609566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_TRUE)); 7619566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7634396437dSToby Isaac } 7644396437dSToby Isaac 765d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_QR(Mat A, Mat B, Mat X) 766d71ae5a4SJacob Faibussowitsch { 7674396437dSToby Isaac PetscScalar *y; 768bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7694396437dSToby Isaac 7704396437dSToby Isaac PetscFunctionBegin; 7719566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7729566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k)); 7739566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7754396437dSToby Isaac } 7764396437dSToby Isaac 777d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_QR(Mat A, Mat B, Mat X) 778d71ae5a4SJacob Faibussowitsch { 7794396437dSToby Isaac PetscScalar *y; 780bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7814396437dSToby Isaac 7824396437dSToby Isaac PetscFunctionBegin; 7839566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7849566063dSJacob Faibussowitsch PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k)); 7859566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7874396437dSToby Isaac } 7884396437dSToby Isaac 789db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots, 790db4efbfdSBarry Smith rather than put it in the Mat->row slot.*/ 791d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLUFactor_SeqDense(Mat A, IS row, IS col, const MatFactorInfo *minfo) 792d71ae5a4SJacob Faibussowitsch { 793db4efbfdSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 794db4efbfdSBarry Smith PetscBLASInt n, m, info; 795db4efbfdSBarry Smith 796db4efbfdSBarry Smith PetscFunctionBegin; 7979566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 7989566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 7994dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); } 8003ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 8019566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 802792fecdfSBarry Smith PetscCallBLAS("LAPACKgetrf", LAPACKgetrf_(&m, &n, mat->v, &mat->lda, mat->pivots, &info)); 8039566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 8048e57ea43SSatish Balay 80505fcb23eSStefano Zampini PetscCheck(info >= 0, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to LU factorization %d", (int)info); 80605fcb23eSStefano Zampini PetscCheck(info <= 0, PETSC_COMM_SELF, PETSC_ERR_MAT_LU_ZRPVT, "Bad LU factorization %d", (int)info); 8078208b9aeSStefano Zampini 8084396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_LU; 8094396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_LU; 8104396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_LU; 8114396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_LU; 812d5f3da31SBarry Smith A->factortype = MAT_FACTOR_LU; 813db4efbfdSBarry Smith 8149566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 8159566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 816f6224b95SHong Zhang 8179566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((2.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3)); 8183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 819db4efbfdSBarry Smith } 820db4efbfdSBarry Smith 821d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) 822d71ae5a4SJacob Faibussowitsch { 8234396437dSToby Isaac MatFactorInfo info; 8244396437dSToby Isaac 8254396437dSToby Isaac PetscFunctionBegin; 8269566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 827dbbe0bcdSBarry Smith PetscUseTypeMethod(fact, lufactor, NULL, NULL, &info); 8283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8294396437dSToby Isaac } 8304396437dSToby Isaac 831d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, IS col, const MatFactorInfo *info) 832d71ae5a4SJacob Faibussowitsch { 8334396437dSToby Isaac PetscFunctionBegin; 8344396437dSToby Isaac fact->preallocated = PETSC_TRUE; 8354396437dSToby Isaac fact->assembled = PETSC_TRUE; 8364396437dSToby Isaac fact->ops->lufactornumeric = MatLUFactorNumeric_SeqDense; 8373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8384396437dSToby Isaac } 8394396437dSToby Isaac 840a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */ 841d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCholeskyFactor_SeqDense(Mat A, IS perm, const MatFactorInfo *factinfo) 842d71ae5a4SJacob Faibussowitsch { 843db4efbfdSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 844c5df96a5SBarry Smith PetscBLASInt info, n; 845db4efbfdSBarry Smith 846db4efbfdSBarry Smith PetscFunctionBegin; 8479566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 8483ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 849b94d7dedSBarry Smith if (A->spd == PETSC_BOOL3_TRUE) { 8509566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 851792fecdfSBarry Smith PetscCallBLAS("LAPACKpotrf", LAPACKpotrf_("L", &n, mat->v, &mat->lda, &info)); 8529566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 853a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX) 854b94d7dedSBarry Smith } else if (A->hermitian == PETSC_BOOL3_TRUE) { 8554dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); } 856a49dc2a2SStefano Zampini if (!mat->fwork) { 857a49dc2a2SStefano Zampini PetscScalar dummy; 858a49dc2a2SStefano Zampini 859a49dc2a2SStefano Zampini mat->lfwork = -1; 8609566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 861792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info)); 8629566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 863a49dc2a2SStefano Zampini mat->lfwork = (PetscInt)PetscRealPart(dummy); 8649566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 865a49dc2a2SStefano Zampini } 8669566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 867792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info)); 8689566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 869a49dc2a2SStefano Zampini #endif 870a49dc2a2SStefano Zampini } else { /* symmetric case */ 8714dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); } 872a49dc2a2SStefano Zampini if (!mat->fwork) { 873a49dc2a2SStefano Zampini PetscScalar dummy; 874a49dc2a2SStefano Zampini 875a49dc2a2SStefano Zampini mat->lfwork = -1; 8769566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 877792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info)); 8789566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 879a49dc2a2SStefano Zampini mat->lfwork = (PetscInt)PetscRealPart(dummy); 8809566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 881a49dc2a2SStefano Zampini } 8829566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 883792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info)); 8849566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 885a49dc2a2SStefano Zampini } 88628b400f6SJacob Faibussowitsch PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad factorization: zero pivot in row %" PetscInt_FMT, (PetscInt)info - 1); 8878208b9aeSStefano Zampini 8884396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_Cholesky; 8894396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_Cholesky; 8904396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_Cholesky; 8914396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_Cholesky; 892d5f3da31SBarry Smith A->factortype = MAT_FACTOR_CHOLESKY; 8932205254eSKarl Rupp 8949566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 8959566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 896f6224b95SHong Zhang 8979566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0)); 8983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 899db4efbfdSBarry Smith } 900db4efbfdSBarry Smith 901d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) 902d71ae5a4SJacob Faibussowitsch { 903db4efbfdSBarry Smith MatFactorInfo info; 904db4efbfdSBarry Smith 905db4efbfdSBarry Smith PetscFunctionBegin; 906db4efbfdSBarry Smith info.fill = 1.0; 9072205254eSKarl Rupp 9089566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 909dbbe0bcdSBarry Smith PetscUseTypeMethod(fact, choleskyfactor, NULL, &info); 9103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 911db4efbfdSBarry Smith } 912db4efbfdSBarry Smith 913d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info) 914d71ae5a4SJacob Faibussowitsch { 915db4efbfdSBarry Smith PetscFunctionBegin; 916c3ef05f6SHong Zhang fact->assembled = PETSC_TRUE; 9171bbcc794SSatish Balay fact->preallocated = PETSC_TRUE; 918719d5645SBarry Smith fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense; 9193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 920db4efbfdSBarry Smith } 921db4efbfdSBarry Smith 922d71ae5a4SJacob Faibussowitsch PetscErrorCode MatQRFactor_SeqDense(Mat A, IS col, const MatFactorInfo *minfo) 923d71ae5a4SJacob Faibussowitsch { 9244905a7bcSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 9254905a7bcSToby Isaac PetscBLASInt n, m, info, min, max; 9264905a7bcSToby Isaac 9274905a7bcSToby Isaac PetscFunctionBegin; 9289566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 9299566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 9304396437dSToby Isaac max = PetscMax(m, n); 9314396437dSToby Isaac min = PetscMin(m, n); 9324dfa11a4SJacob Faibussowitsch if (!mat->tau) { PetscCall(PetscMalloc1(min, &mat->tau)); } 9334dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(n, &mat->pivots)); } 934f4f49eeaSPierre Jolivet if (!mat->qrrhs) PetscCall(MatCreateVecs(A, NULL, &mat->qrrhs)); 9353ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 9364905a7bcSToby Isaac if (!mat->fwork) { 9374905a7bcSToby Isaac PetscScalar dummy; 9384905a7bcSToby Isaac 9394905a7bcSToby Isaac mat->lfwork = -1; 9409566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 941792fecdfSBarry Smith PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, &dummy, &mat->lfwork, &info)); 9429566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 9434905a7bcSToby Isaac mat->lfwork = (PetscInt)PetscRealPart(dummy); 9449566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 9454905a7bcSToby Isaac } 9469566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 947792fecdfSBarry Smith PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, mat->fwork, &mat->lfwork, &info)); 9489566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 94905fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to QR factorization %d", (int)info); 9504905a7bcSToby 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 9514905a7bcSToby Isaac mat->rank = min; 9524905a7bcSToby Isaac 9534396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_QR; 9544396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_QR; 9554905a7bcSToby Isaac A->factortype = MAT_FACTOR_QR; 9564905a7bcSToby Isaac if (m == n) { 9574396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_QR; 9584396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_QR; 9594905a7bcSToby Isaac } 9604905a7bcSToby Isaac 9619566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 9629566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 9634905a7bcSToby Isaac 9649566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * min * min * (max - min / 3.0))); 9653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9664905a7bcSToby Isaac } 9674905a7bcSToby Isaac 968d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatQRFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) 969d71ae5a4SJacob Faibussowitsch { 9704905a7bcSToby Isaac MatFactorInfo info; 9714905a7bcSToby Isaac 9724905a7bcSToby Isaac PetscFunctionBegin; 9734905a7bcSToby Isaac info.fill = 1.0; 9744905a7bcSToby Isaac 9759566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 976cac4c232SBarry Smith PetscUseMethod(fact, "MatQRFactor_C", (Mat, IS, const MatFactorInfo *), (fact, NULL, &info)); 9773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9784905a7bcSToby Isaac } 9794905a7bcSToby Isaac 980d71ae5a4SJacob Faibussowitsch PetscErrorCode MatQRFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info) 981d71ae5a4SJacob Faibussowitsch { 9824905a7bcSToby Isaac PetscFunctionBegin; 9834905a7bcSToby Isaac fact->assembled = PETSC_TRUE; 9844905a7bcSToby Isaac fact->preallocated = PETSC_TRUE; 9859566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)fact, "MatQRFactorNumeric_C", MatQRFactorNumeric_SeqDense)); 9863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9874905a7bcSToby Isaac } 9884905a7bcSToby Isaac 989ca15aa20SStefano Zampini /* uses LAPACK */ 990d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A, MatFactorType ftype, Mat *fact) 991d71ae5a4SJacob Faibussowitsch { 992db4efbfdSBarry Smith PetscFunctionBegin; 9939566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), fact)); 9949566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*fact, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n)); 9959566063dSJacob Faibussowitsch PetscCall(MatSetType(*fact, MATDENSE)); 99666e17bc3SBarry Smith (*fact)->trivialsymbolic = PETSC_TRUE; 9972a350339SBarry Smith if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU) { 998db4efbfdSBarry Smith (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense; 9992a350339SBarry Smith (*fact)->ops->ilufactorsymbolic = MatLUFactorSymbolic_SeqDense; 1000bf5a80bcSToby Isaac } else if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) { 1001db4efbfdSBarry Smith (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense; 1002bf5a80bcSToby Isaac } else if (ftype == MAT_FACTOR_QR) { 1003f4f49eeaSPierre Jolivet PetscCall(PetscObjectComposeFunction((PetscObject)*fact, "MatQRFactorSymbolic_C", MatQRFactorSymbolic_SeqDense)); 1004db4efbfdSBarry Smith } 1005d5f3da31SBarry Smith (*fact)->factortype = ftype; 100600c67f3bSHong Zhang 10079566063dSJacob Faibussowitsch PetscCall(PetscFree((*fact)->solvertype)); 10089566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &(*fact)->solvertype)); 10099566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_LU])); 10109566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ILU])); 10119566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_CHOLESKY])); 10129566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ICC])); 10133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1014db4efbfdSBarry Smith } 1015db4efbfdSBarry Smith 1016d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSOR_SeqDense(Mat A, Vec bb, PetscReal omega, MatSORType flag, PetscReal shift, PetscInt its, PetscInt lits, Vec xx) 1017d71ae5a4SJacob Faibussowitsch { 1018c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1019d9ca1df4SBarry Smith PetscScalar *x, *v = mat->v, zero = 0.0, xt; 1020d9ca1df4SBarry Smith const PetscScalar *b; 1021d0f46423SBarry Smith PetscInt m = A->rmap->n, i; 102223fff9afSBarry Smith PetscBLASInt o = 1, bm = 0; 1023289bc588SBarry Smith 10243a40ed3dSBarry Smith PetscFunctionBegin; 102547d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 102608401ef6SPierre Jolivet PetscCheck(A->offloadmask != PETSC_OFFLOAD_GPU, PETSC_COMM_SELF, PETSC_ERR_SUP, "Not implemented"); 1027ca15aa20SStefano Zampini #endif 1028422a814eSBarry Smith if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */ 10299566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(m, &bm)); 1030289bc588SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 10313bffc371SBarry Smith /* this is a hack fix, should have another version without the second BLASdotu */ 10329566063dSJacob Faibussowitsch PetscCall(VecSet(xx, zero)); 1033289bc588SBarry Smith } 10349566063dSJacob Faibussowitsch PetscCall(VecGetArray(xx, &x)); 10359566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(bb, &b)); 1036b965ef7fSBarry Smith its = its * lits; 103708401ef6SPierre 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); 1038289bc588SBarry Smith while (its--) { 1039fccaa45eSBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 1040289bc588SBarry Smith for (i = 0; i < m; i++) { 1041792fecdfSBarry Smith PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o)); 104255a1b374SBarry Smith x[i] = (1. - omega) * x[i] + omega * (xt + v[i + i * m] * x[i]) / (v[i + i * m] + shift); 1043289bc588SBarry Smith } 1044289bc588SBarry Smith } 1045fccaa45eSBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 1046289bc588SBarry Smith for (i = m - 1; i >= 0; i--) { 1047792fecdfSBarry Smith PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o)); 104855a1b374SBarry Smith x[i] = (1. - omega) * x[i] + omega * (xt + v[i + i * m] * x[i]) / (v[i + i * m] + shift); 1049289bc588SBarry Smith } 1050289bc588SBarry Smith } 1051289bc588SBarry Smith } 10529566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(bb, &b)); 10539566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(xx, &x)); 10543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1055289bc588SBarry Smith } 1056289bc588SBarry Smith 10570be0d8bdSHansol Suh static PetscErrorCode MatMultColumnRangeKernel_SeqDense(Mat A, Vec xx, Vec yy, PetscInt c_start, PetscInt c_end, PetscBool trans, PetscBool herm) 1058d71ae5a4SJacob Faibussowitsch { 1059c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1060d9ca1df4SBarry Smith PetscScalar *y, _DOne = 1.0, _DZero = 0.0; 10610805154bSBarry Smith PetscBLASInt m, n, _One = 1; 1062d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 10633a40ed3dSBarry Smith 10643a40ed3dSBarry Smith PetscFunctionBegin; 10659566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 10660be0d8bdSHansol Suh PetscCall(PetscBLASIntCast(c_end - c_start, &n)); 10679566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 10689566063dSJacob Faibussowitsch PetscCall(VecGetArrayWrite(yy, &y)); 10690be0d8bdSHansol Suh if (!m || !n) { 10705ac36cfcSBarry Smith PetscBLASInt i; 1071459e8d23SBlanca Mellado Pinto if (trans) 1072459e8d23SBlanca Mellado Pinto for (i = 0; i < n; i++) y[i] = 0.0; 1073459e8d23SBlanca Mellado Pinto else 10745ac36cfcSBarry Smith for (i = 0; i < m; i++) y[i] = 0.0; 10755ac36cfcSBarry Smith } else { 1076459e8d23SBlanca Mellado Pinto if (trans) { 10770be0d8bdSHansol Suh if (herm) PetscCallBLAS("BLASgemv", BLASgemv_("C", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x, &_One, &_DZero, y + c_start, &_One)); 10780be0d8bdSHansol Suh else PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x, &_One, &_DZero, y + c_start, &_One)); 1079459e8d23SBlanca Mellado Pinto } else { 10800be0d8bdSHansol Suh PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x + c_start, &_One, &_DZero, y, &_One)); 1081459e8d23SBlanca Mellado Pinto } 10820be0d8bdSHansol Suh PetscCall(PetscLogFlops(2.0 * m * n - n)); 10835ac36cfcSBarry Smith } 10849566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 10859566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayWrite(yy, &y)); 10863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1087289bc588SBarry Smith } 10886ee01492SSatish Balay 10890be0d8bdSHansol Suh PetscErrorCode MatMultHermitianTransposeColumnRange_SeqDense(Mat A, Vec xx, Vec yy, PetscInt c_start, PetscInt c_end) 10900be0d8bdSHansol Suh { 10910be0d8bdSHansol Suh PetscFunctionBegin; 10920be0d8bdSHansol Suh PetscCall(MatMultColumnRangeKernel_SeqDense(A, xx, yy, c_start, c_end, PETSC_TRUE, PETSC_TRUE)); 10930be0d8bdSHansol Suh PetscFunctionReturn(PETSC_SUCCESS); 10940be0d8bdSHansol Suh } 10950be0d8bdSHansol Suh 1096459e8d23SBlanca Mellado Pinto PetscErrorCode MatMult_SeqDense(Mat A, Vec xx, Vec yy) 1097459e8d23SBlanca Mellado Pinto { 1098459e8d23SBlanca Mellado Pinto PetscFunctionBegin; 10990be0d8bdSHansol Suh PetscCall(MatMultColumnRangeKernel_SeqDense(A, xx, yy, 0, A->cmap->n, PETSC_FALSE, PETSC_FALSE)); 1100459e8d23SBlanca Mellado Pinto PetscFunctionReturn(PETSC_SUCCESS); 1101459e8d23SBlanca Mellado Pinto } 1102459e8d23SBlanca Mellado Pinto 1103459e8d23SBlanca Mellado Pinto PetscErrorCode MatMultTranspose_SeqDense(Mat A, Vec xx, Vec yy) 1104459e8d23SBlanca Mellado Pinto { 1105459e8d23SBlanca Mellado Pinto PetscFunctionBegin; 11060be0d8bdSHansol Suh PetscCall(MatMultColumnRangeKernel_SeqDense(A, xx, yy, 0, A->cmap->n, PETSC_TRUE, PETSC_FALSE)); 1107459e8d23SBlanca Mellado Pinto PetscFunctionReturn(PETSC_SUCCESS); 1108459e8d23SBlanca Mellado Pinto } 1109459e8d23SBlanca Mellado Pinto 1110459e8d23SBlanca Mellado Pinto PetscErrorCode MatMultHermitianTranspose_SeqDense(Mat A, Vec xx, Vec yy) 1111459e8d23SBlanca Mellado Pinto { 1112459e8d23SBlanca Mellado Pinto PetscFunctionBegin; 11130be0d8bdSHansol Suh PetscCall(MatMultColumnRangeKernel_SeqDense(A, xx, yy, 0, A->cmap->n, PETSC_TRUE, PETSC_TRUE)); 1114459e8d23SBlanca Mellado Pinto PetscFunctionReturn(PETSC_SUCCESS); 1115459e8d23SBlanca Mellado Pinto } 1116459e8d23SBlanca Mellado Pinto 11170be0d8bdSHansol Suh static PetscErrorCode MatMultAddColumnRangeKernel_SeqDense(Mat A, Vec xx, Vec zz, Vec yy, PetscInt c_start, PetscInt c_end, PetscBool trans, PetscBool herm) 1118d71ae5a4SJacob Faibussowitsch { 1119c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1120d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 1121d9ca1df4SBarry Smith PetscScalar *y, _DOne = 1.0; 11220805154bSBarry Smith PetscBLASInt m, n, _One = 1; 11233a40ed3dSBarry Smith 11243a40ed3dSBarry Smith PetscFunctionBegin; 11259566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 11260be0d8bdSHansol Suh PetscCall(PetscBLASIntCast(c_end - c_start, &n)); 11279566063dSJacob Faibussowitsch PetscCall(VecCopy(zz, yy)); 11280be0d8bdSHansol Suh if (!m || !n) PetscFunctionReturn(PETSC_SUCCESS); 11299566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &y)); 1130459e8d23SBlanca Mellado Pinto PetscCall(VecGetArrayRead(xx, &x)); 1131459e8d23SBlanca Mellado Pinto if (trans) { 11320be0d8bdSHansol Suh if (herm) PetscCallBLAS("BLASgemv", BLASgemv_("C", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x, &_One, &_DOne, y + c_start, &_One)); 11330be0d8bdSHansol Suh else PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x, &_One, &_DOne, y + c_start, &_One)); 1134459e8d23SBlanca Mellado Pinto } else { 11350be0d8bdSHansol Suh PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x + c_start, &_One, &_DOne, y, &_One)); 1136459e8d23SBlanca Mellado Pinto } 11379566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 11389566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &y)); 11390be0d8bdSHansol Suh PetscCall(PetscLogFlops(2.0 * m * n)); 11400be0d8bdSHansol Suh PetscFunctionReturn(PETSC_SUCCESS); 11410be0d8bdSHansol Suh } 11420be0d8bdSHansol Suh 11430be0d8bdSHansol Suh PetscErrorCode MatMultAddColumnRange_SeqDense(Mat A, Vec xx, Vec zz, Vec yy, PetscInt c_start, PetscInt c_end) 11440be0d8bdSHansol Suh { 11450be0d8bdSHansol Suh PetscFunctionBegin; 11460be0d8bdSHansol Suh PetscCall(MatMultAddColumnRangeKernel_SeqDense(A, xx, zz, yy, c_start, c_end, PETSC_FALSE, PETSC_FALSE)); 11470be0d8bdSHansol Suh PetscFunctionReturn(PETSC_SUCCESS); 11480be0d8bdSHansol Suh } 11490be0d8bdSHansol Suh 11500be0d8bdSHansol Suh PetscErrorCode MatMultHermitianTransposeAddColumnRange_SeqDense(Mat A, Vec xx, Vec zz, Vec yy, PetscInt c_start, PetscInt c_end) 11510be0d8bdSHansol Suh { 11520be0d8bdSHansol Suh PetscFunctionBegin; 11530be0d8bdSHansol Suh PetscMPIInt rank; 11540be0d8bdSHansol Suh PetscCallMPI(MPI_Comm_rank(MPI_COMM_WORLD, &rank)); 11550be0d8bdSHansol Suh PetscCall(MatMultAddColumnRangeKernel_SeqDense(A, xx, zz, yy, c_start, c_end, PETSC_TRUE, PETSC_TRUE)); 11563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1157289bc588SBarry Smith } 11586ee01492SSatish Balay 1159459e8d23SBlanca Mellado Pinto PetscErrorCode MatMultAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) 1160459e8d23SBlanca Mellado Pinto { 1161459e8d23SBlanca Mellado Pinto PetscFunctionBegin; 11620be0d8bdSHansol Suh PetscCall(MatMultAddColumnRangeKernel_SeqDense(A, xx, zz, yy, 0, A->cmap->n, PETSC_FALSE, PETSC_FALSE)); 1163459e8d23SBlanca Mellado Pinto PetscFunctionReturn(PETSC_SUCCESS); 1164459e8d23SBlanca Mellado Pinto } 1165459e8d23SBlanca Mellado Pinto 1166d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) 1167d71ae5a4SJacob Faibussowitsch { 11683a40ed3dSBarry Smith PetscFunctionBegin; 11690be0d8bdSHansol Suh PetscCall(MatMultAddColumnRangeKernel_SeqDense(A, xx, zz, yy, 0, A->cmap->n, PETSC_TRUE, PETSC_FALSE)); 1170459e8d23SBlanca Mellado Pinto PetscFunctionReturn(PETSC_SUCCESS); 1171459e8d23SBlanca Mellado Pinto } 1172459e8d23SBlanca Mellado Pinto 1173459e8d23SBlanca Mellado Pinto PetscErrorCode MatMultHermitianTransposeAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) 1174459e8d23SBlanca Mellado Pinto { 1175459e8d23SBlanca Mellado Pinto PetscFunctionBegin; 11760be0d8bdSHansol Suh PetscCall(MatMultAddColumnRangeKernel_SeqDense(A, xx, zz, yy, 0, A->cmap->n, PETSC_TRUE, PETSC_TRUE)); 11773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1178289bc588SBarry Smith } 1179289bc588SBarry Smith 1180d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals) 1181d71ae5a4SJacob Faibussowitsch { 1182c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 118313f74950SBarry Smith PetscInt i; 118467e560aaSBarry Smith 11853a40ed3dSBarry Smith PetscFunctionBegin; 1186c3e1b152SPierre Jolivet if (ncols) *ncols = A->cmap->n; 1187289bc588SBarry Smith if (cols) { 11889566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->cmap->n, cols)); 1189d0f46423SBarry Smith for (i = 0; i < A->cmap->n; i++) (*cols)[i] = i; 1190289bc588SBarry Smith } 1191289bc588SBarry Smith if (vals) { 1192ca15aa20SStefano Zampini const PetscScalar *v; 1193ca15aa20SStefano Zampini 11949566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 11959566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->cmap->n, vals)); 1196ca15aa20SStefano Zampini v += row; 11979371c9d4SSatish Balay for (i = 0; i < A->cmap->n; i++) { 11989371c9d4SSatish Balay (*vals)[i] = *v; 11999371c9d4SSatish Balay v += mat->lda; 12009371c9d4SSatish Balay } 12019566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 1202289bc588SBarry Smith } 12033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1204289bc588SBarry Smith } 12056ee01492SSatish Balay 1206d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRestoreRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals) 1207d71ae5a4SJacob Faibussowitsch { 1208606d414cSSatish Balay PetscFunctionBegin; 12099566063dSJacob Faibussowitsch if (cols) PetscCall(PetscFree(*cols)); 12109566063dSJacob Faibussowitsch if (vals) PetscCall(PetscFree(*vals)); 12113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1212289bc588SBarry Smith } 12132ef1f0ffSBarry Smith 1214d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], const PetscScalar v[], InsertMode addv) 1215d71ae5a4SJacob Faibussowitsch { 1216c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1217ca15aa20SStefano Zampini PetscScalar *av; 121813f74950SBarry Smith PetscInt i, j, idx = 0; 121947d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1220c70f7ee4SJunchao Zhang PetscOffloadMask oldf; 1221ca15aa20SStefano Zampini #endif 1222d6dfbf8fSBarry Smith 12233a40ed3dSBarry Smith PetscFunctionBegin; 12249566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &av)); 1225289bc588SBarry Smith if (!mat->roworiented) { 1226dbb450caSBarry Smith if (addv == INSERT_VALUES) { 1227289bc588SBarry Smith for (j = 0; j < n; j++) { 12289371c9d4SSatish Balay if (indexn[j] < 0) { 12299371c9d4SSatish Balay idx += m; 12309371c9d4SSatish Balay continue; 12319371c9d4SSatish Balay } 12326bdcaf15SBarry 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); 1233289bc588SBarry Smith for (i = 0; i < m; i++) { 12349371c9d4SSatish Balay if (indexm[i] < 0) { 12359371c9d4SSatish Balay idx++; 12369371c9d4SSatish Balay continue; 12379371c9d4SSatish Balay } 12386bdcaf15SBarry 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); 12390be0d8bdSHansol Suh av[indexn[j] * mat->lda + indexm[i]] = v[idx++]; 1240289bc588SBarry Smith } 1241289bc588SBarry Smith } 12420be0d8bdSHansol Suh } else { 1243289bc588SBarry Smith for (j = 0; j < n; j++) { 12449371c9d4SSatish Balay if (indexn[j] < 0) { 12459371c9d4SSatish Balay idx += m; 12469371c9d4SSatish Balay continue; 12479371c9d4SSatish Balay } 12486bdcaf15SBarry 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); 1249289bc588SBarry Smith for (i = 0; i < m; i++) { 12509371c9d4SSatish Balay if (indexm[i] < 0) { 12519371c9d4SSatish Balay idx++; 12529371c9d4SSatish Balay continue; 12539371c9d4SSatish Balay } 12546bdcaf15SBarry 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); 1255ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] += v[idx++]; 1256289bc588SBarry Smith } 1257289bc588SBarry Smith } 1258289bc588SBarry Smith } 12593a40ed3dSBarry Smith } else { 1260dbb450caSBarry Smith if (addv == INSERT_VALUES) { 1261e8d4e0b9SBarry Smith for (i = 0; i < m; i++) { 12629371c9d4SSatish Balay if (indexm[i] < 0) { 12639371c9d4SSatish Balay idx += n; 12649371c9d4SSatish Balay continue; 12659371c9d4SSatish Balay } 12666bdcaf15SBarry 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); 1267e8d4e0b9SBarry Smith for (j = 0; j < n; j++) { 12689371c9d4SSatish Balay if (indexn[j] < 0) { 12699371c9d4SSatish Balay idx++; 12709371c9d4SSatish Balay continue; 12719371c9d4SSatish Balay } 12726bdcaf15SBarry 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); 12730be0d8bdSHansol Suh av[indexn[j] * mat->lda + indexm[i]] = v[idx++]; 1274e8d4e0b9SBarry Smith } 1275e8d4e0b9SBarry Smith } 12760be0d8bdSHansol Suh } else { 1277289bc588SBarry Smith for (i = 0; i < m; i++) { 12789371c9d4SSatish Balay if (indexm[i] < 0) { 12799371c9d4SSatish Balay idx += n; 12809371c9d4SSatish Balay continue; 12819371c9d4SSatish Balay } 12826bdcaf15SBarry 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); 1283289bc588SBarry Smith for (j = 0; j < n; j++) { 12849371c9d4SSatish Balay if (indexn[j] < 0) { 12859371c9d4SSatish Balay idx++; 12869371c9d4SSatish Balay continue; 12879371c9d4SSatish Balay } 12886bdcaf15SBarry 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); 1289ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] += v[idx++]; 1290289bc588SBarry Smith } 1291289bc588SBarry Smith } 1292289bc588SBarry Smith } 1293e8d4e0b9SBarry Smith } 1294ca15aa20SStefano Zampini /* hack to prevent unneeded copy to the GPU while returning the array */ 129547d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1296c70f7ee4SJunchao Zhang oldf = A->offloadmask; 1297c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_GPU; 1298ca15aa20SStefano Zampini #endif 12999566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &av)); 130047d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1301c70f7ee4SJunchao Zhang A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU); 1302ca15aa20SStefano Zampini #endif 13033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1304289bc588SBarry Smith } 1305e8d4e0b9SBarry Smith 1306d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], PetscScalar v[]) 1307d71ae5a4SJacob Faibussowitsch { 1308ae80bb75SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1309ca15aa20SStefano Zampini const PetscScalar *vv; 131013f74950SBarry Smith PetscInt i, j; 1311ae80bb75SLois Curfman McInnes 13123a40ed3dSBarry Smith PetscFunctionBegin; 13139566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &vv)); 1314ae80bb75SLois Curfman McInnes /* row-oriented output */ 1315ae80bb75SLois Curfman McInnes for (i = 0; i < m; i++) { 13169371c9d4SSatish Balay if (indexm[i] < 0) { 13179371c9d4SSatish Balay v += n; 13189371c9d4SSatish Balay continue; 13199371c9d4SSatish Balay } 132008401ef6SPierre 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); 1321ae80bb75SLois Curfman McInnes for (j = 0; j < n; j++) { 13229371c9d4SSatish Balay if (indexn[j] < 0) { 13239371c9d4SSatish Balay v++; 13249371c9d4SSatish Balay continue; 13259371c9d4SSatish Balay } 132608401ef6SPierre 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); 1327ca15aa20SStefano Zampini *v++ = vv[indexn[j] * mat->lda + indexm[i]]; 1328ae80bb75SLois Curfman McInnes } 1329ae80bb75SLois Curfman McInnes } 13309566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &vv)); 13313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1332ae80bb75SLois Curfman McInnes } 1333ae80bb75SLois Curfman McInnes 1334d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_Dense_Binary(Mat mat, PetscViewer viewer) 1335d71ae5a4SJacob Faibussowitsch { 13368491ab44SLisandro Dalcin PetscBool skipHeader; 13378491ab44SLisandro Dalcin PetscViewerFormat format; 13388491ab44SLisandro Dalcin PetscInt header[4], M, N, m, lda, i, j, k; 13398491ab44SLisandro Dalcin const PetscScalar *v; 13408491ab44SLisandro Dalcin PetscScalar *vwork; 1341aabbc4fbSShri Abhyankar 1342aabbc4fbSShri Abhyankar PetscFunctionBegin; 13439566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 13449566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader)); 13459566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 13468491ab44SLisandro Dalcin if (skipHeader) format = PETSC_VIEWER_NATIVE; 1347aabbc4fbSShri Abhyankar 13489566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &M, &N)); 13498491ab44SLisandro Dalcin 13508491ab44SLisandro Dalcin /* write matrix header */ 13519371c9d4SSatish Balay header[0] = MAT_FILE_CLASSID; 13529371c9d4SSatish Balay header[1] = M; 13539371c9d4SSatish Balay header[2] = N; 13548491ab44SLisandro Dalcin header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M * N; 13559566063dSJacob Faibussowitsch if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer, header, 4, PETSC_INT)); 13568491ab44SLisandro Dalcin 13579566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mat, &m, NULL)); 13588491ab44SLisandro Dalcin if (format != PETSC_VIEWER_NATIVE) { 13598491ab44SLisandro Dalcin PetscInt nnz = m * N, *iwork; 13608491ab44SLisandro Dalcin /* store row lengths for each row */ 13619566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz, &iwork)); 13628491ab44SLisandro Dalcin for (i = 0; i < m; i++) iwork[i] = N; 13639566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 13648491ab44SLisandro Dalcin /* store column indices (zero start index) */ 13658491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 13669371c9d4SSatish Balay for (j = 0; j < N; j++, k++) iwork[k] = j; 13679566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 13689566063dSJacob Faibussowitsch PetscCall(PetscFree(iwork)); 13698491ab44SLisandro Dalcin } 13708491ab44SLisandro Dalcin /* store matrix values as a dense matrix in row major order */ 13719566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m * N, &vwork)); 13729566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(mat, &v)); 13739566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(mat, &lda)); 13748491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 13759371c9d4SSatish Balay for (j = 0; j < N; j++, k++) vwork[k] = v[i + lda * j]; 13769566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(mat, &v)); 13779566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, vwork, m * N, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 13789566063dSJacob Faibussowitsch PetscCall(PetscFree(vwork)); 13793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13808491ab44SLisandro Dalcin } 13818491ab44SLisandro Dalcin 1382d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLoad_Dense_Binary(Mat mat, PetscViewer viewer) 1383d71ae5a4SJacob Faibussowitsch { 13848491ab44SLisandro Dalcin PetscBool skipHeader; 13858491ab44SLisandro Dalcin PetscInt header[4], M, N, m, nz, lda, i, j, k; 13868491ab44SLisandro Dalcin PetscInt rows, cols; 13878491ab44SLisandro Dalcin PetscScalar *v, *vwork; 13888491ab44SLisandro Dalcin 13898491ab44SLisandro Dalcin PetscFunctionBegin; 13909566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 13919566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader)); 13928491ab44SLisandro Dalcin 13938491ab44SLisandro Dalcin if (!skipHeader) { 13949566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, header, 4, NULL, PETSC_INT)); 139508401ef6SPierre Jolivet PetscCheck(header[0] == MAT_FILE_CLASSID, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Not a matrix object in file"); 13969371c9d4SSatish Balay M = header[1]; 13979371c9d4SSatish Balay N = header[2]; 139808401ef6SPierre Jolivet PetscCheck(M >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix row size (%" PetscInt_FMT ") in file is negative", M); 139908401ef6SPierre Jolivet PetscCheck(N >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix column size (%" PetscInt_FMT ") in file is negative", N); 14008491ab44SLisandro Dalcin nz = header[3]; 1401aed4548fSBarry Smith PetscCheck(nz == MATRIX_BINARY_FORMAT_DENSE || nz >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Unknown matrix format %" PetscInt_FMT " in file", nz); 1402aabbc4fbSShri Abhyankar } else { 14039566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &M, &N)); 1404aed4548fSBarry Smith PetscCheck(M >= 0 && N >= 0, PETSC_COMM_SELF, PETSC_ERR_USER, "Matrix binary file header was skipped, thus the user must specify the global sizes of input matrix"); 14058491ab44SLisandro Dalcin nz = MATRIX_BINARY_FORMAT_DENSE; 1406e6324fbbSBarry Smith } 1407aabbc4fbSShri Abhyankar 14088491ab44SLisandro Dalcin /* setup global sizes if not set */ 14098491ab44SLisandro Dalcin if (mat->rmap->N < 0) mat->rmap->N = M; 14108491ab44SLisandro Dalcin if (mat->cmap->N < 0) mat->cmap->N = N; 14119566063dSJacob Faibussowitsch PetscCall(MatSetUp(mat)); 14128491ab44SLisandro Dalcin /* check if global sizes are correct */ 14139566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &rows, &cols)); 1414aed4548fSBarry Smith PetscCheck(M == rows && N == cols, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix in file of different sizes (%" PetscInt_FMT ", %" PetscInt_FMT ") than the input matrix (%" PetscInt_FMT ", %" PetscInt_FMT ")", M, N, rows, cols); 1415aabbc4fbSShri Abhyankar 14169566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, NULL, &N)); 14179566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mat, &m, NULL)); 14189566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(mat, &v)); 14199566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(mat, &lda)); 14208491ab44SLisandro Dalcin if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense format */ 14218491ab44SLisandro Dalcin PetscInt nnz = m * N; 14228491ab44SLisandro Dalcin /* read in matrix values */ 14239566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz, &vwork)); 14249566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 14258491ab44SLisandro Dalcin /* store values in column major order */ 14268491ab44SLisandro Dalcin for (j = 0; j < N; j++) 14279371c9d4SSatish Balay for (i = 0; i < m; i++) v[i + lda * j] = vwork[i * N + j]; 14289566063dSJacob Faibussowitsch PetscCall(PetscFree(vwork)); 14298491ab44SLisandro Dalcin } else { /* matrix in file is sparse format */ 14308491ab44SLisandro Dalcin PetscInt nnz = 0, *rlens, *icols; 14318491ab44SLisandro Dalcin /* read in row lengths */ 14329566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m, &rlens)); 14339566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, rlens, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 14348491ab44SLisandro Dalcin for (i = 0; i < m; i++) nnz += rlens[i]; 14358491ab44SLisandro Dalcin /* read in column indices and values */ 14369566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(nnz, &icols, nnz, &vwork)); 14379566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, icols, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 14389566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 14398491ab44SLisandro Dalcin /* store values in column major order */ 14408491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 14419371c9d4SSatish Balay for (j = 0; j < rlens[i]; j++, k++) v[i + lda * icols[k]] = vwork[k]; 14429566063dSJacob Faibussowitsch PetscCall(PetscFree(rlens)); 14439566063dSJacob Faibussowitsch PetscCall(PetscFree2(icols, vwork)); 1444aabbc4fbSShri Abhyankar } 14459566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(mat, &v)); 14469566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY)); 14479566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY)); 14483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1449aabbc4fbSShri Abhyankar } 1450aabbc4fbSShri Abhyankar 145166976f2fSJacob Faibussowitsch static PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer) 1452d71ae5a4SJacob Faibussowitsch { 1453eb91f321SVaclav Hapla PetscBool isbinary, ishdf5; 1454eb91f321SVaclav Hapla 1455eb91f321SVaclav Hapla PetscFunctionBegin; 1456eb91f321SVaclav Hapla PetscValidHeaderSpecific(newMat, MAT_CLASSID, 1); 1457eb91f321SVaclav Hapla PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1458eb91f321SVaclav Hapla /* force binary viewer to load .info file if it has not yet done so */ 14599566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 14609566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 14619566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5)); 1462eb91f321SVaclav Hapla if (isbinary) { 14639566063dSJacob Faibussowitsch PetscCall(MatLoad_Dense_Binary(newMat, viewer)); 1464eb91f321SVaclav Hapla } else if (ishdf5) { 1465eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5) 14669566063dSJacob Faibussowitsch PetscCall(MatLoad_Dense_HDF5(newMat, viewer)); 1467eb91f321SVaclav Hapla #else 1468eb91f321SVaclav Hapla SETERRQ(PetscObjectComm((PetscObject)newMat), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1469eb91f321SVaclav Hapla #endif 1470eb91f321SVaclav Hapla } else { 147198921bdaSJacob Faibussowitsch SETERRQ(PetscObjectComm((PetscObject)newMat), PETSC_ERR_SUP, "Viewer type %s not yet supported for reading %s matrices", ((PetscObject)viewer)->type_name, ((PetscObject)newMat)->type_name); 1472eb91f321SVaclav Hapla } 14733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1474eb91f321SVaclav Hapla } 1475eb91f321SVaclav Hapla 1476d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_ASCII(Mat A, PetscViewer viewer) 1477d71ae5a4SJacob Faibussowitsch { 1478932b0c3eSLois Curfman McInnes Mat_SeqDense *a = (Mat_SeqDense *)A->data; 147913f74950SBarry Smith PetscInt i, j; 14802dcb1b2aSMatthew Knepley const char *name; 1481ca15aa20SStefano Zampini PetscScalar *v, *av; 1482f3ef73ceSBarry Smith PetscViewerFormat format; 14835f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX) 1484ace3abfcSBarry Smith PetscBool allreal = PETSC_TRUE; 14855f481a85SSatish Balay #endif 1486932b0c3eSLois Curfman McInnes 14873a40ed3dSBarry Smith PetscFunctionBegin; 14889566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&av)); 14899566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 1490456192e2SBarry Smith if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 14913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); /* do nothing for now */ 1492fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 14939566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE)); 1494d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 1495ca15aa20SStefano Zampini v = av + i; 14969566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "row %" PetscInt_FMT ":", i)); 1497d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1498aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 1499329f5518SBarry Smith if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) { 15009566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g + %g i) ", j, (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v))); 1501329f5518SBarry Smith } else if (PetscRealPart(*v)) { 15029566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)PetscRealPart(*v))); 15036831982aSBarry Smith } 150480cd9d93SLois Curfman McInnes #else 150548a46eb9SPierre Jolivet if (*v) PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)*v)); 150680cd9d93SLois Curfman McInnes #endif 15071b807ce4Svictorle v += a->lda; 150880cd9d93SLois Curfman McInnes } 15099566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 151080cd9d93SLois Curfman McInnes } 15119566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE)); 15123a40ed3dSBarry Smith } else { 15139566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE)); 1514aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 151547989497SBarry Smith /* determine if matrix has all real values */ 1516bcd8d3a4SJose E. Roman for (j = 0; j < A->cmap->n; j++) { 1517bcd8d3a4SJose E. Roman v = av + j * a->lda; 1518bcd8d3a4SJose E. Roman for (i = 0; i < A->rmap->n; i++) { 15199371c9d4SSatish Balay if (PetscImaginaryPart(v[i])) { 15209371c9d4SSatish Balay allreal = PETSC_FALSE; 15219371c9d4SSatish Balay break; 15229371c9d4SSatish Balay } 152347989497SBarry Smith } 1524bcd8d3a4SJose E. Roman } 152547989497SBarry Smith #endif 1526fb9695e5SSatish Balay if (format == PETSC_VIEWER_ASCII_MATLAB) { 15279566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)A, &name)); 15289566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%% Size = %" PetscInt_FMT " %" PetscInt_FMT " \n", A->rmap->n, A->cmap->n)); 15299566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%s = zeros(%" PetscInt_FMT ",%" PetscInt_FMT ");\n", name, A->rmap->n, A->cmap->n)); 15309566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%s = [\n", name)); 1531ffac6cdbSBarry Smith } 1532ffac6cdbSBarry Smith 1533d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 1534ca15aa20SStefano Zampini v = av + i; 1535d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1536aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 153747989497SBarry Smith if (allreal) { 15389566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)PetscRealPart(*v))); 153947989497SBarry Smith } else { 15409566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e + %18.16ei ", (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v))); 154147989497SBarry Smith } 1542289bc588SBarry Smith #else 15439566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)*v)); 1544289bc588SBarry Smith #endif 15451b807ce4Svictorle v += a->lda; 1546289bc588SBarry Smith } 15479566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 1548289bc588SBarry Smith } 154948a46eb9SPierre Jolivet if (format == PETSC_VIEWER_ASCII_MATLAB) PetscCall(PetscViewerASCIIPrintf(viewer, "];\n")); 15509566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE)); 1551da3a660dSBarry Smith } 15529566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&av)); 15539566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer)); 15543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1555289bc588SBarry Smith } 1556289bc588SBarry Smith 15579804daf3SBarry Smith #include <petscdraw.h> 1558d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw, void *Aa) 1559d71ae5a4SJacob Faibussowitsch { 1560f1af5d2fSBarry Smith Mat A = (Mat)Aa; 1561383922c3SLisandro Dalcin PetscInt m = A->rmap->n, n = A->cmap->n, i, j; 1562383922c3SLisandro Dalcin int color = PETSC_DRAW_WHITE; 1563ca15aa20SStefano Zampini const PetscScalar *v; 1564b0a32e0cSBarry Smith PetscViewer viewer; 1565b05fc000SLisandro Dalcin PetscReal xl, yl, xr, yr, x_l, x_r, y_l, y_r; 1566f3ef73ceSBarry Smith PetscViewerFormat format; 1567f1af5d2fSBarry Smith 1568f1af5d2fSBarry Smith PetscFunctionBegin; 15699566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)A, "Zoomviewer", (PetscObject *)&viewer)); 15709566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 15719566063dSJacob Faibussowitsch PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr)); 1572f1af5d2fSBarry Smith 1573f1af5d2fSBarry Smith /* Loop over matrix elements drawing boxes */ 15749566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 1575fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 1576d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 1577f1af5d2fSBarry Smith /* Blue for negative and Red for positive */ 1578f1af5d2fSBarry Smith for (j = 0; j < n; j++) { 15799371c9d4SSatish Balay x_l = j; 15809371c9d4SSatish Balay x_r = x_l + 1.0; 1581f1af5d2fSBarry Smith for (i = 0; i < m; i++) { 1582f1af5d2fSBarry Smith y_l = m - i - 1.0; 1583f1af5d2fSBarry Smith y_r = y_l + 1.0; 1584ca15aa20SStefano Zampini if (PetscRealPart(v[j * m + i]) > 0.) color = PETSC_DRAW_RED; 1585ca15aa20SStefano Zampini else if (PetscRealPart(v[j * m + i]) < 0.) color = PETSC_DRAW_BLUE; 1586ca15aa20SStefano Zampini else continue; 15879566063dSJacob Faibussowitsch PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color)); 1588f1af5d2fSBarry Smith } 1589f1af5d2fSBarry Smith } 1590d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 1591f1af5d2fSBarry Smith } else { 1592f1af5d2fSBarry Smith /* use contour shading to indicate magnitude of values */ 1593f1af5d2fSBarry Smith /* first determine max of all nonzero values */ 1594b05fc000SLisandro Dalcin PetscReal minv = 0.0, maxv = 0.0; 1595b05fc000SLisandro Dalcin PetscDraw popup; 1596b05fc000SLisandro Dalcin 1597f1af5d2fSBarry Smith for (i = 0; i < m * n; i++) { 1598f1af5d2fSBarry Smith if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]); 1599f1af5d2fSBarry Smith } 1600383922c3SLisandro Dalcin if (minv >= maxv) maxv = minv + PETSC_SMALL; 16019566063dSJacob Faibussowitsch PetscCall(PetscDrawGetPopup(draw, &popup)); 16029566063dSJacob Faibussowitsch PetscCall(PetscDrawScalePopup(popup, minv, maxv)); 1603383922c3SLisandro Dalcin 1604d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 1605f1af5d2fSBarry Smith for (j = 0; j < n; j++) { 1606f1af5d2fSBarry Smith x_l = j; 1607f1af5d2fSBarry Smith x_r = x_l + 1.0; 1608f1af5d2fSBarry Smith for (i = 0; i < m; i++) { 1609f1af5d2fSBarry Smith y_l = m - i - 1.0; 1610f1af5d2fSBarry Smith y_r = y_l + 1.0; 1611b05fc000SLisandro Dalcin color = PetscDrawRealToColor(PetscAbsScalar(v[j * m + i]), minv, maxv); 16129566063dSJacob Faibussowitsch PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color)); 1613f1af5d2fSBarry Smith } 1614f1af5d2fSBarry Smith } 1615d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 1616f1af5d2fSBarry Smith } 16179566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 16183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1619f1af5d2fSBarry Smith } 1620f1af5d2fSBarry Smith 1621d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw(Mat A, PetscViewer viewer) 1622d71ae5a4SJacob Faibussowitsch { 1623b0a32e0cSBarry Smith PetscDraw draw; 1624ace3abfcSBarry Smith PetscBool isnull; 1625329f5518SBarry Smith PetscReal xr, yr, xl, yl, h, w; 1626f1af5d2fSBarry Smith 1627f1af5d2fSBarry Smith PetscFunctionBegin; 16289566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 16299566063dSJacob Faibussowitsch PetscCall(PetscDrawIsNull(draw, &isnull)); 16303ba16761SJacob Faibussowitsch if (isnull) PetscFunctionReturn(PETSC_SUCCESS); 1631f1af5d2fSBarry Smith 16329371c9d4SSatish Balay xr = A->cmap->n; 16339371c9d4SSatish Balay yr = A->rmap->n; 16349371c9d4SSatish Balay h = yr / 10.0; 16359371c9d4SSatish Balay w = xr / 10.0; 16369371c9d4SSatish Balay xr += w; 16379371c9d4SSatish Balay yr += h; 16389371c9d4SSatish Balay xl = -w; 16399371c9d4SSatish Balay yl = -h; 16409566063dSJacob Faibussowitsch PetscCall(PetscDrawSetCoordinates(draw, xl, yl, xr, yr)); 16419566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", (PetscObject)viewer)); 16429566063dSJacob Faibussowitsch PetscCall(PetscDrawZoom(draw, MatView_SeqDense_Draw_Zoom, A)); 16439566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", NULL)); 16449566063dSJacob Faibussowitsch PetscCall(PetscDrawSave(draw)); 16453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1646f1af5d2fSBarry Smith } 1647f1af5d2fSBarry Smith 1648d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_SeqDense(Mat A, PetscViewer viewer) 1649d71ae5a4SJacob Faibussowitsch { 1650ace3abfcSBarry Smith PetscBool iascii, isbinary, isdraw; 1651932b0c3eSLois Curfman McInnes 16523a40ed3dSBarry Smith PetscFunctionBegin; 16539566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 16549566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 16559566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 16561baa6e33SBarry Smith if (iascii) PetscCall(MatView_SeqDense_ASCII(A, viewer)); 16571baa6e33SBarry Smith else if (isbinary) PetscCall(MatView_Dense_Binary(A, viewer)); 16581baa6e33SBarry Smith else if (isdraw) PetscCall(MatView_SeqDense_Draw(A, viewer)); 16593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1660932b0c3eSLois Curfman McInnes } 1661289bc588SBarry Smith 1662d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A, const PetscScalar *array) 1663d71ae5a4SJacob Faibussowitsch { 1664d3042a70SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1665d3042a70SBarry Smith 1666d3042a70SBarry Smith PetscFunctionBegin; 166728b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 166828b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 166928b400f6SJacob Faibussowitsch PetscCheck(!a->unplacedarray, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreArray() first"); 1670d3042a70SBarry Smith a->unplacedarray = a->v; 1671d3042a70SBarry Smith a->unplaced_user_alloc = a->user_alloc; 1672d3042a70SBarry Smith a->v = (PetscScalar *)array; 1673637a0070SStefano Zampini a->user_alloc = PETSC_TRUE; 167447d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1675c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_CPU; 1676ca15aa20SStefano Zampini #endif 16773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1678d3042a70SBarry Smith } 1679d3042a70SBarry Smith 1680d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseResetArray_SeqDense(Mat A) 1681d71ae5a4SJacob Faibussowitsch { 1682d3042a70SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1683d3042a70SBarry Smith 1684d3042a70SBarry Smith PetscFunctionBegin; 168528b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 168628b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 1687d3042a70SBarry Smith a->v = a->unplacedarray; 1688d3042a70SBarry Smith a->user_alloc = a->unplaced_user_alloc; 1689d3042a70SBarry Smith a->unplacedarray = NULL; 169047d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1691c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_CPU; 1692ca15aa20SStefano Zampini #endif 16933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1694d3042a70SBarry Smith } 1695d3042a70SBarry Smith 1696d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A, const PetscScalar *array) 1697d71ae5a4SJacob Faibussowitsch { 1698d5ea218eSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1699d5ea218eSStefano Zampini 1700d5ea218eSStefano Zampini PetscFunctionBegin; 170128b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 170228b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 17039566063dSJacob Faibussowitsch if (!a->user_alloc) PetscCall(PetscFree(a->v)); 1704d5ea218eSStefano Zampini a->v = (PetscScalar *)array; 1705d5ea218eSStefano Zampini a->user_alloc = PETSC_FALSE; 170647d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1707d5ea218eSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 1708d5ea218eSStefano Zampini #endif 17093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1710d5ea218eSStefano Zampini } 1711d5ea218eSStefano Zampini 1712d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDestroy_SeqDense(Mat mat) 1713d71ae5a4SJacob Faibussowitsch { 1714ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)mat->data; 171590f02eecSBarry Smith 17163a40ed3dSBarry Smith PetscFunctionBegin; 17173ba16761SJacob Faibussowitsch PetscCall(PetscLogObjectState((PetscObject)mat, "Rows %" PetscInt_FMT " Cols %" PetscInt_FMT, mat->rmap->n, mat->cmap->n)); 1718f4f49eeaSPierre Jolivet PetscCall(VecDestroy(&l->qrrhs)); 17199566063dSJacob Faibussowitsch PetscCall(PetscFree(l->tau)); 17209566063dSJacob Faibussowitsch PetscCall(PetscFree(l->pivots)); 17219566063dSJacob Faibussowitsch PetscCall(PetscFree(l->fwork)); 17229566063dSJacob Faibussowitsch if (!l->user_alloc) PetscCall(PetscFree(l->v)); 17239566063dSJacob Faibussowitsch if (!l->unplaced_user_alloc) PetscCall(PetscFree(l->unplacedarray)); 172428b400f6SJacob Faibussowitsch PetscCheck(!l->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 172528b400f6SJacob Faibussowitsch PetscCheck(!l->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 17269566063dSJacob Faibussowitsch PetscCall(VecDestroy(&l->cvec)); 17279566063dSJacob Faibussowitsch PetscCall(MatDestroy(&l->cmat)); 17289566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->data)); 1729dbd8c25aSHong Zhang 17309566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)mat, NULL)); 17319566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactor_C", NULL)); 17322e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorSymbolic_C", NULL)); 17332e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorNumeric_C", NULL)); 17349566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetLDA_C", NULL)); 17359566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseSetLDA_C", NULL)); 17369566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArray_C", NULL)); 17379566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArray_C", NULL)); 17389566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDensePlaceArray_C", NULL)); 17399566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseResetArray_C", NULL)); 17409566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseReplaceArray_C", NULL)); 17419566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayRead_C", NULL)); 17429566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayRead_C", NULL)); 17439566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayWrite_C", NULL)); 17449566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayWrite_C", NULL)); 17459566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqaij_C", NULL)); 17468baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 17479566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_elemental_C", NULL)); 17488baccfbdSHong Zhang #endif 1749d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 17509566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_scalapack_C", NULL)); 1751d24d4204SJose E. Roman #endif 17522bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA) 17539566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensecuda_C", NULL)); 17549566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", NULL)); 17559566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdense_C", NULL)); 17562e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensecuda_C", NULL)); 17572bf066beSStefano Zampini #endif 175847d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 175947d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensehip_C", NULL)); 176047d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensehip_seqdensehip_C", NULL)); 176147d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensehip_seqdense_C", NULL)); 176247d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensehip_C", NULL)); 176347d993e7Ssuyashtn #endif 17649566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatSeqDenseSetPreallocation_C", NULL)); 17659566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqaij_seqdense_C", NULL)); 17669566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdense_C", NULL)); 17679566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqbaij_seqdense_C", NULL)); 17689566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqsbaij_seqdense_C", NULL)); 176952c5f739Sprj- 17709566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumn_C", NULL)); 17719566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumn_C", NULL)); 17729566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVec_C", NULL)); 17739566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVec_C", NULL)); 17749566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecRead_C", NULL)); 17759566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecRead_C", NULL)); 17769566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecWrite_C", NULL)); 17779566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecWrite_C", NULL)); 17789566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetSubMatrix_C", NULL)); 17799566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreSubMatrix_C", NULL)); 17800be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatMultAddColumnRange_C", NULL)); 17810be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatMultHermitianTransposeColumnRange_C", NULL)); 17820be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatMultHermitianTransposeAddColumnRange_C", NULL)); 17833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1784289bc588SBarry Smith } 1785289bc588SBarry Smith 1786d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatTranspose_SeqDense(Mat A, MatReuse reuse, Mat *matout) 1787d71ae5a4SJacob Faibussowitsch { 1788c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 17896536e3caSStefano Zampini PetscInt k, j, m = A->rmap->n, M = mat->lda, n = A->cmap->n; 179087828ca2SBarry Smith PetscScalar *v, tmp; 179148b35521SBarry Smith 17923a40ed3dSBarry Smith PetscFunctionBegin; 17937fb60732SBarry Smith if (reuse == MAT_REUSE_MATRIX) PetscCall(MatTransposeCheckNonzeroState_Private(A, *matout)); 17946536e3caSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 17956536e3caSStefano Zampini if (m == n) { /* in place transpose */ 17969566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 1797d3e5ee88SLois Curfman McInnes for (j = 0; j < m; j++) { 1798289bc588SBarry Smith for (k = 0; k < j; k++) { 17991b807ce4Svictorle tmp = v[j + k * M]; 18001b807ce4Svictorle v[j + k * M] = v[k + j * M]; 18011b807ce4Svictorle v[k + j * M] = tmp; 1802289bc588SBarry Smith } 1803289bc588SBarry Smith } 18049566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 18056536e3caSStefano Zampini } else { /* reuse memory, temporary allocates new memory */ 18066536e3caSStefano Zampini PetscScalar *v2; 18076536e3caSStefano Zampini PetscLayout tmplayout; 18086536e3caSStefano Zampini 18099566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((size_t)m * n, &v2)); 18109566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 18116536e3caSStefano Zampini for (j = 0; j < n; j++) { 18126536e3caSStefano Zampini for (k = 0; k < m; k++) v2[j + (size_t)k * n] = v[k + (size_t)j * M]; 18136536e3caSStefano Zampini } 18149566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(v, v2, (size_t)m * n)); 18159566063dSJacob Faibussowitsch PetscCall(PetscFree(v2)); 18169566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 18176536e3caSStefano Zampini /* cleanup size dependent quantities */ 18189566063dSJacob Faibussowitsch PetscCall(VecDestroy(&mat->cvec)); 18199566063dSJacob Faibussowitsch PetscCall(MatDestroy(&mat->cmat)); 18209566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->pivots)); 18219566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->fwork)); 18226536e3caSStefano Zampini /* swap row/col layouts */ 18236536e3caSStefano Zampini mat->lda = n; 18246536e3caSStefano Zampini tmplayout = A->rmap; 18256536e3caSStefano Zampini A->rmap = A->cmap; 18266536e3caSStefano Zampini A->cmap = tmplayout; 18276536e3caSStefano Zampini } 18283a40ed3dSBarry Smith } else { /* out-of-place transpose */ 1829d3e5ee88SLois Curfman McInnes Mat tmat; 1830ec8511deSBarry Smith Mat_SeqDense *tmatd; 183187828ca2SBarry Smith PetscScalar *v2; 1832af36a384SStefano Zampini PetscInt M2; 1833ea709b57SSatish Balay 18346536e3caSStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 18359566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &tmat)); 18369566063dSJacob Faibussowitsch PetscCall(MatSetSizes(tmat, A->cmap->n, A->rmap->n, A->cmap->n, A->rmap->n)); 18379566063dSJacob Faibussowitsch PetscCall(MatSetType(tmat, ((PetscObject)A)->type_name)); 18389566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(tmat, NULL)); 1839ca15aa20SStefano Zampini } else tmat = *matout; 1840ca15aa20SStefano Zampini 18419566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&v)); 18429566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(tmat, &v2)); 1843ec8511deSBarry Smith tmatd = (Mat_SeqDense *)tmat->data; 1844ca15aa20SStefano Zampini M2 = tmatd->lda; 1845d3e5ee88SLois Curfman McInnes for (j = 0; j < n; j++) { 1846af36a384SStefano Zampini for (k = 0; k < m; k++) v2[j + k * M2] = v[k + j * M]; 1847d3e5ee88SLois Curfman McInnes } 18489566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(tmat, &v2)); 18499566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&v)); 18509566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(tmat, MAT_FINAL_ASSEMBLY)); 18519566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(tmat, MAT_FINAL_ASSEMBLY)); 18526536e3caSStefano Zampini *matout = tmat; 185348b35521SBarry Smith } 18543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1855289bc588SBarry Smith } 1856289bc588SBarry Smith 1857d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatEqual_SeqDense(Mat A1, Mat A2, PetscBool *flg) 1858d71ae5a4SJacob Faibussowitsch { 1859c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat1 = (Mat_SeqDense *)A1->data; 1860c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat2 = (Mat_SeqDense *)A2->data; 1861ca15aa20SStefano Zampini PetscInt i; 1862ca15aa20SStefano Zampini const PetscScalar *v1, *v2; 18639ea5d5aeSSatish Balay 18643a40ed3dSBarry Smith PetscFunctionBegin; 18659371c9d4SSatish Balay if (A1->rmap->n != A2->rmap->n) { 18669371c9d4SSatish Balay *flg = PETSC_FALSE; 18673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18689371c9d4SSatish Balay } 18699371c9d4SSatish Balay if (A1->cmap->n != A2->cmap->n) { 18709371c9d4SSatish Balay *flg = PETSC_FALSE; 18713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18729371c9d4SSatish Balay } 18739566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A1, &v1)); 18749566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A2, &v2)); 1875ca15aa20SStefano Zampini for (i = 0; i < A1->cmap->n; i++) { 18769566063dSJacob Faibussowitsch PetscCall(PetscArraycmp(v1, v2, A1->rmap->n, flg)); 18773ba16761SJacob Faibussowitsch if (*flg == PETSC_FALSE) PetscFunctionReturn(PETSC_SUCCESS); 1878ca15aa20SStefano Zampini v1 += mat1->lda; 1879ca15aa20SStefano Zampini v2 += mat2->lda; 18801b807ce4Svictorle } 18819566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A1, &v1)); 18829566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A2, &v2)); 188377c4ece6SBarry Smith *flg = PETSC_TRUE; 18843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1885289bc588SBarry Smith } 1886289bc588SBarry Smith 188714277c92SJacob Faibussowitsch PetscErrorCode MatGetDiagonal_SeqDense(Mat A, Vec v) 1888d71ae5a4SJacob Faibussowitsch { 1889c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 189013f74950SBarry Smith PetscInt i, n, len; 1891ca15aa20SStefano Zampini PetscScalar *x; 1892ca15aa20SStefano Zampini const PetscScalar *vv; 189344cd7ae7SLois Curfman McInnes 18943a40ed3dSBarry Smith PetscFunctionBegin; 18959566063dSJacob Faibussowitsch PetscCall(VecGetSize(v, &n)); 18969566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 1897d0f46423SBarry Smith len = PetscMin(A->rmap->n, A->cmap->n); 18989566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &vv)); 189908401ef6SPierre Jolivet PetscCheck(n == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming mat and vec"); 1900ad540459SPierre Jolivet for (i = 0; i < len; i++) x[i] = vv[i * mat->lda + i]; 19019566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &vv)); 19029566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 19033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1904289bc588SBarry Smith } 1905289bc588SBarry Smith 1906d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDiagonalScale_SeqDense(Mat A, Vec ll, Vec rr) 1907d71ae5a4SJacob Faibussowitsch { 1908c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1909f1ceaac6SMatthew G. Knepley const PetscScalar *l, *r; 1910ca15aa20SStefano Zampini PetscScalar x, *v, *vv; 1911d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n; 191255659b69SBarry Smith 19133a40ed3dSBarry Smith PetscFunctionBegin; 19149566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &vv)); 191528988994SBarry Smith if (ll) { 19169566063dSJacob Faibussowitsch PetscCall(VecGetSize(ll, &m)); 19179566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(ll, &l)); 191808401ef6SPierre Jolivet PetscCheck(m == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Left scaling vec wrong size"); 1919da3a660dSBarry Smith for (i = 0; i < m; i++) { 1920da3a660dSBarry Smith x = l[i]; 1921ca15aa20SStefano Zampini v = vv + i; 19229371c9d4SSatish Balay for (j = 0; j < n; j++) { 19239371c9d4SSatish Balay (*v) *= x; 19249371c9d4SSatish Balay v += mat->lda; 19259371c9d4SSatish Balay } 1926da3a660dSBarry Smith } 19279566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(ll, &l)); 19289566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * n * m)); 1929da3a660dSBarry Smith } 193028988994SBarry Smith if (rr) { 19319566063dSJacob Faibussowitsch PetscCall(VecGetSize(rr, &n)); 19329566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(rr, &r)); 193308401ef6SPierre Jolivet PetscCheck(n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Right scaling vec wrong size"); 1934da3a660dSBarry Smith for (i = 0; i < n; i++) { 1935da3a660dSBarry Smith x = r[i]; 1936ca15aa20SStefano Zampini v = vv + i * mat->lda; 19372205254eSKarl Rupp for (j = 0; j < m; j++) (*v++) *= x; 1938da3a660dSBarry Smith } 19399566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(rr, &r)); 19409566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * n * m)); 1941da3a660dSBarry Smith } 19429566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &vv)); 19433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1944289bc588SBarry Smith } 1945289bc588SBarry Smith 1946d71ae5a4SJacob Faibussowitsch PetscErrorCode MatNorm_SeqDense(Mat A, NormType type, PetscReal *nrm) 1947d71ae5a4SJacob Faibussowitsch { 1948c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1949ca15aa20SStefano Zampini PetscScalar *v, *vv; 1950329f5518SBarry Smith PetscReal sum = 0.0; 195175f6d85dSStefano Zampini PetscInt lda, m = A->rmap->n, i, j; 195255659b69SBarry Smith 19533a40ed3dSBarry Smith PetscFunctionBegin; 19549566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&vv)); 19559566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(A, &lda)); 1956ca15aa20SStefano Zampini v = vv; 1957289bc588SBarry Smith if (type == NORM_FROBENIUS) { 1958a5ce6ee0Svictorle if (lda > m) { 1959d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1960ca15aa20SStefano Zampini v = vv + j * lda; 1961a5ce6ee0Svictorle for (i = 0; i < m; i++) { 19629371c9d4SSatish Balay sum += PetscRealPart(PetscConj(*v) * (*v)); 19639371c9d4SSatish Balay v++; 1964a5ce6ee0Svictorle } 1965a5ce6ee0Svictorle } 1966a5ce6ee0Svictorle } else { 1967570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16) 1968570b7f6dSBarry Smith PetscBLASInt one = 1, cnt = A->cmap->n * A->rmap->n; 1969792fecdfSBarry Smith PetscCallBLAS("BLASnrm2", *nrm = BLASnrm2_(&cnt, v, &one)); 1970570b7f6dSBarry Smith } 1971570b7f6dSBarry Smith #else 1972d0f46423SBarry Smith for (i = 0; i < A->cmap->n * A->rmap->n; i++) { 19739371c9d4SSatish Balay sum += PetscRealPart(PetscConj(*v) * (*v)); 19749371c9d4SSatish Balay v++; 1975289bc588SBarry Smith } 1976a5ce6ee0Svictorle } 19778f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 1978570b7f6dSBarry Smith #endif 19799566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->cmap->n * A->rmap->n)); 19803a40ed3dSBarry Smith } else if (type == NORM_1) { 1981064f8208SBarry Smith *nrm = 0.0; 1982d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1983ca15aa20SStefano Zampini v = vv + j * mat->lda; 1984289bc588SBarry Smith sum = 0.0; 1985d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 19869371c9d4SSatish Balay sum += PetscAbsScalar(*v); 19879371c9d4SSatish Balay v++; 1988289bc588SBarry Smith } 1989064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 1990289bc588SBarry Smith } 19919566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n)); 19923a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 1993064f8208SBarry Smith *nrm = 0.0; 1994d0f46423SBarry Smith for (j = 0; j < A->rmap->n; j++) { 1995ca15aa20SStefano Zampini v = vv + j; 1996289bc588SBarry Smith sum = 0.0; 1997d0f46423SBarry Smith for (i = 0; i < A->cmap->n; i++) { 19989371c9d4SSatish Balay sum += PetscAbsScalar(*v); 19999371c9d4SSatish Balay v += mat->lda; 2000289bc588SBarry Smith } 2001064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 2002289bc588SBarry Smith } 20039566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n)); 2004e7e72b3dSBarry Smith } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "No two norm"); 20059566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&vv)); 20063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2007289bc588SBarry Smith } 2008289bc588SBarry Smith 2009d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetOption_SeqDense(Mat A, MatOption op, PetscBool flg) 2010d71ae5a4SJacob Faibussowitsch { 2011c0bbcb79SLois Curfman McInnes Mat_SeqDense *aij = (Mat_SeqDense *)A->data; 201267e560aaSBarry Smith 20133a40ed3dSBarry Smith PetscFunctionBegin; 2014b5a2b587SKris Buschelman switch (op) { 2015d71ae5a4SJacob Faibussowitsch case MAT_ROW_ORIENTED: 2016d71ae5a4SJacob Faibussowitsch aij->roworiented = flg; 2017d71ae5a4SJacob Faibussowitsch break; 2018512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 2019b5a2b587SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 20203971808eSMatthew Knepley case MAT_NEW_NONZERO_ALLOCATION_ERR: 20218c78258cSHong Zhang case MAT_FORCE_DIAGONAL_ENTRIES: 202213fa8e87SLisandro Dalcin case MAT_KEEP_NONZERO_PATTERN: 2023b5a2b587SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 2024b5a2b587SKris Buschelman case MAT_USE_HASH_TABLE: 20250f8fb01aSBarry Smith case MAT_IGNORE_ZERO_ENTRIES: 20265021d80fSJed Brown case MAT_IGNORE_LOWER_TRIANGULAR: 2027d71ae5a4SJacob Faibussowitsch case MAT_SORTED_FULL: 2028d71ae5a4SJacob Faibussowitsch PetscCall(PetscInfo(A, "Option %s ignored\n", MatOptions[op])); 2029d71ae5a4SJacob Faibussowitsch break; 20305021d80fSJed Brown case MAT_SPD: 203177e54ba9SKris Buschelman case MAT_SYMMETRIC: 203277e54ba9SKris Buschelman case MAT_STRUCTURALLY_SYMMETRIC: 20339a4540c5SBarry Smith case MAT_HERMITIAN: 20349a4540c5SBarry Smith case MAT_SYMMETRY_ETERNAL: 2035b94d7dedSBarry Smith case MAT_STRUCTURAL_SYMMETRY_ETERNAL: 2036d71ae5a4SJacob Faibussowitsch case MAT_SPD_ETERNAL: 2037d71ae5a4SJacob Faibussowitsch break; 2038d71ae5a4SJacob Faibussowitsch default: 2039d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "unknown option %s", MatOptions[op]); 20403a40ed3dSBarry Smith } 20413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2042289bc588SBarry Smith } 2043289bc588SBarry Smith 2044d71ae5a4SJacob Faibussowitsch PetscErrorCode MatZeroEntries_SeqDense(Mat A) 2045d71ae5a4SJacob Faibussowitsch { 2046ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)A->data; 20473d8925e7SStefano Zampini PetscInt lda = l->lda, m = A->rmap->n, n = A->cmap->n, j; 2048ca15aa20SStefano Zampini PetscScalar *v; 20493a40ed3dSBarry Smith 20503a40ed3dSBarry Smith PetscFunctionBegin; 20519566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(A, &v)); 2052a5ce6ee0Svictorle if (lda > m) { 205348a46eb9SPierre Jolivet for (j = 0; j < n; j++) PetscCall(PetscArrayzero(v + j * lda, m)); 2054a5ce6ee0Svictorle } else { 20559566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(v, PetscInt64Mult(m, n))); 2056a5ce6ee0Svictorle } 20579566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(A, &v)); 20583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 20596f0a148fSBarry Smith } 20606f0a148fSBarry Smith 2061d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatZeroRows_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) 2062d71ae5a4SJacob Faibussowitsch { 2063ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)A->data; 2064b9679d65SBarry Smith PetscInt m = l->lda, n = A->cmap->n, i, j; 2065ca15aa20SStefano Zampini PetscScalar *slot, *bb, *v; 206697b48c8fSBarry Smith const PetscScalar *xx; 206755659b69SBarry Smith 20683a40ed3dSBarry Smith PetscFunctionBegin; 206976bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 2070b9679d65SBarry Smith for (i = 0; i < N; i++) { 207108401ef6SPierre Jolivet PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed"); 207208401ef6SPierre 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); 2073b9679d65SBarry Smith } 207476bd3646SJed Brown } 20753ba16761SJacob Faibussowitsch if (!N) PetscFunctionReturn(PETSC_SUCCESS); 2076b9679d65SBarry Smith 2077dd8e379bSPierre Jolivet /* fix right-hand side if needed */ 207897b48c8fSBarry Smith if (x && b) { 20799566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 20809566063dSJacob Faibussowitsch PetscCall(VecGetArray(b, &bb)); 20812205254eSKarl Rupp for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]]; 20829566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 20839566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(b, &bb)); 208497b48c8fSBarry Smith } 208597b48c8fSBarry Smith 20869566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 20876f0a148fSBarry Smith for (i = 0; i < N; i++) { 2088ca15aa20SStefano Zampini slot = v + rows[i]; 20899371c9d4SSatish Balay for (j = 0; j < n; j++) { 20909371c9d4SSatish Balay *slot = 0.0; 20919371c9d4SSatish Balay slot += m; 20929371c9d4SSatish Balay } 20936f0a148fSBarry Smith } 2094f4df32b1SMatthew Knepley if (diag != 0.0) { 209508401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices"); 20966f0a148fSBarry Smith for (i = 0; i < N; i++) { 2097ca15aa20SStefano Zampini slot = v + (m + 1) * rows[i]; 2098f4df32b1SMatthew Knepley *slot = diag; 20996f0a148fSBarry Smith } 21006f0a148fSBarry Smith } 21019566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 21023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 21036f0a148fSBarry Smith } 2104557bce09SLois Curfman McInnes 2105d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A, PetscInt *lda) 2106d71ae5a4SJacob Faibussowitsch { 210749a6ff4bSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 210849a6ff4bSBarry Smith 210949a6ff4bSBarry Smith PetscFunctionBegin; 211049a6ff4bSBarry Smith *lda = mat->lda; 21113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 211249a6ff4bSBarry Smith } 211349a6ff4bSBarry Smith 2114d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArray_SeqDense(Mat A, PetscScalar **array) 2115d71ae5a4SJacob Faibussowitsch { 2116c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 21173a40ed3dSBarry Smith 21183a40ed3dSBarry Smith PetscFunctionBegin; 211928b400f6SJacob Faibussowitsch PetscCheck(!mat->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 212064e87e97SBarry Smith *array = mat->v; 21213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 212264e87e97SBarry Smith } 21230754003eSLois Curfman McInnes 2124d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A, PetscScalar **array) 2125d71ae5a4SJacob Faibussowitsch { 21263a40ed3dSBarry Smith PetscFunctionBegin; 212775f6d85dSStefano Zampini if (array) *array = NULL; 21283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2129ff14e315SSatish Balay } 21300754003eSLois Curfman McInnes 21310f74d2c1SSatish Balay /*@ 213211a5261eSBarry Smith MatDenseGetLDA - gets the leading dimension of the array returned from `MatDenseGetArray()` 213349a6ff4bSBarry Smith 21342ef1f0ffSBarry Smith Not Collective 213549a6ff4bSBarry Smith 213649a6ff4bSBarry Smith Input Parameter: 2137fe59aa6dSJacob Faibussowitsch . A - a `MATDENSE` or `MATDENSECUDA` matrix 213849a6ff4bSBarry Smith 213949a6ff4bSBarry Smith Output Parameter: 214049a6ff4bSBarry Smith . lda - the leading dimension 214149a6ff4bSBarry Smith 214249a6ff4bSBarry Smith Level: intermediate 214349a6ff4bSBarry Smith 21441cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseSetLDA()` 214549a6ff4bSBarry Smith @*/ 2146d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetLDA(Mat A, PetscInt *lda) 2147d71ae5a4SJacob Faibussowitsch { 214849a6ff4bSBarry Smith PetscFunctionBegin; 2149d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 21504f572ea9SToby Isaac PetscAssertPointer(lda, 2); 215175f6d85dSStefano Zampini MatCheckPreallocated(A, 1); 2152cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetLDA_C", (Mat, PetscInt *), (A, lda)); 21533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 215449a6ff4bSBarry Smith } 215549a6ff4bSBarry Smith 21560f74d2c1SSatish Balay /*@ 215711a5261eSBarry Smith MatDenseSetLDA - Sets the leading dimension of the array used by the `MATDENSE` matrix 2158ad16ce7aSStefano Zampini 21592323109cSBarry Smith Collective if the matrix layouts have not yet been setup 2160ad16ce7aSStefano Zampini 2161d8d19677SJose E. Roman Input Parameters: 2162fe59aa6dSJacob Faibussowitsch + A - a `MATDENSE` or `MATDENSECUDA` matrix 2163ad16ce7aSStefano Zampini - lda - the leading dimension 2164ad16ce7aSStefano Zampini 2165ad16ce7aSStefano Zampini Level: intermediate 2166ad16ce7aSStefano Zampini 21671cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetLDA()` 2168ad16ce7aSStefano Zampini @*/ 2169d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA(Mat A, PetscInt lda) 2170d71ae5a4SJacob Faibussowitsch { 2171ad16ce7aSStefano Zampini PetscFunctionBegin; 2172ad16ce7aSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2173cac4c232SBarry Smith PetscTryMethod(A, "MatDenseSetLDA_C", (Mat, PetscInt), (A, lda)); 21743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2175ad16ce7aSStefano Zampini } 2176ad16ce7aSStefano Zampini 2177ad16ce7aSStefano Zampini /*@C 217811a5261eSBarry Smith MatDenseGetArray - gives read-write access to the array where the data for a `MATDENSE` matrix is stored 217973a71a0fSBarry Smith 2180c3339decSBarry Smith Logically Collective 218173a71a0fSBarry Smith 218273a71a0fSBarry Smith Input Parameter: 2183fe59aa6dSJacob Faibussowitsch . A - a dense matrix 218473a71a0fSBarry Smith 218573a71a0fSBarry Smith Output Parameter: 218673a71a0fSBarry Smith . array - pointer to the data 218773a71a0fSBarry Smith 218873a71a0fSBarry Smith Level: intermediate 218973a71a0fSBarry Smith 2190fe59aa6dSJacob Faibussowitsch Fortran Notes: 21910ab4885dSBarry Smith `MatDenseGetArray()` Fortran binding is deprecated (since PETSc 3.19), use `MatDenseGetArrayF90()` 21920ab4885dSBarry Smith 21931cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 219473a71a0fSBarry Smith @*/ 2195d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArray(Mat A, PetscScalar **array) 2196d71ae5a4SJacob Faibussowitsch { 219773a71a0fSBarry Smith PetscFunctionBegin; 2198d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 21994f572ea9SToby Isaac PetscAssertPointer(array, 2); 2200cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array)); 22013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 220273a71a0fSBarry Smith } 220373a71a0fSBarry Smith 2204dec5eb66SMatthew G Knepley /*@C 220511a5261eSBarry Smith MatDenseRestoreArray - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArray()` 220673a71a0fSBarry Smith 2207c3339decSBarry Smith Logically Collective 22088572280aSBarry Smith 22098572280aSBarry Smith Input Parameters: 2210fe59aa6dSJacob Faibussowitsch + A - a dense matrix 22112ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`) 22128572280aSBarry Smith 22138572280aSBarry Smith Level: intermediate 22148572280aSBarry Smith 2215fe59aa6dSJacob Faibussowitsch Fortran Notes: 22160ab4885dSBarry Smith `MatDenseRestoreArray()` Fortran binding is deprecated (since PETSc 3.19), use `MatDenseRestoreArrayF90()` 22170ab4885dSBarry Smith 22181cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 22198572280aSBarry Smith @*/ 2220d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArray(Mat A, PetscScalar **array) 2221d71ae5a4SJacob Faibussowitsch { 22228572280aSBarry Smith PetscFunctionBegin; 2223d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22244f572ea9SToby Isaac if (array) PetscAssertPointer(array, 2); 2225cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array)); 22269566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)A)); 222747d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 2228637a0070SStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 2229637a0070SStefano Zampini #endif 22303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22318572280aSBarry Smith } 22328572280aSBarry Smith 22338572280aSBarry Smith /*@C 223411a5261eSBarry Smith MatDenseGetArrayRead - gives read-only access to the array where the data for a `MATDENSE` matrix is stored 22358572280aSBarry Smith 2236fb850c59SBarry Smith Not Collective 22378572280aSBarry Smith 22388572280aSBarry Smith Input Parameter: 2239fe59aa6dSJacob Faibussowitsch . A - a dense matrix 22408572280aSBarry Smith 22418572280aSBarry Smith Output Parameter: 22428572280aSBarry Smith . array - pointer to the data 22438572280aSBarry Smith 22448572280aSBarry Smith Level: intermediate 22458572280aSBarry Smith 22461cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 22478572280aSBarry Smith @*/ 2248d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArrayRead(Mat A, const PetscScalar **array) 2249d71ae5a4SJacob Faibussowitsch { 22508572280aSBarry Smith PetscFunctionBegin; 2251d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22524f572ea9SToby Isaac PetscAssertPointer(array, 2); 22535c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 22543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22558572280aSBarry Smith } 22568572280aSBarry Smith 22578572280aSBarry Smith /*@C 225811a5261eSBarry Smith MatDenseRestoreArrayRead - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayRead()` 22598572280aSBarry Smith 2260fb850c59SBarry Smith Not Collective 226173a71a0fSBarry Smith 226273a71a0fSBarry Smith Input Parameters: 2263fe59aa6dSJacob Faibussowitsch + A - a dense matrix 22642ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`) 226573a71a0fSBarry Smith 226673a71a0fSBarry Smith Level: intermediate 226773a71a0fSBarry Smith 22681cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 226973a71a0fSBarry Smith @*/ 2270d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArrayRead(Mat A, const PetscScalar **array) 2271d71ae5a4SJacob Faibussowitsch { 227273a71a0fSBarry Smith PetscFunctionBegin; 2273d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22744f572ea9SToby Isaac if (array) PetscAssertPointer(array, 2); 22755c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 22763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 227773a71a0fSBarry Smith } 227873a71a0fSBarry Smith 22796947451fSStefano Zampini /*@C 228011a5261eSBarry Smith MatDenseGetArrayWrite - gives write-only access to the array where the data for a `MATDENSE` matrix is stored 22816947451fSStefano Zampini 2282fb850c59SBarry Smith Not Collective 22836947451fSStefano Zampini 22846947451fSStefano Zampini Input Parameter: 2285fe59aa6dSJacob Faibussowitsch . A - a dense matrix 22866947451fSStefano Zampini 22876947451fSStefano Zampini Output Parameter: 22886947451fSStefano Zampini . array - pointer to the data 22896947451fSStefano Zampini 22906947451fSStefano Zampini Level: intermediate 22916947451fSStefano Zampini 22921cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()` 22936947451fSStefano Zampini @*/ 2294d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArrayWrite(Mat A, PetscScalar **array) 2295d71ae5a4SJacob Faibussowitsch { 22966947451fSStefano Zampini PetscFunctionBegin; 2297d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22984f572ea9SToby Isaac PetscAssertPointer(array, 2); 2299cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array)); 23003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23016947451fSStefano Zampini } 23026947451fSStefano Zampini 23036947451fSStefano Zampini /*@C 230411a5261eSBarry Smith MatDenseRestoreArrayWrite - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayWrite()` 23056947451fSStefano Zampini 2306fb850c59SBarry Smith Not Collective 23076947451fSStefano Zampini 23086947451fSStefano Zampini Input Parameters: 2309fe59aa6dSJacob Faibussowitsch + A - a dense matrix 23102ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`) 23116947451fSStefano Zampini 23126947451fSStefano Zampini Level: intermediate 23136947451fSStefano Zampini 23141cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()` 23156947451fSStefano Zampini @*/ 2316d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArrayWrite(Mat A, PetscScalar **array) 2317d71ae5a4SJacob Faibussowitsch { 23186947451fSStefano Zampini PetscFunctionBegin; 2319d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 23204f572ea9SToby Isaac if (array) PetscAssertPointer(array, 2); 2321cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array)); 23229566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)A)); 232347d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 23246947451fSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 23256947451fSStefano Zampini #endif 23263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23276947451fSStefano Zampini } 23286947451fSStefano Zampini 2329cd3f9d89SJunchao Zhang /*@C 2330cd3f9d89SJunchao Zhang MatDenseGetArrayAndMemType - gives read-write access to the array where the data for a `MATDENSE` matrix is stored 2331cd3f9d89SJunchao Zhang 2332cd3f9d89SJunchao Zhang Logically Collective 2333cd3f9d89SJunchao Zhang 2334cd3f9d89SJunchao Zhang Input Parameter: 2335fe59aa6dSJacob Faibussowitsch . A - a dense matrix 2336cd3f9d89SJunchao Zhang 2337cd3f9d89SJunchao Zhang Output Parameters: 2338cd3f9d89SJunchao Zhang + array - pointer to the data 2339cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer 2340cd3f9d89SJunchao Zhang 2341cd3f9d89SJunchao Zhang Level: intermediate 2342cd3f9d89SJunchao Zhang 2343fb850c59SBarry Smith Note: 23442ef1f0ffSBarry Smith If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc., 23452ef1f0ffSBarry Smith an array on device is always returned and is guaranteed to contain the matrix's latest data. 23462ef1f0ffSBarry Smith 23471cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayAndMemType()`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArrayWriteAndMemType()`, `MatDenseGetArrayRead()`, 2348cd3f9d89SJunchao Zhang `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()` 2349cd3f9d89SJunchao Zhang @*/ 2350cd3f9d89SJunchao Zhang PetscErrorCode MatDenseGetArrayAndMemType(Mat A, PetscScalar **array, PetscMemType *mtype) 2351cd3f9d89SJunchao Zhang { 2352cd3f9d89SJunchao Zhang PetscBool isMPI; 2353cd3f9d89SJunchao Zhang 2354cd3f9d89SJunchao Zhang PetscFunctionBegin; 2355cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 23564f572ea9SToby Isaac PetscAssertPointer(array, 2); 2357e865de01SJunchao 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 */ 2358cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2359cd3f9d89SJunchao Zhang if (isMPI) { 2360cd3f9d89SJunchao Zhang /* Dispatch here so that the code can be reused for all subclasses of MATDENSE */ 2361cd3f9d89SJunchao Zhang PetscCall(MatDenseGetArrayAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype)); 2362cd3f9d89SJunchao Zhang } else { 2363cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **, PetscMemType *); 23643ba16761SJacob Faibussowitsch 23653ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayAndMemType_C", &fptr)); 2366cd3f9d89SJunchao Zhang if (fptr) { 2367cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array, mtype)); 2368cd3f9d89SJunchao Zhang } else { 2369cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array)); 2370cd3f9d89SJunchao Zhang if (mtype) *mtype = PETSC_MEMTYPE_HOST; 2371cd3f9d89SJunchao Zhang } 2372cd3f9d89SJunchao Zhang } 23733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2374cd3f9d89SJunchao Zhang } 2375cd3f9d89SJunchao Zhang 2376cd3f9d89SJunchao Zhang /*@C 2377cd3f9d89SJunchao Zhang MatDenseRestoreArrayAndMemType - returns access to the array that is obtained by `MatDenseGetArrayAndMemType()` 2378cd3f9d89SJunchao Zhang 2379cd3f9d89SJunchao Zhang Logically Collective 2380cd3f9d89SJunchao Zhang 2381cd3f9d89SJunchao Zhang Input Parameters: 2382fe59aa6dSJacob Faibussowitsch + A - a dense matrix 2383cd3f9d89SJunchao Zhang - array - pointer to the data 2384cd3f9d89SJunchao Zhang 2385cd3f9d89SJunchao Zhang Level: intermediate 2386cd3f9d89SJunchao Zhang 23871cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 2388cd3f9d89SJunchao Zhang @*/ 2389cd3f9d89SJunchao Zhang PetscErrorCode MatDenseRestoreArrayAndMemType(Mat A, PetscScalar **array) 2390cd3f9d89SJunchao Zhang { 2391cd3f9d89SJunchao Zhang PetscBool isMPI; 2392cd3f9d89SJunchao Zhang 2393cd3f9d89SJunchao Zhang PetscFunctionBegin; 2394cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 23954f572ea9SToby Isaac PetscAssertPointer(array, 2); 2396cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2397cd3f9d89SJunchao Zhang if (isMPI) { 2398cd3f9d89SJunchao Zhang PetscCall(MatDenseRestoreArrayAndMemType(((Mat_MPIDense *)A->data)->A, array)); 2399cd3f9d89SJunchao Zhang } else { 2400cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **); 24013ba16761SJacob Faibussowitsch 24023ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayAndMemType_C", &fptr)); 2403cd3f9d89SJunchao Zhang if (fptr) { 2404cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array)); 2405cd3f9d89SJunchao Zhang } else { 2406cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array)); 2407cd3f9d89SJunchao Zhang } 2408cd3f9d89SJunchao Zhang *array = NULL; 2409cd3f9d89SJunchao Zhang } 2410cd3f9d89SJunchao Zhang PetscCall(PetscObjectStateIncrease((PetscObject)A)); 24113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2412cd3f9d89SJunchao Zhang } 2413cd3f9d89SJunchao Zhang 2414cd3f9d89SJunchao Zhang /*@C 2415cd3f9d89SJunchao Zhang MatDenseGetArrayReadAndMemType - gives read-only access to the array where the data for a `MATDENSE` matrix is stored 2416cd3f9d89SJunchao Zhang 2417cd3f9d89SJunchao Zhang Logically Collective 2418cd3f9d89SJunchao Zhang 2419cd3f9d89SJunchao Zhang Input Parameter: 2420fe59aa6dSJacob Faibussowitsch . A - a dense matrix 2421cd3f9d89SJunchao Zhang 2422cd3f9d89SJunchao Zhang Output Parameters: 2423cd3f9d89SJunchao Zhang + array - pointer to the data 2424cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer 2425cd3f9d89SJunchao Zhang 2426cd3f9d89SJunchao Zhang Level: intermediate 2427cd3f9d89SJunchao Zhang 2428fb850c59SBarry Smith Note: 24292ef1f0ffSBarry Smith If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc., 24302ef1f0ffSBarry Smith an array on device is always returned and is guaranteed to contain the matrix's latest data. 24312ef1f0ffSBarry Smith 24321cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayReadAndMemType()`, `MatDenseGetArrayWriteAndMemType()`, 2433cd3f9d89SJunchao Zhang `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()` 2434cd3f9d89SJunchao Zhang @*/ 2435cd3f9d89SJunchao Zhang PetscErrorCode MatDenseGetArrayReadAndMemType(Mat A, const PetscScalar **array, PetscMemType *mtype) 2436cd3f9d89SJunchao Zhang { 2437cd3f9d89SJunchao Zhang PetscBool isMPI; 2438cd3f9d89SJunchao Zhang 2439cd3f9d89SJunchao Zhang PetscFunctionBegin; 2440cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 24414f572ea9SToby Isaac PetscAssertPointer(array, 2); 2442e865de01SJunchao 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 */ 2443cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2444cd3f9d89SJunchao Zhang if (isMPI) { /* Dispatch here so that the code can be reused for all subclasses of MATDENSE */ 2445cd3f9d89SJunchao Zhang PetscCall(MatDenseGetArrayReadAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype)); 2446cd3f9d89SJunchao Zhang } else { 2447cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, const PetscScalar **, PetscMemType *); 24483ba16761SJacob Faibussowitsch 24493ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayReadAndMemType_C", &fptr)); 2450cd3f9d89SJunchao Zhang if (fptr) { 2451cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array, mtype)); 2452cd3f9d89SJunchao Zhang } else { 24535c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 2454cd3f9d89SJunchao Zhang if (mtype) *mtype = PETSC_MEMTYPE_HOST; 2455cd3f9d89SJunchao Zhang } 2456cd3f9d89SJunchao Zhang } 24573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2458cd3f9d89SJunchao Zhang } 2459cd3f9d89SJunchao Zhang 2460cd3f9d89SJunchao Zhang /*@C 2461cd3f9d89SJunchao Zhang MatDenseRestoreArrayReadAndMemType - returns access to the array that is obtained by `MatDenseGetArrayReadAndMemType()` 2462cd3f9d89SJunchao Zhang 2463cd3f9d89SJunchao Zhang Logically Collective 2464cd3f9d89SJunchao Zhang 2465cd3f9d89SJunchao Zhang Input Parameters: 2466fe59aa6dSJacob Faibussowitsch + A - a dense matrix 2467cd3f9d89SJunchao Zhang - array - pointer to the data 2468cd3f9d89SJunchao Zhang 2469cd3f9d89SJunchao Zhang Level: intermediate 2470cd3f9d89SJunchao Zhang 24711cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 2472cd3f9d89SJunchao Zhang @*/ 2473cd3f9d89SJunchao Zhang PetscErrorCode MatDenseRestoreArrayReadAndMemType(Mat A, const PetscScalar **array) 2474cd3f9d89SJunchao Zhang { 2475cd3f9d89SJunchao Zhang PetscBool isMPI; 2476cd3f9d89SJunchao Zhang 2477cd3f9d89SJunchao Zhang PetscFunctionBegin; 2478cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 24794f572ea9SToby Isaac PetscAssertPointer(array, 2); 2480cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2481cd3f9d89SJunchao Zhang if (isMPI) { 2482cd3f9d89SJunchao Zhang PetscCall(MatDenseRestoreArrayReadAndMemType(((Mat_MPIDense *)A->data)->A, array)); 2483cd3f9d89SJunchao Zhang } else { 2484cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, const PetscScalar **); 24853ba16761SJacob Faibussowitsch 24863ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayReadAndMemType_C", &fptr)); 2487cd3f9d89SJunchao Zhang if (fptr) { 2488cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array)); 2489cd3f9d89SJunchao Zhang } else { 24905c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 2491cd3f9d89SJunchao Zhang } 2492cd3f9d89SJunchao Zhang *array = NULL; 2493cd3f9d89SJunchao Zhang } 24943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2495cd3f9d89SJunchao Zhang } 2496cd3f9d89SJunchao Zhang 2497cd3f9d89SJunchao Zhang /*@C 2498cd3f9d89SJunchao Zhang MatDenseGetArrayWriteAndMemType - gives write-only access to the array where the data for a `MATDENSE` matrix is stored 2499cd3f9d89SJunchao Zhang 2500cd3f9d89SJunchao Zhang Logically Collective 2501cd3f9d89SJunchao Zhang 2502cd3f9d89SJunchao Zhang Input Parameter: 2503fe59aa6dSJacob Faibussowitsch . A - a dense matrix 2504cd3f9d89SJunchao Zhang 2505cd3f9d89SJunchao Zhang Output Parameters: 2506cd3f9d89SJunchao Zhang + array - pointer to the data 2507cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer 2508cd3f9d89SJunchao Zhang 2509cd3f9d89SJunchao Zhang Level: intermediate 2510cd3f9d89SJunchao Zhang 2511fb850c59SBarry Smith Note: 25122ef1f0ffSBarry Smith If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc., 25132ef1f0ffSBarry Smith an array on device is always returned and is guaranteed to contain the matrix's latest data. 25142ef1f0ffSBarry Smith 25151cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayWriteAndMemType()`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArrayRead()`, 2516cd3f9d89SJunchao Zhang `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()` 2517cd3f9d89SJunchao Zhang @*/ 2518cd3f9d89SJunchao Zhang PetscErrorCode MatDenseGetArrayWriteAndMemType(Mat A, PetscScalar **array, PetscMemType *mtype) 2519cd3f9d89SJunchao Zhang { 2520cd3f9d89SJunchao Zhang PetscBool isMPI; 2521cd3f9d89SJunchao Zhang 2522cd3f9d89SJunchao Zhang PetscFunctionBegin; 2523cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 25244f572ea9SToby Isaac PetscAssertPointer(array, 2); 2525e865de01SJunchao 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 */ 2526cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2527cd3f9d89SJunchao Zhang if (isMPI) { 2528cd3f9d89SJunchao Zhang PetscCall(MatDenseGetArrayWriteAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype)); 2529cd3f9d89SJunchao Zhang } else { 2530cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **, PetscMemType *); 25313ba16761SJacob Faibussowitsch 25323ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayWriteAndMemType_C", &fptr)); 2533cd3f9d89SJunchao Zhang if (fptr) { 2534cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array, mtype)); 2535cd3f9d89SJunchao Zhang } else { 2536cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array)); 2537cd3f9d89SJunchao Zhang if (mtype) *mtype = PETSC_MEMTYPE_HOST; 2538cd3f9d89SJunchao Zhang } 2539cd3f9d89SJunchao Zhang } 25403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2541cd3f9d89SJunchao Zhang } 2542cd3f9d89SJunchao Zhang 2543cd3f9d89SJunchao Zhang /*@C 2544cd3f9d89SJunchao Zhang MatDenseRestoreArrayWriteAndMemType - returns access to the array that is obtained by `MatDenseGetArrayReadAndMemType()` 2545cd3f9d89SJunchao Zhang 2546cd3f9d89SJunchao Zhang Logically Collective 2547cd3f9d89SJunchao Zhang 2548cd3f9d89SJunchao Zhang Input Parameters: 2549fe59aa6dSJacob Faibussowitsch + A - a dense matrix 2550cd3f9d89SJunchao Zhang - array - pointer to the data 2551cd3f9d89SJunchao Zhang 2552cd3f9d89SJunchao Zhang Level: intermediate 2553cd3f9d89SJunchao Zhang 25541cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayWriteAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 2555cd3f9d89SJunchao Zhang @*/ 2556cd3f9d89SJunchao Zhang PetscErrorCode MatDenseRestoreArrayWriteAndMemType(Mat A, PetscScalar **array) 2557cd3f9d89SJunchao Zhang { 2558cd3f9d89SJunchao Zhang PetscBool isMPI; 2559cd3f9d89SJunchao Zhang 2560cd3f9d89SJunchao Zhang PetscFunctionBegin; 2561cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 25624f572ea9SToby Isaac PetscAssertPointer(array, 2); 2563cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2564cd3f9d89SJunchao Zhang if (isMPI) { 2565cd3f9d89SJunchao Zhang PetscCall(MatDenseRestoreArrayWriteAndMemType(((Mat_MPIDense *)A->data)->A, array)); 2566cd3f9d89SJunchao Zhang } else { 2567cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **); 25683ba16761SJacob Faibussowitsch 25693ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayWriteAndMemType_C", &fptr)); 2570cd3f9d89SJunchao Zhang if (fptr) { 2571cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array)); 2572cd3f9d89SJunchao Zhang } else { 2573cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array)); 2574cd3f9d89SJunchao Zhang } 2575cd3f9d89SJunchao Zhang *array = NULL; 2576cd3f9d89SJunchao Zhang } 2577cd3f9d89SJunchao Zhang PetscCall(PetscObjectStateIncrease((PetscObject)A)); 25783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2579cd3f9d89SJunchao Zhang } 2580cd3f9d89SJunchao Zhang 2581d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A, IS isrow, IS iscol, MatReuse scall, Mat *B) 2582d71ae5a4SJacob Faibussowitsch { 2583c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 2584bf5a80bcSToby Isaac PetscInt i, j, nrows, ncols, ldb; 25855d0c19d7SBarry Smith const PetscInt *irow, *icol; 258687828ca2SBarry Smith PetscScalar *av, *bv, *v = mat->v; 25870754003eSLois Curfman McInnes Mat newmat; 25880754003eSLois Curfman McInnes 25893a40ed3dSBarry Smith PetscFunctionBegin; 25909566063dSJacob Faibussowitsch PetscCall(ISGetIndices(isrow, &irow)); 25919566063dSJacob Faibussowitsch PetscCall(ISGetIndices(iscol, &icol)); 25929566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(isrow, &nrows)); 25939566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(iscol, &ncols)); 25940754003eSLois Curfman McInnes 2595182d2002SSatish Balay /* Check submatrixcall */ 2596182d2002SSatish Balay if (scall == MAT_REUSE_MATRIX) { 259713f74950SBarry Smith PetscInt n_cols, n_rows; 25989566063dSJacob Faibussowitsch PetscCall(MatGetSize(*B, &n_rows, &n_cols)); 259921a2c019SBarry Smith if (n_rows != nrows || n_cols != ncols) { 2600f746d493SDmitry Karpeev /* resize the result matrix to match number of requested rows/columns */ 26019566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*B, nrows, ncols, nrows, ncols)); 260221a2c019SBarry Smith } 2603182d2002SSatish Balay newmat = *B; 2604182d2002SSatish Balay } else { 26050754003eSLois Curfman McInnes /* Create and fill new matrix */ 26069566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &newmat)); 26079566063dSJacob Faibussowitsch PetscCall(MatSetSizes(newmat, nrows, ncols, nrows, ncols)); 26089566063dSJacob Faibussowitsch PetscCall(MatSetType(newmat, ((PetscObject)A)->type_name)); 26099566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(newmat, NULL)); 2610182d2002SSatish Balay } 2611182d2002SSatish Balay 2612182d2002SSatish Balay /* Now extract the data pointers and do the copy,column at a time */ 26139566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(newmat, &bv)); 26149566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(newmat, &ldb)); 2615182d2002SSatish Balay for (i = 0; i < ncols; i++) { 26166de62eeeSBarry Smith av = v + mat->lda * icol[i]; 2617ca15aa20SStefano Zampini for (j = 0; j < nrows; j++) bv[j] = av[irow[j]]; 2618bf5a80bcSToby Isaac bv += ldb; 26190754003eSLois Curfman McInnes } 26209566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(newmat, &bv)); 2621182d2002SSatish Balay 2622182d2002SSatish Balay /* Assemble the matrices so that the correct flags are set */ 26239566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(newmat, MAT_FINAL_ASSEMBLY)); 26249566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(newmat, MAT_FINAL_ASSEMBLY)); 26250754003eSLois Curfman McInnes 26260754003eSLois Curfman McInnes /* Free work space */ 26279566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(isrow, &irow)); 26289566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(iscol, &icol)); 2629182d2002SSatish Balay *B = newmat; 26303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26310754003eSLois Curfman McInnes } 26320754003eSLois Curfman McInnes 2633d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A, PetscInt n, const IS irow[], const IS icol[], MatReuse scall, Mat *B[]) 2634d71ae5a4SJacob Faibussowitsch { 263513f74950SBarry Smith PetscInt i; 2636905e6a2fSBarry Smith 26373a40ed3dSBarry Smith PetscFunctionBegin; 263848a46eb9SPierre Jolivet if (scall == MAT_INITIAL_MATRIX) PetscCall(PetscCalloc1(n, B)); 2639905e6a2fSBarry Smith 264048a46eb9SPierre Jolivet for (i = 0; i < n; i++) PetscCall(MatCreateSubMatrix_SeqDense(A, irow[i], icol[i], scall, &(*B)[i])); 26413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2642905e6a2fSBarry Smith } 2643905e6a2fSBarry Smith 2644d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat, MatAssemblyType mode) 2645d71ae5a4SJacob Faibussowitsch { 2646c0aa2d19SHong Zhang PetscFunctionBegin; 26473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2648c0aa2d19SHong Zhang } 2649c0aa2d19SHong Zhang 2650d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat, MatAssemblyType mode) 2651d71ae5a4SJacob Faibussowitsch { 2652c0aa2d19SHong Zhang PetscFunctionBegin; 26533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2654c0aa2d19SHong Zhang } 2655c0aa2d19SHong Zhang 2656d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCopy_SeqDense(Mat A, Mat B, MatStructure str) 2657d71ae5a4SJacob Faibussowitsch { 26584b0e389bSBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data; 2659ca15aa20SStefano Zampini const PetscScalar *va; 2660ca15aa20SStefano Zampini PetscScalar *vb; 2661d0f46423SBarry Smith PetscInt lda1 = a->lda, lda2 = b->lda, m = A->rmap->n, n = A->cmap->n, j; 26623a40ed3dSBarry Smith 26633a40ed3dSBarry Smith PetscFunctionBegin; 266433f4a19fSKris Buschelman /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */ 266533f4a19fSKris Buschelman if (A->ops->copy != B->ops->copy) { 26669566063dSJacob Faibussowitsch PetscCall(MatCopy_Basic(A, B, str)); 26673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26683a40ed3dSBarry Smith } 2669aed4548fSBarry Smith PetscCheck(m == B->rmap->n && n == B->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "size(B) != size(A)"); 26709566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &va)); 26719566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(B, &vb)); 2672a5ce6ee0Svictorle if (lda1 > m || lda2 > m) { 267348a46eb9SPierre Jolivet for (j = 0; j < n; j++) PetscCall(PetscArraycpy(vb + j * lda2, va + j * lda1, m)); 2674a5ce6ee0Svictorle } else { 26759566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(vb, va, A->rmap->n * A->cmap->n)); 2676a5ce6ee0Svictorle } 26779566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(B, &vb)); 26789566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &va)); 26799566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 26809566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 26813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2682273d9f13SBarry Smith } 2683273d9f13SBarry Smith 2684d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetUp_SeqDense(Mat A) 2685d71ae5a4SJacob Faibussowitsch { 2686273d9f13SBarry Smith PetscFunctionBegin; 26879566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 26889566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 268948a46eb9SPierre Jolivet if (!A->preallocated) PetscCall(MatSeqDenseSetPreallocation(A, NULL)); 26903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26914b0e389bSBarry Smith } 26924b0e389bSBarry Smith 2693d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatConjugate_SeqDense(Mat A) 2694d71ae5a4SJacob Faibussowitsch { 26954396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 269606c5243aSJose E. Roman PetscInt i, j; 26974396437dSToby Isaac PetscInt min = PetscMin(A->rmap->n, A->cmap->n); 2698ca15aa20SStefano Zampini PetscScalar *aa; 2699ba337c44SJed Brown 2700ba337c44SJed Brown PetscFunctionBegin; 27019566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 270206c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 270306c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscConj(aa[i + j * mat->lda]); 270406c5243aSJose E. Roman } 27059566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 27069371c9d4SSatish Balay if (mat->tau) 27079371c9d4SSatish Balay for (i = 0; i < min; i++) mat->tau[i] = PetscConj(mat->tau[i]); 27083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2709ba337c44SJed Brown } 2710ba337c44SJed Brown 2711d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRealPart_SeqDense(Mat A) 2712d71ae5a4SJacob Faibussowitsch { 271306c5243aSJose E. Roman Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 271406c5243aSJose E. Roman PetscInt i, j; 2715ca15aa20SStefano Zampini PetscScalar *aa; 2716ba337c44SJed Brown 2717ba337c44SJed Brown PetscFunctionBegin; 27189566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 271906c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 272006c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscRealPart(aa[i + j * mat->lda]); 272106c5243aSJose E. Roman } 27229566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 27233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2724ba337c44SJed Brown } 2725ba337c44SJed Brown 2726d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatImaginaryPart_SeqDense(Mat A) 2727d71ae5a4SJacob Faibussowitsch { 272806c5243aSJose E. Roman Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 272906c5243aSJose E. Roman PetscInt i, j; 2730ca15aa20SStefano Zampini PetscScalar *aa; 2731ba337c44SJed Brown 2732ba337c44SJed Brown PetscFunctionBegin; 27339566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 273406c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 273506c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscImaginaryPart(aa[i + j * mat->lda]); 273606c5243aSJose E. Roman } 27379566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 27383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2739ba337c44SJed Brown } 2740284134d9SBarry Smith 2741d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2742d71ae5a4SJacob Faibussowitsch { 2743d0f46423SBarry Smith PetscInt m = A->rmap->n, n = B->cmap->n; 274447d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 2745a9fe9ddaSSatish Balay 2746ee16a9a1SHong Zhang PetscFunctionBegin; 27479566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 274847d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 27499566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 275047d993e7Ssuyashtn #endif 275147d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 275247d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 275347d993e7Ssuyashtn #endif 27547a3c3d58SStefano Zampini if (!cisdense) { 27557a3c3d58SStefano Zampini PetscBool flg; 27567a3c3d58SStefano Zampini 27579566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 27589566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 27597a3c3d58SStefano Zampini } 27609566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 27613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2762ee16a9a1SHong Zhang } 2763a9fe9ddaSSatish Balay 2764d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2765d71ae5a4SJacob Faibussowitsch { 27666718818eSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data, *c = (Mat_SeqDense *)C->data; 27670805154bSBarry Smith PetscBLASInt m, n, k; 2768ca15aa20SStefano Zampini const PetscScalar *av, *bv; 2769ca15aa20SStefano Zampini PetscScalar *cv; 2770a9fe9ddaSSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 2771a9fe9ddaSSatish Balay 2772a9fe9ddaSSatish Balay PetscFunctionBegin; 27739566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 27749566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 27759566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 27763ba16761SJacob Faibussowitsch if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS); 27779566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 27789566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 27799566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2780792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("N", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 27819566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 27829566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 27839566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 27849566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 27853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2786a9fe9ddaSSatish Balay } 2787a9fe9ddaSSatish Balay 2788d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2789d71ae5a4SJacob Faibussowitsch { 279069f65d41SStefano Zampini PetscInt m = A->rmap->n, n = B->rmap->n; 279147d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 279269f65d41SStefano Zampini 279369f65d41SStefano Zampini PetscFunctionBegin; 27949566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 279547d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 27969566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 279747d993e7Ssuyashtn #endif 279847d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 279947d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 280047d993e7Ssuyashtn #endif 28017a3c3d58SStefano Zampini if (!cisdense) { 28027a3c3d58SStefano Zampini PetscBool flg; 28037a3c3d58SStefano Zampini 28049566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 28059566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 28067a3c3d58SStefano Zampini } 28079566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 28083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 280969f65d41SStefano Zampini } 281069f65d41SStefano Zampini 2811d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2812d71ae5a4SJacob Faibussowitsch { 281369f65d41SStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 281469f65d41SStefano Zampini Mat_SeqDense *b = (Mat_SeqDense *)B->data; 281569f65d41SStefano Zampini Mat_SeqDense *c = (Mat_SeqDense *)C->data; 28166718818eSStefano Zampini const PetscScalar *av, *bv; 28176718818eSStefano Zampini PetscScalar *cv; 281869f65d41SStefano Zampini PetscBLASInt m, n, k; 281969f65d41SStefano Zampini PetscScalar _DOne = 1.0, _DZero = 0.0; 282069f65d41SStefano Zampini 282169f65d41SStefano Zampini PetscFunctionBegin; 28229566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 28239566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 28249566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 28253ba16761SJacob Faibussowitsch if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS); 28269566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 28279566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 28289566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2829792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("N", "T", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 28309566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 28319566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 28329566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 28339566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 28343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 283569f65d41SStefano Zampini } 283669f65d41SStefano Zampini 2837d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2838d71ae5a4SJacob Faibussowitsch { 2839d0f46423SBarry Smith PetscInt m = A->cmap->n, n = B->cmap->n; 284047d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 2841a9fe9ddaSSatish Balay 2842ee16a9a1SHong Zhang PetscFunctionBegin; 28439566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 284447d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 28459566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 284647d993e7Ssuyashtn #endif 284747d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 284847d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 284947d993e7Ssuyashtn #endif 28507a3c3d58SStefano Zampini if (!cisdense) { 28517a3c3d58SStefano Zampini PetscBool flg; 28527a3c3d58SStefano Zampini 28539566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 28549566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 28557a3c3d58SStefano Zampini } 28569566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 28573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2858ee16a9a1SHong Zhang } 2859a9fe9ddaSSatish Balay 2860d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2861d71ae5a4SJacob Faibussowitsch { 2862a9fe9ddaSSatish Balay Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2863a9fe9ddaSSatish Balay Mat_SeqDense *b = (Mat_SeqDense *)B->data; 2864a9fe9ddaSSatish Balay Mat_SeqDense *c = (Mat_SeqDense *)C->data; 28656718818eSStefano Zampini const PetscScalar *av, *bv; 28666718818eSStefano Zampini PetscScalar *cv; 28670805154bSBarry Smith PetscBLASInt m, n, k; 2868a9fe9ddaSSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 2869a9fe9ddaSSatish Balay 2870a9fe9ddaSSatish Balay PetscFunctionBegin; 28719566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 28729566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 28739566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &k)); 28743ba16761SJacob Faibussowitsch if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS); 28759566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 28769566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 28779566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2878792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("T", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 28799566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 28809566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 28819566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 28829566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 28833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2884a9fe9ddaSSatish Balay } 2885985db425SBarry Smith 2886d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C) 2887d71ae5a4SJacob Faibussowitsch { 28884222ddf1SHong Zhang PetscFunctionBegin; 28894222ddf1SHong Zhang C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense; 28904222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AB; 28913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28924222ddf1SHong Zhang } 28934222ddf1SHong Zhang 2894d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C) 2895d71ae5a4SJacob Faibussowitsch { 28964222ddf1SHong Zhang PetscFunctionBegin; 28974222ddf1SHong Zhang C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense; 28984222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AtB; 28993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29004222ddf1SHong Zhang } 29014222ddf1SHong Zhang 2902d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C) 2903d71ae5a4SJacob Faibussowitsch { 29044222ddf1SHong Zhang PetscFunctionBegin; 29054222ddf1SHong Zhang C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense; 29064222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_ABt; 29073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29084222ddf1SHong Zhang } 29094222ddf1SHong Zhang 2910d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C) 2911d71ae5a4SJacob Faibussowitsch { 29124222ddf1SHong Zhang Mat_Product *product = C->product; 29134222ddf1SHong Zhang 29144222ddf1SHong Zhang PetscFunctionBegin; 29154222ddf1SHong Zhang switch (product->type) { 2916d71ae5a4SJacob Faibussowitsch case MATPRODUCT_AB: 2917d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_AB(C)); 2918d71ae5a4SJacob Faibussowitsch break; 2919d71ae5a4SJacob Faibussowitsch case MATPRODUCT_AtB: 2920d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_AtB(C)); 2921d71ae5a4SJacob Faibussowitsch break; 2922d71ae5a4SJacob Faibussowitsch case MATPRODUCT_ABt: 2923d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_ABt(C)); 2924d71ae5a4SJacob Faibussowitsch break; 2925d71ae5a4SJacob Faibussowitsch default: 2926d71ae5a4SJacob Faibussowitsch break; 29274222ddf1SHong Zhang } 29283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29294222ddf1SHong Zhang } 29304222ddf1SHong Zhang 2931d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMax_SeqDense(Mat A, Vec v, PetscInt idx[]) 2932d71ae5a4SJacob Faibussowitsch { 2933985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2934d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2935985db425SBarry Smith PetscScalar *x; 2936ca15aa20SStefano Zampini const PetscScalar *aa; 2937985db425SBarry Smith 2938985db425SBarry Smith PetscFunctionBegin; 293928b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29409566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29419566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 29429566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 294308401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2944985db425SBarry Smith for (i = 0; i < m; i++) { 29459371c9d4SSatish Balay x[i] = aa[i]; 29469371c9d4SSatish Balay if (idx) idx[i] = 0; 2947985db425SBarry Smith for (j = 1; j < n; j++) { 29489371c9d4SSatish Balay if (PetscRealPart(x[i]) < PetscRealPart(aa[i + a->lda * j])) { 29499371c9d4SSatish Balay x[i] = aa[i + a->lda * j]; 29509371c9d4SSatish Balay if (idx) idx[i] = j; 29519371c9d4SSatish Balay } 2952985db425SBarry Smith } 2953985db425SBarry Smith } 29549566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 29559566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 29563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2957985db425SBarry Smith } 2958985db425SBarry Smith 2959d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A, Vec v, PetscInt idx[]) 2960d71ae5a4SJacob Faibussowitsch { 2961985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2962d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2963985db425SBarry Smith PetscScalar *x; 2964985db425SBarry Smith PetscReal atmp; 2965ca15aa20SStefano Zampini const PetscScalar *aa; 2966985db425SBarry Smith 2967985db425SBarry Smith PetscFunctionBegin; 296828b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29699566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29709566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 29719566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 297208401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2973985db425SBarry Smith for (i = 0; i < m; i++) { 29749189402eSHong Zhang x[i] = PetscAbsScalar(aa[i]); 2975985db425SBarry Smith for (j = 1; j < n; j++) { 2976ca15aa20SStefano Zampini atmp = PetscAbsScalar(aa[i + a->lda * j]); 29779371c9d4SSatish Balay if (PetscAbsScalar(x[i]) < atmp) { 29789371c9d4SSatish Balay x[i] = atmp; 29799371c9d4SSatish Balay if (idx) idx[i] = j; 29809371c9d4SSatish Balay } 2981985db425SBarry Smith } 2982985db425SBarry Smith } 29839566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 29849566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 29853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2986985db425SBarry Smith } 2987985db425SBarry Smith 2988d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMin_SeqDense(Mat A, Vec v, PetscInt idx[]) 2989d71ae5a4SJacob Faibussowitsch { 2990985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2991d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2992985db425SBarry Smith PetscScalar *x; 2993ca15aa20SStefano Zampini const PetscScalar *aa; 2994985db425SBarry Smith 2995985db425SBarry Smith PetscFunctionBegin; 299628b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29979566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 29989566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29999566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 300008401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 3001985db425SBarry Smith for (i = 0; i < m; i++) { 30029371c9d4SSatish Balay x[i] = aa[i]; 30039371c9d4SSatish Balay if (idx) idx[i] = 0; 3004985db425SBarry Smith for (j = 1; j < n; j++) { 30059371c9d4SSatish Balay if (PetscRealPart(x[i]) > PetscRealPart(aa[i + a->lda * j])) { 30069371c9d4SSatish Balay x[i] = aa[i + a->lda * j]; 30079371c9d4SSatish Balay if (idx) idx[i] = j; 30089371c9d4SSatish Balay } 3009985db425SBarry Smith } 3010985db425SBarry Smith } 30119566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 30129566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 30133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3014985db425SBarry Smith } 3015985db425SBarry Smith 3016d71ae5a4SJacob Faibussowitsch PetscErrorCode MatGetColumnVector_SeqDense(Mat A, Vec v, PetscInt col) 3017d71ae5a4SJacob Faibussowitsch { 30188d0534beSBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 30198d0534beSBarry Smith PetscScalar *x; 3020ca15aa20SStefano Zampini const PetscScalar *aa; 30218d0534beSBarry Smith 30228d0534beSBarry Smith PetscFunctionBegin; 302328b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 30249566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 30259566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 30269566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(x, aa + col * a->lda, A->rmap->n)); 30279566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 30289566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 30293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30308d0534beSBarry Smith } 30318d0534beSBarry Smith 3032d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatGetColumnReductions_SeqDense(Mat A, PetscInt type, PetscReal *reductions) 3033d71ae5a4SJacob Faibussowitsch { 30340716a85fSBarry Smith PetscInt i, j, m, n; 30351683a169SBarry Smith const PetscScalar *a; 30360716a85fSBarry Smith 30370716a85fSBarry Smith PetscFunctionBegin; 30389566063dSJacob Faibussowitsch PetscCall(MatGetSize(A, &m, &n)); 30399566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(reductions, n)); 30409566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &a)); 3041857cbf51SRichard Tran Mills if (type == NORM_2) { 30420716a85fSBarry Smith for (i = 0; i < n; i++) { 3043ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j] * a[j]); 304416cd844bSPierre Jolivet a = PetscSafePointerPlusOffset(a, m); 30450716a85fSBarry Smith } 3046857cbf51SRichard Tran Mills } else if (type == NORM_1) { 30470716a85fSBarry Smith for (i = 0; i < n; i++) { 3048ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j]); 304916cd844bSPierre Jolivet a = PetscSafePointerPlusOffset(a, m); 30500716a85fSBarry Smith } 3051857cbf51SRichard Tran Mills } else if (type == NORM_INFINITY) { 30520716a85fSBarry Smith for (i = 0; i < n; i++) { 3053ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] = PetscMax(PetscAbsScalar(a[j]), reductions[i]); 305416cd844bSPierre Jolivet a = PetscSafePointerPlusOffset(a, m); 30550716a85fSBarry Smith } 3056857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_REALPART || type == REDUCTION_MEAN_REALPART) { 3057a873a8cdSSam Reynolds for (i = 0; i < n; i++) { 3058ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscRealPart(a[j]); 305916cd844bSPierre Jolivet a = PetscSafePointerPlusOffset(a, m); 3060a873a8cdSSam Reynolds } 3061857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_IMAGINARYPART || type == REDUCTION_MEAN_IMAGINARYPART) { 3062857cbf51SRichard Tran Mills for (i = 0; i < n; i++) { 3063ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscImaginaryPart(a[j]); 306416cd844bSPierre Jolivet a = PetscSafePointerPlusOffset(a, m); 3065857cbf51SRichard Tran Mills } 3066857cbf51SRichard Tran Mills } else SETERRQ(PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Unknown reduction type"); 30679566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &a)); 3068857cbf51SRichard Tran Mills if (type == NORM_2) { 3069a873a8cdSSam Reynolds for (i = 0; i < n; i++) reductions[i] = PetscSqrtReal(reductions[i]); 3070857cbf51SRichard Tran Mills } else if (type == REDUCTION_MEAN_REALPART || type == REDUCTION_MEAN_IMAGINARYPART) { 3071a873a8cdSSam Reynolds for (i = 0; i < n; i++) reductions[i] /= m; 30720716a85fSBarry Smith } 30733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30740716a85fSBarry Smith } 30750716a85fSBarry Smith 3076d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetRandom_SeqDense(Mat x, PetscRandom rctx) 3077d71ae5a4SJacob Faibussowitsch { 307873a71a0fSBarry Smith PetscScalar *a; 3079637a0070SStefano Zampini PetscInt lda, m, n, i, j; 308073a71a0fSBarry Smith 308173a71a0fSBarry Smith PetscFunctionBegin; 30829566063dSJacob Faibussowitsch PetscCall(MatGetSize(x, &m, &n)); 30839566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(x, &lda)); 30843faff063SStefano Zampini PetscCall(MatDenseGetArrayWrite(x, &a)); 3085637a0070SStefano Zampini for (j = 0; j < n; j++) { 308648a46eb9SPierre Jolivet for (i = 0; i < m; i++) PetscCall(PetscRandomGetValue(rctx, a + j * lda + i)); 308773a71a0fSBarry Smith } 30883faff063SStefano Zampini PetscCall(MatDenseRestoreArrayWrite(x, &a)); 30893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 309073a71a0fSBarry Smith } 309173a71a0fSBarry Smith 3092d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A, PetscBool *missing, PetscInt *d) 3093d71ae5a4SJacob Faibussowitsch { 30943b49f96aSBarry Smith PetscFunctionBegin; 30953b49f96aSBarry Smith *missing = PETSC_FALSE; 30963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30973b49f96aSBarry Smith } 309873a71a0fSBarry Smith 3099ca15aa20SStefano Zampini /* vals is not const */ 3100d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A, PetscInt col, PetscScalar **vals) 3101d71ae5a4SJacob Faibussowitsch { 310286aefd0dSHong Zhang Mat_SeqDense *a = (Mat_SeqDense *)A->data; 3103ca15aa20SStefano Zampini PetscScalar *v; 310486aefd0dSHong Zhang 310586aefd0dSHong Zhang PetscFunctionBegin; 310628b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 31079566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 3108ca15aa20SStefano Zampini *vals = v + col * a->lda; 31099566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 31103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 311186aefd0dSHong Zhang } 311286aefd0dSHong Zhang 3113d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A, PetscScalar **vals) 3114d71ae5a4SJacob Faibussowitsch { 311586aefd0dSHong Zhang PetscFunctionBegin; 3116742765d3SMatthew Knepley if (vals) *vals = NULL; /* user cannot accidentally use the array later */ 31173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 311886aefd0dSHong Zhang } 3119abc3b08eSStefano Zampini 3120a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqDense, 3121905e6a2fSBarry Smith MatGetRow_SeqDense, 3122905e6a2fSBarry Smith MatRestoreRow_SeqDense, 3123905e6a2fSBarry Smith MatMult_SeqDense, 312497304618SKris Buschelman /* 4*/ MatMultAdd_SeqDense, 31257c922b88SBarry Smith MatMultTranspose_SeqDense, 31267c922b88SBarry Smith MatMultTransposeAdd_SeqDense, 3127f4259b30SLisandro Dalcin NULL, 3128f4259b30SLisandro Dalcin NULL, 3129f4259b30SLisandro Dalcin NULL, 3130f4259b30SLisandro Dalcin /* 10*/ NULL, 3131905e6a2fSBarry Smith MatLUFactor_SeqDense, 3132905e6a2fSBarry Smith MatCholeskyFactor_SeqDense, 313341f059aeSBarry Smith MatSOR_SeqDense, 3134ec8511deSBarry Smith MatTranspose_SeqDense, 313597304618SKris Buschelman /* 15*/ MatGetInfo_SeqDense, 3136905e6a2fSBarry Smith MatEqual_SeqDense, 3137905e6a2fSBarry Smith MatGetDiagonal_SeqDense, 3138905e6a2fSBarry Smith MatDiagonalScale_SeqDense, 3139905e6a2fSBarry Smith MatNorm_SeqDense, 3140c0aa2d19SHong Zhang /* 20*/ MatAssemblyBegin_SeqDense, 3141c0aa2d19SHong Zhang MatAssemblyEnd_SeqDense, 3142905e6a2fSBarry Smith MatSetOption_SeqDense, 3143905e6a2fSBarry Smith MatZeroEntries_SeqDense, 3144d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqDense, 3145f4259b30SLisandro Dalcin NULL, 3146f4259b30SLisandro Dalcin NULL, 3147f4259b30SLisandro Dalcin NULL, 3148f4259b30SLisandro Dalcin NULL, 31494994cf47SJed Brown /* 29*/ MatSetUp_SeqDense, 3150f4259b30SLisandro Dalcin NULL, 3151f4259b30SLisandro Dalcin NULL, 3152f4259b30SLisandro Dalcin NULL, 3153f4259b30SLisandro Dalcin NULL, 3154d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqDense, 3155f4259b30SLisandro Dalcin NULL, 3156f4259b30SLisandro Dalcin NULL, 3157f4259b30SLisandro Dalcin NULL, 3158f4259b30SLisandro Dalcin NULL, 3159d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqDense, 31607dae84e0SHong Zhang MatCreateSubMatrices_SeqDense, 3161f4259b30SLisandro Dalcin NULL, 31624b0e389bSBarry Smith MatGetValues_SeqDense, 3163a5ae1ecdSBarry Smith MatCopy_SeqDense, 3164d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqDense, 3165a5ae1ecdSBarry Smith MatScale_SeqDense, 31662f605a99SJose E. Roman MatShift_SeqDense, 3167f4259b30SLisandro Dalcin NULL, 31683f49a652SStefano Zampini MatZeroRowsColumns_SeqDense, 316973a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqDense, 3170f4259b30SLisandro Dalcin NULL, 3171f4259b30SLisandro Dalcin NULL, 3172f4259b30SLisandro Dalcin NULL, 3173f4259b30SLisandro Dalcin NULL, 3174f4259b30SLisandro Dalcin /* 54*/ NULL, 3175f4259b30SLisandro Dalcin NULL, 3176f4259b30SLisandro Dalcin NULL, 3177f4259b30SLisandro Dalcin NULL, 3178f4259b30SLisandro Dalcin NULL, 3179023c16fcSToby Isaac /* 59*/ MatCreateSubMatrix_SeqDense, 3180e03a110bSBarry Smith MatDestroy_SeqDense, 3181e03a110bSBarry Smith MatView_SeqDense, 3182f4259b30SLisandro Dalcin NULL, 3183f4259b30SLisandro Dalcin NULL, 3184f4259b30SLisandro Dalcin /* 64*/ NULL, 3185f4259b30SLisandro Dalcin NULL, 3186f4259b30SLisandro Dalcin NULL, 3187f4259b30SLisandro Dalcin NULL, 3188f4259b30SLisandro Dalcin NULL, 3189d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqDense, 3190f4259b30SLisandro Dalcin NULL, 3191f4259b30SLisandro Dalcin NULL, 3192f4259b30SLisandro Dalcin NULL, 3193f4259b30SLisandro Dalcin NULL, 3194f4259b30SLisandro Dalcin /* 74*/ NULL, 3195f4259b30SLisandro Dalcin NULL, 3196f4259b30SLisandro Dalcin NULL, 3197f4259b30SLisandro Dalcin NULL, 3198f4259b30SLisandro Dalcin NULL, 3199f4259b30SLisandro Dalcin /* 79*/ NULL, 3200f4259b30SLisandro Dalcin NULL, 3201f4259b30SLisandro Dalcin NULL, 3202f4259b30SLisandro Dalcin NULL, 32035bba2384SShri Abhyankar /* 83*/ MatLoad_SeqDense, 3204637a0070SStefano Zampini MatIsSymmetric_SeqDense, 32051cbb95d3SBarry Smith MatIsHermitian_SeqDense, 3206f4259b30SLisandro Dalcin NULL, 3207f4259b30SLisandro Dalcin NULL, 3208f4259b30SLisandro Dalcin NULL, 3209f4259b30SLisandro Dalcin /* 89*/ NULL, 3210f4259b30SLisandro Dalcin NULL, 3211a9fe9ddaSSatish Balay MatMatMultNumeric_SeqDense_SeqDense, 3212f4259b30SLisandro Dalcin NULL, 3213f4259b30SLisandro Dalcin NULL, 3214f4259b30SLisandro Dalcin /* 94*/ NULL, 3215f4259b30SLisandro Dalcin NULL, 3216f4259b30SLisandro Dalcin NULL, 321769f65d41SStefano Zampini MatMatTransposeMultNumeric_SeqDense_SeqDense, 3218f4259b30SLisandro Dalcin NULL, 32194222ddf1SHong Zhang /* 99*/ MatProductSetFromOptions_SeqDense, 3220f4259b30SLisandro Dalcin NULL, 3221f4259b30SLisandro Dalcin NULL, 3222ba337c44SJed Brown MatConjugate_SeqDense, 3223f4259b30SLisandro Dalcin NULL, 3224f4259b30SLisandro Dalcin /*104*/ NULL, 3225ba337c44SJed Brown MatRealPart_SeqDense, 3226ba337c44SJed Brown MatImaginaryPart_SeqDense, 3227f4259b30SLisandro Dalcin NULL, 3228f4259b30SLisandro Dalcin NULL, 3229f4259b30SLisandro Dalcin /*109*/ NULL, 3230f4259b30SLisandro Dalcin NULL, 32318d0534beSBarry Smith MatGetRowMin_SeqDense, 3232aabbc4fbSShri Abhyankar MatGetColumnVector_SeqDense, 32333b49f96aSBarry Smith MatMissingDiagonal_SeqDense, 3234f4259b30SLisandro Dalcin /*114*/ NULL, 3235f4259b30SLisandro Dalcin NULL, 3236f4259b30SLisandro Dalcin NULL, 3237f4259b30SLisandro Dalcin NULL, 3238f4259b30SLisandro Dalcin NULL, 3239f4259b30SLisandro Dalcin /*119*/ NULL, 3240f4259b30SLisandro Dalcin NULL, 3241459e8d23SBlanca Mellado Pinto MatMultHermitianTranspose_SeqDense, 3242459e8d23SBlanca Mellado Pinto MatMultHermitianTransposeAdd_SeqDense, 3243f4259b30SLisandro Dalcin NULL, 3244f4259b30SLisandro Dalcin /*124*/ NULL, 3245a873a8cdSSam Reynolds MatGetColumnReductions_SeqDense, 3246f4259b30SLisandro Dalcin NULL, 3247f4259b30SLisandro Dalcin NULL, 3248f4259b30SLisandro Dalcin NULL, 3249f4259b30SLisandro Dalcin /*129*/ NULL, 3250f4259b30SLisandro Dalcin NULL, 3251f4259b30SLisandro Dalcin NULL, 325275648e8dSHong Zhang MatTransposeMatMultNumeric_SeqDense_SeqDense, 3253f4259b30SLisandro Dalcin NULL, 3254f4259b30SLisandro Dalcin /*134*/ NULL, 3255f4259b30SLisandro Dalcin NULL, 3256f4259b30SLisandro Dalcin NULL, 3257f4259b30SLisandro Dalcin NULL, 3258f4259b30SLisandro Dalcin NULL, 3259f4259b30SLisandro Dalcin /*139*/ NULL, 3260f4259b30SLisandro Dalcin NULL, 3261f4259b30SLisandro Dalcin NULL, 3262f4259b30SLisandro Dalcin NULL, 3263f4259b30SLisandro Dalcin NULL, 32644222ddf1SHong Zhang MatCreateMPIMatConcatenateSeqMat_SeqDense, 3265f4259b30SLisandro Dalcin /*145*/ NULL, 3266f4259b30SLisandro Dalcin NULL, 326799a7f59eSMark Adams NULL, 326899a7f59eSMark Adams NULL, 32697fb60732SBarry Smith NULL, 3270dec0b466SHong Zhang /*150*/ NULL, 3271eede4a3fSMark Adams NULL, 3272dec0b466SHong Zhang NULL}; 327390ace30eSBarry Smith 32744b828684SBarry Smith /*@C 327511a5261eSBarry Smith MatCreateSeqDense - Creates a `MATSEQDENSE` that 3276fb850c59SBarry Smith is stored in column major order (the usual Fortran format). 3277289bc588SBarry Smith 3278d083f849SBarry Smith Collective 3279db81eaa0SLois Curfman McInnes 328020563c6bSBarry Smith Input Parameters: 328111a5261eSBarry Smith + comm - MPI communicator, set to `PETSC_COMM_SELF` 32820c775827SLois Curfman McInnes . m - number of rows 328318f449edSLois Curfman McInnes . n - number of columns 32842ef1f0ffSBarry Smith - data - optional location of matrix data in column major order. Use `NULL` for PETSc 3285dfc5480cSLois Curfman McInnes to control all matrix memory allocation. 328620563c6bSBarry Smith 328720563c6bSBarry Smith Output Parameter: 328844cd7ae7SLois Curfman McInnes . A - the matrix 328920563c6bSBarry Smith 32902ef1f0ffSBarry Smith Level: intermediate 32912ef1f0ffSBarry Smith 329211a5261eSBarry Smith Note: 329318f449edSLois Curfman McInnes The data input variable is intended primarily for Fortran programmers 329418f449edSLois Curfman McInnes who wish to allocate their own matrix memory space. Most users should 32952ef1f0ffSBarry Smith set `data` = `NULL`. 329618f449edSLois Curfman McInnes 3297fb850c59SBarry Smith Developer Note: 3298fb850c59SBarry Smith Many of the matrix operations for this variant use the BLAS and LAPACK routines. 3299fb850c59SBarry Smith 33001cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()` 330120563c6bSBarry Smith @*/ 3302d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateSeqDense(MPI_Comm comm, PetscInt m, PetscInt n, PetscScalar *data, Mat *A) 3303d71ae5a4SJacob Faibussowitsch { 33043a40ed3dSBarry Smith PetscFunctionBegin; 33059566063dSJacob Faibussowitsch PetscCall(MatCreate(comm, A)); 33069566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*A, m, n, m, n)); 33079566063dSJacob Faibussowitsch PetscCall(MatSetType(*A, MATSEQDENSE)); 33089566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(*A, data)); 33093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3310273d9f13SBarry Smith } 3311273d9f13SBarry Smith 3312273d9f13SBarry Smith /*@C 331311a5261eSBarry Smith MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements of a `MATSEQDENSE` matrix 3314273d9f13SBarry Smith 3315d083f849SBarry Smith Collective 3316273d9f13SBarry Smith 3317273d9f13SBarry Smith Input Parameters: 33181c4f3114SJed Brown + B - the matrix 33192ef1f0ffSBarry Smith - data - the array (or `NULL`) 33202ef1f0ffSBarry Smith 33212ef1f0ffSBarry Smith Level: intermediate 3322273d9f13SBarry Smith 332311a5261eSBarry Smith Note: 3324273d9f13SBarry Smith The data input variable is intended primarily for Fortran programmers 3325273d9f13SBarry Smith who wish to allocate their own matrix memory space. Most users should 3326284134d9SBarry Smith need not call this routine. 3327273d9f13SBarry Smith 33281cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()`, `MatDenseSetLDA()` 3329273d9f13SBarry Smith @*/ 3330d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation(Mat B, PetscScalar data[]) 3331d71ae5a4SJacob Faibussowitsch { 3332a23d5eceSKris Buschelman PetscFunctionBegin; 3333d5ea218eSStefano Zampini PetscValidHeaderSpecific(B, MAT_CLASSID, 1); 3334cac4c232SBarry Smith PetscTryMethod(B, "MatSeqDenseSetPreallocation_C", (Mat, PetscScalar[]), (B, data)); 33353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3336a23d5eceSKris Buschelman } 3337a23d5eceSKris Buschelman 3338d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation_SeqDense(Mat B, PetscScalar *data) 3339d71ae5a4SJacob Faibussowitsch { 3340ad16ce7aSStefano Zampini Mat_SeqDense *b = (Mat_SeqDense *)B->data; 3341273d9f13SBarry Smith 3342273d9f13SBarry Smith PetscFunctionBegin; 334328b400f6SJacob Faibussowitsch PetscCheck(!b->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3344273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 3345a868139aSShri Abhyankar 33469566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(B->rmap)); 33479566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(B->cmap)); 334834ef9618SShri Abhyankar 3349ad16ce7aSStefano Zampini if (b->lda <= 0) b->lda = B->rmap->n; 335086d161a7SShri Abhyankar 33519e8f95c4SLisandro Dalcin if (!data) { /* petsc-allocated storage */ 33529566063dSJacob Faibussowitsch if (!b->user_alloc) PetscCall(PetscFree(b->v)); 33539566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((size_t)b->lda * B->cmap->n, &b->v)); 33542205254eSKarl Rupp 33559e8f95c4SLisandro Dalcin b->user_alloc = PETSC_FALSE; 3356273d9f13SBarry Smith } else { /* user-allocated storage */ 33579566063dSJacob Faibussowitsch if (!b->user_alloc) PetscCall(PetscFree(b->v)); 3358273d9f13SBarry Smith b->v = data; 3359273d9f13SBarry Smith b->user_alloc = PETSC_TRUE; 3360273d9f13SBarry Smith } 33610450473dSBarry Smith B->assembled = PETSC_TRUE; 33623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3363273d9f13SBarry Smith } 3364273d9f13SBarry Smith 336565b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 3366d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) 3367d71ae5a4SJacob Faibussowitsch { 3368d77f618aSHong Zhang Mat mat_elemental; 33691683a169SBarry Smith const PetscScalar *array; 33701683a169SBarry Smith PetscScalar *v_colwise; 3371d77f618aSHong Zhang PetscInt M = A->rmap->N, N = A->cmap->N, i, j, k, *rows, *cols; 3372d77f618aSHong Zhang 33738baccfbdSHong Zhang PetscFunctionBegin; 33749566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(M * N, &v_colwise, M, &rows, N, &cols)); 33759566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &array)); 3376d77f618aSHong Zhang /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */ 3377d77f618aSHong Zhang k = 0; 3378d77f618aSHong Zhang for (j = 0; j < N; j++) { 3379d77f618aSHong Zhang cols[j] = j; 3380ad540459SPierre Jolivet for (i = 0; i < M; i++) v_colwise[j * M + i] = array[k++]; 3381d77f618aSHong Zhang } 3382ad540459SPierre Jolivet for (i = 0; i < M; i++) rows[i] = i; 33839566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &array)); 3384d77f618aSHong Zhang 33859566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental)); 33869566063dSJacob Faibussowitsch PetscCall(MatSetSizes(mat_elemental, PETSC_DECIDE, PETSC_DECIDE, M, N)); 33879566063dSJacob Faibussowitsch PetscCall(MatSetType(mat_elemental, MATELEMENTAL)); 33889566063dSJacob Faibussowitsch PetscCall(MatSetUp(mat_elemental)); 3389d77f618aSHong Zhang 3390d77f618aSHong Zhang /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */ 33919566063dSJacob Faibussowitsch PetscCall(MatSetValues(mat_elemental, M, rows, N, cols, v_colwise, ADD_VALUES)); 33929566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY)); 33939566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY)); 33949566063dSJacob Faibussowitsch PetscCall(PetscFree3(v_colwise, rows, cols)); 3395d77f618aSHong Zhang 3396511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 33979566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A, &mat_elemental)); 3398d77f618aSHong Zhang } else { 3399d77f618aSHong Zhang *newmat = mat_elemental; 3400d77f618aSHong Zhang } 34013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34028baccfbdSHong Zhang } 340365b80a83SHong Zhang #endif 34048baccfbdSHong Zhang 3405d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA_SeqDense(Mat B, PetscInt lda) 3406d71ae5a4SJacob Faibussowitsch { 34071b807ce4Svictorle Mat_SeqDense *b = (Mat_SeqDense *)B->data; 34087422da62SJose E. Roman PetscBool data; 340921a2c019SBarry Smith 34101b807ce4Svictorle PetscFunctionBegin; 34117422da62SJose E. Roman data = (PetscBool)((B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE); 3412aed4548fSBarry Smith PetscCheck(b->user_alloc || !data || b->lda == lda, PETSC_COMM_SELF, PETSC_ERR_ORDER, "LDA cannot be changed after allocation of internal storage"); 341308401ef6SPierre 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); 34141b807ce4Svictorle b->lda = lda; 34153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34161b807ce4Svictorle } 34171b807ce4Svictorle 3418d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm, Mat inmat, PetscInt n, MatReuse scall, Mat *outmat) 3419d71ae5a4SJacob Faibussowitsch { 3420d528f656SJakub Kruzik PetscFunctionBegin; 34219566063dSJacob Faibussowitsch PetscCall(MatCreateMPIMatConcatenateSeqMat_MPIDense(comm, inmat, n, scall, outmat)); 34223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3423d528f656SJakub Kruzik } 3424d528f656SJakub Kruzik 3425d16ceb75SStefano Zampini PetscErrorCode MatDenseCreateColumnVec_Private(Mat A, Vec *v) 3426d16ceb75SStefano Zampini { 3427d16ceb75SStefano Zampini PetscBool isstd, iskok, iscuda, iship; 3428d16ceb75SStefano Zampini PetscMPIInt size; 3429d16ceb75SStefano Zampini #if PetscDefined(HAVE_CUDA) || PetscDefined(HAVE_HIP) 3430d16ceb75SStefano Zampini /* we pass the data of A, to prevent allocating needless GPU memory the first time VecCUPMPlaceArray is called. */ 3431d16ceb75SStefano Zampini const PetscScalar *a; 3432d16ceb75SStefano Zampini #endif 3433d16ceb75SStefano Zampini 3434d16ceb75SStefano Zampini PetscFunctionBegin; 3435d16ceb75SStefano Zampini *v = NULL; 3436d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &isstd, VECSTANDARD, VECSEQ, VECMPI, "")); 3437d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &iskok, VECKOKKOS, VECSEQKOKKOS, VECMPIKOKKOS, "")); 3438d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &iscuda, VECCUDA, VECSEQCUDA, VECMPICUDA, "")); 3439d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &iship, VECHIP, VECSEQHIP, VECMPIHIP, "")); 3440d16ceb75SStefano Zampini PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A), &size)); 3441d16ceb75SStefano Zampini if (isstd) { 3442d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPIWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, v)); 3443d16ceb75SStefano Zampini else PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, v)); 3444d16ceb75SStefano Zampini } else if (iskok) { 3445d16ceb75SStefano Zampini PetscCheck(PetscDefined(HAVE_KOKKOS_KERNELS), PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Reconfigure using KOKKOS kernels support"); 3446d16ceb75SStefano Zampini #if PetscDefined(HAVE_KOKKOS_KERNELS) 3447d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPIKokkosWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, v)); 3448d16ceb75SStefano Zampini else PetscCall(VecCreateSeqKokkosWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, v)); 3449d16ceb75SStefano Zampini #endif 3450d16ceb75SStefano Zampini } else if (iscuda) { 3451d16ceb75SStefano Zampini PetscCheck(PetscDefined(HAVE_CUDA), PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Reconfigure using CUDA support"); 3452d16ceb75SStefano Zampini #if PetscDefined(HAVE_CUDA) 3453d16ceb75SStefano Zampini PetscCall(MatDenseCUDAGetArrayRead(A, &a)); 3454d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPICUDAWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, a, v)); 3455d16ceb75SStefano Zampini else PetscCall(VecCreateSeqCUDAWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, a, v)); 3456d16ceb75SStefano Zampini #endif 3457d16ceb75SStefano Zampini } else if (iship) { 3458d16ceb75SStefano Zampini PetscCheck(PetscDefined(HAVE_HIP), PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Reconfigure using HIP support"); 3459d16ceb75SStefano Zampini #if PetscDefined(HAVE_HIP) 3460d16ceb75SStefano Zampini PetscCall(MatDenseHIPGetArrayRead(A, &a)); 3461d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPIHIPWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, a, v)); 3462d16ceb75SStefano Zampini else PetscCall(VecCreateSeqHIPWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, a, v)); 3463d16ceb75SStefano Zampini #endif 3464d16ceb75SStefano Zampini } 3465d16ceb75SStefano Zampini PetscCheck(*v, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Not coded for type %s", A->defaultvectype); 3466d16ceb75SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 3467d16ceb75SStefano Zampini } 3468d16ceb75SStefano Zampini 3469d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A, PetscInt col, Vec *v) 3470d71ae5a4SJacob Faibussowitsch { 34716947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34726947451fSStefano Zampini 34736947451fSStefano Zampini PetscFunctionBegin; 347428b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 347528b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3476d16ceb75SStefano Zampini if (!a->cvec) PetscCall(MatDenseCreateColumnVec_Private(A, &a->cvec)); 34776947451fSStefano Zampini a->vecinuse = col + 1; 34789566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, (PetscScalar **)&a->ptrinuse)); 34799566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda)); 34806947451fSStefano Zampini *v = a->cvec; 34813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34826947451fSStefano Zampini } 34836947451fSStefano Zampini 3484d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A, PetscInt col, Vec *v) 3485d71ae5a4SJacob Faibussowitsch { 34866947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34876947451fSStefano Zampini 34886947451fSStefano Zampini PetscFunctionBegin; 348928b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 349028b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 3491*4186a4bbSPierre Jolivet VecCheckAssembled(a->cvec); 34926947451fSStefano Zampini a->vecinuse = 0; 34939566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, (PetscScalar **)&a->ptrinuse)); 34949566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 349575f6d85dSStefano Zampini if (v) *v = NULL; 34963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34976947451fSStefano Zampini } 34986947451fSStefano Zampini 3499d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v) 3500d71ae5a4SJacob Faibussowitsch { 35016947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35026947451fSStefano Zampini 35036947451fSStefano Zampini PetscFunctionBegin; 350428b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 350528b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3506d16ceb75SStefano Zampini if (!a->cvec) PetscCall(MatDenseCreateColumnVec_Private(A, &a->cvec)); 35076947451fSStefano Zampini a->vecinuse = col + 1; 35089566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &a->ptrinuse)); 35098e3a54c0SPierre Jolivet PetscCall(VecPlaceArray(a->cvec, PetscSafePointerPlusOffset(a->ptrinuse, (size_t)col * (size_t)a->lda))); 35109566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(a->cvec)); 35116947451fSStefano Zampini *v = a->cvec; 35123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35136947451fSStefano Zampini } 35146947451fSStefano Zampini 3515d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v) 3516d71ae5a4SJacob Faibussowitsch { 35176947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35186947451fSStefano Zampini 35196947451fSStefano Zampini PetscFunctionBegin; 352028b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 352128b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 3522*4186a4bbSPierre Jolivet VecCheckAssembled(a->cvec); 35236947451fSStefano Zampini a->vecinuse = 0; 35249566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &a->ptrinuse)); 35259566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(a->cvec)); 35269566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 352775f6d85dSStefano Zampini if (v) *v = NULL; 35283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35296947451fSStefano Zampini } 35306947451fSStefano Zampini 3531d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v) 3532d71ae5a4SJacob Faibussowitsch { 35336947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35346947451fSStefano Zampini 35356947451fSStefano Zampini PetscFunctionBegin; 353628b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 353728b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3538d16ceb75SStefano Zampini if (!a->cvec) PetscCall(MatDenseCreateColumnVec_Private(A, &a->cvec)); 35396947451fSStefano Zampini a->vecinuse = col + 1; 35409566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(A, (PetscScalar **)&a->ptrinuse)); 35418e3a54c0SPierre Jolivet PetscCall(VecPlaceArray(a->cvec, PetscSafePointerPlusOffset(a->ptrinuse, (size_t)col * (size_t)a->lda))); 35426947451fSStefano Zampini *v = a->cvec; 35433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35446947451fSStefano Zampini } 35456947451fSStefano Zampini 3546d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v) 3547d71ae5a4SJacob Faibussowitsch { 35486947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35496947451fSStefano Zampini 35506947451fSStefano Zampini PetscFunctionBegin; 355128b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 355228b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 3553*4186a4bbSPierre Jolivet VecCheckAssembled(a->cvec); 35546947451fSStefano Zampini a->vecinuse = 0; 35559566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(A, (PetscScalar **)&a->ptrinuse)); 35569566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 355775f6d85dSStefano Zampini if (v) *v = NULL; 35583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35596947451fSStefano Zampini } 35606947451fSStefano Zampini 3561d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) 3562d71ae5a4SJacob Faibussowitsch { 35635ea7661aSPierre Jolivet Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35645ea7661aSPierre Jolivet 35655ea7661aSPierre Jolivet PetscFunctionBegin; 356628b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 356728b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3568a2748737SPierre Jolivet if (a->cmat && (cend - cbegin != a->cmat->cmap->N || rend - rbegin != a->cmat->rmap->N)) PetscCall(MatDestroy(&a->cmat)); 35695ea7661aSPierre Jolivet if (!a->cmat) { 35708e3a54c0SPierre 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)); 35715ea7661aSPierre Jolivet } else { 35728e3a54c0SPierre Jolivet PetscCall(MatDensePlaceArray(a->cmat, PetscSafePointerPlusOffset(a->v, rbegin + (size_t)cbegin * a->lda))); 35735ea7661aSPierre Jolivet } 35749566063dSJacob Faibussowitsch PetscCall(MatDenseSetLDA(a->cmat, a->lda)); 35755ea7661aSPierre Jolivet a->matinuse = cbegin + 1; 35765ea7661aSPierre Jolivet *v = a->cmat; 357747d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 357875f6d85dSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 357975f6d85dSStefano Zampini #endif 35803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35815ea7661aSPierre Jolivet } 35825ea7661aSPierre Jolivet 3583d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A, Mat *v) 3584d71ae5a4SJacob Faibussowitsch { 35855ea7661aSPierre Jolivet Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35865ea7661aSPierre Jolivet 35875ea7661aSPierre Jolivet PetscFunctionBegin; 358828b400f6SJacob Faibussowitsch PetscCheck(a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetSubMatrix() first"); 358928b400f6SJacob Faibussowitsch PetscCheck(a->cmat, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column matrix"); 359008401ef6SPierre Jolivet PetscCheck(*v == a->cmat, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not the matrix obtained from MatDenseGetSubMatrix()"); 35915ea7661aSPierre Jolivet a->matinuse = 0; 35929566063dSJacob Faibussowitsch PetscCall(MatDenseResetArray(a->cmat)); 3593742765d3SMatthew Knepley if (v) *v = NULL; 359447d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 35953faff063SStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 35963faff063SStefano Zampini #endif 35973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35985ea7661aSPierre Jolivet } 35995ea7661aSPierre Jolivet 36000bad9183SKris Buschelman /*MC 3601fafad747SKris Buschelman MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices. 36020bad9183SKris Buschelman 36032ef1f0ffSBarry Smith Options Database Key: 360411a5261eSBarry Smith . -mat_type seqdense - sets the matrix type to `MATSEQDENSE` during a call to `MatSetFromOptions()` 36050bad9183SKris Buschelman 36060bad9183SKris Buschelman Level: beginner 36070bad9183SKris Buschelman 36081cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreateSeqDense()` 36090bad9183SKris Buschelman M*/ 3610d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreate_SeqDense(Mat B) 3611d71ae5a4SJacob Faibussowitsch { 3612273d9f13SBarry Smith Mat_SeqDense *b; 36137c334f02SBarry Smith PetscMPIInt size; 3614273d9f13SBarry Smith 3615273d9f13SBarry Smith PetscFunctionBegin; 36169566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)B), &size)); 361708401ef6SPierre Jolivet PetscCheck(size <= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Comm must be of size 1"); 361855659b69SBarry Smith 36194dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&b)); 362044cd7ae7SLois Curfman McInnes B->data = (void *)b; 3621aea10558SJacob Faibussowitsch B->ops[0] = MatOps_Values; 362218f449edSLois Curfman McInnes 3623273d9f13SBarry Smith b->roworiented = PETSC_TRUE; 36244e220ebcSLois Curfman McInnes 36259566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatQRFactor_C", MatQRFactor_SeqDense)); 36269566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetLDA_C", MatDenseGetLDA_SeqDense)); 36279566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseSetLDA_C", MatDenseSetLDA_SeqDense)); 36289566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArray_C", MatDenseGetArray_SeqDense)); 36299566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArray_C", MatDenseRestoreArray_SeqDense)); 36309566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDensePlaceArray_C", MatDensePlaceArray_SeqDense)); 36319566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseResetArray_C", MatDenseResetArray_SeqDense)); 36329566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseReplaceArray_C", MatDenseReplaceArray_SeqDense)); 36339566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayRead_C", MatDenseGetArray_SeqDense)); 36349566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayRead_C", MatDenseRestoreArray_SeqDense)); 36359566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayWrite_C", MatDenseGetArray_SeqDense)); 36369566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayWrite_C", MatDenseRestoreArray_SeqDense)); 36379566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqaij_C", MatConvert_SeqDense_SeqAIJ)); 36388baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 36399566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_elemental_C", MatConvert_SeqDense_Elemental)); 36408baccfbdSHong Zhang #endif 3641d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 36429566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_scalapack_C", MatConvert_Dense_ScaLAPACK)); 3643d24d4204SJose E. Roman #endif 36442bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA) 36459566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensecuda_C", MatConvert_SeqDense_SeqDenseCUDA)); 36469566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", MatProductSetFromOptions_SeqDense)); 36479566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdense_C", MatProductSetFromOptions_SeqDense)); 36489566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensecuda_C", MatProductSetFromOptions_SeqDense)); 36492bf066beSStefano Zampini #endif 365047d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 365147d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensehip_C", MatConvert_SeqDense_SeqDenseHIP)); 365247d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensehip_seqdensehip_C", MatProductSetFromOptions_SeqDense)); 365347d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensehip_seqdense_C", MatProductSetFromOptions_SeqDense)); 365447d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensehip_C", MatProductSetFromOptions_SeqDense)); 365547d993e7Ssuyashtn #endif 36569566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSeqDenseSetPreallocation_C", MatSeqDenseSetPreallocation_SeqDense)); 36579566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqaij_seqdense_C", MatProductSetFromOptions_SeqAIJ_SeqDense)); 36589566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdense_C", MatProductSetFromOptions_SeqDense)); 36599566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense)); 36609566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqsbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense)); 366196e6d5c4SRichard Tran Mills 36629566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumn_C", MatDenseGetColumn_SeqDense)); 36639566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumn_C", MatDenseRestoreColumn_SeqDense)); 36649566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVec_C", MatDenseGetColumnVec_SeqDense)); 36659566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVec_C", MatDenseRestoreColumnVec_SeqDense)); 36669566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecRead_C", MatDenseGetColumnVecRead_SeqDense)); 36679566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecRead_C", MatDenseRestoreColumnVecRead_SeqDense)); 36689566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecWrite_C", MatDenseGetColumnVecWrite_SeqDense)); 36699566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecWrite_C", MatDenseRestoreColumnVecWrite_SeqDense)); 36709566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetSubMatrix_C", MatDenseGetSubMatrix_SeqDense)); 36719566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreSubMatrix_C", MatDenseRestoreSubMatrix_SeqDense)); 36720be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatMultAddColumnRange_C", MatMultAddColumnRange_SeqDense)); 36730be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatMultHermitianTransposeColumnRange_C", MatMultHermitianTransposeColumnRange_SeqDense)); 36740be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatMultHermitianTransposeAddColumnRange_C", MatMultHermitianTransposeAddColumnRange_SeqDense)); 36759566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)B, MATSEQDENSE)); 36763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3677289bc588SBarry Smith } 367886aefd0dSHong Zhang 367986aefd0dSHong Zhang /*@C 368011a5261eSBarry 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. 368186aefd0dSHong Zhang 368286aefd0dSHong Zhang Not Collective 368386aefd0dSHong Zhang 36845ea7661aSPierre Jolivet Input Parameters: 3685fe59aa6dSJacob Faibussowitsch + A - a `MATSEQDENSE` or `MATMPIDENSE` matrix 368686aefd0dSHong Zhang - col - column index 368786aefd0dSHong Zhang 368886aefd0dSHong Zhang Output Parameter: 368986aefd0dSHong Zhang . vals - pointer to the data 369086aefd0dSHong Zhang 369186aefd0dSHong Zhang Level: intermediate 369286aefd0dSHong Zhang 369311a5261eSBarry Smith Note: 369411a5261eSBarry Smith Use `MatDenseGetColumnVec()` to get access to a column of a `MATDENSE` treated as a `Vec` 369511a5261eSBarry Smith 36961cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreColumn()`, `MatDenseGetColumnVec()` 369786aefd0dSHong Zhang @*/ 3698d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumn(Mat A, PetscInt col, PetscScalar **vals) 3699d71ae5a4SJacob Faibussowitsch { 370086aefd0dSHong Zhang PetscFunctionBegin; 3701d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3702d5ea218eSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 37034f572ea9SToby Isaac PetscAssertPointer(vals, 3); 3704cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumn_C", (Mat, PetscInt, PetscScalar **), (A, col, vals)); 37053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 370686aefd0dSHong Zhang } 370786aefd0dSHong Zhang 370886aefd0dSHong Zhang /*@C 370911a5261eSBarry Smith MatDenseRestoreColumn - returns access to a column of a `MATDENSE` matrix which is returned by `MatDenseGetColumn()`. 371086aefd0dSHong Zhang 371186aefd0dSHong Zhang Not Collective 371286aefd0dSHong Zhang 3713742765d3SMatthew Knepley Input Parameters: 3714fe59aa6dSJacob Faibussowitsch + A - a `MATSEQDENSE` or `MATMPIDENSE` matrix 37152ef1f0ffSBarry Smith - vals - pointer to the data (may be `NULL`) 371686aefd0dSHong Zhang 371786aefd0dSHong Zhang Level: intermediate 371886aefd0dSHong Zhang 37191cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetColumn()` 372086aefd0dSHong Zhang @*/ 3721d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumn(Mat A, PetscScalar **vals) 3722d71ae5a4SJacob Faibussowitsch { 372386aefd0dSHong Zhang PetscFunctionBegin; 3724d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 37254f572ea9SToby Isaac PetscAssertPointer(vals, 2); 3726cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumn_C", (Mat, PetscScalar **), (A, vals)); 37273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 372886aefd0dSHong Zhang } 37296947451fSStefano Zampini 37300f74d2c1SSatish Balay /*@ 373111a5261eSBarry Smith MatDenseGetColumnVec - Gives read-write access to a column of a `MATDENSE` matrix, represented as a `Vec`. 37326947451fSStefano Zampini 37336947451fSStefano Zampini Collective 37346947451fSStefano Zampini 37355ea7661aSPierre Jolivet Input Parameters: 3736fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 37376947451fSStefano Zampini - col - the column index 37386947451fSStefano Zampini 37396947451fSStefano Zampini Output Parameter: 37406947451fSStefano Zampini . v - the vector 37416947451fSStefano Zampini 37422ef1f0ffSBarry Smith Level: intermediate 37432ef1f0ffSBarry Smith 37446947451fSStefano Zampini Notes: 374511a5261eSBarry Smith The vector is owned by PETSc. Users need to call `MatDenseRestoreColumnVec()` when the vector is no longer needed. 374611a5261eSBarry Smith 374711a5261eSBarry Smith Use `MatDenseGetColumnVecRead()` to obtain read-only access or `MatDenseGetColumnVecWrite()` for write-only access. 37486947451fSStefano Zampini 37491cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`, `MatDenseGetColumn()` 37506947451fSStefano Zampini @*/ 3751d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec(Mat A, PetscInt col, Vec *v) 3752d71ae5a4SJacob Faibussowitsch { 37536947451fSStefano Zampini PetscFunctionBegin; 37546947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 37556947451fSStefano Zampini PetscValidType(A, 1); 37566947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 37574f572ea9SToby Isaac PetscAssertPointer(v, 3); 375828b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 37592cf15c64SPierre 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); 3760cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v)); 37613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37626947451fSStefano Zampini } 37636947451fSStefano Zampini 37640f74d2c1SSatish Balay /*@ 3765fb850c59SBarry Smith MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from `MatDenseGetColumnVec()`. 37666947451fSStefano Zampini 37676947451fSStefano Zampini Collective 37686947451fSStefano Zampini 37695ea7661aSPierre Jolivet Input Parameters: 3770fb850c59SBarry Smith + A - the `Mat` object 37716947451fSStefano Zampini . col - the column index 3772fb850c59SBarry Smith - v - the `Vec` object (may be `NULL`) 37736947451fSStefano Zampini 37746947451fSStefano Zampini Level: intermediate 37756947451fSStefano Zampini 37761cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 37776947451fSStefano Zampini @*/ 3778d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec(Mat A, PetscInt col, Vec *v) 3779d71ae5a4SJacob Faibussowitsch { 37806947451fSStefano Zampini PetscFunctionBegin; 37816947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 37826947451fSStefano Zampini PetscValidType(A, 1); 37836947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 378408401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 37852cf15c64SPierre 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); 3786cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v)); 37873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37886947451fSStefano Zampini } 37896947451fSStefano Zampini 37900f74d2c1SSatish Balay /*@ 3791fb850c59SBarry Smith MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a `Vec`. 37926947451fSStefano Zampini 37936947451fSStefano Zampini Collective 37946947451fSStefano Zampini 37955ea7661aSPierre Jolivet Input Parameters: 3796fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 37976947451fSStefano Zampini - col - the column index 37986947451fSStefano Zampini 37996947451fSStefano Zampini Output Parameter: 38006947451fSStefano Zampini . v - the vector 38016947451fSStefano Zampini 38022ef1f0ffSBarry Smith Level: intermediate 38032ef1f0ffSBarry Smith 38046947451fSStefano Zampini Notes: 38056947451fSStefano Zampini The vector is owned by PETSc and users cannot modify it. 380611a5261eSBarry Smith 38072ef1f0ffSBarry Smith Users need to call `MatDenseRestoreColumnVecRead()` when the vector is no longer needed. 380811a5261eSBarry Smith 38092ef1f0ffSBarry Smith Use `MatDenseGetColumnVec()` to obtain read-write access or `MatDenseGetColumnVecWrite()` for write-only access. 38106947451fSStefano Zampini 38111cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 38126947451fSStefano Zampini @*/ 3813d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead(Mat A, PetscInt col, Vec *v) 3814d71ae5a4SJacob Faibussowitsch { 38156947451fSStefano Zampini PetscFunctionBegin; 38166947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38176947451fSStefano Zampini PetscValidType(A, 1); 38186947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 38194f572ea9SToby Isaac PetscAssertPointer(v, 3); 382028b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 38212cf15c64SPierre 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); 3822cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v)); 38233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38246947451fSStefano Zampini } 38256947451fSStefano Zampini 38260f74d2c1SSatish Balay /*@ 3827fb850c59SBarry Smith MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from `MatDenseGetColumnVecRead()`. 38286947451fSStefano Zampini 38296947451fSStefano Zampini Collective 38306947451fSStefano Zampini 38315ea7661aSPierre Jolivet Input Parameters: 3832fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 38336947451fSStefano Zampini . col - the column index 3834fb850c59SBarry Smith - v - the `Vec` object (may be `NULL`) 38356947451fSStefano Zampini 38366947451fSStefano Zampini Level: intermediate 38376947451fSStefano Zampini 38381cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecWrite()` 38396947451fSStefano Zampini @*/ 3840d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead(Mat A, PetscInt col, Vec *v) 3841d71ae5a4SJacob Faibussowitsch { 38426947451fSStefano Zampini PetscFunctionBegin; 38436947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38446947451fSStefano Zampini PetscValidType(A, 1); 38456947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 384608401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 38472cf15c64SPierre 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); 3848cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v)); 38493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38506947451fSStefano Zampini } 38516947451fSStefano Zampini 38520f74d2c1SSatish Balay /*@ 3853fb850c59SBarry Smith MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a `Vec`. 38546947451fSStefano Zampini 38556947451fSStefano Zampini Collective 38566947451fSStefano Zampini 38575ea7661aSPierre Jolivet Input Parameters: 3858fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 38596947451fSStefano Zampini - col - the column index 38606947451fSStefano Zampini 38616947451fSStefano Zampini Output Parameter: 38626947451fSStefano Zampini . v - the vector 38636947451fSStefano Zampini 38646947451fSStefano Zampini Level: intermediate 38656947451fSStefano Zampini 38662ef1f0ffSBarry Smith Notes: 38672ef1f0ffSBarry Smith The vector is owned by PETSc. Users need to call `MatDenseRestoreColumnVecWrite()` when the vector is no longer needed. 38682ef1f0ffSBarry Smith 38692ef1f0ffSBarry Smith Use `MatDenseGetColumnVec()` to obtain read-write access or `MatDenseGetColumnVecRead()` for read-only access. 38702ef1f0ffSBarry Smith 38711cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 38726947451fSStefano Zampini @*/ 3873d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite(Mat A, PetscInt col, Vec *v) 3874d71ae5a4SJacob Faibussowitsch { 38756947451fSStefano Zampini PetscFunctionBegin; 38766947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38776947451fSStefano Zampini PetscValidType(A, 1); 38786947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 38794f572ea9SToby Isaac PetscAssertPointer(v, 3); 388028b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3881aed4548fSBarry 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); 3882cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v)); 38833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38846947451fSStefano Zampini } 38856947451fSStefano Zampini 38860f74d2c1SSatish Balay /*@ 3887fb850c59SBarry Smith MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from `MatDenseGetColumnVecWrite()`. 38886947451fSStefano Zampini 38896947451fSStefano Zampini Collective 38906947451fSStefano Zampini 38915ea7661aSPierre Jolivet Input Parameters: 3892fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 38936947451fSStefano Zampini . col - the column index 38942ef1f0ffSBarry Smith - v - the `Vec` object (may be `NULL`) 38956947451fSStefano Zampini 38966947451fSStefano Zampini Level: intermediate 38976947451fSStefano Zampini 38981cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()` 38996947451fSStefano Zampini @*/ 3900d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A, PetscInt col, Vec *v) 3901d71ae5a4SJacob Faibussowitsch { 39026947451fSStefano Zampini PetscFunctionBegin; 39036947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 39046947451fSStefano Zampini PetscValidType(A, 1); 39056947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 390608401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3907aed4548fSBarry 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); 3908cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v)); 39093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 39106947451fSStefano Zampini } 39115ea7661aSPierre Jolivet 39120f74d2c1SSatish Balay /*@ 3913fb850c59SBarry Smith MatDenseGetSubMatrix - Gives access to a block of rows and columns of a dense matrix, represented as a `Mat`. 39145ea7661aSPierre Jolivet 39155ea7661aSPierre Jolivet Collective 39165ea7661aSPierre Jolivet 39175ea7661aSPierre Jolivet Input Parameters: 3918fb850c59SBarry Smith + A - the `Mat` object 39192ef1f0ffSBarry Smith . rbegin - the first global row index in the block (if `PETSC_DECIDE`, is 0) 39202ef1f0ffSBarry Smith . rend - the global row index past the last one in the block (if `PETSC_DECIDE`, is `M`) 39212ef1f0ffSBarry Smith . cbegin - the first global column index in the block (if `PETSC_DECIDE`, is 0) 39222ef1f0ffSBarry Smith - cend - the global column index past the last one in the block (if `PETSC_DECIDE`, is `N`) 39235ea7661aSPierre Jolivet 39245ea7661aSPierre Jolivet Output Parameter: 39255ea7661aSPierre Jolivet . v - the matrix 39265ea7661aSPierre Jolivet 39275ea7661aSPierre Jolivet Level: intermediate 39285ea7661aSPierre Jolivet 39292ef1f0ffSBarry Smith Notes: 39302ef1f0ffSBarry Smith The matrix is owned by PETSc. Users need to call `MatDenseRestoreSubMatrix()` when the matrix is no longer needed. 39312ef1f0ffSBarry Smith 39322ef1f0ffSBarry 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. 39332ef1f0ffSBarry Smith 39341cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreSubMatrix()` 39355ea7661aSPierre Jolivet @*/ 3936d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) 3937d71ae5a4SJacob Faibussowitsch { 39385ea7661aSPierre Jolivet PetscFunctionBegin; 39395ea7661aSPierre Jolivet PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 39405ea7661aSPierre Jolivet PetscValidType(A, 1); 3941a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, rbegin, 2); 3942a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, rend, 3); 3943a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, cbegin, 4); 3944a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, cend, 5); 39454f572ea9SToby Isaac PetscAssertPointer(v, 6); 3946a2748737SPierre Jolivet if (rbegin == PETSC_DECIDE) rbegin = 0; 3947a2748737SPierre Jolivet if (rend == PETSC_DECIDE) rend = A->rmap->N; 3948a2748737SPierre Jolivet if (cbegin == PETSC_DECIDE) cbegin = 0; 3949a2748737SPierre Jolivet if (cend == PETSC_DECIDE) cend = A->cmap->N; 395028b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3951a2748737SPierre 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); 3952a2748737SPierre 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); 3953a2748737SPierre 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); 3954a2748737SPierre 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); 3955a2748737SPierre Jolivet PetscUseMethod(A, "MatDenseGetSubMatrix_C", (Mat, PetscInt, PetscInt, PetscInt, PetscInt, Mat *), (A, rbegin, rend, cbegin, cend, v)); 39563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 39575ea7661aSPierre Jolivet } 39585ea7661aSPierre Jolivet 39590f74d2c1SSatish Balay /*@ 3960fb850c59SBarry Smith MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from `MatDenseGetSubMatrix()`. 39615ea7661aSPierre Jolivet 39625ea7661aSPierre Jolivet Collective 39635ea7661aSPierre Jolivet 39645ea7661aSPierre Jolivet Input Parameters: 3965fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 39662ef1f0ffSBarry Smith - v - the `Mat` object (may be `NULL`) 39675ea7661aSPierre Jolivet 39685ea7661aSPierre Jolivet Level: intermediate 39695ea7661aSPierre Jolivet 39701cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseGetSubMatrix()` 39715ea7661aSPierre Jolivet @*/ 3972d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix(Mat A, Mat *v) 3973d71ae5a4SJacob Faibussowitsch { 39745ea7661aSPierre Jolivet PetscFunctionBegin; 39755ea7661aSPierre Jolivet PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 39765ea7661aSPierre Jolivet PetscValidType(A, 1); 39774f572ea9SToby Isaac PetscAssertPointer(v, 2); 3978cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreSubMatrix_C", (Mat, Mat *), (A, v)); 39793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 39805ea7661aSPierre Jolivet } 39818a9c020eSBarry Smith 39828a9c020eSBarry Smith #include <petscblaslapack.h> 39838a9c020eSBarry Smith #include <petsc/private/kernels/blockinvert.h> 39848a9c020eSBarry Smith 3985d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseInvert(Mat A) 3986d71ae5a4SJacob Faibussowitsch { 3987d63b1753SJacob Faibussowitsch PetscInt m; 39888a9c020eSBarry Smith const PetscReal shift = 0.0; 3989d63b1753SJacob Faibussowitsch PetscBool allowzeropivot, zeropivotdetected = PETSC_FALSE; 3990d63b1753SJacob Faibussowitsch PetscScalar *values; 39918a9c020eSBarry Smith 39928a9c020eSBarry Smith PetscFunctionBegin; 3993d63b1753SJacob Faibussowitsch PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3994d63b1753SJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &values)); 3995d63b1753SJacob Faibussowitsch PetscCall(MatGetLocalSize(A, &m, NULL)); 3996d63b1753SJacob Faibussowitsch allowzeropivot = PetscNot(A->erroriffailure); 39978a9c020eSBarry Smith /* factor and invert each block */ 3998d63b1753SJacob Faibussowitsch switch (m) { 3999d71ae5a4SJacob Faibussowitsch case 1: 4000d71ae5a4SJacob Faibussowitsch values[0] = (PetscScalar)1.0 / (values[0] + shift); 4001d71ae5a4SJacob Faibussowitsch break; 40028a9c020eSBarry Smith case 2: 40038a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_2(values, shift, allowzeropivot, &zeropivotdetected)); 40048a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 40058a9c020eSBarry Smith break; 40068a9c020eSBarry Smith case 3: 40078a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_3(values, shift, allowzeropivot, &zeropivotdetected)); 40088a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 40098a9c020eSBarry Smith break; 40108a9c020eSBarry Smith case 4: 40118a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_4(values, shift, allowzeropivot, &zeropivotdetected)); 40128a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 40138a9c020eSBarry Smith break; 40149371c9d4SSatish Balay case 5: { 40158a9c020eSBarry Smith PetscScalar work[25]; 40168a9c020eSBarry Smith PetscInt ipvt[5]; 40178a9c020eSBarry Smith 40188a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_5(values, ipvt, work, shift, allowzeropivot, &zeropivotdetected)); 40198a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 40209371c9d4SSatish Balay } break; 40218a9c020eSBarry Smith case 6: 40228a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_6(values, shift, allowzeropivot, &zeropivotdetected)); 40238a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 40248a9c020eSBarry Smith break; 40258a9c020eSBarry Smith case 7: 40268a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_7(values, shift, allowzeropivot, &zeropivotdetected)); 40278a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 40288a9c020eSBarry Smith break; 40299371c9d4SSatish Balay default: { 40308a9c020eSBarry Smith PetscInt *v_pivots, *IJ, j; 40318a9c020eSBarry Smith PetscScalar *v_work; 40328a9c020eSBarry Smith 4033d63b1753SJacob Faibussowitsch PetscCall(PetscMalloc3(m, &v_work, m, &v_pivots, m, &IJ)); 4034d63b1753SJacob Faibussowitsch for (j = 0; j < m; j++) IJ[j] = j; 4035d63b1753SJacob Faibussowitsch PetscCall(PetscKernel_A_gets_inverse_A(m, values, v_pivots, v_work, allowzeropivot, &zeropivotdetected)); 40368a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 40378a9c020eSBarry Smith PetscCall(PetscFree3(v_work, v_pivots, IJ)); 40388a9c020eSBarry Smith } 40398a9c020eSBarry Smith } 4040d63b1753SJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &values)); 40413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 40428a9c020eSBarry Smith } 4043