167e560aaSBarry Smith /* 267e560aaSBarry Smith Defines the basic matrix operations for sequential dense. 347d993e7Ssuyashtn Portions of this code are under: 447d993e7Ssuyashtn Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved. 567e560aaSBarry Smith */ 6289bc588SBarry Smith 7dec5eb66SMatthew G Knepley #include <../src/mat/impls/dense/seq/dense.h> /*I "petscmat.h" I*/ 8cd3f9d89SJunchao Zhang #include <../src/mat/impls/dense/mpi/mpidense.h> 9c6db04a5SJed Brown #include <petscblaslapack.h> 106a63e612SBarry Smith #include <../src/mat/impls/aij/seq/aij.h> 114186a4bbSPierre Jolivet #include <petsc/private/vecimpl.h> 12b2573a8aSBarry Smith 13d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSymmetrize_Private(Mat A, PetscBool hermitian) 14d71ae5a4SJacob Faibussowitsch { 158c178816SStefano Zampini Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 168c178816SStefano Zampini PetscInt j, k, n = A->rmap->n; 17ca15aa20SStefano Zampini PetscScalar *v; 188c178816SStefano Zampini 198c178816SStefano Zampini PetscFunctionBegin; 2008401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Cannot symmetrize a rectangular matrix"); 219566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 228c178816SStefano Zampini if (!hermitian) { 238c178816SStefano Zampini for (k = 0; k < n; k++) { 24ad540459SPierre Jolivet for (j = k; j < n; j++) v[j * mat->lda + k] = v[k * mat->lda + j]; 258c178816SStefano Zampini } 268c178816SStefano Zampini } else { 278c178816SStefano Zampini for (k = 0; k < n; k++) { 28ad540459SPierre Jolivet for (j = k; j < n; j++) v[j * mat->lda + k] = PetscConj(v[k * mat->lda + j]); 298c178816SStefano Zampini } 308c178816SStefano Zampini } 319566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 338c178816SStefano Zampini } 348c178816SStefano Zampini 35ff6a9541SJacob Faibussowitsch PetscErrorCode MatSeqDenseInvertFactors_Private(Mat A) 36d71ae5a4SJacob Faibussowitsch { 378c178816SStefano Zampini Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 388c178816SStefano Zampini PetscBLASInt info, n; 398c178816SStefano Zampini 408c178816SStefano Zampini PetscFunctionBegin; 413ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 429566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 438c178816SStefano Zampini if (A->factortype == MAT_FACTOR_LU) { 4428b400f6SJacob Faibussowitsch PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present"); 458c178816SStefano Zampini if (!mat->fwork) { 468c178816SStefano Zampini mat->lfwork = n; 479566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 488c178816SStefano Zampini } 499566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 50792fecdfSBarry Smith PetscCallBLAS("LAPACKgetri", LAPACKgetri_(&n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info)); 519566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 529566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0)); 538c178816SStefano Zampini } else if (A->factortype == MAT_FACTOR_CHOLESKY) { 54b94d7dedSBarry Smith if (A->spd == PETSC_BOOL3_TRUE) { 559566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 56792fecdfSBarry Smith PetscCallBLAS("LAPACKpotri", LAPACKpotri_("L", &n, mat->v, &mat->lda, &info)); 579566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 589566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_TRUE)); 598c178816SStefano Zampini #if defined(PETSC_USE_COMPLEX) 60b94d7dedSBarry Smith } else if (A->hermitian == PETSC_BOOL3_TRUE) { 6128b400f6SJacob Faibussowitsch PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present"); 6228b400f6SJacob Faibussowitsch PetscCheck(mat->fwork, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Fwork not present"); 639566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 64792fecdfSBarry Smith PetscCallBLAS("LAPACKhetri", LAPACKhetri_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &info)); 659566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 669566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_TRUE)); 678c178816SStefano Zampini #endif 688c178816SStefano Zampini } else { /* symmetric case */ 6928b400f6SJacob Faibussowitsch PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present"); 7028b400f6SJacob Faibussowitsch PetscCheck(mat->fwork, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Fwork not present"); 719566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 72792fecdfSBarry Smith PetscCallBLAS("LAPACKsytri", LAPACKsytri_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &info)); 739566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 749566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_FALSE)); 758c178816SStefano Zampini } 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)); 388c956ced0SPierre Jolivet PetscCall(MatPropagateSymmetryOptions(A, newi)); 389b24902e0SBarry Smith } 3903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 391b24902e0SBarry Smith } 392b24902e0SBarry Smith 393d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDuplicate_SeqDense(Mat A, MatDuplicateOption cpvalues, Mat *newmat) 394d71ae5a4SJacob Faibussowitsch { 3953a40ed3dSBarry Smith PetscFunctionBegin; 3969566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), newmat)); 3979566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*newmat, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n)); 3989566063dSJacob Faibussowitsch PetscCall(MatSetType(*newmat, ((PetscObject)A)->type_name)); 3999566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(*newmat, A, cpvalues)); 4003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 401b24902e0SBarry Smith } 402b24902e0SBarry Smith 403d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_LU(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T) 404d71ae5a4SJacob Faibussowitsch { 405c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4064396437dSToby Isaac PetscBLASInt info; 40767e560aaSBarry Smith 4083a40ed3dSBarry Smith PetscFunctionBegin; 4099566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 410792fecdfSBarry Smith PetscCallBLAS("LAPACKgetrs", LAPACKgetrs_(T ? "T" : "N", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info)); 4119566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 41205fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "GETRS - Bad solve %d", (int)info); 4139566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m))); 4143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4154396437dSToby Isaac } 4164396437dSToby Isaac 4174396437dSToby Isaac static PetscErrorCode MatConjugate_SeqDense(Mat); 4184396437dSToby Isaac 419d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_Cholesky(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T) 420d71ae5a4SJacob Faibussowitsch { 4214396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4224396437dSToby Isaac PetscBLASInt info; 4234396437dSToby Isaac 4244396437dSToby Isaac PetscFunctionBegin; 425b94d7dedSBarry Smith if (A->spd == PETSC_BOOL3_TRUE) { 4269566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A)); 4279566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 428792fecdfSBarry Smith PetscCallBLAS("LAPACKpotrs", LAPACKpotrs_("L", &m, &nrhs, mat->v, &mat->lda, x, &m, &info)); 4299566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 43005fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "POTRS Bad solve %d", (int)info); 4319566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A)); 432a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX) 433b94d7dedSBarry Smith } else if (A->hermitian == PETSC_BOOL3_TRUE) { 4349566063dSJacob Faibussowitsch if (T) PetscCall(MatConjugate_SeqDense(A)); 4359566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 436792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrs", LAPACKhetrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info)); 4379566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 43805fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "HETRS Bad solve %d", (int)info); 4399566063dSJacob Faibussowitsch if (T) PetscCall(MatConjugate_SeqDense(A)); 440a49dc2a2SStefano Zampini #endif 441a49dc2a2SStefano Zampini } else { /* symmetric case */ 4429566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 443792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrs", LAPACKsytrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info)); 4449566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 44505fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "SYTRS Bad solve %d", (int)info); 446a49dc2a2SStefano Zampini } 4479566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m))); 4483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4494396437dSToby Isaac } 45085e2c93fSHong Zhang 451d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k) 452d71ae5a4SJacob Faibussowitsch { 4534396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4544396437dSToby Isaac PetscBLASInt info; 4554396437dSToby Isaac char trans; 4564396437dSToby Isaac 4574396437dSToby Isaac PetscFunctionBegin; 4584905a7bcSToby Isaac if (PetscDefined(USE_COMPLEX)) { 4594905a7bcSToby Isaac trans = 'C'; 4604905a7bcSToby Isaac } else { 4614905a7bcSToby Isaac trans = 'T'; 4624905a7bcSToby Isaac } 4639566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 46405fcb23eSStefano Zampini { /* lwork depends on the number of right-hand sides */ 46505fcb23eSStefano Zampini PetscBLASInt nlfwork, lfwork = -1; 46605fcb23eSStefano Zampini PetscScalar fwork; 46705fcb23eSStefano Zampini 468792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info)); 46905fcb23eSStefano Zampini nlfwork = (PetscBLASInt)PetscRealPart(fwork); 47005fcb23eSStefano Zampini if (nlfwork > mat->lfwork) { 47105fcb23eSStefano Zampini mat->lfwork = nlfwork; 47205fcb23eSStefano Zampini PetscCall(PetscFree(mat->fwork)); 47305fcb23eSStefano Zampini PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 47405fcb23eSStefano Zampini } 47505fcb23eSStefano Zampini } 476792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info)); 4779566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 47805fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %d", (int)info); 4799566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 480792fecdfSBarry Smith PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "N", "N", &mat->rank, &nrhs, mat->v, &mat->lda, x, &ldx, &info)); 4819566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 48205fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %d", (int)info); 4834905a7bcSToby Isaac for (PetscInt j = 0; j < nrhs; j++) { 484ad540459SPierre Jolivet for (PetscInt i = mat->rank; i < k; i++) x[j * ldx + i] = 0.; 4854905a7bcSToby Isaac } 4869566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank)))); 4873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4884905a7bcSToby Isaac } 4894905a7bcSToby Isaac 490d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k) 491d71ae5a4SJacob Faibussowitsch { 4924396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4934396437dSToby Isaac PetscBLASInt info; 4944396437dSToby Isaac 4954396437dSToby Isaac PetscFunctionBegin; 4964396437dSToby Isaac if (A->rmap->n == A->cmap->n && mat->rank == A->rmap->n) { 4979566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 498792fecdfSBarry Smith PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "T", "N", &m, &nrhs, mat->v, &mat->lda, x, &ldx, &info)); 4999566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 50005fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %d", (int)info); 5019566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A)); 50205fcb23eSStefano Zampini { /* lwork depends on the number of right-hand sides */ 50305fcb23eSStefano Zampini PetscBLASInt nlfwork, lfwork = -1; 50405fcb23eSStefano Zampini PetscScalar fwork; 50505fcb23eSStefano Zampini 506792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info)); 50705fcb23eSStefano Zampini nlfwork = (PetscBLASInt)PetscRealPart(fwork); 50805fcb23eSStefano Zampini if (nlfwork > mat->lfwork) { 50905fcb23eSStefano Zampini mat->lfwork = nlfwork; 51005fcb23eSStefano Zampini PetscCall(PetscFree(mat->fwork)); 51105fcb23eSStefano Zampini PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 51205fcb23eSStefano Zampini } 51305fcb23eSStefano Zampini } 5149566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 515792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info)); 5169566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 51705fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %d", (int)info); 5189566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A)); 5194396437dSToby Isaac } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "QR factored matrix cannot be used for transpose solve"); 5209566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank)))); 5213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5224396437dSToby Isaac } 5234396437dSToby Isaac 524d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_SetUp(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k) 525d71ae5a4SJacob Faibussowitsch { 5264396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 5274905a7bcSToby Isaac PetscScalar *y; 5284905a7bcSToby Isaac PetscBLASInt m = 0, k = 0; 5294905a7bcSToby Isaac 5304905a7bcSToby Isaac PetscFunctionBegin; 5319566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 5329566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 5334905a7bcSToby Isaac if (k < m) { 5349566063dSJacob Faibussowitsch PetscCall(VecCopy(xx, mat->qrrhs)); 5359566063dSJacob Faibussowitsch PetscCall(VecGetArray(mat->qrrhs, &y)); 5364905a7bcSToby Isaac } else { 5379566063dSJacob Faibussowitsch PetscCall(VecCopy(xx, yy)); 5389566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &y)); 5394905a7bcSToby Isaac } 5404396437dSToby Isaac *_y = y; 5414396437dSToby Isaac *_k = k; 5424396437dSToby Isaac *_m = m; 5433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5444396437dSToby Isaac } 5454396437dSToby Isaac 546d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_TearDown(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k) 547d71ae5a4SJacob Faibussowitsch { 5484396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 54942e9364cSSatish Balay PetscScalar *y = NULL; 5504396437dSToby Isaac PetscBLASInt m, k; 5514396437dSToby Isaac 5524396437dSToby Isaac PetscFunctionBegin; 5534396437dSToby Isaac y = *_y; 5544396437dSToby Isaac *_y = NULL; 5554396437dSToby Isaac k = *_k; 5564396437dSToby Isaac m = *_m; 5574905a7bcSToby Isaac if (k < m) { 5584905a7bcSToby Isaac PetscScalar *yv; 5599566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &yv)); 5609566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(yv, y, k)); 5619566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &yv)); 5629566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(mat->qrrhs, &y)); 5634905a7bcSToby Isaac } else { 5649566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &y)); 5654905a7bcSToby Isaac } 5663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5674905a7bcSToby Isaac } 5684905a7bcSToby Isaac 569d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_LU(Mat A, Vec xx, Vec yy) 570d71ae5a4SJacob Faibussowitsch { 57142e9364cSSatish Balay PetscScalar *y = NULL; 57242e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 5734396437dSToby Isaac 5744396437dSToby Isaac PetscFunctionBegin; 5759566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 5769566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_FALSE)); 5779566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 5783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5794396437dSToby Isaac } 5804396437dSToby Isaac 581d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_LU(Mat A, Vec xx, Vec yy) 582d71ae5a4SJacob Faibussowitsch { 58342e9364cSSatish Balay PetscScalar *y = NULL; 58442e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 5854396437dSToby Isaac 5864396437dSToby Isaac PetscFunctionBegin; 5879566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 5889566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_TRUE)); 5899566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 5903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5914396437dSToby Isaac } 5924396437dSToby Isaac 593d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Cholesky(Mat A, Vec xx, Vec yy) 594d71ae5a4SJacob Faibussowitsch { 595e54beecaSStefano Zampini PetscScalar *y = NULL; 596e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 5974396437dSToby Isaac 5984396437dSToby Isaac PetscFunctionBegin; 5999566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6009566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_FALSE)); 6019566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6034396437dSToby Isaac } 6044396437dSToby Isaac 605d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_Cholesky(Mat A, Vec xx, Vec yy) 606d71ae5a4SJacob Faibussowitsch { 607e54beecaSStefano Zampini PetscScalar *y = NULL; 608e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 6094396437dSToby Isaac 6104396437dSToby Isaac PetscFunctionBegin; 6119566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6129566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_TRUE)); 6139566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6154396437dSToby Isaac } 6164396437dSToby Isaac 617d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_QR(Mat A, Vec xx, Vec yy) 618d71ae5a4SJacob Faibussowitsch { 619e54beecaSStefano Zampini PetscScalar *y = NULL; 620e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 6214396437dSToby Isaac 6224396437dSToby Isaac PetscFunctionBegin; 6239566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6249566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k)); 6259566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6274396437dSToby Isaac } 6284396437dSToby Isaac 629d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_QR(Mat A, Vec xx, Vec yy) 630d71ae5a4SJacob Faibussowitsch { 63142e9364cSSatish Balay PetscScalar *y = NULL; 63242e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 6334396437dSToby Isaac 6344396437dSToby Isaac PetscFunctionBegin; 6359566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6369566063dSJacob Faibussowitsch PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k)); 6379566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6394396437dSToby Isaac } 6404396437dSToby Isaac 641d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_SetUp(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k) 642d71ae5a4SJacob Faibussowitsch { 6434905a7bcSToby Isaac const PetscScalar *b; 6444396437dSToby Isaac PetscScalar *y; 645bf5a80bcSToby Isaac PetscInt n, _ldb, _ldx; 646bf5a80bcSToby Isaac PetscBLASInt nrhs = 0, m = 0, k = 0, ldb = 0, ldx = 0, ldy = 0; 6474905a7bcSToby Isaac 6484905a7bcSToby Isaac PetscFunctionBegin; 6499371c9d4SSatish Balay *_ldy = 0; 6509371c9d4SSatish Balay *_m = 0; 6519371c9d4SSatish Balay *_nrhs = 0; 6529371c9d4SSatish Balay *_k = 0; 6539371c9d4SSatish Balay *_y = NULL; 6549566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 6559566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 6569566063dSJacob Faibussowitsch PetscCall(MatGetSize(B, NULL, &n)); 6579566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(n, &nrhs)); 6589566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(B, &_ldb)); 6599566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldb, &ldb)); 6609566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(X, &_ldx)); 6619566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldx, &ldx)); 662bf5a80bcSToby Isaac if (ldx < m) { 6639566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &b)); 6649566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nrhs * m, &y)); 665bf5a80bcSToby Isaac if (ldb == m) { 6669566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(y, b, ldb * nrhs)); 6674905a7bcSToby Isaac } else { 66848a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * m], &b[j * ldb], m)); 6694905a7bcSToby Isaac } 670bf5a80bcSToby Isaac ldy = m; 6719566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &b)); 6724905a7bcSToby Isaac } else { 673bf5a80bcSToby Isaac if (ldb == ldx) { 6749566063dSJacob Faibussowitsch PetscCall(MatCopy(B, X, SAME_NONZERO_PATTERN)); 6759566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &y)); 6764905a7bcSToby Isaac } else { 6779566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &y)); 6789566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &b)); 67948a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * ldx], &b[j * ldb], m)); 6809566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &b)); 6814905a7bcSToby Isaac } 682bf5a80bcSToby Isaac ldy = ldx; 6834905a7bcSToby Isaac } 6844396437dSToby Isaac *_y = y; 685bf5a80bcSToby Isaac *_ldy = ldy; 6864396437dSToby Isaac *_k = k; 6874396437dSToby Isaac *_m = m; 6884396437dSToby Isaac *_nrhs = nrhs; 6893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6904396437dSToby Isaac } 6914396437dSToby Isaac 692d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_TearDown(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k) 693d71ae5a4SJacob Faibussowitsch { 6944396437dSToby Isaac PetscScalar *y; 695bf5a80bcSToby Isaac PetscInt _ldx; 696bf5a80bcSToby Isaac PetscBLASInt k, ldy, nrhs, ldx = 0; 6974396437dSToby Isaac 6984396437dSToby Isaac PetscFunctionBegin; 6994396437dSToby Isaac y = *_y; 7004396437dSToby Isaac *_y = NULL; 7014396437dSToby Isaac k = *_k; 702bf5a80bcSToby Isaac ldy = *_ldy; 7034396437dSToby Isaac nrhs = *_nrhs; 7049566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(X, &_ldx)); 7059566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldx, &ldx)); 706bf5a80bcSToby Isaac if (ldx != ldy) { 7074905a7bcSToby Isaac PetscScalar *xv; 7089566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &xv)); 70948a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&xv[j * ldx], &y[j * ldy], k)); 7109566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(X, &xv)); 7119566063dSJacob Faibussowitsch PetscCall(PetscFree(y)); 7124905a7bcSToby Isaac } else { 7139566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(X, &y)); 7144905a7bcSToby Isaac } 7153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 71685e2c93fSHong Zhang } 71785e2c93fSHong Zhang 718d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_LU(Mat A, Mat B, Mat X) 719d71ae5a4SJacob Faibussowitsch { 7204396437dSToby Isaac PetscScalar *y; 721bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7224396437dSToby Isaac 7234396437dSToby Isaac PetscFunctionBegin; 7249566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7259566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_FALSE)); 7269566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7284396437dSToby Isaac } 7294396437dSToby Isaac 730d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_LU(Mat A, Mat B, Mat X) 731d71ae5a4SJacob Faibussowitsch { 7324396437dSToby Isaac PetscScalar *y; 733bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7344396437dSToby Isaac 7354396437dSToby Isaac PetscFunctionBegin; 7369566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7379566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_TRUE)); 7389566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7404396437dSToby Isaac } 7414396437dSToby Isaac 742d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_Cholesky(Mat A, Mat B, Mat X) 743d71ae5a4SJacob Faibussowitsch { 7444396437dSToby Isaac PetscScalar *y; 745bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7464396437dSToby Isaac 7474396437dSToby Isaac PetscFunctionBegin; 7489566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7499566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_FALSE)); 7509566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7524396437dSToby Isaac } 7534396437dSToby Isaac 754d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_Cholesky(Mat A, Mat B, Mat X) 755d71ae5a4SJacob Faibussowitsch { 7564396437dSToby Isaac PetscScalar *y; 757bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7584396437dSToby Isaac 7594396437dSToby Isaac PetscFunctionBegin; 7609566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7619566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_TRUE)); 7629566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7644396437dSToby Isaac } 7654396437dSToby Isaac 766d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_QR(Mat A, Mat B, Mat X) 767d71ae5a4SJacob Faibussowitsch { 7684396437dSToby Isaac PetscScalar *y; 769bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7704396437dSToby Isaac 7714396437dSToby Isaac PetscFunctionBegin; 7729566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7739566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k)); 7749566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7764396437dSToby Isaac } 7774396437dSToby Isaac 778d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_QR(Mat A, Mat B, Mat X) 779d71ae5a4SJacob Faibussowitsch { 7804396437dSToby Isaac PetscScalar *y; 781bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7824396437dSToby Isaac 7834396437dSToby Isaac PetscFunctionBegin; 7849566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7859566063dSJacob Faibussowitsch PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k)); 7869566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7884396437dSToby Isaac } 7894396437dSToby Isaac 790db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots, 791db4efbfdSBarry Smith rather than put it in the Mat->row slot.*/ 792d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLUFactor_SeqDense(Mat A, IS row, IS col, const MatFactorInfo *minfo) 793d71ae5a4SJacob Faibussowitsch { 794db4efbfdSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 795db4efbfdSBarry Smith PetscBLASInt n, m, info; 796db4efbfdSBarry Smith 797db4efbfdSBarry Smith PetscFunctionBegin; 7989566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 7999566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 8004dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); } 8013ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 8029566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 803792fecdfSBarry Smith PetscCallBLAS("LAPACKgetrf", LAPACKgetrf_(&m, &n, mat->v, &mat->lda, mat->pivots, &info)); 8049566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 8058e57ea43SSatish Balay 80605fcb23eSStefano Zampini PetscCheck(info >= 0, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to LU factorization %d", (int)info); 80705fcb23eSStefano Zampini PetscCheck(info <= 0, PETSC_COMM_SELF, PETSC_ERR_MAT_LU_ZRPVT, "Bad LU factorization %d", (int)info); 8088208b9aeSStefano Zampini 8094396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_LU; 8104396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_LU; 8114396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_LU; 8124396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_LU; 813d5f3da31SBarry Smith A->factortype = MAT_FACTOR_LU; 814db4efbfdSBarry Smith 8159566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 8169566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 817f6224b95SHong Zhang 8189566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((2.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3)); 8193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 820db4efbfdSBarry Smith } 821db4efbfdSBarry Smith 822d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) 823d71ae5a4SJacob Faibussowitsch { 8244396437dSToby Isaac MatFactorInfo info; 8254396437dSToby Isaac 8264396437dSToby Isaac PetscFunctionBegin; 8279566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 828dbbe0bcdSBarry Smith PetscUseTypeMethod(fact, lufactor, NULL, NULL, &info); 8293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8304396437dSToby Isaac } 8314396437dSToby Isaac 832d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, IS col, const MatFactorInfo *info) 833d71ae5a4SJacob Faibussowitsch { 8344396437dSToby Isaac PetscFunctionBegin; 8354396437dSToby Isaac fact->preallocated = PETSC_TRUE; 8364396437dSToby Isaac fact->assembled = PETSC_TRUE; 8374396437dSToby Isaac fact->ops->lufactornumeric = MatLUFactorNumeric_SeqDense; 8383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8394396437dSToby Isaac } 8404396437dSToby Isaac 841a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */ 842d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCholeskyFactor_SeqDense(Mat A, IS perm, const MatFactorInfo *factinfo) 843d71ae5a4SJacob Faibussowitsch { 844db4efbfdSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 845c5df96a5SBarry Smith PetscBLASInt info, n; 846db4efbfdSBarry Smith 847db4efbfdSBarry Smith PetscFunctionBegin; 8489566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 8493ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 850b94d7dedSBarry Smith if (A->spd == PETSC_BOOL3_TRUE) { 8519566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 852792fecdfSBarry Smith PetscCallBLAS("LAPACKpotrf", LAPACKpotrf_("L", &n, mat->v, &mat->lda, &info)); 8539566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 854a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX) 855b94d7dedSBarry Smith } else if (A->hermitian == PETSC_BOOL3_TRUE) { 8564dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); } 857a49dc2a2SStefano Zampini if (!mat->fwork) { 858a49dc2a2SStefano Zampini PetscScalar dummy; 859a49dc2a2SStefano Zampini 860a49dc2a2SStefano Zampini mat->lfwork = -1; 8619566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 862792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info)); 8639566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 86407c83e99SJose E. Roman PetscCall(PetscBLASIntCast((PetscCount)(PetscRealPart(dummy)), &mat->lfwork)); 8659566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 866a49dc2a2SStefano Zampini } 8679566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 868792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info)); 8699566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 870a49dc2a2SStefano Zampini #endif 871a49dc2a2SStefano Zampini } else { /* symmetric case */ 8724dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); } 873a49dc2a2SStefano Zampini if (!mat->fwork) { 874a49dc2a2SStefano Zampini PetscScalar dummy; 875a49dc2a2SStefano Zampini 876a49dc2a2SStefano Zampini mat->lfwork = -1; 8779566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 878792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info)); 8799566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 8806497c311SBarry Smith PetscCall(PetscBLASIntCast((PetscCount)(PetscRealPart(dummy)), &mat->lfwork)); 8819566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 882a49dc2a2SStefano Zampini } 8839566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 884792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info)); 8859566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 886a49dc2a2SStefano Zampini } 88728b400f6SJacob Faibussowitsch PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad factorization: zero pivot in row %" PetscInt_FMT, (PetscInt)info - 1); 8888208b9aeSStefano Zampini 8894396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_Cholesky; 8904396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_Cholesky; 8914396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_Cholesky; 8924396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_Cholesky; 893d5f3da31SBarry Smith A->factortype = MAT_FACTOR_CHOLESKY; 8942205254eSKarl Rupp 8959566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 8969566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 897f6224b95SHong Zhang 8989566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0)); 8993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 900db4efbfdSBarry Smith } 901db4efbfdSBarry Smith 902d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) 903d71ae5a4SJacob Faibussowitsch { 904db4efbfdSBarry Smith MatFactorInfo info; 905db4efbfdSBarry Smith 906db4efbfdSBarry Smith PetscFunctionBegin; 907db4efbfdSBarry Smith info.fill = 1.0; 9082205254eSKarl Rupp 9099566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 910dbbe0bcdSBarry Smith PetscUseTypeMethod(fact, choleskyfactor, NULL, &info); 9113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 912db4efbfdSBarry Smith } 913db4efbfdSBarry Smith 914d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info) 915d71ae5a4SJacob Faibussowitsch { 916db4efbfdSBarry Smith PetscFunctionBegin; 917c3ef05f6SHong Zhang fact->assembled = PETSC_TRUE; 9181bbcc794SSatish Balay fact->preallocated = PETSC_TRUE; 919719d5645SBarry Smith fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense; 9203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 921db4efbfdSBarry Smith } 922db4efbfdSBarry Smith 923d71ae5a4SJacob Faibussowitsch PetscErrorCode MatQRFactor_SeqDense(Mat A, IS col, const MatFactorInfo *minfo) 924d71ae5a4SJacob Faibussowitsch { 9254905a7bcSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 9264905a7bcSToby Isaac PetscBLASInt n, m, info, min, max; 9274905a7bcSToby Isaac 9284905a7bcSToby Isaac PetscFunctionBegin; 9299566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 9309566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 9314396437dSToby Isaac max = PetscMax(m, n); 9324396437dSToby Isaac min = PetscMin(m, n); 9334dfa11a4SJacob Faibussowitsch if (!mat->tau) { PetscCall(PetscMalloc1(min, &mat->tau)); } 9344dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(n, &mat->pivots)); } 935f4f49eeaSPierre Jolivet if (!mat->qrrhs) PetscCall(MatCreateVecs(A, NULL, &mat->qrrhs)); 9363ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 9374905a7bcSToby Isaac if (!mat->fwork) { 9384905a7bcSToby Isaac PetscScalar dummy; 9394905a7bcSToby Isaac 9404905a7bcSToby Isaac mat->lfwork = -1; 9419566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 942792fecdfSBarry Smith PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, &dummy, &mat->lfwork, &info)); 9439566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 9446497c311SBarry Smith PetscCall(PetscBLASIntCast((PetscCount)(PetscRealPart(dummy)), &mat->lfwork)); 9459566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 9464905a7bcSToby Isaac } 9479566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 948792fecdfSBarry Smith PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, mat->fwork, &mat->lfwork, &info)); 9499566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 95005fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to QR factorization %d", (int)info); 9514905a7bcSToby 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 9524905a7bcSToby Isaac mat->rank = min; 9534905a7bcSToby Isaac 9544396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_QR; 9554396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_QR; 9564905a7bcSToby Isaac A->factortype = MAT_FACTOR_QR; 9574905a7bcSToby Isaac if (m == n) { 9584396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_QR; 9594396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_QR; 9604905a7bcSToby Isaac } 9614905a7bcSToby Isaac 9629566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 9639566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 9644905a7bcSToby Isaac 9659566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * min * min * (max - min / 3.0))); 9663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9674905a7bcSToby Isaac } 9684905a7bcSToby Isaac 969d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatQRFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) 970d71ae5a4SJacob Faibussowitsch { 9714905a7bcSToby Isaac MatFactorInfo info; 9724905a7bcSToby Isaac 9734905a7bcSToby Isaac PetscFunctionBegin; 9744905a7bcSToby Isaac info.fill = 1.0; 9754905a7bcSToby Isaac 9769566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 977cac4c232SBarry Smith PetscUseMethod(fact, "MatQRFactor_C", (Mat, IS, const MatFactorInfo *), (fact, NULL, &info)); 9783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9794905a7bcSToby Isaac } 9804905a7bcSToby Isaac 981d71ae5a4SJacob Faibussowitsch PetscErrorCode MatQRFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info) 982d71ae5a4SJacob Faibussowitsch { 9834905a7bcSToby Isaac PetscFunctionBegin; 9844905a7bcSToby Isaac fact->assembled = PETSC_TRUE; 9854905a7bcSToby Isaac fact->preallocated = PETSC_TRUE; 9869566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)fact, "MatQRFactorNumeric_C", MatQRFactorNumeric_SeqDense)); 9873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9884905a7bcSToby Isaac } 9894905a7bcSToby Isaac 990ca15aa20SStefano Zampini /* uses LAPACK */ 991d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A, MatFactorType ftype, Mat *fact) 992d71ae5a4SJacob Faibussowitsch { 993db4efbfdSBarry Smith PetscFunctionBegin; 9949566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), fact)); 9959566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*fact, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n)); 9969566063dSJacob Faibussowitsch PetscCall(MatSetType(*fact, MATDENSE)); 99766e17bc3SBarry Smith (*fact)->trivialsymbolic = PETSC_TRUE; 9982a350339SBarry Smith if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU) { 999db4efbfdSBarry Smith (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense; 10002a350339SBarry Smith (*fact)->ops->ilufactorsymbolic = MatLUFactorSymbolic_SeqDense; 1001bf5a80bcSToby Isaac } else if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) { 1002db4efbfdSBarry Smith (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense; 1003bf5a80bcSToby Isaac } else if (ftype == MAT_FACTOR_QR) { 1004f4f49eeaSPierre Jolivet PetscCall(PetscObjectComposeFunction((PetscObject)*fact, "MatQRFactorSymbolic_C", MatQRFactorSymbolic_SeqDense)); 1005db4efbfdSBarry Smith } 1006d5f3da31SBarry Smith (*fact)->factortype = ftype; 100700c67f3bSHong Zhang 10089566063dSJacob Faibussowitsch PetscCall(PetscFree((*fact)->solvertype)); 10099566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &(*fact)->solvertype)); 10109566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_LU])); 10119566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ILU])); 10129566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_CHOLESKY])); 10139566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ICC])); 10143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1015db4efbfdSBarry Smith } 1016db4efbfdSBarry Smith 1017d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSOR_SeqDense(Mat A, Vec bb, PetscReal omega, MatSORType flag, PetscReal shift, PetscInt its, PetscInt lits, Vec xx) 1018d71ae5a4SJacob Faibussowitsch { 1019c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1020d9ca1df4SBarry Smith PetscScalar *x, *v = mat->v, zero = 0.0, xt; 1021d9ca1df4SBarry Smith const PetscScalar *b; 1022d0f46423SBarry Smith PetscInt m = A->rmap->n, i; 102323fff9afSBarry Smith PetscBLASInt o = 1, bm = 0; 1024289bc588SBarry Smith 10253a40ed3dSBarry Smith PetscFunctionBegin; 102647d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 102708401ef6SPierre Jolivet PetscCheck(A->offloadmask != PETSC_OFFLOAD_GPU, PETSC_COMM_SELF, PETSC_ERR_SUP, "Not implemented"); 1028ca15aa20SStefano Zampini #endif 1029422a814eSBarry Smith if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */ 10309566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(m, &bm)); 1031289bc588SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 10323bffc371SBarry Smith /* this is a hack fix, should have another version without the second BLASdotu */ 10339566063dSJacob Faibussowitsch PetscCall(VecSet(xx, zero)); 1034289bc588SBarry Smith } 10359566063dSJacob Faibussowitsch PetscCall(VecGetArray(xx, &x)); 10369566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(bb, &b)); 1037b965ef7fSBarry Smith its = its * lits; 103808401ef6SPierre 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); 1039289bc588SBarry Smith while (its--) { 1040fccaa45eSBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 1041289bc588SBarry Smith for (i = 0; i < m; i++) { 1042792fecdfSBarry Smith PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o)); 104355a1b374SBarry Smith x[i] = (1. - omega) * x[i] + omega * (xt + v[i + i * m] * x[i]) / (v[i + i * m] + shift); 1044289bc588SBarry Smith } 1045289bc588SBarry Smith } 1046fccaa45eSBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 1047289bc588SBarry Smith for (i = m - 1; i >= 0; i--) { 1048792fecdfSBarry Smith PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o)); 104955a1b374SBarry Smith x[i] = (1. - omega) * x[i] + omega * (xt + v[i + i * m] * x[i]) / (v[i + i * m] + shift); 1050289bc588SBarry Smith } 1051289bc588SBarry Smith } 1052289bc588SBarry Smith } 10539566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(bb, &b)); 10549566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(xx, &x)); 10553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1056289bc588SBarry Smith } 1057289bc588SBarry Smith 10580be0d8bdSHansol Suh static PetscErrorCode MatMultColumnRangeKernel_SeqDense(Mat A, Vec xx, Vec yy, PetscInt c_start, PetscInt c_end, PetscBool trans, PetscBool herm) 1059d71ae5a4SJacob Faibussowitsch { 1060c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1061d9ca1df4SBarry Smith PetscScalar *y, _DOne = 1.0, _DZero = 0.0; 10620805154bSBarry Smith PetscBLASInt m, n, _One = 1; 1063d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 10643a40ed3dSBarry Smith 10653a40ed3dSBarry Smith PetscFunctionBegin; 10669566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 10670be0d8bdSHansol Suh PetscCall(PetscBLASIntCast(c_end - c_start, &n)); 10689566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 10699566063dSJacob Faibussowitsch PetscCall(VecGetArrayWrite(yy, &y)); 10700be0d8bdSHansol Suh if (!m || !n) { 10715ac36cfcSBarry Smith PetscBLASInt i; 1072459e8d23SBlanca Mellado Pinto if (trans) 1073459e8d23SBlanca Mellado Pinto for (i = 0; i < n; i++) y[i] = 0.0; 1074459e8d23SBlanca Mellado Pinto else 10755ac36cfcSBarry Smith for (i = 0; i < m; i++) y[i] = 0.0; 10765ac36cfcSBarry Smith } else { 1077459e8d23SBlanca Mellado Pinto if (trans) { 10780be0d8bdSHansol Suh if (herm) PetscCallBLAS("BLASgemv", BLASgemv_("C", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x, &_One, &_DZero, y + c_start, &_One)); 10790be0d8bdSHansol Suh else PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x, &_One, &_DZero, y + c_start, &_One)); 1080459e8d23SBlanca Mellado Pinto } else { 10810be0d8bdSHansol Suh PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x + c_start, &_One, &_DZero, y, &_One)); 1082459e8d23SBlanca Mellado Pinto } 10830be0d8bdSHansol Suh PetscCall(PetscLogFlops(2.0 * m * n - n)); 10845ac36cfcSBarry Smith } 10859566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 10869566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayWrite(yy, &y)); 10873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1088289bc588SBarry Smith } 10896ee01492SSatish Balay 10900be0d8bdSHansol Suh PetscErrorCode MatMultHermitianTransposeColumnRange_SeqDense(Mat A, Vec xx, Vec yy, PetscInt c_start, PetscInt c_end) 10910be0d8bdSHansol Suh { 10920be0d8bdSHansol Suh PetscFunctionBegin; 10930be0d8bdSHansol Suh PetscCall(MatMultColumnRangeKernel_SeqDense(A, xx, yy, c_start, c_end, PETSC_TRUE, PETSC_TRUE)); 10940be0d8bdSHansol Suh PetscFunctionReturn(PETSC_SUCCESS); 10950be0d8bdSHansol Suh } 10960be0d8bdSHansol Suh 1097459e8d23SBlanca Mellado Pinto PetscErrorCode MatMult_SeqDense(Mat A, Vec xx, Vec yy) 1098459e8d23SBlanca Mellado Pinto { 1099459e8d23SBlanca Mellado Pinto PetscFunctionBegin; 11000be0d8bdSHansol Suh PetscCall(MatMultColumnRangeKernel_SeqDense(A, xx, yy, 0, A->cmap->n, PETSC_FALSE, PETSC_FALSE)); 1101459e8d23SBlanca Mellado Pinto PetscFunctionReturn(PETSC_SUCCESS); 1102459e8d23SBlanca Mellado Pinto } 1103459e8d23SBlanca Mellado Pinto 1104459e8d23SBlanca Mellado Pinto PetscErrorCode MatMultTranspose_SeqDense(Mat A, Vec xx, Vec yy) 1105459e8d23SBlanca Mellado Pinto { 1106459e8d23SBlanca Mellado Pinto PetscFunctionBegin; 11070be0d8bdSHansol Suh PetscCall(MatMultColumnRangeKernel_SeqDense(A, xx, yy, 0, A->cmap->n, PETSC_TRUE, PETSC_FALSE)); 1108459e8d23SBlanca Mellado Pinto PetscFunctionReturn(PETSC_SUCCESS); 1109459e8d23SBlanca Mellado Pinto } 1110459e8d23SBlanca Mellado Pinto 1111459e8d23SBlanca Mellado Pinto PetscErrorCode MatMultHermitianTranspose_SeqDense(Mat A, Vec xx, Vec yy) 1112459e8d23SBlanca Mellado Pinto { 1113459e8d23SBlanca Mellado Pinto PetscFunctionBegin; 11140be0d8bdSHansol Suh PetscCall(MatMultColumnRangeKernel_SeqDense(A, xx, yy, 0, A->cmap->n, PETSC_TRUE, PETSC_TRUE)); 1115459e8d23SBlanca Mellado Pinto PetscFunctionReturn(PETSC_SUCCESS); 1116459e8d23SBlanca Mellado Pinto } 1117459e8d23SBlanca Mellado Pinto 11180be0d8bdSHansol Suh static PetscErrorCode MatMultAddColumnRangeKernel_SeqDense(Mat A, Vec xx, Vec zz, Vec yy, PetscInt c_start, PetscInt c_end, PetscBool trans, PetscBool herm) 1119d71ae5a4SJacob Faibussowitsch { 1120c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1121d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 1122d9ca1df4SBarry Smith PetscScalar *y, _DOne = 1.0; 11230805154bSBarry Smith PetscBLASInt m, n, _One = 1; 11243a40ed3dSBarry Smith 11253a40ed3dSBarry Smith PetscFunctionBegin; 11269566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 11270be0d8bdSHansol Suh PetscCall(PetscBLASIntCast(c_end - c_start, &n)); 11289566063dSJacob Faibussowitsch PetscCall(VecCopy(zz, yy)); 11290be0d8bdSHansol Suh if (!m || !n) PetscFunctionReturn(PETSC_SUCCESS); 11309566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &y)); 1131459e8d23SBlanca Mellado Pinto PetscCall(VecGetArrayRead(xx, &x)); 1132459e8d23SBlanca Mellado Pinto if (trans) { 11330be0d8bdSHansol Suh if (herm) PetscCallBLAS("BLASgemv", BLASgemv_("C", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x, &_One, &_DOne, y + c_start, &_One)); 11340be0d8bdSHansol Suh else PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x, &_One, &_DOne, y + c_start, &_One)); 1135459e8d23SBlanca Mellado Pinto } else { 11360be0d8bdSHansol Suh PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x + c_start, &_One, &_DOne, y, &_One)); 1137459e8d23SBlanca Mellado Pinto } 11389566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 11399566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &y)); 11400be0d8bdSHansol Suh PetscCall(PetscLogFlops(2.0 * m * n)); 11410be0d8bdSHansol Suh PetscFunctionReturn(PETSC_SUCCESS); 11420be0d8bdSHansol Suh } 11430be0d8bdSHansol Suh 11440be0d8bdSHansol Suh PetscErrorCode MatMultAddColumnRange_SeqDense(Mat A, Vec xx, Vec zz, Vec yy, PetscInt c_start, PetscInt c_end) 11450be0d8bdSHansol Suh { 11460be0d8bdSHansol Suh PetscFunctionBegin; 11470be0d8bdSHansol Suh PetscCall(MatMultAddColumnRangeKernel_SeqDense(A, xx, zz, yy, c_start, c_end, PETSC_FALSE, PETSC_FALSE)); 11480be0d8bdSHansol Suh PetscFunctionReturn(PETSC_SUCCESS); 11490be0d8bdSHansol Suh } 11500be0d8bdSHansol Suh 11510be0d8bdSHansol Suh PetscErrorCode MatMultHermitianTransposeAddColumnRange_SeqDense(Mat A, Vec xx, Vec zz, Vec yy, PetscInt c_start, PetscInt c_end) 11520be0d8bdSHansol Suh { 11530be0d8bdSHansol Suh PetscFunctionBegin; 11540be0d8bdSHansol Suh PetscMPIInt rank; 11550be0d8bdSHansol Suh PetscCallMPI(MPI_Comm_rank(MPI_COMM_WORLD, &rank)); 11560be0d8bdSHansol Suh PetscCall(MatMultAddColumnRangeKernel_SeqDense(A, xx, zz, yy, c_start, c_end, PETSC_TRUE, PETSC_TRUE)); 11573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1158289bc588SBarry Smith } 11596ee01492SSatish Balay 1160459e8d23SBlanca Mellado Pinto PetscErrorCode MatMultAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) 1161459e8d23SBlanca Mellado Pinto { 1162459e8d23SBlanca Mellado Pinto PetscFunctionBegin; 11630be0d8bdSHansol Suh PetscCall(MatMultAddColumnRangeKernel_SeqDense(A, xx, zz, yy, 0, A->cmap->n, PETSC_FALSE, PETSC_FALSE)); 1164459e8d23SBlanca Mellado Pinto PetscFunctionReturn(PETSC_SUCCESS); 1165459e8d23SBlanca Mellado Pinto } 1166459e8d23SBlanca Mellado Pinto 1167d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) 1168d71ae5a4SJacob Faibussowitsch { 11693a40ed3dSBarry Smith PetscFunctionBegin; 11700be0d8bdSHansol Suh PetscCall(MatMultAddColumnRangeKernel_SeqDense(A, xx, zz, yy, 0, A->cmap->n, PETSC_TRUE, PETSC_FALSE)); 1171459e8d23SBlanca Mellado Pinto PetscFunctionReturn(PETSC_SUCCESS); 1172459e8d23SBlanca Mellado Pinto } 1173459e8d23SBlanca Mellado Pinto 1174459e8d23SBlanca Mellado Pinto PetscErrorCode MatMultHermitianTransposeAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) 1175459e8d23SBlanca Mellado Pinto { 1176459e8d23SBlanca Mellado Pinto PetscFunctionBegin; 11770be0d8bdSHansol Suh PetscCall(MatMultAddColumnRangeKernel_SeqDense(A, xx, zz, yy, 0, A->cmap->n, PETSC_TRUE, PETSC_TRUE)); 11783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1179289bc588SBarry Smith } 1180289bc588SBarry Smith 1181d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals) 1182d71ae5a4SJacob Faibussowitsch { 1183c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 118413f74950SBarry Smith PetscInt i; 118567e560aaSBarry Smith 11863a40ed3dSBarry Smith PetscFunctionBegin; 1187c3e1b152SPierre Jolivet if (ncols) *ncols = A->cmap->n; 1188289bc588SBarry Smith if (cols) { 11899566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->cmap->n, cols)); 1190d0f46423SBarry Smith for (i = 0; i < A->cmap->n; i++) (*cols)[i] = i; 1191289bc588SBarry Smith } 1192289bc588SBarry Smith if (vals) { 1193ca15aa20SStefano Zampini const PetscScalar *v; 1194ca15aa20SStefano Zampini 11959566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 11969566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->cmap->n, vals)); 1197ca15aa20SStefano Zampini v += row; 11989371c9d4SSatish Balay for (i = 0; i < A->cmap->n; i++) { 11999371c9d4SSatish Balay (*vals)[i] = *v; 12009371c9d4SSatish Balay v += mat->lda; 12019371c9d4SSatish Balay } 12029566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 1203289bc588SBarry Smith } 12043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1205289bc588SBarry Smith } 12066ee01492SSatish Balay 1207d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRestoreRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals) 1208d71ae5a4SJacob Faibussowitsch { 1209606d414cSSatish Balay PetscFunctionBegin; 12109566063dSJacob Faibussowitsch if (cols) PetscCall(PetscFree(*cols)); 12119566063dSJacob Faibussowitsch if (vals) PetscCall(PetscFree(*vals)); 12123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1213289bc588SBarry Smith } 12142ef1f0ffSBarry Smith 1215d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], const PetscScalar v[], InsertMode addv) 1216d71ae5a4SJacob Faibussowitsch { 1217c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1218ca15aa20SStefano Zampini PetscScalar *av; 121913f74950SBarry Smith PetscInt i, j, idx = 0; 122047d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1221c70f7ee4SJunchao Zhang PetscOffloadMask oldf; 1222ca15aa20SStefano Zampini #endif 1223d6dfbf8fSBarry Smith 12243a40ed3dSBarry Smith PetscFunctionBegin; 12259566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &av)); 1226289bc588SBarry Smith if (!mat->roworiented) { 1227dbb450caSBarry Smith if (addv == INSERT_VALUES) { 1228289bc588SBarry Smith for (j = 0; j < n; j++) { 12299371c9d4SSatish Balay if (indexn[j] < 0) { 12309371c9d4SSatish Balay idx += m; 12319371c9d4SSatish Balay continue; 12329371c9d4SSatish Balay } 12336bdcaf15SBarry 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); 1234289bc588SBarry Smith for (i = 0; i < m; i++) { 12359371c9d4SSatish Balay if (indexm[i] < 0) { 12369371c9d4SSatish Balay idx++; 12379371c9d4SSatish Balay continue; 12389371c9d4SSatish Balay } 12396bdcaf15SBarry 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); 12408c4a67a0SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] = v ? v[idx++] : (idx++, 0.0); 1241289bc588SBarry Smith } 1242289bc588SBarry Smith } 12430be0d8bdSHansol Suh } else { 1244289bc588SBarry Smith for (j = 0; j < n; j++) { 12459371c9d4SSatish Balay if (indexn[j] < 0) { 12469371c9d4SSatish Balay idx += m; 12479371c9d4SSatish Balay continue; 12489371c9d4SSatish Balay } 12496bdcaf15SBarry 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); 1250289bc588SBarry Smith for (i = 0; i < m; i++) { 12519371c9d4SSatish Balay if (indexm[i] < 0) { 12529371c9d4SSatish Balay idx++; 12539371c9d4SSatish Balay continue; 12549371c9d4SSatish Balay } 12556bdcaf15SBarry 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); 12568c4a67a0SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] += v ? v[idx++] : (idx++, 0.0); 1257289bc588SBarry Smith } 1258289bc588SBarry Smith } 1259289bc588SBarry Smith } 12603a40ed3dSBarry Smith } else { 1261dbb450caSBarry Smith if (addv == INSERT_VALUES) { 1262e8d4e0b9SBarry Smith for (i = 0; i < m; i++) { 12639371c9d4SSatish Balay if (indexm[i] < 0) { 12649371c9d4SSatish Balay idx += n; 12659371c9d4SSatish Balay continue; 12669371c9d4SSatish Balay } 12676bdcaf15SBarry 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); 1268e8d4e0b9SBarry Smith for (j = 0; j < n; j++) { 12699371c9d4SSatish Balay if (indexn[j] < 0) { 12709371c9d4SSatish Balay idx++; 12719371c9d4SSatish Balay continue; 12729371c9d4SSatish Balay } 12736bdcaf15SBarry 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); 12748c4a67a0SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] = v ? v[idx++] : (idx++, 0.0); 1275e8d4e0b9SBarry Smith } 1276e8d4e0b9SBarry Smith } 12770be0d8bdSHansol Suh } else { 1278289bc588SBarry Smith for (i = 0; i < m; i++) { 12799371c9d4SSatish Balay if (indexm[i] < 0) { 12809371c9d4SSatish Balay idx += n; 12819371c9d4SSatish Balay continue; 12829371c9d4SSatish Balay } 12836bdcaf15SBarry 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); 1284289bc588SBarry Smith for (j = 0; j < n; j++) { 12859371c9d4SSatish Balay if (indexn[j] < 0) { 12869371c9d4SSatish Balay idx++; 12879371c9d4SSatish Balay continue; 12889371c9d4SSatish Balay } 12896bdcaf15SBarry 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); 12908c4a67a0SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] += v ? v[idx++] : (idx++, 0.0); 1291289bc588SBarry Smith } 1292289bc588SBarry Smith } 1293289bc588SBarry Smith } 1294e8d4e0b9SBarry Smith } 1295ca15aa20SStefano Zampini /* hack to prevent unneeded copy to the GPU while returning the array */ 129647d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1297c70f7ee4SJunchao Zhang oldf = A->offloadmask; 1298c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_GPU; 1299ca15aa20SStefano Zampini #endif 13009566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &av)); 130147d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1302c70f7ee4SJunchao Zhang A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU); 1303ca15aa20SStefano Zampini #endif 13043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1305289bc588SBarry Smith } 1306e8d4e0b9SBarry Smith 1307d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], PetscScalar v[]) 1308d71ae5a4SJacob Faibussowitsch { 1309ae80bb75SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1310ca15aa20SStefano Zampini const PetscScalar *vv; 131113f74950SBarry Smith PetscInt i, j; 1312ae80bb75SLois Curfman McInnes 13133a40ed3dSBarry Smith PetscFunctionBegin; 13149566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &vv)); 1315ae80bb75SLois Curfman McInnes /* row-oriented output */ 1316ae80bb75SLois Curfman McInnes for (i = 0; i < m; i++) { 13179371c9d4SSatish Balay if (indexm[i] < 0) { 13189371c9d4SSatish Balay v += n; 13199371c9d4SSatish Balay continue; 13209371c9d4SSatish Balay } 132108401ef6SPierre 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); 1322ae80bb75SLois Curfman McInnes for (j = 0; j < n; j++) { 13239371c9d4SSatish Balay if (indexn[j] < 0) { 13249371c9d4SSatish Balay v++; 13259371c9d4SSatish Balay continue; 13269371c9d4SSatish Balay } 132708401ef6SPierre 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); 1328ca15aa20SStefano Zampini *v++ = vv[indexn[j] * mat->lda + indexm[i]]; 1329ae80bb75SLois Curfman McInnes } 1330ae80bb75SLois Curfman McInnes } 13319566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &vv)); 13323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1333ae80bb75SLois Curfman McInnes } 1334ae80bb75SLois Curfman McInnes 1335d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_Dense_Binary(Mat mat, PetscViewer viewer) 1336d71ae5a4SJacob Faibussowitsch { 13378491ab44SLisandro Dalcin PetscBool skipHeader; 13388491ab44SLisandro Dalcin PetscViewerFormat format; 1339*3e1d7bceSPierre Jolivet PetscInt header[4], M, N, m, lda, i, j; 1340*3e1d7bceSPierre Jolivet PetscCount k; 13418491ab44SLisandro Dalcin const PetscScalar *v; 13428491ab44SLisandro Dalcin PetscScalar *vwork; 1343aabbc4fbSShri Abhyankar 1344aabbc4fbSShri Abhyankar PetscFunctionBegin; 13459566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 13469566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader)); 13479566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 13488491ab44SLisandro Dalcin if (skipHeader) format = PETSC_VIEWER_NATIVE; 1349aabbc4fbSShri Abhyankar 13509566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &M, &N)); 13518491ab44SLisandro Dalcin 13528491ab44SLisandro Dalcin /* write matrix header */ 13539371c9d4SSatish Balay header[0] = MAT_FILE_CLASSID; 13549371c9d4SSatish Balay header[1] = M; 13559371c9d4SSatish Balay header[2] = N; 13568491ab44SLisandro Dalcin header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M * N; 13579566063dSJacob Faibussowitsch if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer, header, 4, PETSC_INT)); 13588491ab44SLisandro Dalcin 13599566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mat, &m, NULL)); 13608491ab44SLisandro Dalcin if (format != PETSC_VIEWER_NATIVE) { 13618491ab44SLisandro Dalcin PetscInt nnz = m * N, *iwork; 13628491ab44SLisandro Dalcin /* store row lengths for each row */ 13639566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz, &iwork)); 13648491ab44SLisandro Dalcin for (i = 0; i < m; i++) iwork[i] = N; 13659566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 13668491ab44SLisandro Dalcin /* store column indices (zero start index) */ 13678491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 13689371c9d4SSatish Balay for (j = 0; j < N; j++, k++) iwork[k] = j; 13699566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 13709566063dSJacob Faibussowitsch PetscCall(PetscFree(iwork)); 13718491ab44SLisandro Dalcin } 13728491ab44SLisandro Dalcin /* store matrix values as a dense matrix in row major order */ 13739566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m * N, &vwork)); 13749566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(mat, &v)); 13759566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(mat, &lda)); 13768491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 1377*3e1d7bceSPierre Jolivet for (j = 0; j < N; j++, k++) vwork[k] = v[i + (size_t)lda * j]; 13789566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(mat, &v)); 13799566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, vwork, m * N, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 13809566063dSJacob Faibussowitsch PetscCall(PetscFree(vwork)); 13813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13828491ab44SLisandro Dalcin } 13838491ab44SLisandro Dalcin 1384d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLoad_Dense_Binary(Mat mat, PetscViewer viewer) 1385d71ae5a4SJacob Faibussowitsch { 13868491ab44SLisandro Dalcin PetscBool skipHeader; 13878491ab44SLisandro Dalcin PetscInt header[4], M, N, m, nz, lda, i, j, k; 13888491ab44SLisandro Dalcin PetscInt rows, cols; 13898491ab44SLisandro Dalcin PetscScalar *v, *vwork; 13908491ab44SLisandro Dalcin 13918491ab44SLisandro Dalcin PetscFunctionBegin; 13929566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 13939566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader)); 13948491ab44SLisandro Dalcin 13958491ab44SLisandro Dalcin if (!skipHeader) { 13969566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, header, 4, NULL, PETSC_INT)); 139708401ef6SPierre Jolivet PetscCheck(header[0] == MAT_FILE_CLASSID, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Not a matrix object in file"); 13989371c9d4SSatish Balay M = header[1]; 13999371c9d4SSatish Balay N = header[2]; 140008401ef6SPierre Jolivet PetscCheck(M >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix row size (%" PetscInt_FMT ") in file is negative", M); 140108401ef6SPierre Jolivet PetscCheck(N >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix column size (%" PetscInt_FMT ") in file is negative", N); 14028491ab44SLisandro Dalcin nz = header[3]; 1403aed4548fSBarry Smith PetscCheck(nz == MATRIX_BINARY_FORMAT_DENSE || nz >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Unknown matrix format %" PetscInt_FMT " in file", nz); 1404aabbc4fbSShri Abhyankar } else { 14059566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &M, &N)); 1406aed4548fSBarry 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"); 14078491ab44SLisandro Dalcin nz = MATRIX_BINARY_FORMAT_DENSE; 1408e6324fbbSBarry Smith } 1409aabbc4fbSShri Abhyankar 14108491ab44SLisandro Dalcin /* setup global sizes if not set */ 14118491ab44SLisandro Dalcin if (mat->rmap->N < 0) mat->rmap->N = M; 14128491ab44SLisandro Dalcin if (mat->cmap->N < 0) mat->cmap->N = N; 14139566063dSJacob Faibussowitsch PetscCall(MatSetUp(mat)); 14148491ab44SLisandro Dalcin /* check if global sizes are correct */ 14159566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &rows, &cols)); 1416aed4548fSBarry 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); 1417aabbc4fbSShri Abhyankar 14189566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, NULL, &N)); 14199566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mat, &m, NULL)); 14209566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(mat, &v)); 14219566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(mat, &lda)); 14228491ab44SLisandro Dalcin if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense format */ 1423*3e1d7bceSPierre Jolivet PetscCount nnz = (size_t)m * N; 14248491ab44SLisandro Dalcin /* read in matrix values */ 14259566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz, &vwork)); 14269566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 14278491ab44SLisandro Dalcin /* store values in column major order */ 14288491ab44SLisandro Dalcin for (j = 0; j < N; j++) 1429*3e1d7bceSPierre Jolivet for (i = 0; i < m; i++) v[i + (size_t)lda * j] = vwork[(size_t)i * N + j]; 14309566063dSJacob Faibussowitsch PetscCall(PetscFree(vwork)); 14318491ab44SLisandro Dalcin } else { /* matrix in file is sparse format */ 14328491ab44SLisandro Dalcin PetscInt nnz = 0, *rlens, *icols; 14338491ab44SLisandro Dalcin /* read in row lengths */ 14349566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m, &rlens)); 14359566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, rlens, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 14368491ab44SLisandro Dalcin for (i = 0; i < m; i++) nnz += rlens[i]; 14378491ab44SLisandro Dalcin /* read in column indices and values */ 14389566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(nnz, &icols, nnz, &vwork)); 14399566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, icols, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 14409566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 14418491ab44SLisandro Dalcin /* store values in column major order */ 14428491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 14439371c9d4SSatish Balay for (j = 0; j < rlens[i]; j++, k++) v[i + lda * icols[k]] = vwork[k]; 14449566063dSJacob Faibussowitsch PetscCall(PetscFree(rlens)); 14459566063dSJacob Faibussowitsch PetscCall(PetscFree2(icols, vwork)); 1446aabbc4fbSShri Abhyankar } 14479566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(mat, &v)); 14489566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY)); 14499566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY)); 14503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1451aabbc4fbSShri Abhyankar } 1452aabbc4fbSShri Abhyankar 145366976f2fSJacob Faibussowitsch static PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer) 1454d71ae5a4SJacob Faibussowitsch { 1455eb91f321SVaclav Hapla PetscBool isbinary, ishdf5; 1456eb91f321SVaclav Hapla 1457eb91f321SVaclav Hapla PetscFunctionBegin; 1458eb91f321SVaclav Hapla PetscValidHeaderSpecific(newMat, MAT_CLASSID, 1); 1459eb91f321SVaclav Hapla PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1460eb91f321SVaclav Hapla /* force binary viewer to load .info file if it has not yet done so */ 14619566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 14629566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 14639566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5)); 1464eb91f321SVaclav Hapla if (isbinary) { 14659566063dSJacob Faibussowitsch PetscCall(MatLoad_Dense_Binary(newMat, viewer)); 1466eb91f321SVaclav Hapla } else if (ishdf5) { 1467eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5) 14689566063dSJacob Faibussowitsch PetscCall(MatLoad_Dense_HDF5(newMat, viewer)); 1469eb91f321SVaclav Hapla #else 1470eb91f321SVaclav Hapla SETERRQ(PetscObjectComm((PetscObject)newMat), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1471eb91f321SVaclav Hapla #endif 1472eb91f321SVaclav Hapla } else { 147398921bdaSJacob 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); 1474eb91f321SVaclav Hapla } 14753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1476eb91f321SVaclav Hapla } 1477eb91f321SVaclav Hapla 1478d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_ASCII(Mat A, PetscViewer viewer) 1479d71ae5a4SJacob Faibussowitsch { 1480932b0c3eSLois Curfman McInnes Mat_SeqDense *a = (Mat_SeqDense *)A->data; 148113f74950SBarry Smith PetscInt i, j; 14822dcb1b2aSMatthew Knepley const char *name; 1483ca15aa20SStefano Zampini PetscScalar *v, *av; 1484f3ef73ceSBarry Smith PetscViewerFormat format; 14855f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX) 1486ace3abfcSBarry Smith PetscBool allreal = PETSC_TRUE; 14875f481a85SSatish Balay #endif 1488932b0c3eSLois Curfman McInnes 14893a40ed3dSBarry Smith PetscFunctionBegin; 14909566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&av)); 14919566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 1492456192e2SBarry Smith if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 14933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); /* do nothing for now */ 1494fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 14959566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE)); 1496d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 1497ca15aa20SStefano Zampini v = av + i; 14989566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "row %" PetscInt_FMT ":", i)); 1499d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1500aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 1501329f5518SBarry Smith if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) { 15029566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g + %g i) ", j, (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v))); 1503329f5518SBarry Smith } else if (PetscRealPart(*v)) { 15049566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)PetscRealPart(*v))); 15056831982aSBarry Smith } 150680cd9d93SLois Curfman McInnes #else 150748a46eb9SPierre Jolivet if (*v) PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)*v)); 150880cd9d93SLois Curfman McInnes #endif 15091b807ce4Svictorle v += a->lda; 151080cd9d93SLois Curfman McInnes } 15119566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 151280cd9d93SLois Curfman McInnes } 15139566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE)); 15143a40ed3dSBarry Smith } else { 15159566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE)); 1516aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 151747989497SBarry Smith /* determine if matrix has all real values */ 1518bcd8d3a4SJose E. Roman for (j = 0; j < A->cmap->n; j++) { 1519bcd8d3a4SJose E. Roman v = av + j * a->lda; 1520bcd8d3a4SJose E. Roman for (i = 0; i < A->rmap->n; i++) { 15219371c9d4SSatish Balay if (PetscImaginaryPart(v[i])) { 15229371c9d4SSatish Balay allreal = PETSC_FALSE; 15239371c9d4SSatish Balay break; 15249371c9d4SSatish Balay } 152547989497SBarry Smith } 1526bcd8d3a4SJose E. Roman } 152747989497SBarry Smith #endif 1528fb9695e5SSatish Balay if (format == PETSC_VIEWER_ASCII_MATLAB) { 15299566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)A, &name)); 15309566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%% Size = %" PetscInt_FMT " %" PetscInt_FMT " \n", A->rmap->n, A->cmap->n)); 15319566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%s = zeros(%" PetscInt_FMT ",%" PetscInt_FMT ");\n", name, A->rmap->n, A->cmap->n)); 15329566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%s = [\n", name)); 1533ffac6cdbSBarry Smith } 1534ffac6cdbSBarry Smith 1535d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 1536ca15aa20SStefano Zampini v = av + i; 1537d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1538aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 153947989497SBarry Smith if (allreal) { 15409566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)PetscRealPart(*v))); 154147989497SBarry Smith } else { 15429566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e + %18.16ei ", (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v))); 154347989497SBarry Smith } 1544289bc588SBarry Smith #else 15459566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)*v)); 1546289bc588SBarry Smith #endif 15471b807ce4Svictorle v += a->lda; 1548289bc588SBarry Smith } 15499566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 1550289bc588SBarry Smith } 155148a46eb9SPierre Jolivet if (format == PETSC_VIEWER_ASCII_MATLAB) PetscCall(PetscViewerASCIIPrintf(viewer, "];\n")); 15529566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE)); 1553da3a660dSBarry Smith } 15549566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&av)); 15559566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer)); 15563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1557289bc588SBarry Smith } 1558289bc588SBarry Smith 15599804daf3SBarry Smith #include <petscdraw.h> 1560d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw, void *Aa) 1561d71ae5a4SJacob Faibussowitsch { 1562f1af5d2fSBarry Smith Mat A = (Mat)Aa; 1563383922c3SLisandro Dalcin PetscInt m = A->rmap->n, n = A->cmap->n, i, j; 1564383922c3SLisandro Dalcin int color = PETSC_DRAW_WHITE; 1565ca15aa20SStefano Zampini const PetscScalar *v; 1566b0a32e0cSBarry Smith PetscViewer viewer; 1567b05fc000SLisandro Dalcin PetscReal xl, yl, xr, yr, x_l, x_r, y_l, y_r; 1568f3ef73ceSBarry Smith PetscViewerFormat format; 1569f1af5d2fSBarry Smith 1570f1af5d2fSBarry Smith PetscFunctionBegin; 15719566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)A, "Zoomviewer", (PetscObject *)&viewer)); 15729566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 15739566063dSJacob Faibussowitsch PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr)); 1574f1af5d2fSBarry Smith 1575f1af5d2fSBarry Smith /* Loop over matrix elements drawing boxes */ 15769566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 1577fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 1578d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 1579f1af5d2fSBarry Smith /* Blue for negative and Red for positive */ 1580f1af5d2fSBarry Smith for (j = 0; j < n; j++) { 15819371c9d4SSatish Balay x_l = j; 15829371c9d4SSatish Balay x_r = x_l + 1.0; 1583f1af5d2fSBarry Smith for (i = 0; i < m; i++) { 1584f1af5d2fSBarry Smith y_l = m - i - 1.0; 1585f1af5d2fSBarry Smith y_r = y_l + 1.0; 1586ca15aa20SStefano Zampini if (PetscRealPart(v[j * m + i]) > 0.) color = PETSC_DRAW_RED; 1587ca15aa20SStefano Zampini else if (PetscRealPart(v[j * m + i]) < 0.) color = PETSC_DRAW_BLUE; 1588ca15aa20SStefano Zampini else continue; 15899566063dSJacob Faibussowitsch PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color)); 1590f1af5d2fSBarry Smith } 1591f1af5d2fSBarry Smith } 1592d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 1593f1af5d2fSBarry Smith } else { 1594f1af5d2fSBarry Smith /* use contour shading to indicate magnitude of values */ 1595f1af5d2fSBarry Smith /* first determine max of all nonzero values */ 1596b05fc000SLisandro Dalcin PetscReal minv = 0.0, maxv = 0.0; 1597b05fc000SLisandro Dalcin PetscDraw popup; 1598b05fc000SLisandro Dalcin 1599f1af5d2fSBarry Smith for (i = 0; i < m * n; i++) { 1600f1af5d2fSBarry Smith if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]); 1601f1af5d2fSBarry Smith } 1602383922c3SLisandro Dalcin if (minv >= maxv) maxv = minv + PETSC_SMALL; 16039566063dSJacob Faibussowitsch PetscCall(PetscDrawGetPopup(draw, &popup)); 16049566063dSJacob Faibussowitsch PetscCall(PetscDrawScalePopup(popup, minv, maxv)); 1605383922c3SLisandro Dalcin 1606d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 1607f1af5d2fSBarry Smith for (j = 0; j < n; j++) { 1608f1af5d2fSBarry Smith x_l = j; 1609f1af5d2fSBarry Smith x_r = x_l + 1.0; 1610f1af5d2fSBarry Smith for (i = 0; i < m; i++) { 1611f1af5d2fSBarry Smith y_l = m - i - 1.0; 1612f1af5d2fSBarry Smith y_r = y_l + 1.0; 1613b05fc000SLisandro Dalcin color = PetscDrawRealToColor(PetscAbsScalar(v[j * m + i]), minv, maxv); 16149566063dSJacob Faibussowitsch PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color)); 1615f1af5d2fSBarry Smith } 1616f1af5d2fSBarry Smith } 1617d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 1618f1af5d2fSBarry Smith } 16199566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 16203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1621f1af5d2fSBarry Smith } 1622f1af5d2fSBarry Smith 1623d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw(Mat A, PetscViewer viewer) 1624d71ae5a4SJacob Faibussowitsch { 1625b0a32e0cSBarry Smith PetscDraw draw; 1626ace3abfcSBarry Smith PetscBool isnull; 1627329f5518SBarry Smith PetscReal xr, yr, xl, yl, h, w; 1628f1af5d2fSBarry Smith 1629f1af5d2fSBarry Smith PetscFunctionBegin; 16309566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 16319566063dSJacob Faibussowitsch PetscCall(PetscDrawIsNull(draw, &isnull)); 16323ba16761SJacob Faibussowitsch if (isnull) PetscFunctionReturn(PETSC_SUCCESS); 1633f1af5d2fSBarry Smith 16349371c9d4SSatish Balay xr = A->cmap->n; 16359371c9d4SSatish Balay yr = A->rmap->n; 16369371c9d4SSatish Balay h = yr / 10.0; 16379371c9d4SSatish Balay w = xr / 10.0; 16389371c9d4SSatish Balay xr += w; 16399371c9d4SSatish Balay yr += h; 16409371c9d4SSatish Balay xl = -w; 16419371c9d4SSatish Balay yl = -h; 16429566063dSJacob Faibussowitsch PetscCall(PetscDrawSetCoordinates(draw, xl, yl, xr, yr)); 16439566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", (PetscObject)viewer)); 16449566063dSJacob Faibussowitsch PetscCall(PetscDrawZoom(draw, MatView_SeqDense_Draw_Zoom, A)); 16459566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", NULL)); 16469566063dSJacob Faibussowitsch PetscCall(PetscDrawSave(draw)); 16473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1648f1af5d2fSBarry Smith } 1649f1af5d2fSBarry Smith 1650d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_SeqDense(Mat A, PetscViewer viewer) 1651d71ae5a4SJacob Faibussowitsch { 1652ace3abfcSBarry Smith PetscBool iascii, isbinary, isdraw; 1653932b0c3eSLois Curfman McInnes 16543a40ed3dSBarry Smith PetscFunctionBegin; 16559566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 16569566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 16579566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 16581baa6e33SBarry Smith if (iascii) PetscCall(MatView_SeqDense_ASCII(A, viewer)); 16591baa6e33SBarry Smith else if (isbinary) PetscCall(MatView_Dense_Binary(A, viewer)); 16601baa6e33SBarry Smith else if (isdraw) PetscCall(MatView_SeqDense_Draw(A, viewer)); 16613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1662932b0c3eSLois Curfman McInnes } 1663289bc588SBarry Smith 1664d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A, const PetscScalar *array) 1665d71ae5a4SJacob Faibussowitsch { 1666d3042a70SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1667d3042a70SBarry Smith 1668d3042a70SBarry Smith PetscFunctionBegin; 166928b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 167028b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 16716635c364SPierre Jolivet PetscCheck(!a->unplacedarray, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseResetArray() first"); 1672d3042a70SBarry Smith a->unplacedarray = a->v; 1673d3042a70SBarry Smith a->unplaced_user_alloc = a->user_alloc; 1674d3042a70SBarry Smith a->v = (PetscScalar *)array; 1675637a0070SStefano Zampini a->user_alloc = PETSC_TRUE; 167647d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1677c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_CPU; 1678ca15aa20SStefano Zampini #endif 16793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1680d3042a70SBarry Smith } 1681d3042a70SBarry Smith 1682d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseResetArray_SeqDense(Mat A) 1683d71ae5a4SJacob Faibussowitsch { 1684d3042a70SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1685d3042a70SBarry Smith 1686d3042a70SBarry Smith PetscFunctionBegin; 168728b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 168828b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 1689d3042a70SBarry Smith a->v = a->unplacedarray; 1690d3042a70SBarry Smith a->user_alloc = a->unplaced_user_alloc; 1691d3042a70SBarry Smith a->unplacedarray = NULL; 169247d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1693c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_CPU; 1694ca15aa20SStefano Zampini #endif 16953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1696d3042a70SBarry Smith } 1697d3042a70SBarry Smith 1698d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A, const PetscScalar *array) 1699d71ae5a4SJacob Faibussowitsch { 1700d5ea218eSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1701d5ea218eSStefano Zampini 1702d5ea218eSStefano Zampini PetscFunctionBegin; 170328b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 170428b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 17059566063dSJacob Faibussowitsch if (!a->user_alloc) PetscCall(PetscFree(a->v)); 1706d5ea218eSStefano Zampini a->v = (PetscScalar *)array; 1707d5ea218eSStefano Zampini a->user_alloc = PETSC_FALSE; 170847d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1709d5ea218eSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 1710d5ea218eSStefano Zampini #endif 17113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1712d5ea218eSStefano Zampini } 1713d5ea218eSStefano Zampini 1714d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDestroy_SeqDense(Mat mat) 1715d71ae5a4SJacob Faibussowitsch { 1716ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)mat->data; 171790f02eecSBarry Smith 17183a40ed3dSBarry Smith PetscFunctionBegin; 17193ba16761SJacob Faibussowitsch PetscCall(PetscLogObjectState((PetscObject)mat, "Rows %" PetscInt_FMT " Cols %" PetscInt_FMT, mat->rmap->n, mat->cmap->n)); 1720f4f49eeaSPierre Jolivet PetscCall(VecDestroy(&l->qrrhs)); 17219566063dSJacob Faibussowitsch PetscCall(PetscFree(l->tau)); 17229566063dSJacob Faibussowitsch PetscCall(PetscFree(l->pivots)); 17239566063dSJacob Faibussowitsch PetscCall(PetscFree(l->fwork)); 17249566063dSJacob Faibussowitsch if (!l->user_alloc) PetscCall(PetscFree(l->v)); 17259566063dSJacob Faibussowitsch if (!l->unplaced_user_alloc) PetscCall(PetscFree(l->unplacedarray)); 172628b400f6SJacob Faibussowitsch PetscCheck(!l->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 172728b400f6SJacob Faibussowitsch PetscCheck(!l->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 17289566063dSJacob Faibussowitsch PetscCall(VecDestroy(&l->cvec)); 17299566063dSJacob Faibussowitsch PetscCall(MatDestroy(&l->cmat)); 17309566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->data)); 1731dbd8c25aSHong Zhang 17329566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)mat, NULL)); 17339566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactor_C", NULL)); 17342e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorSymbolic_C", NULL)); 17352e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorNumeric_C", NULL)); 17369566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetLDA_C", NULL)); 17379566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseSetLDA_C", NULL)); 17389566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArray_C", NULL)); 17399566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArray_C", NULL)); 17409566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDensePlaceArray_C", NULL)); 17419566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseResetArray_C", NULL)); 17429566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseReplaceArray_C", NULL)); 17439566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayRead_C", NULL)); 17449566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayRead_C", NULL)); 17459566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayWrite_C", NULL)); 17469566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayWrite_C", NULL)); 17479566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqaij_C", NULL)); 17488baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 17499566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_elemental_C", NULL)); 17508baccfbdSHong Zhang #endif 1751d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 17529566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_scalapack_C", NULL)); 1753d24d4204SJose E. Roman #endif 17542bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA) 17559566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensecuda_C", NULL)); 17569566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", NULL)); 17579566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdense_C", NULL)); 17582e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensecuda_C", NULL)); 17592bf066beSStefano Zampini #endif 176047d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 176147d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensehip_C", NULL)); 176247d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensehip_seqdensehip_C", NULL)); 176347d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensehip_seqdense_C", NULL)); 176447d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensehip_C", NULL)); 176547d993e7Ssuyashtn #endif 17669566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatSeqDenseSetPreallocation_C", NULL)); 17679566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqaij_seqdense_C", NULL)); 17689566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdense_C", NULL)); 17699566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqbaij_seqdense_C", NULL)); 17709566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqsbaij_seqdense_C", NULL)); 177152c5f739Sprj- 17729566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumn_C", NULL)); 17739566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumn_C", NULL)); 17749566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVec_C", NULL)); 17759566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVec_C", NULL)); 17769566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecRead_C", NULL)); 17779566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecRead_C", NULL)); 17789566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecWrite_C", NULL)); 17799566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecWrite_C", NULL)); 17809566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetSubMatrix_C", NULL)); 17819566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreSubMatrix_C", NULL)); 17820be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatMultAddColumnRange_C", NULL)); 17830be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatMultHermitianTransposeColumnRange_C", NULL)); 17840be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatMultHermitianTransposeAddColumnRange_C", NULL)); 17853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1786289bc588SBarry Smith } 1787289bc588SBarry Smith 1788d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatTranspose_SeqDense(Mat A, MatReuse reuse, Mat *matout) 1789d71ae5a4SJacob Faibussowitsch { 1790c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 17916536e3caSStefano Zampini PetscInt k, j, m = A->rmap->n, M = mat->lda, n = A->cmap->n; 179287828ca2SBarry Smith PetscScalar *v, tmp; 179348b35521SBarry Smith 17943a40ed3dSBarry Smith PetscFunctionBegin; 17957fb60732SBarry Smith if (reuse == MAT_REUSE_MATRIX) PetscCall(MatTransposeCheckNonzeroState_Private(A, *matout)); 17966536e3caSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 17976536e3caSStefano Zampini if (m == n) { /* in place transpose */ 17989566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 1799d3e5ee88SLois Curfman McInnes for (j = 0; j < m; j++) { 1800289bc588SBarry Smith for (k = 0; k < j; k++) { 18011b807ce4Svictorle tmp = v[j + k * M]; 18021b807ce4Svictorle v[j + k * M] = v[k + j * M]; 18031b807ce4Svictorle v[k + j * M] = tmp; 1804289bc588SBarry Smith } 1805289bc588SBarry Smith } 18069566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 18076536e3caSStefano Zampini } else { /* reuse memory, temporary allocates new memory */ 18086536e3caSStefano Zampini PetscScalar *v2; 18096536e3caSStefano Zampini PetscLayout tmplayout; 18106536e3caSStefano Zampini 18119566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((size_t)m * n, &v2)); 18129566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 18136536e3caSStefano Zampini for (j = 0; j < n; j++) { 18146536e3caSStefano Zampini for (k = 0; k < m; k++) v2[j + (size_t)k * n] = v[k + (size_t)j * M]; 18156536e3caSStefano Zampini } 18169566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(v, v2, (size_t)m * n)); 18179566063dSJacob Faibussowitsch PetscCall(PetscFree(v2)); 18189566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 18196536e3caSStefano Zampini /* cleanup size dependent quantities */ 18209566063dSJacob Faibussowitsch PetscCall(VecDestroy(&mat->cvec)); 18219566063dSJacob Faibussowitsch PetscCall(MatDestroy(&mat->cmat)); 18229566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->pivots)); 18239566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->fwork)); 18246536e3caSStefano Zampini /* swap row/col layouts */ 18256497c311SBarry Smith PetscCall(PetscBLASIntCast(n, &mat->lda)); 18266536e3caSStefano Zampini tmplayout = A->rmap; 18276536e3caSStefano Zampini A->rmap = A->cmap; 18286536e3caSStefano Zampini A->cmap = tmplayout; 18296536e3caSStefano Zampini } 18303a40ed3dSBarry Smith } else { /* out-of-place transpose */ 1831d3e5ee88SLois Curfman McInnes Mat tmat; 1832ec8511deSBarry Smith Mat_SeqDense *tmatd; 183387828ca2SBarry Smith PetscScalar *v2; 1834af36a384SStefano Zampini PetscInt M2; 1835ea709b57SSatish Balay 18366536e3caSStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 18379566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &tmat)); 18389566063dSJacob Faibussowitsch PetscCall(MatSetSizes(tmat, A->cmap->n, A->rmap->n, A->cmap->n, A->rmap->n)); 18399566063dSJacob Faibussowitsch PetscCall(MatSetType(tmat, ((PetscObject)A)->type_name)); 18409566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(tmat, NULL)); 1841ca15aa20SStefano Zampini } else tmat = *matout; 1842ca15aa20SStefano Zampini 18439566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&v)); 18449566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(tmat, &v2)); 1845ec8511deSBarry Smith tmatd = (Mat_SeqDense *)tmat->data; 1846ca15aa20SStefano Zampini M2 = tmatd->lda; 1847d3e5ee88SLois Curfman McInnes for (j = 0; j < n; j++) { 1848af36a384SStefano Zampini for (k = 0; k < m; k++) v2[j + k * M2] = v[k + j * M]; 1849d3e5ee88SLois Curfman McInnes } 18509566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(tmat, &v2)); 18519566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&v)); 18529566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(tmat, MAT_FINAL_ASSEMBLY)); 18539566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(tmat, MAT_FINAL_ASSEMBLY)); 18546536e3caSStefano Zampini *matout = tmat; 185548b35521SBarry Smith } 18563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1857289bc588SBarry Smith } 1858289bc588SBarry Smith 1859d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatEqual_SeqDense(Mat A1, Mat A2, PetscBool *flg) 1860d71ae5a4SJacob Faibussowitsch { 1861c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat1 = (Mat_SeqDense *)A1->data; 1862c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat2 = (Mat_SeqDense *)A2->data; 1863ca15aa20SStefano Zampini PetscInt i; 1864ca15aa20SStefano Zampini const PetscScalar *v1, *v2; 18659ea5d5aeSSatish Balay 18663a40ed3dSBarry Smith PetscFunctionBegin; 18679371c9d4SSatish Balay if (A1->rmap->n != A2->rmap->n) { 18689371c9d4SSatish Balay *flg = PETSC_FALSE; 18693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18709371c9d4SSatish Balay } 18719371c9d4SSatish Balay if (A1->cmap->n != A2->cmap->n) { 18729371c9d4SSatish Balay *flg = PETSC_FALSE; 18733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18749371c9d4SSatish Balay } 18759566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A1, &v1)); 18769566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A2, &v2)); 1877ca15aa20SStefano Zampini for (i = 0; i < A1->cmap->n; i++) { 18789566063dSJacob Faibussowitsch PetscCall(PetscArraycmp(v1, v2, A1->rmap->n, flg)); 18793ba16761SJacob Faibussowitsch if (*flg == PETSC_FALSE) PetscFunctionReturn(PETSC_SUCCESS); 1880ca15aa20SStefano Zampini v1 += mat1->lda; 1881ca15aa20SStefano Zampini v2 += mat2->lda; 18821b807ce4Svictorle } 18839566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A1, &v1)); 18849566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A2, &v2)); 188577c4ece6SBarry Smith *flg = PETSC_TRUE; 18863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1887289bc588SBarry Smith } 1888289bc588SBarry Smith 188914277c92SJacob Faibussowitsch PetscErrorCode MatGetDiagonal_SeqDense(Mat A, Vec v) 1890d71ae5a4SJacob Faibussowitsch { 1891c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 189213f74950SBarry Smith PetscInt i, n, len; 1893ca15aa20SStefano Zampini PetscScalar *x; 1894ca15aa20SStefano Zampini const PetscScalar *vv; 189544cd7ae7SLois Curfman McInnes 18963a40ed3dSBarry Smith PetscFunctionBegin; 18979566063dSJacob Faibussowitsch PetscCall(VecGetSize(v, &n)); 18989566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 1899d0f46423SBarry Smith len = PetscMin(A->rmap->n, A->cmap->n); 19009566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &vv)); 190108401ef6SPierre Jolivet PetscCheck(n == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming mat and vec"); 1902ad540459SPierre Jolivet for (i = 0; i < len; i++) x[i] = vv[i * mat->lda + i]; 19039566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &vv)); 19049566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 19053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1906289bc588SBarry Smith } 1907289bc588SBarry Smith 1908d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDiagonalScale_SeqDense(Mat A, Vec ll, Vec rr) 1909d71ae5a4SJacob Faibussowitsch { 1910c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1911f1ceaac6SMatthew G. Knepley const PetscScalar *l, *r; 1912ca15aa20SStefano Zampini PetscScalar x, *v, *vv; 1913d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n; 191455659b69SBarry Smith 19153a40ed3dSBarry Smith PetscFunctionBegin; 19169566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &vv)); 191728988994SBarry Smith if (ll) { 19189566063dSJacob Faibussowitsch PetscCall(VecGetSize(ll, &m)); 19199566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(ll, &l)); 192008401ef6SPierre Jolivet PetscCheck(m == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Left scaling vec wrong size"); 1921da3a660dSBarry Smith for (i = 0; i < m; i++) { 1922da3a660dSBarry Smith x = l[i]; 1923ca15aa20SStefano Zampini v = vv + i; 19249371c9d4SSatish Balay for (j = 0; j < n; j++) { 19259371c9d4SSatish Balay (*v) *= x; 19269371c9d4SSatish Balay v += mat->lda; 19279371c9d4SSatish Balay } 1928da3a660dSBarry Smith } 19299566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(ll, &l)); 19309566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * n * m)); 1931da3a660dSBarry Smith } 193228988994SBarry Smith if (rr) { 19339566063dSJacob Faibussowitsch PetscCall(VecGetSize(rr, &n)); 19349566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(rr, &r)); 193508401ef6SPierre Jolivet PetscCheck(n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Right scaling vec wrong size"); 1936da3a660dSBarry Smith for (i = 0; i < n; i++) { 1937da3a660dSBarry Smith x = r[i]; 1938ca15aa20SStefano Zampini v = vv + i * mat->lda; 19392205254eSKarl Rupp for (j = 0; j < m; j++) (*v++) *= x; 1940da3a660dSBarry Smith } 19419566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(rr, &r)); 19429566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * n * m)); 1943da3a660dSBarry Smith } 19449566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &vv)); 19453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1946289bc588SBarry Smith } 1947289bc588SBarry Smith 1948d71ae5a4SJacob Faibussowitsch PetscErrorCode MatNorm_SeqDense(Mat A, NormType type, PetscReal *nrm) 1949d71ae5a4SJacob Faibussowitsch { 1950c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1951ca15aa20SStefano Zampini PetscScalar *v, *vv; 1952329f5518SBarry Smith PetscReal sum = 0.0; 195375f6d85dSStefano Zampini PetscInt lda, m = A->rmap->n, i, j; 195455659b69SBarry Smith 19553a40ed3dSBarry Smith PetscFunctionBegin; 19569566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&vv)); 19579566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(A, &lda)); 1958ca15aa20SStefano Zampini v = vv; 1959289bc588SBarry Smith if (type == NORM_FROBENIUS) { 1960a5ce6ee0Svictorle if (lda > m) { 1961d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1962ca15aa20SStefano Zampini v = vv + j * lda; 1963a5ce6ee0Svictorle for (i = 0; i < m; i++) { 19649371c9d4SSatish Balay sum += PetscRealPart(PetscConj(*v) * (*v)); 19659371c9d4SSatish Balay v++; 1966a5ce6ee0Svictorle } 1967a5ce6ee0Svictorle } 1968a5ce6ee0Svictorle } else { 1969570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16) 1970570b7f6dSBarry Smith PetscBLASInt one = 1, cnt = A->cmap->n * A->rmap->n; 1971792fecdfSBarry Smith PetscCallBLAS("BLASnrm2", *nrm = BLASnrm2_(&cnt, v, &one)); 1972570b7f6dSBarry Smith } 1973570b7f6dSBarry Smith #else 1974d0f46423SBarry Smith for (i = 0; i < A->cmap->n * A->rmap->n; i++) { 19759371c9d4SSatish Balay sum += PetscRealPart(PetscConj(*v) * (*v)); 19769371c9d4SSatish Balay v++; 1977289bc588SBarry Smith } 1978a5ce6ee0Svictorle } 19798f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 1980570b7f6dSBarry Smith #endif 19819566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->cmap->n * A->rmap->n)); 19823a40ed3dSBarry Smith } else if (type == NORM_1) { 1983064f8208SBarry Smith *nrm = 0.0; 1984d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1985ca15aa20SStefano Zampini v = vv + j * mat->lda; 1986289bc588SBarry Smith sum = 0.0; 1987d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 19889371c9d4SSatish Balay sum += PetscAbsScalar(*v); 19899371c9d4SSatish Balay v++; 1990289bc588SBarry Smith } 1991064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 1992289bc588SBarry Smith } 19939566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n)); 19943a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 1995064f8208SBarry Smith *nrm = 0.0; 1996d0f46423SBarry Smith for (j = 0; j < A->rmap->n; j++) { 1997ca15aa20SStefano Zampini v = vv + j; 1998289bc588SBarry Smith sum = 0.0; 1999d0f46423SBarry Smith for (i = 0; i < A->cmap->n; i++) { 20009371c9d4SSatish Balay sum += PetscAbsScalar(*v); 20019371c9d4SSatish Balay v += mat->lda; 2002289bc588SBarry Smith } 2003064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 2004289bc588SBarry Smith } 20059566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n)); 2006e7e72b3dSBarry Smith } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "No two norm"); 20079566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&vv)); 20083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2009289bc588SBarry Smith } 2010289bc588SBarry Smith 2011d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetOption_SeqDense(Mat A, MatOption op, PetscBool flg) 2012d71ae5a4SJacob Faibussowitsch { 2013c0bbcb79SLois Curfman McInnes Mat_SeqDense *aij = (Mat_SeqDense *)A->data; 201467e560aaSBarry Smith 20153a40ed3dSBarry Smith PetscFunctionBegin; 2016b5a2b587SKris Buschelman switch (op) { 2017d71ae5a4SJacob Faibussowitsch case MAT_ROW_ORIENTED: 2018d71ae5a4SJacob Faibussowitsch aij->roworiented = flg; 2019d71ae5a4SJacob Faibussowitsch break; 2020512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 2021b5a2b587SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 20223971808eSMatthew Knepley case MAT_NEW_NONZERO_ALLOCATION_ERR: 20238c78258cSHong Zhang case MAT_FORCE_DIAGONAL_ENTRIES: 202413fa8e87SLisandro Dalcin case MAT_KEEP_NONZERO_PATTERN: 2025b5a2b587SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 2026b5a2b587SKris Buschelman case MAT_USE_HASH_TABLE: 20270f8fb01aSBarry Smith case MAT_IGNORE_ZERO_ENTRIES: 20285021d80fSJed Brown case MAT_IGNORE_LOWER_TRIANGULAR: 2029d71ae5a4SJacob Faibussowitsch case MAT_SORTED_FULL: 2030d71ae5a4SJacob Faibussowitsch PetscCall(PetscInfo(A, "Option %s ignored\n", MatOptions[op])); 2031d71ae5a4SJacob Faibussowitsch break; 20325021d80fSJed Brown case MAT_SPD: 203377e54ba9SKris Buschelman case MAT_SYMMETRIC: 203477e54ba9SKris Buschelman case MAT_STRUCTURALLY_SYMMETRIC: 20359a4540c5SBarry Smith case MAT_HERMITIAN: 20369a4540c5SBarry Smith case MAT_SYMMETRY_ETERNAL: 2037b94d7dedSBarry Smith case MAT_STRUCTURAL_SYMMETRY_ETERNAL: 2038d71ae5a4SJacob Faibussowitsch case MAT_SPD_ETERNAL: 2039d71ae5a4SJacob Faibussowitsch break; 2040d71ae5a4SJacob Faibussowitsch default: 2041d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "unknown option %s", MatOptions[op]); 20423a40ed3dSBarry Smith } 20433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2044289bc588SBarry Smith } 2045289bc588SBarry Smith 2046d71ae5a4SJacob Faibussowitsch PetscErrorCode MatZeroEntries_SeqDense(Mat A) 2047d71ae5a4SJacob Faibussowitsch { 2048ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)A->data; 20493d8925e7SStefano Zampini PetscInt lda = l->lda, m = A->rmap->n, n = A->cmap->n, j; 2050ca15aa20SStefano Zampini PetscScalar *v; 20513a40ed3dSBarry Smith 20523a40ed3dSBarry Smith PetscFunctionBegin; 20539566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(A, &v)); 2054a5ce6ee0Svictorle if (lda > m) { 205548a46eb9SPierre Jolivet for (j = 0; j < n; j++) PetscCall(PetscArrayzero(v + j * lda, m)); 2056a5ce6ee0Svictorle } else { 20579566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(v, PetscInt64Mult(m, n))); 2058a5ce6ee0Svictorle } 20599566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(A, &v)); 20603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 20616f0a148fSBarry Smith } 20626f0a148fSBarry Smith 2063d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatZeroRows_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) 2064d71ae5a4SJacob Faibussowitsch { 2065ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)A->data; 2066b9679d65SBarry Smith PetscInt m = l->lda, n = A->cmap->n, i, j; 2067ca15aa20SStefano Zampini PetscScalar *slot, *bb, *v; 206897b48c8fSBarry Smith const PetscScalar *xx; 206955659b69SBarry Smith 20703a40ed3dSBarry Smith PetscFunctionBegin; 207176bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 2072b9679d65SBarry Smith for (i = 0; i < N; i++) { 207308401ef6SPierre Jolivet PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed"); 207408401ef6SPierre 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); 2075b9679d65SBarry Smith } 207676bd3646SJed Brown } 20773ba16761SJacob Faibussowitsch if (!N) PetscFunctionReturn(PETSC_SUCCESS); 2078b9679d65SBarry Smith 2079dd8e379bSPierre Jolivet /* fix right-hand side if needed */ 208097b48c8fSBarry Smith if (x && b) { 20819566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 20829566063dSJacob Faibussowitsch PetscCall(VecGetArray(b, &bb)); 20832205254eSKarl Rupp for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]]; 20849566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 20859566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(b, &bb)); 208697b48c8fSBarry Smith } 208797b48c8fSBarry Smith 20889566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 20896f0a148fSBarry Smith for (i = 0; i < N; i++) { 2090ca15aa20SStefano Zampini slot = v + rows[i]; 20919371c9d4SSatish Balay for (j = 0; j < n; j++) { 20929371c9d4SSatish Balay *slot = 0.0; 20939371c9d4SSatish Balay slot += m; 20949371c9d4SSatish Balay } 20956f0a148fSBarry Smith } 2096f4df32b1SMatthew Knepley if (diag != 0.0) { 209708401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices"); 20986f0a148fSBarry Smith for (i = 0; i < N; i++) { 2099ca15aa20SStefano Zampini slot = v + (m + 1) * rows[i]; 2100f4df32b1SMatthew Knepley *slot = diag; 21016f0a148fSBarry Smith } 21026f0a148fSBarry Smith } 21039566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 21043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 21056f0a148fSBarry Smith } 2106557bce09SLois Curfman McInnes 2107d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A, PetscInt *lda) 2108d71ae5a4SJacob Faibussowitsch { 210949a6ff4bSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 211049a6ff4bSBarry Smith 211149a6ff4bSBarry Smith PetscFunctionBegin; 211249a6ff4bSBarry Smith *lda = mat->lda; 21133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 211449a6ff4bSBarry Smith } 211549a6ff4bSBarry Smith 2116d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArray_SeqDense(Mat A, PetscScalar **array) 2117d71ae5a4SJacob Faibussowitsch { 2118c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 21193a40ed3dSBarry Smith 21203a40ed3dSBarry Smith PetscFunctionBegin; 212128b400f6SJacob Faibussowitsch PetscCheck(!mat->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 212264e87e97SBarry Smith *array = mat->v; 21233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 212464e87e97SBarry Smith } 21250754003eSLois Curfman McInnes 2126d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A, PetscScalar **array) 2127d71ae5a4SJacob Faibussowitsch { 21283a40ed3dSBarry Smith PetscFunctionBegin; 212975f6d85dSStefano Zampini if (array) *array = NULL; 21303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2131ff14e315SSatish Balay } 21320754003eSLois Curfman McInnes 21330f74d2c1SSatish Balay /*@ 213411a5261eSBarry Smith MatDenseGetLDA - gets the leading dimension of the array returned from `MatDenseGetArray()` 213549a6ff4bSBarry Smith 21362ef1f0ffSBarry Smith Not Collective 213749a6ff4bSBarry Smith 213849a6ff4bSBarry Smith Input Parameter: 2139fe59aa6dSJacob Faibussowitsch . A - a `MATDENSE` or `MATDENSECUDA` matrix 214049a6ff4bSBarry Smith 214149a6ff4bSBarry Smith Output Parameter: 214249a6ff4bSBarry Smith . lda - the leading dimension 214349a6ff4bSBarry Smith 214449a6ff4bSBarry Smith Level: intermediate 214549a6ff4bSBarry Smith 21461cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseSetLDA()` 214749a6ff4bSBarry Smith @*/ 2148d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetLDA(Mat A, PetscInt *lda) 2149d71ae5a4SJacob Faibussowitsch { 215049a6ff4bSBarry Smith PetscFunctionBegin; 2151d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 21524f572ea9SToby Isaac PetscAssertPointer(lda, 2); 215375f6d85dSStefano Zampini MatCheckPreallocated(A, 1); 2154cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetLDA_C", (Mat, PetscInt *), (A, lda)); 21553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 215649a6ff4bSBarry Smith } 215749a6ff4bSBarry Smith 21580f74d2c1SSatish Balay /*@ 215911a5261eSBarry Smith MatDenseSetLDA - Sets the leading dimension of the array used by the `MATDENSE` matrix 2160ad16ce7aSStefano Zampini 21612323109cSBarry Smith Collective if the matrix layouts have not yet been setup 2162ad16ce7aSStefano Zampini 2163d8d19677SJose E. Roman Input Parameters: 2164fe59aa6dSJacob Faibussowitsch + A - a `MATDENSE` or `MATDENSECUDA` matrix 2165ad16ce7aSStefano Zampini - lda - the leading dimension 2166ad16ce7aSStefano Zampini 2167ad16ce7aSStefano Zampini Level: intermediate 2168ad16ce7aSStefano Zampini 21691cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetLDA()` 2170ad16ce7aSStefano Zampini @*/ 2171d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA(Mat A, PetscInt lda) 2172d71ae5a4SJacob Faibussowitsch { 2173ad16ce7aSStefano Zampini PetscFunctionBegin; 2174ad16ce7aSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2175cac4c232SBarry Smith PetscTryMethod(A, "MatDenseSetLDA_C", (Mat, PetscInt), (A, lda)); 21763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2177ad16ce7aSStefano Zampini } 2178ad16ce7aSStefano Zampini 2179ad16ce7aSStefano Zampini /*@C 218011a5261eSBarry Smith MatDenseGetArray - gives read-write access to the array where the data for a `MATDENSE` matrix is stored 218173a71a0fSBarry Smith 2182c3339decSBarry Smith Logically Collective 218373a71a0fSBarry Smith 218473a71a0fSBarry Smith Input Parameter: 2185fe59aa6dSJacob Faibussowitsch . A - a dense matrix 218673a71a0fSBarry Smith 218773a71a0fSBarry Smith Output Parameter: 218873a71a0fSBarry Smith . array - pointer to the data 218973a71a0fSBarry Smith 219073a71a0fSBarry Smith Level: intermediate 219173a71a0fSBarry Smith 2192fe59aa6dSJacob Faibussowitsch Fortran Notes: 21930ab4885dSBarry Smith `MatDenseGetArray()` Fortran binding is deprecated (since PETSc 3.19), use `MatDenseGetArrayF90()` 21940ab4885dSBarry Smith 21951cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 219673a71a0fSBarry Smith @*/ 21975d83a8b1SBarry Smith PetscErrorCode MatDenseGetArray(Mat A, PetscScalar *array[]) 2198d71ae5a4SJacob Faibussowitsch { 219973a71a0fSBarry Smith PetscFunctionBegin; 2200d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22014f572ea9SToby Isaac PetscAssertPointer(array, 2); 2202cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array)); 22033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 220473a71a0fSBarry Smith } 220573a71a0fSBarry Smith 2206dec5eb66SMatthew G Knepley /*@C 220711a5261eSBarry Smith MatDenseRestoreArray - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArray()` 220873a71a0fSBarry Smith 2209c3339decSBarry Smith Logically Collective 22108572280aSBarry Smith 22118572280aSBarry Smith Input Parameters: 2212fe59aa6dSJacob Faibussowitsch + A - a dense matrix 22132ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`) 22148572280aSBarry Smith 22158572280aSBarry Smith Level: intermediate 22168572280aSBarry Smith 2217fe59aa6dSJacob Faibussowitsch Fortran Notes: 22180ab4885dSBarry Smith `MatDenseRestoreArray()` Fortran binding is deprecated (since PETSc 3.19), use `MatDenseRestoreArrayF90()` 22190ab4885dSBarry Smith 22201cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 22218572280aSBarry Smith @*/ 22225d83a8b1SBarry Smith PetscErrorCode MatDenseRestoreArray(Mat A, PetscScalar *array[]) 2223d71ae5a4SJacob Faibussowitsch { 22248572280aSBarry Smith PetscFunctionBegin; 2225d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22264f572ea9SToby Isaac if (array) PetscAssertPointer(array, 2); 2227cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array)); 22289566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)A)); 222947d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 2230637a0070SStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 2231637a0070SStefano Zampini #endif 22323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22338572280aSBarry Smith } 22348572280aSBarry Smith 22358572280aSBarry Smith /*@C 223611a5261eSBarry Smith MatDenseGetArrayRead - gives read-only access to the array where the data for a `MATDENSE` matrix is stored 22378572280aSBarry Smith 2238fb850c59SBarry Smith Not Collective 22398572280aSBarry Smith 22408572280aSBarry Smith Input Parameter: 2241fe59aa6dSJacob Faibussowitsch . A - a dense matrix 22428572280aSBarry Smith 22438572280aSBarry Smith Output Parameter: 22448572280aSBarry Smith . array - pointer to the data 22458572280aSBarry Smith 22468572280aSBarry Smith Level: intermediate 22478572280aSBarry Smith 22481cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 22498572280aSBarry Smith @*/ 22505d83a8b1SBarry Smith PetscErrorCode MatDenseGetArrayRead(Mat A, const PetscScalar *array[]) 2251d71ae5a4SJacob Faibussowitsch { 22528572280aSBarry Smith PetscFunctionBegin; 2253d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22544f572ea9SToby Isaac PetscAssertPointer(array, 2); 22555c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 22563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22578572280aSBarry Smith } 22588572280aSBarry Smith 22598572280aSBarry Smith /*@C 226011a5261eSBarry Smith MatDenseRestoreArrayRead - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayRead()` 22618572280aSBarry Smith 2262fb850c59SBarry Smith Not Collective 226373a71a0fSBarry Smith 226473a71a0fSBarry Smith Input Parameters: 2265fe59aa6dSJacob Faibussowitsch + A - a dense matrix 22662ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`) 226773a71a0fSBarry Smith 226873a71a0fSBarry Smith Level: intermediate 226973a71a0fSBarry Smith 22701cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 227173a71a0fSBarry Smith @*/ 22725d83a8b1SBarry Smith PetscErrorCode MatDenseRestoreArrayRead(Mat A, const PetscScalar *array[]) 2273d71ae5a4SJacob Faibussowitsch { 227473a71a0fSBarry Smith PetscFunctionBegin; 2275d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22764f572ea9SToby Isaac if (array) PetscAssertPointer(array, 2); 22775c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 22783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 227973a71a0fSBarry Smith } 228073a71a0fSBarry Smith 22816947451fSStefano Zampini /*@C 228211a5261eSBarry Smith MatDenseGetArrayWrite - gives write-only access to the array where the data for a `MATDENSE` matrix is stored 22836947451fSStefano Zampini 2284fb850c59SBarry Smith Not Collective 22856947451fSStefano Zampini 22866947451fSStefano Zampini Input Parameter: 2287fe59aa6dSJacob Faibussowitsch . A - a dense matrix 22886947451fSStefano Zampini 22896947451fSStefano Zampini Output Parameter: 22906947451fSStefano Zampini . array - pointer to the data 22916947451fSStefano Zampini 22926947451fSStefano Zampini Level: intermediate 22936947451fSStefano Zampini 22941cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()` 22956947451fSStefano Zampini @*/ 22965d83a8b1SBarry Smith PetscErrorCode MatDenseGetArrayWrite(Mat A, PetscScalar *array[]) 2297d71ae5a4SJacob Faibussowitsch { 22986947451fSStefano Zampini PetscFunctionBegin; 2299d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 23004f572ea9SToby Isaac PetscAssertPointer(array, 2); 2301cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array)); 23023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23036947451fSStefano Zampini } 23046947451fSStefano Zampini 23056947451fSStefano Zampini /*@C 230611a5261eSBarry Smith MatDenseRestoreArrayWrite - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayWrite()` 23076947451fSStefano Zampini 2308fb850c59SBarry Smith Not Collective 23096947451fSStefano Zampini 23106947451fSStefano Zampini Input Parameters: 2311fe59aa6dSJacob Faibussowitsch + A - a dense matrix 23122ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`) 23136947451fSStefano Zampini 23146947451fSStefano Zampini Level: intermediate 23156947451fSStefano Zampini 23161cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()` 23176947451fSStefano Zampini @*/ 23185d83a8b1SBarry Smith PetscErrorCode MatDenseRestoreArrayWrite(Mat A, PetscScalar *array[]) 2319d71ae5a4SJacob Faibussowitsch { 23206947451fSStefano Zampini PetscFunctionBegin; 2321d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 23224f572ea9SToby Isaac if (array) PetscAssertPointer(array, 2); 2323cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array)); 23249566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)A)); 232547d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 23266947451fSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 23276947451fSStefano Zampini #endif 23283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23296947451fSStefano Zampini } 23306947451fSStefano Zampini 2331cd3f9d89SJunchao Zhang /*@C 2332cd3f9d89SJunchao Zhang MatDenseGetArrayAndMemType - gives read-write access to the array where the data for a `MATDENSE` matrix is stored 2333cd3f9d89SJunchao Zhang 2334cd3f9d89SJunchao Zhang Logically Collective 2335cd3f9d89SJunchao Zhang 2336cd3f9d89SJunchao Zhang Input Parameter: 2337fe59aa6dSJacob Faibussowitsch . A - a dense matrix 2338cd3f9d89SJunchao Zhang 2339cd3f9d89SJunchao Zhang Output Parameters: 2340cd3f9d89SJunchao Zhang + array - pointer to the data 2341cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer 2342cd3f9d89SJunchao Zhang 2343cd3f9d89SJunchao Zhang Level: intermediate 2344cd3f9d89SJunchao Zhang 2345fb850c59SBarry Smith Note: 23462ef1f0ffSBarry Smith If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc., 23472ef1f0ffSBarry Smith an array on device is always returned and is guaranteed to contain the matrix's latest data. 23482ef1f0ffSBarry Smith 23491cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayAndMemType()`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArrayWriteAndMemType()`, `MatDenseGetArrayRead()`, 2350cd3f9d89SJunchao Zhang `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()` 2351cd3f9d89SJunchao Zhang @*/ 23525d83a8b1SBarry Smith PetscErrorCode MatDenseGetArrayAndMemType(Mat A, PetscScalar *array[], PetscMemType *mtype) 2353cd3f9d89SJunchao Zhang { 2354cd3f9d89SJunchao Zhang PetscBool isMPI; 2355cd3f9d89SJunchao Zhang 2356cd3f9d89SJunchao Zhang PetscFunctionBegin; 2357cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 23584f572ea9SToby Isaac PetscAssertPointer(array, 2); 2359e865de01SJunchao 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 */ 2360cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2361cd3f9d89SJunchao Zhang if (isMPI) { 2362cd3f9d89SJunchao Zhang /* Dispatch here so that the code can be reused for all subclasses of MATDENSE */ 2363cd3f9d89SJunchao Zhang PetscCall(MatDenseGetArrayAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype)); 2364cd3f9d89SJunchao Zhang } else { 2365cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **, PetscMemType *); 23663ba16761SJacob Faibussowitsch 23673ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayAndMemType_C", &fptr)); 2368cd3f9d89SJunchao Zhang if (fptr) { 2369cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array, mtype)); 2370cd3f9d89SJunchao Zhang } else { 2371cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array)); 2372cd3f9d89SJunchao Zhang if (mtype) *mtype = PETSC_MEMTYPE_HOST; 2373cd3f9d89SJunchao Zhang } 2374cd3f9d89SJunchao Zhang } 23753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2376cd3f9d89SJunchao Zhang } 2377cd3f9d89SJunchao Zhang 2378cd3f9d89SJunchao Zhang /*@C 2379cd3f9d89SJunchao Zhang MatDenseRestoreArrayAndMemType - returns access to the array that is obtained by `MatDenseGetArrayAndMemType()` 2380cd3f9d89SJunchao Zhang 2381cd3f9d89SJunchao Zhang Logically Collective 2382cd3f9d89SJunchao Zhang 2383cd3f9d89SJunchao Zhang Input Parameters: 2384fe59aa6dSJacob Faibussowitsch + A - a dense matrix 2385cd3f9d89SJunchao Zhang - array - pointer to the data 2386cd3f9d89SJunchao Zhang 2387cd3f9d89SJunchao Zhang Level: intermediate 2388cd3f9d89SJunchao Zhang 23891cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 2390cd3f9d89SJunchao Zhang @*/ 23915d83a8b1SBarry Smith PetscErrorCode MatDenseRestoreArrayAndMemType(Mat A, PetscScalar *array[]) 2392cd3f9d89SJunchao Zhang { 2393cd3f9d89SJunchao Zhang PetscBool isMPI; 2394cd3f9d89SJunchao Zhang 2395cd3f9d89SJunchao Zhang PetscFunctionBegin; 2396cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 23974f572ea9SToby Isaac PetscAssertPointer(array, 2); 2398cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2399cd3f9d89SJunchao Zhang if (isMPI) { 2400cd3f9d89SJunchao Zhang PetscCall(MatDenseRestoreArrayAndMemType(((Mat_MPIDense *)A->data)->A, array)); 2401cd3f9d89SJunchao Zhang } else { 2402cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **); 24033ba16761SJacob Faibussowitsch 24043ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayAndMemType_C", &fptr)); 2405cd3f9d89SJunchao Zhang if (fptr) { 2406cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array)); 2407cd3f9d89SJunchao Zhang } else { 2408cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array)); 2409cd3f9d89SJunchao Zhang } 2410cd3f9d89SJunchao Zhang *array = NULL; 2411cd3f9d89SJunchao Zhang } 2412cd3f9d89SJunchao Zhang PetscCall(PetscObjectStateIncrease((PetscObject)A)); 24133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2414cd3f9d89SJunchao Zhang } 2415cd3f9d89SJunchao Zhang 2416cd3f9d89SJunchao Zhang /*@C 2417cd3f9d89SJunchao Zhang MatDenseGetArrayReadAndMemType - gives read-only access to the array where the data for a `MATDENSE` matrix is stored 2418cd3f9d89SJunchao Zhang 2419cd3f9d89SJunchao Zhang Logically Collective 2420cd3f9d89SJunchao Zhang 2421cd3f9d89SJunchao Zhang Input Parameter: 2422fe59aa6dSJacob Faibussowitsch . A - a dense matrix 2423cd3f9d89SJunchao Zhang 2424cd3f9d89SJunchao Zhang Output Parameters: 2425cd3f9d89SJunchao Zhang + array - pointer to the data 2426cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer 2427cd3f9d89SJunchao Zhang 2428cd3f9d89SJunchao Zhang Level: intermediate 2429cd3f9d89SJunchao Zhang 2430fb850c59SBarry Smith Note: 24312ef1f0ffSBarry Smith If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc., 24322ef1f0ffSBarry Smith an array on device is always returned and is guaranteed to contain the matrix's latest data. 24332ef1f0ffSBarry Smith 24341cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayReadAndMemType()`, `MatDenseGetArrayWriteAndMemType()`, 2435cd3f9d89SJunchao Zhang `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()` 2436cd3f9d89SJunchao Zhang @*/ 24375d83a8b1SBarry Smith PetscErrorCode MatDenseGetArrayReadAndMemType(Mat A, const PetscScalar *array[], PetscMemType *mtype) 2438cd3f9d89SJunchao Zhang { 2439cd3f9d89SJunchao Zhang PetscBool isMPI; 2440cd3f9d89SJunchao Zhang 2441cd3f9d89SJunchao Zhang PetscFunctionBegin; 2442cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 24434f572ea9SToby Isaac PetscAssertPointer(array, 2); 2444e865de01SJunchao 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 */ 2445cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2446cd3f9d89SJunchao Zhang if (isMPI) { /* Dispatch here so that the code can be reused for all subclasses of MATDENSE */ 2447cd3f9d89SJunchao Zhang PetscCall(MatDenseGetArrayReadAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype)); 2448cd3f9d89SJunchao Zhang } else { 2449cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, const PetscScalar **, PetscMemType *); 24503ba16761SJacob Faibussowitsch 24513ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayReadAndMemType_C", &fptr)); 2452cd3f9d89SJunchao Zhang if (fptr) { 2453cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array, mtype)); 2454cd3f9d89SJunchao Zhang } else { 24555c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 2456cd3f9d89SJunchao Zhang if (mtype) *mtype = PETSC_MEMTYPE_HOST; 2457cd3f9d89SJunchao Zhang } 2458cd3f9d89SJunchao Zhang } 24593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2460cd3f9d89SJunchao Zhang } 2461cd3f9d89SJunchao Zhang 2462cd3f9d89SJunchao Zhang /*@C 2463cd3f9d89SJunchao Zhang MatDenseRestoreArrayReadAndMemType - returns access to the array that is obtained by `MatDenseGetArrayReadAndMemType()` 2464cd3f9d89SJunchao Zhang 2465cd3f9d89SJunchao Zhang Logically Collective 2466cd3f9d89SJunchao Zhang 2467cd3f9d89SJunchao Zhang Input Parameters: 2468fe59aa6dSJacob Faibussowitsch + A - a dense matrix 2469cd3f9d89SJunchao Zhang - array - pointer to the data 2470cd3f9d89SJunchao Zhang 2471cd3f9d89SJunchao Zhang Level: intermediate 2472cd3f9d89SJunchao Zhang 24731cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 2474cd3f9d89SJunchao Zhang @*/ 24755d83a8b1SBarry Smith PetscErrorCode MatDenseRestoreArrayReadAndMemType(Mat A, const PetscScalar *array[]) 2476cd3f9d89SJunchao Zhang { 2477cd3f9d89SJunchao Zhang PetscBool isMPI; 2478cd3f9d89SJunchao Zhang 2479cd3f9d89SJunchao Zhang PetscFunctionBegin; 2480cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 24814f572ea9SToby Isaac PetscAssertPointer(array, 2); 2482cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2483cd3f9d89SJunchao Zhang if (isMPI) { 2484cd3f9d89SJunchao Zhang PetscCall(MatDenseRestoreArrayReadAndMemType(((Mat_MPIDense *)A->data)->A, array)); 2485cd3f9d89SJunchao Zhang } else { 2486cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, const PetscScalar **); 24873ba16761SJacob Faibussowitsch 24883ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayReadAndMemType_C", &fptr)); 2489cd3f9d89SJunchao Zhang if (fptr) { 2490cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array)); 2491cd3f9d89SJunchao Zhang } else { 24925c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 2493cd3f9d89SJunchao Zhang } 2494cd3f9d89SJunchao Zhang *array = NULL; 2495cd3f9d89SJunchao Zhang } 24963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2497cd3f9d89SJunchao Zhang } 2498cd3f9d89SJunchao Zhang 2499cd3f9d89SJunchao Zhang /*@C 2500cd3f9d89SJunchao Zhang MatDenseGetArrayWriteAndMemType - gives write-only access to the array where the data for a `MATDENSE` matrix is stored 2501cd3f9d89SJunchao Zhang 2502cd3f9d89SJunchao Zhang Logically Collective 2503cd3f9d89SJunchao Zhang 2504cd3f9d89SJunchao Zhang Input Parameter: 2505fe59aa6dSJacob Faibussowitsch . A - a dense matrix 2506cd3f9d89SJunchao Zhang 2507cd3f9d89SJunchao Zhang Output Parameters: 2508cd3f9d89SJunchao Zhang + array - pointer to the data 2509cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer 2510cd3f9d89SJunchao Zhang 2511cd3f9d89SJunchao Zhang Level: intermediate 2512cd3f9d89SJunchao Zhang 2513fb850c59SBarry Smith Note: 25142ef1f0ffSBarry Smith If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc., 25152ef1f0ffSBarry Smith an array on device is always returned and is guaranteed to contain the matrix's latest data. 25162ef1f0ffSBarry Smith 25171cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayWriteAndMemType()`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArrayRead()`, 2518cd3f9d89SJunchao Zhang `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()` 2519cd3f9d89SJunchao Zhang @*/ 25205d83a8b1SBarry Smith PetscErrorCode MatDenseGetArrayWriteAndMemType(Mat A, PetscScalar *array[], PetscMemType *mtype) 2521cd3f9d89SJunchao Zhang { 2522cd3f9d89SJunchao Zhang PetscBool isMPI; 2523cd3f9d89SJunchao Zhang 2524cd3f9d89SJunchao Zhang PetscFunctionBegin; 2525cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 25264f572ea9SToby Isaac PetscAssertPointer(array, 2); 2527e865de01SJunchao 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 */ 2528cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2529cd3f9d89SJunchao Zhang if (isMPI) { 2530cd3f9d89SJunchao Zhang PetscCall(MatDenseGetArrayWriteAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype)); 2531cd3f9d89SJunchao Zhang } else { 2532cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **, PetscMemType *); 25333ba16761SJacob Faibussowitsch 25343ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayWriteAndMemType_C", &fptr)); 2535cd3f9d89SJunchao Zhang if (fptr) { 2536cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array, mtype)); 2537cd3f9d89SJunchao Zhang } else { 2538cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array)); 2539cd3f9d89SJunchao Zhang if (mtype) *mtype = PETSC_MEMTYPE_HOST; 2540cd3f9d89SJunchao Zhang } 2541cd3f9d89SJunchao Zhang } 25423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2543cd3f9d89SJunchao Zhang } 2544cd3f9d89SJunchao Zhang 2545cd3f9d89SJunchao Zhang /*@C 2546cd3f9d89SJunchao Zhang MatDenseRestoreArrayWriteAndMemType - returns access to the array that is obtained by `MatDenseGetArrayReadAndMemType()` 2547cd3f9d89SJunchao Zhang 2548cd3f9d89SJunchao Zhang Logically Collective 2549cd3f9d89SJunchao Zhang 2550cd3f9d89SJunchao Zhang Input Parameters: 2551fe59aa6dSJacob Faibussowitsch + A - a dense matrix 2552cd3f9d89SJunchao Zhang - array - pointer to the data 2553cd3f9d89SJunchao Zhang 2554cd3f9d89SJunchao Zhang Level: intermediate 2555cd3f9d89SJunchao Zhang 25561cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayWriteAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 2557cd3f9d89SJunchao Zhang @*/ 25585d83a8b1SBarry Smith PetscErrorCode MatDenseRestoreArrayWriteAndMemType(Mat A, PetscScalar *array[]) 2559cd3f9d89SJunchao Zhang { 2560cd3f9d89SJunchao Zhang PetscBool isMPI; 2561cd3f9d89SJunchao Zhang 2562cd3f9d89SJunchao Zhang PetscFunctionBegin; 2563cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 25644f572ea9SToby Isaac PetscAssertPointer(array, 2); 2565cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2566cd3f9d89SJunchao Zhang if (isMPI) { 2567cd3f9d89SJunchao Zhang PetscCall(MatDenseRestoreArrayWriteAndMemType(((Mat_MPIDense *)A->data)->A, array)); 2568cd3f9d89SJunchao Zhang } else { 2569cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **); 25703ba16761SJacob Faibussowitsch 25713ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayWriteAndMemType_C", &fptr)); 2572cd3f9d89SJunchao Zhang if (fptr) { 2573cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array)); 2574cd3f9d89SJunchao Zhang } else { 2575cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array)); 2576cd3f9d89SJunchao Zhang } 2577cd3f9d89SJunchao Zhang *array = NULL; 2578cd3f9d89SJunchao Zhang } 2579cd3f9d89SJunchao Zhang PetscCall(PetscObjectStateIncrease((PetscObject)A)); 25803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2581cd3f9d89SJunchao Zhang } 2582cd3f9d89SJunchao Zhang 2583d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A, IS isrow, IS iscol, MatReuse scall, Mat *B) 2584d71ae5a4SJacob Faibussowitsch { 2585c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 2586bf5a80bcSToby Isaac PetscInt i, j, nrows, ncols, ldb; 25875d0c19d7SBarry Smith const PetscInt *irow, *icol; 258887828ca2SBarry Smith PetscScalar *av, *bv, *v = mat->v; 25890754003eSLois Curfman McInnes Mat newmat; 25900754003eSLois Curfman McInnes 25913a40ed3dSBarry Smith PetscFunctionBegin; 25929566063dSJacob Faibussowitsch PetscCall(ISGetIndices(isrow, &irow)); 25939566063dSJacob Faibussowitsch PetscCall(ISGetIndices(iscol, &icol)); 25949566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(isrow, &nrows)); 25959566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(iscol, &ncols)); 25960754003eSLois Curfman McInnes 2597182d2002SSatish Balay /* Check submatrixcall */ 2598182d2002SSatish Balay if (scall == MAT_REUSE_MATRIX) { 259913f74950SBarry Smith PetscInt n_cols, n_rows; 26009566063dSJacob Faibussowitsch PetscCall(MatGetSize(*B, &n_rows, &n_cols)); 260121a2c019SBarry Smith if (n_rows != nrows || n_cols != ncols) { 2602f746d493SDmitry Karpeev /* resize the result matrix to match number of requested rows/columns */ 26039566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*B, nrows, ncols, nrows, ncols)); 260421a2c019SBarry Smith } 2605182d2002SSatish Balay newmat = *B; 2606182d2002SSatish Balay } else { 26070754003eSLois Curfman McInnes /* Create and fill new matrix */ 26089566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &newmat)); 26099566063dSJacob Faibussowitsch PetscCall(MatSetSizes(newmat, nrows, ncols, nrows, ncols)); 26109566063dSJacob Faibussowitsch PetscCall(MatSetType(newmat, ((PetscObject)A)->type_name)); 26119566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(newmat, NULL)); 2612182d2002SSatish Balay } 2613182d2002SSatish Balay 2614182d2002SSatish Balay /* Now extract the data pointers and do the copy,column at a time */ 26159566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(newmat, &bv)); 26169566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(newmat, &ldb)); 2617182d2002SSatish Balay for (i = 0; i < ncols; i++) { 26186de62eeeSBarry Smith av = v + mat->lda * icol[i]; 2619ca15aa20SStefano Zampini for (j = 0; j < nrows; j++) bv[j] = av[irow[j]]; 2620bf5a80bcSToby Isaac bv += ldb; 26210754003eSLois Curfman McInnes } 26229566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(newmat, &bv)); 2623182d2002SSatish Balay 2624182d2002SSatish Balay /* Assemble the matrices so that the correct flags are set */ 26259566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(newmat, MAT_FINAL_ASSEMBLY)); 26269566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(newmat, MAT_FINAL_ASSEMBLY)); 26270754003eSLois Curfman McInnes 26280754003eSLois Curfman McInnes /* Free work space */ 26299566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(isrow, &irow)); 26309566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(iscol, &icol)); 2631182d2002SSatish Balay *B = newmat; 26323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26330754003eSLois Curfman McInnes } 26340754003eSLois Curfman McInnes 2635d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A, PetscInt n, const IS irow[], const IS icol[], MatReuse scall, Mat *B[]) 2636d71ae5a4SJacob Faibussowitsch { 263713f74950SBarry Smith PetscInt i; 2638905e6a2fSBarry Smith 26393a40ed3dSBarry Smith PetscFunctionBegin; 264048a46eb9SPierre Jolivet if (scall == MAT_INITIAL_MATRIX) PetscCall(PetscCalloc1(n, B)); 2641905e6a2fSBarry Smith 264248a46eb9SPierre Jolivet for (i = 0; i < n; i++) PetscCall(MatCreateSubMatrix_SeqDense(A, irow[i], icol[i], scall, &(*B)[i])); 26433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2644905e6a2fSBarry Smith } 2645905e6a2fSBarry Smith 2646d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat, MatAssemblyType mode) 2647d71ae5a4SJacob Faibussowitsch { 2648c0aa2d19SHong Zhang PetscFunctionBegin; 26493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2650c0aa2d19SHong Zhang } 2651c0aa2d19SHong Zhang 2652d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat, MatAssemblyType mode) 2653d71ae5a4SJacob Faibussowitsch { 2654c0aa2d19SHong Zhang PetscFunctionBegin; 26553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2656c0aa2d19SHong Zhang } 2657c0aa2d19SHong Zhang 2658d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCopy_SeqDense(Mat A, Mat B, MatStructure str) 2659d71ae5a4SJacob Faibussowitsch { 26604b0e389bSBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data; 2661ca15aa20SStefano Zampini const PetscScalar *va; 2662ca15aa20SStefano Zampini PetscScalar *vb; 2663d0f46423SBarry Smith PetscInt lda1 = a->lda, lda2 = b->lda, m = A->rmap->n, n = A->cmap->n, j; 26643a40ed3dSBarry Smith 26653a40ed3dSBarry Smith PetscFunctionBegin; 266633f4a19fSKris Buschelman /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */ 266733f4a19fSKris Buschelman if (A->ops->copy != B->ops->copy) { 26689566063dSJacob Faibussowitsch PetscCall(MatCopy_Basic(A, B, str)); 26693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26703a40ed3dSBarry Smith } 2671aed4548fSBarry Smith PetscCheck(m == B->rmap->n && n == B->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "size(B) != size(A)"); 26729566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &va)); 26739566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(B, &vb)); 2674a5ce6ee0Svictorle if (lda1 > m || lda2 > m) { 267548a46eb9SPierre Jolivet for (j = 0; j < n; j++) PetscCall(PetscArraycpy(vb + j * lda2, va + j * lda1, m)); 2676a5ce6ee0Svictorle } else { 26779566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(vb, va, A->rmap->n * A->cmap->n)); 2678a5ce6ee0Svictorle } 26799566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(B, &vb)); 26809566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &va)); 26819566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 26829566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 26833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2684273d9f13SBarry Smith } 2685273d9f13SBarry Smith 2686d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetUp_SeqDense(Mat A) 2687d71ae5a4SJacob Faibussowitsch { 2688273d9f13SBarry Smith PetscFunctionBegin; 26899566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 26909566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 269148a46eb9SPierre Jolivet if (!A->preallocated) PetscCall(MatSeqDenseSetPreallocation(A, NULL)); 26923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26934b0e389bSBarry Smith } 26944b0e389bSBarry Smith 2695d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatConjugate_SeqDense(Mat A) 2696d71ae5a4SJacob Faibussowitsch { 26974396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 269806c5243aSJose E. Roman PetscInt i, j; 26994396437dSToby Isaac PetscInt min = PetscMin(A->rmap->n, A->cmap->n); 2700ca15aa20SStefano Zampini PetscScalar *aa; 2701ba337c44SJed Brown 2702ba337c44SJed Brown PetscFunctionBegin; 27039566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 270406c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 270506c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscConj(aa[i + j * mat->lda]); 270606c5243aSJose E. Roman } 27079566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 27089371c9d4SSatish Balay if (mat->tau) 27099371c9d4SSatish Balay for (i = 0; i < min; i++) mat->tau[i] = PetscConj(mat->tau[i]); 27103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2711ba337c44SJed Brown } 2712ba337c44SJed Brown 2713d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRealPart_SeqDense(Mat A) 2714d71ae5a4SJacob Faibussowitsch { 271506c5243aSJose E. Roman Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 271606c5243aSJose E. Roman PetscInt i, j; 2717ca15aa20SStefano Zampini PetscScalar *aa; 2718ba337c44SJed Brown 2719ba337c44SJed Brown PetscFunctionBegin; 27209566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 272106c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 272206c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscRealPart(aa[i + j * mat->lda]); 272306c5243aSJose E. Roman } 27249566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 27253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2726ba337c44SJed Brown } 2727ba337c44SJed Brown 2728d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatImaginaryPart_SeqDense(Mat A) 2729d71ae5a4SJacob Faibussowitsch { 273006c5243aSJose E. Roman Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 273106c5243aSJose E. Roman PetscInt i, j; 2732ca15aa20SStefano Zampini PetscScalar *aa; 2733ba337c44SJed Brown 2734ba337c44SJed Brown PetscFunctionBegin; 27359566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 273606c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 273706c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscImaginaryPart(aa[i + j * mat->lda]); 273806c5243aSJose E. Roman } 27399566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 27403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2741ba337c44SJed Brown } 2742284134d9SBarry Smith 2743d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2744d71ae5a4SJacob Faibussowitsch { 2745d0f46423SBarry Smith PetscInt m = A->rmap->n, n = B->cmap->n; 274647d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 2747a9fe9ddaSSatish Balay 2748ee16a9a1SHong Zhang PetscFunctionBegin; 27499566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 275047d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 27519566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 275247d993e7Ssuyashtn #endif 275347d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 275447d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 275547d993e7Ssuyashtn #endif 27567a3c3d58SStefano Zampini if (!cisdense) { 27577a3c3d58SStefano Zampini PetscBool flg; 27587a3c3d58SStefano Zampini 27599566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 27609566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 27617a3c3d58SStefano Zampini } 27629566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 27633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2764ee16a9a1SHong Zhang } 2765a9fe9ddaSSatish Balay 2766d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2767d71ae5a4SJacob Faibussowitsch { 27686718818eSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data, *c = (Mat_SeqDense *)C->data; 27690805154bSBarry Smith PetscBLASInt m, n, k; 2770ca15aa20SStefano Zampini const PetscScalar *av, *bv; 2771ca15aa20SStefano Zampini PetscScalar *cv; 2772a9fe9ddaSSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 2773a9fe9ddaSSatish Balay 2774a9fe9ddaSSatish Balay PetscFunctionBegin; 27759566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 27769566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 27779566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 27783ba16761SJacob Faibussowitsch if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS); 27799566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 27809566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 27819566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2782792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("N", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 27839566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 27849566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 27859566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 27869566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 27873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2788a9fe9ddaSSatish Balay } 2789a9fe9ddaSSatish Balay 2790d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2791d71ae5a4SJacob Faibussowitsch { 279269f65d41SStefano Zampini PetscInt m = A->rmap->n, n = B->rmap->n; 279347d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 279469f65d41SStefano Zampini 279569f65d41SStefano Zampini PetscFunctionBegin; 27969566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 279747d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 27989566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 279947d993e7Ssuyashtn #endif 280047d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 280147d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 280247d993e7Ssuyashtn #endif 28037a3c3d58SStefano Zampini if (!cisdense) { 28047a3c3d58SStefano Zampini PetscBool flg; 28057a3c3d58SStefano Zampini 28069566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 28079566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 28087a3c3d58SStefano Zampini } 28099566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 28103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 281169f65d41SStefano Zampini } 281269f65d41SStefano Zampini 2813d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2814d71ae5a4SJacob Faibussowitsch { 281569f65d41SStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 281669f65d41SStefano Zampini Mat_SeqDense *b = (Mat_SeqDense *)B->data; 281769f65d41SStefano Zampini Mat_SeqDense *c = (Mat_SeqDense *)C->data; 28186718818eSStefano Zampini const PetscScalar *av, *bv; 28196718818eSStefano Zampini PetscScalar *cv; 282069f65d41SStefano Zampini PetscBLASInt m, n, k; 282169f65d41SStefano Zampini PetscScalar _DOne = 1.0, _DZero = 0.0; 282269f65d41SStefano Zampini 282369f65d41SStefano Zampini PetscFunctionBegin; 28249566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 28259566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 28269566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 28273ba16761SJacob Faibussowitsch if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS); 28289566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 28299566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 28309566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2831792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("N", "T", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 28329566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 28339566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 28349566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 28359566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 28363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 283769f65d41SStefano Zampini } 283869f65d41SStefano Zampini 2839d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2840d71ae5a4SJacob Faibussowitsch { 2841d0f46423SBarry Smith PetscInt m = A->cmap->n, n = B->cmap->n; 284247d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 2843a9fe9ddaSSatish Balay 2844ee16a9a1SHong Zhang PetscFunctionBegin; 28459566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 284647d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 28479566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 284847d993e7Ssuyashtn #endif 284947d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 285047d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 285147d993e7Ssuyashtn #endif 28527a3c3d58SStefano Zampini if (!cisdense) { 28537a3c3d58SStefano Zampini PetscBool flg; 28547a3c3d58SStefano Zampini 28559566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 28569566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 28577a3c3d58SStefano Zampini } 28589566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 28593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2860ee16a9a1SHong Zhang } 2861a9fe9ddaSSatish Balay 2862d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2863d71ae5a4SJacob Faibussowitsch { 2864a9fe9ddaSSatish Balay Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2865a9fe9ddaSSatish Balay Mat_SeqDense *b = (Mat_SeqDense *)B->data; 2866a9fe9ddaSSatish Balay Mat_SeqDense *c = (Mat_SeqDense *)C->data; 28676718818eSStefano Zampini const PetscScalar *av, *bv; 28686718818eSStefano Zampini PetscScalar *cv; 28690805154bSBarry Smith PetscBLASInt m, n, k; 2870a9fe9ddaSSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 2871a9fe9ddaSSatish Balay 2872a9fe9ddaSSatish Balay PetscFunctionBegin; 28739566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 28749566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 28759566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &k)); 28763ba16761SJacob Faibussowitsch if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS); 28779566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 28789566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 28799566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2880792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("T", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 28819566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 28829566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 28839566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 28849566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 28853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2886a9fe9ddaSSatish Balay } 2887985db425SBarry Smith 2888d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C) 2889d71ae5a4SJacob Faibussowitsch { 28904222ddf1SHong Zhang PetscFunctionBegin; 28914222ddf1SHong Zhang C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense; 28924222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AB; 28933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28944222ddf1SHong Zhang } 28954222ddf1SHong Zhang 2896d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C) 2897d71ae5a4SJacob Faibussowitsch { 28984222ddf1SHong Zhang PetscFunctionBegin; 28994222ddf1SHong Zhang C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense; 29004222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AtB; 29013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29024222ddf1SHong Zhang } 29034222ddf1SHong Zhang 2904d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C) 2905d71ae5a4SJacob Faibussowitsch { 29064222ddf1SHong Zhang PetscFunctionBegin; 29074222ddf1SHong Zhang C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense; 29084222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_ABt; 29093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29104222ddf1SHong Zhang } 29114222ddf1SHong Zhang 2912d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C) 2913d71ae5a4SJacob Faibussowitsch { 29144222ddf1SHong Zhang Mat_Product *product = C->product; 29154222ddf1SHong Zhang 29164222ddf1SHong Zhang PetscFunctionBegin; 29174222ddf1SHong Zhang switch (product->type) { 2918d71ae5a4SJacob Faibussowitsch case MATPRODUCT_AB: 2919d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_AB(C)); 2920d71ae5a4SJacob Faibussowitsch break; 2921d71ae5a4SJacob Faibussowitsch case MATPRODUCT_AtB: 2922d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_AtB(C)); 2923d71ae5a4SJacob Faibussowitsch break; 2924d71ae5a4SJacob Faibussowitsch case MATPRODUCT_ABt: 2925d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_ABt(C)); 2926d71ae5a4SJacob Faibussowitsch break; 2927d71ae5a4SJacob Faibussowitsch default: 2928d71ae5a4SJacob Faibussowitsch break; 29294222ddf1SHong Zhang } 29303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29314222ddf1SHong Zhang } 29324222ddf1SHong Zhang 2933d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMax_SeqDense(Mat A, Vec v, PetscInt idx[]) 2934d71ae5a4SJacob Faibussowitsch { 2935985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2936d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2937985db425SBarry Smith PetscScalar *x; 2938ca15aa20SStefano Zampini const PetscScalar *aa; 2939985db425SBarry Smith 2940985db425SBarry Smith PetscFunctionBegin; 294128b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29429566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29439566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 29449566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 294508401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2946985db425SBarry Smith for (i = 0; i < m; i++) { 29479371c9d4SSatish Balay x[i] = aa[i]; 29489371c9d4SSatish Balay if (idx) idx[i] = 0; 2949985db425SBarry Smith for (j = 1; j < n; j++) { 29509371c9d4SSatish Balay if (PetscRealPart(x[i]) < PetscRealPart(aa[i + a->lda * j])) { 29519371c9d4SSatish Balay x[i] = aa[i + a->lda * j]; 29529371c9d4SSatish Balay if (idx) idx[i] = j; 29539371c9d4SSatish Balay } 2954985db425SBarry Smith } 2955985db425SBarry Smith } 29569566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 29579566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 29583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2959985db425SBarry Smith } 2960985db425SBarry Smith 2961d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A, Vec v, PetscInt idx[]) 2962d71ae5a4SJacob Faibussowitsch { 2963985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2964d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2965985db425SBarry Smith PetscScalar *x; 2966985db425SBarry Smith PetscReal atmp; 2967ca15aa20SStefano Zampini const PetscScalar *aa; 2968985db425SBarry Smith 2969985db425SBarry Smith PetscFunctionBegin; 297028b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29719566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29729566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 29739566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 297408401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2975985db425SBarry Smith for (i = 0; i < m; i++) { 29769189402eSHong Zhang x[i] = PetscAbsScalar(aa[i]); 2977985db425SBarry Smith for (j = 1; j < n; j++) { 2978ca15aa20SStefano Zampini atmp = PetscAbsScalar(aa[i + a->lda * j]); 29799371c9d4SSatish Balay if (PetscAbsScalar(x[i]) < atmp) { 29809371c9d4SSatish Balay x[i] = atmp; 29819371c9d4SSatish Balay if (idx) idx[i] = j; 29829371c9d4SSatish Balay } 2983985db425SBarry Smith } 2984985db425SBarry Smith } 29859566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 29869566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 29873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2988985db425SBarry Smith } 2989985db425SBarry Smith 2990d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMin_SeqDense(Mat A, Vec v, PetscInt idx[]) 2991d71ae5a4SJacob Faibussowitsch { 2992985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2993d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2994985db425SBarry Smith PetscScalar *x; 2995ca15aa20SStefano Zampini const PetscScalar *aa; 2996985db425SBarry Smith 2997985db425SBarry Smith PetscFunctionBegin; 299828b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29999566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 30009566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 30019566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 300208401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 3003985db425SBarry Smith for (i = 0; i < m; i++) { 30049371c9d4SSatish Balay x[i] = aa[i]; 30059371c9d4SSatish Balay if (idx) idx[i] = 0; 3006985db425SBarry Smith for (j = 1; j < n; j++) { 30079371c9d4SSatish Balay if (PetscRealPart(x[i]) > PetscRealPart(aa[i + a->lda * j])) { 30089371c9d4SSatish Balay x[i] = aa[i + a->lda * j]; 30099371c9d4SSatish Balay if (idx) idx[i] = j; 30109371c9d4SSatish Balay } 3011985db425SBarry Smith } 3012985db425SBarry Smith } 30139566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 30149566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 30153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3016985db425SBarry Smith } 3017985db425SBarry Smith 3018d71ae5a4SJacob Faibussowitsch PetscErrorCode MatGetColumnVector_SeqDense(Mat A, Vec v, PetscInt col) 3019d71ae5a4SJacob Faibussowitsch { 30208d0534beSBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 30218d0534beSBarry Smith PetscScalar *x; 3022ca15aa20SStefano Zampini const PetscScalar *aa; 30238d0534beSBarry Smith 30248d0534beSBarry Smith PetscFunctionBegin; 302528b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 30269566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 30279566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 30289566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(x, aa + col * a->lda, A->rmap->n)); 30299566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 30309566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 30313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30328d0534beSBarry Smith } 30338d0534beSBarry Smith 3034d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatGetColumnReductions_SeqDense(Mat A, PetscInt type, PetscReal *reductions) 3035d71ae5a4SJacob Faibussowitsch { 30360716a85fSBarry Smith PetscInt i, j, m, n; 30371683a169SBarry Smith const PetscScalar *a; 30380716a85fSBarry Smith 30390716a85fSBarry Smith PetscFunctionBegin; 30409566063dSJacob Faibussowitsch PetscCall(MatGetSize(A, &m, &n)); 30419566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(reductions, n)); 30429566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &a)); 3043857cbf51SRichard Tran Mills if (type == NORM_2) { 30440716a85fSBarry Smith for (i = 0; i < n; i++) { 3045ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j] * a[j]); 304616cd844bSPierre Jolivet a = PetscSafePointerPlusOffset(a, m); 30470716a85fSBarry Smith } 3048857cbf51SRichard Tran Mills } else if (type == NORM_1) { 30490716a85fSBarry Smith for (i = 0; i < n; i++) { 3050ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j]); 305116cd844bSPierre Jolivet a = PetscSafePointerPlusOffset(a, m); 30520716a85fSBarry Smith } 3053857cbf51SRichard Tran Mills } else if (type == NORM_INFINITY) { 30540716a85fSBarry Smith for (i = 0; i < n; i++) { 3055ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] = PetscMax(PetscAbsScalar(a[j]), reductions[i]); 305616cd844bSPierre Jolivet a = PetscSafePointerPlusOffset(a, m); 30570716a85fSBarry Smith } 3058857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_REALPART || type == REDUCTION_MEAN_REALPART) { 3059a873a8cdSSam Reynolds for (i = 0; i < n; i++) { 3060ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscRealPart(a[j]); 306116cd844bSPierre Jolivet a = PetscSafePointerPlusOffset(a, m); 3062a873a8cdSSam Reynolds } 3063857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_IMAGINARYPART || type == REDUCTION_MEAN_IMAGINARYPART) { 3064857cbf51SRichard Tran Mills for (i = 0; i < n; i++) { 3065ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscImaginaryPart(a[j]); 306616cd844bSPierre Jolivet a = PetscSafePointerPlusOffset(a, m); 3067857cbf51SRichard Tran Mills } 3068857cbf51SRichard Tran Mills } else SETERRQ(PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Unknown reduction type"); 30699566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &a)); 3070857cbf51SRichard Tran Mills if (type == NORM_2) { 3071a873a8cdSSam Reynolds for (i = 0; i < n; i++) reductions[i] = PetscSqrtReal(reductions[i]); 3072857cbf51SRichard Tran Mills } else if (type == REDUCTION_MEAN_REALPART || type == REDUCTION_MEAN_IMAGINARYPART) { 3073a873a8cdSSam Reynolds for (i = 0; i < n; i++) reductions[i] /= m; 30740716a85fSBarry Smith } 30753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30760716a85fSBarry Smith } 30770716a85fSBarry Smith 3078d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetRandom_SeqDense(Mat x, PetscRandom rctx) 3079d71ae5a4SJacob Faibussowitsch { 308073a71a0fSBarry Smith PetscScalar *a; 3081637a0070SStefano Zampini PetscInt lda, m, n, i, j; 308273a71a0fSBarry Smith 308373a71a0fSBarry Smith PetscFunctionBegin; 30849566063dSJacob Faibussowitsch PetscCall(MatGetSize(x, &m, &n)); 30859566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(x, &lda)); 30863faff063SStefano Zampini PetscCall(MatDenseGetArrayWrite(x, &a)); 3087637a0070SStefano Zampini for (j = 0; j < n; j++) { 308848a46eb9SPierre Jolivet for (i = 0; i < m; i++) PetscCall(PetscRandomGetValue(rctx, a + j * lda + i)); 308973a71a0fSBarry Smith } 30903faff063SStefano Zampini PetscCall(MatDenseRestoreArrayWrite(x, &a)); 30913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 309273a71a0fSBarry Smith } 309373a71a0fSBarry Smith 3094d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A, PetscBool *missing, PetscInt *d) 3095d71ae5a4SJacob Faibussowitsch { 30963b49f96aSBarry Smith PetscFunctionBegin; 30973b49f96aSBarry Smith *missing = PETSC_FALSE; 30983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30993b49f96aSBarry Smith } 310073a71a0fSBarry Smith 3101ca15aa20SStefano Zampini /* vals is not const */ 3102d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A, PetscInt col, PetscScalar **vals) 3103d71ae5a4SJacob Faibussowitsch { 310486aefd0dSHong Zhang Mat_SeqDense *a = (Mat_SeqDense *)A->data; 3105ca15aa20SStefano Zampini PetscScalar *v; 310686aefd0dSHong Zhang 310786aefd0dSHong Zhang PetscFunctionBegin; 310828b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 31099566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 3110ca15aa20SStefano Zampini *vals = v + col * a->lda; 31119566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 31123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 311386aefd0dSHong Zhang } 311486aefd0dSHong Zhang 3115d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A, PetscScalar **vals) 3116d71ae5a4SJacob Faibussowitsch { 311786aefd0dSHong Zhang PetscFunctionBegin; 3118742765d3SMatthew Knepley if (vals) *vals = NULL; /* user cannot accidentally use the array later */ 31193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 312086aefd0dSHong Zhang } 3121abc3b08eSStefano Zampini 3122a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqDense, 3123905e6a2fSBarry Smith MatGetRow_SeqDense, 3124905e6a2fSBarry Smith MatRestoreRow_SeqDense, 3125905e6a2fSBarry Smith MatMult_SeqDense, 312697304618SKris Buschelman /* 4*/ MatMultAdd_SeqDense, 31277c922b88SBarry Smith MatMultTranspose_SeqDense, 31287c922b88SBarry Smith MatMultTransposeAdd_SeqDense, 3129f4259b30SLisandro Dalcin NULL, 3130f4259b30SLisandro Dalcin NULL, 3131f4259b30SLisandro Dalcin NULL, 3132f4259b30SLisandro Dalcin /* 10*/ NULL, 3133905e6a2fSBarry Smith MatLUFactor_SeqDense, 3134905e6a2fSBarry Smith MatCholeskyFactor_SeqDense, 313541f059aeSBarry Smith MatSOR_SeqDense, 3136ec8511deSBarry Smith MatTranspose_SeqDense, 313797304618SKris Buschelman /* 15*/ MatGetInfo_SeqDense, 3138905e6a2fSBarry Smith MatEqual_SeqDense, 3139905e6a2fSBarry Smith MatGetDiagonal_SeqDense, 3140905e6a2fSBarry Smith MatDiagonalScale_SeqDense, 3141905e6a2fSBarry Smith MatNorm_SeqDense, 3142c0aa2d19SHong Zhang /* 20*/ MatAssemblyBegin_SeqDense, 3143c0aa2d19SHong Zhang MatAssemblyEnd_SeqDense, 3144905e6a2fSBarry Smith MatSetOption_SeqDense, 3145905e6a2fSBarry Smith MatZeroEntries_SeqDense, 3146d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqDense, 3147f4259b30SLisandro Dalcin NULL, 3148f4259b30SLisandro Dalcin NULL, 3149f4259b30SLisandro Dalcin NULL, 3150f4259b30SLisandro Dalcin NULL, 31514994cf47SJed Brown /* 29*/ MatSetUp_SeqDense, 3152f4259b30SLisandro Dalcin NULL, 3153f4259b30SLisandro Dalcin NULL, 3154f4259b30SLisandro Dalcin NULL, 3155f4259b30SLisandro Dalcin NULL, 3156d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqDense, 3157f4259b30SLisandro Dalcin NULL, 3158f4259b30SLisandro Dalcin NULL, 3159f4259b30SLisandro Dalcin NULL, 3160f4259b30SLisandro Dalcin NULL, 3161d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqDense, 31627dae84e0SHong Zhang MatCreateSubMatrices_SeqDense, 3163f4259b30SLisandro Dalcin NULL, 31644b0e389bSBarry Smith MatGetValues_SeqDense, 3165a5ae1ecdSBarry Smith MatCopy_SeqDense, 3166d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqDense, 3167a5ae1ecdSBarry Smith MatScale_SeqDense, 31682f605a99SJose E. Roman MatShift_SeqDense, 3169f4259b30SLisandro Dalcin NULL, 31703f49a652SStefano Zampini MatZeroRowsColumns_SeqDense, 317173a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqDense, 3172f4259b30SLisandro Dalcin NULL, 3173f4259b30SLisandro Dalcin NULL, 3174f4259b30SLisandro Dalcin NULL, 3175f4259b30SLisandro Dalcin NULL, 3176f4259b30SLisandro Dalcin /* 54*/ NULL, 3177f4259b30SLisandro Dalcin NULL, 3178f4259b30SLisandro Dalcin NULL, 3179f4259b30SLisandro Dalcin NULL, 3180f4259b30SLisandro Dalcin NULL, 3181023c16fcSToby Isaac /* 59*/ MatCreateSubMatrix_SeqDense, 3182e03a110bSBarry Smith MatDestroy_SeqDense, 3183e03a110bSBarry Smith MatView_SeqDense, 3184f4259b30SLisandro Dalcin NULL, 3185f4259b30SLisandro Dalcin NULL, 3186f4259b30SLisandro Dalcin /* 64*/ NULL, 3187f4259b30SLisandro Dalcin NULL, 3188f4259b30SLisandro Dalcin NULL, 3189f4259b30SLisandro Dalcin NULL, 3190f4259b30SLisandro Dalcin NULL, 3191d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqDense, 3192f4259b30SLisandro Dalcin NULL, 3193f4259b30SLisandro Dalcin NULL, 3194f4259b30SLisandro Dalcin NULL, 3195f4259b30SLisandro Dalcin NULL, 3196f4259b30SLisandro Dalcin /* 74*/ NULL, 3197f4259b30SLisandro Dalcin NULL, 3198f4259b30SLisandro Dalcin NULL, 3199f4259b30SLisandro Dalcin NULL, 3200f4259b30SLisandro Dalcin NULL, 3201f4259b30SLisandro Dalcin /* 79*/ NULL, 3202f4259b30SLisandro Dalcin NULL, 3203f4259b30SLisandro Dalcin NULL, 3204f4259b30SLisandro Dalcin NULL, 32055bba2384SShri Abhyankar /* 83*/ MatLoad_SeqDense, 3206637a0070SStefano Zampini MatIsSymmetric_SeqDense, 32071cbb95d3SBarry Smith MatIsHermitian_SeqDense, 3208f4259b30SLisandro Dalcin NULL, 3209f4259b30SLisandro Dalcin NULL, 3210f4259b30SLisandro Dalcin NULL, 3211f4259b30SLisandro Dalcin /* 89*/ NULL, 3212f4259b30SLisandro Dalcin NULL, 3213a9fe9ddaSSatish Balay MatMatMultNumeric_SeqDense_SeqDense, 3214f4259b30SLisandro Dalcin NULL, 3215f4259b30SLisandro Dalcin NULL, 3216f4259b30SLisandro Dalcin /* 94*/ NULL, 3217f4259b30SLisandro Dalcin NULL, 3218f4259b30SLisandro Dalcin NULL, 321969f65d41SStefano Zampini MatMatTransposeMultNumeric_SeqDense_SeqDense, 3220f4259b30SLisandro Dalcin NULL, 32214222ddf1SHong Zhang /* 99*/ MatProductSetFromOptions_SeqDense, 3222f4259b30SLisandro Dalcin NULL, 3223f4259b30SLisandro Dalcin NULL, 3224ba337c44SJed Brown MatConjugate_SeqDense, 3225f4259b30SLisandro Dalcin NULL, 3226f4259b30SLisandro Dalcin /*104*/ NULL, 3227ba337c44SJed Brown MatRealPart_SeqDense, 3228ba337c44SJed Brown MatImaginaryPart_SeqDense, 3229f4259b30SLisandro Dalcin NULL, 3230f4259b30SLisandro Dalcin NULL, 3231f4259b30SLisandro Dalcin /*109*/ NULL, 3232f4259b30SLisandro Dalcin NULL, 32338d0534beSBarry Smith MatGetRowMin_SeqDense, 3234aabbc4fbSShri Abhyankar MatGetColumnVector_SeqDense, 32353b49f96aSBarry Smith MatMissingDiagonal_SeqDense, 3236f4259b30SLisandro Dalcin /*114*/ NULL, 3237f4259b30SLisandro Dalcin NULL, 3238f4259b30SLisandro Dalcin NULL, 3239f4259b30SLisandro Dalcin NULL, 3240f4259b30SLisandro Dalcin NULL, 3241f4259b30SLisandro Dalcin /*119*/ NULL, 3242f4259b30SLisandro Dalcin NULL, 3243459e8d23SBlanca Mellado Pinto MatMultHermitianTranspose_SeqDense, 3244459e8d23SBlanca Mellado Pinto MatMultHermitianTransposeAdd_SeqDense, 3245f4259b30SLisandro Dalcin NULL, 3246f4259b30SLisandro Dalcin /*124*/ NULL, 3247a873a8cdSSam Reynolds MatGetColumnReductions_SeqDense, 3248f4259b30SLisandro Dalcin NULL, 3249f4259b30SLisandro Dalcin NULL, 3250f4259b30SLisandro Dalcin NULL, 3251f4259b30SLisandro Dalcin /*129*/ NULL, 3252f4259b30SLisandro Dalcin NULL, 3253f4259b30SLisandro Dalcin NULL, 325475648e8dSHong Zhang MatTransposeMatMultNumeric_SeqDense_SeqDense, 3255f4259b30SLisandro Dalcin NULL, 3256f4259b30SLisandro Dalcin /*134*/ NULL, 3257f4259b30SLisandro Dalcin NULL, 3258f4259b30SLisandro Dalcin NULL, 3259f4259b30SLisandro Dalcin NULL, 3260f4259b30SLisandro Dalcin NULL, 3261f4259b30SLisandro Dalcin /*139*/ NULL, 3262f4259b30SLisandro Dalcin NULL, 3263f4259b30SLisandro Dalcin NULL, 3264f4259b30SLisandro Dalcin NULL, 3265f4259b30SLisandro Dalcin NULL, 32664222ddf1SHong Zhang MatCreateMPIMatConcatenateSeqMat_SeqDense, 3267f4259b30SLisandro Dalcin /*145*/ NULL, 3268f4259b30SLisandro Dalcin NULL, 326999a7f59eSMark Adams NULL, 327099a7f59eSMark Adams NULL, 32717fb60732SBarry Smith NULL, 3272dec0b466SHong Zhang /*150*/ NULL, 3273eede4a3fSMark Adams NULL, 32744cc2b5b5SPierre Jolivet NULL, 327542ce410bSJunchao Zhang NULL, 327642ce410bSJunchao Zhang NULL, 3277dec0b466SHong Zhang NULL}; 327890ace30eSBarry Smith 32795d83a8b1SBarry Smith /*@ 328011a5261eSBarry Smith MatCreateSeqDense - Creates a `MATSEQDENSE` that 3281fb850c59SBarry Smith is stored in column major order (the usual Fortran format). 3282289bc588SBarry Smith 3283d083f849SBarry Smith Collective 3284db81eaa0SLois Curfman McInnes 328520563c6bSBarry Smith Input Parameters: 328611a5261eSBarry Smith + comm - MPI communicator, set to `PETSC_COMM_SELF` 32870c775827SLois Curfman McInnes . m - number of rows 328818f449edSLois Curfman McInnes . n - number of columns 32892ef1f0ffSBarry Smith - data - optional location of matrix data in column major order. Use `NULL` for PETSc 3290dfc5480cSLois Curfman McInnes to control all matrix memory allocation. 329120563c6bSBarry Smith 329220563c6bSBarry Smith Output Parameter: 329344cd7ae7SLois Curfman McInnes . A - the matrix 329420563c6bSBarry Smith 32952ef1f0ffSBarry Smith Level: intermediate 32962ef1f0ffSBarry Smith 329711a5261eSBarry Smith Note: 329818f449edSLois Curfman McInnes The data input variable is intended primarily for Fortran programmers 329918f449edSLois Curfman McInnes who wish to allocate their own matrix memory space. Most users should 33002ef1f0ffSBarry Smith set `data` = `NULL`. 330118f449edSLois Curfman McInnes 3302fb850c59SBarry Smith Developer Note: 3303fb850c59SBarry Smith Many of the matrix operations for this variant use the BLAS and LAPACK routines. 3304fb850c59SBarry Smith 33051cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()` 330620563c6bSBarry Smith @*/ 33075d83a8b1SBarry Smith PetscErrorCode MatCreateSeqDense(MPI_Comm comm, PetscInt m, PetscInt n, PetscScalar data[], Mat *A) 3308d71ae5a4SJacob Faibussowitsch { 33093a40ed3dSBarry Smith PetscFunctionBegin; 33109566063dSJacob Faibussowitsch PetscCall(MatCreate(comm, A)); 33119566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*A, m, n, m, n)); 33129566063dSJacob Faibussowitsch PetscCall(MatSetType(*A, MATSEQDENSE)); 33139566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(*A, data)); 33143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3315273d9f13SBarry Smith } 3316273d9f13SBarry Smith 33175d83a8b1SBarry Smith /*@ 331811a5261eSBarry Smith MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements of a `MATSEQDENSE` matrix 3319273d9f13SBarry Smith 3320d083f849SBarry Smith Collective 3321273d9f13SBarry Smith 3322273d9f13SBarry Smith Input Parameters: 33231c4f3114SJed Brown + B - the matrix 33242ef1f0ffSBarry Smith - data - the array (or `NULL`) 33252ef1f0ffSBarry Smith 33262ef1f0ffSBarry Smith Level: intermediate 3327273d9f13SBarry Smith 332811a5261eSBarry Smith Note: 3329273d9f13SBarry Smith The data input variable is intended primarily for Fortran programmers 3330273d9f13SBarry Smith who wish to allocate their own matrix memory space. Most users should 3331284134d9SBarry Smith need not call this routine. 3332273d9f13SBarry Smith 33331cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()`, `MatDenseSetLDA()` 3334273d9f13SBarry Smith @*/ 3335d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation(Mat B, PetscScalar data[]) 3336d71ae5a4SJacob Faibussowitsch { 3337a23d5eceSKris Buschelman PetscFunctionBegin; 3338d5ea218eSStefano Zampini PetscValidHeaderSpecific(B, MAT_CLASSID, 1); 3339cac4c232SBarry Smith PetscTryMethod(B, "MatSeqDenseSetPreallocation_C", (Mat, PetscScalar[]), (B, data)); 33403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3341a23d5eceSKris Buschelman } 3342a23d5eceSKris Buschelman 3343d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation_SeqDense(Mat B, PetscScalar *data) 3344d71ae5a4SJacob Faibussowitsch { 3345ad16ce7aSStefano Zampini Mat_SeqDense *b = (Mat_SeqDense *)B->data; 3346273d9f13SBarry Smith 3347273d9f13SBarry Smith PetscFunctionBegin; 334828b400f6SJacob Faibussowitsch PetscCheck(!b->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3349273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 3350a868139aSShri Abhyankar 33519566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(B->rmap)); 33529566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(B->cmap)); 335334ef9618SShri Abhyankar 33546497c311SBarry Smith if (b->lda <= 0) PetscCall(PetscBLASIntCast(B->rmap->n, &b->lda)); 335586d161a7SShri Abhyankar 33569e8f95c4SLisandro Dalcin if (!data) { /* petsc-allocated storage */ 33579566063dSJacob Faibussowitsch if (!b->user_alloc) PetscCall(PetscFree(b->v)); 33589566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((size_t)b->lda * B->cmap->n, &b->v)); 33592205254eSKarl Rupp 33609e8f95c4SLisandro Dalcin b->user_alloc = PETSC_FALSE; 3361273d9f13SBarry Smith } else { /* user-allocated storage */ 33629566063dSJacob Faibussowitsch if (!b->user_alloc) PetscCall(PetscFree(b->v)); 3363273d9f13SBarry Smith b->v = data; 3364273d9f13SBarry Smith b->user_alloc = PETSC_TRUE; 3365273d9f13SBarry Smith } 33660450473dSBarry Smith B->assembled = PETSC_TRUE; 33673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3368273d9f13SBarry Smith } 3369273d9f13SBarry Smith 337065b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 3371d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) 3372d71ae5a4SJacob Faibussowitsch { 3373d77f618aSHong Zhang Mat mat_elemental; 33741683a169SBarry Smith const PetscScalar *array; 33751683a169SBarry Smith PetscScalar *v_colwise; 3376d77f618aSHong Zhang PetscInt M = A->rmap->N, N = A->cmap->N, i, j, k, *rows, *cols; 3377d77f618aSHong Zhang 33788baccfbdSHong Zhang PetscFunctionBegin; 33799566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(M * N, &v_colwise, M, &rows, N, &cols)); 33809566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &array)); 3381d77f618aSHong Zhang /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */ 3382d77f618aSHong Zhang k = 0; 3383d77f618aSHong Zhang for (j = 0; j < N; j++) { 3384d77f618aSHong Zhang cols[j] = j; 3385ad540459SPierre Jolivet for (i = 0; i < M; i++) v_colwise[j * M + i] = array[k++]; 3386d77f618aSHong Zhang } 3387ad540459SPierre Jolivet for (i = 0; i < M; i++) rows[i] = i; 33889566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &array)); 3389d77f618aSHong Zhang 33909566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental)); 33919566063dSJacob Faibussowitsch PetscCall(MatSetSizes(mat_elemental, PETSC_DECIDE, PETSC_DECIDE, M, N)); 33929566063dSJacob Faibussowitsch PetscCall(MatSetType(mat_elemental, MATELEMENTAL)); 33939566063dSJacob Faibussowitsch PetscCall(MatSetUp(mat_elemental)); 3394d77f618aSHong Zhang 3395d77f618aSHong Zhang /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */ 33969566063dSJacob Faibussowitsch PetscCall(MatSetValues(mat_elemental, M, rows, N, cols, v_colwise, ADD_VALUES)); 33979566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY)); 33989566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY)); 33999566063dSJacob Faibussowitsch PetscCall(PetscFree3(v_colwise, rows, cols)); 3400d77f618aSHong Zhang 3401511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 34029566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A, &mat_elemental)); 3403d77f618aSHong Zhang } else { 3404d77f618aSHong Zhang *newmat = mat_elemental; 3405d77f618aSHong Zhang } 34063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34078baccfbdSHong Zhang } 340865b80a83SHong Zhang #endif 34098baccfbdSHong Zhang 3410d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA_SeqDense(Mat B, PetscInt lda) 3411d71ae5a4SJacob Faibussowitsch { 34121b807ce4Svictorle Mat_SeqDense *b = (Mat_SeqDense *)B->data; 34137422da62SJose E. Roman PetscBool data; 341421a2c019SBarry Smith 34151b807ce4Svictorle PetscFunctionBegin; 34167422da62SJose E. Roman data = (PetscBool)((B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE); 3417aed4548fSBarry Smith PetscCheck(b->user_alloc || !data || b->lda == lda, PETSC_COMM_SELF, PETSC_ERR_ORDER, "LDA cannot be changed after allocation of internal storage"); 341808401ef6SPierre 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); 34196497c311SBarry Smith PetscCall(PetscBLASIntCast(lda, &b->lda)); 34203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34211b807ce4Svictorle } 34221b807ce4Svictorle 3423d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm, Mat inmat, PetscInt n, MatReuse scall, Mat *outmat) 3424d71ae5a4SJacob Faibussowitsch { 3425d528f656SJakub Kruzik PetscFunctionBegin; 34269566063dSJacob Faibussowitsch PetscCall(MatCreateMPIMatConcatenateSeqMat_MPIDense(comm, inmat, n, scall, outmat)); 34273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3428d528f656SJakub Kruzik } 3429d528f656SJakub Kruzik 3430d16ceb75SStefano Zampini PetscErrorCode MatDenseCreateColumnVec_Private(Mat A, Vec *v) 3431d16ceb75SStefano Zampini { 3432d16ceb75SStefano Zampini PetscBool isstd, iskok, iscuda, iship; 3433d16ceb75SStefano Zampini PetscMPIInt size; 3434d16ceb75SStefano Zampini #if PetscDefined(HAVE_CUDA) || PetscDefined(HAVE_HIP) 3435d16ceb75SStefano Zampini /* we pass the data of A, to prevent allocating needless GPU memory the first time VecCUPMPlaceArray is called. */ 3436d16ceb75SStefano Zampini const PetscScalar *a; 3437d16ceb75SStefano Zampini #endif 3438d16ceb75SStefano Zampini 3439d16ceb75SStefano Zampini PetscFunctionBegin; 3440d16ceb75SStefano Zampini *v = NULL; 3441d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &isstd, VECSTANDARD, VECSEQ, VECMPI, "")); 3442d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &iskok, VECKOKKOS, VECSEQKOKKOS, VECMPIKOKKOS, "")); 3443d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &iscuda, VECCUDA, VECSEQCUDA, VECMPICUDA, "")); 3444d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &iship, VECHIP, VECSEQHIP, VECMPIHIP, "")); 3445d16ceb75SStefano Zampini PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A), &size)); 3446d16ceb75SStefano Zampini if (isstd) { 3447d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPIWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, v)); 3448d16ceb75SStefano Zampini else PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, v)); 3449d16ceb75SStefano Zampini } else if (iskok) { 3450d16ceb75SStefano Zampini PetscCheck(PetscDefined(HAVE_KOKKOS_KERNELS), PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Reconfigure using KOKKOS kernels support"); 3451d16ceb75SStefano Zampini #if PetscDefined(HAVE_KOKKOS_KERNELS) 3452d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPIKokkosWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, v)); 3453d16ceb75SStefano Zampini else PetscCall(VecCreateSeqKokkosWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, v)); 3454d16ceb75SStefano Zampini #endif 3455d16ceb75SStefano Zampini } else if (iscuda) { 3456d16ceb75SStefano Zampini PetscCheck(PetscDefined(HAVE_CUDA), PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Reconfigure using CUDA support"); 3457d16ceb75SStefano Zampini #if PetscDefined(HAVE_CUDA) 3458d16ceb75SStefano Zampini PetscCall(MatDenseCUDAGetArrayRead(A, &a)); 3459d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPICUDAWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, a, v)); 3460d16ceb75SStefano Zampini else PetscCall(VecCreateSeqCUDAWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, a, v)); 3461d16ceb75SStefano Zampini #endif 3462d16ceb75SStefano Zampini } else if (iship) { 3463d16ceb75SStefano Zampini PetscCheck(PetscDefined(HAVE_HIP), PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Reconfigure using HIP support"); 3464d16ceb75SStefano Zampini #if PetscDefined(HAVE_HIP) 3465d16ceb75SStefano Zampini PetscCall(MatDenseHIPGetArrayRead(A, &a)); 3466d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPIHIPWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, a, v)); 3467d16ceb75SStefano Zampini else PetscCall(VecCreateSeqHIPWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, a, v)); 3468d16ceb75SStefano Zampini #endif 3469d16ceb75SStefano Zampini } 3470d16ceb75SStefano Zampini PetscCheck(*v, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Not coded for type %s", A->defaultvectype); 3471d16ceb75SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 3472d16ceb75SStefano Zampini } 3473d16ceb75SStefano Zampini 3474d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A, PetscInt col, Vec *v) 3475d71ae5a4SJacob Faibussowitsch { 34766947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34776947451fSStefano Zampini 34786947451fSStefano Zampini PetscFunctionBegin; 347928b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 348028b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3481d16ceb75SStefano Zampini if (!a->cvec) PetscCall(MatDenseCreateColumnVec_Private(A, &a->cvec)); 34826947451fSStefano Zampini a->vecinuse = col + 1; 34839566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, (PetscScalar **)&a->ptrinuse)); 34849566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda)); 34856947451fSStefano Zampini *v = a->cvec; 34863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34876947451fSStefano Zampini } 34886947451fSStefano Zampini 3489d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A, PetscInt col, Vec *v) 3490d71ae5a4SJacob Faibussowitsch { 34916947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34926947451fSStefano Zampini 34936947451fSStefano Zampini PetscFunctionBegin; 349428b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 349528b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 34964186a4bbSPierre Jolivet VecCheckAssembled(a->cvec); 34976947451fSStefano Zampini a->vecinuse = 0; 34989566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, (PetscScalar **)&a->ptrinuse)); 34999566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 350075f6d85dSStefano Zampini if (v) *v = NULL; 35013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35026947451fSStefano Zampini } 35036947451fSStefano Zampini 3504d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v) 3505d71ae5a4SJacob Faibussowitsch { 35066947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35076947451fSStefano Zampini 35086947451fSStefano Zampini PetscFunctionBegin; 350928b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 351028b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3511d16ceb75SStefano Zampini if (!a->cvec) PetscCall(MatDenseCreateColumnVec_Private(A, &a->cvec)); 35126947451fSStefano Zampini a->vecinuse = col + 1; 35139566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &a->ptrinuse)); 35148e3a54c0SPierre Jolivet PetscCall(VecPlaceArray(a->cvec, PetscSafePointerPlusOffset(a->ptrinuse, (size_t)col * (size_t)a->lda))); 35159566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(a->cvec)); 35166947451fSStefano Zampini *v = a->cvec; 35173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35186947451fSStefano Zampini } 35196947451fSStefano Zampini 3520d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v) 3521d71ae5a4SJacob Faibussowitsch { 35226947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35236947451fSStefano Zampini 35246947451fSStefano Zampini PetscFunctionBegin; 352528b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 352628b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 35274186a4bbSPierre Jolivet VecCheckAssembled(a->cvec); 35286947451fSStefano Zampini a->vecinuse = 0; 35299566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &a->ptrinuse)); 35309566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(a->cvec)); 35319566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 353275f6d85dSStefano Zampini if (v) *v = NULL; 35333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35346947451fSStefano Zampini } 35356947451fSStefano Zampini 3536d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v) 3537d71ae5a4SJacob Faibussowitsch { 35386947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35396947451fSStefano Zampini 35406947451fSStefano Zampini PetscFunctionBegin; 354128b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 354228b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3543d16ceb75SStefano Zampini if (!a->cvec) PetscCall(MatDenseCreateColumnVec_Private(A, &a->cvec)); 35446947451fSStefano Zampini a->vecinuse = col + 1; 35459566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(A, (PetscScalar **)&a->ptrinuse)); 35468e3a54c0SPierre Jolivet PetscCall(VecPlaceArray(a->cvec, PetscSafePointerPlusOffset(a->ptrinuse, (size_t)col * (size_t)a->lda))); 35476947451fSStefano Zampini *v = a->cvec; 35483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35496947451fSStefano Zampini } 35506947451fSStefano Zampini 3551d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v) 3552d71ae5a4SJacob Faibussowitsch { 35536947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35546947451fSStefano Zampini 35556947451fSStefano Zampini PetscFunctionBegin; 355628b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 355728b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 35584186a4bbSPierre Jolivet VecCheckAssembled(a->cvec); 35596947451fSStefano Zampini a->vecinuse = 0; 35609566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(A, (PetscScalar **)&a->ptrinuse)); 35619566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 356275f6d85dSStefano Zampini if (v) *v = NULL; 35633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35646947451fSStefano Zampini } 35656947451fSStefano Zampini 3566d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) 3567d71ae5a4SJacob Faibussowitsch { 35685ea7661aSPierre Jolivet Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35695ea7661aSPierre Jolivet 35705ea7661aSPierre Jolivet PetscFunctionBegin; 357128b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 357228b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3573a2748737SPierre Jolivet if (a->cmat && (cend - cbegin != a->cmat->cmap->N || rend - rbegin != a->cmat->rmap->N)) PetscCall(MatDestroy(&a->cmat)); 35745ea7661aSPierre Jolivet if (!a->cmat) { 35758e3a54c0SPierre 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)); 35765ea7661aSPierre Jolivet } else { 35778e3a54c0SPierre Jolivet PetscCall(MatDensePlaceArray(a->cmat, PetscSafePointerPlusOffset(a->v, rbegin + (size_t)cbegin * a->lda))); 35785ea7661aSPierre Jolivet } 35799566063dSJacob Faibussowitsch PetscCall(MatDenseSetLDA(a->cmat, a->lda)); 35805ea7661aSPierre Jolivet a->matinuse = cbegin + 1; 35815ea7661aSPierre Jolivet *v = a->cmat; 358247d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 358375f6d85dSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 358475f6d85dSStefano Zampini #endif 35853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35865ea7661aSPierre Jolivet } 35875ea7661aSPierre Jolivet 3588d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A, Mat *v) 3589d71ae5a4SJacob Faibussowitsch { 35905ea7661aSPierre Jolivet Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35915ea7661aSPierre Jolivet 35925ea7661aSPierre Jolivet PetscFunctionBegin; 359328b400f6SJacob Faibussowitsch PetscCheck(a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetSubMatrix() first"); 359428b400f6SJacob Faibussowitsch PetscCheck(a->cmat, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column matrix"); 359508401ef6SPierre Jolivet PetscCheck(*v == a->cmat, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not the matrix obtained from MatDenseGetSubMatrix()"); 35965ea7661aSPierre Jolivet a->matinuse = 0; 35979566063dSJacob Faibussowitsch PetscCall(MatDenseResetArray(a->cmat)); 3598742765d3SMatthew Knepley if (v) *v = NULL; 359947d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 36003faff063SStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 36013faff063SStefano Zampini #endif 36023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 36035ea7661aSPierre Jolivet } 36045ea7661aSPierre Jolivet 36050bad9183SKris Buschelman /*MC 3606fafad747SKris Buschelman MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices. 36070bad9183SKris Buschelman 36082ef1f0ffSBarry Smith Options Database Key: 360911a5261eSBarry Smith . -mat_type seqdense - sets the matrix type to `MATSEQDENSE` during a call to `MatSetFromOptions()` 36100bad9183SKris Buschelman 36110bad9183SKris Buschelman Level: beginner 36120bad9183SKris Buschelman 36131cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreateSeqDense()` 36140bad9183SKris Buschelman M*/ 3615d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreate_SeqDense(Mat B) 3616d71ae5a4SJacob Faibussowitsch { 3617273d9f13SBarry Smith Mat_SeqDense *b; 36187c334f02SBarry Smith PetscMPIInt size; 3619273d9f13SBarry Smith 3620273d9f13SBarry Smith PetscFunctionBegin; 36219566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)B), &size)); 362208401ef6SPierre Jolivet PetscCheck(size <= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Comm must be of size 1"); 362355659b69SBarry Smith 36244dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&b)); 362544cd7ae7SLois Curfman McInnes B->data = (void *)b; 3626aea10558SJacob Faibussowitsch B->ops[0] = MatOps_Values; 362718f449edSLois Curfman McInnes 3628273d9f13SBarry Smith b->roworiented = PETSC_TRUE; 36294e220ebcSLois Curfman McInnes 36309566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatQRFactor_C", MatQRFactor_SeqDense)); 36319566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetLDA_C", MatDenseGetLDA_SeqDense)); 36329566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseSetLDA_C", MatDenseSetLDA_SeqDense)); 36339566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArray_C", MatDenseGetArray_SeqDense)); 36349566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArray_C", MatDenseRestoreArray_SeqDense)); 36359566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDensePlaceArray_C", MatDensePlaceArray_SeqDense)); 36369566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseResetArray_C", MatDenseResetArray_SeqDense)); 36379566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseReplaceArray_C", MatDenseReplaceArray_SeqDense)); 36389566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayRead_C", MatDenseGetArray_SeqDense)); 36399566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayRead_C", MatDenseRestoreArray_SeqDense)); 36409566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayWrite_C", MatDenseGetArray_SeqDense)); 36419566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayWrite_C", MatDenseRestoreArray_SeqDense)); 36429566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqaij_C", MatConvert_SeqDense_SeqAIJ)); 36438baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 36449566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_elemental_C", MatConvert_SeqDense_Elemental)); 36458baccfbdSHong Zhang #endif 3646d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 36479566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_scalapack_C", MatConvert_Dense_ScaLAPACK)); 3648d24d4204SJose E. Roman #endif 36492bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA) 36509566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensecuda_C", MatConvert_SeqDense_SeqDenseCUDA)); 36519566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", MatProductSetFromOptions_SeqDense)); 36529566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdense_C", MatProductSetFromOptions_SeqDense)); 36539566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensecuda_C", MatProductSetFromOptions_SeqDense)); 36542bf066beSStefano Zampini #endif 365547d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 365647d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensehip_C", MatConvert_SeqDense_SeqDenseHIP)); 365747d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensehip_seqdensehip_C", MatProductSetFromOptions_SeqDense)); 365847d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensehip_seqdense_C", MatProductSetFromOptions_SeqDense)); 365947d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensehip_C", MatProductSetFromOptions_SeqDense)); 366047d993e7Ssuyashtn #endif 36619566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSeqDenseSetPreallocation_C", MatSeqDenseSetPreallocation_SeqDense)); 36629566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqaij_seqdense_C", MatProductSetFromOptions_SeqAIJ_SeqDense)); 36639566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdense_C", MatProductSetFromOptions_SeqDense)); 36649566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense)); 36659566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqsbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense)); 366696e6d5c4SRichard Tran Mills 36679566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumn_C", MatDenseGetColumn_SeqDense)); 36689566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumn_C", MatDenseRestoreColumn_SeqDense)); 36699566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVec_C", MatDenseGetColumnVec_SeqDense)); 36709566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVec_C", MatDenseRestoreColumnVec_SeqDense)); 36719566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecRead_C", MatDenseGetColumnVecRead_SeqDense)); 36729566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecRead_C", MatDenseRestoreColumnVecRead_SeqDense)); 36739566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecWrite_C", MatDenseGetColumnVecWrite_SeqDense)); 36749566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecWrite_C", MatDenseRestoreColumnVecWrite_SeqDense)); 36759566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetSubMatrix_C", MatDenseGetSubMatrix_SeqDense)); 36769566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreSubMatrix_C", MatDenseRestoreSubMatrix_SeqDense)); 36770be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatMultAddColumnRange_C", MatMultAddColumnRange_SeqDense)); 36780be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatMultHermitianTransposeColumnRange_C", MatMultHermitianTransposeColumnRange_SeqDense)); 36790be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatMultHermitianTransposeAddColumnRange_C", MatMultHermitianTransposeAddColumnRange_SeqDense)); 36809566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)B, MATSEQDENSE)); 36813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3682289bc588SBarry Smith } 368386aefd0dSHong Zhang 368486aefd0dSHong Zhang /*@C 368511a5261eSBarry 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. 368686aefd0dSHong Zhang 368786aefd0dSHong Zhang Not Collective 368886aefd0dSHong Zhang 36895ea7661aSPierre Jolivet Input Parameters: 3690fe59aa6dSJacob Faibussowitsch + A - a `MATSEQDENSE` or `MATMPIDENSE` matrix 369186aefd0dSHong Zhang - col - column index 369286aefd0dSHong Zhang 369386aefd0dSHong Zhang Output Parameter: 369486aefd0dSHong Zhang . vals - pointer to the data 369586aefd0dSHong Zhang 369686aefd0dSHong Zhang Level: intermediate 369786aefd0dSHong Zhang 369811a5261eSBarry Smith Note: 369911a5261eSBarry Smith Use `MatDenseGetColumnVec()` to get access to a column of a `MATDENSE` treated as a `Vec` 370011a5261eSBarry Smith 37011cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreColumn()`, `MatDenseGetColumnVec()` 370286aefd0dSHong Zhang @*/ 37035d83a8b1SBarry Smith PetscErrorCode MatDenseGetColumn(Mat A, PetscInt col, PetscScalar *vals[]) 3704d71ae5a4SJacob Faibussowitsch { 370586aefd0dSHong Zhang PetscFunctionBegin; 3706d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3707d5ea218eSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 37084f572ea9SToby Isaac PetscAssertPointer(vals, 3); 3709cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumn_C", (Mat, PetscInt, PetscScalar **), (A, col, vals)); 37103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 371186aefd0dSHong Zhang } 371286aefd0dSHong Zhang 371386aefd0dSHong Zhang /*@C 371411a5261eSBarry Smith MatDenseRestoreColumn - returns access to a column of a `MATDENSE` matrix which is returned by `MatDenseGetColumn()`. 371586aefd0dSHong Zhang 371686aefd0dSHong Zhang Not Collective 371786aefd0dSHong Zhang 3718742765d3SMatthew Knepley Input Parameters: 3719fe59aa6dSJacob Faibussowitsch + A - a `MATSEQDENSE` or `MATMPIDENSE` matrix 37202ef1f0ffSBarry Smith - vals - pointer to the data (may be `NULL`) 372186aefd0dSHong Zhang 372286aefd0dSHong Zhang Level: intermediate 372386aefd0dSHong Zhang 37241cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetColumn()` 372586aefd0dSHong Zhang @*/ 37265d83a8b1SBarry Smith PetscErrorCode MatDenseRestoreColumn(Mat A, PetscScalar *vals[]) 3727d71ae5a4SJacob Faibussowitsch { 372886aefd0dSHong Zhang PetscFunctionBegin; 3729d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 37304f572ea9SToby Isaac PetscAssertPointer(vals, 2); 3731cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumn_C", (Mat, PetscScalar **), (A, vals)); 37323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 373386aefd0dSHong Zhang } 37346947451fSStefano Zampini 37350f74d2c1SSatish Balay /*@ 373611a5261eSBarry Smith MatDenseGetColumnVec - Gives read-write access to a column of a `MATDENSE` matrix, represented as a `Vec`. 37376947451fSStefano Zampini 37386947451fSStefano Zampini Collective 37396947451fSStefano Zampini 37405ea7661aSPierre Jolivet Input Parameters: 3741fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 37426947451fSStefano Zampini - col - the column index 37436947451fSStefano Zampini 37446947451fSStefano Zampini Output Parameter: 37456947451fSStefano Zampini . v - the vector 37466947451fSStefano Zampini 37472ef1f0ffSBarry Smith Level: intermediate 37482ef1f0ffSBarry Smith 37496947451fSStefano Zampini Notes: 375011a5261eSBarry Smith The vector is owned by PETSc. Users need to call `MatDenseRestoreColumnVec()` when the vector is no longer needed. 375111a5261eSBarry Smith 375211a5261eSBarry Smith Use `MatDenseGetColumnVecRead()` to obtain read-only access or `MatDenseGetColumnVecWrite()` for write-only access. 37536947451fSStefano Zampini 37541cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`, `MatDenseGetColumn()` 37556947451fSStefano Zampini @*/ 3756d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec(Mat A, PetscInt col, Vec *v) 3757d71ae5a4SJacob Faibussowitsch { 37586947451fSStefano Zampini PetscFunctionBegin; 37596947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 37606947451fSStefano Zampini PetscValidType(A, 1); 37616947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 37624f572ea9SToby Isaac PetscAssertPointer(v, 3); 376328b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 37642cf15c64SPierre 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); 3765cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v)); 37663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37676947451fSStefano Zampini } 37686947451fSStefano Zampini 37690f74d2c1SSatish Balay /*@ 3770fb850c59SBarry Smith MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from `MatDenseGetColumnVec()`. 37716947451fSStefano Zampini 37726947451fSStefano Zampini Collective 37736947451fSStefano Zampini 37745ea7661aSPierre Jolivet Input Parameters: 3775fb850c59SBarry Smith + A - the `Mat` object 37766947451fSStefano Zampini . col - the column index 3777fb850c59SBarry Smith - v - the `Vec` object (may be `NULL`) 37786947451fSStefano Zampini 37796947451fSStefano Zampini Level: intermediate 37806947451fSStefano Zampini 37811cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 37826947451fSStefano Zampini @*/ 3783d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec(Mat A, PetscInt col, Vec *v) 3784d71ae5a4SJacob Faibussowitsch { 37856947451fSStefano Zampini PetscFunctionBegin; 37866947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 37876947451fSStefano Zampini PetscValidType(A, 1); 37886947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 378908401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 37902cf15c64SPierre 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); 3791cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v)); 37923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37936947451fSStefano Zampini } 37946947451fSStefano Zampini 37950f74d2c1SSatish Balay /*@ 3796fb850c59SBarry Smith MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a `Vec`. 37976947451fSStefano Zampini 37986947451fSStefano Zampini Collective 37996947451fSStefano Zampini 38005ea7661aSPierre Jolivet Input Parameters: 3801fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 38026947451fSStefano Zampini - col - the column index 38036947451fSStefano Zampini 38046947451fSStefano Zampini Output Parameter: 38056947451fSStefano Zampini . v - the vector 38066947451fSStefano Zampini 38072ef1f0ffSBarry Smith Level: intermediate 38082ef1f0ffSBarry Smith 38096947451fSStefano Zampini Notes: 38106947451fSStefano Zampini The vector is owned by PETSc and users cannot modify it. 381111a5261eSBarry Smith 38122ef1f0ffSBarry Smith Users need to call `MatDenseRestoreColumnVecRead()` when the vector is no longer needed. 381311a5261eSBarry Smith 38142ef1f0ffSBarry Smith Use `MatDenseGetColumnVec()` to obtain read-write access or `MatDenseGetColumnVecWrite()` for write-only access. 38156947451fSStefano Zampini 38161cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 38176947451fSStefano Zampini @*/ 3818d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead(Mat A, PetscInt col, Vec *v) 3819d71ae5a4SJacob Faibussowitsch { 38206947451fSStefano Zampini PetscFunctionBegin; 38216947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38226947451fSStefano Zampini PetscValidType(A, 1); 38236947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 38244f572ea9SToby Isaac PetscAssertPointer(v, 3); 382528b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 38262cf15c64SPierre 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); 3827cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v)); 38283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38296947451fSStefano Zampini } 38306947451fSStefano Zampini 38310f74d2c1SSatish Balay /*@ 3832fb850c59SBarry Smith MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from `MatDenseGetColumnVecRead()`. 38336947451fSStefano Zampini 38346947451fSStefano Zampini Collective 38356947451fSStefano Zampini 38365ea7661aSPierre Jolivet Input Parameters: 3837fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 38386947451fSStefano Zampini . col - the column index 3839fb850c59SBarry Smith - v - the `Vec` object (may be `NULL`) 38406947451fSStefano Zampini 38416947451fSStefano Zampini Level: intermediate 38426947451fSStefano Zampini 38431cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecWrite()` 38446947451fSStefano Zampini @*/ 3845d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead(Mat A, PetscInt col, Vec *v) 3846d71ae5a4SJacob Faibussowitsch { 38476947451fSStefano Zampini PetscFunctionBegin; 38486947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38496947451fSStefano Zampini PetscValidType(A, 1); 38506947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 385108401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 38522cf15c64SPierre 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); 3853cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v)); 38543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38556947451fSStefano Zampini } 38566947451fSStefano Zampini 38570f74d2c1SSatish Balay /*@ 3858fb850c59SBarry Smith MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a `Vec`. 38596947451fSStefano Zampini 38606947451fSStefano Zampini Collective 38616947451fSStefano Zampini 38625ea7661aSPierre Jolivet Input Parameters: 3863fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 38646947451fSStefano Zampini - col - the column index 38656947451fSStefano Zampini 38666947451fSStefano Zampini Output Parameter: 38676947451fSStefano Zampini . v - the vector 38686947451fSStefano Zampini 38696947451fSStefano Zampini Level: intermediate 38706947451fSStefano Zampini 38712ef1f0ffSBarry Smith Notes: 38722ef1f0ffSBarry Smith The vector is owned by PETSc. Users need to call `MatDenseRestoreColumnVecWrite()` when the vector is no longer needed. 38732ef1f0ffSBarry Smith 38742ef1f0ffSBarry Smith Use `MatDenseGetColumnVec()` to obtain read-write access or `MatDenseGetColumnVecRead()` for read-only access. 38752ef1f0ffSBarry Smith 38761cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 38776947451fSStefano Zampini @*/ 3878d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite(Mat A, PetscInt col, Vec *v) 3879d71ae5a4SJacob Faibussowitsch { 38806947451fSStefano Zampini PetscFunctionBegin; 38816947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38826947451fSStefano Zampini PetscValidType(A, 1); 38836947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 38844f572ea9SToby Isaac PetscAssertPointer(v, 3); 388528b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3886aed4548fSBarry 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); 3887cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v)); 38883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38896947451fSStefano Zampini } 38906947451fSStefano Zampini 38910f74d2c1SSatish Balay /*@ 3892fb850c59SBarry Smith MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from `MatDenseGetColumnVecWrite()`. 38936947451fSStefano Zampini 38946947451fSStefano Zampini Collective 38956947451fSStefano Zampini 38965ea7661aSPierre Jolivet Input Parameters: 3897fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 38986947451fSStefano Zampini . col - the column index 38992ef1f0ffSBarry Smith - v - the `Vec` object (may be `NULL`) 39006947451fSStefano Zampini 39016947451fSStefano Zampini Level: intermediate 39026947451fSStefano Zampini 39031cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()` 39046947451fSStefano Zampini @*/ 3905d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A, PetscInt col, Vec *v) 3906d71ae5a4SJacob Faibussowitsch { 39076947451fSStefano Zampini PetscFunctionBegin; 39086947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 39096947451fSStefano Zampini PetscValidType(A, 1); 39106947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 391108401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3912aed4548fSBarry 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); 3913cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v)); 39143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 39156947451fSStefano Zampini } 39165ea7661aSPierre Jolivet 39170f74d2c1SSatish Balay /*@ 3918fb850c59SBarry Smith MatDenseGetSubMatrix - Gives access to a block of rows and columns of a dense matrix, represented as a `Mat`. 39195ea7661aSPierre Jolivet 39205ea7661aSPierre Jolivet Collective 39215ea7661aSPierre Jolivet 39225ea7661aSPierre Jolivet Input Parameters: 3923fb850c59SBarry Smith + A - the `Mat` object 39242ef1f0ffSBarry Smith . rbegin - the first global row index in the block (if `PETSC_DECIDE`, is 0) 39252ef1f0ffSBarry Smith . rend - the global row index past the last one in the block (if `PETSC_DECIDE`, is `M`) 39262ef1f0ffSBarry Smith . cbegin - the first global column index in the block (if `PETSC_DECIDE`, is 0) 39272ef1f0ffSBarry Smith - cend - the global column index past the last one in the block (if `PETSC_DECIDE`, is `N`) 39285ea7661aSPierre Jolivet 39295ea7661aSPierre Jolivet Output Parameter: 39305ea7661aSPierre Jolivet . v - the matrix 39315ea7661aSPierre Jolivet 39325ea7661aSPierre Jolivet Level: intermediate 39335ea7661aSPierre Jolivet 39342ef1f0ffSBarry Smith Notes: 39352ef1f0ffSBarry Smith The matrix is owned by PETSc. Users need to call `MatDenseRestoreSubMatrix()` when the matrix is no longer needed. 39362ef1f0ffSBarry Smith 39372ef1f0ffSBarry 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. 39382ef1f0ffSBarry Smith 39391cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreSubMatrix()` 39405ea7661aSPierre Jolivet @*/ 3941d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) 3942d71ae5a4SJacob Faibussowitsch { 39435ea7661aSPierre Jolivet PetscFunctionBegin; 39445ea7661aSPierre Jolivet PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 39455ea7661aSPierre Jolivet PetscValidType(A, 1); 3946a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, rbegin, 2); 3947a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, rend, 3); 3948a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, cbegin, 4); 3949a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, cend, 5); 39504f572ea9SToby Isaac PetscAssertPointer(v, 6); 3951a2748737SPierre Jolivet if (rbegin == PETSC_DECIDE) rbegin = 0; 3952a2748737SPierre Jolivet if (rend == PETSC_DECIDE) rend = A->rmap->N; 3953a2748737SPierre Jolivet if (cbegin == PETSC_DECIDE) cbegin = 0; 3954a2748737SPierre Jolivet if (cend == PETSC_DECIDE) cend = A->cmap->N; 395528b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3956a2748737SPierre 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); 3957a2748737SPierre 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); 3958a2748737SPierre 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); 3959a2748737SPierre 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); 3960a2748737SPierre Jolivet PetscUseMethod(A, "MatDenseGetSubMatrix_C", (Mat, PetscInt, PetscInt, PetscInt, PetscInt, Mat *), (A, rbegin, rend, cbegin, cend, v)); 39613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 39625ea7661aSPierre Jolivet } 39635ea7661aSPierre Jolivet 39640f74d2c1SSatish Balay /*@ 3965fb850c59SBarry Smith MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from `MatDenseGetSubMatrix()`. 39665ea7661aSPierre Jolivet 39675ea7661aSPierre Jolivet Collective 39685ea7661aSPierre Jolivet 39695ea7661aSPierre Jolivet Input Parameters: 3970fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 39712ef1f0ffSBarry Smith - v - the `Mat` object (may be `NULL`) 39725ea7661aSPierre Jolivet 39735ea7661aSPierre Jolivet Level: intermediate 39745ea7661aSPierre Jolivet 39751cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseGetSubMatrix()` 39765ea7661aSPierre Jolivet @*/ 3977d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix(Mat A, Mat *v) 3978d71ae5a4SJacob Faibussowitsch { 39795ea7661aSPierre Jolivet PetscFunctionBegin; 39805ea7661aSPierre Jolivet PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 39815ea7661aSPierre Jolivet PetscValidType(A, 1); 39824f572ea9SToby Isaac PetscAssertPointer(v, 2); 3983cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreSubMatrix_C", (Mat, Mat *), (A, v)); 39843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 39855ea7661aSPierre Jolivet } 39868a9c020eSBarry Smith 39878a9c020eSBarry Smith #include <petscblaslapack.h> 39888a9c020eSBarry Smith #include <petsc/private/kernels/blockinvert.h> 39898a9c020eSBarry Smith 3990d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseInvert(Mat A) 3991d71ae5a4SJacob Faibussowitsch { 3992d63b1753SJacob Faibussowitsch PetscInt m; 39938a9c020eSBarry Smith const PetscReal shift = 0.0; 3994d63b1753SJacob Faibussowitsch PetscBool allowzeropivot, zeropivotdetected = PETSC_FALSE; 3995d63b1753SJacob Faibussowitsch PetscScalar *values; 39968a9c020eSBarry Smith 39978a9c020eSBarry Smith PetscFunctionBegin; 3998d63b1753SJacob Faibussowitsch PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3999d63b1753SJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &values)); 4000d63b1753SJacob Faibussowitsch PetscCall(MatGetLocalSize(A, &m, NULL)); 4001d63b1753SJacob Faibussowitsch allowzeropivot = PetscNot(A->erroriffailure); 40028a9c020eSBarry Smith /* factor and invert each block */ 4003d63b1753SJacob Faibussowitsch switch (m) { 4004d71ae5a4SJacob Faibussowitsch case 1: 4005d71ae5a4SJacob Faibussowitsch values[0] = (PetscScalar)1.0 / (values[0] + shift); 4006d71ae5a4SJacob Faibussowitsch break; 40078a9c020eSBarry Smith case 2: 40088a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_2(values, shift, allowzeropivot, &zeropivotdetected)); 40098a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 40108a9c020eSBarry Smith break; 40118a9c020eSBarry Smith case 3: 40128a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_3(values, shift, allowzeropivot, &zeropivotdetected)); 40138a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 40148a9c020eSBarry Smith break; 40158a9c020eSBarry Smith case 4: 40168a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_4(values, shift, allowzeropivot, &zeropivotdetected)); 40178a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 40188a9c020eSBarry Smith break; 40199371c9d4SSatish Balay case 5: { 40208a9c020eSBarry Smith PetscScalar work[25]; 40218a9c020eSBarry Smith PetscInt ipvt[5]; 40228a9c020eSBarry Smith 40238a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_5(values, ipvt, work, shift, allowzeropivot, &zeropivotdetected)); 40248a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 40259371c9d4SSatish Balay } break; 40268a9c020eSBarry Smith case 6: 40278a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_6(values, shift, allowzeropivot, &zeropivotdetected)); 40288a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 40298a9c020eSBarry Smith break; 40308a9c020eSBarry Smith case 7: 40318a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_7(values, shift, allowzeropivot, &zeropivotdetected)); 40328a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 40338a9c020eSBarry Smith break; 40349371c9d4SSatish Balay default: { 40358a9c020eSBarry Smith PetscInt *v_pivots, *IJ, j; 40368a9c020eSBarry Smith PetscScalar *v_work; 40378a9c020eSBarry Smith 4038d63b1753SJacob Faibussowitsch PetscCall(PetscMalloc3(m, &v_work, m, &v_pivots, m, &IJ)); 4039d63b1753SJacob Faibussowitsch for (j = 0; j < m; j++) IJ[j] = j; 4040d63b1753SJacob Faibussowitsch PetscCall(PetscKernel_A_gets_inverse_A(m, values, v_pivots, v_work, allowzeropivot, &zeropivotdetected)); 40418a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 40428a9c020eSBarry Smith PetscCall(PetscFree3(v_work, v_pivots, IJ)); 40438a9c020eSBarry Smith } 40448a9c020eSBarry Smith } 4045d63b1753SJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &values)); 40463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 40478a9c020eSBarry Smith } 4048