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> 11b2573a8aSBarry Smith 12d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSymmetrize_Private(Mat A, PetscBool hermitian) 13d71ae5a4SJacob Faibussowitsch { 148c178816SStefano Zampini Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 158c178816SStefano Zampini PetscInt j, k, n = A->rmap->n; 16ca15aa20SStefano Zampini PetscScalar *v; 178c178816SStefano Zampini 188c178816SStefano Zampini PetscFunctionBegin; 1908401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Cannot symmetrize a rectangular matrix"); 209566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 218c178816SStefano Zampini if (!hermitian) { 228c178816SStefano Zampini for (k = 0; k < n; k++) { 23ad540459SPierre Jolivet for (j = k; j < n; j++) v[j * mat->lda + k] = v[k * mat->lda + j]; 248c178816SStefano Zampini } 258c178816SStefano Zampini } else { 268c178816SStefano Zampini for (k = 0; k < n; k++) { 27ad540459SPierre Jolivet for (j = k; j < n; j++) v[j * mat->lda + k] = PetscConj(v[k * mat->lda + j]); 288c178816SStefano Zampini } 298c178816SStefano Zampini } 309566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 328c178816SStefano Zampini } 338c178816SStefano Zampini 34ff6a9541SJacob Faibussowitsch PetscErrorCode MatSeqDenseInvertFactors_Private(Mat A) 35d71ae5a4SJacob Faibussowitsch { 368c178816SStefano Zampini Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 378c178816SStefano Zampini PetscBLASInt info, n; 388c178816SStefano Zampini 398c178816SStefano Zampini PetscFunctionBegin; 403ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 419566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 428c178816SStefano Zampini if (A->factortype == MAT_FACTOR_LU) { 4328b400f6SJacob Faibussowitsch PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present"); 448c178816SStefano Zampini if (!mat->fwork) { 458c178816SStefano Zampini mat->lfwork = n; 469566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 478c178816SStefano Zampini } 489566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 49792fecdfSBarry Smith PetscCallBLAS("LAPACKgetri", LAPACKgetri_(&n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info)); 509566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 519566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0)); 528c178816SStefano Zampini } else if (A->factortype == MAT_FACTOR_CHOLESKY) { 53b94d7dedSBarry Smith if (A->spd == PETSC_BOOL3_TRUE) { 549566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 55792fecdfSBarry Smith PetscCallBLAS("LAPACKpotri", LAPACKpotri_("L", &n, mat->v, &mat->lda, &info)); 569566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 579566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_TRUE)); 588c178816SStefano Zampini #if defined(PETSC_USE_COMPLEX) 59b94d7dedSBarry Smith } else if (A->hermitian == PETSC_BOOL3_TRUE) { 6028b400f6SJacob Faibussowitsch PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present"); 6128b400f6SJacob Faibussowitsch PetscCheck(mat->fwork, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Fwork not present"); 629566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 63792fecdfSBarry Smith PetscCallBLAS("LAPACKhetri", LAPACKhetri_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &info)); 649566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 659566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_TRUE)); 668c178816SStefano Zampini #endif 678c178816SStefano Zampini } else { /* symmetric case */ 6828b400f6SJacob Faibussowitsch PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present"); 6928b400f6SJacob Faibussowitsch PetscCheck(mat->fwork, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Fwork not present"); 709566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 71792fecdfSBarry Smith PetscCallBLAS("LAPACKsytri", LAPACKsytri_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &info)); 729566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 739566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_FALSE)); 748c178816SStefano Zampini } 7528b400f6SJacob Faibussowitsch PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad Inversion: zero pivot in row %" PetscInt_FMT, (PetscInt)info - 1); 769566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0)); 778c178816SStefano Zampini } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Matrix must be factored to solve"); 788c178816SStefano Zampini 798c178816SStefano Zampini A->ops->solve = NULL; 808c178816SStefano Zampini A->ops->matsolve = NULL; 818c178816SStefano Zampini A->ops->solvetranspose = NULL; 828c178816SStefano Zampini A->ops->matsolvetranspose = NULL; 838c178816SStefano Zampini A->ops->solveadd = NULL; 848c178816SStefano Zampini A->ops->solvetransposeadd = NULL; 858c178816SStefano Zampini A->factortype = MAT_FACTOR_NONE; 869566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 888c178816SStefano Zampini } 898c178816SStefano Zampini 9066976f2fSJacob Faibussowitsch static PetscErrorCode MatZeroRowsColumns_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) 91d71ae5a4SJacob Faibussowitsch { 923f49a652SStefano Zampini Mat_SeqDense *l = (Mat_SeqDense *)A->data; 933f49a652SStefano Zampini PetscInt m = l->lda, n = A->cmap->n, r = A->rmap->n, i, j; 94ca15aa20SStefano Zampini PetscScalar *slot, *bb, *v; 953f49a652SStefano Zampini const PetscScalar *xx; 963f49a652SStefano Zampini 973f49a652SStefano Zampini PetscFunctionBegin; 9876bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 993f49a652SStefano Zampini for (i = 0; i < N; i++) { 10008401ef6SPierre Jolivet PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed"); 10108401ef6SPierre 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); 10208401ef6SPierre 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); 1033f49a652SStefano Zampini } 10476bd3646SJed Brown } 1053ba16761SJacob Faibussowitsch if (!N) PetscFunctionReturn(PETSC_SUCCESS); 1063f49a652SStefano Zampini 1073f49a652SStefano Zampini /* fix right hand side if needed */ 1083f49a652SStefano Zampini if (x && b) { 1096c4d906cSStefano Zampini Vec xt; 1106c4d906cSStefano Zampini 11108401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices"); 1129566063dSJacob Faibussowitsch PetscCall(VecDuplicate(x, &xt)); 1139566063dSJacob Faibussowitsch PetscCall(VecCopy(x, xt)); 1149566063dSJacob Faibussowitsch PetscCall(VecScale(xt, -1.0)); 1159566063dSJacob Faibussowitsch PetscCall(MatMultAdd(A, xt, b, b)); 1169566063dSJacob Faibussowitsch PetscCall(VecDestroy(&xt)); 1179566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 1189566063dSJacob Faibussowitsch PetscCall(VecGetArray(b, &bb)); 1193f49a652SStefano Zampini for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]]; 1209566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 1219566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(b, &bb)); 1223f49a652SStefano Zampini } 1233f49a652SStefano Zampini 1249566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 1253f49a652SStefano Zampini for (i = 0; i < N; i++) { 126ca15aa20SStefano Zampini slot = v + rows[i] * m; 1279566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(slot, r)); 1283f49a652SStefano Zampini } 1293f49a652SStefano Zampini for (i = 0; i < N; i++) { 130ca15aa20SStefano Zampini slot = v + rows[i]; 1319371c9d4SSatish Balay for (j = 0; j < n; j++) { 1329371c9d4SSatish Balay *slot = 0.0; 1339371c9d4SSatish Balay slot += m; 1349371c9d4SSatish Balay } 1353f49a652SStefano Zampini } 1363f49a652SStefano Zampini if (diag != 0.0) { 13708401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices"); 1383f49a652SStefano Zampini for (i = 0; i < N; i++) { 139ca15aa20SStefano Zampini slot = v + (m + 1) * rows[i]; 1403f49a652SStefano Zampini *slot = diag; 1413f49a652SStefano Zampini } 1423f49a652SStefano Zampini } 1439566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 1443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1453f49a652SStefano Zampini } 1463f49a652SStefano Zampini 147d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) 148d71ae5a4SJacob Faibussowitsch { 149a13144ffSStefano Zampini Mat B = NULL; 150b49cda9fSStefano Zampini Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data; 151b49cda9fSStefano Zampini Mat_SeqDense *b; 152b49cda9fSStefano Zampini PetscInt *ai = a->i, *aj = a->j, m = A->rmap->N, n = A->cmap->N, i; 1532e5835c6SStefano Zampini const MatScalar *av; 154a13144ffSStefano Zampini PetscBool isseqdense; 155b49cda9fSStefano Zampini 156b49cda9fSStefano Zampini PetscFunctionBegin; 157a13144ffSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 1589566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)*newmat, MATSEQDENSE, &isseqdense)); 15928b400f6SJacob Faibussowitsch PetscCheck(isseqdense, PetscObjectComm((PetscObject)*newmat), PETSC_ERR_USER, "Cannot reuse matrix of type %s", ((PetscObject)(*newmat))->type_name); 160a13144ffSStefano Zampini } 161a13144ffSStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 1629566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B)); 1639566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B, m, n, m, n)); 1649566063dSJacob Faibussowitsch PetscCall(MatSetType(B, MATSEQDENSE)); 1659566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(B, NULL)); 166b49cda9fSStefano Zampini b = (Mat_SeqDense *)(B->data); 167a13144ffSStefano Zampini } else { 168a13144ffSStefano Zampini b = (Mat_SeqDense *)((*newmat)->data); 169e1ea5af7SJose E. Roman for (i = 0; i < n; i++) PetscCall(PetscArrayzero(b->v + i * b->lda, m)); 170a13144ffSStefano Zampini } 1719566063dSJacob Faibussowitsch PetscCall(MatSeqAIJGetArrayRead(A, &av)); 172b49cda9fSStefano Zampini for (i = 0; i < m; i++) { 173b49cda9fSStefano Zampini PetscInt j; 174b49cda9fSStefano Zampini for (j = 0; j < ai[1] - ai[0]; j++) { 175e1ea5af7SJose E. Roman b->v[*aj * b->lda + i] = *av; 176b49cda9fSStefano Zampini aj++; 177b49cda9fSStefano Zampini av++; 178b49cda9fSStefano Zampini } 179b49cda9fSStefano Zampini ai++; 180b49cda9fSStefano Zampini } 1819566063dSJacob Faibussowitsch PetscCall(MatSeqAIJRestoreArrayRead(A, &av)); 182b49cda9fSStefano Zampini 183511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 1849566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 1859566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 1869566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A, &B)); 187b49cda9fSStefano Zampini } else { 188a13144ffSStefano Zampini if (B) *newmat = B; 1899566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(*newmat, MAT_FINAL_ASSEMBLY)); 1909566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(*newmat, MAT_FINAL_ASSEMBLY)); 191b49cda9fSStefano Zampini } 1923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 193b49cda9fSStefano Zampini } 194b49cda9fSStefano Zampini 195d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqDense_SeqAIJ(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) 196d71ae5a4SJacob Faibussowitsch { 1976d4ec7b0SPierre Jolivet Mat B = NULL; 1986a63e612SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1999399e1b8SMatthew G. Knepley PetscInt i, j; 2009399e1b8SMatthew G. Knepley PetscInt *rows, *nnz; 2019399e1b8SMatthew G. Knepley MatScalar *aa = a->v, *vals; 2026a63e612SBarry Smith 2036a63e612SBarry Smith PetscFunctionBegin; 2049566063dSJacob Faibussowitsch PetscCall(PetscCalloc3(A->rmap->n, &rows, A->rmap->n, &nnz, A->rmap->n, &vals)); 2056d4ec7b0SPierre Jolivet if (reuse != MAT_REUSE_MATRIX) { 2069566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B)); 2079566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B, A->rmap->n, A->cmap->n, A->rmap->N, A->cmap->N)); 2089566063dSJacob Faibussowitsch PetscCall(MatSetType(B, MATSEQAIJ)); 2099399e1b8SMatthew G. Knepley for (j = 0; j < A->cmap->n; j++) { 2109371c9d4SSatish Balay for (i = 0; i < A->rmap->n; i++) 2119371c9d4SSatish Balay if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) ++nnz[i]; 2126a63e612SBarry Smith aa += a->lda; 2136a63e612SBarry Smith } 2149566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(B, PETSC_DETERMINE, nnz)); 2156d4ec7b0SPierre Jolivet } else B = *newmat; 2169399e1b8SMatthew G. Knepley aa = a->v; 2179399e1b8SMatthew G. Knepley for (j = 0; j < A->cmap->n; j++) { 2189399e1b8SMatthew G. Knepley PetscInt numRows = 0; 2199371c9d4SSatish Balay for (i = 0; i < A->rmap->n; i++) 2209371c9d4SSatish Balay if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) { 2219371c9d4SSatish Balay rows[numRows] = i; 2229371c9d4SSatish Balay vals[numRows++] = aa[i]; 2239371c9d4SSatish Balay } 2249566063dSJacob Faibussowitsch PetscCall(MatSetValues(B, numRows, rows, 1, &j, vals, INSERT_VALUES)); 2259399e1b8SMatthew G. Knepley aa += a->lda; 2269399e1b8SMatthew G. Knepley } 2279566063dSJacob Faibussowitsch PetscCall(PetscFree3(rows, nnz, vals)); 2289566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 2299566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 2306a63e612SBarry Smith 231511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 2329566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A, &B)); 2336d4ec7b0SPierre Jolivet } else if (reuse != MAT_REUSE_MATRIX) *newmat = B; 2343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2356a63e612SBarry Smith } 2366a63e612SBarry Smith 237d71ae5a4SJacob Faibussowitsch PetscErrorCode MatAXPY_SeqDense(Mat Y, PetscScalar alpha, Mat X, MatStructure str) 238d71ae5a4SJacob Faibussowitsch { 2391987afe7SBarry Smith Mat_SeqDense *x = (Mat_SeqDense *)X->data, *y = (Mat_SeqDense *)Y->data; 240ca15aa20SStefano Zampini const PetscScalar *xv; 241ca15aa20SStefano Zampini PetscScalar *yv; 24223fff9afSBarry Smith PetscBLASInt N, m, ldax = 0, lday = 0, one = 1; 2433a40ed3dSBarry Smith 2443a40ed3dSBarry Smith PetscFunctionBegin; 2459566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(X, &xv)); 2469566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(Y, &yv)); 2479566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(X->rmap->n * X->cmap->n, &N)); 2489566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(X->rmap->n, &m)); 2499566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(x->lda, &ldax)); 2509566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(y->lda, &lday)); 251a5ce6ee0Svictorle if (ldax > m || lday > m) { 252*8e3a54c0SPierre 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)); 253a5ce6ee0Svictorle } else { 254792fecdfSBarry Smith PetscCallBLAS("BLASaxpy", BLASaxpy_(&N, &alpha, xv, &one, yv, &one)); 255a5ce6ee0Svictorle } 2569566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(X, &xv)); 2579566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(Y, &yv)); 2589566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(PetscMax(2.0 * N - 1, 0))); 2593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2601987afe7SBarry Smith } 2611987afe7SBarry Smith 262d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetInfo_SeqDense(Mat A, MatInfoType flag, MatInfo *info) 263d71ae5a4SJacob Faibussowitsch { 264ca15aa20SStefano Zampini PetscLogDouble N = A->rmap->n * A->cmap->n; 2653a40ed3dSBarry Smith 2663a40ed3dSBarry Smith PetscFunctionBegin; 2674e220ebcSLois Curfman McInnes info->block_size = 1.0; 268ca15aa20SStefano Zampini info->nz_allocated = N; 269ca15aa20SStefano Zampini info->nz_used = N; 270ca15aa20SStefano Zampini info->nz_unneeded = 0; 271ca15aa20SStefano Zampini info->assemblies = A->num_ass; 2724e220ebcSLois Curfman McInnes info->mallocs = 0; 2734dfa11a4SJacob Faibussowitsch info->memory = 0; /* REVIEW ME */ 2744e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 2754e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 2764e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 2773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 278289bc588SBarry Smith } 279289bc588SBarry Smith 280d71ae5a4SJacob Faibussowitsch PetscErrorCode MatScale_SeqDense(Mat A, PetscScalar alpha) 281d71ae5a4SJacob Faibussowitsch { 282273d9f13SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 283ca15aa20SStefano Zampini PetscScalar *v; 28423fff9afSBarry Smith PetscBLASInt one = 1, j, nz, lda = 0; 28580cd9d93SLois Curfman McInnes 2863a40ed3dSBarry Smith PetscFunctionBegin; 2879566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 2889566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(a->lda, &lda)); 289d0f46423SBarry Smith if (lda > A->rmap->n) { 2909566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &nz)); 29148a46eb9SPierre Jolivet for (j = 0; j < A->cmap->n; j++) PetscCallBLAS("BLASscal", BLASscal_(&nz, &alpha, v + j * lda, &one)); 292a5ce6ee0Svictorle } else { 2939566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n * A->cmap->n, &nz)); 294792fecdfSBarry Smith PetscCallBLAS("BLASscal", BLASscal_(&nz, &alpha, v, &one)); 295a5ce6ee0Svictorle } 29604cbc005SJose E. Roman PetscCall(PetscLogFlops(A->rmap->n * A->cmap->n)); 2979566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 2983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29980cd9d93SLois Curfman McInnes } 30080cd9d93SLois Curfman McInnes 301d71ae5a4SJacob Faibussowitsch PetscErrorCode MatShift_SeqDense(Mat A, PetscScalar alpha) 302d71ae5a4SJacob Faibussowitsch { 3032f605a99SJose E. Roman Mat_SeqDense *a = (Mat_SeqDense *)A->data; 3042f605a99SJose E. Roman PetscScalar *v; 3052f605a99SJose E. Roman PetscInt j, k; 3062f605a99SJose E. Roman 3072f605a99SJose E. Roman PetscFunctionBegin; 3082f605a99SJose E. Roman PetscCall(MatDenseGetArray(A, &v)); 3092f605a99SJose E. Roman k = PetscMin(A->rmap->n, A->cmap->n); 3102f605a99SJose E. Roman for (j = 0; j < k; j++) v[j + j * a->lda] += alpha; 3112f605a99SJose E. Roman PetscCall(PetscLogFlops(k)); 3122f605a99SJose E. Roman PetscCall(MatDenseRestoreArray(A, &v)); 3133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3142f605a99SJose E. Roman } 3152f605a99SJose E. Roman 316d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatIsHermitian_SeqDense(Mat A, PetscReal rtol, PetscBool *fl) 317d71ae5a4SJacob Faibussowitsch { 3181cbb95d3SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 319ca15aa20SStefano Zampini PetscInt i, j, m = A->rmap->n, N = a->lda; 320ca15aa20SStefano Zampini const PetscScalar *v; 3211cbb95d3SBarry Smith 3221cbb95d3SBarry Smith PetscFunctionBegin; 3231cbb95d3SBarry Smith *fl = PETSC_FALSE; 3243ba16761SJacob Faibussowitsch if (A->rmap->n != A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 3259566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 3261cbb95d3SBarry Smith for (i = 0; i < m; i++) { 327ca15aa20SStefano Zampini for (j = i; j < m; j++) { 328ad540459SPierre Jolivet if (PetscAbsScalar(v[i + j * N] - PetscConj(v[j + i * N])) > rtol) goto restore; 3291cbb95d3SBarry Smith } 330637a0070SStefano Zampini } 3311cbb95d3SBarry Smith *fl = PETSC_TRUE; 332637a0070SStefano Zampini restore: 3339566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 3343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 335637a0070SStefano Zampini } 336637a0070SStefano Zampini 337d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatIsSymmetric_SeqDense(Mat A, PetscReal rtol, PetscBool *fl) 338d71ae5a4SJacob Faibussowitsch { 339637a0070SStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 340637a0070SStefano Zampini PetscInt i, j, m = A->rmap->n, N = a->lda; 341637a0070SStefano Zampini const PetscScalar *v; 342637a0070SStefano Zampini 343637a0070SStefano Zampini PetscFunctionBegin; 344637a0070SStefano Zampini *fl = PETSC_FALSE; 3453ba16761SJacob Faibussowitsch if (A->rmap->n != A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 3469566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 347637a0070SStefano Zampini for (i = 0; i < m; i++) { 348637a0070SStefano Zampini for (j = i; j < m; j++) { 349ad540459SPierre Jolivet if (PetscAbsScalar(v[i + j * N] - v[j + i * N]) > rtol) goto restore; 350637a0070SStefano Zampini } 351637a0070SStefano Zampini } 352637a0070SStefano Zampini *fl = PETSC_TRUE; 353637a0070SStefano Zampini restore: 3549566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 3553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3561cbb95d3SBarry Smith } 3571cbb95d3SBarry Smith 358d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi, Mat A, MatDuplicateOption cpvalues) 359d71ae5a4SJacob Faibussowitsch { 360ca15aa20SStefano Zampini Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 36123fc5dcaSStefano Zampini PetscInt lda = (PetscInt)mat->lda, j, m, nlda = lda; 36275f6d85dSStefano Zampini PetscBool isdensecpu; 363b24902e0SBarry Smith 364b24902e0SBarry Smith PetscFunctionBegin; 3659566063dSJacob Faibussowitsch PetscCall(PetscLayoutReference(A->rmap, &newi->rmap)); 3669566063dSJacob Faibussowitsch PetscCall(PetscLayoutReference(A->cmap, &newi->cmap)); 36723fc5dcaSStefano Zampini if (cpvalues == MAT_SHARE_NONZERO_PATTERN) { /* propagate LDA */ 3689566063dSJacob Faibussowitsch PetscCall(MatDenseSetLDA(newi, lda)); 36923fc5dcaSStefano Zampini } 3709566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)newi, MATSEQDENSE, &isdensecpu)); 3719566063dSJacob Faibussowitsch if (isdensecpu) PetscCall(MatSeqDenseSetPreallocation(newi, NULL)); 372b24902e0SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 373ca15aa20SStefano Zampini const PetscScalar *av; 374ca15aa20SStefano Zampini PetscScalar *v; 375ca15aa20SStefano Zampini 3769566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 3779566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(newi, &v)); 3789566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(newi, &nlda)); 379d0f46423SBarry Smith m = A->rmap->n; 38023fc5dcaSStefano Zampini if (lda > m || nlda > m) { 381*8e3a54c0SPierre Jolivet for (j = 0; j < A->cmap->n; j++) PetscCall(PetscArraycpy(PetscSafePointerPlusOffset(v, j * nlda), PetscSafePointerPlusOffset(av, j * lda), m)); 382b24902e0SBarry Smith } else { 3839566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(v, av, A->rmap->n * A->cmap->n)); 384b24902e0SBarry Smith } 3859566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(newi, &v)); 3869566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 387b24902e0SBarry Smith } 3883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 389b24902e0SBarry Smith } 390b24902e0SBarry Smith 391d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDuplicate_SeqDense(Mat A, MatDuplicateOption cpvalues, Mat *newmat) 392d71ae5a4SJacob Faibussowitsch { 3933a40ed3dSBarry Smith PetscFunctionBegin; 3949566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), newmat)); 3959566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*newmat, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n)); 3969566063dSJacob Faibussowitsch PetscCall(MatSetType(*newmat, ((PetscObject)A)->type_name)); 3979566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(*newmat, A, cpvalues)); 3983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 399b24902e0SBarry Smith } 400b24902e0SBarry Smith 401d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_LU(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T) 402d71ae5a4SJacob Faibussowitsch { 403c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4044396437dSToby Isaac PetscBLASInt info; 40567e560aaSBarry Smith 4063a40ed3dSBarry Smith PetscFunctionBegin; 4079566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 408792fecdfSBarry Smith PetscCallBLAS("LAPACKgetrs", LAPACKgetrs_(T ? "T" : "N", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info)); 4099566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 41005fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "GETRS - Bad solve %d", (int)info); 4119566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m))); 4123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4134396437dSToby Isaac } 4144396437dSToby Isaac 4154396437dSToby Isaac static PetscErrorCode MatConjugate_SeqDense(Mat); 4164396437dSToby Isaac 417d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_Cholesky(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T) 418d71ae5a4SJacob Faibussowitsch { 4194396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4204396437dSToby Isaac PetscBLASInt info; 4214396437dSToby Isaac 4224396437dSToby Isaac PetscFunctionBegin; 423b94d7dedSBarry Smith if (A->spd == PETSC_BOOL3_TRUE) { 4249566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A)); 4259566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 426792fecdfSBarry Smith PetscCallBLAS("LAPACKpotrs", LAPACKpotrs_("L", &m, &nrhs, mat->v, &mat->lda, x, &m, &info)); 4279566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 42805fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "POTRS Bad solve %d", (int)info); 4299566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A)); 430a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX) 431b94d7dedSBarry Smith } else if (A->hermitian == PETSC_BOOL3_TRUE) { 4329566063dSJacob Faibussowitsch if (T) PetscCall(MatConjugate_SeqDense(A)); 4339566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 434792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrs", LAPACKhetrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info)); 4359566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 43605fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "HETRS Bad solve %d", (int)info); 4379566063dSJacob Faibussowitsch if (T) PetscCall(MatConjugate_SeqDense(A)); 438a49dc2a2SStefano Zampini #endif 439a49dc2a2SStefano Zampini } else { /* symmetric case */ 4409566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 441792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrs", LAPACKsytrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info)); 4429566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 44305fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "SYTRS Bad solve %d", (int)info); 444a49dc2a2SStefano Zampini } 4459566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m))); 4463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4474396437dSToby Isaac } 44885e2c93fSHong Zhang 449d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k) 450d71ae5a4SJacob Faibussowitsch { 4514396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4524396437dSToby Isaac PetscBLASInt info; 4534396437dSToby Isaac char trans; 4544396437dSToby Isaac 4554396437dSToby Isaac PetscFunctionBegin; 4564905a7bcSToby Isaac if (PetscDefined(USE_COMPLEX)) { 4574905a7bcSToby Isaac trans = 'C'; 4584905a7bcSToby Isaac } else { 4594905a7bcSToby Isaac trans = 'T'; 4604905a7bcSToby Isaac } 4619566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 46205fcb23eSStefano Zampini { /* lwork depends on the number of right-hand sides */ 46305fcb23eSStefano Zampini PetscBLASInt nlfwork, lfwork = -1; 46405fcb23eSStefano Zampini PetscScalar fwork; 46505fcb23eSStefano Zampini 466792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info)); 46705fcb23eSStefano Zampini nlfwork = (PetscBLASInt)PetscRealPart(fwork); 46805fcb23eSStefano Zampini if (nlfwork > mat->lfwork) { 46905fcb23eSStefano Zampini mat->lfwork = nlfwork; 47005fcb23eSStefano Zampini PetscCall(PetscFree(mat->fwork)); 47105fcb23eSStefano Zampini PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 47205fcb23eSStefano Zampini } 47305fcb23eSStefano Zampini } 474792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info)); 4759566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 47605fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %d", (int)info); 4779566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 478792fecdfSBarry Smith PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "N", "N", &mat->rank, &nrhs, mat->v, &mat->lda, x, &ldx, &info)); 4799566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 48005fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %d", (int)info); 4814905a7bcSToby Isaac for (PetscInt j = 0; j < nrhs; j++) { 482ad540459SPierre Jolivet for (PetscInt i = mat->rank; i < k; i++) x[j * ldx + i] = 0.; 4834905a7bcSToby Isaac } 4849566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank)))); 4853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4864905a7bcSToby Isaac } 4874905a7bcSToby Isaac 488d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k) 489d71ae5a4SJacob Faibussowitsch { 4904396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4914396437dSToby Isaac PetscBLASInt info; 4924396437dSToby Isaac 4934396437dSToby Isaac PetscFunctionBegin; 4944396437dSToby Isaac if (A->rmap->n == A->cmap->n && mat->rank == A->rmap->n) { 4959566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 496792fecdfSBarry Smith PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "T", "N", &m, &nrhs, mat->v, &mat->lda, x, &ldx, &info)); 4979566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 49805fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %d", (int)info); 4999566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A)); 50005fcb23eSStefano Zampini { /* lwork depends on the number of right-hand sides */ 50105fcb23eSStefano Zampini PetscBLASInt nlfwork, lfwork = -1; 50205fcb23eSStefano Zampini PetscScalar fwork; 50305fcb23eSStefano Zampini 504792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info)); 50505fcb23eSStefano Zampini nlfwork = (PetscBLASInt)PetscRealPart(fwork); 50605fcb23eSStefano Zampini if (nlfwork > mat->lfwork) { 50705fcb23eSStefano Zampini mat->lfwork = nlfwork; 50805fcb23eSStefano Zampini PetscCall(PetscFree(mat->fwork)); 50905fcb23eSStefano Zampini PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 51005fcb23eSStefano Zampini } 51105fcb23eSStefano Zampini } 5129566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 513792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info)); 5149566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 51505fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %d", (int)info); 5169566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A)); 5174396437dSToby Isaac } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "QR factored matrix cannot be used for transpose solve"); 5189566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank)))); 5193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5204396437dSToby Isaac } 5214396437dSToby Isaac 522d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_SetUp(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k) 523d71ae5a4SJacob Faibussowitsch { 5244396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 5254905a7bcSToby Isaac PetscScalar *y; 5264905a7bcSToby Isaac PetscBLASInt m = 0, k = 0; 5274905a7bcSToby Isaac 5284905a7bcSToby Isaac PetscFunctionBegin; 5299566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 5309566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 5314905a7bcSToby Isaac if (k < m) { 5329566063dSJacob Faibussowitsch PetscCall(VecCopy(xx, mat->qrrhs)); 5339566063dSJacob Faibussowitsch PetscCall(VecGetArray(mat->qrrhs, &y)); 5344905a7bcSToby Isaac } else { 5359566063dSJacob Faibussowitsch PetscCall(VecCopy(xx, yy)); 5369566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &y)); 5374905a7bcSToby Isaac } 5384396437dSToby Isaac *_y = y; 5394396437dSToby Isaac *_k = k; 5404396437dSToby Isaac *_m = m; 5413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5424396437dSToby Isaac } 5434396437dSToby Isaac 544d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_TearDown(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k) 545d71ae5a4SJacob Faibussowitsch { 5464396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 54742e9364cSSatish Balay PetscScalar *y = NULL; 5484396437dSToby Isaac PetscBLASInt m, k; 5494396437dSToby Isaac 5504396437dSToby Isaac PetscFunctionBegin; 5514396437dSToby Isaac y = *_y; 5524396437dSToby Isaac *_y = NULL; 5534396437dSToby Isaac k = *_k; 5544396437dSToby Isaac m = *_m; 5554905a7bcSToby Isaac if (k < m) { 5564905a7bcSToby Isaac PetscScalar *yv; 5579566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &yv)); 5589566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(yv, y, k)); 5599566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &yv)); 5609566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(mat->qrrhs, &y)); 5614905a7bcSToby Isaac } else { 5629566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &y)); 5634905a7bcSToby Isaac } 5643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5654905a7bcSToby Isaac } 5664905a7bcSToby Isaac 567d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_LU(Mat A, Vec xx, Vec yy) 568d71ae5a4SJacob Faibussowitsch { 56942e9364cSSatish Balay PetscScalar *y = NULL; 57042e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 5714396437dSToby Isaac 5724396437dSToby Isaac PetscFunctionBegin; 5739566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 5749566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_FALSE)); 5759566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 5763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5774396437dSToby Isaac } 5784396437dSToby Isaac 579d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_LU(Mat A, Vec xx, Vec yy) 580d71ae5a4SJacob Faibussowitsch { 58142e9364cSSatish Balay PetscScalar *y = NULL; 58242e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 5834396437dSToby Isaac 5844396437dSToby Isaac PetscFunctionBegin; 5859566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 5869566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_TRUE)); 5879566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 5883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5894396437dSToby Isaac } 5904396437dSToby Isaac 591d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Cholesky(Mat A, Vec xx, Vec yy) 592d71ae5a4SJacob Faibussowitsch { 593e54beecaSStefano Zampini PetscScalar *y = NULL; 594e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 5954396437dSToby Isaac 5964396437dSToby Isaac PetscFunctionBegin; 5979566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 5989566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_FALSE)); 5999566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6014396437dSToby Isaac } 6024396437dSToby Isaac 603d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_Cholesky(Mat A, Vec xx, Vec yy) 604d71ae5a4SJacob Faibussowitsch { 605e54beecaSStefano Zampini PetscScalar *y = NULL; 606e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 6074396437dSToby Isaac 6084396437dSToby Isaac PetscFunctionBegin; 6099566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6109566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_TRUE)); 6119566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6134396437dSToby Isaac } 6144396437dSToby Isaac 615d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_QR(Mat A, Vec xx, Vec yy) 616d71ae5a4SJacob Faibussowitsch { 617e54beecaSStefano Zampini PetscScalar *y = NULL; 618e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 6194396437dSToby Isaac 6204396437dSToby Isaac PetscFunctionBegin; 6219566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6229566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k)); 6239566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6254396437dSToby Isaac } 6264396437dSToby Isaac 627d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_QR(Mat A, Vec xx, Vec yy) 628d71ae5a4SJacob Faibussowitsch { 62942e9364cSSatish Balay PetscScalar *y = NULL; 63042e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 6314396437dSToby Isaac 6324396437dSToby Isaac PetscFunctionBegin; 6339566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6349566063dSJacob Faibussowitsch PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k)); 6359566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6374396437dSToby Isaac } 6384396437dSToby Isaac 639d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_SetUp(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k) 640d71ae5a4SJacob Faibussowitsch { 6414905a7bcSToby Isaac const PetscScalar *b; 6424396437dSToby Isaac PetscScalar *y; 643bf5a80bcSToby Isaac PetscInt n, _ldb, _ldx; 644bf5a80bcSToby Isaac PetscBLASInt nrhs = 0, m = 0, k = 0, ldb = 0, ldx = 0, ldy = 0; 6454905a7bcSToby Isaac 6464905a7bcSToby Isaac PetscFunctionBegin; 6479371c9d4SSatish Balay *_ldy = 0; 6489371c9d4SSatish Balay *_m = 0; 6499371c9d4SSatish Balay *_nrhs = 0; 6509371c9d4SSatish Balay *_k = 0; 6519371c9d4SSatish Balay *_y = NULL; 6529566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 6539566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 6549566063dSJacob Faibussowitsch PetscCall(MatGetSize(B, NULL, &n)); 6559566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(n, &nrhs)); 6569566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(B, &_ldb)); 6579566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldb, &ldb)); 6589566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(X, &_ldx)); 6599566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldx, &ldx)); 660bf5a80bcSToby Isaac if (ldx < m) { 6619566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &b)); 6629566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nrhs * m, &y)); 663bf5a80bcSToby Isaac if (ldb == m) { 6649566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(y, b, ldb * nrhs)); 6654905a7bcSToby Isaac } else { 66648a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * m], &b[j * ldb], m)); 6674905a7bcSToby Isaac } 668bf5a80bcSToby Isaac ldy = m; 6699566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &b)); 6704905a7bcSToby Isaac } else { 671bf5a80bcSToby Isaac if (ldb == ldx) { 6729566063dSJacob Faibussowitsch PetscCall(MatCopy(B, X, SAME_NONZERO_PATTERN)); 6739566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &y)); 6744905a7bcSToby Isaac } else { 6759566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &y)); 6769566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &b)); 67748a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * ldx], &b[j * ldb], m)); 6789566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &b)); 6794905a7bcSToby Isaac } 680bf5a80bcSToby Isaac ldy = ldx; 6814905a7bcSToby Isaac } 6824396437dSToby Isaac *_y = y; 683bf5a80bcSToby Isaac *_ldy = ldy; 6844396437dSToby Isaac *_k = k; 6854396437dSToby Isaac *_m = m; 6864396437dSToby Isaac *_nrhs = nrhs; 6873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6884396437dSToby Isaac } 6894396437dSToby Isaac 690d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_TearDown(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k) 691d71ae5a4SJacob Faibussowitsch { 6924396437dSToby Isaac PetscScalar *y; 693bf5a80bcSToby Isaac PetscInt _ldx; 694bf5a80bcSToby Isaac PetscBLASInt k, ldy, nrhs, ldx = 0; 6954396437dSToby Isaac 6964396437dSToby Isaac PetscFunctionBegin; 6974396437dSToby Isaac y = *_y; 6984396437dSToby Isaac *_y = NULL; 6994396437dSToby Isaac k = *_k; 700bf5a80bcSToby Isaac ldy = *_ldy; 7014396437dSToby Isaac nrhs = *_nrhs; 7029566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(X, &_ldx)); 7039566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldx, &ldx)); 704bf5a80bcSToby Isaac if (ldx != ldy) { 7054905a7bcSToby Isaac PetscScalar *xv; 7069566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &xv)); 70748a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&xv[j * ldx], &y[j * ldy], k)); 7089566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(X, &xv)); 7099566063dSJacob Faibussowitsch PetscCall(PetscFree(y)); 7104905a7bcSToby Isaac } else { 7119566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(X, &y)); 7124905a7bcSToby Isaac } 7133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 71485e2c93fSHong Zhang } 71585e2c93fSHong Zhang 716d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_LU(Mat A, Mat B, Mat X) 717d71ae5a4SJacob Faibussowitsch { 7184396437dSToby Isaac PetscScalar *y; 719bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7204396437dSToby Isaac 7214396437dSToby Isaac PetscFunctionBegin; 7229566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7239566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_FALSE)); 7249566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7264396437dSToby Isaac } 7274396437dSToby Isaac 728d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_LU(Mat A, Mat B, Mat X) 729d71ae5a4SJacob Faibussowitsch { 7304396437dSToby Isaac PetscScalar *y; 731bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7324396437dSToby Isaac 7334396437dSToby Isaac PetscFunctionBegin; 7349566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7359566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_TRUE)); 7369566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7384396437dSToby Isaac } 7394396437dSToby Isaac 740d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_Cholesky(Mat A, Mat B, Mat X) 741d71ae5a4SJacob Faibussowitsch { 7424396437dSToby Isaac PetscScalar *y; 743bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7444396437dSToby Isaac 7454396437dSToby Isaac PetscFunctionBegin; 7469566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7479566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_FALSE)); 7489566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7504396437dSToby Isaac } 7514396437dSToby Isaac 752d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_Cholesky(Mat A, Mat B, Mat X) 753d71ae5a4SJacob Faibussowitsch { 7544396437dSToby Isaac PetscScalar *y; 755bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7564396437dSToby Isaac 7574396437dSToby Isaac PetscFunctionBegin; 7589566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7599566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_TRUE)); 7609566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7624396437dSToby Isaac } 7634396437dSToby Isaac 764d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_QR(Mat A, Mat B, Mat X) 765d71ae5a4SJacob Faibussowitsch { 7664396437dSToby Isaac PetscScalar *y; 767bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7684396437dSToby Isaac 7694396437dSToby Isaac PetscFunctionBegin; 7709566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7719566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k)); 7729566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7744396437dSToby Isaac } 7754396437dSToby Isaac 776d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_QR(Mat A, Mat B, Mat X) 777d71ae5a4SJacob Faibussowitsch { 7784396437dSToby Isaac PetscScalar *y; 779bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7804396437dSToby Isaac 7814396437dSToby Isaac PetscFunctionBegin; 7829566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7839566063dSJacob Faibussowitsch PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k)); 7849566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7864396437dSToby Isaac } 7874396437dSToby Isaac 788db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots, 789db4efbfdSBarry Smith rather than put it in the Mat->row slot.*/ 790d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLUFactor_SeqDense(Mat A, IS row, IS col, const MatFactorInfo *minfo) 791d71ae5a4SJacob Faibussowitsch { 792db4efbfdSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 793db4efbfdSBarry Smith PetscBLASInt n, m, info; 794db4efbfdSBarry Smith 795db4efbfdSBarry Smith PetscFunctionBegin; 7969566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 7979566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 7984dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); } 7993ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 8009566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 801792fecdfSBarry Smith PetscCallBLAS("LAPACKgetrf", LAPACKgetrf_(&m, &n, mat->v, &mat->lda, mat->pivots, &info)); 8029566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 8038e57ea43SSatish Balay 80405fcb23eSStefano Zampini PetscCheck(info >= 0, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to LU factorization %d", (int)info); 80505fcb23eSStefano Zampini PetscCheck(info <= 0, PETSC_COMM_SELF, PETSC_ERR_MAT_LU_ZRPVT, "Bad LU factorization %d", (int)info); 8068208b9aeSStefano Zampini 8074396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_LU; 8084396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_LU; 8094396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_LU; 8104396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_LU; 811d5f3da31SBarry Smith A->factortype = MAT_FACTOR_LU; 812db4efbfdSBarry Smith 8139566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 8149566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 815f6224b95SHong Zhang 8169566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((2.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3)); 8173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 818db4efbfdSBarry Smith } 819db4efbfdSBarry Smith 820d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) 821d71ae5a4SJacob Faibussowitsch { 8224396437dSToby Isaac MatFactorInfo info; 8234396437dSToby Isaac 8244396437dSToby Isaac PetscFunctionBegin; 8259566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 826dbbe0bcdSBarry Smith PetscUseTypeMethod(fact, lufactor, NULL, NULL, &info); 8273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8284396437dSToby Isaac } 8294396437dSToby Isaac 830d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, IS col, const MatFactorInfo *info) 831d71ae5a4SJacob Faibussowitsch { 8324396437dSToby Isaac PetscFunctionBegin; 8334396437dSToby Isaac fact->preallocated = PETSC_TRUE; 8344396437dSToby Isaac fact->assembled = PETSC_TRUE; 8354396437dSToby Isaac fact->ops->lufactornumeric = MatLUFactorNumeric_SeqDense; 8363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8374396437dSToby Isaac } 8384396437dSToby Isaac 839a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */ 840d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCholeskyFactor_SeqDense(Mat A, IS perm, const MatFactorInfo *factinfo) 841d71ae5a4SJacob Faibussowitsch { 842db4efbfdSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 843c5df96a5SBarry Smith PetscBLASInt info, n; 844db4efbfdSBarry Smith 845db4efbfdSBarry Smith PetscFunctionBegin; 8469566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 8473ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 848b94d7dedSBarry Smith if (A->spd == PETSC_BOOL3_TRUE) { 8499566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 850792fecdfSBarry Smith PetscCallBLAS("LAPACKpotrf", LAPACKpotrf_("L", &n, mat->v, &mat->lda, &info)); 8519566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 852a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX) 853b94d7dedSBarry Smith } else if (A->hermitian == PETSC_BOOL3_TRUE) { 8544dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); } 855a49dc2a2SStefano Zampini if (!mat->fwork) { 856a49dc2a2SStefano Zampini PetscScalar dummy; 857a49dc2a2SStefano Zampini 858a49dc2a2SStefano Zampini mat->lfwork = -1; 8599566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 860792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info)); 8619566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 862a49dc2a2SStefano Zampini mat->lfwork = (PetscInt)PetscRealPart(dummy); 8639566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 864a49dc2a2SStefano Zampini } 8659566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 866792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info)); 8679566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 868a49dc2a2SStefano Zampini #endif 869a49dc2a2SStefano Zampini } else { /* symmetric case */ 8704dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); } 871a49dc2a2SStefano Zampini if (!mat->fwork) { 872a49dc2a2SStefano Zampini PetscScalar dummy; 873a49dc2a2SStefano Zampini 874a49dc2a2SStefano Zampini mat->lfwork = -1; 8759566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 876792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info)); 8779566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 878a49dc2a2SStefano Zampini mat->lfwork = (PetscInt)PetscRealPart(dummy); 8799566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 880a49dc2a2SStefano Zampini } 8819566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 882792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info)); 8839566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 884a49dc2a2SStefano Zampini } 88528b400f6SJacob Faibussowitsch PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad factorization: zero pivot in row %" PetscInt_FMT, (PetscInt)info - 1); 8868208b9aeSStefano Zampini 8874396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_Cholesky; 8884396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_Cholesky; 8894396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_Cholesky; 8904396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_Cholesky; 891d5f3da31SBarry Smith A->factortype = MAT_FACTOR_CHOLESKY; 8922205254eSKarl Rupp 8939566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 8949566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 895f6224b95SHong Zhang 8969566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0)); 8973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 898db4efbfdSBarry Smith } 899db4efbfdSBarry Smith 900d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) 901d71ae5a4SJacob Faibussowitsch { 902db4efbfdSBarry Smith MatFactorInfo info; 903db4efbfdSBarry Smith 904db4efbfdSBarry Smith PetscFunctionBegin; 905db4efbfdSBarry Smith info.fill = 1.0; 9062205254eSKarl Rupp 9079566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 908dbbe0bcdSBarry Smith PetscUseTypeMethod(fact, choleskyfactor, NULL, &info); 9093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 910db4efbfdSBarry Smith } 911db4efbfdSBarry Smith 912d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info) 913d71ae5a4SJacob Faibussowitsch { 914db4efbfdSBarry Smith PetscFunctionBegin; 915c3ef05f6SHong Zhang fact->assembled = PETSC_TRUE; 9161bbcc794SSatish Balay fact->preallocated = PETSC_TRUE; 917719d5645SBarry Smith fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense; 9183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 919db4efbfdSBarry Smith } 920db4efbfdSBarry Smith 921d71ae5a4SJacob Faibussowitsch PetscErrorCode MatQRFactor_SeqDense(Mat A, IS col, const MatFactorInfo *minfo) 922d71ae5a4SJacob Faibussowitsch { 9234905a7bcSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 9244905a7bcSToby Isaac PetscBLASInt n, m, info, min, max; 9254905a7bcSToby Isaac 9264905a7bcSToby Isaac PetscFunctionBegin; 9279566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 9289566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 9294396437dSToby Isaac max = PetscMax(m, n); 9304396437dSToby Isaac min = PetscMin(m, n); 9314dfa11a4SJacob Faibussowitsch if (!mat->tau) { PetscCall(PetscMalloc1(min, &mat->tau)); } 9324dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(n, &mat->pivots)); } 93348a46eb9SPierre Jolivet if (!mat->qrrhs) PetscCall(MatCreateVecs(A, NULL, &(mat->qrrhs))); 9343ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 9354905a7bcSToby Isaac if (!mat->fwork) { 9364905a7bcSToby Isaac PetscScalar dummy; 9374905a7bcSToby Isaac 9384905a7bcSToby Isaac mat->lfwork = -1; 9399566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 940792fecdfSBarry Smith PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, &dummy, &mat->lfwork, &info)); 9419566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 9424905a7bcSToby Isaac mat->lfwork = (PetscInt)PetscRealPart(dummy); 9439566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 9444905a7bcSToby Isaac } 9459566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 946792fecdfSBarry Smith PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, mat->fwork, &mat->lfwork, &info)); 9479566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 94805fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to QR factorization %d", (int)info); 9494905a7bcSToby Isaac // TODO: try to estimate rank or test for and use geqp3 for rank revealing QR. For now just say rank is min of m and n 9504905a7bcSToby Isaac mat->rank = min; 9514905a7bcSToby Isaac 9524396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_QR; 9534396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_QR; 9544905a7bcSToby Isaac A->factortype = MAT_FACTOR_QR; 9554905a7bcSToby Isaac if (m == n) { 9564396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_QR; 9574396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_QR; 9584905a7bcSToby Isaac } 9594905a7bcSToby Isaac 9609566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 9619566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 9624905a7bcSToby Isaac 9639566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * min * min * (max - min / 3.0))); 9643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9654905a7bcSToby Isaac } 9664905a7bcSToby Isaac 967d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatQRFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) 968d71ae5a4SJacob Faibussowitsch { 9694905a7bcSToby Isaac MatFactorInfo info; 9704905a7bcSToby Isaac 9714905a7bcSToby Isaac PetscFunctionBegin; 9724905a7bcSToby Isaac info.fill = 1.0; 9734905a7bcSToby Isaac 9749566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 975cac4c232SBarry Smith PetscUseMethod(fact, "MatQRFactor_C", (Mat, IS, const MatFactorInfo *), (fact, NULL, &info)); 9763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9774905a7bcSToby Isaac } 9784905a7bcSToby Isaac 979d71ae5a4SJacob Faibussowitsch PetscErrorCode MatQRFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info) 980d71ae5a4SJacob Faibussowitsch { 9814905a7bcSToby Isaac PetscFunctionBegin; 9824905a7bcSToby Isaac fact->assembled = PETSC_TRUE; 9834905a7bcSToby Isaac fact->preallocated = PETSC_TRUE; 9849566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)fact, "MatQRFactorNumeric_C", MatQRFactorNumeric_SeqDense)); 9853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9864905a7bcSToby Isaac } 9874905a7bcSToby Isaac 988ca15aa20SStefano Zampini /* uses LAPACK */ 989d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A, MatFactorType ftype, Mat *fact) 990d71ae5a4SJacob Faibussowitsch { 991db4efbfdSBarry Smith PetscFunctionBegin; 9929566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), fact)); 9939566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*fact, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n)); 9949566063dSJacob Faibussowitsch PetscCall(MatSetType(*fact, MATDENSE)); 99566e17bc3SBarry Smith (*fact)->trivialsymbolic = PETSC_TRUE; 9962a350339SBarry Smith if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU) { 997db4efbfdSBarry Smith (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense; 9982a350339SBarry Smith (*fact)->ops->ilufactorsymbolic = MatLUFactorSymbolic_SeqDense; 999bf5a80bcSToby Isaac } else if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) { 1000db4efbfdSBarry Smith (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense; 1001bf5a80bcSToby Isaac } else if (ftype == MAT_FACTOR_QR) { 10029566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)(*fact), "MatQRFactorSymbolic_C", MatQRFactorSymbolic_SeqDense)); 1003db4efbfdSBarry Smith } 1004d5f3da31SBarry Smith (*fact)->factortype = ftype; 100500c67f3bSHong Zhang 10069566063dSJacob Faibussowitsch PetscCall(PetscFree((*fact)->solvertype)); 10079566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &(*fact)->solvertype)); 10089566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_LU])); 10099566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ILU])); 10109566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_CHOLESKY])); 10119566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ICC])); 10123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1013db4efbfdSBarry Smith } 1014db4efbfdSBarry Smith 1015d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSOR_SeqDense(Mat A, Vec bb, PetscReal omega, MatSORType flag, PetscReal shift, PetscInt its, PetscInt lits, Vec xx) 1016d71ae5a4SJacob Faibussowitsch { 1017c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1018d9ca1df4SBarry Smith PetscScalar *x, *v = mat->v, zero = 0.0, xt; 1019d9ca1df4SBarry Smith const PetscScalar *b; 1020d0f46423SBarry Smith PetscInt m = A->rmap->n, i; 102123fff9afSBarry Smith PetscBLASInt o = 1, bm = 0; 1022289bc588SBarry Smith 10233a40ed3dSBarry Smith PetscFunctionBegin; 102447d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 102508401ef6SPierre Jolivet PetscCheck(A->offloadmask != PETSC_OFFLOAD_GPU, PETSC_COMM_SELF, PETSC_ERR_SUP, "Not implemented"); 1026ca15aa20SStefano Zampini #endif 1027422a814eSBarry Smith if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */ 10289566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(m, &bm)); 1029289bc588SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 10303bffc371SBarry Smith /* this is a hack fix, should have another version without the second BLASdotu */ 10319566063dSJacob Faibussowitsch PetscCall(VecSet(xx, zero)); 1032289bc588SBarry Smith } 10339566063dSJacob Faibussowitsch PetscCall(VecGetArray(xx, &x)); 10349566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(bb, &b)); 1035b965ef7fSBarry Smith its = its * lits; 103608401ef6SPierre Jolivet PetscCheck(its > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Relaxation requires global its %" PetscInt_FMT " and local its %" PetscInt_FMT " both positive", its, lits); 1037289bc588SBarry Smith while (its--) { 1038fccaa45eSBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 1039289bc588SBarry Smith for (i = 0; i < m; i++) { 1040792fecdfSBarry Smith PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o)); 104155a1b374SBarry Smith x[i] = (1. - omega) * x[i] + omega * (xt + v[i + i * m] * x[i]) / (v[i + i * m] + shift); 1042289bc588SBarry Smith } 1043289bc588SBarry Smith } 1044fccaa45eSBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 1045289bc588SBarry Smith for (i = m - 1; i >= 0; i--) { 1046792fecdfSBarry Smith PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o)); 104755a1b374SBarry Smith x[i] = (1. - omega) * x[i] + omega * (xt + v[i + i * m] * x[i]) / (v[i + i * m] + shift); 1048289bc588SBarry Smith } 1049289bc588SBarry Smith } 1050289bc588SBarry Smith } 10519566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(bb, &b)); 10529566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(xx, &x)); 10533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1054289bc588SBarry Smith } 1055289bc588SBarry Smith 1056d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultTranspose_SeqDense(Mat A, Vec xx, Vec yy) 1057d71ae5a4SJacob Faibussowitsch { 1058c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1059d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 1060d9ca1df4SBarry Smith PetscScalar *y; 10610805154bSBarry Smith PetscBLASInt m, n, _One = 1; 1062ea709b57SSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 10633a40ed3dSBarry Smith 10643a40ed3dSBarry Smith PetscFunctionBegin; 10659566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 10669566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 10679566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 10689566063dSJacob Faibussowitsch PetscCall(VecGetArrayWrite(yy, &y)); 10695ac36cfcSBarry Smith if (!A->rmap->n || !A->cmap->n) { 10705ac36cfcSBarry Smith PetscBLASInt i; 10715ac36cfcSBarry Smith for (i = 0; i < n; i++) y[i] = 0.0; 10725ac36cfcSBarry Smith } else { 1073792fecdfSBarry Smith PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v, &mat->lda, x, &_One, &_DZero, y, &_One)); 10749566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n - A->cmap->n)); 10755ac36cfcSBarry Smith } 10769566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 10779566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayWrite(yy, &y)); 10783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1079289bc588SBarry Smith } 1080800995b7SMatthew Knepley 1081d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMult_SeqDense(Mat A, Vec xx, Vec yy) 1082d71ae5a4SJacob Faibussowitsch { 1083c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1084d9ca1df4SBarry Smith PetscScalar *y, _DOne = 1.0, _DZero = 0.0; 10850805154bSBarry Smith PetscBLASInt m, n, _One = 1; 1086d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 10873a40ed3dSBarry Smith 10883a40ed3dSBarry Smith PetscFunctionBegin; 10899566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 10909566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 10919566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 10929566063dSJacob Faibussowitsch PetscCall(VecGetArrayWrite(yy, &y)); 10935ac36cfcSBarry Smith if (!A->rmap->n || !A->cmap->n) { 10945ac36cfcSBarry Smith PetscBLASInt i; 10955ac36cfcSBarry Smith for (i = 0; i < m; i++) y[i] = 0.0; 10965ac36cfcSBarry Smith } else { 1097792fecdfSBarry Smith PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DZero, y, &_One)); 10989566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n - A->rmap->n)); 10995ac36cfcSBarry Smith } 11009566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 11019566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayWrite(yy, &y)); 11023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1103289bc588SBarry Smith } 11046ee01492SSatish Balay 1105d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) 1106d71ae5a4SJacob Faibussowitsch { 1107c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1108d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 1109d9ca1df4SBarry Smith PetscScalar *y, _DOne = 1.0; 11100805154bSBarry Smith PetscBLASInt m, n, _One = 1; 11113a40ed3dSBarry Smith 11123a40ed3dSBarry Smith PetscFunctionBegin; 11139566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 11149566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 11159566063dSJacob Faibussowitsch PetscCall(VecCopy(zz, yy)); 11163ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 11179566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 11189566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &y)); 1119792fecdfSBarry Smith PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DOne, y, &_One)); 11209566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 11219566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &y)); 11229566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n)); 11233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1124289bc588SBarry Smith } 11256ee01492SSatish Balay 1126d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) 1127d71ae5a4SJacob Faibussowitsch { 1128c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1129d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 1130d9ca1df4SBarry Smith PetscScalar *y; 11310805154bSBarry Smith PetscBLASInt m, n, _One = 1; 113287828ca2SBarry Smith PetscScalar _DOne = 1.0; 11333a40ed3dSBarry Smith 11343a40ed3dSBarry Smith PetscFunctionBegin; 11359566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 11369566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 11379566063dSJacob Faibussowitsch PetscCall(VecCopy(zz, yy)); 11383ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 11399566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 11409566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &y)); 1141792fecdfSBarry Smith PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DOne, y, &_One)); 11429566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 11439566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &y)); 11449566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n)); 11453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1146289bc588SBarry Smith } 1147289bc588SBarry Smith 1148d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals) 1149d71ae5a4SJacob Faibussowitsch { 1150c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 115113f74950SBarry Smith PetscInt i; 115267e560aaSBarry Smith 11533a40ed3dSBarry Smith PetscFunctionBegin; 1154c3e1b152SPierre Jolivet if (ncols) *ncols = A->cmap->n; 1155289bc588SBarry Smith if (cols) { 11569566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->cmap->n, cols)); 1157d0f46423SBarry Smith for (i = 0; i < A->cmap->n; i++) (*cols)[i] = i; 1158289bc588SBarry Smith } 1159289bc588SBarry Smith if (vals) { 1160ca15aa20SStefano Zampini const PetscScalar *v; 1161ca15aa20SStefano Zampini 11629566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 11639566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->cmap->n, vals)); 1164ca15aa20SStefano Zampini v += row; 11659371c9d4SSatish Balay for (i = 0; i < A->cmap->n; i++) { 11669371c9d4SSatish Balay (*vals)[i] = *v; 11679371c9d4SSatish Balay v += mat->lda; 11689371c9d4SSatish Balay } 11699566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 1170289bc588SBarry Smith } 11713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1172289bc588SBarry Smith } 11736ee01492SSatish Balay 1174d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRestoreRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals) 1175d71ae5a4SJacob Faibussowitsch { 1176606d414cSSatish Balay PetscFunctionBegin; 11779566063dSJacob Faibussowitsch if (cols) PetscCall(PetscFree(*cols)); 11789566063dSJacob Faibussowitsch if (vals) PetscCall(PetscFree(*vals)); 11793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1180289bc588SBarry Smith } 11812ef1f0ffSBarry Smith 1182d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], const PetscScalar v[], InsertMode addv) 1183d71ae5a4SJacob Faibussowitsch { 1184c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1185ca15aa20SStefano Zampini PetscScalar *av; 118613f74950SBarry Smith PetscInt i, j, idx = 0; 118747d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1188c70f7ee4SJunchao Zhang PetscOffloadMask oldf; 1189ca15aa20SStefano Zampini #endif 1190d6dfbf8fSBarry Smith 11913a40ed3dSBarry Smith PetscFunctionBegin; 11929566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &av)); 1193289bc588SBarry Smith if (!mat->roworiented) { 1194dbb450caSBarry Smith if (addv == INSERT_VALUES) { 1195289bc588SBarry Smith for (j = 0; j < n; j++) { 11969371c9d4SSatish Balay if (indexn[j] < 0) { 11979371c9d4SSatish Balay idx += m; 11989371c9d4SSatish Balay continue; 11999371c9d4SSatish Balay } 12006bdcaf15SBarry 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); 1201289bc588SBarry Smith for (i = 0; i < m; i++) { 12029371c9d4SSatish Balay if (indexm[i] < 0) { 12039371c9d4SSatish Balay idx++; 12049371c9d4SSatish Balay continue; 12059371c9d4SSatish Balay } 12066bdcaf15SBarry 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); 1207ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] = v[idx++]; 1208289bc588SBarry Smith } 1209289bc588SBarry Smith } 12103a40ed3dSBarry Smith } else { 1211289bc588SBarry Smith for (j = 0; j < n; j++) { 12129371c9d4SSatish Balay if (indexn[j] < 0) { 12139371c9d4SSatish Balay idx += m; 12149371c9d4SSatish Balay continue; 12159371c9d4SSatish Balay } 12166bdcaf15SBarry 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); 1217289bc588SBarry Smith for (i = 0; i < m; i++) { 12189371c9d4SSatish Balay if (indexm[i] < 0) { 12199371c9d4SSatish Balay idx++; 12209371c9d4SSatish Balay continue; 12219371c9d4SSatish Balay } 12226bdcaf15SBarry 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); 1223ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] += v[idx++]; 1224289bc588SBarry Smith } 1225289bc588SBarry Smith } 1226289bc588SBarry Smith } 12273a40ed3dSBarry Smith } else { 1228dbb450caSBarry Smith if (addv == INSERT_VALUES) { 1229e8d4e0b9SBarry Smith for (i = 0; i < m; i++) { 12309371c9d4SSatish Balay if (indexm[i] < 0) { 12319371c9d4SSatish Balay idx += n; 12329371c9d4SSatish Balay continue; 12339371c9d4SSatish Balay } 12346bdcaf15SBarry Smith PetscCheck(indexm[i] < A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Row too large: row %" PetscInt_FMT " max %" PetscInt_FMT, indexm[i], A->rmap->n - 1); 1235e8d4e0b9SBarry Smith for (j = 0; j < n; j++) { 12369371c9d4SSatish Balay if (indexn[j] < 0) { 12379371c9d4SSatish Balay idx++; 12389371c9d4SSatish Balay continue; 12399371c9d4SSatish Balay } 12406bdcaf15SBarry 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); 1241ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] = v[idx++]; 1242e8d4e0b9SBarry Smith } 1243e8d4e0b9SBarry Smith } 12443a40ed3dSBarry Smith } else { 1245289bc588SBarry Smith for (i = 0; i < m; i++) { 12469371c9d4SSatish Balay if (indexm[i] < 0) { 12479371c9d4SSatish Balay idx += n; 12489371c9d4SSatish Balay continue; 12499371c9d4SSatish Balay } 12506bdcaf15SBarry Smith PetscCheck(indexm[i] < A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Row too large: row %" PetscInt_FMT " max %" PetscInt_FMT, indexm[i], A->rmap->n - 1); 1251289bc588SBarry Smith for (j = 0; j < n; j++) { 12529371c9d4SSatish Balay if (indexn[j] < 0) { 12539371c9d4SSatish Balay idx++; 12549371c9d4SSatish Balay continue; 12559371c9d4SSatish Balay } 12566bdcaf15SBarry 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); 1257ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] += v[idx++]; 1258289bc588SBarry Smith } 1259289bc588SBarry Smith } 1260289bc588SBarry Smith } 1261e8d4e0b9SBarry Smith } 1262ca15aa20SStefano Zampini /* hack to prevent unneeded copy to the GPU while returning the array */ 126347d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1264c70f7ee4SJunchao Zhang oldf = A->offloadmask; 1265c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_GPU; 1266ca15aa20SStefano Zampini #endif 12679566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &av)); 126847d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1269c70f7ee4SJunchao Zhang A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU); 1270ca15aa20SStefano Zampini #endif 12713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1272289bc588SBarry Smith } 1273e8d4e0b9SBarry Smith 1274d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], PetscScalar v[]) 1275d71ae5a4SJacob Faibussowitsch { 1276ae80bb75SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1277ca15aa20SStefano Zampini const PetscScalar *vv; 127813f74950SBarry Smith PetscInt i, j; 1279ae80bb75SLois Curfman McInnes 12803a40ed3dSBarry Smith PetscFunctionBegin; 12819566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &vv)); 1282ae80bb75SLois Curfman McInnes /* row-oriented output */ 1283ae80bb75SLois Curfman McInnes for (i = 0; i < m; i++) { 12849371c9d4SSatish Balay if (indexm[i] < 0) { 12859371c9d4SSatish Balay v += n; 12869371c9d4SSatish Balay continue; 12879371c9d4SSatish Balay } 128808401ef6SPierre 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); 1289ae80bb75SLois Curfman McInnes for (j = 0; j < n; j++) { 12909371c9d4SSatish Balay if (indexn[j] < 0) { 12919371c9d4SSatish Balay v++; 12929371c9d4SSatish Balay continue; 12939371c9d4SSatish Balay } 129408401ef6SPierre 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); 1295ca15aa20SStefano Zampini *v++ = vv[indexn[j] * mat->lda + indexm[i]]; 1296ae80bb75SLois Curfman McInnes } 1297ae80bb75SLois Curfman McInnes } 12989566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &vv)); 12993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1300ae80bb75SLois Curfman McInnes } 1301ae80bb75SLois Curfman McInnes 1302d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_Dense_Binary(Mat mat, PetscViewer viewer) 1303d71ae5a4SJacob Faibussowitsch { 13048491ab44SLisandro Dalcin PetscBool skipHeader; 13058491ab44SLisandro Dalcin PetscViewerFormat format; 13068491ab44SLisandro Dalcin PetscInt header[4], M, N, m, lda, i, j, k; 13078491ab44SLisandro Dalcin const PetscScalar *v; 13088491ab44SLisandro Dalcin PetscScalar *vwork; 1309aabbc4fbSShri Abhyankar 1310aabbc4fbSShri Abhyankar PetscFunctionBegin; 13119566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 13129566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader)); 13139566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 13148491ab44SLisandro Dalcin if (skipHeader) format = PETSC_VIEWER_NATIVE; 1315aabbc4fbSShri Abhyankar 13169566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &M, &N)); 13178491ab44SLisandro Dalcin 13188491ab44SLisandro Dalcin /* write matrix header */ 13199371c9d4SSatish Balay header[0] = MAT_FILE_CLASSID; 13209371c9d4SSatish Balay header[1] = M; 13219371c9d4SSatish Balay header[2] = N; 13228491ab44SLisandro Dalcin header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M * N; 13239566063dSJacob Faibussowitsch if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer, header, 4, PETSC_INT)); 13248491ab44SLisandro Dalcin 13259566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mat, &m, NULL)); 13268491ab44SLisandro Dalcin if (format != PETSC_VIEWER_NATIVE) { 13278491ab44SLisandro Dalcin PetscInt nnz = m * N, *iwork; 13288491ab44SLisandro Dalcin /* store row lengths for each row */ 13299566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz, &iwork)); 13308491ab44SLisandro Dalcin for (i = 0; i < m; i++) iwork[i] = N; 13319566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 13328491ab44SLisandro Dalcin /* store column indices (zero start index) */ 13338491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 13349371c9d4SSatish Balay for (j = 0; j < N; j++, k++) iwork[k] = j; 13359566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 13369566063dSJacob Faibussowitsch PetscCall(PetscFree(iwork)); 13378491ab44SLisandro Dalcin } 13388491ab44SLisandro Dalcin /* store matrix values as a dense matrix in row major order */ 13399566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m * N, &vwork)); 13409566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(mat, &v)); 13419566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(mat, &lda)); 13428491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 13439371c9d4SSatish Balay for (j = 0; j < N; j++, k++) vwork[k] = v[i + lda * j]; 13449566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(mat, &v)); 13459566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, vwork, m * N, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 13469566063dSJacob Faibussowitsch PetscCall(PetscFree(vwork)); 13473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13488491ab44SLisandro Dalcin } 13498491ab44SLisandro Dalcin 1350d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLoad_Dense_Binary(Mat mat, PetscViewer viewer) 1351d71ae5a4SJacob Faibussowitsch { 13528491ab44SLisandro Dalcin PetscBool skipHeader; 13538491ab44SLisandro Dalcin PetscInt header[4], M, N, m, nz, lda, i, j, k; 13548491ab44SLisandro Dalcin PetscInt rows, cols; 13558491ab44SLisandro Dalcin PetscScalar *v, *vwork; 13568491ab44SLisandro Dalcin 13578491ab44SLisandro Dalcin PetscFunctionBegin; 13589566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 13599566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader)); 13608491ab44SLisandro Dalcin 13618491ab44SLisandro Dalcin if (!skipHeader) { 13629566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, header, 4, NULL, PETSC_INT)); 136308401ef6SPierre Jolivet PetscCheck(header[0] == MAT_FILE_CLASSID, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Not a matrix object in file"); 13649371c9d4SSatish Balay M = header[1]; 13659371c9d4SSatish Balay N = header[2]; 136608401ef6SPierre Jolivet PetscCheck(M >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix row size (%" PetscInt_FMT ") in file is negative", M); 136708401ef6SPierre Jolivet PetscCheck(N >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix column size (%" PetscInt_FMT ") in file is negative", N); 13688491ab44SLisandro Dalcin nz = header[3]; 1369aed4548fSBarry Smith PetscCheck(nz == MATRIX_BINARY_FORMAT_DENSE || nz >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Unknown matrix format %" PetscInt_FMT " in file", nz); 1370aabbc4fbSShri Abhyankar } else { 13719566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &M, &N)); 1372aed4548fSBarry 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"); 13738491ab44SLisandro Dalcin nz = MATRIX_BINARY_FORMAT_DENSE; 1374e6324fbbSBarry Smith } 1375aabbc4fbSShri Abhyankar 13768491ab44SLisandro Dalcin /* setup global sizes if not set */ 13778491ab44SLisandro Dalcin if (mat->rmap->N < 0) mat->rmap->N = M; 13788491ab44SLisandro Dalcin if (mat->cmap->N < 0) mat->cmap->N = N; 13799566063dSJacob Faibussowitsch PetscCall(MatSetUp(mat)); 13808491ab44SLisandro Dalcin /* check if global sizes are correct */ 13819566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &rows, &cols)); 1382aed4548fSBarry 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); 1383aabbc4fbSShri Abhyankar 13849566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, NULL, &N)); 13859566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mat, &m, NULL)); 13869566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(mat, &v)); 13879566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(mat, &lda)); 13888491ab44SLisandro Dalcin if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense format */ 13898491ab44SLisandro Dalcin PetscInt nnz = m * N; 13908491ab44SLisandro Dalcin /* read in matrix values */ 13919566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz, &vwork)); 13929566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 13938491ab44SLisandro Dalcin /* store values in column major order */ 13948491ab44SLisandro Dalcin for (j = 0; j < N; j++) 13959371c9d4SSatish Balay for (i = 0; i < m; i++) v[i + lda * j] = vwork[i * N + j]; 13969566063dSJacob Faibussowitsch PetscCall(PetscFree(vwork)); 13978491ab44SLisandro Dalcin } else { /* matrix in file is sparse format */ 13988491ab44SLisandro Dalcin PetscInt nnz = 0, *rlens, *icols; 13998491ab44SLisandro Dalcin /* read in row lengths */ 14009566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m, &rlens)); 14019566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, rlens, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 14028491ab44SLisandro Dalcin for (i = 0; i < m; i++) nnz += rlens[i]; 14038491ab44SLisandro Dalcin /* read in column indices and values */ 14049566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(nnz, &icols, nnz, &vwork)); 14059566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, icols, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 14069566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 14078491ab44SLisandro Dalcin /* store values in column major order */ 14088491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 14099371c9d4SSatish Balay for (j = 0; j < rlens[i]; j++, k++) v[i + lda * icols[k]] = vwork[k]; 14109566063dSJacob Faibussowitsch PetscCall(PetscFree(rlens)); 14119566063dSJacob Faibussowitsch PetscCall(PetscFree2(icols, vwork)); 1412aabbc4fbSShri Abhyankar } 14139566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(mat, &v)); 14149566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY)); 14159566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY)); 14163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1417aabbc4fbSShri Abhyankar } 1418aabbc4fbSShri Abhyankar 141966976f2fSJacob Faibussowitsch static PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer) 1420d71ae5a4SJacob Faibussowitsch { 1421eb91f321SVaclav Hapla PetscBool isbinary, ishdf5; 1422eb91f321SVaclav Hapla 1423eb91f321SVaclav Hapla PetscFunctionBegin; 1424eb91f321SVaclav Hapla PetscValidHeaderSpecific(newMat, MAT_CLASSID, 1); 1425eb91f321SVaclav Hapla PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1426eb91f321SVaclav Hapla /* force binary viewer to load .info file if it has not yet done so */ 14279566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 14289566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 14299566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5)); 1430eb91f321SVaclav Hapla if (isbinary) { 14319566063dSJacob Faibussowitsch PetscCall(MatLoad_Dense_Binary(newMat, viewer)); 1432eb91f321SVaclav Hapla } else if (ishdf5) { 1433eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5) 14349566063dSJacob Faibussowitsch PetscCall(MatLoad_Dense_HDF5(newMat, viewer)); 1435eb91f321SVaclav Hapla #else 1436eb91f321SVaclav Hapla SETERRQ(PetscObjectComm((PetscObject)newMat), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1437eb91f321SVaclav Hapla #endif 1438eb91f321SVaclav Hapla } else { 143998921bdaSJacob 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); 1440eb91f321SVaclav Hapla } 14413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1442eb91f321SVaclav Hapla } 1443eb91f321SVaclav Hapla 1444d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_ASCII(Mat A, PetscViewer viewer) 1445d71ae5a4SJacob Faibussowitsch { 1446932b0c3eSLois Curfman McInnes Mat_SeqDense *a = (Mat_SeqDense *)A->data; 144713f74950SBarry Smith PetscInt i, j; 14482dcb1b2aSMatthew Knepley const char *name; 1449ca15aa20SStefano Zampini PetscScalar *v, *av; 1450f3ef73ceSBarry Smith PetscViewerFormat format; 14515f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX) 1452ace3abfcSBarry Smith PetscBool allreal = PETSC_TRUE; 14535f481a85SSatish Balay #endif 1454932b0c3eSLois Curfman McInnes 14553a40ed3dSBarry Smith PetscFunctionBegin; 14569566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&av)); 14579566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 1458456192e2SBarry Smith if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 14593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); /* do nothing for now */ 1460fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 14619566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE)); 1462d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 1463ca15aa20SStefano Zampini v = av + i; 14649566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "row %" PetscInt_FMT ":", i)); 1465d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1466aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 1467329f5518SBarry Smith if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) { 14689566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g + %g i) ", j, (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v))); 1469329f5518SBarry Smith } else if (PetscRealPart(*v)) { 14709566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)PetscRealPart(*v))); 14716831982aSBarry Smith } 147280cd9d93SLois Curfman McInnes #else 147348a46eb9SPierre Jolivet if (*v) PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)*v)); 147480cd9d93SLois Curfman McInnes #endif 14751b807ce4Svictorle v += a->lda; 147680cd9d93SLois Curfman McInnes } 14779566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 147880cd9d93SLois Curfman McInnes } 14799566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE)); 14803a40ed3dSBarry Smith } else { 14819566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE)); 1482aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 148347989497SBarry Smith /* determine if matrix has all real values */ 1484bcd8d3a4SJose E. Roman for (j = 0; j < A->cmap->n; j++) { 1485bcd8d3a4SJose E. Roman v = av + j * a->lda; 1486bcd8d3a4SJose E. Roman for (i = 0; i < A->rmap->n; i++) { 14879371c9d4SSatish Balay if (PetscImaginaryPart(v[i])) { 14889371c9d4SSatish Balay allreal = PETSC_FALSE; 14899371c9d4SSatish Balay break; 14909371c9d4SSatish Balay } 149147989497SBarry Smith } 1492bcd8d3a4SJose E. Roman } 149347989497SBarry Smith #endif 1494fb9695e5SSatish Balay if (format == PETSC_VIEWER_ASCII_MATLAB) { 14959566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)A, &name)); 14969566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%% Size = %" PetscInt_FMT " %" PetscInt_FMT " \n", A->rmap->n, A->cmap->n)); 14979566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%s = zeros(%" PetscInt_FMT ",%" PetscInt_FMT ");\n", name, A->rmap->n, A->cmap->n)); 14989566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%s = [\n", name)); 1499ffac6cdbSBarry Smith } 1500ffac6cdbSBarry Smith 1501d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 1502ca15aa20SStefano Zampini v = av + i; 1503d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1504aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 150547989497SBarry Smith if (allreal) { 15069566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)PetscRealPart(*v))); 150747989497SBarry Smith } else { 15089566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e + %18.16ei ", (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v))); 150947989497SBarry Smith } 1510289bc588SBarry Smith #else 15119566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)*v)); 1512289bc588SBarry Smith #endif 15131b807ce4Svictorle v += a->lda; 1514289bc588SBarry Smith } 15159566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 1516289bc588SBarry Smith } 151748a46eb9SPierre Jolivet if (format == PETSC_VIEWER_ASCII_MATLAB) PetscCall(PetscViewerASCIIPrintf(viewer, "];\n")); 15189566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE)); 1519da3a660dSBarry Smith } 15209566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&av)); 15219566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer)); 15223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1523289bc588SBarry Smith } 1524289bc588SBarry Smith 15259804daf3SBarry Smith #include <petscdraw.h> 1526d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw, void *Aa) 1527d71ae5a4SJacob Faibussowitsch { 1528f1af5d2fSBarry Smith Mat A = (Mat)Aa; 1529383922c3SLisandro Dalcin PetscInt m = A->rmap->n, n = A->cmap->n, i, j; 1530383922c3SLisandro Dalcin int color = PETSC_DRAW_WHITE; 1531ca15aa20SStefano Zampini const PetscScalar *v; 1532b0a32e0cSBarry Smith PetscViewer viewer; 1533b05fc000SLisandro Dalcin PetscReal xl, yl, xr, yr, x_l, x_r, y_l, y_r; 1534f3ef73ceSBarry Smith PetscViewerFormat format; 1535f1af5d2fSBarry Smith 1536f1af5d2fSBarry Smith PetscFunctionBegin; 15379566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)A, "Zoomviewer", (PetscObject *)&viewer)); 15389566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 15399566063dSJacob Faibussowitsch PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr)); 1540f1af5d2fSBarry Smith 1541f1af5d2fSBarry Smith /* Loop over matrix elements drawing boxes */ 15429566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 1543fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 1544d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 1545f1af5d2fSBarry Smith /* Blue for negative and Red for positive */ 1546f1af5d2fSBarry Smith for (j = 0; j < n; j++) { 15479371c9d4SSatish Balay x_l = j; 15489371c9d4SSatish Balay x_r = x_l + 1.0; 1549f1af5d2fSBarry Smith for (i = 0; i < m; i++) { 1550f1af5d2fSBarry Smith y_l = m - i - 1.0; 1551f1af5d2fSBarry Smith y_r = y_l + 1.0; 1552ca15aa20SStefano Zampini if (PetscRealPart(v[j * m + i]) > 0.) color = PETSC_DRAW_RED; 1553ca15aa20SStefano Zampini else if (PetscRealPart(v[j * m + i]) < 0.) color = PETSC_DRAW_BLUE; 1554ca15aa20SStefano Zampini else continue; 15559566063dSJacob Faibussowitsch PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color)); 1556f1af5d2fSBarry Smith } 1557f1af5d2fSBarry Smith } 1558d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 1559f1af5d2fSBarry Smith } else { 1560f1af5d2fSBarry Smith /* use contour shading to indicate magnitude of values */ 1561f1af5d2fSBarry Smith /* first determine max of all nonzero values */ 1562b05fc000SLisandro Dalcin PetscReal minv = 0.0, maxv = 0.0; 1563b05fc000SLisandro Dalcin PetscDraw popup; 1564b05fc000SLisandro Dalcin 1565f1af5d2fSBarry Smith for (i = 0; i < m * n; i++) { 1566f1af5d2fSBarry Smith if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]); 1567f1af5d2fSBarry Smith } 1568383922c3SLisandro Dalcin if (minv >= maxv) maxv = minv + PETSC_SMALL; 15699566063dSJacob Faibussowitsch PetscCall(PetscDrawGetPopup(draw, &popup)); 15709566063dSJacob Faibussowitsch PetscCall(PetscDrawScalePopup(popup, minv, maxv)); 1571383922c3SLisandro Dalcin 1572d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 1573f1af5d2fSBarry Smith for (j = 0; j < n; j++) { 1574f1af5d2fSBarry Smith x_l = j; 1575f1af5d2fSBarry Smith x_r = x_l + 1.0; 1576f1af5d2fSBarry Smith for (i = 0; i < m; i++) { 1577f1af5d2fSBarry Smith y_l = m - i - 1.0; 1578f1af5d2fSBarry Smith y_r = y_l + 1.0; 1579b05fc000SLisandro Dalcin color = PetscDrawRealToColor(PetscAbsScalar(v[j * m + i]), minv, maxv); 15809566063dSJacob Faibussowitsch PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color)); 1581f1af5d2fSBarry Smith } 1582f1af5d2fSBarry Smith } 1583d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 1584f1af5d2fSBarry Smith } 15859566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 15863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1587f1af5d2fSBarry Smith } 1588f1af5d2fSBarry Smith 1589d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw(Mat A, PetscViewer viewer) 1590d71ae5a4SJacob Faibussowitsch { 1591b0a32e0cSBarry Smith PetscDraw draw; 1592ace3abfcSBarry Smith PetscBool isnull; 1593329f5518SBarry Smith PetscReal xr, yr, xl, yl, h, w; 1594f1af5d2fSBarry Smith 1595f1af5d2fSBarry Smith PetscFunctionBegin; 15969566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 15979566063dSJacob Faibussowitsch PetscCall(PetscDrawIsNull(draw, &isnull)); 15983ba16761SJacob Faibussowitsch if (isnull) PetscFunctionReturn(PETSC_SUCCESS); 1599f1af5d2fSBarry Smith 16009371c9d4SSatish Balay xr = A->cmap->n; 16019371c9d4SSatish Balay yr = A->rmap->n; 16029371c9d4SSatish Balay h = yr / 10.0; 16039371c9d4SSatish Balay w = xr / 10.0; 16049371c9d4SSatish Balay xr += w; 16059371c9d4SSatish Balay yr += h; 16069371c9d4SSatish Balay xl = -w; 16079371c9d4SSatish Balay yl = -h; 16089566063dSJacob Faibussowitsch PetscCall(PetscDrawSetCoordinates(draw, xl, yl, xr, yr)); 16099566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", (PetscObject)viewer)); 16109566063dSJacob Faibussowitsch PetscCall(PetscDrawZoom(draw, MatView_SeqDense_Draw_Zoom, A)); 16119566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", NULL)); 16129566063dSJacob Faibussowitsch PetscCall(PetscDrawSave(draw)); 16133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1614f1af5d2fSBarry Smith } 1615f1af5d2fSBarry Smith 1616d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_SeqDense(Mat A, PetscViewer viewer) 1617d71ae5a4SJacob Faibussowitsch { 1618ace3abfcSBarry Smith PetscBool iascii, isbinary, isdraw; 1619932b0c3eSLois Curfman McInnes 16203a40ed3dSBarry Smith PetscFunctionBegin; 16219566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 16229566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 16239566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 16241baa6e33SBarry Smith if (iascii) PetscCall(MatView_SeqDense_ASCII(A, viewer)); 16251baa6e33SBarry Smith else if (isbinary) PetscCall(MatView_Dense_Binary(A, viewer)); 16261baa6e33SBarry Smith else if (isdraw) PetscCall(MatView_SeqDense_Draw(A, viewer)); 16273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1628932b0c3eSLois Curfman McInnes } 1629289bc588SBarry Smith 1630d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A, const PetscScalar *array) 1631d71ae5a4SJacob Faibussowitsch { 1632d3042a70SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1633d3042a70SBarry Smith 1634d3042a70SBarry Smith PetscFunctionBegin; 163528b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 163628b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 163728b400f6SJacob Faibussowitsch PetscCheck(!a->unplacedarray, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreArray() first"); 1638d3042a70SBarry Smith a->unplacedarray = a->v; 1639d3042a70SBarry Smith a->unplaced_user_alloc = a->user_alloc; 1640d3042a70SBarry Smith a->v = (PetscScalar *)array; 1641637a0070SStefano Zampini a->user_alloc = PETSC_TRUE; 164247d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1643c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_CPU; 1644ca15aa20SStefano Zampini #endif 16453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1646d3042a70SBarry Smith } 1647d3042a70SBarry Smith 1648d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseResetArray_SeqDense(Mat A) 1649d71ae5a4SJacob Faibussowitsch { 1650d3042a70SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1651d3042a70SBarry Smith 1652d3042a70SBarry Smith PetscFunctionBegin; 165328b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 165428b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 1655d3042a70SBarry Smith a->v = a->unplacedarray; 1656d3042a70SBarry Smith a->user_alloc = a->unplaced_user_alloc; 1657d3042a70SBarry Smith a->unplacedarray = NULL; 165847d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1659c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_CPU; 1660ca15aa20SStefano Zampini #endif 16613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1662d3042a70SBarry Smith } 1663d3042a70SBarry Smith 1664d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A, const PetscScalar *array) 1665d71ae5a4SJacob Faibussowitsch { 1666d5ea218eSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1667d5ea218eSStefano Zampini 1668d5ea218eSStefano Zampini 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"); 16719566063dSJacob Faibussowitsch if (!a->user_alloc) PetscCall(PetscFree(a->v)); 1672d5ea218eSStefano Zampini a->v = (PetscScalar *)array; 1673d5ea218eSStefano Zampini a->user_alloc = PETSC_FALSE; 167447d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1675d5ea218eSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 1676d5ea218eSStefano Zampini #endif 16773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1678d5ea218eSStefano Zampini } 1679d5ea218eSStefano Zampini 1680d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDestroy_SeqDense(Mat mat) 1681d71ae5a4SJacob Faibussowitsch { 1682ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)mat->data; 168390f02eecSBarry Smith 16843a40ed3dSBarry Smith PetscFunctionBegin; 16853ba16761SJacob Faibussowitsch PetscCall(PetscLogObjectState((PetscObject)mat, "Rows %" PetscInt_FMT " Cols %" PetscInt_FMT, mat->rmap->n, mat->cmap->n)); 16869566063dSJacob Faibussowitsch PetscCall(VecDestroy(&(l->qrrhs))); 16879566063dSJacob Faibussowitsch PetscCall(PetscFree(l->tau)); 16889566063dSJacob Faibussowitsch PetscCall(PetscFree(l->pivots)); 16899566063dSJacob Faibussowitsch PetscCall(PetscFree(l->fwork)); 16909566063dSJacob Faibussowitsch if (!l->user_alloc) PetscCall(PetscFree(l->v)); 16919566063dSJacob Faibussowitsch if (!l->unplaced_user_alloc) PetscCall(PetscFree(l->unplacedarray)); 169228b400f6SJacob Faibussowitsch PetscCheck(!l->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 169328b400f6SJacob Faibussowitsch PetscCheck(!l->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 16949566063dSJacob Faibussowitsch PetscCall(VecDestroy(&l->cvec)); 16959566063dSJacob Faibussowitsch PetscCall(MatDestroy(&l->cmat)); 16969566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->data)); 1697dbd8c25aSHong Zhang 16989566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)mat, NULL)); 16999566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactor_C", NULL)); 17002e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorSymbolic_C", NULL)); 17012e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorNumeric_C", NULL)); 17029566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetLDA_C", NULL)); 17039566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseSetLDA_C", NULL)); 17049566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArray_C", NULL)); 17059566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArray_C", NULL)); 17069566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDensePlaceArray_C", NULL)); 17079566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseResetArray_C", NULL)); 17089566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseReplaceArray_C", NULL)); 17099566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayRead_C", NULL)); 17109566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayRead_C", NULL)); 17119566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayWrite_C", NULL)); 17129566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayWrite_C", NULL)); 17139566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqaij_C", NULL)); 17148baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 17159566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_elemental_C", NULL)); 17168baccfbdSHong Zhang #endif 1717d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 17189566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_scalapack_C", NULL)); 1719d24d4204SJose E. Roman #endif 17202bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA) 17219566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensecuda_C", NULL)); 17229566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", NULL)); 17239566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdense_C", NULL)); 17242e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensecuda_C", NULL)); 17252bf066beSStefano Zampini #endif 172647d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 172747d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensehip_C", NULL)); 172847d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensehip_seqdensehip_C", NULL)); 172947d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensehip_seqdense_C", NULL)); 173047d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensehip_C", NULL)); 173147d993e7Ssuyashtn #endif 17329566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatSeqDenseSetPreallocation_C", NULL)); 17339566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqaij_seqdense_C", NULL)); 17349566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdense_C", NULL)); 17359566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqbaij_seqdense_C", NULL)); 17369566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqsbaij_seqdense_C", NULL)); 173752c5f739Sprj- 17389566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumn_C", NULL)); 17399566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumn_C", NULL)); 17409566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVec_C", NULL)); 17419566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVec_C", NULL)); 17429566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecRead_C", NULL)); 17439566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecRead_C", NULL)); 17449566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecWrite_C", NULL)); 17459566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecWrite_C", NULL)); 17469566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetSubMatrix_C", NULL)); 17479566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreSubMatrix_C", NULL)); 17483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1749289bc588SBarry Smith } 1750289bc588SBarry Smith 1751d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatTranspose_SeqDense(Mat A, MatReuse reuse, Mat *matout) 1752d71ae5a4SJacob Faibussowitsch { 1753c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 17546536e3caSStefano Zampini PetscInt k, j, m = A->rmap->n, M = mat->lda, n = A->cmap->n; 175587828ca2SBarry Smith PetscScalar *v, tmp; 175648b35521SBarry Smith 17573a40ed3dSBarry Smith PetscFunctionBegin; 17587fb60732SBarry Smith if (reuse == MAT_REUSE_MATRIX) PetscCall(MatTransposeCheckNonzeroState_Private(A, *matout)); 17596536e3caSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 17606536e3caSStefano Zampini if (m == n) { /* in place transpose */ 17619566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 1762d3e5ee88SLois Curfman McInnes for (j = 0; j < m; j++) { 1763289bc588SBarry Smith for (k = 0; k < j; k++) { 17641b807ce4Svictorle tmp = v[j + k * M]; 17651b807ce4Svictorle v[j + k * M] = v[k + j * M]; 17661b807ce4Svictorle v[k + j * M] = tmp; 1767289bc588SBarry Smith } 1768289bc588SBarry Smith } 17699566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 17706536e3caSStefano Zampini } else { /* reuse memory, temporary allocates new memory */ 17716536e3caSStefano Zampini PetscScalar *v2; 17726536e3caSStefano Zampini PetscLayout tmplayout; 17736536e3caSStefano Zampini 17749566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((size_t)m * n, &v2)); 17759566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 17766536e3caSStefano Zampini for (j = 0; j < n; j++) { 17776536e3caSStefano Zampini for (k = 0; k < m; k++) v2[j + (size_t)k * n] = v[k + (size_t)j * M]; 17786536e3caSStefano Zampini } 17799566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(v, v2, (size_t)m * n)); 17809566063dSJacob Faibussowitsch PetscCall(PetscFree(v2)); 17819566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 17826536e3caSStefano Zampini /* cleanup size dependent quantities */ 17839566063dSJacob Faibussowitsch PetscCall(VecDestroy(&mat->cvec)); 17849566063dSJacob Faibussowitsch PetscCall(MatDestroy(&mat->cmat)); 17859566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->pivots)); 17869566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->fwork)); 17876536e3caSStefano Zampini /* swap row/col layouts */ 17886536e3caSStefano Zampini mat->lda = n; 17896536e3caSStefano Zampini tmplayout = A->rmap; 17906536e3caSStefano Zampini A->rmap = A->cmap; 17916536e3caSStefano Zampini A->cmap = tmplayout; 17926536e3caSStefano Zampini } 17933a40ed3dSBarry Smith } else { /* out-of-place transpose */ 1794d3e5ee88SLois Curfman McInnes Mat tmat; 1795ec8511deSBarry Smith Mat_SeqDense *tmatd; 179687828ca2SBarry Smith PetscScalar *v2; 1797af36a384SStefano Zampini PetscInt M2; 1798ea709b57SSatish Balay 17996536e3caSStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 18009566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &tmat)); 18019566063dSJacob Faibussowitsch PetscCall(MatSetSizes(tmat, A->cmap->n, A->rmap->n, A->cmap->n, A->rmap->n)); 18029566063dSJacob Faibussowitsch PetscCall(MatSetType(tmat, ((PetscObject)A)->type_name)); 18039566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(tmat, NULL)); 1804ca15aa20SStefano Zampini } else tmat = *matout; 1805ca15aa20SStefano Zampini 18069566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&v)); 18079566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(tmat, &v2)); 1808ec8511deSBarry Smith tmatd = (Mat_SeqDense *)tmat->data; 1809ca15aa20SStefano Zampini M2 = tmatd->lda; 1810d3e5ee88SLois Curfman McInnes for (j = 0; j < n; j++) { 1811af36a384SStefano Zampini for (k = 0; k < m; k++) v2[j + k * M2] = v[k + j * M]; 1812d3e5ee88SLois Curfman McInnes } 18139566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(tmat, &v2)); 18149566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&v)); 18159566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(tmat, MAT_FINAL_ASSEMBLY)); 18169566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(tmat, MAT_FINAL_ASSEMBLY)); 18176536e3caSStefano Zampini *matout = tmat; 181848b35521SBarry Smith } 18193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1820289bc588SBarry Smith } 1821289bc588SBarry Smith 1822d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatEqual_SeqDense(Mat A1, Mat A2, PetscBool *flg) 1823d71ae5a4SJacob Faibussowitsch { 1824c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat1 = (Mat_SeqDense *)A1->data; 1825c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat2 = (Mat_SeqDense *)A2->data; 1826ca15aa20SStefano Zampini PetscInt i; 1827ca15aa20SStefano Zampini const PetscScalar *v1, *v2; 18289ea5d5aeSSatish Balay 18293a40ed3dSBarry Smith PetscFunctionBegin; 18309371c9d4SSatish Balay if (A1->rmap->n != A2->rmap->n) { 18319371c9d4SSatish Balay *flg = PETSC_FALSE; 18323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18339371c9d4SSatish Balay } 18349371c9d4SSatish Balay if (A1->cmap->n != A2->cmap->n) { 18359371c9d4SSatish Balay *flg = PETSC_FALSE; 18363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18379371c9d4SSatish Balay } 18389566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A1, &v1)); 18399566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A2, &v2)); 1840ca15aa20SStefano Zampini for (i = 0; i < A1->cmap->n; i++) { 18419566063dSJacob Faibussowitsch PetscCall(PetscArraycmp(v1, v2, A1->rmap->n, flg)); 18423ba16761SJacob Faibussowitsch if (*flg == PETSC_FALSE) PetscFunctionReturn(PETSC_SUCCESS); 1843ca15aa20SStefano Zampini v1 += mat1->lda; 1844ca15aa20SStefano Zampini v2 += mat2->lda; 18451b807ce4Svictorle } 18469566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A1, &v1)); 18479566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A2, &v2)); 184877c4ece6SBarry Smith *flg = PETSC_TRUE; 18493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1850289bc588SBarry Smith } 1851289bc588SBarry Smith 185214277c92SJacob Faibussowitsch PetscErrorCode MatGetDiagonal_SeqDense(Mat A, Vec v) 1853d71ae5a4SJacob Faibussowitsch { 1854c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 185513f74950SBarry Smith PetscInt i, n, len; 1856ca15aa20SStefano Zampini PetscScalar *x; 1857ca15aa20SStefano Zampini const PetscScalar *vv; 185844cd7ae7SLois Curfman McInnes 18593a40ed3dSBarry Smith PetscFunctionBegin; 18609566063dSJacob Faibussowitsch PetscCall(VecGetSize(v, &n)); 18619566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 1862d0f46423SBarry Smith len = PetscMin(A->rmap->n, A->cmap->n); 18639566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &vv)); 186408401ef6SPierre Jolivet PetscCheck(n == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming mat and vec"); 1865ad540459SPierre Jolivet for (i = 0; i < len; i++) x[i] = vv[i * mat->lda + i]; 18669566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &vv)); 18679566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 18683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1869289bc588SBarry Smith } 1870289bc588SBarry Smith 1871d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDiagonalScale_SeqDense(Mat A, Vec ll, Vec rr) 1872d71ae5a4SJacob Faibussowitsch { 1873c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1874f1ceaac6SMatthew G. Knepley const PetscScalar *l, *r; 1875ca15aa20SStefano Zampini PetscScalar x, *v, *vv; 1876d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n; 187755659b69SBarry Smith 18783a40ed3dSBarry Smith PetscFunctionBegin; 18799566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &vv)); 188028988994SBarry Smith if (ll) { 18819566063dSJacob Faibussowitsch PetscCall(VecGetSize(ll, &m)); 18829566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(ll, &l)); 188308401ef6SPierre Jolivet PetscCheck(m == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Left scaling vec wrong size"); 1884da3a660dSBarry Smith for (i = 0; i < m; i++) { 1885da3a660dSBarry Smith x = l[i]; 1886ca15aa20SStefano Zampini v = vv + i; 18879371c9d4SSatish Balay for (j = 0; j < n; j++) { 18889371c9d4SSatish Balay (*v) *= x; 18899371c9d4SSatish Balay v += mat->lda; 18909371c9d4SSatish Balay } 1891da3a660dSBarry Smith } 18929566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(ll, &l)); 18939566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * n * m)); 1894da3a660dSBarry Smith } 189528988994SBarry Smith if (rr) { 18969566063dSJacob Faibussowitsch PetscCall(VecGetSize(rr, &n)); 18979566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(rr, &r)); 189808401ef6SPierre Jolivet PetscCheck(n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Right scaling vec wrong size"); 1899da3a660dSBarry Smith for (i = 0; i < n; i++) { 1900da3a660dSBarry Smith x = r[i]; 1901ca15aa20SStefano Zampini v = vv + i * mat->lda; 19022205254eSKarl Rupp for (j = 0; j < m; j++) (*v++) *= x; 1903da3a660dSBarry Smith } 19049566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(rr, &r)); 19059566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * n * m)); 1906da3a660dSBarry Smith } 19079566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &vv)); 19083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1909289bc588SBarry Smith } 1910289bc588SBarry Smith 1911d71ae5a4SJacob Faibussowitsch PetscErrorCode MatNorm_SeqDense(Mat A, NormType type, PetscReal *nrm) 1912d71ae5a4SJacob Faibussowitsch { 1913c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1914ca15aa20SStefano Zampini PetscScalar *v, *vv; 1915329f5518SBarry Smith PetscReal sum = 0.0; 191675f6d85dSStefano Zampini PetscInt lda, m = A->rmap->n, i, j; 191755659b69SBarry Smith 19183a40ed3dSBarry Smith PetscFunctionBegin; 19199566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&vv)); 19209566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(A, &lda)); 1921ca15aa20SStefano Zampini v = vv; 1922289bc588SBarry Smith if (type == NORM_FROBENIUS) { 1923a5ce6ee0Svictorle if (lda > m) { 1924d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1925ca15aa20SStefano Zampini v = vv + j * lda; 1926a5ce6ee0Svictorle for (i = 0; i < m; i++) { 19279371c9d4SSatish Balay sum += PetscRealPart(PetscConj(*v) * (*v)); 19289371c9d4SSatish Balay v++; 1929a5ce6ee0Svictorle } 1930a5ce6ee0Svictorle } 1931a5ce6ee0Svictorle } else { 1932570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16) 1933570b7f6dSBarry Smith PetscBLASInt one = 1, cnt = A->cmap->n * A->rmap->n; 1934792fecdfSBarry Smith PetscCallBLAS("BLASnrm2", *nrm = BLASnrm2_(&cnt, v, &one)); 1935570b7f6dSBarry Smith } 1936570b7f6dSBarry Smith #else 1937d0f46423SBarry Smith for (i = 0; i < A->cmap->n * A->rmap->n; i++) { 19389371c9d4SSatish Balay sum += PetscRealPart(PetscConj(*v) * (*v)); 19399371c9d4SSatish Balay v++; 1940289bc588SBarry Smith } 1941a5ce6ee0Svictorle } 19428f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 1943570b7f6dSBarry Smith #endif 19449566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->cmap->n * A->rmap->n)); 19453a40ed3dSBarry Smith } else if (type == NORM_1) { 1946064f8208SBarry Smith *nrm = 0.0; 1947d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1948ca15aa20SStefano Zampini v = vv + j * mat->lda; 1949289bc588SBarry Smith sum = 0.0; 1950d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 19519371c9d4SSatish Balay sum += PetscAbsScalar(*v); 19529371c9d4SSatish Balay v++; 1953289bc588SBarry Smith } 1954064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 1955289bc588SBarry Smith } 19569566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n)); 19573a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 1958064f8208SBarry Smith *nrm = 0.0; 1959d0f46423SBarry Smith for (j = 0; j < A->rmap->n; j++) { 1960ca15aa20SStefano Zampini v = vv + j; 1961289bc588SBarry Smith sum = 0.0; 1962d0f46423SBarry Smith for (i = 0; i < A->cmap->n; i++) { 19639371c9d4SSatish Balay sum += PetscAbsScalar(*v); 19649371c9d4SSatish Balay v += mat->lda; 1965289bc588SBarry Smith } 1966064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 1967289bc588SBarry Smith } 19689566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n)); 1969e7e72b3dSBarry Smith } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "No two norm"); 19709566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&vv)); 19713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1972289bc588SBarry Smith } 1973289bc588SBarry Smith 1974d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetOption_SeqDense(Mat A, MatOption op, PetscBool flg) 1975d71ae5a4SJacob Faibussowitsch { 1976c0bbcb79SLois Curfman McInnes Mat_SeqDense *aij = (Mat_SeqDense *)A->data; 197767e560aaSBarry Smith 19783a40ed3dSBarry Smith PetscFunctionBegin; 1979b5a2b587SKris Buschelman switch (op) { 1980d71ae5a4SJacob Faibussowitsch case MAT_ROW_ORIENTED: 1981d71ae5a4SJacob Faibussowitsch aij->roworiented = flg; 1982d71ae5a4SJacob Faibussowitsch break; 1983512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 1984b5a2b587SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 19853971808eSMatthew Knepley case MAT_NEW_NONZERO_ALLOCATION_ERR: 19868c78258cSHong Zhang case MAT_FORCE_DIAGONAL_ENTRIES: 198713fa8e87SLisandro Dalcin case MAT_KEEP_NONZERO_PATTERN: 1988b5a2b587SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 1989b5a2b587SKris Buschelman case MAT_USE_HASH_TABLE: 19900f8fb01aSBarry Smith case MAT_IGNORE_ZERO_ENTRIES: 19915021d80fSJed Brown case MAT_IGNORE_LOWER_TRIANGULAR: 1992d71ae5a4SJacob Faibussowitsch case MAT_SORTED_FULL: 1993d71ae5a4SJacob Faibussowitsch PetscCall(PetscInfo(A, "Option %s ignored\n", MatOptions[op])); 1994d71ae5a4SJacob Faibussowitsch break; 19955021d80fSJed Brown case MAT_SPD: 199677e54ba9SKris Buschelman case MAT_SYMMETRIC: 199777e54ba9SKris Buschelman case MAT_STRUCTURALLY_SYMMETRIC: 19989a4540c5SBarry Smith case MAT_HERMITIAN: 19999a4540c5SBarry Smith case MAT_SYMMETRY_ETERNAL: 2000b94d7dedSBarry Smith case MAT_STRUCTURAL_SYMMETRY_ETERNAL: 2001d71ae5a4SJacob Faibussowitsch case MAT_SPD_ETERNAL: 2002d71ae5a4SJacob Faibussowitsch break; 2003d71ae5a4SJacob Faibussowitsch default: 2004d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "unknown option %s", MatOptions[op]); 20053a40ed3dSBarry Smith } 20063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2007289bc588SBarry Smith } 2008289bc588SBarry Smith 2009d71ae5a4SJacob Faibussowitsch PetscErrorCode MatZeroEntries_SeqDense(Mat A) 2010d71ae5a4SJacob Faibussowitsch { 2011ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)A->data; 20123d8925e7SStefano Zampini PetscInt lda = l->lda, m = A->rmap->n, n = A->cmap->n, j; 2013ca15aa20SStefano Zampini PetscScalar *v; 20143a40ed3dSBarry Smith 20153a40ed3dSBarry Smith PetscFunctionBegin; 20169566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(A, &v)); 2017a5ce6ee0Svictorle if (lda > m) { 201848a46eb9SPierre Jolivet for (j = 0; j < n; j++) PetscCall(PetscArrayzero(v + j * lda, m)); 2019a5ce6ee0Svictorle } else { 20209566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(v, PetscInt64Mult(m, n))); 2021a5ce6ee0Svictorle } 20229566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(A, &v)); 20233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 20246f0a148fSBarry Smith } 20256f0a148fSBarry Smith 2026d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatZeroRows_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) 2027d71ae5a4SJacob Faibussowitsch { 2028ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)A->data; 2029b9679d65SBarry Smith PetscInt m = l->lda, n = A->cmap->n, i, j; 2030ca15aa20SStefano Zampini PetscScalar *slot, *bb, *v; 203197b48c8fSBarry Smith const PetscScalar *xx; 203255659b69SBarry Smith 20333a40ed3dSBarry Smith PetscFunctionBegin; 203476bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 2035b9679d65SBarry Smith for (i = 0; i < N; i++) { 203608401ef6SPierre Jolivet PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed"); 203708401ef6SPierre 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); 2038b9679d65SBarry Smith } 203976bd3646SJed Brown } 20403ba16761SJacob Faibussowitsch if (!N) PetscFunctionReturn(PETSC_SUCCESS); 2041b9679d65SBarry Smith 204297b48c8fSBarry Smith /* fix right hand side if needed */ 204397b48c8fSBarry Smith if (x && b) { 20449566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 20459566063dSJacob Faibussowitsch PetscCall(VecGetArray(b, &bb)); 20462205254eSKarl Rupp for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]]; 20479566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 20489566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(b, &bb)); 204997b48c8fSBarry Smith } 205097b48c8fSBarry Smith 20519566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 20526f0a148fSBarry Smith for (i = 0; i < N; i++) { 2053ca15aa20SStefano Zampini slot = v + rows[i]; 20549371c9d4SSatish Balay for (j = 0; j < n; j++) { 20559371c9d4SSatish Balay *slot = 0.0; 20569371c9d4SSatish Balay slot += m; 20579371c9d4SSatish Balay } 20586f0a148fSBarry Smith } 2059f4df32b1SMatthew Knepley if (diag != 0.0) { 206008401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices"); 20616f0a148fSBarry Smith for (i = 0; i < N; i++) { 2062ca15aa20SStefano Zampini slot = v + (m + 1) * rows[i]; 2063f4df32b1SMatthew Knepley *slot = diag; 20646f0a148fSBarry Smith } 20656f0a148fSBarry Smith } 20669566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 20673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 20686f0a148fSBarry Smith } 2069557bce09SLois Curfman McInnes 2070d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A, PetscInt *lda) 2071d71ae5a4SJacob Faibussowitsch { 207249a6ff4bSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 207349a6ff4bSBarry Smith 207449a6ff4bSBarry Smith PetscFunctionBegin; 207549a6ff4bSBarry Smith *lda = mat->lda; 20763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 207749a6ff4bSBarry Smith } 207849a6ff4bSBarry Smith 2079d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArray_SeqDense(Mat A, PetscScalar **array) 2080d71ae5a4SJacob Faibussowitsch { 2081c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 20823a40ed3dSBarry Smith 20833a40ed3dSBarry Smith PetscFunctionBegin; 208428b400f6SJacob Faibussowitsch PetscCheck(!mat->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 208564e87e97SBarry Smith *array = mat->v; 20863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 208764e87e97SBarry Smith } 20880754003eSLois Curfman McInnes 2089d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A, PetscScalar **array) 2090d71ae5a4SJacob Faibussowitsch { 20913a40ed3dSBarry Smith PetscFunctionBegin; 209275f6d85dSStefano Zampini if (array) *array = NULL; 20933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2094ff14e315SSatish Balay } 20950754003eSLois Curfman McInnes 20960f74d2c1SSatish Balay /*@ 209711a5261eSBarry Smith MatDenseGetLDA - gets the leading dimension of the array returned from `MatDenseGetArray()` 209849a6ff4bSBarry Smith 20992ef1f0ffSBarry Smith Not Collective 210049a6ff4bSBarry Smith 210149a6ff4bSBarry Smith Input Parameter: 2102fe59aa6dSJacob Faibussowitsch . A - a `MATDENSE` or `MATDENSECUDA` matrix 210349a6ff4bSBarry Smith 210449a6ff4bSBarry Smith Output Parameter: 210549a6ff4bSBarry Smith . lda - the leading dimension 210649a6ff4bSBarry Smith 210749a6ff4bSBarry Smith Level: intermediate 210849a6ff4bSBarry Smith 21091cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseSetLDA()` 211049a6ff4bSBarry Smith @*/ 2111d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetLDA(Mat A, PetscInt *lda) 2112d71ae5a4SJacob Faibussowitsch { 211349a6ff4bSBarry Smith PetscFunctionBegin; 2114d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 21154f572ea9SToby Isaac PetscAssertPointer(lda, 2); 211675f6d85dSStefano Zampini MatCheckPreallocated(A, 1); 2117cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetLDA_C", (Mat, PetscInt *), (A, lda)); 21183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 211949a6ff4bSBarry Smith } 212049a6ff4bSBarry Smith 21210f74d2c1SSatish Balay /*@ 212211a5261eSBarry Smith MatDenseSetLDA - Sets the leading dimension of the array used by the `MATDENSE` matrix 2123ad16ce7aSStefano Zampini 21242323109cSBarry Smith Collective if the matrix layouts have not yet been setup 2125ad16ce7aSStefano Zampini 2126d8d19677SJose E. Roman Input Parameters: 2127fe59aa6dSJacob Faibussowitsch + A - a `MATDENSE` or `MATDENSECUDA` matrix 2128ad16ce7aSStefano Zampini - lda - the leading dimension 2129ad16ce7aSStefano Zampini 2130ad16ce7aSStefano Zampini Level: intermediate 2131ad16ce7aSStefano Zampini 21321cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetLDA()` 2133ad16ce7aSStefano Zampini @*/ 2134d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA(Mat A, PetscInt lda) 2135d71ae5a4SJacob Faibussowitsch { 2136ad16ce7aSStefano Zampini PetscFunctionBegin; 2137ad16ce7aSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2138cac4c232SBarry Smith PetscTryMethod(A, "MatDenseSetLDA_C", (Mat, PetscInt), (A, lda)); 21393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2140ad16ce7aSStefano Zampini } 2141ad16ce7aSStefano Zampini 2142ad16ce7aSStefano Zampini /*@C 214311a5261eSBarry Smith MatDenseGetArray - gives read-write access to the array where the data for a `MATDENSE` matrix is stored 214473a71a0fSBarry Smith 2145c3339decSBarry Smith Logically Collective 214673a71a0fSBarry Smith 214773a71a0fSBarry Smith Input Parameter: 2148fe59aa6dSJacob Faibussowitsch . A - a dense matrix 214973a71a0fSBarry Smith 215073a71a0fSBarry Smith Output Parameter: 215173a71a0fSBarry Smith . array - pointer to the data 215273a71a0fSBarry Smith 215373a71a0fSBarry Smith Level: intermediate 215473a71a0fSBarry Smith 2155fe59aa6dSJacob Faibussowitsch Fortran Notes: 21560ab4885dSBarry Smith `MatDenseGetArray()` Fortran binding is deprecated (since PETSc 3.19), use `MatDenseGetArrayF90()` 21570ab4885dSBarry Smith 21581cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 215973a71a0fSBarry Smith @*/ 2160d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArray(Mat A, PetscScalar **array) 2161d71ae5a4SJacob Faibussowitsch { 216273a71a0fSBarry Smith PetscFunctionBegin; 2163d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 21644f572ea9SToby Isaac PetscAssertPointer(array, 2); 2165cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array)); 21663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 216773a71a0fSBarry Smith } 216873a71a0fSBarry Smith 2169dec5eb66SMatthew G Knepley /*@C 217011a5261eSBarry Smith MatDenseRestoreArray - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArray()` 217173a71a0fSBarry Smith 2172c3339decSBarry Smith Logically Collective 21738572280aSBarry Smith 21748572280aSBarry Smith Input Parameters: 2175fe59aa6dSJacob Faibussowitsch + A - a dense matrix 21762ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`) 21778572280aSBarry Smith 21788572280aSBarry Smith Level: intermediate 21798572280aSBarry Smith 2180fe59aa6dSJacob Faibussowitsch Fortran Notes: 21810ab4885dSBarry Smith `MatDenseRestoreArray()` Fortran binding is deprecated (since PETSc 3.19), use `MatDenseRestoreArrayF90()` 21820ab4885dSBarry Smith 21831cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 21848572280aSBarry Smith @*/ 2185d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArray(Mat A, PetscScalar **array) 2186d71ae5a4SJacob Faibussowitsch { 21878572280aSBarry Smith PetscFunctionBegin; 2188d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 21894f572ea9SToby Isaac if (array) PetscAssertPointer(array, 2); 2190cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array)); 21919566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)A)); 219247d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 2193637a0070SStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 2194637a0070SStefano Zampini #endif 21953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 21968572280aSBarry Smith } 21978572280aSBarry Smith 21988572280aSBarry Smith /*@C 219911a5261eSBarry Smith MatDenseGetArrayRead - gives read-only access to the array where the data for a `MATDENSE` matrix is stored 22008572280aSBarry Smith 2201fb850c59SBarry Smith Not Collective 22028572280aSBarry Smith 22038572280aSBarry Smith Input Parameter: 2204fe59aa6dSJacob Faibussowitsch . A - a dense matrix 22058572280aSBarry Smith 22068572280aSBarry Smith Output Parameter: 22078572280aSBarry Smith . array - pointer to the data 22088572280aSBarry Smith 22098572280aSBarry Smith Level: intermediate 22108572280aSBarry Smith 22111cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 22128572280aSBarry Smith @*/ 2213d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArrayRead(Mat A, const PetscScalar **array) 2214d71ae5a4SJacob Faibussowitsch { 22158572280aSBarry Smith PetscFunctionBegin; 2216d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22174f572ea9SToby Isaac PetscAssertPointer(array, 2); 22185c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 22193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22208572280aSBarry Smith } 22218572280aSBarry Smith 22228572280aSBarry Smith /*@C 222311a5261eSBarry Smith MatDenseRestoreArrayRead - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayRead()` 22248572280aSBarry Smith 2225fb850c59SBarry Smith Not Collective 222673a71a0fSBarry Smith 222773a71a0fSBarry Smith Input Parameters: 2228fe59aa6dSJacob Faibussowitsch + A - a dense matrix 22292ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`) 223073a71a0fSBarry Smith 223173a71a0fSBarry Smith Level: intermediate 223273a71a0fSBarry Smith 22331cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 223473a71a0fSBarry Smith @*/ 2235d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArrayRead(Mat A, const PetscScalar **array) 2236d71ae5a4SJacob Faibussowitsch { 223773a71a0fSBarry Smith PetscFunctionBegin; 2238d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22394f572ea9SToby Isaac if (array) PetscAssertPointer(array, 2); 22405c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 22413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 224273a71a0fSBarry Smith } 224373a71a0fSBarry Smith 22446947451fSStefano Zampini /*@C 224511a5261eSBarry Smith MatDenseGetArrayWrite - gives write-only access to the array where the data for a `MATDENSE` matrix is stored 22466947451fSStefano Zampini 2247fb850c59SBarry Smith Not Collective 22486947451fSStefano Zampini 22496947451fSStefano Zampini Input Parameter: 2250fe59aa6dSJacob Faibussowitsch . A - a dense matrix 22516947451fSStefano Zampini 22526947451fSStefano Zampini Output Parameter: 22536947451fSStefano Zampini . array - pointer to the data 22546947451fSStefano Zampini 22556947451fSStefano Zampini Level: intermediate 22566947451fSStefano Zampini 22571cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()` 22586947451fSStefano Zampini @*/ 2259d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArrayWrite(Mat A, PetscScalar **array) 2260d71ae5a4SJacob Faibussowitsch { 22616947451fSStefano Zampini PetscFunctionBegin; 2262d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22634f572ea9SToby Isaac PetscAssertPointer(array, 2); 2264cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array)); 22653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22666947451fSStefano Zampini } 22676947451fSStefano Zampini 22686947451fSStefano Zampini /*@C 226911a5261eSBarry Smith MatDenseRestoreArrayWrite - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayWrite()` 22706947451fSStefano Zampini 2271fb850c59SBarry Smith Not Collective 22726947451fSStefano Zampini 22736947451fSStefano Zampini Input Parameters: 2274fe59aa6dSJacob Faibussowitsch + A - a dense matrix 22752ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`) 22766947451fSStefano Zampini 22776947451fSStefano Zampini Level: intermediate 22786947451fSStefano Zampini 22791cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()` 22806947451fSStefano Zampini @*/ 2281d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArrayWrite(Mat A, PetscScalar **array) 2282d71ae5a4SJacob Faibussowitsch { 22836947451fSStefano Zampini PetscFunctionBegin; 2284d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22854f572ea9SToby Isaac if (array) PetscAssertPointer(array, 2); 2286cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array)); 22879566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)A)); 228847d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 22896947451fSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 22906947451fSStefano Zampini #endif 22913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22926947451fSStefano Zampini } 22936947451fSStefano Zampini 2294cd3f9d89SJunchao Zhang /*@C 2295cd3f9d89SJunchao Zhang MatDenseGetArrayAndMemType - gives read-write access to the array where the data for a `MATDENSE` matrix is stored 2296cd3f9d89SJunchao Zhang 2297cd3f9d89SJunchao Zhang Logically Collective 2298cd3f9d89SJunchao Zhang 2299cd3f9d89SJunchao Zhang Input Parameter: 2300fe59aa6dSJacob Faibussowitsch . A - a dense matrix 2301cd3f9d89SJunchao Zhang 2302cd3f9d89SJunchao Zhang Output Parameters: 2303cd3f9d89SJunchao Zhang + array - pointer to the data 2304cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer 2305cd3f9d89SJunchao Zhang 2306cd3f9d89SJunchao Zhang Level: intermediate 2307cd3f9d89SJunchao Zhang 2308fb850c59SBarry Smith Note: 23092ef1f0ffSBarry Smith If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc., 23102ef1f0ffSBarry Smith an array on device is always returned and is guaranteed to contain the matrix's latest data. 23112ef1f0ffSBarry Smith 23121cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayAndMemType()`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArrayWriteAndMemType()`, `MatDenseGetArrayRead()`, 2313cd3f9d89SJunchao Zhang `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()` 2314cd3f9d89SJunchao Zhang @*/ 2315cd3f9d89SJunchao Zhang PetscErrorCode MatDenseGetArrayAndMemType(Mat A, PetscScalar **array, PetscMemType *mtype) 2316cd3f9d89SJunchao Zhang { 2317cd3f9d89SJunchao Zhang PetscBool isMPI; 2318cd3f9d89SJunchao Zhang 2319cd3f9d89SJunchao Zhang PetscFunctionBegin; 2320cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 23214f572ea9SToby Isaac PetscAssertPointer(array, 2); 2322e865de01SJunchao 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 */ 2323cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2324cd3f9d89SJunchao Zhang if (isMPI) { 2325cd3f9d89SJunchao Zhang /* Dispatch here so that the code can be reused for all subclasses of MATDENSE */ 2326cd3f9d89SJunchao Zhang PetscCall(MatDenseGetArrayAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype)); 2327cd3f9d89SJunchao Zhang } else { 2328cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **, PetscMemType *); 23293ba16761SJacob Faibussowitsch 23303ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayAndMemType_C", &fptr)); 2331cd3f9d89SJunchao Zhang if (fptr) { 2332cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array, mtype)); 2333cd3f9d89SJunchao Zhang } else { 2334cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array)); 2335cd3f9d89SJunchao Zhang if (mtype) *mtype = PETSC_MEMTYPE_HOST; 2336cd3f9d89SJunchao Zhang } 2337cd3f9d89SJunchao Zhang } 23383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2339cd3f9d89SJunchao Zhang } 2340cd3f9d89SJunchao Zhang 2341cd3f9d89SJunchao Zhang /*@C 2342cd3f9d89SJunchao Zhang MatDenseRestoreArrayAndMemType - returns access to the array that is obtained by `MatDenseGetArrayAndMemType()` 2343cd3f9d89SJunchao Zhang 2344cd3f9d89SJunchao Zhang Logically Collective 2345cd3f9d89SJunchao Zhang 2346cd3f9d89SJunchao Zhang Input Parameters: 2347fe59aa6dSJacob Faibussowitsch + A - a dense matrix 2348cd3f9d89SJunchao Zhang - array - pointer to the data 2349cd3f9d89SJunchao Zhang 2350cd3f9d89SJunchao Zhang Level: intermediate 2351cd3f9d89SJunchao Zhang 23521cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 2353cd3f9d89SJunchao Zhang @*/ 2354cd3f9d89SJunchao Zhang PetscErrorCode MatDenseRestoreArrayAndMemType(Mat A, PetscScalar **array) 2355cd3f9d89SJunchao Zhang { 2356cd3f9d89SJunchao Zhang PetscBool isMPI; 2357cd3f9d89SJunchao Zhang 2358cd3f9d89SJunchao Zhang PetscFunctionBegin; 2359cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 23604f572ea9SToby Isaac PetscAssertPointer(array, 2); 2361cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2362cd3f9d89SJunchao Zhang if (isMPI) { 2363cd3f9d89SJunchao Zhang PetscCall(MatDenseRestoreArrayAndMemType(((Mat_MPIDense *)A->data)->A, array)); 2364cd3f9d89SJunchao Zhang } else { 2365cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **); 23663ba16761SJacob Faibussowitsch 23673ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayAndMemType_C", &fptr)); 2368cd3f9d89SJunchao Zhang if (fptr) { 2369cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array)); 2370cd3f9d89SJunchao Zhang } else { 2371cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array)); 2372cd3f9d89SJunchao Zhang } 2373cd3f9d89SJunchao Zhang *array = NULL; 2374cd3f9d89SJunchao Zhang } 2375cd3f9d89SJunchao Zhang PetscCall(PetscObjectStateIncrease((PetscObject)A)); 23763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2377cd3f9d89SJunchao Zhang } 2378cd3f9d89SJunchao Zhang 2379cd3f9d89SJunchao Zhang /*@C 2380cd3f9d89SJunchao Zhang MatDenseGetArrayReadAndMemType - gives read-only access to the array where the data for a `MATDENSE` matrix is stored 2381cd3f9d89SJunchao Zhang 2382cd3f9d89SJunchao Zhang Logically Collective 2383cd3f9d89SJunchao Zhang 2384cd3f9d89SJunchao Zhang Input Parameter: 2385fe59aa6dSJacob Faibussowitsch . A - a dense matrix 2386cd3f9d89SJunchao Zhang 2387cd3f9d89SJunchao Zhang Output Parameters: 2388cd3f9d89SJunchao Zhang + array - pointer to the data 2389cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer 2390cd3f9d89SJunchao Zhang 2391cd3f9d89SJunchao Zhang Level: intermediate 2392cd3f9d89SJunchao Zhang 2393fb850c59SBarry Smith Note: 23942ef1f0ffSBarry Smith If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc., 23952ef1f0ffSBarry Smith an array on device is always returned and is guaranteed to contain the matrix's latest data. 23962ef1f0ffSBarry Smith 23971cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayReadAndMemType()`, `MatDenseGetArrayWriteAndMemType()`, 2398cd3f9d89SJunchao Zhang `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()` 2399cd3f9d89SJunchao Zhang @*/ 2400cd3f9d89SJunchao Zhang PetscErrorCode MatDenseGetArrayReadAndMemType(Mat A, const PetscScalar **array, PetscMemType *mtype) 2401cd3f9d89SJunchao Zhang { 2402cd3f9d89SJunchao Zhang PetscBool isMPI; 2403cd3f9d89SJunchao Zhang 2404cd3f9d89SJunchao Zhang PetscFunctionBegin; 2405cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 24064f572ea9SToby Isaac PetscAssertPointer(array, 2); 2407e865de01SJunchao 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 */ 2408cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2409cd3f9d89SJunchao Zhang if (isMPI) { /* Dispatch here so that the code can be reused for all subclasses of MATDENSE */ 2410cd3f9d89SJunchao Zhang PetscCall(MatDenseGetArrayReadAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype)); 2411cd3f9d89SJunchao Zhang } else { 2412cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, const PetscScalar **, PetscMemType *); 24133ba16761SJacob Faibussowitsch 24143ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayReadAndMemType_C", &fptr)); 2415cd3f9d89SJunchao Zhang if (fptr) { 2416cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array, mtype)); 2417cd3f9d89SJunchao Zhang } else { 24185c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 2419cd3f9d89SJunchao Zhang if (mtype) *mtype = PETSC_MEMTYPE_HOST; 2420cd3f9d89SJunchao Zhang } 2421cd3f9d89SJunchao Zhang } 24223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2423cd3f9d89SJunchao Zhang } 2424cd3f9d89SJunchao Zhang 2425cd3f9d89SJunchao Zhang /*@C 2426cd3f9d89SJunchao Zhang MatDenseRestoreArrayReadAndMemType - returns access to the array that is obtained by `MatDenseGetArrayReadAndMemType()` 2427cd3f9d89SJunchao Zhang 2428cd3f9d89SJunchao Zhang Logically Collective 2429cd3f9d89SJunchao Zhang 2430cd3f9d89SJunchao Zhang Input Parameters: 2431fe59aa6dSJacob Faibussowitsch + A - a dense matrix 2432cd3f9d89SJunchao Zhang - array - pointer to the data 2433cd3f9d89SJunchao Zhang 2434cd3f9d89SJunchao Zhang Level: intermediate 2435cd3f9d89SJunchao Zhang 24361cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 2437cd3f9d89SJunchao Zhang @*/ 2438cd3f9d89SJunchao Zhang PetscErrorCode MatDenseRestoreArrayReadAndMemType(Mat A, const PetscScalar **array) 2439cd3f9d89SJunchao Zhang { 2440cd3f9d89SJunchao Zhang PetscBool isMPI; 2441cd3f9d89SJunchao Zhang 2442cd3f9d89SJunchao Zhang PetscFunctionBegin; 2443cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 24444f572ea9SToby Isaac PetscAssertPointer(array, 2); 2445cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2446cd3f9d89SJunchao Zhang if (isMPI) { 2447cd3f9d89SJunchao Zhang PetscCall(MatDenseRestoreArrayReadAndMemType(((Mat_MPIDense *)A->data)->A, array)); 2448cd3f9d89SJunchao Zhang } else { 2449cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, const PetscScalar **); 24503ba16761SJacob Faibussowitsch 24513ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayReadAndMemType_C", &fptr)); 2452cd3f9d89SJunchao Zhang if (fptr) { 2453cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array)); 2454cd3f9d89SJunchao Zhang } else { 24555c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 2456cd3f9d89SJunchao Zhang } 2457cd3f9d89SJunchao Zhang *array = NULL; 2458cd3f9d89SJunchao Zhang } 24593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2460cd3f9d89SJunchao Zhang } 2461cd3f9d89SJunchao Zhang 2462cd3f9d89SJunchao Zhang /*@C 2463cd3f9d89SJunchao Zhang MatDenseGetArrayWriteAndMemType - gives write-only access to the array where the data for a `MATDENSE` matrix is stored 2464cd3f9d89SJunchao Zhang 2465cd3f9d89SJunchao Zhang Logically Collective 2466cd3f9d89SJunchao Zhang 2467cd3f9d89SJunchao Zhang Input Parameter: 2468fe59aa6dSJacob Faibussowitsch . A - a dense matrix 2469cd3f9d89SJunchao Zhang 2470cd3f9d89SJunchao Zhang Output Parameters: 2471cd3f9d89SJunchao Zhang + array - pointer to the data 2472cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer 2473cd3f9d89SJunchao Zhang 2474cd3f9d89SJunchao Zhang Level: intermediate 2475cd3f9d89SJunchao Zhang 2476fb850c59SBarry Smith Note: 24772ef1f0ffSBarry Smith If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc., 24782ef1f0ffSBarry Smith an array on device is always returned and is guaranteed to contain the matrix's latest data. 24792ef1f0ffSBarry Smith 24801cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayWriteAndMemType()`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArrayRead()`, 2481cd3f9d89SJunchao Zhang `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()` 2482cd3f9d89SJunchao Zhang @*/ 2483cd3f9d89SJunchao Zhang PetscErrorCode MatDenseGetArrayWriteAndMemType(Mat A, PetscScalar **array, PetscMemType *mtype) 2484cd3f9d89SJunchao Zhang { 2485cd3f9d89SJunchao Zhang PetscBool isMPI; 2486cd3f9d89SJunchao Zhang 2487cd3f9d89SJunchao Zhang PetscFunctionBegin; 2488cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 24894f572ea9SToby Isaac PetscAssertPointer(array, 2); 2490e865de01SJunchao 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 */ 2491cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2492cd3f9d89SJunchao Zhang if (isMPI) { 2493cd3f9d89SJunchao Zhang PetscCall(MatDenseGetArrayWriteAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype)); 2494cd3f9d89SJunchao Zhang } else { 2495cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **, PetscMemType *); 24963ba16761SJacob Faibussowitsch 24973ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayWriteAndMemType_C", &fptr)); 2498cd3f9d89SJunchao Zhang if (fptr) { 2499cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array, mtype)); 2500cd3f9d89SJunchao Zhang } else { 2501cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array)); 2502cd3f9d89SJunchao Zhang if (mtype) *mtype = PETSC_MEMTYPE_HOST; 2503cd3f9d89SJunchao Zhang } 2504cd3f9d89SJunchao Zhang } 25053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2506cd3f9d89SJunchao Zhang } 2507cd3f9d89SJunchao Zhang 2508cd3f9d89SJunchao Zhang /*@C 2509cd3f9d89SJunchao Zhang MatDenseRestoreArrayWriteAndMemType - returns access to the array that is obtained by `MatDenseGetArrayReadAndMemType()` 2510cd3f9d89SJunchao Zhang 2511cd3f9d89SJunchao Zhang Logically Collective 2512cd3f9d89SJunchao Zhang 2513cd3f9d89SJunchao Zhang Input Parameters: 2514fe59aa6dSJacob Faibussowitsch + A - a dense matrix 2515cd3f9d89SJunchao Zhang - array - pointer to the data 2516cd3f9d89SJunchao Zhang 2517cd3f9d89SJunchao Zhang Level: intermediate 2518cd3f9d89SJunchao Zhang 25191cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayWriteAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 2520cd3f9d89SJunchao Zhang @*/ 2521cd3f9d89SJunchao Zhang PetscErrorCode MatDenseRestoreArrayWriteAndMemType(Mat A, PetscScalar **array) 2522cd3f9d89SJunchao Zhang { 2523cd3f9d89SJunchao Zhang PetscBool isMPI; 2524cd3f9d89SJunchao Zhang 2525cd3f9d89SJunchao Zhang PetscFunctionBegin; 2526cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 25274f572ea9SToby Isaac PetscAssertPointer(array, 2); 2528cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2529cd3f9d89SJunchao Zhang if (isMPI) { 2530cd3f9d89SJunchao Zhang PetscCall(MatDenseRestoreArrayWriteAndMemType(((Mat_MPIDense *)A->data)->A, array)); 2531cd3f9d89SJunchao Zhang } else { 2532cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **); 25333ba16761SJacob Faibussowitsch 25343ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayWriteAndMemType_C", &fptr)); 2535cd3f9d89SJunchao Zhang if (fptr) { 2536cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array)); 2537cd3f9d89SJunchao Zhang } else { 2538cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array)); 2539cd3f9d89SJunchao Zhang } 2540cd3f9d89SJunchao Zhang *array = NULL; 2541cd3f9d89SJunchao Zhang } 2542cd3f9d89SJunchao Zhang PetscCall(PetscObjectStateIncrease((PetscObject)A)); 25433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2544cd3f9d89SJunchao Zhang } 2545cd3f9d89SJunchao Zhang 2546d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A, IS isrow, IS iscol, MatReuse scall, Mat *B) 2547d71ae5a4SJacob Faibussowitsch { 2548c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 2549bf5a80bcSToby Isaac PetscInt i, j, nrows, ncols, ldb; 25505d0c19d7SBarry Smith const PetscInt *irow, *icol; 255187828ca2SBarry Smith PetscScalar *av, *bv, *v = mat->v; 25520754003eSLois Curfman McInnes Mat newmat; 25530754003eSLois Curfman McInnes 25543a40ed3dSBarry Smith PetscFunctionBegin; 25559566063dSJacob Faibussowitsch PetscCall(ISGetIndices(isrow, &irow)); 25569566063dSJacob Faibussowitsch PetscCall(ISGetIndices(iscol, &icol)); 25579566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(isrow, &nrows)); 25589566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(iscol, &ncols)); 25590754003eSLois Curfman McInnes 2560182d2002SSatish Balay /* Check submatrixcall */ 2561182d2002SSatish Balay if (scall == MAT_REUSE_MATRIX) { 256213f74950SBarry Smith PetscInt n_cols, n_rows; 25639566063dSJacob Faibussowitsch PetscCall(MatGetSize(*B, &n_rows, &n_cols)); 256421a2c019SBarry Smith if (n_rows != nrows || n_cols != ncols) { 2565f746d493SDmitry Karpeev /* resize the result matrix to match number of requested rows/columns */ 25669566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*B, nrows, ncols, nrows, ncols)); 256721a2c019SBarry Smith } 2568182d2002SSatish Balay newmat = *B; 2569182d2002SSatish Balay } else { 25700754003eSLois Curfman McInnes /* Create and fill new matrix */ 25719566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &newmat)); 25729566063dSJacob Faibussowitsch PetscCall(MatSetSizes(newmat, nrows, ncols, nrows, ncols)); 25739566063dSJacob Faibussowitsch PetscCall(MatSetType(newmat, ((PetscObject)A)->type_name)); 25749566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(newmat, NULL)); 2575182d2002SSatish Balay } 2576182d2002SSatish Balay 2577182d2002SSatish Balay /* Now extract the data pointers and do the copy,column at a time */ 25789566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(newmat, &bv)); 25799566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(newmat, &ldb)); 2580182d2002SSatish Balay for (i = 0; i < ncols; i++) { 25816de62eeeSBarry Smith av = v + mat->lda * icol[i]; 2582ca15aa20SStefano Zampini for (j = 0; j < nrows; j++) bv[j] = av[irow[j]]; 2583bf5a80bcSToby Isaac bv += ldb; 25840754003eSLois Curfman McInnes } 25859566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(newmat, &bv)); 2586182d2002SSatish Balay 2587182d2002SSatish Balay /* Assemble the matrices so that the correct flags are set */ 25889566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(newmat, MAT_FINAL_ASSEMBLY)); 25899566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(newmat, MAT_FINAL_ASSEMBLY)); 25900754003eSLois Curfman McInnes 25910754003eSLois Curfman McInnes /* Free work space */ 25929566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(isrow, &irow)); 25939566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(iscol, &icol)); 2594182d2002SSatish Balay *B = newmat; 25953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 25960754003eSLois Curfman McInnes } 25970754003eSLois Curfman McInnes 2598d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A, PetscInt n, const IS irow[], const IS icol[], MatReuse scall, Mat *B[]) 2599d71ae5a4SJacob Faibussowitsch { 260013f74950SBarry Smith PetscInt i; 2601905e6a2fSBarry Smith 26023a40ed3dSBarry Smith PetscFunctionBegin; 260348a46eb9SPierre Jolivet if (scall == MAT_INITIAL_MATRIX) PetscCall(PetscCalloc1(n, B)); 2604905e6a2fSBarry Smith 260548a46eb9SPierre Jolivet for (i = 0; i < n; i++) PetscCall(MatCreateSubMatrix_SeqDense(A, irow[i], icol[i], scall, &(*B)[i])); 26063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2607905e6a2fSBarry Smith } 2608905e6a2fSBarry Smith 2609d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat, MatAssemblyType mode) 2610d71ae5a4SJacob Faibussowitsch { 2611c0aa2d19SHong Zhang PetscFunctionBegin; 26123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2613c0aa2d19SHong Zhang } 2614c0aa2d19SHong Zhang 2615d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat, MatAssemblyType mode) 2616d71ae5a4SJacob Faibussowitsch { 2617c0aa2d19SHong Zhang PetscFunctionBegin; 26183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2619c0aa2d19SHong Zhang } 2620c0aa2d19SHong Zhang 2621d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCopy_SeqDense(Mat A, Mat B, MatStructure str) 2622d71ae5a4SJacob Faibussowitsch { 26234b0e389bSBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data; 2624ca15aa20SStefano Zampini const PetscScalar *va; 2625ca15aa20SStefano Zampini PetscScalar *vb; 2626d0f46423SBarry Smith PetscInt lda1 = a->lda, lda2 = b->lda, m = A->rmap->n, n = A->cmap->n, j; 26273a40ed3dSBarry Smith 26283a40ed3dSBarry Smith PetscFunctionBegin; 262933f4a19fSKris Buschelman /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */ 263033f4a19fSKris Buschelman if (A->ops->copy != B->ops->copy) { 26319566063dSJacob Faibussowitsch PetscCall(MatCopy_Basic(A, B, str)); 26323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26333a40ed3dSBarry Smith } 2634aed4548fSBarry Smith PetscCheck(m == B->rmap->n && n == B->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "size(B) != size(A)"); 26359566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &va)); 26369566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(B, &vb)); 2637a5ce6ee0Svictorle if (lda1 > m || lda2 > m) { 263848a46eb9SPierre Jolivet for (j = 0; j < n; j++) PetscCall(PetscArraycpy(vb + j * lda2, va + j * lda1, m)); 2639a5ce6ee0Svictorle } else { 26409566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(vb, va, A->rmap->n * A->cmap->n)); 2641a5ce6ee0Svictorle } 26429566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(B, &vb)); 26439566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &va)); 26449566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 26459566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 26463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2647273d9f13SBarry Smith } 2648273d9f13SBarry Smith 2649d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetUp_SeqDense(Mat A) 2650d71ae5a4SJacob Faibussowitsch { 2651273d9f13SBarry Smith PetscFunctionBegin; 26529566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 26539566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 265448a46eb9SPierre Jolivet if (!A->preallocated) PetscCall(MatSeqDenseSetPreallocation(A, NULL)); 26553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26564b0e389bSBarry Smith } 26574b0e389bSBarry Smith 2658d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatConjugate_SeqDense(Mat A) 2659d71ae5a4SJacob Faibussowitsch { 26604396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 266106c5243aSJose E. Roman PetscInt i, j; 26624396437dSToby Isaac PetscInt min = PetscMin(A->rmap->n, A->cmap->n); 2663ca15aa20SStefano Zampini PetscScalar *aa; 2664ba337c44SJed Brown 2665ba337c44SJed Brown PetscFunctionBegin; 26669566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 266706c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 266806c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscConj(aa[i + j * mat->lda]); 266906c5243aSJose E. Roman } 26709566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 26719371c9d4SSatish Balay if (mat->tau) 26729371c9d4SSatish Balay for (i = 0; i < min; i++) mat->tau[i] = PetscConj(mat->tau[i]); 26733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2674ba337c44SJed Brown } 2675ba337c44SJed Brown 2676d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRealPart_SeqDense(Mat A) 2677d71ae5a4SJacob Faibussowitsch { 267806c5243aSJose E. Roman Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 267906c5243aSJose E. Roman PetscInt i, j; 2680ca15aa20SStefano Zampini PetscScalar *aa; 2681ba337c44SJed Brown 2682ba337c44SJed Brown PetscFunctionBegin; 26839566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 268406c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 268506c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscRealPart(aa[i + j * mat->lda]); 268606c5243aSJose E. Roman } 26879566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 26883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2689ba337c44SJed Brown } 2690ba337c44SJed Brown 2691d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatImaginaryPart_SeqDense(Mat A) 2692d71ae5a4SJacob Faibussowitsch { 269306c5243aSJose E. Roman Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 269406c5243aSJose E. Roman PetscInt i, j; 2695ca15aa20SStefano Zampini PetscScalar *aa; 2696ba337c44SJed Brown 2697ba337c44SJed Brown PetscFunctionBegin; 26989566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 269906c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 270006c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscImaginaryPart(aa[i + j * mat->lda]); 270106c5243aSJose E. Roman } 27029566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 27033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2704ba337c44SJed Brown } 2705284134d9SBarry Smith 2706d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2707d71ae5a4SJacob Faibussowitsch { 2708d0f46423SBarry Smith PetscInt m = A->rmap->n, n = B->cmap->n; 270947d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 2710a9fe9ddaSSatish Balay 2711ee16a9a1SHong Zhang PetscFunctionBegin; 27129566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 271347d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 27149566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 271547d993e7Ssuyashtn #endif 271647d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 271747d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 271847d993e7Ssuyashtn #endif 27197a3c3d58SStefano Zampini if (!cisdense) { 27207a3c3d58SStefano Zampini PetscBool flg; 27217a3c3d58SStefano Zampini 27229566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 27239566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 27247a3c3d58SStefano Zampini } 27259566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 27263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2727ee16a9a1SHong Zhang } 2728a9fe9ddaSSatish Balay 2729d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2730d71ae5a4SJacob Faibussowitsch { 27316718818eSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data, *c = (Mat_SeqDense *)C->data; 27320805154bSBarry Smith PetscBLASInt m, n, k; 2733ca15aa20SStefano Zampini const PetscScalar *av, *bv; 2734ca15aa20SStefano Zampini PetscScalar *cv; 2735a9fe9ddaSSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 2736a9fe9ddaSSatish Balay 2737a9fe9ddaSSatish Balay PetscFunctionBegin; 27389566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 27399566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 27409566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 27413ba16761SJacob Faibussowitsch if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS); 27429566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 27439566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 27449566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2745792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("N", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 27469566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 27479566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 27489566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 27499566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 27503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2751a9fe9ddaSSatish Balay } 2752a9fe9ddaSSatish Balay 2753d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2754d71ae5a4SJacob Faibussowitsch { 275569f65d41SStefano Zampini PetscInt m = A->rmap->n, n = B->rmap->n; 275647d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 275769f65d41SStefano Zampini 275869f65d41SStefano Zampini PetscFunctionBegin; 27599566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 276047d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 27619566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 276247d993e7Ssuyashtn #endif 276347d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 276447d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 276547d993e7Ssuyashtn #endif 27667a3c3d58SStefano Zampini if (!cisdense) { 27677a3c3d58SStefano Zampini PetscBool flg; 27687a3c3d58SStefano Zampini 27699566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 27709566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 27717a3c3d58SStefano Zampini } 27729566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 27733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 277469f65d41SStefano Zampini } 277569f65d41SStefano Zampini 2776d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2777d71ae5a4SJacob Faibussowitsch { 277869f65d41SStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 277969f65d41SStefano Zampini Mat_SeqDense *b = (Mat_SeqDense *)B->data; 278069f65d41SStefano Zampini Mat_SeqDense *c = (Mat_SeqDense *)C->data; 27816718818eSStefano Zampini const PetscScalar *av, *bv; 27826718818eSStefano Zampini PetscScalar *cv; 278369f65d41SStefano Zampini PetscBLASInt m, n, k; 278469f65d41SStefano Zampini PetscScalar _DOne = 1.0, _DZero = 0.0; 278569f65d41SStefano Zampini 278669f65d41SStefano Zampini PetscFunctionBegin; 27879566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 27889566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 27899566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 27903ba16761SJacob Faibussowitsch if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS); 27919566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 27929566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 27939566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2794792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("N", "T", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 27959566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 27969566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 27979566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 27989566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 27993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 280069f65d41SStefano Zampini } 280169f65d41SStefano Zampini 2802d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2803d71ae5a4SJacob Faibussowitsch { 2804d0f46423SBarry Smith PetscInt m = A->cmap->n, n = B->cmap->n; 280547d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 2806a9fe9ddaSSatish Balay 2807ee16a9a1SHong Zhang PetscFunctionBegin; 28089566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 280947d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 28109566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 281147d993e7Ssuyashtn #endif 281247d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 281347d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 281447d993e7Ssuyashtn #endif 28157a3c3d58SStefano Zampini if (!cisdense) { 28167a3c3d58SStefano Zampini PetscBool flg; 28177a3c3d58SStefano Zampini 28189566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 28199566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 28207a3c3d58SStefano Zampini } 28219566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 28223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2823ee16a9a1SHong Zhang } 2824a9fe9ddaSSatish Balay 2825d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2826d71ae5a4SJacob Faibussowitsch { 2827a9fe9ddaSSatish Balay Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2828a9fe9ddaSSatish Balay Mat_SeqDense *b = (Mat_SeqDense *)B->data; 2829a9fe9ddaSSatish Balay Mat_SeqDense *c = (Mat_SeqDense *)C->data; 28306718818eSStefano Zampini const PetscScalar *av, *bv; 28316718818eSStefano Zampini PetscScalar *cv; 28320805154bSBarry Smith PetscBLASInt m, n, k; 2833a9fe9ddaSSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 2834a9fe9ddaSSatish Balay 2835a9fe9ddaSSatish Balay PetscFunctionBegin; 28369566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 28379566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 28389566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &k)); 28393ba16761SJacob Faibussowitsch if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS); 28409566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 28419566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 28429566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2843792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("T", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 28449566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 28459566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 28469566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 28479566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 28483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2849a9fe9ddaSSatish Balay } 2850985db425SBarry Smith 2851d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C) 2852d71ae5a4SJacob Faibussowitsch { 28534222ddf1SHong Zhang PetscFunctionBegin; 28544222ddf1SHong Zhang C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense; 28554222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AB; 28563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28574222ddf1SHong Zhang } 28584222ddf1SHong Zhang 2859d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C) 2860d71ae5a4SJacob Faibussowitsch { 28614222ddf1SHong Zhang PetscFunctionBegin; 28624222ddf1SHong Zhang C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense; 28634222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AtB; 28643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28654222ddf1SHong Zhang } 28664222ddf1SHong Zhang 2867d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C) 2868d71ae5a4SJacob Faibussowitsch { 28694222ddf1SHong Zhang PetscFunctionBegin; 28704222ddf1SHong Zhang C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense; 28714222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_ABt; 28723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28734222ddf1SHong Zhang } 28744222ddf1SHong Zhang 2875d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C) 2876d71ae5a4SJacob Faibussowitsch { 28774222ddf1SHong Zhang Mat_Product *product = C->product; 28784222ddf1SHong Zhang 28794222ddf1SHong Zhang PetscFunctionBegin; 28804222ddf1SHong Zhang switch (product->type) { 2881d71ae5a4SJacob Faibussowitsch case MATPRODUCT_AB: 2882d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_AB(C)); 2883d71ae5a4SJacob Faibussowitsch break; 2884d71ae5a4SJacob Faibussowitsch case MATPRODUCT_AtB: 2885d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_AtB(C)); 2886d71ae5a4SJacob Faibussowitsch break; 2887d71ae5a4SJacob Faibussowitsch case MATPRODUCT_ABt: 2888d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_ABt(C)); 2889d71ae5a4SJacob Faibussowitsch break; 2890d71ae5a4SJacob Faibussowitsch default: 2891d71ae5a4SJacob Faibussowitsch break; 28924222ddf1SHong Zhang } 28933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28944222ddf1SHong Zhang } 28954222ddf1SHong Zhang 2896d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMax_SeqDense(Mat A, Vec v, PetscInt idx[]) 2897d71ae5a4SJacob Faibussowitsch { 2898985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2899d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2900985db425SBarry Smith PetscScalar *x; 2901ca15aa20SStefano Zampini const PetscScalar *aa; 2902985db425SBarry Smith 2903985db425SBarry Smith PetscFunctionBegin; 290428b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29059566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29069566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 29079566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 290808401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2909985db425SBarry Smith for (i = 0; i < m; i++) { 29109371c9d4SSatish Balay x[i] = aa[i]; 29119371c9d4SSatish Balay if (idx) idx[i] = 0; 2912985db425SBarry Smith for (j = 1; j < n; j++) { 29139371c9d4SSatish Balay if (PetscRealPart(x[i]) < PetscRealPart(aa[i + a->lda * j])) { 29149371c9d4SSatish Balay x[i] = aa[i + a->lda * j]; 29159371c9d4SSatish Balay if (idx) idx[i] = j; 29169371c9d4SSatish Balay } 2917985db425SBarry Smith } 2918985db425SBarry Smith } 29199566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 29209566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 29213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2922985db425SBarry Smith } 2923985db425SBarry Smith 2924d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A, Vec v, PetscInt idx[]) 2925d71ae5a4SJacob Faibussowitsch { 2926985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2927d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2928985db425SBarry Smith PetscScalar *x; 2929985db425SBarry Smith PetscReal atmp; 2930ca15aa20SStefano Zampini const PetscScalar *aa; 2931985db425SBarry Smith 2932985db425SBarry Smith PetscFunctionBegin; 293328b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29349566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29359566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 29369566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 293708401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2938985db425SBarry Smith for (i = 0; i < m; i++) { 29399189402eSHong Zhang x[i] = PetscAbsScalar(aa[i]); 2940985db425SBarry Smith for (j = 1; j < n; j++) { 2941ca15aa20SStefano Zampini atmp = PetscAbsScalar(aa[i + a->lda * j]); 29429371c9d4SSatish Balay if (PetscAbsScalar(x[i]) < atmp) { 29439371c9d4SSatish Balay x[i] = atmp; 29449371c9d4SSatish Balay if (idx) idx[i] = j; 29459371c9d4SSatish Balay } 2946985db425SBarry Smith } 2947985db425SBarry Smith } 29489566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 29499566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 29503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2951985db425SBarry Smith } 2952985db425SBarry Smith 2953d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMin_SeqDense(Mat A, Vec v, PetscInt idx[]) 2954d71ae5a4SJacob Faibussowitsch { 2955985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2956d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2957985db425SBarry Smith PetscScalar *x; 2958ca15aa20SStefano Zampini const PetscScalar *aa; 2959985db425SBarry Smith 2960985db425SBarry Smith PetscFunctionBegin; 296128b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29629566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 29639566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29649566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 296508401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2966985db425SBarry Smith for (i = 0; i < m; i++) { 29679371c9d4SSatish Balay x[i] = aa[i]; 29689371c9d4SSatish Balay if (idx) idx[i] = 0; 2969985db425SBarry Smith for (j = 1; j < n; j++) { 29709371c9d4SSatish Balay if (PetscRealPart(x[i]) > PetscRealPart(aa[i + a->lda * j])) { 29719371c9d4SSatish Balay x[i] = aa[i + a->lda * j]; 29729371c9d4SSatish Balay if (idx) idx[i] = j; 29739371c9d4SSatish Balay } 2974985db425SBarry Smith } 2975985db425SBarry Smith } 29769566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 29779566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 29783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2979985db425SBarry Smith } 2980985db425SBarry Smith 2981d71ae5a4SJacob Faibussowitsch PetscErrorCode MatGetColumnVector_SeqDense(Mat A, Vec v, PetscInt col) 2982d71ae5a4SJacob Faibussowitsch { 29838d0534beSBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 29848d0534beSBarry Smith PetscScalar *x; 2985ca15aa20SStefano Zampini const PetscScalar *aa; 29868d0534beSBarry Smith 29878d0534beSBarry Smith PetscFunctionBegin; 298828b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29899566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 29909566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29919566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(x, aa + col * a->lda, A->rmap->n)); 29929566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 29939566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 29943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29958d0534beSBarry Smith } 29968d0534beSBarry Smith 2997d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatGetColumnReductions_SeqDense(Mat A, PetscInt type, PetscReal *reductions) 2998d71ae5a4SJacob Faibussowitsch { 29990716a85fSBarry Smith PetscInt i, j, m, n; 30001683a169SBarry Smith const PetscScalar *a; 30010716a85fSBarry Smith 30020716a85fSBarry Smith PetscFunctionBegin; 30039566063dSJacob Faibussowitsch PetscCall(MatGetSize(A, &m, &n)); 30049566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(reductions, n)); 30059566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &a)); 3006857cbf51SRichard Tran Mills if (type == NORM_2) { 30070716a85fSBarry Smith for (i = 0; i < n; i++) { 3008ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j] * a[j]); 30090716a85fSBarry Smith a += m; 30100716a85fSBarry Smith } 3011857cbf51SRichard Tran Mills } else if (type == NORM_1) { 30120716a85fSBarry Smith for (i = 0; i < n; i++) { 3013ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j]); 30140716a85fSBarry Smith a += m; 30150716a85fSBarry Smith } 3016857cbf51SRichard Tran Mills } else if (type == NORM_INFINITY) { 30170716a85fSBarry Smith for (i = 0; i < n; i++) { 3018ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] = PetscMax(PetscAbsScalar(a[j]), reductions[i]); 30190716a85fSBarry Smith a += m; 30200716a85fSBarry Smith } 3021857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_REALPART || type == REDUCTION_MEAN_REALPART) { 3022a873a8cdSSam Reynolds for (i = 0; i < n; i++) { 3023ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscRealPart(a[j]); 3024a873a8cdSSam Reynolds a += m; 3025a873a8cdSSam Reynolds } 3026857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_IMAGINARYPART || type == REDUCTION_MEAN_IMAGINARYPART) { 3027857cbf51SRichard Tran Mills for (i = 0; i < n; i++) { 3028ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscImaginaryPart(a[j]); 3029857cbf51SRichard Tran Mills a += m; 3030857cbf51SRichard Tran Mills } 3031857cbf51SRichard Tran Mills } else SETERRQ(PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Unknown reduction type"); 30329566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &a)); 3033857cbf51SRichard Tran Mills if (type == NORM_2) { 3034a873a8cdSSam Reynolds for (i = 0; i < n; i++) reductions[i] = PetscSqrtReal(reductions[i]); 3035857cbf51SRichard Tran Mills } else if (type == REDUCTION_MEAN_REALPART || type == REDUCTION_MEAN_IMAGINARYPART) { 3036a873a8cdSSam Reynolds for (i = 0; i < n; i++) reductions[i] /= m; 30370716a85fSBarry Smith } 30383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30390716a85fSBarry Smith } 30400716a85fSBarry Smith 3041d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetRandom_SeqDense(Mat x, PetscRandom rctx) 3042d71ae5a4SJacob Faibussowitsch { 304373a71a0fSBarry Smith PetscScalar *a; 3044637a0070SStefano Zampini PetscInt lda, m, n, i, j; 304573a71a0fSBarry Smith 304673a71a0fSBarry Smith PetscFunctionBegin; 30479566063dSJacob Faibussowitsch PetscCall(MatGetSize(x, &m, &n)); 30489566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(x, &lda)); 30493faff063SStefano Zampini PetscCall(MatDenseGetArrayWrite(x, &a)); 3050637a0070SStefano Zampini for (j = 0; j < n; j++) { 305148a46eb9SPierre Jolivet for (i = 0; i < m; i++) PetscCall(PetscRandomGetValue(rctx, a + j * lda + i)); 305273a71a0fSBarry Smith } 30533faff063SStefano Zampini PetscCall(MatDenseRestoreArrayWrite(x, &a)); 30543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 305573a71a0fSBarry Smith } 305673a71a0fSBarry Smith 3057d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A, PetscBool *missing, PetscInt *d) 3058d71ae5a4SJacob Faibussowitsch { 30593b49f96aSBarry Smith PetscFunctionBegin; 30603b49f96aSBarry Smith *missing = PETSC_FALSE; 30613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30623b49f96aSBarry Smith } 306373a71a0fSBarry Smith 3064ca15aa20SStefano Zampini /* vals is not const */ 3065d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A, PetscInt col, PetscScalar **vals) 3066d71ae5a4SJacob Faibussowitsch { 306786aefd0dSHong Zhang Mat_SeqDense *a = (Mat_SeqDense *)A->data; 3068ca15aa20SStefano Zampini PetscScalar *v; 306986aefd0dSHong Zhang 307086aefd0dSHong Zhang PetscFunctionBegin; 307128b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 30729566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 3073ca15aa20SStefano Zampini *vals = v + col * a->lda; 30749566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 30753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 307686aefd0dSHong Zhang } 307786aefd0dSHong Zhang 3078d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A, PetscScalar **vals) 3079d71ae5a4SJacob Faibussowitsch { 308086aefd0dSHong Zhang PetscFunctionBegin; 3081742765d3SMatthew Knepley if (vals) *vals = NULL; /* user cannot accidentally use the array later */ 30823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 308386aefd0dSHong Zhang } 3084abc3b08eSStefano Zampini 3085a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqDense, 3086905e6a2fSBarry Smith MatGetRow_SeqDense, 3087905e6a2fSBarry Smith MatRestoreRow_SeqDense, 3088905e6a2fSBarry Smith MatMult_SeqDense, 308997304618SKris Buschelman /* 4*/ MatMultAdd_SeqDense, 30907c922b88SBarry Smith MatMultTranspose_SeqDense, 30917c922b88SBarry Smith MatMultTransposeAdd_SeqDense, 3092f4259b30SLisandro Dalcin NULL, 3093f4259b30SLisandro Dalcin NULL, 3094f4259b30SLisandro Dalcin NULL, 3095f4259b30SLisandro Dalcin /* 10*/ NULL, 3096905e6a2fSBarry Smith MatLUFactor_SeqDense, 3097905e6a2fSBarry Smith MatCholeskyFactor_SeqDense, 309841f059aeSBarry Smith MatSOR_SeqDense, 3099ec8511deSBarry Smith MatTranspose_SeqDense, 310097304618SKris Buschelman /* 15*/ MatGetInfo_SeqDense, 3101905e6a2fSBarry Smith MatEqual_SeqDense, 3102905e6a2fSBarry Smith MatGetDiagonal_SeqDense, 3103905e6a2fSBarry Smith MatDiagonalScale_SeqDense, 3104905e6a2fSBarry Smith MatNorm_SeqDense, 3105c0aa2d19SHong Zhang /* 20*/ MatAssemblyBegin_SeqDense, 3106c0aa2d19SHong Zhang MatAssemblyEnd_SeqDense, 3107905e6a2fSBarry Smith MatSetOption_SeqDense, 3108905e6a2fSBarry Smith MatZeroEntries_SeqDense, 3109d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqDense, 3110f4259b30SLisandro Dalcin NULL, 3111f4259b30SLisandro Dalcin NULL, 3112f4259b30SLisandro Dalcin NULL, 3113f4259b30SLisandro Dalcin NULL, 31144994cf47SJed Brown /* 29*/ MatSetUp_SeqDense, 3115f4259b30SLisandro Dalcin NULL, 3116f4259b30SLisandro Dalcin NULL, 3117f4259b30SLisandro Dalcin NULL, 3118f4259b30SLisandro Dalcin NULL, 3119d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqDense, 3120f4259b30SLisandro Dalcin NULL, 3121f4259b30SLisandro Dalcin NULL, 3122f4259b30SLisandro Dalcin NULL, 3123f4259b30SLisandro Dalcin NULL, 3124d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqDense, 31257dae84e0SHong Zhang MatCreateSubMatrices_SeqDense, 3126f4259b30SLisandro Dalcin NULL, 31274b0e389bSBarry Smith MatGetValues_SeqDense, 3128a5ae1ecdSBarry Smith MatCopy_SeqDense, 3129d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqDense, 3130a5ae1ecdSBarry Smith MatScale_SeqDense, 31312f605a99SJose E. Roman MatShift_SeqDense, 3132f4259b30SLisandro Dalcin NULL, 31333f49a652SStefano Zampini MatZeroRowsColumns_SeqDense, 313473a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqDense, 3135f4259b30SLisandro Dalcin NULL, 3136f4259b30SLisandro Dalcin NULL, 3137f4259b30SLisandro Dalcin NULL, 3138f4259b30SLisandro Dalcin NULL, 3139f4259b30SLisandro Dalcin /* 54*/ NULL, 3140f4259b30SLisandro Dalcin NULL, 3141f4259b30SLisandro Dalcin NULL, 3142f4259b30SLisandro Dalcin NULL, 3143f4259b30SLisandro Dalcin NULL, 3144023c16fcSToby Isaac /* 59*/ MatCreateSubMatrix_SeqDense, 3145e03a110bSBarry Smith MatDestroy_SeqDense, 3146e03a110bSBarry Smith MatView_SeqDense, 3147f4259b30SLisandro Dalcin NULL, 3148f4259b30SLisandro Dalcin NULL, 3149f4259b30SLisandro Dalcin /* 64*/ NULL, 3150f4259b30SLisandro Dalcin NULL, 3151f4259b30SLisandro Dalcin NULL, 3152f4259b30SLisandro Dalcin NULL, 3153f4259b30SLisandro Dalcin NULL, 3154d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqDense, 3155f4259b30SLisandro Dalcin NULL, 3156f4259b30SLisandro Dalcin NULL, 3157f4259b30SLisandro Dalcin NULL, 3158f4259b30SLisandro Dalcin NULL, 3159f4259b30SLisandro Dalcin /* 74*/ NULL, 3160f4259b30SLisandro Dalcin NULL, 3161f4259b30SLisandro Dalcin NULL, 3162f4259b30SLisandro Dalcin NULL, 3163f4259b30SLisandro Dalcin NULL, 3164f4259b30SLisandro Dalcin /* 79*/ NULL, 3165f4259b30SLisandro Dalcin NULL, 3166f4259b30SLisandro Dalcin NULL, 3167f4259b30SLisandro Dalcin NULL, 31685bba2384SShri Abhyankar /* 83*/ MatLoad_SeqDense, 3169637a0070SStefano Zampini MatIsSymmetric_SeqDense, 31701cbb95d3SBarry Smith MatIsHermitian_SeqDense, 3171f4259b30SLisandro Dalcin NULL, 3172f4259b30SLisandro Dalcin NULL, 3173f4259b30SLisandro Dalcin NULL, 3174f4259b30SLisandro Dalcin /* 89*/ NULL, 3175f4259b30SLisandro Dalcin NULL, 3176a9fe9ddaSSatish Balay MatMatMultNumeric_SeqDense_SeqDense, 3177f4259b30SLisandro Dalcin NULL, 3178f4259b30SLisandro Dalcin NULL, 3179f4259b30SLisandro Dalcin /* 94*/ NULL, 3180f4259b30SLisandro Dalcin NULL, 3181f4259b30SLisandro Dalcin NULL, 318269f65d41SStefano Zampini MatMatTransposeMultNumeric_SeqDense_SeqDense, 3183f4259b30SLisandro Dalcin NULL, 31844222ddf1SHong Zhang /* 99*/ MatProductSetFromOptions_SeqDense, 3185f4259b30SLisandro Dalcin NULL, 3186f4259b30SLisandro Dalcin NULL, 3187ba337c44SJed Brown MatConjugate_SeqDense, 3188f4259b30SLisandro Dalcin NULL, 3189f4259b30SLisandro Dalcin /*104*/ NULL, 3190ba337c44SJed Brown MatRealPart_SeqDense, 3191ba337c44SJed Brown MatImaginaryPart_SeqDense, 3192f4259b30SLisandro Dalcin NULL, 3193f4259b30SLisandro Dalcin NULL, 3194f4259b30SLisandro Dalcin /*109*/ NULL, 3195f4259b30SLisandro Dalcin NULL, 31968d0534beSBarry Smith MatGetRowMin_SeqDense, 3197aabbc4fbSShri Abhyankar MatGetColumnVector_SeqDense, 31983b49f96aSBarry Smith MatMissingDiagonal_SeqDense, 3199f4259b30SLisandro Dalcin /*114*/ NULL, 3200f4259b30SLisandro Dalcin NULL, 3201f4259b30SLisandro Dalcin NULL, 3202f4259b30SLisandro Dalcin NULL, 3203f4259b30SLisandro Dalcin NULL, 3204f4259b30SLisandro Dalcin /*119*/ NULL, 3205f4259b30SLisandro Dalcin NULL, 3206f4259b30SLisandro Dalcin NULL, 3207f4259b30SLisandro Dalcin NULL, 3208f4259b30SLisandro Dalcin NULL, 3209f4259b30SLisandro Dalcin /*124*/ NULL, 3210a873a8cdSSam Reynolds MatGetColumnReductions_SeqDense, 3211f4259b30SLisandro Dalcin NULL, 3212f4259b30SLisandro Dalcin NULL, 3213f4259b30SLisandro Dalcin NULL, 3214f4259b30SLisandro Dalcin /*129*/ NULL, 3215f4259b30SLisandro Dalcin NULL, 3216f4259b30SLisandro Dalcin NULL, 321775648e8dSHong Zhang MatTransposeMatMultNumeric_SeqDense_SeqDense, 3218f4259b30SLisandro Dalcin NULL, 3219f4259b30SLisandro Dalcin /*134*/ NULL, 3220f4259b30SLisandro Dalcin NULL, 3221f4259b30SLisandro Dalcin NULL, 3222f4259b30SLisandro Dalcin NULL, 3223f4259b30SLisandro Dalcin NULL, 3224f4259b30SLisandro Dalcin /*139*/ NULL, 3225f4259b30SLisandro Dalcin NULL, 3226f4259b30SLisandro Dalcin NULL, 3227f4259b30SLisandro Dalcin NULL, 3228f4259b30SLisandro Dalcin NULL, 32294222ddf1SHong Zhang MatCreateMPIMatConcatenateSeqMat_SeqDense, 3230f4259b30SLisandro Dalcin /*145*/ NULL, 3231f4259b30SLisandro Dalcin NULL, 323299a7f59eSMark Adams NULL, 323399a7f59eSMark Adams NULL, 32347fb60732SBarry Smith NULL, 3235dec0b466SHong Zhang /*150*/ NULL, 3236dec0b466SHong Zhang NULL}; 323790ace30eSBarry Smith 32384b828684SBarry Smith /*@C 323911a5261eSBarry Smith MatCreateSeqDense - Creates a `MATSEQDENSE` that 3240fb850c59SBarry Smith is stored in column major order (the usual Fortran format). 3241289bc588SBarry Smith 3242d083f849SBarry Smith Collective 3243db81eaa0SLois Curfman McInnes 324420563c6bSBarry Smith Input Parameters: 324511a5261eSBarry Smith + comm - MPI communicator, set to `PETSC_COMM_SELF` 32460c775827SLois Curfman McInnes . m - number of rows 324718f449edSLois Curfman McInnes . n - number of columns 32482ef1f0ffSBarry Smith - data - optional location of matrix data in column major order. Use `NULL` for PETSc 3249dfc5480cSLois Curfman McInnes to control all matrix memory allocation. 325020563c6bSBarry Smith 325120563c6bSBarry Smith Output Parameter: 325244cd7ae7SLois Curfman McInnes . A - the matrix 325320563c6bSBarry Smith 32542ef1f0ffSBarry Smith Level: intermediate 32552ef1f0ffSBarry Smith 325611a5261eSBarry Smith Note: 325718f449edSLois Curfman McInnes The data input variable is intended primarily for Fortran programmers 325818f449edSLois Curfman McInnes who wish to allocate their own matrix memory space. Most users should 32592ef1f0ffSBarry Smith set `data` = `NULL`. 326018f449edSLois Curfman McInnes 3261fb850c59SBarry Smith Developer Note: 3262fb850c59SBarry Smith Many of the matrix operations for this variant use the BLAS and LAPACK routines. 3263fb850c59SBarry Smith 32641cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()` 326520563c6bSBarry Smith @*/ 3266d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateSeqDense(MPI_Comm comm, PetscInt m, PetscInt n, PetscScalar *data, Mat *A) 3267d71ae5a4SJacob Faibussowitsch { 32683a40ed3dSBarry Smith PetscFunctionBegin; 32699566063dSJacob Faibussowitsch PetscCall(MatCreate(comm, A)); 32709566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*A, m, n, m, n)); 32719566063dSJacob Faibussowitsch PetscCall(MatSetType(*A, MATSEQDENSE)); 32729566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(*A, data)); 32733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3274273d9f13SBarry Smith } 3275273d9f13SBarry Smith 3276273d9f13SBarry Smith /*@C 327711a5261eSBarry Smith MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements of a `MATSEQDENSE` matrix 3278273d9f13SBarry Smith 3279d083f849SBarry Smith Collective 3280273d9f13SBarry Smith 3281273d9f13SBarry Smith Input Parameters: 32821c4f3114SJed Brown + B - the matrix 32832ef1f0ffSBarry Smith - data - the array (or `NULL`) 32842ef1f0ffSBarry Smith 32852ef1f0ffSBarry Smith Level: intermediate 3286273d9f13SBarry Smith 328711a5261eSBarry Smith Note: 3288273d9f13SBarry Smith The data input variable is intended primarily for Fortran programmers 3289273d9f13SBarry Smith who wish to allocate their own matrix memory space. Most users should 3290284134d9SBarry Smith need not call this routine. 3291273d9f13SBarry Smith 32921cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()`, `MatDenseSetLDA()` 3293273d9f13SBarry Smith @*/ 3294d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation(Mat B, PetscScalar data[]) 3295d71ae5a4SJacob Faibussowitsch { 3296a23d5eceSKris Buschelman PetscFunctionBegin; 3297d5ea218eSStefano Zampini PetscValidHeaderSpecific(B, MAT_CLASSID, 1); 3298cac4c232SBarry Smith PetscTryMethod(B, "MatSeqDenseSetPreallocation_C", (Mat, PetscScalar[]), (B, data)); 32993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3300a23d5eceSKris Buschelman } 3301a23d5eceSKris Buschelman 3302d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation_SeqDense(Mat B, PetscScalar *data) 3303d71ae5a4SJacob Faibussowitsch { 3304ad16ce7aSStefano Zampini Mat_SeqDense *b = (Mat_SeqDense *)B->data; 3305273d9f13SBarry Smith 3306273d9f13SBarry Smith PetscFunctionBegin; 330728b400f6SJacob Faibussowitsch PetscCheck(!b->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3308273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 3309a868139aSShri Abhyankar 33109566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(B->rmap)); 33119566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(B->cmap)); 331234ef9618SShri Abhyankar 3313ad16ce7aSStefano Zampini if (b->lda <= 0) b->lda = B->rmap->n; 331486d161a7SShri Abhyankar 33159e8f95c4SLisandro Dalcin if (!data) { /* petsc-allocated storage */ 33169566063dSJacob Faibussowitsch if (!b->user_alloc) PetscCall(PetscFree(b->v)); 33179566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((size_t)b->lda * B->cmap->n, &b->v)); 33182205254eSKarl Rupp 33199e8f95c4SLisandro Dalcin b->user_alloc = PETSC_FALSE; 3320273d9f13SBarry Smith } else { /* user-allocated storage */ 33219566063dSJacob Faibussowitsch if (!b->user_alloc) PetscCall(PetscFree(b->v)); 3322273d9f13SBarry Smith b->v = data; 3323273d9f13SBarry Smith b->user_alloc = PETSC_TRUE; 3324273d9f13SBarry Smith } 33250450473dSBarry Smith B->assembled = PETSC_TRUE; 33263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3327273d9f13SBarry Smith } 3328273d9f13SBarry Smith 332965b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 3330d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) 3331d71ae5a4SJacob Faibussowitsch { 3332d77f618aSHong Zhang Mat mat_elemental; 33331683a169SBarry Smith const PetscScalar *array; 33341683a169SBarry Smith PetscScalar *v_colwise; 3335d77f618aSHong Zhang PetscInt M = A->rmap->N, N = A->cmap->N, i, j, k, *rows, *cols; 3336d77f618aSHong Zhang 33378baccfbdSHong Zhang PetscFunctionBegin; 33389566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(M * N, &v_colwise, M, &rows, N, &cols)); 33399566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &array)); 3340d77f618aSHong Zhang /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */ 3341d77f618aSHong Zhang k = 0; 3342d77f618aSHong Zhang for (j = 0; j < N; j++) { 3343d77f618aSHong Zhang cols[j] = j; 3344ad540459SPierre Jolivet for (i = 0; i < M; i++) v_colwise[j * M + i] = array[k++]; 3345d77f618aSHong Zhang } 3346ad540459SPierre Jolivet for (i = 0; i < M; i++) rows[i] = i; 33479566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &array)); 3348d77f618aSHong Zhang 33499566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental)); 33509566063dSJacob Faibussowitsch PetscCall(MatSetSizes(mat_elemental, PETSC_DECIDE, PETSC_DECIDE, M, N)); 33519566063dSJacob Faibussowitsch PetscCall(MatSetType(mat_elemental, MATELEMENTAL)); 33529566063dSJacob Faibussowitsch PetscCall(MatSetUp(mat_elemental)); 3353d77f618aSHong Zhang 3354d77f618aSHong Zhang /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */ 33559566063dSJacob Faibussowitsch PetscCall(MatSetValues(mat_elemental, M, rows, N, cols, v_colwise, ADD_VALUES)); 33569566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY)); 33579566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY)); 33589566063dSJacob Faibussowitsch PetscCall(PetscFree3(v_colwise, rows, cols)); 3359d77f618aSHong Zhang 3360511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 33619566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A, &mat_elemental)); 3362d77f618aSHong Zhang } else { 3363d77f618aSHong Zhang *newmat = mat_elemental; 3364d77f618aSHong Zhang } 33653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 33668baccfbdSHong Zhang } 336765b80a83SHong Zhang #endif 33688baccfbdSHong Zhang 3369d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA_SeqDense(Mat B, PetscInt lda) 3370d71ae5a4SJacob Faibussowitsch { 33711b807ce4Svictorle Mat_SeqDense *b = (Mat_SeqDense *)B->data; 33727422da62SJose E. Roman PetscBool data; 337321a2c019SBarry Smith 33741b807ce4Svictorle PetscFunctionBegin; 33757422da62SJose E. Roman data = (PetscBool)((B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE); 3376aed4548fSBarry Smith PetscCheck(b->user_alloc || !data || b->lda == lda, PETSC_COMM_SELF, PETSC_ERR_ORDER, "LDA cannot be changed after allocation of internal storage"); 337708401ef6SPierre 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); 33781b807ce4Svictorle b->lda = lda; 33793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 33801b807ce4Svictorle } 33811b807ce4Svictorle 3382d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm, Mat inmat, PetscInt n, MatReuse scall, Mat *outmat) 3383d71ae5a4SJacob Faibussowitsch { 3384d528f656SJakub Kruzik PetscFunctionBegin; 33859566063dSJacob Faibussowitsch PetscCall(MatCreateMPIMatConcatenateSeqMat_MPIDense(comm, inmat, n, scall, outmat)); 33863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3387d528f656SJakub Kruzik } 3388d528f656SJakub Kruzik 3389d16ceb75SStefano Zampini PetscErrorCode MatDenseCreateColumnVec_Private(Mat A, Vec *v) 3390d16ceb75SStefano Zampini { 3391d16ceb75SStefano Zampini PetscBool isstd, iskok, iscuda, iship; 3392d16ceb75SStefano Zampini PetscMPIInt size; 3393d16ceb75SStefano Zampini #if PetscDefined(HAVE_CUDA) || PetscDefined(HAVE_HIP) 3394d16ceb75SStefano Zampini /* we pass the data of A, to prevent allocating needless GPU memory the first time VecCUPMPlaceArray is called. */ 3395d16ceb75SStefano Zampini const PetscScalar *a; 3396d16ceb75SStefano Zampini #endif 3397d16ceb75SStefano Zampini 3398d16ceb75SStefano Zampini PetscFunctionBegin; 3399d16ceb75SStefano Zampini *v = NULL; 3400d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &isstd, VECSTANDARD, VECSEQ, VECMPI, "")); 3401d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &iskok, VECKOKKOS, VECSEQKOKKOS, VECMPIKOKKOS, "")); 3402d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &iscuda, VECCUDA, VECSEQCUDA, VECMPICUDA, "")); 3403d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &iship, VECHIP, VECSEQHIP, VECMPIHIP, "")); 3404d16ceb75SStefano Zampini PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A), &size)); 3405d16ceb75SStefano Zampini if (isstd) { 3406d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPIWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, v)); 3407d16ceb75SStefano Zampini else PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, v)); 3408d16ceb75SStefano Zampini } else if (iskok) { 3409d16ceb75SStefano Zampini PetscCheck(PetscDefined(HAVE_KOKKOS_KERNELS), PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Reconfigure using KOKKOS kernels support"); 3410d16ceb75SStefano Zampini #if PetscDefined(HAVE_KOKKOS_KERNELS) 3411d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPIKokkosWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, v)); 3412d16ceb75SStefano Zampini else PetscCall(VecCreateSeqKokkosWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, v)); 3413d16ceb75SStefano Zampini #endif 3414d16ceb75SStefano Zampini } else if (iscuda) { 3415d16ceb75SStefano Zampini PetscCheck(PetscDefined(HAVE_CUDA), PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Reconfigure using CUDA support"); 3416d16ceb75SStefano Zampini #if PetscDefined(HAVE_CUDA) 3417d16ceb75SStefano Zampini PetscCall(MatDenseCUDAGetArrayRead(A, &a)); 3418d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPICUDAWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, a, v)); 3419d16ceb75SStefano Zampini else PetscCall(VecCreateSeqCUDAWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, a, v)); 3420d16ceb75SStefano Zampini #endif 3421d16ceb75SStefano Zampini } else if (iship) { 3422d16ceb75SStefano Zampini PetscCheck(PetscDefined(HAVE_HIP), PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Reconfigure using HIP support"); 3423d16ceb75SStefano Zampini #if PetscDefined(HAVE_HIP) 3424d16ceb75SStefano Zampini PetscCall(MatDenseHIPGetArrayRead(A, &a)); 3425d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPIHIPWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, a, v)); 3426d16ceb75SStefano Zampini else PetscCall(VecCreateSeqHIPWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, a, v)); 3427d16ceb75SStefano Zampini #endif 3428d16ceb75SStefano Zampini } 3429d16ceb75SStefano Zampini PetscCheck(*v, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Not coded for type %s", A->defaultvectype); 3430d16ceb75SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 3431d16ceb75SStefano Zampini } 3432d16ceb75SStefano Zampini 3433d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A, PetscInt col, Vec *v) 3434d71ae5a4SJacob Faibussowitsch { 34356947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34366947451fSStefano Zampini 34376947451fSStefano Zampini PetscFunctionBegin; 343828b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 343928b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3440d16ceb75SStefano Zampini if (!a->cvec) PetscCall(MatDenseCreateColumnVec_Private(A, &a->cvec)); 34416947451fSStefano Zampini a->vecinuse = col + 1; 34429566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, (PetscScalar **)&a->ptrinuse)); 34439566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda)); 34446947451fSStefano Zampini *v = a->cvec; 34453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34466947451fSStefano Zampini } 34476947451fSStefano Zampini 3448d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A, PetscInt col, Vec *v) 3449d71ae5a4SJacob Faibussowitsch { 34506947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34516947451fSStefano Zampini 34526947451fSStefano Zampini PetscFunctionBegin; 345328b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 345428b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 34556947451fSStefano Zampini a->vecinuse = 0; 34569566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, (PetscScalar **)&a->ptrinuse)); 34579566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 345875f6d85dSStefano Zampini if (v) *v = NULL; 34593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34606947451fSStefano Zampini } 34616947451fSStefano Zampini 3462d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v) 3463d71ae5a4SJacob Faibussowitsch { 34646947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34656947451fSStefano Zampini 34666947451fSStefano Zampini PetscFunctionBegin; 346728b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 346828b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3469d16ceb75SStefano Zampini if (!a->cvec) PetscCall(MatDenseCreateColumnVec_Private(A, &a->cvec)); 34706947451fSStefano Zampini a->vecinuse = col + 1; 34719566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &a->ptrinuse)); 3472*8e3a54c0SPierre Jolivet PetscCall(VecPlaceArray(a->cvec, PetscSafePointerPlusOffset(a->ptrinuse, (size_t)col * (size_t)a->lda))); 34739566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(a->cvec)); 34746947451fSStefano Zampini *v = a->cvec; 34753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34766947451fSStefano Zampini } 34776947451fSStefano Zampini 3478d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v) 3479d71ae5a4SJacob Faibussowitsch { 34806947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34816947451fSStefano Zampini 34826947451fSStefano Zampini PetscFunctionBegin; 348328b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 348428b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 34856947451fSStefano Zampini a->vecinuse = 0; 34869566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &a->ptrinuse)); 34879566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(a->cvec)); 34889566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 348975f6d85dSStefano Zampini if (v) *v = NULL; 34903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34916947451fSStefano Zampini } 34926947451fSStefano Zampini 3493d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v) 3494d71ae5a4SJacob Faibussowitsch { 34956947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34966947451fSStefano Zampini 34976947451fSStefano Zampini PetscFunctionBegin; 349828b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 349928b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3500d16ceb75SStefano Zampini if (!a->cvec) PetscCall(MatDenseCreateColumnVec_Private(A, &a->cvec)); 35016947451fSStefano Zampini a->vecinuse = col + 1; 35029566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(A, (PetscScalar **)&a->ptrinuse)); 3503*8e3a54c0SPierre Jolivet PetscCall(VecPlaceArray(a->cvec, PetscSafePointerPlusOffset(a->ptrinuse, (size_t)col * (size_t)a->lda))); 35046947451fSStefano Zampini *v = a->cvec; 35053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35066947451fSStefano Zampini } 35076947451fSStefano Zampini 3508d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v) 3509d71ae5a4SJacob Faibussowitsch { 35106947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35116947451fSStefano Zampini 35126947451fSStefano Zampini PetscFunctionBegin; 351328b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 351428b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 35156947451fSStefano Zampini a->vecinuse = 0; 35169566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(A, (PetscScalar **)&a->ptrinuse)); 35179566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 351875f6d85dSStefano Zampini if (v) *v = NULL; 35193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35206947451fSStefano Zampini } 35216947451fSStefano Zampini 3522d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) 3523d71ae5a4SJacob Faibussowitsch { 35245ea7661aSPierre Jolivet Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35255ea7661aSPierre Jolivet 35265ea7661aSPierre Jolivet PetscFunctionBegin; 352728b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 352828b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3529a2748737SPierre Jolivet if (a->cmat && (cend - cbegin != a->cmat->cmap->N || rend - rbegin != a->cmat->rmap->N)) PetscCall(MatDestroy(&a->cmat)); 35305ea7661aSPierre Jolivet if (!a->cmat) { 3531*8e3a54c0SPierre 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)); 35325ea7661aSPierre Jolivet } else { 3533*8e3a54c0SPierre Jolivet PetscCall(MatDensePlaceArray(a->cmat, PetscSafePointerPlusOffset(a->v, rbegin + (size_t)cbegin * a->lda))); 35345ea7661aSPierre Jolivet } 35359566063dSJacob Faibussowitsch PetscCall(MatDenseSetLDA(a->cmat, a->lda)); 35365ea7661aSPierre Jolivet a->matinuse = cbegin + 1; 35375ea7661aSPierre Jolivet *v = a->cmat; 353847d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 353975f6d85dSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 354075f6d85dSStefano Zampini #endif 35413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35425ea7661aSPierre Jolivet } 35435ea7661aSPierre Jolivet 3544d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A, Mat *v) 3545d71ae5a4SJacob Faibussowitsch { 35465ea7661aSPierre Jolivet Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35475ea7661aSPierre Jolivet 35485ea7661aSPierre Jolivet PetscFunctionBegin; 354928b400f6SJacob Faibussowitsch PetscCheck(a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetSubMatrix() first"); 355028b400f6SJacob Faibussowitsch PetscCheck(a->cmat, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column matrix"); 355108401ef6SPierre Jolivet PetscCheck(*v == a->cmat, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not the matrix obtained from MatDenseGetSubMatrix()"); 35525ea7661aSPierre Jolivet a->matinuse = 0; 35539566063dSJacob Faibussowitsch PetscCall(MatDenseResetArray(a->cmat)); 3554742765d3SMatthew Knepley if (v) *v = NULL; 355547d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 35563faff063SStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 35573faff063SStefano Zampini #endif 35583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35595ea7661aSPierre Jolivet } 35605ea7661aSPierre Jolivet 35610bad9183SKris Buschelman /*MC 3562fafad747SKris Buschelman MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices. 35630bad9183SKris Buschelman 35642ef1f0ffSBarry Smith Options Database Key: 356511a5261eSBarry Smith . -mat_type seqdense - sets the matrix type to `MATSEQDENSE` during a call to `MatSetFromOptions()` 35660bad9183SKris Buschelman 35670bad9183SKris Buschelman Level: beginner 35680bad9183SKris Buschelman 35691cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreateSeqDense()` 35700bad9183SKris Buschelman M*/ 3571d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreate_SeqDense(Mat B) 3572d71ae5a4SJacob Faibussowitsch { 3573273d9f13SBarry Smith Mat_SeqDense *b; 35747c334f02SBarry Smith PetscMPIInt size; 3575273d9f13SBarry Smith 3576273d9f13SBarry Smith PetscFunctionBegin; 35779566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)B), &size)); 357808401ef6SPierre Jolivet PetscCheck(size <= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Comm must be of size 1"); 357955659b69SBarry Smith 35804dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&b)); 358144cd7ae7SLois Curfman McInnes B->data = (void *)b; 3582aea10558SJacob Faibussowitsch B->ops[0] = MatOps_Values; 358318f449edSLois Curfman McInnes 3584273d9f13SBarry Smith b->roworiented = PETSC_TRUE; 35854e220ebcSLois Curfman McInnes 35869566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatQRFactor_C", MatQRFactor_SeqDense)); 35879566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetLDA_C", MatDenseGetLDA_SeqDense)); 35889566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseSetLDA_C", MatDenseSetLDA_SeqDense)); 35899566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArray_C", MatDenseGetArray_SeqDense)); 35909566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArray_C", MatDenseRestoreArray_SeqDense)); 35919566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDensePlaceArray_C", MatDensePlaceArray_SeqDense)); 35929566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseResetArray_C", MatDenseResetArray_SeqDense)); 35939566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseReplaceArray_C", MatDenseReplaceArray_SeqDense)); 35949566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayRead_C", MatDenseGetArray_SeqDense)); 35959566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayRead_C", MatDenseRestoreArray_SeqDense)); 35969566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayWrite_C", MatDenseGetArray_SeqDense)); 35979566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayWrite_C", MatDenseRestoreArray_SeqDense)); 35989566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqaij_C", MatConvert_SeqDense_SeqAIJ)); 35998baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 36009566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_elemental_C", MatConvert_SeqDense_Elemental)); 36018baccfbdSHong Zhang #endif 3602d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 36039566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_scalapack_C", MatConvert_Dense_ScaLAPACK)); 3604d24d4204SJose E. Roman #endif 36052bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA) 36069566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensecuda_C", MatConvert_SeqDense_SeqDenseCUDA)); 36079566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", MatProductSetFromOptions_SeqDense)); 36089566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdense_C", MatProductSetFromOptions_SeqDense)); 36099566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensecuda_C", MatProductSetFromOptions_SeqDense)); 36102bf066beSStefano Zampini #endif 361147d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 361247d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensehip_C", MatConvert_SeqDense_SeqDenseHIP)); 361347d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensehip_seqdensehip_C", MatProductSetFromOptions_SeqDense)); 361447d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensehip_seqdense_C", MatProductSetFromOptions_SeqDense)); 361547d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensehip_C", MatProductSetFromOptions_SeqDense)); 361647d993e7Ssuyashtn #endif 36179566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSeqDenseSetPreallocation_C", MatSeqDenseSetPreallocation_SeqDense)); 36189566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqaij_seqdense_C", MatProductSetFromOptions_SeqAIJ_SeqDense)); 36199566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdense_C", MatProductSetFromOptions_SeqDense)); 36209566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense)); 36219566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqsbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense)); 362296e6d5c4SRichard Tran Mills 36239566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumn_C", MatDenseGetColumn_SeqDense)); 36249566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumn_C", MatDenseRestoreColumn_SeqDense)); 36259566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVec_C", MatDenseGetColumnVec_SeqDense)); 36269566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVec_C", MatDenseRestoreColumnVec_SeqDense)); 36279566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecRead_C", MatDenseGetColumnVecRead_SeqDense)); 36289566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecRead_C", MatDenseRestoreColumnVecRead_SeqDense)); 36299566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecWrite_C", MatDenseGetColumnVecWrite_SeqDense)); 36309566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecWrite_C", MatDenseRestoreColumnVecWrite_SeqDense)); 36319566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetSubMatrix_C", MatDenseGetSubMatrix_SeqDense)); 36329566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreSubMatrix_C", MatDenseRestoreSubMatrix_SeqDense)); 36339566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)B, MATSEQDENSE)); 36343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3635289bc588SBarry Smith } 363686aefd0dSHong Zhang 363786aefd0dSHong Zhang /*@C 363811a5261eSBarry Smith MatDenseGetColumn - gives access to a column of a dense matrix. This is only the local part of the column. You MUST call `MatDenseRestoreColumn()` to avoid memory bleeding. 363986aefd0dSHong Zhang 364086aefd0dSHong Zhang Not Collective 364186aefd0dSHong Zhang 36425ea7661aSPierre Jolivet Input Parameters: 3643fe59aa6dSJacob Faibussowitsch + A - a `MATSEQDENSE` or `MATMPIDENSE` matrix 364486aefd0dSHong Zhang - col - column index 364586aefd0dSHong Zhang 364686aefd0dSHong Zhang Output Parameter: 364786aefd0dSHong Zhang . vals - pointer to the data 364886aefd0dSHong Zhang 364986aefd0dSHong Zhang Level: intermediate 365086aefd0dSHong Zhang 365111a5261eSBarry Smith Note: 365211a5261eSBarry Smith Use `MatDenseGetColumnVec()` to get access to a column of a `MATDENSE` treated as a `Vec` 365311a5261eSBarry Smith 36541cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreColumn()`, `MatDenseGetColumnVec()` 365586aefd0dSHong Zhang @*/ 3656d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumn(Mat A, PetscInt col, PetscScalar **vals) 3657d71ae5a4SJacob Faibussowitsch { 365886aefd0dSHong Zhang PetscFunctionBegin; 3659d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3660d5ea218eSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 36614f572ea9SToby Isaac PetscAssertPointer(vals, 3); 3662cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumn_C", (Mat, PetscInt, PetscScalar **), (A, col, vals)); 36633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 366486aefd0dSHong Zhang } 366586aefd0dSHong Zhang 366686aefd0dSHong Zhang /*@C 366711a5261eSBarry Smith MatDenseRestoreColumn - returns access to a column of a `MATDENSE` matrix which is returned by `MatDenseGetColumn()`. 366886aefd0dSHong Zhang 366986aefd0dSHong Zhang Not Collective 367086aefd0dSHong Zhang 3671742765d3SMatthew Knepley Input Parameters: 3672fe59aa6dSJacob Faibussowitsch + A - a `MATSEQDENSE` or `MATMPIDENSE` matrix 36732ef1f0ffSBarry Smith - vals - pointer to the data (may be `NULL`) 367486aefd0dSHong Zhang 367586aefd0dSHong Zhang Level: intermediate 367686aefd0dSHong Zhang 36771cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetColumn()` 367886aefd0dSHong Zhang @*/ 3679d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumn(Mat A, PetscScalar **vals) 3680d71ae5a4SJacob Faibussowitsch { 368186aefd0dSHong Zhang PetscFunctionBegin; 3682d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 36834f572ea9SToby Isaac PetscAssertPointer(vals, 2); 3684cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumn_C", (Mat, PetscScalar **), (A, vals)); 36853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 368686aefd0dSHong Zhang } 36876947451fSStefano Zampini 36880f74d2c1SSatish Balay /*@ 368911a5261eSBarry Smith MatDenseGetColumnVec - Gives read-write access to a column of a `MATDENSE` matrix, represented as a `Vec`. 36906947451fSStefano Zampini 36916947451fSStefano Zampini Collective 36926947451fSStefano Zampini 36935ea7661aSPierre Jolivet Input Parameters: 3694fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 36956947451fSStefano Zampini - col - the column index 36966947451fSStefano Zampini 36976947451fSStefano Zampini Output Parameter: 36986947451fSStefano Zampini . v - the vector 36996947451fSStefano Zampini 37002ef1f0ffSBarry Smith Level: intermediate 37012ef1f0ffSBarry Smith 37026947451fSStefano Zampini Notes: 370311a5261eSBarry Smith The vector is owned by PETSc. Users need to call `MatDenseRestoreColumnVec()` when the vector is no longer needed. 370411a5261eSBarry Smith 370511a5261eSBarry Smith Use `MatDenseGetColumnVecRead()` to obtain read-only access or `MatDenseGetColumnVecWrite()` for write-only access. 37066947451fSStefano Zampini 37071cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`, `MatDenseGetColumn()` 37086947451fSStefano Zampini @*/ 3709d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec(Mat A, PetscInt col, Vec *v) 3710d71ae5a4SJacob Faibussowitsch { 37116947451fSStefano Zampini PetscFunctionBegin; 37126947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 37136947451fSStefano Zampini PetscValidType(A, 1); 37146947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 37154f572ea9SToby Isaac PetscAssertPointer(v, 3); 371628b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 37172cf15c64SPierre Jolivet PetscCheck(col >= 0 && col < A->cmap->N, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")", col, A->cmap->N); 3718cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v)); 37193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37206947451fSStefano Zampini } 37216947451fSStefano Zampini 37220f74d2c1SSatish Balay /*@ 3723fb850c59SBarry Smith MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from `MatDenseGetColumnVec()`. 37246947451fSStefano Zampini 37256947451fSStefano Zampini Collective 37266947451fSStefano Zampini 37275ea7661aSPierre Jolivet Input Parameters: 3728fb850c59SBarry Smith + A - the `Mat` object 37296947451fSStefano Zampini . col - the column index 3730fb850c59SBarry Smith - v - the `Vec` object (may be `NULL`) 37316947451fSStefano Zampini 37326947451fSStefano Zampini Level: intermediate 37336947451fSStefano Zampini 37341cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 37356947451fSStefano Zampini @*/ 3736d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec(Mat A, PetscInt col, Vec *v) 3737d71ae5a4SJacob Faibussowitsch { 37386947451fSStefano Zampini PetscFunctionBegin; 37396947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 37406947451fSStefano Zampini PetscValidType(A, 1); 37416947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 374208401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 37432cf15c64SPierre Jolivet PetscCheck(col >= 0 && col < A->cmap->N, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")", col, A->cmap->N); 3744cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v)); 37453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37466947451fSStefano Zampini } 37476947451fSStefano Zampini 37480f74d2c1SSatish Balay /*@ 3749fb850c59SBarry Smith MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a `Vec`. 37506947451fSStefano Zampini 37516947451fSStefano Zampini Collective 37526947451fSStefano Zampini 37535ea7661aSPierre Jolivet Input Parameters: 3754fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 37556947451fSStefano Zampini - col - the column index 37566947451fSStefano Zampini 37576947451fSStefano Zampini Output Parameter: 37586947451fSStefano Zampini . v - the vector 37596947451fSStefano Zampini 37602ef1f0ffSBarry Smith Level: intermediate 37612ef1f0ffSBarry Smith 37626947451fSStefano Zampini Notes: 37636947451fSStefano Zampini The vector is owned by PETSc and users cannot modify it. 376411a5261eSBarry Smith 37652ef1f0ffSBarry Smith Users need to call `MatDenseRestoreColumnVecRead()` when the vector is no longer needed. 376611a5261eSBarry Smith 37672ef1f0ffSBarry Smith Use `MatDenseGetColumnVec()` to obtain read-write access or `MatDenseGetColumnVecWrite()` for write-only access. 37686947451fSStefano Zampini 37691cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 37706947451fSStefano Zampini @*/ 3771d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead(Mat A, PetscInt col, Vec *v) 3772d71ae5a4SJacob Faibussowitsch { 37736947451fSStefano Zampini PetscFunctionBegin; 37746947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 37756947451fSStefano Zampini PetscValidType(A, 1); 37766947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 37774f572ea9SToby Isaac PetscAssertPointer(v, 3); 377828b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 37792cf15c64SPierre Jolivet PetscCheck(col >= 0 && col < A->cmap->N, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")", col, A->cmap->N); 3780cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v)); 37813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37826947451fSStefano Zampini } 37836947451fSStefano Zampini 37840f74d2c1SSatish Balay /*@ 3785fb850c59SBarry Smith MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from `MatDenseGetColumnVecRead()`. 37866947451fSStefano Zampini 37876947451fSStefano Zampini Collective 37886947451fSStefano Zampini 37895ea7661aSPierre Jolivet Input Parameters: 3790fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 37916947451fSStefano Zampini . col - the column index 3792fb850c59SBarry Smith - v - the `Vec` object (may be `NULL`) 37936947451fSStefano Zampini 37946947451fSStefano Zampini Level: intermediate 37956947451fSStefano Zampini 37961cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecWrite()` 37976947451fSStefano Zampini @*/ 3798d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead(Mat A, PetscInt col, Vec *v) 3799d71ae5a4SJacob Faibussowitsch { 38006947451fSStefano Zampini PetscFunctionBegin; 38016947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38026947451fSStefano Zampini PetscValidType(A, 1); 38036947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 380408401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 38052cf15c64SPierre Jolivet PetscCheck(col >= 0 && col < A->cmap->N, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")", col, A->cmap->N); 3806cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v)); 38073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38086947451fSStefano Zampini } 38096947451fSStefano Zampini 38100f74d2c1SSatish Balay /*@ 3811fb850c59SBarry Smith MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a `Vec`. 38126947451fSStefano Zampini 38136947451fSStefano Zampini Collective 38146947451fSStefano Zampini 38155ea7661aSPierre Jolivet Input Parameters: 3816fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 38176947451fSStefano Zampini - col - the column index 38186947451fSStefano Zampini 38196947451fSStefano Zampini Output Parameter: 38206947451fSStefano Zampini . v - the vector 38216947451fSStefano Zampini 38226947451fSStefano Zampini Level: intermediate 38236947451fSStefano Zampini 38242ef1f0ffSBarry Smith Notes: 38252ef1f0ffSBarry Smith The vector is owned by PETSc. Users need to call `MatDenseRestoreColumnVecWrite()` when the vector is no longer needed. 38262ef1f0ffSBarry Smith 38272ef1f0ffSBarry Smith Use `MatDenseGetColumnVec()` to obtain read-write access or `MatDenseGetColumnVecRead()` for read-only access. 38282ef1f0ffSBarry Smith 38291cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 38306947451fSStefano Zampini @*/ 3831d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite(Mat A, PetscInt col, Vec *v) 3832d71ae5a4SJacob Faibussowitsch { 38336947451fSStefano Zampini PetscFunctionBegin; 38346947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38356947451fSStefano Zampini PetscValidType(A, 1); 38366947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 38374f572ea9SToby Isaac PetscAssertPointer(v, 3); 383828b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3839aed4548fSBarry Smith PetscCheck(col >= 0 && col < A->cmap->N, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")", col, A->cmap->N); 3840cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v)); 38413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38426947451fSStefano Zampini } 38436947451fSStefano Zampini 38440f74d2c1SSatish Balay /*@ 3845fb850c59SBarry Smith MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from `MatDenseGetColumnVecWrite()`. 38466947451fSStefano Zampini 38476947451fSStefano Zampini Collective 38486947451fSStefano Zampini 38495ea7661aSPierre Jolivet Input Parameters: 3850fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 38516947451fSStefano Zampini . col - the column index 38522ef1f0ffSBarry Smith - v - the `Vec` object (may be `NULL`) 38536947451fSStefano Zampini 38546947451fSStefano Zampini Level: intermediate 38556947451fSStefano Zampini 38561cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()` 38576947451fSStefano Zampini @*/ 3858d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A, PetscInt col, Vec *v) 3859d71ae5a4SJacob Faibussowitsch { 38606947451fSStefano Zampini PetscFunctionBegin; 38616947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38626947451fSStefano Zampini PetscValidType(A, 1); 38636947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 386408401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3865aed4548fSBarry Smith PetscCheck(col >= 0 && col < A->cmap->N, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")", col, A->cmap->N); 3866cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v)); 38673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38686947451fSStefano Zampini } 38695ea7661aSPierre Jolivet 38700f74d2c1SSatish Balay /*@ 3871fb850c59SBarry Smith MatDenseGetSubMatrix - Gives access to a block of rows and columns of a dense matrix, represented as a `Mat`. 38725ea7661aSPierre Jolivet 38735ea7661aSPierre Jolivet Collective 38745ea7661aSPierre Jolivet 38755ea7661aSPierre Jolivet Input Parameters: 3876fb850c59SBarry Smith + A - the `Mat` object 38772ef1f0ffSBarry Smith . rbegin - the first global row index in the block (if `PETSC_DECIDE`, is 0) 38782ef1f0ffSBarry Smith . rend - the global row index past the last one in the block (if `PETSC_DECIDE`, is `M`) 38792ef1f0ffSBarry Smith . cbegin - the first global column index in the block (if `PETSC_DECIDE`, is 0) 38802ef1f0ffSBarry Smith - cend - the global column index past the last one in the block (if `PETSC_DECIDE`, is `N`) 38815ea7661aSPierre Jolivet 38825ea7661aSPierre Jolivet Output Parameter: 38835ea7661aSPierre Jolivet . v - the matrix 38845ea7661aSPierre Jolivet 38855ea7661aSPierre Jolivet Level: intermediate 38865ea7661aSPierre Jolivet 38872ef1f0ffSBarry Smith Notes: 38882ef1f0ffSBarry Smith The matrix is owned by PETSc. Users need to call `MatDenseRestoreSubMatrix()` when the matrix is no longer needed. 38892ef1f0ffSBarry Smith 38902ef1f0ffSBarry Smith The output matrix is not redistributed by PETSc, so depending on the values of `rbegin` and `rend`, some processes may have no local rows. 38912ef1f0ffSBarry Smith 38921cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreSubMatrix()` 38935ea7661aSPierre Jolivet @*/ 3894d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) 3895d71ae5a4SJacob Faibussowitsch { 38965ea7661aSPierre Jolivet PetscFunctionBegin; 38975ea7661aSPierre Jolivet PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38985ea7661aSPierre Jolivet PetscValidType(A, 1); 3899a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, rbegin, 2); 3900a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, rend, 3); 3901a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, cbegin, 4); 3902a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, cend, 5); 39034f572ea9SToby Isaac PetscAssertPointer(v, 6); 3904a2748737SPierre Jolivet if (rbegin == PETSC_DECIDE) rbegin = 0; 3905a2748737SPierre Jolivet if (rend == PETSC_DECIDE) rend = A->rmap->N; 3906a2748737SPierre Jolivet if (cbegin == PETSC_DECIDE) cbegin = 0; 3907a2748737SPierre Jolivet if (cend == PETSC_DECIDE) cend = A->cmap->N; 390828b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3909a2748737SPierre Jolivet PetscCheck(rbegin >= 0 && rbegin <= A->rmap->N, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Invalid rbegin %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT "]", rbegin, A->rmap->N); 3910a2748737SPierre Jolivet PetscCheck(rend >= rbegin && rend <= A->rmap->N, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Invalid rend %" PetscInt_FMT ", should be in [%" PetscInt_FMT ",%" PetscInt_FMT "]", rend, rbegin, A->rmap->N); 3911a2748737SPierre Jolivet PetscCheck(cbegin >= 0 && cbegin <= A->cmap->N, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Invalid cbegin %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT "]", cbegin, A->cmap->N); 3912a2748737SPierre Jolivet PetscCheck(cend >= cbegin && cend <= A->cmap->N, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Invalid cend %" PetscInt_FMT ", should be in [%" PetscInt_FMT ",%" PetscInt_FMT "]", cend, cbegin, A->cmap->N); 3913a2748737SPierre Jolivet PetscUseMethod(A, "MatDenseGetSubMatrix_C", (Mat, PetscInt, PetscInt, PetscInt, PetscInt, Mat *), (A, rbegin, rend, cbegin, cend, v)); 39143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 39155ea7661aSPierre Jolivet } 39165ea7661aSPierre Jolivet 39170f74d2c1SSatish Balay /*@ 3918fb850c59SBarry Smith MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from `MatDenseGetSubMatrix()`. 39195ea7661aSPierre Jolivet 39205ea7661aSPierre Jolivet Collective 39215ea7661aSPierre Jolivet 39225ea7661aSPierre Jolivet Input Parameters: 3923fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 39242ef1f0ffSBarry Smith - v - the `Mat` object (may be `NULL`) 39255ea7661aSPierre Jolivet 39265ea7661aSPierre Jolivet Level: intermediate 39275ea7661aSPierre Jolivet 39281cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseGetSubMatrix()` 39295ea7661aSPierre Jolivet @*/ 3930d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix(Mat A, Mat *v) 3931d71ae5a4SJacob Faibussowitsch { 39325ea7661aSPierre Jolivet PetscFunctionBegin; 39335ea7661aSPierre Jolivet PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 39345ea7661aSPierre Jolivet PetscValidType(A, 1); 39354f572ea9SToby Isaac PetscAssertPointer(v, 2); 3936cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreSubMatrix_C", (Mat, Mat *), (A, v)); 39373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 39385ea7661aSPierre Jolivet } 39398a9c020eSBarry Smith 39408a9c020eSBarry Smith #include <petscblaslapack.h> 39418a9c020eSBarry Smith #include <petsc/private/kernels/blockinvert.h> 39428a9c020eSBarry Smith 3943d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseInvert(Mat A) 3944d71ae5a4SJacob Faibussowitsch { 3945d63b1753SJacob Faibussowitsch PetscInt m; 39468a9c020eSBarry Smith const PetscReal shift = 0.0; 3947d63b1753SJacob Faibussowitsch PetscBool allowzeropivot, zeropivotdetected = PETSC_FALSE; 3948d63b1753SJacob Faibussowitsch PetscScalar *values; 39498a9c020eSBarry Smith 39508a9c020eSBarry Smith PetscFunctionBegin; 3951d63b1753SJacob Faibussowitsch PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3952d63b1753SJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &values)); 3953d63b1753SJacob Faibussowitsch PetscCall(MatGetLocalSize(A, &m, NULL)); 3954d63b1753SJacob Faibussowitsch allowzeropivot = PetscNot(A->erroriffailure); 39558a9c020eSBarry Smith /* factor and invert each block */ 3956d63b1753SJacob Faibussowitsch switch (m) { 3957d71ae5a4SJacob Faibussowitsch case 1: 3958d71ae5a4SJacob Faibussowitsch values[0] = (PetscScalar)1.0 / (values[0] + shift); 3959d71ae5a4SJacob Faibussowitsch break; 39608a9c020eSBarry Smith case 2: 39618a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_2(values, shift, allowzeropivot, &zeropivotdetected)); 39628a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39638a9c020eSBarry Smith break; 39648a9c020eSBarry Smith case 3: 39658a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_3(values, shift, allowzeropivot, &zeropivotdetected)); 39668a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39678a9c020eSBarry Smith break; 39688a9c020eSBarry Smith case 4: 39698a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_4(values, shift, allowzeropivot, &zeropivotdetected)); 39708a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39718a9c020eSBarry Smith break; 39729371c9d4SSatish Balay case 5: { 39738a9c020eSBarry Smith PetscScalar work[25]; 39748a9c020eSBarry Smith PetscInt ipvt[5]; 39758a9c020eSBarry Smith 39768a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_5(values, ipvt, work, shift, allowzeropivot, &zeropivotdetected)); 39778a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39789371c9d4SSatish Balay } break; 39798a9c020eSBarry Smith case 6: 39808a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_6(values, shift, allowzeropivot, &zeropivotdetected)); 39818a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39828a9c020eSBarry Smith break; 39838a9c020eSBarry Smith case 7: 39848a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_7(values, shift, allowzeropivot, &zeropivotdetected)); 39858a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39868a9c020eSBarry Smith break; 39879371c9d4SSatish Balay default: { 39888a9c020eSBarry Smith PetscInt *v_pivots, *IJ, j; 39898a9c020eSBarry Smith PetscScalar *v_work; 39908a9c020eSBarry Smith 3991d63b1753SJacob Faibussowitsch PetscCall(PetscMalloc3(m, &v_work, m, &v_pivots, m, &IJ)); 3992d63b1753SJacob Faibussowitsch for (j = 0; j < m; j++) IJ[j] = j; 3993d63b1753SJacob Faibussowitsch PetscCall(PetscKernel_A_gets_inverse_A(m, values, v_pivots, v_work, allowzeropivot, &zeropivotdetected)); 39948a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39958a9c020eSBarry Smith PetscCall(PetscFree3(v_work, v_pivots, IJ)); 39968a9c020eSBarry Smith } 39978a9c020eSBarry Smith } 3998d63b1753SJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &values)); 39993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 40008a9c020eSBarry Smith } 4001