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 90d71ae5a4SJacob Faibussowitsch 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); 1699566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(b->v, m * n)); 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++) { 175b49cda9fSStefano Zampini b->v[*aj * m + 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) { 252ca15aa20SStefano Zampini PetscInt j; 253ca15aa20SStefano Zampini 25448a46eb9SPierre Jolivet for (j = 0; j < X->cmap->n; j++) PetscCallBLAS("BLASaxpy", BLASaxpy_(&m, &alpha, xv + j * ldax, &one, yv + j * lday, &one)); 255a5ce6ee0Svictorle } else { 256792fecdfSBarry Smith PetscCallBLAS("BLASaxpy", BLASaxpy_(&N, &alpha, xv, &one, yv, &one)); 257a5ce6ee0Svictorle } 2589566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(X, &xv)); 2599566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(Y, &yv)); 2609566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(PetscMax(2.0 * N - 1, 0))); 2613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2621987afe7SBarry Smith } 2631987afe7SBarry Smith 264d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetInfo_SeqDense(Mat A, MatInfoType flag, MatInfo *info) 265d71ae5a4SJacob Faibussowitsch { 266ca15aa20SStefano Zampini PetscLogDouble N = A->rmap->n * A->cmap->n; 2673a40ed3dSBarry Smith 2683a40ed3dSBarry Smith PetscFunctionBegin; 2694e220ebcSLois Curfman McInnes info->block_size = 1.0; 270ca15aa20SStefano Zampini info->nz_allocated = N; 271ca15aa20SStefano Zampini info->nz_used = N; 272ca15aa20SStefano Zampini info->nz_unneeded = 0; 273ca15aa20SStefano Zampini info->assemblies = A->num_ass; 2744e220ebcSLois Curfman McInnes info->mallocs = 0; 2754dfa11a4SJacob Faibussowitsch info->memory = 0; /* REVIEW ME */ 2764e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 2774e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 2784e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 2793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 280289bc588SBarry Smith } 281289bc588SBarry Smith 282d71ae5a4SJacob Faibussowitsch PetscErrorCode MatScale_SeqDense(Mat A, PetscScalar alpha) 283d71ae5a4SJacob Faibussowitsch { 284273d9f13SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 285ca15aa20SStefano Zampini PetscScalar *v; 28623fff9afSBarry Smith PetscBLASInt one = 1, j, nz, lda = 0; 28780cd9d93SLois Curfman McInnes 2883a40ed3dSBarry Smith PetscFunctionBegin; 2899566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 2909566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(a->lda, &lda)); 291d0f46423SBarry Smith if (lda > A->rmap->n) { 2929566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &nz)); 29348a46eb9SPierre Jolivet for (j = 0; j < A->cmap->n; j++) PetscCallBLAS("BLASscal", BLASscal_(&nz, &alpha, v + j * lda, &one)); 294a5ce6ee0Svictorle } else { 2959566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n * A->cmap->n, &nz)); 296792fecdfSBarry Smith PetscCallBLAS("BLASscal", BLASscal_(&nz, &alpha, v, &one)); 297a5ce6ee0Svictorle } 29804cbc005SJose E. Roman PetscCall(PetscLogFlops(A->rmap->n * A->cmap->n)); 2999566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 3003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30180cd9d93SLois Curfman McInnes } 30280cd9d93SLois Curfman McInnes 303d71ae5a4SJacob Faibussowitsch PetscErrorCode MatShift_SeqDense(Mat A, PetscScalar alpha) 304d71ae5a4SJacob Faibussowitsch { 3052f605a99SJose E. Roman Mat_SeqDense *a = (Mat_SeqDense *)A->data; 3062f605a99SJose E. Roman PetscScalar *v; 3072f605a99SJose E. Roman PetscInt j, k; 3082f605a99SJose E. Roman 3092f605a99SJose E. Roman PetscFunctionBegin; 3102f605a99SJose E. Roman PetscCall(MatDenseGetArray(A, &v)); 3112f605a99SJose E. Roman k = PetscMin(A->rmap->n, A->cmap->n); 3122f605a99SJose E. Roman for (j = 0; j < k; j++) v[j + j * a->lda] += alpha; 3132f605a99SJose E. Roman PetscCall(PetscLogFlops(k)); 3142f605a99SJose E. Roman PetscCall(MatDenseRestoreArray(A, &v)); 3153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3162f605a99SJose E. Roman } 3172f605a99SJose E. Roman 318d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatIsHermitian_SeqDense(Mat A, PetscReal rtol, PetscBool *fl) 319d71ae5a4SJacob Faibussowitsch { 3201cbb95d3SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 321ca15aa20SStefano Zampini PetscInt i, j, m = A->rmap->n, N = a->lda; 322ca15aa20SStefano Zampini const PetscScalar *v; 3231cbb95d3SBarry Smith 3241cbb95d3SBarry Smith PetscFunctionBegin; 3251cbb95d3SBarry Smith *fl = PETSC_FALSE; 3263ba16761SJacob Faibussowitsch if (A->rmap->n != A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 3279566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 3281cbb95d3SBarry Smith for (i = 0; i < m; i++) { 329ca15aa20SStefano Zampini for (j = i; j < m; j++) { 330ad540459SPierre Jolivet if (PetscAbsScalar(v[i + j * N] - PetscConj(v[j + i * N])) > rtol) goto restore; 3311cbb95d3SBarry Smith } 332637a0070SStefano Zampini } 3331cbb95d3SBarry Smith *fl = PETSC_TRUE; 334637a0070SStefano Zampini restore: 3359566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 3363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 337637a0070SStefano Zampini } 338637a0070SStefano Zampini 339d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatIsSymmetric_SeqDense(Mat A, PetscReal rtol, PetscBool *fl) 340d71ae5a4SJacob Faibussowitsch { 341637a0070SStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 342637a0070SStefano Zampini PetscInt i, j, m = A->rmap->n, N = a->lda; 343637a0070SStefano Zampini const PetscScalar *v; 344637a0070SStefano Zampini 345637a0070SStefano Zampini PetscFunctionBegin; 346637a0070SStefano Zampini *fl = PETSC_FALSE; 3473ba16761SJacob Faibussowitsch if (A->rmap->n != A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 3489566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 349637a0070SStefano Zampini for (i = 0; i < m; i++) { 350637a0070SStefano Zampini for (j = i; j < m; j++) { 351ad540459SPierre Jolivet if (PetscAbsScalar(v[i + j * N] - v[j + i * N]) > rtol) goto restore; 352637a0070SStefano Zampini } 353637a0070SStefano Zampini } 354637a0070SStefano Zampini *fl = PETSC_TRUE; 355637a0070SStefano Zampini restore: 3569566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 3573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3581cbb95d3SBarry Smith } 3591cbb95d3SBarry Smith 360d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi, Mat A, MatDuplicateOption cpvalues) 361d71ae5a4SJacob Faibussowitsch { 362ca15aa20SStefano Zampini Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 36323fc5dcaSStefano Zampini PetscInt lda = (PetscInt)mat->lda, j, m, nlda = lda; 36475f6d85dSStefano Zampini PetscBool isdensecpu; 365b24902e0SBarry Smith 366b24902e0SBarry Smith PetscFunctionBegin; 3679566063dSJacob Faibussowitsch PetscCall(PetscLayoutReference(A->rmap, &newi->rmap)); 3689566063dSJacob Faibussowitsch PetscCall(PetscLayoutReference(A->cmap, &newi->cmap)); 36923fc5dcaSStefano Zampini if (cpvalues == MAT_SHARE_NONZERO_PATTERN) { /* propagate LDA */ 3709566063dSJacob Faibussowitsch PetscCall(MatDenseSetLDA(newi, lda)); 37123fc5dcaSStefano Zampini } 3729566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)newi, MATSEQDENSE, &isdensecpu)); 3739566063dSJacob Faibussowitsch if (isdensecpu) PetscCall(MatSeqDenseSetPreallocation(newi, NULL)); 374b24902e0SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 375ca15aa20SStefano Zampini const PetscScalar *av; 376ca15aa20SStefano Zampini PetscScalar *v; 377ca15aa20SStefano Zampini 3789566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 3799566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(newi, &v)); 3809566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(newi, &nlda)); 381d0f46423SBarry Smith m = A->rmap->n; 38223fc5dcaSStefano Zampini if (lda > m || nlda > m) { 38348a46eb9SPierre Jolivet for (j = 0; j < A->cmap->n; j++) PetscCall(PetscArraycpy(v + j * nlda, av + j * lda, m)); 384b24902e0SBarry Smith } else { 3859566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(v, av, A->rmap->n * A->cmap->n)); 386b24902e0SBarry Smith } 3879566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(newi, &v)); 3889566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 389b24902e0SBarry Smith } 3903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 391b24902e0SBarry Smith } 392b24902e0SBarry Smith 393d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDuplicate_SeqDense(Mat A, MatDuplicateOption cpvalues, Mat *newmat) 394d71ae5a4SJacob Faibussowitsch { 3953a40ed3dSBarry Smith PetscFunctionBegin; 3969566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), newmat)); 3979566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*newmat, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n)); 3989566063dSJacob Faibussowitsch PetscCall(MatSetType(*newmat, ((PetscObject)A)->type_name)); 3999566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(*newmat, A, cpvalues)); 4003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 401b24902e0SBarry Smith } 402b24902e0SBarry Smith 403d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_LU(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T) 404d71ae5a4SJacob Faibussowitsch { 405c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4064396437dSToby Isaac PetscBLASInt info; 40767e560aaSBarry Smith 4083a40ed3dSBarry Smith PetscFunctionBegin; 4099566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 410792fecdfSBarry Smith PetscCallBLAS("LAPACKgetrs", LAPACKgetrs_(T ? "T" : "N", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info)); 4119566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 41205fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "GETRS - Bad solve %d", (int)info); 4139566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m))); 4143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4154396437dSToby Isaac } 4164396437dSToby Isaac 4174396437dSToby Isaac static PetscErrorCode MatConjugate_SeqDense(Mat); 4184396437dSToby Isaac 419d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_Cholesky(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T) 420d71ae5a4SJacob Faibussowitsch { 4214396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4224396437dSToby Isaac PetscBLASInt info; 4234396437dSToby Isaac 4244396437dSToby Isaac PetscFunctionBegin; 425b94d7dedSBarry Smith if (A->spd == PETSC_BOOL3_TRUE) { 4269566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A)); 4279566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 428792fecdfSBarry Smith PetscCallBLAS("LAPACKpotrs", LAPACKpotrs_("L", &m, &nrhs, mat->v, &mat->lda, x, &m, &info)); 4299566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 43005fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "POTRS Bad solve %d", (int)info); 4319566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A)); 432a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX) 433b94d7dedSBarry Smith } else if (A->hermitian == PETSC_BOOL3_TRUE) { 4349566063dSJacob Faibussowitsch if (T) PetscCall(MatConjugate_SeqDense(A)); 4359566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 436792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrs", LAPACKhetrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info)); 4379566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 43805fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "HETRS Bad solve %d", (int)info); 4399566063dSJacob Faibussowitsch if (T) PetscCall(MatConjugate_SeqDense(A)); 440a49dc2a2SStefano Zampini #endif 441a49dc2a2SStefano Zampini } else { /* symmetric case */ 4429566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 443792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrs", LAPACKsytrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info)); 4449566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 44505fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "SYTRS Bad solve %d", (int)info); 446a49dc2a2SStefano Zampini } 4479566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m))); 4483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4494396437dSToby Isaac } 45085e2c93fSHong Zhang 451d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k) 452d71ae5a4SJacob Faibussowitsch { 4534396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4544396437dSToby Isaac PetscBLASInt info; 4554396437dSToby Isaac char trans; 4564396437dSToby Isaac 4574396437dSToby Isaac PetscFunctionBegin; 4584905a7bcSToby Isaac if (PetscDefined(USE_COMPLEX)) { 4594905a7bcSToby Isaac trans = 'C'; 4604905a7bcSToby Isaac } else { 4614905a7bcSToby Isaac trans = 'T'; 4624905a7bcSToby Isaac } 4639566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 46405fcb23eSStefano Zampini { /* lwork depends on the number of right-hand sides */ 46505fcb23eSStefano Zampini PetscBLASInt nlfwork, lfwork = -1; 46605fcb23eSStefano Zampini PetscScalar fwork; 46705fcb23eSStefano Zampini 468792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info)); 46905fcb23eSStefano Zampini nlfwork = (PetscBLASInt)PetscRealPart(fwork); 47005fcb23eSStefano Zampini if (nlfwork > mat->lfwork) { 47105fcb23eSStefano Zampini mat->lfwork = nlfwork; 47205fcb23eSStefano Zampini PetscCall(PetscFree(mat->fwork)); 47305fcb23eSStefano Zampini PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 47405fcb23eSStefano Zampini } 47505fcb23eSStefano Zampini } 476792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info)); 4779566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 47805fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %d", (int)info); 4799566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 480792fecdfSBarry Smith PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "N", "N", &mat->rank, &nrhs, mat->v, &mat->lda, x, &ldx, &info)); 4819566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 48205fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %d", (int)info); 4834905a7bcSToby Isaac for (PetscInt j = 0; j < nrhs; j++) { 484ad540459SPierre Jolivet for (PetscInt i = mat->rank; i < k; i++) x[j * ldx + i] = 0.; 4854905a7bcSToby Isaac } 4869566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank)))); 4873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4884905a7bcSToby Isaac } 4894905a7bcSToby Isaac 490d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k) 491d71ae5a4SJacob Faibussowitsch { 4924396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4934396437dSToby Isaac PetscBLASInt info; 4944396437dSToby Isaac 4954396437dSToby Isaac PetscFunctionBegin; 4964396437dSToby Isaac if (A->rmap->n == A->cmap->n && mat->rank == A->rmap->n) { 4979566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 498792fecdfSBarry Smith PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "T", "N", &m, &nrhs, mat->v, &mat->lda, x, &ldx, &info)); 4999566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 50005fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %d", (int)info); 5019566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A)); 50205fcb23eSStefano Zampini { /* lwork depends on the number of right-hand sides */ 50305fcb23eSStefano Zampini PetscBLASInt nlfwork, lfwork = -1; 50405fcb23eSStefano Zampini PetscScalar fwork; 50505fcb23eSStefano Zampini 506792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info)); 50705fcb23eSStefano Zampini nlfwork = (PetscBLASInt)PetscRealPart(fwork); 50805fcb23eSStefano Zampini if (nlfwork > mat->lfwork) { 50905fcb23eSStefano Zampini mat->lfwork = nlfwork; 51005fcb23eSStefano Zampini PetscCall(PetscFree(mat->fwork)); 51105fcb23eSStefano Zampini PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 51205fcb23eSStefano Zampini } 51305fcb23eSStefano Zampini } 5149566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 515792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info)); 5169566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 51705fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %d", (int)info); 5189566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A)); 5194396437dSToby Isaac } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "QR factored matrix cannot be used for transpose solve"); 5209566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank)))); 5213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5224396437dSToby Isaac } 5234396437dSToby Isaac 524d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_SetUp(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k) 525d71ae5a4SJacob Faibussowitsch { 5264396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 5274905a7bcSToby Isaac PetscScalar *y; 5284905a7bcSToby Isaac PetscBLASInt m = 0, k = 0; 5294905a7bcSToby Isaac 5304905a7bcSToby Isaac PetscFunctionBegin; 5319566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 5329566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 5334905a7bcSToby Isaac if (k < m) { 5349566063dSJacob Faibussowitsch PetscCall(VecCopy(xx, mat->qrrhs)); 5359566063dSJacob Faibussowitsch PetscCall(VecGetArray(mat->qrrhs, &y)); 5364905a7bcSToby Isaac } else { 5379566063dSJacob Faibussowitsch PetscCall(VecCopy(xx, yy)); 5389566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &y)); 5394905a7bcSToby Isaac } 5404396437dSToby Isaac *_y = y; 5414396437dSToby Isaac *_k = k; 5424396437dSToby Isaac *_m = m; 5433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5444396437dSToby Isaac } 5454396437dSToby Isaac 546d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_TearDown(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k) 547d71ae5a4SJacob Faibussowitsch { 5484396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 54942e9364cSSatish Balay PetscScalar *y = NULL; 5504396437dSToby Isaac PetscBLASInt m, k; 5514396437dSToby Isaac 5524396437dSToby Isaac PetscFunctionBegin; 5534396437dSToby Isaac y = *_y; 5544396437dSToby Isaac *_y = NULL; 5554396437dSToby Isaac k = *_k; 5564396437dSToby Isaac m = *_m; 5574905a7bcSToby Isaac if (k < m) { 5584905a7bcSToby Isaac PetscScalar *yv; 5599566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &yv)); 5609566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(yv, y, k)); 5619566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &yv)); 5629566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(mat->qrrhs, &y)); 5634905a7bcSToby Isaac } else { 5649566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &y)); 5654905a7bcSToby Isaac } 5663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5674905a7bcSToby Isaac } 5684905a7bcSToby Isaac 569d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_LU(Mat A, Vec xx, Vec yy) 570d71ae5a4SJacob Faibussowitsch { 57142e9364cSSatish Balay PetscScalar *y = NULL; 57242e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 5734396437dSToby Isaac 5744396437dSToby Isaac PetscFunctionBegin; 5759566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 5769566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_FALSE)); 5779566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 5783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5794396437dSToby Isaac } 5804396437dSToby Isaac 581d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_LU(Mat A, Vec xx, Vec yy) 582d71ae5a4SJacob Faibussowitsch { 58342e9364cSSatish Balay PetscScalar *y = NULL; 58442e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 5854396437dSToby Isaac 5864396437dSToby Isaac PetscFunctionBegin; 5879566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 5889566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_TRUE)); 5899566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 5903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5914396437dSToby Isaac } 5924396437dSToby Isaac 593d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Cholesky(Mat A, Vec xx, Vec yy) 594d71ae5a4SJacob Faibussowitsch { 595e54beecaSStefano Zampini PetscScalar *y = NULL; 596e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 5974396437dSToby Isaac 5984396437dSToby Isaac PetscFunctionBegin; 5999566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6009566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_FALSE)); 6019566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6034396437dSToby Isaac } 6044396437dSToby Isaac 605d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_Cholesky(Mat A, Vec xx, Vec yy) 606d71ae5a4SJacob Faibussowitsch { 607e54beecaSStefano Zampini PetscScalar *y = NULL; 608e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 6094396437dSToby Isaac 6104396437dSToby Isaac PetscFunctionBegin; 6119566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6129566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_TRUE)); 6139566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6154396437dSToby Isaac } 6164396437dSToby Isaac 617d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_QR(Mat A, Vec xx, Vec yy) 618d71ae5a4SJacob Faibussowitsch { 619e54beecaSStefano Zampini PetscScalar *y = NULL; 620e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 6214396437dSToby Isaac 6224396437dSToby Isaac PetscFunctionBegin; 6239566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6249566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k)); 6259566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6274396437dSToby Isaac } 6284396437dSToby Isaac 629d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_QR(Mat A, Vec xx, Vec yy) 630d71ae5a4SJacob Faibussowitsch { 63142e9364cSSatish Balay PetscScalar *y = NULL; 63242e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 6334396437dSToby Isaac 6344396437dSToby Isaac PetscFunctionBegin; 6359566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6369566063dSJacob Faibussowitsch PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k)); 6379566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6394396437dSToby Isaac } 6404396437dSToby Isaac 641d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_SetUp(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k) 642d71ae5a4SJacob Faibussowitsch { 6434905a7bcSToby Isaac const PetscScalar *b; 6444396437dSToby Isaac PetscScalar *y; 645bf5a80bcSToby Isaac PetscInt n, _ldb, _ldx; 646bf5a80bcSToby Isaac PetscBLASInt nrhs = 0, m = 0, k = 0, ldb = 0, ldx = 0, ldy = 0; 6474905a7bcSToby Isaac 6484905a7bcSToby Isaac PetscFunctionBegin; 6499371c9d4SSatish Balay *_ldy = 0; 6509371c9d4SSatish Balay *_m = 0; 6519371c9d4SSatish Balay *_nrhs = 0; 6529371c9d4SSatish Balay *_k = 0; 6539371c9d4SSatish Balay *_y = NULL; 6549566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 6559566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 6569566063dSJacob Faibussowitsch PetscCall(MatGetSize(B, NULL, &n)); 6579566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(n, &nrhs)); 6589566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(B, &_ldb)); 6599566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldb, &ldb)); 6609566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(X, &_ldx)); 6619566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldx, &ldx)); 662bf5a80bcSToby Isaac if (ldx < m) { 6639566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &b)); 6649566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nrhs * m, &y)); 665bf5a80bcSToby Isaac if (ldb == m) { 6669566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(y, b, ldb * nrhs)); 6674905a7bcSToby Isaac } else { 66848a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * m], &b[j * ldb], m)); 6694905a7bcSToby Isaac } 670bf5a80bcSToby Isaac ldy = m; 6719566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &b)); 6724905a7bcSToby Isaac } else { 673bf5a80bcSToby Isaac if (ldb == ldx) { 6749566063dSJacob Faibussowitsch PetscCall(MatCopy(B, X, SAME_NONZERO_PATTERN)); 6759566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &y)); 6764905a7bcSToby Isaac } else { 6779566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &y)); 6789566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &b)); 67948a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * ldx], &b[j * ldb], m)); 6809566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &b)); 6814905a7bcSToby Isaac } 682bf5a80bcSToby Isaac ldy = ldx; 6834905a7bcSToby Isaac } 6844396437dSToby Isaac *_y = y; 685bf5a80bcSToby Isaac *_ldy = ldy; 6864396437dSToby Isaac *_k = k; 6874396437dSToby Isaac *_m = m; 6884396437dSToby Isaac *_nrhs = nrhs; 6893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6904396437dSToby Isaac } 6914396437dSToby Isaac 692d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_TearDown(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k) 693d71ae5a4SJacob Faibussowitsch { 6944396437dSToby Isaac PetscScalar *y; 695bf5a80bcSToby Isaac PetscInt _ldx; 696bf5a80bcSToby Isaac PetscBLASInt k, ldy, nrhs, ldx = 0; 6974396437dSToby Isaac 6984396437dSToby Isaac PetscFunctionBegin; 6994396437dSToby Isaac y = *_y; 7004396437dSToby Isaac *_y = NULL; 7014396437dSToby Isaac k = *_k; 702bf5a80bcSToby Isaac ldy = *_ldy; 7034396437dSToby Isaac nrhs = *_nrhs; 7049566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(X, &_ldx)); 7059566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldx, &ldx)); 706bf5a80bcSToby Isaac if (ldx != ldy) { 7074905a7bcSToby Isaac PetscScalar *xv; 7089566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &xv)); 70948a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&xv[j * ldx], &y[j * ldy], k)); 7109566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(X, &xv)); 7119566063dSJacob Faibussowitsch PetscCall(PetscFree(y)); 7124905a7bcSToby Isaac } else { 7139566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(X, &y)); 7144905a7bcSToby Isaac } 7153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 71685e2c93fSHong Zhang } 71785e2c93fSHong Zhang 718d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_LU(Mat A, Mat B, Mat X) 719d71ae5a4SJacob Faibussowitsch { 7204396437dSToby Isaac PetscScalar *y; 721bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7224396437dSToby Isaac 7234396437dSToby Isaac PetscFunctionBegin; 7249566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7259566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_FALSE)); 7269566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7284396437dSToby Isaac } 7294396437dSToby Isaac 730d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_LU(Mat A, Mat B, Mat X) 731d71ae5a4SJacob Faibussowitsch { 7324396437dSToby Isaac PetscScalar *y; 733bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7344396437dSToby Isaac 7354396437dSToby Isaac PetscFunctionBegin; 7369566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7379566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_TRUE)); 7389566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7404396437dSToby Isaac } 7414396437dSToby Isaac 742d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_Cholesky(Mat A, Mat B, Mat X) 743d71ae5a4SJacob Faibussowitsch { 7444396437dSToby Isaac PetscScalar *y; 745bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7464396437dSToby Isaac 7474396437dSToby Isaac PetscFunctionBegin; 7489566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7499566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_FALSE)); 7509566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7524396437dSToby Isaac } 7534396437dSToby Isaac 754d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_Cholesky(Mat A, Mat B, Mat X) 755d71ae5a4SJacob Faibussowitsch { 7564396437dSToby Isaac PetscScalar *y; 757bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7584396437dSToby Isaac 7594396437dSToby Isaac PetscFunctionBegin; 7609566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7619566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_TRUE)); 7629566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7644396437dSToby Isaac } 7654396437dSToby Isaac 766d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_QR(Mat A, Mat B, Mat X) 767d71ae5a4SJacob Faibussowitsch { 7684396437dSToby Isaac PetscScalar *y; 769bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7704396437dSToby Isaac 7714396437dSToby Isaac PetscFunctionBegin; 7729566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7739566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k)); 7749566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7764396437dSToby Isaac } 7774396437dSToby Isaac 778d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_QR(Mat A, Mat B, Mat X) 779d71ae5a4SJacob Faibussowitsch { 7804396437dSToby Isaac PetscScalar *y; 781bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7824396437dSToby Isaac 7834396437dSToby Isaac PetscFunctionBegin; 7849566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7859566063dSJacob Faibussowitsch PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k)); 7869566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7884396437dSToby Isaac } 7894396437dSToby Isaac 790db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots, 791db4efbfdSBarry Smith rather than put it in the Mat->row slot.*/ 792d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLUFactor_SeqDense(Mat A, IS row, IS col, const MatFactorInfo *minfo) 793d71ae5a4SJacob Faibussowitsch { 794db4efbfdSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 795db4efbfdSBarry Smith PetscBLASInt n, m, info; 796db4efbfdSBarry Smith 797db4efbfdSBarry Smith PetscFunctionBegin; 7989566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 7999566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 8004dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); } 8013ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 8029566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 803792fecdfSBarry Smith PetscCallBLAS("LAPACKgetrf", LAPACKgetrf_(&m, &n, mat->v, &mat->lda, mat->pivots, &info)); 8049566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 8058e57ea43SSatish Balay 80605fcb23eSStefano Zampini PetscCheck(info >= 0, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to LU factorization %d", (int)info); 80705fcb23eSStefano Zampini PetscCheck(info <= 0, PETSC_COMM_SELF, PETSC_ERR_MAT_LU_ZRPVT, "Bad LU factorization %d", (int)info); 8088208b9aeSStefano Zampini 8094396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_LU; 8104396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_LU; 8114396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_LU; 8124396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_LU; 813d5f3da31SBarry Smith A->factortype = MAT_FACTOR_LU; 814db4efbfdSBarry Smith 8159566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 8169566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 817f6224b95SHong Zhang 8189566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((2.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3)); 8193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 820db4efbfdSBarry Smith } 821db4efbfdSBarry Smith 822d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) 823d71ae5a4SJacob Faibussowitsch { 8244396437dSToby Isaac MatFactorInfo info; 8254396437dSToby Isaac 8264396437dSToby Isaac PetscFunctionBegin; 8279566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 828dbbe0bcdSBarry Smith PetscUseTypeMethod(fact, lufactor, NULL, NULL, &info); 8293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8304396437dSToby Isaac } 8314396437dSToby Isaac 832d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, IS col, const MatFactorInfo *info) 833d71ae5a4SJacob Faibussowitsch { 8344396437dSToby Isaac PetscFunctionBegin; 8354396437dSToby Isaac fact->preallocated = PETSC_TRUE; 8364396437dSToby Isaac fact->assembled = PETSC_TRUE; 8374396437dSToby Isaac fact->ops->lufactornumeric = MatLUFactorNumeric_SeqDense; 8383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8394396437dSToby Isaac } 8404396437dSToby Isaac 841a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */ 842d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCholeskyFactor_SeqDense(Mat A, IS perm, const MatFactorInfo *factinfo) 843d71ae5a4SJacob Faibussowitsch { 844db4efbfdSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 845c5df96a5SBarry Smith PetscBLASInt info, n; 846db4efbfdSBarry Smith 847db4efbfdSBarry Smith PetscFunctionBegin; 8489566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 8493ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 850b94d7dedSBarry Smith if (A->spd == PETSC_BOOL3_TRUE) { 8519566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 852792fecdfSBarry Smith PetscCallBLAS("LAPACKpotrf", LAPACKpotrf_("L", &n, mat->v, &mat->lda, &info)); 8539566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 854a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX) 855b94d7dedSBarry Smith } else if (A->hermitian == PETSC_BOOL3_TRUE) { 8564dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); } 857a49dc2a2SStefano Zampini if (!mat->fwork) { 858a49dc2a2SStefano Zampini PetscScalar dummy; 859a49dc2a2SStefano Zampini 860a49dc2a2SStefano Zampini mat->lfwork = -1; 8619566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 862792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info)); 8639566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 864a49dc2a2SStefano Zampini mat->lfwork = (PetscInt)PetscRealPart(dummy); 8659566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 866a49dc2a2SStefano Zampini } 8679566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 868792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info)); 8699566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 870a49dc2a2SStefano Zampini #endif 871a49dc2a2SStefano Zampini } else { /* symmetric case */ 8724dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); } 873a49dc2a2SStefano Zampini if (!mat->fwork) { 874a49dc2a2SStefano Zampini PetscScalar dummy; 875a49dc2a2SStefano Zampini 876a49dc2a2SStefano Zampini mat->lfwork = -1; 8779566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 878792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info)); 8799566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 880a49dc2a2SStefano Zampini mat->lfwork = (PetscInt)PetscRealPart(dummy); 8819566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 882a49dc2a2SStefano Zampini } 8839566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 884792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info)); 8859566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 886a49dc2a2SStefano Zampini } 88728b400f6SJacob Faibussowitsch PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad factorization: zero pivot in row %" PetscInt_FMT, (PetscInt)info - 1); 8888208b9aeSStefano Zampini 8894396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_Cholesky; 8904396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_Cholesky; 8914396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_Cholesky; 8924396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_Cholesky; 893d5f3da31SBarry Smith A->factortype = MAT_FACTOR_CHOLESKY; 8942205254eSKarl Rupp 8959566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 8969566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 897f6224b95SHong Zhang 8989566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0)); 8993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 900db4efbfdSBarry Smith } 901db4efbfdSBarry Smith 902d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) 903d71ae5a4SJacob Faibussowitsch { 904db4efbfdSBarry Smith MatFactorInfo info; 905db4efbfdSBarry Smith 906db4efbfdSBarry Smith PetscFunctionBegin; 907db4efbfdSBarry Smith info.fill = 1.0; 9082205254eSKarl Rupp 9099566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 910dbbe0bcdSBarry Smith PetscUseTypeMethod(fact, choleskyfactor, NULL, &info); 9113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 912db4efbfdSBarry Smith } 913db4efbfdSBarry Smith 914d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info) 915d71ae5a4SJacob Faibussowitsch { 916db4efbfdSBarry Smith PetscFunctionBegin; 917c3ef05f6SHong Zhang fact->assembled = PETSC_TRUE; 9181bbcc794SSatish Balay fact->preallocated = PETSC_TRUE; 919719d5645SBarry Smith fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense; 9203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 921db4efbfdSBarry Smith } 922db4efbfdSBarry Smith 923d71ae5a4SJacob Faibussowitsch PetscErrorCode MatQRFactor_SeqDense(Mat A, IS col, const MatFactorInfo *minfo) 924d71ae5a4SJacob Faibussowitsch { 9254905a7bcSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 9264905a7bcSToby Isaac PetscBLASInt n, m, info, min, max; 9274905a7bcSToby Isaac 9284905a7bcSToby Isaac PetscFunctionBegin; 9299566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 9309566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 9314396437dSToby Isaac max = PetscMax(m, n); 9324396437dSToby Isaac min = PetscMin(m, n); 9334dfa11a4SJacob Faibussowitsch if (!mat->tau) { PetscCall(PetscMalloc1(min, &mat->tau)); } 9344dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(n, &mat->pivots)); } 93548a46eb9SPierre Jolivet if (!mat->qrrhs) PetscCall(MatCreateVecs(A, NULL, &(mat->qrrhs))); 9363ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 9374905a7bcSToby Isaac if (!mat->fwork) { 9384905a7bcSToby Isaac PetscScalar dummy; 9394905a7bcSToby Isaac 9404905a7bcSToby Isaac mat->lfwork = -1; 9419566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 942792fecdfSBarry Smith PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, &dummy, &mat->lfwork, &info)); 9439566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 9444905a7bcSToby Isaac mat->lfwork = (PetscInt)PetscRealPart(dummy); 9459566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 9464905a7bcSToby Isaac } 9479566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 948792fecdfSBarry Smith PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, mat->fwork, &mat->lfwork, &info)); 9499566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 95005fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to QR factorization %d", (int)info); 9514905a7bcSToby Isaac // TODO: try to estimate rank or test for and use geqp3 for rank revealing QR. For now just say rank is min of m and n 9524905a7bcSToby Isaac mat->rank = min; 9534905a7bcSToby Isaac 9544396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_QR; 9554396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_QR; 9564905a7bcSToby Isaac A->factortype = MAT_FACTOR_QR; 9574905a7bcSToby Isaac if (m == n) { 9584396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_QR; 9594396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_QR; 9604905a7bcSToby Isaac } 9614905a7bcSToby Isaac 9629566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 9639566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 9644905a7bcSToby Isaac 9659566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * min * min * (max - min / 3.0))); 9663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9674905a7bcSToby Isaac } 9684905a7bcSToby Isaac 969d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatQRFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) 970d71ae5a4SJacob Faibussowitsch { 9714905a7bcSToby Isaac MatFactorInfo info; 9724905a7bcSToby Isaac 9734905a7bcSToby Isaac PetscFunctionBegin; 9744905a7bcSToby Isaac info.fill = 1.0; 9754905a7bcSToby Isaac 9769566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 977cac4c232SBarry Smith PetscUseMethod(fact, "MatQRFactor_C", (Mat, IS, const MatFactorInfo *), (fact, NULL, &info)); 9783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9794905a7bcSToby Isaac } 9804905a7bcSToby Isaac 981d71ae5a4SJacob Faibussowitsch PetscErrorCode MatQRFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info) 982d71ae5a4SJacob Faibussowitsch { 9834905a7bcSToby Isaac PetscFunctionBegin; 9844905a7bcSToby Isaac fact->assembled = PETSC_TRUE; 9854905a7bcSToby Isaac fact->preallocated = PETSC_TRUE; 9869566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)fact, "MatQRFactorNumeric_C", MatQRFactorNumeric_SeqDense)); 9873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9884905a7bcSToby Isaac } 9894905a7bcSToby Isaac 990ca15aa20SStefano Zampini /* uses LAPACK */ 991d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A, MatFactorType ftype, Mat *fact) 992d71ae5a4SJacob Faibussowitsch { 993db4efbfdSBarry Smith PetscFunctionBegin; 9949566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), fact)); 9959566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*fact, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n)); 9969566063dSJacob Faibussowitsch PetscCall(MatSetType(*fact, MATDENSE)); 99766e17bc3SBarry Smith (*fact)->trivialsymbolic = PETSC_TRUE; 9982a350339SBarry Smith if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU) { 999db4efbfdSBarry Smith (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense; 10002a350339SBarry Smith (*fact)->ops->ilufactorsymbolic = MatLUFactorSymbolic_SeqDense; 1001bf5a80bcSToby Isaac } else if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) { 1002db4efbfdSBarry Smith (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense; 1003bf5a80bcSToby Isaac } else if (ftype == MAT_FACTOR_QR) { 10049566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)(*fact), "MatQRFactorSymbolic_C", MatQRFactorSymbolic_SeqDense)); 1005db4efbfdSBarry Smith } 1006d5f3da31SBarry Smith (*fact)->factortype = ftype; 100700c67f3bSHong Zhang 10089566063dSJacob Faibussowitsch PetscCall(PetscFree((*fact)->solvertype)); 10099566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &(*fact)->solvertype)); 10109566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_LU])); 10119566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ILU])); 10129566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_CHOLESKY])); 10139566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ICC])); 10143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1015db4efbfdSBarry Smith } 1016db4efbfdSBarry Smith 1017d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSOR_SeqDense(Mat A, Vec bb, PetscReal omega, MatSORType flag, PetscReal shift, PetscInt its, PetscInt lits, Vec xx) 1018d71ae5a4SJacob Faibussowitsch { 1019c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1020d9ca1df4SBarry Smith PetscScalar *x, *v = mat->v, zero = 0.0, xt; 1021d9ca1df4SBarry Smith const PetscScalar *b; 1022d0f46423SBarry Smith PetscInt m = A->rmap->n, i; 102323fff9afSBarry Smith PetscBLASInt o = 1, bm = 0; 1024289bc588SBarry Smith 10253a40ed3dSBarry Smith PetscFunctionBegin; 102647d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 102708401ef6SPierre Jolivet PetscCheck(A->offloadmask != PETSC_OFFLOAD_GPU, PETSC_COMM_SELF, PETSC_ERR_SUP, "Not implemented"); 1028ca15aa20SStefano Zampini #endif 1029422a814eSBarry Smith if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */ 10309566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(m, &bm)); 1031289bc588SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 10323bffc371SBarry Smith /* this is a hack fix, should have another version without the second BLASdotu */ 10339566063dSJacob Faibussowitsch PetscCall(VecSet(xx, zero)); 1034289bc588SBarry Smith } 10359566063dSJacob Faibussowitsch PetscCall(VecGetArray(xx, &x)); 10369566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(bb, &b)); 1037b965ef7fSBarry Smith its = its * lits; 103808401ef6SPierre Jolivet PetscCheck(its > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Relaxation requires global its %" PetscInt_FMT " and local its %" PetscInt_FMT " both positive", its, lits); 1039289bc588SBarry Smith while (its--) { 1040fccaa45eSBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 1041289bc588SBarry Smith for (i = 0; i < m; i++) { 1042792fecdfSBarry Smith PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o)); 104355a1b374SBarry Smith x[i] = (1. - omega) * x[i] + omega * (xt + v[i + i * m] * x[i]) / (v[i + i * m] + shift); 1044289bc588SBarry Smith } 1045289bc588SBarry Smith } 1046fccaa45eSBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 1047289bc588SBarry Smith for (i = m - 1; i >= 0; i--) { 1048792fecdfSBarry Smith PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o)); 104955a1b374SBarry Smith x[i] = (1. - omega) * x[i] + omega * (xt + v[i + i * m] * x[i]) / (v[i + i * m] + shift); 1050289bc588SBarry Smith } 1051289bc588SBarry Smith } 1052289bc588SBarry Smith } 10539566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(bb, &b)); 10549566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(xx, &x)); 10553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1056289bc588SBarry Smith } 1057289bc588SBarry Smith 1058d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultTranspose_SeqDense(Mat A, Vec xx, Vec yy) 1059d71ae5a4SJacob Faibussowitsch { 1060c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1061d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 1062d9ca1df4SBarry Smith PetscScalar *y; 10630805154bSBarry Smith PetscBLASInt m, n, _One = 1; 1064ea709b57SSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 10653a40ed3dSBarry Smith 10663a40ed3dSBarry Smith PetscFunctionBegin; 10679566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 10689566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 10699566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 10709566063dSJacob Faibussowitsch PetscCall(VecGetArrayWrite(yy, &y)); 10715ac36cfcSBarry Smith if (!A->rmap->n || !A->cmap->n) { 10725ac36cfcSBarry Smith PetscBLASInt i; 10735ac36cfcSBarry Smith for (i = 0; i < n; i++) y[i] = 0.0; 10745ac36cfcSBarry Smith } else { 1075792fecdfSBarry Smith PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v, &mat->lda, x, &_One, &_DZero, y, &_One)); 10769566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n - A->cmap->n)); 10775ac36cfcSBarry Smith } 10789566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 10799566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayWrite(yy, &y)); 10803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1081289bc588SBarry Smith } 1082800995b7SMatthew Knepley 1083d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMult_SeqDense(Mat A, Vec xx, Vec yy) 1084d71ae5a4SJacob Faibussowitsch { 1085c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1086d9ca1df4SBarry Smith PetscScalar *y, _DOne = 1.0, _DZero = 0.0; 10870805154bSBarry Smith PetscBLASInt m, n, _One = 1; 1088d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 10893a40ed3dSBarry Smith 10903a40ed3dSBarry Smith PetscFunctionBegin; 10919566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 10929566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 10939566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 10949566063dSJacob Faibussowitsch PetscCall(VecGetArrayWrite(yy, &y)); 10955ac36cfcSBarry Smith if (!A->rmap->n || !A->cmap->n) { 10965ac36cfcSBarry Smith PetscBLASInt i; 10975ac36cfcSBarry Smith for (i = 0; i < m; i++) y[i] = 0.0; 10985ac36cfcSBarry Smith } else { 1099792fecdfSBarry Smith PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DZero, y, &_One)); 11009566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n - A->rmap->n)); 11015ac36cfcSBarry Smith } 11029566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 11039566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayWrite(yy, &y)); 11043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1105289bc588SBarry Smith } 11066ee01492SSatish Balay 1107d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) 1108d71ae5a4SJacob Faibussowitsch { 1109c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1110d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 1111d9ca1df4SBarry Smith PetscScalar *y, _DOne = 1.0; 11120805154bSBarry Smith PetscBLASInt m, n, _One = 1; 11133a40ed3dSBarry Smith 11143a40ed3dSBarry Smith PetscFunctionBegin; 11159566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 11169566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 11179566063dSJacob Faibussowitsch PetscCall(VecCopy(zz, yy)); 11183ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 11199566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 11209566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &y)); 1121792fecdfSBarry Smith PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DOne, y, &_One)); 11229566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 11239566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &y)); 11249566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n)); 11253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1126289bc588SBarry Smith } 11276ee01492SSatish Balay 1128d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) 1129d71ae5a4SJacob Faibussowitsch { 1130c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1131d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 1132d9ca1df4SBarry Smith PetscScalar *y; 11330805154bSBarry Smith PetscBLASInt m, n, _One = 1; 113487828ca2SBarry Smith PetscScalar _DOne = 1.0; 11353a40ed3dSBarry Smith 11363a40ed3dSBarry Smith PetscFunctionBegin; 11379566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 11389566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 11399566063dSJacob Faibussowitsch PetscCall(VecCopy(zz, yy)); 11403ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 11419566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 11429566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &y)); 1143792fecdfSBarry Smith PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DOne, y, &_One)); 11449566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 11459566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &y)); 11469566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n)); 11473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1148289bc588SBarry Smith } 1149289bc588SBarry Smith 1150d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals) 1151d71ae5a4SJacob Faibussowitsch { 1152c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 115313f74950SBarry Smith PetscInt i; 115467e560aaSBarry Smith 11553a40ed3dSBarry Smith PetscFunctionBegin; 1156d0f46423SBarry Smith *ncols = A->cmap->n; 1157289bc588SBarry Smith if (cols) { 11589566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->cmap->n, cols)); 1159d0f46423SBarry Smith for (i = 0; i < A->cmap->n; i++) (*cols)[i] = i; 1160289bc588SBarry Smith } 1161289bc588SBarry Smith if (vals) { 1162ca15aa20SStefano Zampini const PetscScalar *v; 1163ca15aa20SStefano Zampini 11649566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 11659566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->cmap->n, vals)); 1166ca15aa20SStefano Zampini v += row; 11679371c9d4SSatish Balay for (i = 0; i < A->cmap->n; i++) { 11689371c9d4SSatish Balay (*vals)[i] = *v; 11699371c9d4SSatish Balay v += mat->lda; 11709371c9d4SSatish Balay } 11719566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 1172289bc588SBarry Smith } 11733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1174289bc588SBarry Smith } 11756ee01492SSatish Balay 1176d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRestoreRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals) 1177d71ae5a4SJacob Faibussowitsch { 1178606d414cSSatish Balay PetscFunctionBegin; 1179cb4a9cd9SHong Zhang if (ncols) *ncols = 0; 11809566063dSJacob Faibussowitsch if (cols) PetscCall(PetscFree(*cols)); 11819566063dSJacob Faibussowitsch if (vals) PetscCall(PetscFree(*vals)); 11823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1183289bc588SBarry Smith } 11842ef1f0ffSBarry Smith 1185d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], const PetscScalar v[], InsertMode addv) 1186d71ae5a4SJacob Faibussowitsch { 1187c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1188ca15aa20SStefano Zampini PetscScalar *av; 118913f74950SBarry Smith PetscInt i, j, idx = 0; 119047d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1191c70f7ee4SJunchao Zhang PetscOffloadMask oldf; 1192ca15aa20SStefano Zampini #endif 1193d6dfbf8fSBarry Smith 11943a40ed3dSBarry Smith PetscFunctionBegin; 11959566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &av)); 1196289bc588SBarry Smith if (!mat->roworiented) { 1197dbb450caSBarry Smith if (addv == INSERT_VALUES) { 1198289bc588SBarry Smith for (j = 0; j < n; j++) { 11999371c9d4SSatish Balay if (indexn[j] < 0) { 12009371c9d4SSatish Balay idx += m; 12019371c9d4SSatish Balay continue; 12029371c9d4SSatish Balay } 12036bdcaf15SBarry 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); 1204289bc588SBarry Smith for (i = 0; i < m; i++) { 12059371c9d4SSatish Balay if (indexm[i] < 0) { 12069371c9d4SSatish Balay idx++; 12079371c9d4SSatish Balay continue; 12089371c9d4SSatish Balay } 12096bdcaf15SBarry 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); 1210ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] = v[idx++]; 1211289bc588SBarry Smith } 1212289bc588SBarry Smith } 12133a40ed3dSBarry Smith } else { 1214289bc588SBarry Smith for (j = 0; j < n; j++) { 12159371c9d4SSatish Balay if (indexn[j] < 0) { 12169371c9d4SSatish Balay idx += m; 12179371c9d4SSatish Balay continue; 12189371c9d4SSatish Balay } 12196bdcaf15SBarry 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); 1220289bc588SBarry Smith for (i = 0; i < m; i++) { 12219371c9d4SSatish Balay if (indexm[i] < 0) { 12229371c9d4SSatish Balay idx++; 12239371c9d4SSatish Balay continue; 12249371c9d4SSatish Balay } 12256bdcaf15SBarry 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); 1226ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] += v[idx++]; 1227289bc588SBarry Smith } 1228289bc588SBarry Smith } 1229289bc588SBarry Smith } 12303a40ed3dSBarry Smith } else { 1231dbb450caSBarry Smith if (addv == INSERT_VALUES) { 1232e8d4e0b9SBarry Smith for (i = 0; i < m; i++) { 12339371c9d4SSatish Balay if (indexm[i] < 0) { 12349371c9d4SSatish Balay idx += n; 12359371c9d4SSatish Balay continue; 12369371c9d4SSatish Balay } 12376bdcaf15SBarry Smith PetscCheck(indexm[i] < A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Row too large: row %" PetscInt_FMT " max %" PetscInt_FMT, indexm[i], A->rmap->n - 1); 1238e8d4e0b9SBarry Smith for (j = 0; j < n; j++) { 12399371c9d4SSatish Balay if (indexn[j] < 0) { 12409371c9d4SSatish Balay idx++; 12419371c9d4SSatish Balay continue; 12429371c9d4SSatish Balay } 12436bdcaf15SBarry 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); 1244ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] = v[idx++]; 1245e8d4e0b9SBarry Smith } 1246e8d4e0b9SBarry Smith } 12473a40ed3dSBarry Smith } else { 1248289bc588SBarry Smith for (i = 0; i < m; i++) { 12499371c9d4SSatish Balay if (indexm[i] < 0) { 12509371c9d4SSatish Balay idx += n; 12519371c9d4SSatish Balay continue; 12529371c9d4SSatish Balay } 12536bdcaf15SBarry Smith PetscCheck(indexm[i] < A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Row too large: row %" PetscInt_FMT " max %" PetscInt_FMT, indexm[i], A->rmap->n - 1); 1254289bc588SBarry Smith for (j = 0; j < n; j++) { 12559371c9d4SSatish Balay if (indexn[j] < 0) { 12569371c9d4SSatish Balay idx++; 12579371c9d4SSatish Balay continue; 12589371c9d4SSatish Balay } 12596bdcaf15SBarry 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); 1260ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] += v[idx++]; 1261289bc588SBarry Smith } 1262289bc588SBarry Smith } 1263289bc588SBarry Smith } 1264e8d4e0b9SBarry Smith } 1265ca15aa20SStefano Zampini /* hack to prevent unneeded copy to the GPU while returning the array */ 126647d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1267c70f7ee4SJunchao Zhang oldf = A->offloadmask; 1268c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_GPU; 1269ca15aa20SStefano Zampini #endif 12709566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &av)); 127147d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1272c70f7ee4SJunchao Zhang A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU); 1273ca15aa20SStefano Zampini #endif 12743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1275289bc588SBarry Smith } 1276e8d4e0b9SBarry Smith 1277d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], PetscScalar v[]) 1278d71ae5a4SJacob Faibussowitsch { 1279ae80bb75SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1280ca15aa20SStefano Zampini const PetscScalar *vv; 128113f74950SBarry Smith PetscInt i, j; 1282ae80bb75SLois Curfman McInnes 12833a40ed3dSBarry Smith PetscFunctionBegin; 12849566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &vv)); 1285ae80bb75SLois Curfman McInnes /* row-oriented output */ 1286ae80bb75SLois Curfman McInnes for (i = 0; i < m; i++) { 12879371c9d4SSatish Balay if (indexm[i] < 0) { 12889371c9d4SSatish Balay v += n; 12899371c9d4SSatish Balay continue; 12909371c9d4SSatish Balay } 129108401ef6SPierre 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); 1292ae80bb75SLois Curfman McInnes for (j = 0; j < n; j++) { 12939371c9d4SSatish Balay if (indexn[j] < 0) { 12949371c9d4SSatish Balay v++; 12959371c9d4SSatish Balay continue; 12969371c9d4SSatish Balay } 129708401ef6SPierre 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); 1298ca15aa20SStefano Zampini *v++ = vv[indexn[j] * mat->lda + indexm[i]]; 1299ae80bb75SLois Curfman McInnes } 1300ae80bb75SLois Curfman McInnes } 13019566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &vv)); 13023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1303ae80bb75SLois Curfman McInnes } 1304ae80bb75SLois Curfman McInnes 1305d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_Dense_Binary(Mat mat, PetscViewer viewer) 1306d71ae5a4SJacob Faibussowitsch { 13078491ab44SLisandro Dalcin PetscBool skipHeader; 13088491ab44SLisandro Dalcin PetscViewerFormat format; 13098491ab44SLisandro Dalcin PetscInt header[4], M, N, m, lda, i, j, k; 13108491ab44SLisandro Dalcin const PetscScalar *v; 13118491ab44SLisandro Dalcin PetscScalar *vwork; 1312aabbc4fbSShri Abhyankar 1313aabbc4fbSShri Abhyankar PetscFunctionBegin; 13149566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 13159566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader)); 13169566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 13178491ab44SLisandro Dalcin if (skipHeader) format = PETSC_VIEWER_NATIVE; 1318aabbc4fbSShri Abhyankar 13199566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &M, &N)); 13208491ab44SLisandro Dalcin 13218491ab44SLisandro Dalcin /* write matrix header */ 13229371c9d4SSatish Balay header[0] = MAT_FILE_CLASSID; 13239371c9d4SSatish Balay header[1] = M; 13249371c9d4SSatish Balay header[2] = N; 13258491ab44SLisandro Dalcin header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M * N; 13269566063dSJacob Faibussowitsch if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer, header, 4, PETSC_INT)); 13278491ab44SLisandro Dalcin 13289566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mat, &m, NULL)); 13298491ab44SLisandro Dalcin if (format != PETSC_VIEWER_NATIVE) { 13308491ab44SLisandro Dalcin PetscInt nnz = m * N, *iwork; 13318491ab44SLisandro Dalcin /* store row lengths for each row */ 13329566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz, &iwork)); 13338491ab44SLisandro Dalcin for (i = 0; i < m; i++) iwork[i] = N; 13349566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 13358491ab44SLisandro Dalcin /* store column indices (zero start index) */ 13368491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 13379371c9d4SSatish Balay for (j = 0; j < N; j++, k++) iwork[k] = j; 13389566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 13399566063dSJacob Faibussowitsch PetscCall(PetscFree(iwork)); 13408491ab44SLisandro Dalcin } 13418491ab44SLisandro Dalcin /* store matrix values as a dense matrix in row major order */ 13429566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m * N, &vwork)); 13439566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(mat, &v)); 13449566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(mat, &lda)); 13458491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 13469371c9d4SSatish Balay for (j = 0; j < N; j++, k++) vwork[k] = v[i + lda * j]; 13479566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(mat, &v)); 13489566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, vwork, m * N, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 13499566063dSJacob Faibussowitsch PetscCall(PetscFree(vwork)); 13503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13518491ab44SLisandro Dalcin } 13528491ab44SLisandro Dalcin 1353d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLoad_Dense_Binary(Mat mat, PetscViewer viewer) 1354d71ae5a4SJacob Faibussowitsch { 13558491ab44SLisandro Dalcin PetscBool skipHeader; 13568491ab44SLisandro Dalcin PetscInt header[4], M, N, m, nz, lda, i, j, k; 13578491ab44SLisandro Dalcin PetscInt rows, cols; 13588491ab44SLisandro Dalcin PetscScalar *v, *vwork; 13598491ab44SLisandro Dalcin 13608491ab44SLisandro Dalcin PetscFunctionBegin; 13619566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 13629566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader)); 13638491ab44SLisandro Dalcin 13648491ab44SLisandro Dalcin if (!skipHeader) { 13659566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, header, 4, NULL, PETSC_INT)); 136608401ef6SPierre Jolivet PetscCheck(header[0] == MAT_FILE_CLASSID, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Not a matrix object in file"); 13679371c9d4SSatish Balay M = header[1]; 13689371c9d4SSatish Balay N = header[2]; 136908401ef6SPierre Jolivet PetscCheck(M >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix row size (%" PetscInt_FMT ") in file is negative", M); 137008401ef6SPierre Jolivet PetscCheck(N >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix column size (%" PetscInt_FMT ") in file is negative", N); 13718491ab44SLisandro Dalcin nz = header[3]; 1372aed4548fSBarry Smith PetscCheck(nz == MATRIX_BINARY_FORMAT_DENSE || nz >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Unknown matrix format %" PetscInt_FMT " in file", nz); 1373aabbc4fbSShri Abhyankar } else { 13749566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &M, &N)); 1375aed4548fSBarry 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"); 13768491ab44SLisandro Dalcin nz = MATRIX_BINARY_FORMAT_DENSE; 1377e6324fbbSBarry Smith } 1378aabbc4fbSShri Abhyankar 13798491ab44SLisandro Dalcin /* setup global sizes if not set */ 13808491ab44SLisandro Dalcin if (mat->rmap->N < 0) mat->rmap->N = M; 13818491ab44SLisandro Dalcin if (mat->cmap->N < 0) mat->cmap->N = N; 13829566063dSJacob Faibussowitsch PetscCall(MatSetUp(mat)); 13838491ab44SLisandro Dalcin /* check if global sizes are correct */ 13849566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &rows, &cols)); 1385aed4548fSBarry 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); 1386aabbc4fbSShri Abhyankar 13879566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, NULL, &N)); 13889566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mat, &m, NULL)); 13899566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(mat, &v)); 13909566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(mat, &lda)); 13918491ab44SLisandro Dalcin if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense format */ 13928491ab44SLisandro Dalcin PetscInt nnz = m * N; 13938491ab44SLisandro Dalcin /* read in matrix values */ 13949566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz, &vwork)); 13959566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 13968491ab44SLisandro Dalcin /* store values in column major order */ 13978491ab44SLisandro Dalcin for (j = 0; j < N; j++) 13989371c9d4SSatish Balay for (i = 0; i < m; i++) v[i + lda * j] = vwork[i * N + j]; 13999566063dSJacob Faibussowitsch PetscCall(PetscFree(vwork)); 14008491ab44SLisandro Dalcin } else { /* matrix in file is sparse format */ 14018491ab44SLisandro Dalcin PetscInt nnz = 0, *rlens, *icols; 14028491ab44SLisandro Dalcin /* read in row lengths */ 14039566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m, &rlens)); 14049566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, rlens, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 14058491ab44SLisandro Dalcin for (i = 0; i < m; i++) nnz += rlens[i]; 14068491ab44SLisandro Dalcin /* read in column indices and values */ 14079566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(nnz, &icols, nnz, &vwork)); 14089566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, icols, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 14099566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 14108491ab44SLisandro Dalcin /* store values in column major order */ 14118491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 14129371c9d4SSatish Balay for (j = 0; j < rlens[i]; j++, k++) v[i + lda * icols[k]] = vwork[k]; 14139566063dSJacob Faibussowitsch PetscCall(PetscFree(rlens)); 14149566063dSJacob Faibussowitsch PetscCall(PetscFree2(icols, vwork)); 1415aabbc4fbSShri Abhyankar } 14169566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(mat, &v)); 14179566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY)); 14189566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY)); 14193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1420aabbc4fbSShri Abhyankar } 1421aabbc4fbSShri Abhyankar 1422d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer) 1423d71ae5a4SJacob Faibussowitsch { 1424eb91f321SVaclav Hapla PetscBool isbinary, ishdf5; 1425eb91f321SVaclav Hapla 1426eb91f321SVaclav Hapla PetscFunctionBegin; 1427eb91f321SVaclav Hapla PetscValidHeaderSpecific(newMat, MAT_CLASSID, 1); 1428eb91f321SVaclav Hapla PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1429eb91f321SVaclav Hapla /* force binary viewer to load .info file if it has not yet done so */ 14309566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 14319566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 14329566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5)); 1433eb91f321SVaclav Hapla if (isbinary) { 14349566063dSJacob Faibussowitsch PetscCall(MatLoad_Dense_Binary(newMat, viewer)); 1435eb91f321SVaclav Hapla } else if (ishdf5) { 1436eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5) 14379566063dSJacob Faibussowitsch PetscCall(MatLoad_Dense_HDF5(newMat, viewer)); 1438eb91f321SVaclav Hapla #else 1439eb91f321SVaclav Hapla SETERRQ(PetscObjectComm((PetscObject)newMat), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1440eb91f321SVaclav Hapla #endif 1441eb91f321SVaclav Hapla } else { 144298921bdaSJacob 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); 1443eb91f321SVaclav Hapla } 14443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1445eb91f321SVaclav Hapla } 1446eb91f321SVaclav Hapla 1447d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_ASCII(Mat A, PetscViewer viewer) 1448d71ae5a4SJacob Faibussowitsch { 1449932b0c3eSLois Curfman McInnes Mat_SeqDense *a = (Mat_SeqDense *)A->data; 145013f74950SBarry Smith PetscInt i, j; 14512dcb1b2aSMatthew Knepley const char *name; 1452ca15aa20SStefano Zampini PetscScalar *v, *av; 1453f3ef73ceSBarry Smith PetscViewerFormat format; 14545f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX) 1455ace3abfcSBarry Smith PetscBool allreal = PETSC_TRUE; 14565f481a85SSatish Balay #endif 1457932b0c3eSLois Curfman McInnes 14583a40ed3dSBarry Smith PetscFunctionBegin; 14599566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&av)); 14609566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 1461456192e2SBarry Smith if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 14623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); /* do nothing for now */ 1463fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 14649566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE)); 1465d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 1466ca15aa20SStefano Zampini v = av + i; 14679566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "row %" PetscInt_FMT ":", i)); 1468d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1469aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 1470329f5518SBarry Smith if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) { 14719566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g + %g i) ", j, (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v))); 1472329f5518SBarry Smith } else if (PetscRealPart(*v)) { 14739566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)PetscRealPart(*v))); 14746831982aSBarry Smith } 147580cd9d93SLois Curfman McInnes #else 147648a46eb9SPierre Jolivet if (*v) PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)*v)); 147780cd9d93SLois Curfman McInnes #endif 14781b807ce4Svictorle v += a->lda; 147980cd9d93SLois Curfman McInnes } 14809566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 148180cd9d93SLois Curfman McInnes } 14829566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE)); 14833a40ed3dSBarry Smith } else { 14849566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE)); 1485aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 148647989497SBarry Smith /* determine if matrix has all real values */ 1487bcd8d3a4SJose E. Roman for (j = 0; j < A->cmap->n; j++) { 1488bcd8d3a4SJose E. Roman v = av + j * a->lda; 1489bcd8d3a4SJose E. Roman for (i = 0; i < A->rmap->n; i++) { 14909371c9d4SSatish Balay if (PetscImaginaryPart(v[i])) { 14919371c9d4SSatish Balay allreal = PETSC_FALSE; 14929371c9d4SSatish Balay break; 14939371c9d4SSatish Balay } 149447989497SBarry Smith } 1495bcd8d3a4SJose E. Roman } 149647989497SBarry Smith #endif 1497fb9695e5SSatish Balay if (format == PETSC_VIEWER_ASCII_MATLAB) { 14989566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)A, &name)); 14999566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%% Size = %" PetscInt_FMT " %" PetscInt_FMT " \n", A->rmap->n, A->cmap->n)); 15009566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%s = zeros(%" PetscInt_FMT ",%" PetscInt_FMT ");\n", name, A->rmap->n, A->cmap->n)); 15019566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%s = [\n", name)); 1502ffac6cdbSBarry Smith } 1503ffac6cdbSBarry Smith 1504d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 1505ca15aa20SStefano Zampini v = av + i; 1506d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1507aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 150847989497SBarry Smith if (allreal) { 15099566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)PetscRealPart(*v))); 151047989497SBarry Smith } else { 15119566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e + %18.16ei ", (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v))); 151247989497SBarry Smith } 1513289bc588SBarry Smith #else 15149566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)*v)); 1515289bc588SBarry Smith #endif 15161b807ce4Svictorle v += a->lda; 1517289bc588SBarry Smith } 15189566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 1519289bc588SBarry Smith } 152048a46eb9SPierre Jolivet if (format == PETSC_VIEWER_ASCII_MATLAB) PetscCall(PetscViewerASCIIPrintf(viewer, "];\n")); 15219566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE)); 1522da3a660dSBarry Smith } 15239566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&av)); 15249566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer)); 15253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1526289bc588SBarry Smith } 1527289bc588SBarry Smith 15289804daf3SBarry Smith #include <petscdraw.h> 1529d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw, void *Aa) 1530d71ae5a4SJacob Faibussowitsch { 1531f1af5d2fSBarry Smith Mat A = (Mat)Aa; 1532383922c3SLisandro Dalcin PetscInt m = A->rmap->n, n = A->cmap->n, i, j; 1533383922c3SLisandro Dalcin int color = PETSC_DRAW_WHITE; 1534ca15aa20SStefano Zampini const PetscScalar *v; 1535b0a32e0cSBarry Smith PetscViewer viewer; 1536b05fc000SLisandro Dalcin PetscReal xl, yl, xr, yr, x_l, x_r, y_l, y_r; 1537f3ef73ceSBarry Smith PetscViewerFormat format; 1538f1af5d2fSBarry Smith 1539f1af5d2fSBarry Smith PetscFunctionBegin; 15409566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)A, "Zoomviewer", (PetscObject *)&viewer)); 15419566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 15429566063dSJacob Faibussowitsch PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr)); 1543f1af5d2fSBarry Smith 1544f1af5d2fSBarry Smith /* Loop over matrix elements drawing boxes */ 15459566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 1546fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 1547d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 1548f1af5d2fSBarry Smith /* Blue for negative and Red for positive */ 1549f1af5d2fSBarry Smith for (j = 0; j < n; j++) { 15509371c9d4SSatish Balay x_l = j; 15519371c9d4SSatish Balay x_r = x_l + 1.0; 1552f1af5d2fSBarry Smith for (i = 0; i < m; i++) { 1553f1af5d2fSBarry Smith y_l = m - i - 1.0; 1554f1af5d2fSBarry Smith y_r = y_l + 1.0; 1555ca15aa20SStefano Zampini if (PetscRealPart(v[j * m + i]) > 0.) color = PETSC_DRAW_RED; 1556ca15aa20SStefano Zampini else if (PetscRealPart(v[j * m + i]) < 0.) color = PETSC_DRAW_BLUE; 1557ca15aa20SStefano Zampini else continue; 15589566063dSJacob Faibussowitsch PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color)); 1559f1af5d2fSBarry Smith } 1560f1af5d2fSBarry Smith } 1561d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 1562f1af5d2fSBarry Smith } else { 1563f1af5d2fSBarry Smith /* use contour shading to indicate magnitude of values */ 1564f1af5d2fSBarry Smith /* first determine max of all nonzero values */ 1565b05fc000SLisandro Dalcin PetscReal minv = 0.0, maxv = 0.0; 1566b05fc000SLisandro Dalcin PetscDraw popup; 1567b05fc000SLisandro Dalcin 1568f1af5d2fSBarry Smith for (i = 0; i < m * n; i++) { 1569f1af5d2fSBarry Smith if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]); 1570f1af5d2fSBarry Smith } 1571383922c3SLisandro Dalcin if (minv >= maxv) maxv = minv + PETSC_SMALL; 15729566063dSJacob Faibussowitsch PetscCall(PetscDrawGetPopup(draw, &popup)); 15739566063dSJacob Faibussowitsch PetscCall(PetscDrawScalePopup(popup, minv, maxv)); 1574383922c3SLisandro Dalcin 1575d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 1576f1af5d2fSBarry Smith for (j = 0; j < n; j++) { 1577f1af5d2fSBarry Smith x_l = j; 1578f1af5d2fSBarry Smith x_r = x_l + 1.0; 1579f1af5d2fSBarry Smith for (i = 0; i < m; i++) { 1580f1af5d2fSBarry Smith y_l = m - i - 1.0; 1581f1af5d2fSBarry Smith y_r = y_l + 1.0; 1582b05fc000SLisandro Dalcin color = PetscDrawRealToColor(PetscAbsScalar(v[j * m + i]), minv, maxv); 15839566063dSJacob Faibussowitsch PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color)); 1584f1af5d2fSBarry Smith } 1585f1af5d2fSBarry Smith } 1586d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 1587f1af5d2fSBarry Smith } 15889566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 15893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1590f1af5d2fSBarry Smith } 1591f1af5d2fSBarry Smith 1592d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw(Mat A, PetscViewer viewer) 1593d71ae5a4SJacob Faibussowitsch { 1594b0a32e0cSBarry Smith PetscDraw draw; 1595ace3abfcSBarry Smith PetscBool isnull; 1596329f5518SBarry Smith PetscReal xr, yr, xl, yl, h, w; 1597f1af5d2fSBarry Smith 1598f1af5d2fSBarry Smith PetscFunctionBegin; 15999566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 16009566063dSJacob Faibussowitsch PetscCall(PetscDrawIsNull(draw, &isnull)); 16013ba16761SJacob Faibussowitsch if (isnull) PetscFunctionReturn(PETSC_SUCCESS); 1602f1af5d2fSBarry Smith 16039371c9d4SSatish Balay xr = A->cmap->n; 16049371c9d4SSatish Balay yr = A->rmap->n; 16059371c9d4SSatish Balay h = yr / 10.0; 16069371c9d4SSatish Balay w = xr / 10.0; 16079371c9d4SSatish Balay xr += w; 16089371c9d4SSatish Balay yr += h; 16099371c9d4SSatish Balay xl = -w; 16109371c9d4SSatish Balay yl = -h; 16119566063dSJacob Faibussowitsch PetscCall(PetscDrawSetCoordinates(draw, xl, yl, xr, yr)); 16129566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", (PetscObject)viewer)); 16139566063dSJacob Faibussowitsch PetscCall(PetscDrawZoom(draw, MatView_SeqDense_Draw_Zoom, A)); 16149566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", NULL)); 16159566063dSJacob Faibussowitsch PetscCall(PetscDrawSave(draw)); 16163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1617f1af5d2fSBarry Smith } 1618f1af5d2fSBarry Smith 1619d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_SeqDense(Mat A, PetscViewer viewer) 1620d71ae5a4SJacob Faibussowitsch { 1621ace3abfcSBarry Smith PetscBool iascii, isbinary, isdraw; 1622932b0c3eSLois Curfman McInnes 16233a40ed3dSBarry Smith PetscFunctionBegin; 16249566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 16259566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 16269566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 16271baa6e33SBarry Smith if (iascii) PetscCall(MatView_SeqDense_ASCII(A, viewer)); 16281baa6e33SBarry Smith else if (isbinary) PetscCall(MatView_Dense_Binary(A, viewer)); 16291baa6e33SBarry Smith else if (isdraw) PetscCall(MatView_SeqDense_Draw(A, viewer)); 16303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1631932b0c3eSLois Curfman McInnes } 1632289bc588SBarry Smith 1633d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A, const PetscScalar *array) 1634d71ae5a4SJacob Faibussowitsch { 1635d3042a70SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1636d3042a70SBarry Smith 1637d3042a70SBarry Smith PetscFunctionBegin; 163828b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 163928b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 164028b400f6SJacob Faibussowitsch PetscCheck(!a->unplacedarray, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreArray() first"); 1641d3042a70SBarry Smith a->unplacedarray = a->v; 1642d3042a70SBarry Smith a->unplaced_user_alloc = a->user_alloc; 1643d3042a70SBarry Smith a->v = (PetscScalar *)array; 1644637a0070SStefano Zampini a->user_alloc = PETSC_TRUE; 164547d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1646c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_CPU; 1647ca15aa20SStefano Zampini #endif 16483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1649d3042a70SBarry Smith } 1650d3042a70SBarry Smith 1651d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseResetArray_SeqDense(Mat A) 1652d71ae5a4SJacob Faibussowitsch { 1653d3042a70SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1654d3042a70SBarry Smith 1655d3042a70SBarry Smith PetscFunctionBegin; 165628b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 165728b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 1658d3042a70SBarry Smith a->v = a->unplacedarray; 1659d3042a70SBarry Smith a->user_alloc = a->unplaced_user_alloc; 1660d3042a70SBarry Smith a->unplacedarray = NULL; 166147d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1662c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_CPU; 1663ca15aa20SStefano Zampini #endif 16643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1665d3042a70SBarry Smith } 1666d3042a70SBarry Smith 1667d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A, const PetscScalar *array) 1668d71ae5a4SJacob Faibussowitsch { 1669d5ea218eSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1670d5ea218eSStefano Zampini 1671d5ea218eSStefano Zampini PetscFunctionBegin; 167228b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 167328b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 16749566063dSJacob Faibussowitsch if (!a->user_alloc) PetscCall(PetscFree(a->v)); 1675d5ea218eSStefano Zampini a->v = (PetscScalar *)array; 1676d5ea218eSStefano Zampini a->user_alloc = PETSC_FALSE; 167747d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1678d5ea218eSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 1679d5ea218eSStefano Zampini #endif 16803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1681d5ea218eSStefano Zampini } 1682d5ea218eSStefano Zampini 1683d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDestroy_SeqDense(Mat mat) 1684d71ae5a4SJacob Faibussowitsch { 1685ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)mat->data; 168690f02eecSBarry Smith 16873a40ed3dSBarry Smith PetscFunctionBegin; 1688aa482453SBarry Smith #if defined(PETSC_USE_LOG) 16893ba16761SJacob Faibussowitsch PetscCall(PetscLogObjectState((PetscObject)mat, "Rows %" PetscInt_FMT " Cols %" PetscInt_FMT, mat->rmap->n, mat->cmap->n)); 1690a5a9c739SBarry Smith #endif 16919566063dSJacob Faibussowitsch PetscCall(VecDestroy(&(l->qrrhs))); 16929566063dSJacob Faibussowitsch PetscCall(PetscFree(l->tau)); 16939566063dSJacob Faibussowitsch PetscCall(PetscFree(l->pivots)); 16949566063dSJacob Faibussowitsch PetscCall(PetscFree(l->fwork)); 16959566063dSJacob Faibussowitsch if (!l->user_alloc) PetscCall(PetscFree(l->v)); 16969566063dSJacob Faibussowitsch if (!l->unplaced_user_alloc) PetscCall(PetscFree(l->unplacedarray)); 169728b400f6SJacob Faibussowitsch PetscCheck(!l->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 169828b400f6SJacob Faibussowitsch PetscCheck(!l->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 16999566063dSJacob Faibussowitsch PetscCall(VecDestroy(&l->cvec)); 17009566063dSJacob Faibussowitsch PetscCall(MatDestroy(&l->cmat)); 17019566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->data)); 1702dbd8c25aSHong Zhang 17039566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)mat, NULL)); 17049566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactor_C", NULL)); 17052e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorSymbolic_C", NULL)); 17062e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorNumeric_C", NULL)); 17079566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetLDA_C", NULL)); 17089566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseSetLDA_C", NULL)); 17099566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArray_C", NULL)); 17109566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArray_C", NULL)); 17119566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDensePlaceArray_C", NULL)); 17129566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseResetArray_C", NULL)); 17139566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseReplaceArray_C", NULL)); 17149566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayRead_C", NULL)); 17159566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayRead_C", NULL)); 17169566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayWrite_C", NULL)); 17179566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayWrite_C", NULL)); 17189566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqaij_C", NULL)); 17198baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 17209566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_elemental_C", NULL)); 17218baccfbdSHong Zhang #endif 1722d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 17239566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_scalapack_C", NULL)); 1724d24d4204SJose E. Roman #endif 17252bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA) 17269566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensecuda_C", NULL)); 17279566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", NULL)); 17289566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdense_C", NULL)); 17292e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensecuda_C", NULL)); 17302bf066beSStefano Zampini #endif 173147d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 173247d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensehip_C", NULL)); 173347d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensehip_seqdensehip_C", NULL)); 173447d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensehip_seqdense_C", NULL)); 173547d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensehip_C", NULL)); 173647d993e7Ssuyashtn #endif 17379566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatSeqDenseSetPreallocation_C", NULL)); 17389566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqaij_seqdense_C", NULL)); 17399566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdense_C", NULL)); 17409566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqbaij_seqdense_C", NULL)); 17419566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqsbaij_seqdense_C", NULL)); 174252c5f739Sprj- 17439566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumn_C", NULL)); 17449566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumn_C", NULL)); 17459566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVec_C", NULL)); 17469566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVec_C", NULL)); 17479566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecRead_C", NULL)); 17489566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecRead_C", NULL)); 17499566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecWrite_C", NULL)); 17509566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecWrite_C", NULL)); 17519566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetSubMatrix_C", NULL)); 17529566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreSubMatrix_C", NULL)); 17533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1754289bc588SBarry Smith } 1755289bc588SBarry Smith 1756d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatTranspose_SeqDense(Mat A, MatReuse reuse, Mat *matout) 1757d71ae5a4SJacob Faibussowitsch { 1758c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 17596536e3caSStefano Zampini PetscInt k, j, m = A->rmap->n, M = mat->lda, n = A->cmap->n; 176087828ca2SBarry Smith PetscScalar *v, tmp; 176148b35521SBarry Smith 17623a40ed3dSBarry Smith PetscFunctionBegin; 17637fb60732SBarry Smith if (reuse == MAT_REUSE_MATRIX) PetscCall(MatTransposeCheckNonzeroState_Private(A, *matout)); 17646536e3caSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 17656536e3caSStefano Zampini if (m == n) { /* in place transpose */ 17669566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 1767d3e5ee88SLois Curfman McInnes for (j = 0; j < m; j++) { 1768289bc588SBarry Smith for (k = 0; k < j; k++) { 17691b807ce4Svictorle tmp = v[j + k * M]; 17701b807ce4Svictorle v[j + k * M] = v[k + j * M]; 17711b807ce4Svictorle v[k + j * M] = tmp; 1772289bc588SBarry Smith } 1773289bc588SBarry Smith } 17749566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 17756536e3caSStefano Zampini } else { /* reuse memory, temporary allocates new memory */ 17766536e3caSStefano Zampini PetscScalar *v2; 17776536e3caSStefano Zampini PetscLayout tmplayout; 17786536e3caSStefano Zampini 17799566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((size_t)m * n, &v2)); 17809566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 17816536e3caSStefano Zampini for (j = 0; j < n; j++) { 17826536e3caSStefano Zampini for (k = 0; k < m; k++) v2[j + (size_t)k * n] = v[k + (size_t)j * M]; 17836536e3caSStefano Zampini } 17849566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(v, v2, (size_t)m * n)); 17859566063dSJacob Faibussowitsch PetscCall(PetscFree(v2)); 17869566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 17876536e3caSStefano Zampini /* cleanup size dependent quantities */ 17889566063dSJacob Faibussowitsch PetscCall(VecDestroy(&mat->cvec)); 17899566063dSJacob Faibussowitsch PetscCall(MatDestroy(&mat->cmat)); 17909566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->pivots)); 17919566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->fwork)); 17926536e3caSStefano Zampini /* swap row/col layouts */ 17936536e3caSStefano Zampini mat->lda = n; 17946536e3caSStefano Zampini tmplayout = A->rmap; 17956536e3caSStefano Zampini A->rmap = A->cmap; 17966536e3caSStefano Zampini A->cmap = tmplayout; 17976536e3caSStefano Zampini } 17983a40ed3dSBarry Smith } else { /* out-of-place transpose */ 1799d3e5ee88SLois Curfman McInnes Mat tmat; 1800ec8511deSBarry Smith Mat_SeqDense *tmatd; 180187828ca2SBarry Smith PetscScalar *v2; 1802af36a384SStefano Zampini PetscInt M2; 1803ea709b57SSatish Balay 18046536e3caSStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 18059566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &tmat)); 18069566063dSJacob Faibussowitsch PetscCall(MatSetSizes(tmat, A->cmap->n, A->rmap->n, A->cmap->n, A->rmap->n)); 18079566063dSJacob Faibussowitsch PetscCall(MatSetType(tmat, ((PetscObject)A)->type_name)); 18089566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(tmat, NULL)); 1809ca15aa20SStefano Zampini } else tmat = *matout; 1810ca15aa20SStefano Zampini 18119566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&v)); 18129566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(tmat, &v2)); 1813ec8511deSBarry Smith tmatd = (Mat_SeqDense *)tmat->data; 1814ca15aa20SStefano Zampini M2 = tmatd->lda; 1815d3e5ee88SLois Curfman McInnes for (j = 0; j < n; j++) { 1816af36a384SStefano Zampini for (k = 0; k < m; k++) v2[j + k * M2] = v[k + j * M]; 1817d3e5ee88SLois Curfman McInnes } 18189566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(tmat, &v2)); 18199566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&v)); 18209566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(tmat, MAT_FINAL_ASSEMBLY)); 18219566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(tmat, MAT_FINAL_ASSEMBLY)); 18226536e3caSStefano Zampini *matout = tmat; 182348b35521SBarry Smith } 18243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1825289bc588SBarry Smith } 1826289bc588SBarry Smith 1827d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatEqual_SeqDense(Mat A1, Mat A2, PetscBool *flg) 1828d71ae5a4SJacob Faibussowitsch { 1829c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat1 = (Mat_SeqDense *)A1->data; 1830c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat2 = (Mat_SeqDense *)A2->data; 1831ca15aa20SStefano Zampini PetscInt i; 1832ca15aa20SStefano Zampini const PetscScalar *v1, *v2; 18339ea5d5aeSSatish Balay 18343a40ed3dSBarry Smith PetscFunctionBegin; 18359371c9d4SSatish Balay if (A1->rmap->n != A2->rmap->n) { 18369371c9d4SSatish Balay *flg = PETSC_FALSE; 18373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18389371c9d4SSatish Balay } 18399371c9d4SSatish Balay if (A1->cmap->n != A2->cmap->n) { 18409371c9d4SSatish Balay *flg = PETSC_FALSE; 18413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18429371c9d4SSatish Balay } 18439566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A1, &v1)); 18449566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A2, &v2)); 1845ca15aa20SStefano Zampini for (i = 0; i < A1->cmap->n; i++) { 18469566063dSJacob Faibussowitsch PetscCall(PetscArraycmp(v1, v2, A1->rmap->n, flg)); 18473ba16761SJacob Faibussowitsch if (*flg == PETSC_FALSE) PetscFunctionReturn(PETSC_SUCCESS); 1848ca15aa20SStefano Zampini v1 += mat1->lda; 1849ca15aa20SStefano Zampini v2 += mat2->lda; 18501b807ce4Svictorle } 18519566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A1, &v1)); 18529566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A2, &v2)); 185377c4ece6SBarry Smith *flg = PETSC_TRUE; 18543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1855289bc588SBarry Smith } 1856289bc588SBarry Smith 1857d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetDiagonal_SeqDense(Mat A, Vec v) 1858d71ae5a4SJacob Faibussowitsch { 1859c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 186013f74950SBarry Smith PetscInt i, n, len; 1861ca15aa20SStefano Zampini PetscScalar *x; 1862ca15aa20SStefano Zampini const PetscScalar *vv; 186344cd7ae7SLois Curfman McInnes 18643a40ed3dSBarry Smith PetscFunctionBegin; 18659566063dSJacob Faibussowitsch PetscCall(VecGetSize(v, &n)); 18669566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 1867d0f46423SBarry Smith len = PetscMin(A->rmap->n, A->cmap->n); 18689566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &vv)); 186908401ef6SPierre Jolivet PetscCheck(n == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming mat and vec"); 1870ad540459SPierre Jolivet for (i = 0; i < len; i++) x[i] = vv[i * mat->lda + i]; 18719566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &vv)); 18729566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 18733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1874289bc588SBarry Smith } 1875289bc588SBarry Smith 1876d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDiagonalScale_SeqDense(Mat A, Vec ll, Vec rr) 1877d71ae5a4SJacob Faibussowitsch { 1878c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1879f1ceaac6SMatthew G. Knepley const PetscScalar *l, *r; 1880ca15aa20SStefano Zampini PetscScalar x, *v, *vv; 1881d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n; 188255659b69SBarry Smith 18833a40ed3dSBarry Smith PetscFunctionBegin; 18849566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &vv)); 188528988994SBarry Smith if (ll) { 18869566063dSJacob Faibussowitsch PetscCall(VecGetSize(ll, &m)); 18879566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(ll, &l)); 188808401ef6SPierre Jolivet PetscCheck(m == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Left scaling vec wrong size"); 1889da3a660dSBarry Smith for (i = 0; i < m; i++) { 1890da3a660dSBarry Smith x = l[i]; 1891ca15aa20SStefano Zampini v = vv + i; 18929371c9d4SSatish Balay for (j = 0; j < n; j++) { 18939371c9d4SSatish Balay (*v) *= x; 18949371c9d4SSatish Balay v += mat->lda; 18959371c9d4SSatish Balay } 1896da3a660dSBarry Smith } 18979566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(ll, &l)); 18989566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * n * m)); 1899da3a660dSBarry Smith } 190028988994SBarry Smith if (rr) { 19019566063dSJacob Faibussowitsch PetscCall(VecGetSize(rr, &n)); 19029566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(rr, &r)); 190308401ef6SPierre Jolivet PetscCheck(n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Right scaling vec wrong size"); 1904da3a660dSBarry Smith for (i = 0; i < n; i++) { 1905da3a660dSBarry Smith x = r[i]; 1906ca15aa20SStefano Zampini v = vv + i * mat->lda; 19072205254eSKarl Rupp for (j = 0; j < m; j++) (*v++) *= x; 1908da3a660dSBarry Smith } 19099566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(rr, &r)); 19109566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * n * m)); 1911da3a660dSBarry Smith } 19129566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &vv)); 19133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1914289bc588SBarry Smith } 1915289bc588SBarry Smith 1916d71ae5a4SJacob Faibussowitsch PetscErrorCode MatNorm_SeqDense(Mat A, NormType type, PetscReal *nrm) 1917d71ae5a4SJacob Faibussowitsch { 1918c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1919ca15aa20SStefano Zampini PetscScalar *v, *vv; 1920329f5518SBarry Smith PetscReal sum = 0.0; 192175f6d85dSStefano Zampini PetscInt lda, m = A->rmap->n, i, j; 192255659b69SBarry Smith 19233a40ed3dSBarry Smith PetscFunctionBegin; 19249566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&vv)); 19259566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(A, &lda)); 1926ca15aa20SStefano Zampini v = vv; 1927289bc588SBarry Smith if (type == NORM_FROBENIUS) { 1928a5ce6ee0Svictorle if (lda > m) { 1929d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1930ca15aa20SStefano Zampini v = vv + j * lda; 1931a5ce6ee0Svictorle for (i = 0; i < m; i++) { 19329371c9d4SSatish Balay sum += PetscRealPart(PetscConj(*v) * (*v)); 19339371c9d4SSatish Balay v++; 1934a5ce6ee0Svictorle } 1935a5ce6ee0Svictorle } 1936a5ce6ee0Svictorle } else { 1937570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16) 1938570b7f6dSBarry Smith PetscBLASInt one = 1, cnt = A->cmap->n * A->rmap->n; 1939792fecdfSBarry Smith PetscCallBLAS("BLASnrm2", *nrm = BLASnrm2_(&cnt, v, &one)); 1940570b7f6dSBarry Smith } 1941570b7f6dSBarry Smith #else 1942d0f46423SBarry Smith for (i = 0; i < A->cmap->n * A->rmap->n; i++) { 19439371c9d4SSatish Balay sum += PetscRealPart(PetscConj(*v) * (*v)); 19449371c9d4SSatish Balay v++; 1945289bc588SBarry Smith } 1946a5ce6ee0Svictorle } 19478f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 1948570b7f6dSBarry Smith #endif 19499566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->cmap->n * A->rmap->n)); 19503a40ed3dSBarry Smith } else if (type == NORM_1) { 1951064f8208SBarry Smith *nrm = 0.0; 1952d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1953ca15aa20SStefano Zampini v = vv + j * mat->lda; 1954289bc588SBarry Smith sum = 0.0; 1955d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 19569371c9d4SSatish Balay sum += PetscAbsScalar(*v); 19579371c9d4SSatish Balay v++; 1958289bc588SBarry Smith } 1959064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 1960289bc588SBarry Smith } 19619566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n)); 19623a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 1963064f8208SBarry Smith *nrm = 0.0; 1964d0f46423SBarry Smith for (j = 0; j < A->rmap->n; j++) { 1965ca15aa20SStefano Zampini v = vv + j; 1966289bc588SBarry Smith sum = 0.0; 1967d0f46423SBarry Smith for (i = 0; i < A->cmap->n; i++) { 19689371c9d4SSatish Balay sum += PetscAbsScalar(*v); 19699371c9d4SSatish Balay v += mat->lda; 1970289bc588SBarry Smith } 1971064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 1972289bc588SBarry Smith } 19739566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n)); 1974e7e72b3dSBarry Smith } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "No two norm"); 19759566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&vv)); 19763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1977289bc588SBarry Smith } 1978289bc588SBarry Smith 1979d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetOption_SeqDense(Mat A, MatOption op, PetscBool flg) 1980d71ae5a4SJacob Faibussowitsch { 1981c0bbcb79SLois Curfman McInnes Mat_SeqDense *aij = (Mat_SeqDense *)A->data; 198267e560aaSBarry Smith 19833a40ed3dSBarry Smith PetscFunctionBegin; 1984b5a2b587SKris Buschelman switch (op) { 1985d71ae5a4SJacob Faibussowitsch case MAT_ROW_ORIENTED: 1986d71ae5a4SJacob Faibussowitsch aij->roworiented = flg; 1987d71ae5a4SJacob Faibussowitsch break; 1988512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 1989b5a2b587SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 19903971808eSMatthew Knepley case MAT_NEW_NONZERO_ALLOCATION_ERR: 19918c78258cSHong Zhang case MAT_FORCE_DIAGONAL_ENTRIES: 199213fa8e87SLisandro Dalcin case MAT_KEEP_NONZERO_PATTERN: 1993b5a2b587SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 1994b5a2b587SKris Buschelman case MAT_USE_HASH_TABLE: 19950f8fb01aSBarry Smith case MAT_IGNORE_ZERO_ENTRIES: 19965021d80fSJed Brown case MAT_IGNORE_LOWER_TRIANGULAR: 1997d71ae5a4SJacob Faibussowitsch case MAT_SORTED_FULL: 1998d71ae5a4SJacob Faibussowitsch PetscCall(PetscInfo(A, "Option %s ignored\n", MatOptions[op])); 1999d71ae5a4SJacob Faibussowitsch break; 20005021d80fSJed Brown case MAT_SPD: 200177e54ba9SKris Buschelman case MAT_SYMMETRIC: 200277e54ba9SKris Buschelman case MAT_STRUCTURALLY_SYMMETRIC: 20039a4540c5SBarry Smith case MAT_HERMITIAN: 20049a4540c5SBarry Smith case MAT_SYMMETRY_ETERNAL: 2005b94d7dedSBarry Smith case MAT_STRUCTURAL_SYMMETRY_ETERNAL: 2006d71ae5a4SJacob Faibussowitsch case MAT_SPD_ETERNAL: 2007d71ae5a4SJacob Faibussowitsch break; 2008d71ae5a4SJacob Faibussowitsch default: 2009d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "unknown option %s", MatOptions[op]); 20103a40ed3dSBarry Smith } 20113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2012289bc588SBarry Smith } 2013289bc588SBarry Smith 2014d71ae5a4SJacob Faibussowitsch PetscErrorCode MatZeroEntries_SeqDense(Mat A) 2015d71ae5a4SJacob Faibussowitsch { 2016ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)A->data; 20173d8925e7SStefano Zampini PetscInt lda = l->lda, m = A->rmap->n, n = A->cmap->n, j; 2018ca15aa20SStefano Zampini PetscScalar *v; 20193a40ed3dSBarry Smith 20203a40ed3dSBarry Smith PetscFunctionBegin; 20219566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(A, &v)); 2022a5ce6ee0Svictorle if (lda > m) { 202348a46eb9SPierre Jolivet for (j = 0; j < n; j++) PetscCall(PetscArrayzero(v + j * lda, m)); 2024a5ce6ee0Svictorle } else { 20259566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(v, PetscInt64Mult(m, n))); 2026a5ce6ee0Svictorle } 20279566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(A, &v)); 20283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 20296f0a148fSBarry Smith } 20306f0a148fSBarry Smith 2031d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatZeroRows_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) 2032d71ae5a4SJacob Faibussowitsch { 2033ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)A->data; 2034b9679d65SBarry Smith PetscInt m = l->lda, n = A->cmap->n, i, j; 2035ca15aa20SStefano Zampini PetscScalar *slot, *bb, *v; 203697b48c8fSBarry Smith const PetscScalar *xx; 203755659b69SBarry Smith 20383a40ed3dSBarry Smith PetscFunctionBegin; 203976bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 2040b9679d65SBarry Smith for (i = 0; i < N; i++) { 204108401ef6SPierre Jolivet PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed"); 204208401ef6SPierre 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); 2043b9679d65SBarry Smith } 204476bd3646SJed Brown } 20453ba16761SJacob Faibussowitsch if (!N) PetscFunctionReturn(PETSC_SUCCESS); 2046b9679d65SBarry Smith 204797b48c8fSBarry Smith /* fix right hand side if needed */ 204897b48c8fSBarry Smith if (x && b) { 20499566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 20509566063dSJacob Faibussowitsch PetscCall(VecGetArray(b, &bb)); 20512205254eSKarl Rupp for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]]; 20529566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 20539566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(b, &bb)); 205497b48c8fSBarry Smith } 205597b48c8fSBarry Smith 20569566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 20576f0a148fSBarry Smith for (i = 0; i < N; i++) { 2058ca15aa20SStefano Zampini slot = v + rows[i]; 20599371c9d4SSatish Balay for (j = 0; j < n; j++) { 20609371c9d4SSatish Balay *slot = 0.0; 20619371c9d4SSatish Balay slot += m; 20629371c9d4SSatish Balay } 20636f0a148fSBarry Smith } 2064f4df32b1SMatthew Knepley if (diag != 0.0) { 206508401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices"); 20666f0a148fSBarry Smith for (i = 0; i < N; i++) { 2067ca15aa20SStefano Zampini slot = v + (m + 1) * rows[i]; 2068f4df32b1SMatthew Knepley *slot = diag; 20696f0a148fSBarry Smith } 20706f0a148fSBarry Smith } 20719566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 20723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 20736f0a148fSBarry Smith } 2074557bce09SLois Curfman McInnes 2075d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A, PetscInt *lda) 2076d71ae5a4SJacob Faibussowitsch { 207749a6ff4bSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 207849a6ff4bSBarry Smith 207949a6ff4bSBarry Smith PetscFunctionBegin; 208049a6ff4bSBarry Smith *lda = mat->lda; 20813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 208249a6ff4bSBarry Smith } 208349a6ff4bSBarry Smith 2084d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArray_SeqDense(Mat A, PetscScalar **array) 2085d71ae5a4SJacob Faibussowitsch { 2086c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 20873a40ed3dSBarry Smith 20883a40ed3dSBarry Smith PetscFunctionBegin; 208928b400f6SJacob Faibussowitsch PetscCheck(!mat->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 209064e87e97SBarry Smith *array = mat->v; 20913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 209264e87e97SBarry Smith } 20930754003eSLois Curfman McInnes 2094d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A, PetscScalar **array) 2095d71ae5a4SJacob Faibussowitsch { 20963a40ed3dSBarry Smith PetscFunctionBegin; 209775f6d85dSStefano Zampini if (array) *array = NULL; 20983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2099ff14e315SSatish Balay } 21000754003eSLois Curfman McInnes 21010f74d2c1SSatish Balay /*@ 210211a5261eSBarry Smith MatDenseGetLDA - gets the leading dimension of the array returned from `MatDenseGetArray()` 210349a6ff4bSBarry Smith 21042ef1f0ffSBarry Smith Not Collective 210549a6ff4bSBarry Smith 210649a6ff4bSBarry Smith Input Parameter: 210711a5261eSBarry Smith . mat - a `MATDENSE` or `MATDENSECUDA` matrix 210849a6ff4bSBarry Smith 210949a6ff4bSBarry Smith Output Parameter: 211049a6ff4bSBarry Smith . lda - the leading dimension 211149a6ff4bSBarry Smith 211249a6ff4bSBarry Smith Level: intermediate 211349a6ff4bSBarry Smith 2114*1cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseSetLDA()` 211549a6ff4bSBarry Smith @*/ 2116d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetLDA(Mat A, PetscInt *lda) 2117d71ae5a4SJacob Faibussowitsch { 211849a6ff4bSBarry Smith PetscFunctionBegin; 2119d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2120dadcf809SJacob Faibussowitsch PetscValidIntPointer(lda, 2); 212175f6d85dSStefano Zampini MatCheckPreallocated(A, 1); 2122cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetLDA_C", (Mat, PetscInt *), (A, lda)); 21233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 212449a6ff4bSBarry Smith } 212549a6ff4bSBarry Smith 21260f74d2c1SSatish Balay /*@ 212711a5261eSBarry Smith MatDenseSetLDA - Sets the leading dimension of the array used by the `MATDENSE` matrix 2128ad16ce7aSStefano Zampini 21292ef1f0ffSBarry Smith Not Collective 2130ad16ce7aSStefano Zampini 2131d8d19677SJose E. Roman Input Parameters: 213211a5261eSBarry Smith + mat - a `MATDENSE` or `MATDENSECUDA` matrix 2133ad16ce7aSStefano Zampini - lda - the leading dimension 2134ad16ce7aSStefano Zampini 2135ad16ce7aSStefano Zampini Level: intermediate 2136ad16ce7aSStefano Zampini 2137*1cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetLDA()` 2138ad16ce7aSStefano Zampini @*/ 2139d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA(Mat A, PetscInt lda) 2140d71ae5a4SJacob Faibussowitsch { 2141ad16ce7aSStefano Zampini PetscFunctionBegin; 2142ad16ce7aSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2143cac4c232SBarry Smith PetscTryMethod(A, "MatDenseSetLDA_C", (Mat, PetscInt), (A, lda)); 21443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2145ad16ce7aSStefano Zampini } 2146ad16ce7aSStefano Zampini 2147ad16ce7aSStefano Zampini /*@C 214811a5261eSBarry Smith MatDenseGetArray - gives read-write access to the array where the data for a `MATDENSE` matrix is stored 214973a71a0fSBarry Smith 2150c3339decSBarry Smith Logically Collective 215173a71a0fSBarry Smith 215273a71a0fSBarry Smith Input Parameter: 21536947451fSStefano Zampini . mat - a dense matrix 215473a71a0fSBarry Smith 215573a71a0fSBarry Smith Output Parameter: 215673a71a0fSBarry Smith . array - pointer to the data 215773a71a0fSBarry Smith 215873a71a0fSBarry Smith Level: intermediate 215973a71a0fSBarry Smith 21600ab4885dSBarry Smith Fortran Note: 21610ab4885dSBarry Smith `MatDenseGetArray()` Fortran binding is deprecated (since PETSc 3.19), use `MatDenseGetArrayF90()` 21620ab4885dSBarry Smith 2163*1cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 216473a71a0fSBarry Smith @*/ 2165d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArray(Mat A, PetscScalar **array) 2166d71ae5a4SJacob Faibussowitsch { 216773a71a0fSBarry Smith PetscFunctionBegin; 2168d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2169d5ea218eSStefano Zampini PetscValidPointer(array, 2); 2170cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array)); 21713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 217273a71a0fSBarry Smith } 217373a71a0fSBarry Smith 2174dec5eb66SMatthew G Knepley /*@C 217511a5261eSBarry Smith MatDenseRestoreArray - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArray()` 217673a71a0fSBarry Smith 2177c3339decSBarry Smith Logically Collective 21788572280aSBarry Smith 21798572280aSBarry Smith Input Parameters: 21806947451fSStefano Zampini + mat - a dense matrix 21812ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`) 21828572280aSBarry Smith 21838572280aSBarry Smith Level: intermediate 21848572280aSBarry Smith 21850ab4885dSBarry Smith Fortran Note: 21860ab4885dSBarry Smith `MatDenseRestoreArray()` Fortran binding is deprecated (since PETSc 3.19), use `MatDenseRestoreArrayF90()` 21870ab4885dSBarry Smith 2188*1cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 21898572280aSBarry Smith @*/ 2190d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArray(Mat A, PetscScalar **array) 2191d71ae5a4SJacob Faibussowitsch { 21928572280aSBarry Smith PetscFunctionBegin; 2193d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 219403858510SHong Zhang if (array) PetscValidPointer(array, 2); 2195cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array)); 21969566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)A)); 219747d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 2198637a0070SStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 2199637a0070SStefano Zampini #endif 22003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22018572280aSBarry Smith } 22028572280aSBarry Smith 22038572280aSBarry Smith /*@C 220411a5261eSBarry Smith MatDenseGetArrayRead - gives read-only access to the array where the data for a `MATDENSE` matrix is stored 22058572280aSBarry Smith 22060ab4885dSBarry Smith Not Collective; No Fortran Support 22078572280aSBarry Smith 22088572280aSBarry Smith Input Parameter: 22096947451fSStefano Zampini . mat - a dense matrix 22108572280aSBarry Smith 22118572280aSBarry Smith Output Parameter: 22128572280aSBarry Smith . array - pointer to the data 22138572280aSBarry Smith 22148572280aSBarry Smith Level: intermediate 22158572280aSBarry Smith 2216*1cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 22178572280aSBarry Smith @*/ 2218d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArrayRead(Mat A, const PetscScalar **array) 2219d71ae5a4SJacob Faibussowitsch { 22208572280aSBarry Smith PetscFunctionBegin; 2221d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2222d5ea218eSStefano Zampini PetscValidPointer(array, 2); 2223cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, const PetscScalar **), (A, array)); 22243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22258572280aSBarry Smith } 22268572280aSBarry Smith 22278572280aSBarry Smith /*@C 222811a5261eSBarry Smith MatDenseRestoreArrayRead - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayRead()` 22298572280aSBarry Smith 22300ab4885dSBarry Smith Not Collective; No Fortran Support 223173a71a0fSBarry Smith 223273a71a0fSBarry Smith Input Parameters: 22336947451fSStefano Zampini + mat - a dense matrix 22342ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`) 223573a71a0fSBarry Smith 223673a71a0fSBarry Smith Level: intermediate 223773a71a0fSBarry Smith 2238*1cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 223973a71a0fSBarry Smith @*/ 2240d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArrayRead(Mat A, const PetscScalar **array) 2241d71ae5a4SJacob Faibussowitsch { 224273a71a0fSBarry Smith PetscFunctionBegin; 2243d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 224403858510SHong Zhang if (array) PetscValidPointer(array, 2); 2245cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, const PetscScalar **), (A, array)); 22463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 224773a71a0fSBarry Smith } 224873a71a0fSBarry Smith 22496947451fSStefano Zampini /*@C 225011a5261eSBarry Smith MatDenseGetArrayWrite - gives write-only access to the array where the data for a `MATDENSE` matrix is stored 22516947451fSStefano Zampini 22520ab4885dSBarry Smith Not Collective; No Fortran Support 22536947451fSStefano Zampini 22546947451fSStefano Zampini Input Parameter: 22556947451fSStefano Zampini . mat - a dense matrix 22566947451fSStefano Zampini 22576947451fSStefano Zampini Output Parameter: 22586947451fSStefano Zampini . array - pointer to the data 22596947451fSStefano Zampini 22606947451fSStefano Zampini Level: intermediate 22616947451fSStefano Zampini 2262*1cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()` 22636947451fSStefano Zampini @*/ 2264d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArrayWrite(Mat A, PetscScalar **array) 2265d71ae5a4SJacob Faibussowitsch { 22666947451fSStefano Zampini PetscFunctionBegin; 2267d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2268d5ea218eSStefano Zampini PetscValidPointer(array, 2); 2269cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array)); 22703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22716947451fSStefano Zampini } 22726947451fSStefano Zampini 22736947451fSStefano Zampini /*@C 227411a5261eSBarry Smith MatDenseRestoreArrayWrite - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayWrite()` 22756947451fSStefano Zampini 22760ab4885dSBarry Smith Not Collective; No Fortran Support 22776947451fSStefano Zampini 22786947451fSStefano Zampini Input Parameters: 22796947451fSStefano Zampini + mat - a dense matrix 22802ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`) 22816947451fSStefano Zampini 22826947451fSStefano Zampini Level: intermediate 22836947451fSStefano Zampini 2284*1cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()` 22856947451fSStefano Zampini @*/ 2286d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArrayWrite(Mat A, PetscScalar **array) 2287d71ae5a4SJacob Faibussowitsch { 22886947451fSStefano Zampini PetscFunctionBegin; 2289d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 229003858510SHong Zhang if (array) PetscValidPointer(array, 2); 2291cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array)); 22929566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)A)); 229347d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 22946947451fSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 22956947451fSStefano Zampini #endif 22963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22976947451fSStefano Zampini } 22986947451fSStefano Zampini 2299cd3f9d89SJunchao Zhang /*@C 2300cd3f9d89SJunchao Zhang MatDenseGetArrayAndMemType - gives read-write access to the array where the data for a `MATDENSE` matrix is stored 2301cd3f9d89SJunchao Zhang 2302cd3f9d89SJunchao Zhang Logically Collective 2303cd3f9d89SJunchao Zhang 2304cd3f9d89SJunchao Zhang Input Parameter: 2305cd3f9d89SJunchao Zhang . mat - a dense matrix 2306cd3f9d89SJunchao Zhang 2307cd3f9d89SJunchao Zhang Output Parameters: 2308cd3f9d89SJunchao Zhang + array - pointer to the data 2309cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer 2310cd3f9d89SJunchao Zhang 2311cd3f9d89SJunchao Zhang Level: intermediate 2312cd3f9d89SJunchao Zhang 23132ef1f0ffSBarry Smith Notes: 23142ef1f0ffSBarry Smith If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc., 23152ef1f0ffSBarry Smith an array on device is always returned and is guaranteed to contain the matrix's latest data. 23162ef1f0ffSBarry Smith 2317*1cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayAndMemType()`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArrayWriteAndMemType()`, `MatDenseGetArrayRead()`, 2318cd3f9d89SJunchao Zhang `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()` 2319cd3f9d89SJunchao Zhang @*/ 2320cd3f9d89SJunchao Zhang PetscErrorCode MatDenseGetArrayAndMemType(Mat A, PetscScalar **array, PetscMemType *mtype) 2321cd3f9d89SJunchao Zhang { 2322cd3f9d89SJunchao Zhang PetscBool isMPI; 2323cd3f9d89SJunchao Zhang 2324cd3f9d89SJunchao Zhang PetscFunctionBegin; 2325cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2326cd3f9d89SJunchao Zhang PetscValidPointer(array, 2); 2327e865de01SJunchao 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 */ 2328cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2329cd3f9d89SJunchao Zhang if (isMPI) { 2330cd3f9d89SJunchao Zhang /* Dispatch here so that the code can be reused for all subclasses of MATDENSE */ 2331cd3f9d89SJunchao Zhang PetscCall(MatDenseGetArrayAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype)); 2332cd3f9d89SJunchao Zhang } else { 2333cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **, PetscMemType *); 23343ba16761SJacob Faibussowitsch 23353ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayAndMemType_C", &fptr)); 2336cd3f9d89SJunchao Zhang if (fptr) { 2337cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array, mtype)); 2338cd3f9d89SJunchao Zhang } else { 2339cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array)); 2340cd3f9d89SJunchao Zhang if (mtype) *mtype = PETSC_MEMTYPE_HOST; 2341cd3f9d89SJunchao Zhang } 2342cd3f9d89SJunchao Zhang } 23433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2344cd3f9d89SJunchao Zhang } 2345cd3f9d89SJunchao Zhang 2346cd3f9d89SJunchao Zhang /*@C 2347cd3f9d89SJunchao Zhang MatDenseRestoreArrayAndMemType - returns access to the array that is obtained by `MatDenseGetArrayAndMemType()` 2348cd3f9d89SJunchao Zhang 2349cd3f9d89SJunchao Zhang Logically Collective 2350cd3f9d89SJunchao Zhang 2351cd3f9d89SJunchao Zhang Input Parameters: 2352cd3f9d89SJunchao Zhang + mat - a dense matrix 2353cd3f9d89SJunchao Zhang - array - pointer to the data 2354cd3f9d89SJunchao Zhang 2355cd3f9d89SJunchao Zhang Level: intermediate 2356cd3f9d89SJunchao Zhang 2357*1cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 2358cd3f9d89SJunchao Zhang @*/ 2359cd3f9d89SJunchao Zhang PetscErrorCode MatDenseRestoreArrayAndMemType(Mat A, PetscScalar **array) 2360cd3f9d89SJunchao Zhang { 2361cd3f9d89SJunchao Zhang PetscBool isMPI; 2362cd3f9d89SJunchao Zhang 2363cd3f9d89SJunchao Zhang PetscFunctionBegin; 2364cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2365cd3f9d89SJunchao Zhang PetscValidPointer(array, 2); 2366cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2367cd3f9d89SJunchao Zhang if (isMPI) { 2368cd3f9d89SJunchao Zhang PetscCall(MatDenseRestoreArrayAndMemType(((Mat_MPIDense *)A->data)->A, array)); 2369cd3f9d89SJunchao Zhang } else { 2370cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **); 23713ba16761SJacob Faibussowitsch 23723ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayAndMemType_C", &fptr)); 2373cd3f9d89SJunchao Zhang if (fptr) { 2374cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array)); 2375cd3f9d89SJunchao Zhang } else { 2376cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array)); 2377cd3f9d89SJunchao Zhang } 2378cd3f9d89SJunchao Zhang *array = NULL; 2379cd3f9d89SJunchao Zhang } 2380cd3f9d89SJunchao Zhang PetscCall(PetscObjectStateIncrease((PetscObject)A)); 23813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2382cd3f9d89SJunchao Zhang } 2383cd3f9d89SJunchao Zhang 2384cd3f9d89SJunchao Zhang /*@C 2385cd3f9d89SJunchao Zhang MatDenseGetArrayReadAndMemType - gives read-only access to the array where the data for a `MATDENSE` matrix is stored 2386cd3f9d89SJunchao Zhang 2387cd3f9d89SJunchao Zhang Logically Collective 2388cd3f9d89SJunchao Zhang 2389cd3f9d89SJunchao Zhang Input Parameter: 2390cd3f9d89SJunchao Zhang . mat - a dense matrix 2391cd3f9d89SJunchao Zhang 2392cd3f9d89SJunchao Zhang Output Parameters: 2393cd3f9d89SJunchao Zhang + array - pointer to the data 2394cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer 2395cd3f9d89SJunchao Zhang 2396cd3f9d89SJunchao Zhang Level: intermediate 2397cd3f9d89SJunchao Zhang 23982ef1f0ffSBarry Smith Notes: 23992ef1f0ffSBarry Smith If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc., 24002ef1f0ffSBarry Smith an array on device is always returned and is guaranteed to contain the matrix's latest data. 24012ef1f0ffSBarry Smith 2402*1cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayReadAndMemType()`, `MatDenseGetArrayWriteAndMemType()`, 2403cd3f9d89SJunchao Zhang `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()` 2404cd3f9d89SJunchao Zhang @*/ 2405cd3f9d89SJunchao Zhang PetscErrorCode MatDenseGetArrayReadAndMemType(Mat A, const PetscScalar **array, PetscMemType *mtype) 2406cd3f9d89SJunchao Zhang { 2407cd3f9d89SJunchao Zhang PetscBool isMPI; 2408cd3f9d89SJunchao Zhang 2409cd3f9d89SJunchao Zhang PetscFunctionBegin; 2410cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2411cd3f9d89SJunchao Zhang PetscValidPointer(array, 2); 2412e865de01SJunchao 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 */ 2413cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2414cd3f9d89SJunchao Zhang if (isMPI) { /* Dispatch here so that the code can be reused for all subclasses of MATDENSE */ 2415cd3f9d89SJunchao Zhang PetscCall(MatDenseGetArrayReadAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype)); 2416cd3f9d89SJunchao Zhang } else { 2417cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, const PetscScalar **, PetscMemType *); 24183ba16761SJacob Faibussowitsch 24193ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayReadAndMemType_C", &fptr)); 2420cd3f9d89SJunchao Zhang if (fptr) { 2421cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array, mtype)); 2422cd3f9d89SJunchao Zhang } else { 2423cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, const PetscScalar **), (A, array)); 2424cd3f9d89SJunchao Zhang if (mtype) *mtype = PETSC_MEMTYPE_HOST; 2425cd3f9d89SJunchao Zhang } 2426cd3f9d89SJunchao Zhang } 24273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2428cd3f9d89SJunchao Zhang } 2429cd3f9d89SJunchao Zhang 2430cd3f9d89SJunchao Zhang /*@C 2431cd3f9d89SJunchao Zhang MatDenseRestoreArrayReadAndMemType - returns access to the array that is obtained by `MatDenseGetArrayReadAndMemType()` 2432cd3f9d89SJunchao Zhang 2433cd3f9d89SJunchao Zhang Logically Collective 2434cd3f9d89SJunchao Zhang 2435cd3f9d89SJunchao Zhang Input Parameters: 2436cd3f9d89SJunchao Zhang + mat - a dense matrix 2437cd3f9d89SJunchao Zhang - array - pointer to the data 2438cd3f9d89SJunchao Zhang 2439cd3f9d89SJunchao Zhang Level: intermediate 2440cd3f9d89SJunchao Zhang 2441*1cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 2442cd3f9d89SJunchao Zhang @*/ 2443cd3f9d89SJunchao Zhang PetscErrorCode MatDenseRestoreArrayReadAndMemType(Mat A, const PetscScalar **array) 2444cd3f9d89SJunchao Zhang { 2445cd3f9d89SJunchao Zhang PetscBool isMPI; 2446cd3f9d89SJunchao Zhang 2447cd3f9d89SJunchao Zhang PetscFunctionBegin; 2448cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2449cd3f9d89SJunchao Zhang PetscValidPointer(array, 2); 2450cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2451cd3f9d89SJunchao Zhang if (isMPI) { 2452cd3f9d89SJunchao Zhang PetscCall(MatDenseRestoreArrayReadAndMemType(((Mat_MPIDense *)A->data)->A, array)); 2453cd3f9d89SJunchao Zhang } else { 2454cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, const PetscScalar **); 24553ba16761SJacob Faibussowitsch 24563ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayReadAndMemType_C", &fptr)); 2457cd3f9d89SJunchao Zhang if (fptr) { 2458cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array)); 2459cd3f9d89SJunchao Zhang } else { 2460cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, const PetscScalar **), (A, array)); 2461cd3f9d89SJunchao Zhang } 2462cd3f9d89SJunchao Zhang *array = NULL; 2463cd3f9d89SJunchao Zhang } 24643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2465cd3f9d89SJunchao Zhang } 2466cd3f9d89SJunchao Zhang 2467cd3f9d89SJunchao Zhang /*@C 2468cd3f9d89SJunchao Zhang MatDenseGetArrayWriteAndMemType - gives write-only access to the array where the data for a `MATDENSE` matrix is stored 2469cd3f9d89SJunchao Zhang 2470cd3f9d89SJunchao Zhang Logically Collective 2471cd3f9d89SJunchao Zhang 2472cd3f9d89SJunchao Zhang Input Parameter: 2473cd3f9d89SJunchao Zhang . mat - a dense matrix 2474cd3f9d89SJunchao Zhang 2475cd3f9d89SJunchao Zhang Output Parameters: 2476cd3f9d89SJunchao Zhang + array - pointer to the data 2477cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer 2478cd3f9d89SJunchao Zhang 2479cd3f9d89SJunchao Zhang Level: intermediate 2480cd3f9d89SJunchao Zhang 24812ef1f0ffSBarry Smith Notes: 24822ef1f0ffSBarry Smith If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc., 24832ef1f0ffSBarry Smith an array on device is always returned and is guaranteed to contain the matrix's latest data. 24842ef1f0ffSBarry Smith 2485*1cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayWriteAndMemType()`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArrayRead()`, 2486cd3f9d89SJunchao Zhang `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()` 2487cd3f9d89SJunchao Zhang @*/ 2488cd3f9d89SJunchao Zhang PetscErrorCode MatDenseGetArrayWriteAndMemType(Mat A, PetscScalar **array, PetscMemType *mtype) 2489cd3f9d89SJunchao Zhang { 2490cd3f9d89SJunchao Zhang PetscBool isMPI; 2491cd3f9d89SJunchao Zhang 2492cd3f9d89SJunchao Zhang PetscFunctionBegin; 2493cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2494cd3f9d89SJunchao Zhang PetscValidPointer(array, 2); 2495e865de01SJunchao 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 */ 2496cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2497cd3f9d89SJunchao Zhang if (isMPI) { 2498cd3f9d89SJunchao Zhang PetscCall(MatDenseGetArrayWriteAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype)); 2499cd3f9d89SJunchao Zhang } else { 2500cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **, PetscMemType *); 25013ba16761SJacob Faibussowitsch 25023ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayWriteAndMemType_C", &fptr)); 2503cd3f9d89SJunchao Zhang if (fptr) { 2504cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array, mtype)); 2505cd3f9d89SJunchao Zhang } else { 2506cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array)); 2507cd3f9d89SJunchao Zhang if (mtype) *mtype = PETSC_MEMTYPE_HOST; 2508cd3f9d89SJunchao Zhang } 2509cd3f9d89SJunchao Zhang } 25103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2511cd3f9d89SJunchao Zhang } 2512cd3f9d89SJunchao Zhang 2513cd3f9d89SJunchao Zhang /*@C 2514cd3f9d89SJunchao Zhang MatDenseRestoreArrayWriteAndMemType - returns access to the array that is obtained by `MatDenseGetArrayReadAndMemType()` 2515cd3f9d89SJunchao Zhang 2516cd3f9d89SJunchao Zhang Logically Collective 2517cd3f9d89SJunchao Zhang 2518cd3f9d89SJunchao Zhang Input Parameters: 2519cd3f9d89SJunchao Zhang + mat - a dense matrix 2520cd3f9d89SJunchao Zhang - array - pointer to the data 2521cd3f9d89SJunchao Zhang 2522cd3f9d89SJunchao Zhang Level: intermediate 2523cd3f9d89SJunchao Zhang 2524*1cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayWriteAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 2525cd3f9d89SJunchao Zhang @*/ 2526cd3f9d89SJunchao Zhang PetscErrorCode MatDenseRestoreArrayWriteAndMemType(Mat A, PetscScalar **array) 2527cd3f9d89SJunchao Zhang { 2528cd3f9d89SJunchao Zhang PetscBool isMPI; 2529cd3f9d89SJunchao Zhang 2530cd3f9d89SJunchao Zhang PetscFunctionBegin; 2531cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2532cd3f9d89SJunchao Zhang PetscValidPointer(array, 2); 2533cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2534cd3f9d89SJunchao Zhang if (isMPI) { 2535cd3f9d89SJunchao Zhang PetscCall(MatDenseRestoreArrayWriteAndMemType(((Mat_MPIDense *)A->data)->A, array)); 2536cd3f9d89SJunchao Zhang } else { 2537cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **); 25383ba16761SJacob Faibussowitsch 25393ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayWriteAndMemType_C", &fptr)); 2540cd3f9d89SJunchao Zhang if (fptr) { 2541cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array)); 2542cd3f9d89SJunchao Zhang } else { 2543cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array)); 2544cd3f9d89SJunchao Zhang } 2545cd3f9d89SJunchao Zhang *array = NULL; 2546cd3f9d89SJunchao Zhang } 2547cd3f9d89SJunchao Zhang PetscCall(PetscObjectStateIncrease((PetscObject)A)); 25483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2549cd3f9d89SJunchao Zhang } 2550cd3f9d89SJunchao Zhang 2551d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A, IS isrow, IS iscol, MatReuse scall, Mat *B) 2552d71ae5a4SJacob Faibussowitsch { 2553c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 2554bf5a80bcSToby Isaac PetscInt i, j, nrows, ncols, ldb; 25555d0c19d7SBarry Smith const PetscInt *irow, *icol; 255687828ca2SBarry Smith PetscScalar *av, *bv, *v = mat->v; 25570754003eSLois Curfman McInnes Mat newmat; 25580754003eSLois Curfman McInnes 25593a40ed3dSBarry Smith PetscFunctionBegin; 25609566063dSJacob Faibussowitsch PetscCall(ISGetIndices(isrow, &irow)); 25619566063dSJacob Faibussowitsch PetscCall(ISGetIndices(iscol, &icol)); 25629566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(isrow, &nrows)); 25639566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(iscol, &ncols)); 25640754003eSLois Curfman McInnes 2565182d2002SSatish Balay /* Check submatrixcall */ 2566182d2002SSatish Balay if (scall == MAT_REUSE_MATRIX) { 256713f74950SBarry Smith PetscInt n_cols, n_rows; 25689566063dSJacob Faibussowitsch PetscCall(MatGetSize(*B, &n_rows, &n_cols)); 256921a2c019SBarry Smith if (n_rows != nrows || n_cols != ncols) { 2570f746d493SDmitry Karpeev /* resize the result matrix to match number of requested rows/columns */ 25719566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*B, nrows, ncols, nrows, ncols)); 257221a2c019SBarry Smith } 2573182d2002SSatish Balay newmat = *B; 2574182d2002SSatish Balay } else { 25750754003eSLois Curfman McInnes /* Create and fill new matrix */ 25769566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &newmat)); 25779566063dSJacob Faibussowitsch PetscCall(MatSetSizes(newmat, nrows, ncols, nrows, ncols)); 25789566063dSJacob Faibussowitsch PetscCall(MatSetType(newmat, ((PetscObject)A)->type_name)); 25799566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(newmat, NULL)); 2580182d2002SSatish Balay } 2581182d2002SSatish Balay 2582182d2002SSatish Balay /* Now extract the data pointers and do the copy,column at a time */ 25839566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(newmat, &bv)); 25849566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(newmat, &ldb)); 2585182d2002SSatish Balay for (i = 0; i < ncols; i++) { 25866de62eeeSBarry Smith av = v + mat->lda * icol[i]; 2587ca15aa20SStefano Zampini for (j = 0; j < nrows; j++) bv[j] = av[irow[j]]; 2588bf5a80bcSToby Isaac bv += ldb; 25890754003eSLois Curfman McInnes } 25909566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(newmat, &bv)); 2591182d2002SSatish Balay 2592182d2002SSatish Balay /* Assemble the matrices so that the correct flags are set */ 25939566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(newmat, MAT_FINAL_ASSEMBLY)); 25949566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(newmat, MAT_FINAL_ASSEMBLY)); 25950754003eSLois Curfman McInnes 25960754003eSLois Curfman McInnes /* Free work space */ 25979566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(isrow, &irow)); 25989566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(iscol, &icol)); 2599182d2002SSatish Balay *B = newmat; 26003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26010754003eSLois Curfman McInnes } 26020754003eSLois Curfman McInnes 2603d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A, PetscInt n, const IS irow[], const IS icol[], MatReuse scall, Mat *B[]) 2604d71ae5a4SJacob Faibussowitsch { 260513f74950SBarry Smith PetscInt i; 2606905e6a2fSBarry Smith 26073a40ed3dSBarry Smith PetscFunctionBegin; 260848a46eb9SPierre Jolivet if (scall == MAT_INITIAL_MATRIX) PetscCall(PetscCalloc1(n, B)); 2609905e6a2fSBarry Smith 261048a46eb9SPierre Jolivet for (i = 0; i < n; i++) PetscCall(MatCreateSubMatrix_SeqDense(A, irow[i], icol[i], scall, &(*B)[i])); 26113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2612905e6a2fSBarry Smith } 2613905e6a2fSBarry Smith 2614d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat, MatAssemblyType mode) 2615d71ae5a4SJacob Faibussowitsch { 2616c0aa2d19SHong Zhang PetscFunctionBegin; 26173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2618c0aa2d19SHong Zhang } 2619c0aa2d19SHong Zhang 2620d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat, MatAssemblyType mode) 2621d71ae5a4SJacob Faibussowitsch { 2622c0aa2d19SHong Zhang PetscFunctionBegin; 26233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2624c0aa2d19SHong Zhang } 2625c0aa2d19SHong Zhang 2626d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCopy_SeqDense(Mat A, Mat B, MatStructure str) 2627d71ae5a4SJacob Faibussowitsch { 26284b0e389bSBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data; 2629ca15aa20SStefano Zampini const PetscScalar *va; 2630ca15aa20SStefano Zampini PetscScalar *vb; 2631d0f46423SBarry Smith PetscInt lda1 = a->lda, lda2 = b->lda, m = A->rmap->n, n = A->cmap->n, j; 26323a40ed3dSBarry Smith 26333a40ed3dSBarry Smith PetscFunctionBegin; 263433f4a19fSKris Buschelman /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */ 263533f4a19fSKris Buschelman if (A->ops->copy != B->ops->copy) { 26369566063dSJacob Faibussowitsch PetscCall(MatCopy_Basic(A, B, str)); 26373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26383a40ed3dSBarry Smith } 2639aed4548fSBarry Smith PetscCheck(m == B->rmap->n && n == B->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "size(B) != size(A)"); 26409566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &va)); 26419566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(B, &vb)); 2642a5ce6ee0Svictorle if (lda1 > m || lda2 > m) { 264348a46eb9SPierre Jolivet for (j = 0; j < n; j++) PetscCall(PetscArraycpy(vb + j * lda2, va + j * lda1, m)); 2644a5ce6ee0Svictorle } else { 26459566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(vb, va, A->rmap->n * A->cmap->n)); 2646a5ce6ee0Svictorle } 26479566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(B, &vb)); 26489566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &va)); 26499566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 26509566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 26513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2652273d9f13SBarry Smith } 2653273d9f13SBarry Smith 2654d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetUp_SeqDense(Mat A) 2655d71ae5a4SJacob Faibussowitsch { 2656273d9f13SBarry Smith PetscFunctionBegin; 26579566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 26589566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 265948a46eb9SPierre Jolivet if (!A->preallocated) PetscCall(MatSeqDenseSetPreallocation(A, NULL)); 26603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26614b0e389bSBarry Smith } 26624b0e389bSBarry Smith 2663d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatConjugate_SeqDense(Mat A) 2664d71ae5a4SJacob Faibussowitsch { 26654396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 266606c5243aSJose E. Roman PetscInt i, j; 26674396437dSToby Isaac PetscInt min = PetscMin(A->rmap->n, A->cmap->n); 2668ca15aa20SStefano Zampini PetscScalar *aa; 2669ba337c44SJed Brown 2670ba337c44SJed Brown PetscFunctionBegin; 26719566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 267206c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 267306c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscConj(aa[i + j * mat->lda]); 267406c5243aSJose E. Roman } 26759566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 26769371c9d4SSatish Balay if (mat->tau) 26779371c9d4SSatish Balay for (i = 0; i < min; i++) mat->tau[i] = PetscConj(mat->tau[i]); 26783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2679ba337c44SJed Brown } 2680ba337c44SJed Brown 2681d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRealPart_SeqDense(Mat A) 2682d71ae5a4SJacob Faibussowitsch { 268306c5243aSJose E. Roman Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 268406c5243aSJose E. Roman PetscInt i, j; 2685ca15aa20SStefano Zampini PetscScalar *aa; 2686ba337c44SJed Brown 2687ba337c44SJed Brown PetscFunctionBegin; 26889566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 268906c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 269006c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscRealPart(aa[i + j * mat->lda]); 269106c5243aSJose E. Roman } 26929566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 26933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2694ba337c44SJed Brown } 2695ba337c44SJed Brown 2696d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatImaginaryPart_SeqDense(Mat A) 2697d71ae5a4SJacob Faibussowitsch { 269806c5243aSJose E. Roman Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 269906c5243aSJose E. Roman PetscInt i, j; 2700ca15aa20SStefano Zampini PetscScalar *aa; 2701ba337c44SJed Brown 2702ba337c44SJed Brown PetscFunctionBegin; 27039566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 270406c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 270506c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscImaginaryPart(aa[i + j * mat->lda]); 270606c5243aSJose E. Roman } 27079566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 27083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2709ba337c44SJed Brown } 2710284134d9SBarry Smith 2711d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2712d71ae5a4SJacob Faibussowitsch { 2713d0f46423SBarry Smith PetscInt m = A->rmap->n, n = B->cmap->n; 271447d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 2715a9fe9ddaSSatish Balay 2716ee16a9a1SHong Zhang PetscFunctionBegin; 27179566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 271847d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 27199566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 272047d993e7Ssuyashtn #endif 272147d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 272247d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 272347d993e7Ssuyashtn #endif 27247a3c3d58SStefano Zampini if (!cisdense) { 27257a3c3d58SStefano Zampini PetscBool flg; 27267a3c3d58SStefano Zampini 27279566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 27289566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 27297a3c3d58SStefano Zampini } 27309566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 27313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2732ee16a9a1SHong Zhang } 2733a9fe9ddaSSatish Balay 2734d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2735d71ae5a4SJacob Faibussowitsch { 27366718818eSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data, *c = (Mat_SeqDense *)C->data; 27370805154bSBarry Smith PetscBLASInt m, n, k; 2738ca15aa20SStefano Zampini const PetscScalar *av, *bv; 2739ca15aa20SStefano Zampini PetscScalar *cv; 2740a9fe9ddaSSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 2741a9fe9ddaSSatish Balay 2742a9fe9ddaSSatish Balay PetscFunctionBegin; 27439566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 27449566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 27459566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 27463ba16761SJacob Faibussowitsch if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS); 27479566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 27489566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 27499566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2750792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("N", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 27519566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 27529566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 27539566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 27549566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 27553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2756a9fe9ddaSSatish Balay } 2757a9fe9ddaSSatish Balay 2758d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2759d71ae5a4SJacob Faibussowitsch { 276069f65d41SStefano Zampini PetscInt m = A->rmap->n, n = B->rmap->n; 276147d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 276269f65d41SStefano Zampini 276369f65d41SStefano Zampini PetscFunctionBegin; 27649566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 276547d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 27669566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 276747d993e7Ssuyashtn #endif 276847d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 276947d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 277047d993e7Ssuyashtn #endif 27717a3c3d58SStefano Zampini if (!cisdense) { 27727a3c3d58SStefano Zampini PetscBool flg; 27737a3c3d58SStefano Zampini 27749566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 27759566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 27767a3c3d58SStefano Zampini } 27779566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 27783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 277969f65d41SStefano Zampini } 278069f65d41SStefano Zampini 2781d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2782d71ae5a4SJacob Faibussowitsch { 278369f65d41SStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 278469f65d41SStefano Zampini Mat_SeqDense *b = (Mat_SeqDense *)B->data; 278569f65d41SStefano Zampini Mat_SeqDense *c = (Mat_SeqDense *)C->data; 27866718818eSStefano Zampini const PetscScalar *av, *bv; 27876718818eSStefano Zampini PetscScalar *cv; 278869f65d41SStefano Zampini PetscBLASInt m, n, k; 278969f65d41SStefano Zampini PetscScalar _DOne = 1.0, _DZero = 0.0; 279069f65d41SStefano Zampini 279169f65d41SStefano Zampini PetscFunctionBegin; 27929566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 27939566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 27949566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 27953ba16761SJacob Faibussowitsch if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS); 27969566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 27979566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 27989566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2799792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("N", "T", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 28009566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 28019566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 28029566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 28039566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 28043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 280569f65d41SStefano Zampini } 280669f65d41SStefano Zampini 2807d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2808d71ae5a4SJacob Faibussowitsch { 2809d0f46423SBarry Smith PetscInt m = A->cmap->n, n = B->cmap->n; 281047d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 2811a9fe9ddaSSatish Balay 2812ee16a9a1SHong Zhang PetscFunctionBegin; 28139566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 281447d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 28159566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 281647d993e7Ssuyashtn #endif 281747d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 281847d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 281947d993e7Ssuyashtn #endif 28207a3c3d58SStefano Zampini if (!cisdense) { 28217a3c3d58SStefano Zampini PetscBool flg; 28227a3c3d58SStefano Zampini 28239566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 28249566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 28257a3c3d58SStefano Zampini } 28269566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 28273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2828ee16a9a1SHong Zhang } 2829a9fe9ddaSSatish Balay 2830d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2831d71ae5a4SJacob Faibussowitsch { 2832a9fe9ddaSSatish Balay Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2833a9fe9ddaSSatish Balay Mat_SeqDense *b = (Mat_SeqDense *)B->data; 2834a9fe9ddaSSatish Balay Mat_SeqDense *c = (Mat_SeqDense *)C->data; 28356718818eSStefano Zampini const PetscScalar *av, *bv; 28366718818eSStefano Zampini PetscScalar *cv; 28370805154bSBarry Smith PetscBLASInt m, n, k; 2838a9fe9ddaSSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 2839a9fe9ddaSSatish Balay 2840a9fe9ddaSSatish Balay PetscFunctionBegin; 28419566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 28429566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 28439566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &k)); 28443ba16761SJacob Faibussowitsch if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS); 28459566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 28469566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 28479566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2848792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("T", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 28499566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 28509566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 28519566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 28529566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 28533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2854a9fe9ddaSSatish Balay } 2855985db425SBarry Smith 2856d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C) 2857d71ae5a4SJacob Faibussowitsch { 28584222ddf1SHong Zhang PetscFunctionBegin; 28594222ddf1SHong Zhang C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense; 28604222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AB; 28613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28624222ddf1SHong Zhang } 28634222ddf1SHong Zhang 2864d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C) 2865d71ae5a4SJacob Faibussowitsch { 28664222ddf1SHong Zhang PetscFunctionBegin; 28674222ddf1SHong Zhang C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense; 28684222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AtB; 28693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28704222ddf1SHong Zhang } 28714222ddf1SHong Zhang 2872d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C) 2873d71ae5a4SJacob Faibussowitsch { 28744222ddf1SHong Zhang PetscFunctionBegin; 28754222ddf1SHong Zhang C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense; 28764222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_ABt; 28773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28784222ddf1SHong Zhang } 28794222ddf1SHong Zhang 2880d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C) 2881d71ae5a4SJacob Faibussowitsch { 28824222ddf1SHong Zhang Mat_Product *product = C->product; 28834222ddf1SHong Zhang 28844222ddf1SHong Zhang PetscFunctionBegin; 28854222ddf1SHong Zhang switch (product->type) { 2886d71ae5a4SJacob Faibussowitsch case MATPRODUCT_AB: 2887d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_AB(C)); 2888d71ae5a4SJacob Faibussowitsch break; 2889d71ae5a4SJacob Faibussowitsch case MATPRODUCT_AtB: 2890d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_AtB(C)); 2891d71ae5a4SJacob Faibussowitsch break; 2892d71ae5a4SJacob Faibussowitsch case MATPRODUCT_ABt: 2893d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_ABt(C)); 2894d71ae5a4SJacob Faibussowitsch break; 2895d71ae5a4SJacob Faibussowitsch default: 2896d71ae5a4SJacob Faibussowitsch break; 28974222ddf1SHong Zhang } 28983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28994222ddf1SHong Zhang } 29004222ddf1SHong Zhang 2901d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMax_SeqDense(Mat A, Vec v, PetscInt idx[]) 2902d71ae5a4SJacob Faibussowitsch { 2903985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2904d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2905985db425SBarry Smith PetscScalar *x; 2906ca15aa20SStefano Zampini const PetscScalar *aa; 2907985db425SBarry Smith 2908985db425SBarry Smith PetscFunctionBegin; 290928b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29109566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29119566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 29129566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 291308401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2914985db425SBarry Smith for (i = 0; i < m; i++) { 29159371c9d4SSatish Balay x[i] = aa[i]; 29169371c9d4SSatish Balay if (idx) idx[i] = 0; 2917985db425SBarry Smith for (j = 1; j < n; j++) { 29189371c9d4SSatish Balay if (PetscRealPart(x[i]) < PetscRealPart(aa[i + a->lda * j])) { 29199371c9d4SSatish Balay x[i] = aa[i + a->lda * j]; 29209371c9d4SSatish Balay if (idx) idx[i] = j; 29219371c9d4SSatish Balay } 2922985db425SBarry Smith } 2923985db425SBarry Smith } 29249566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 29259566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 29263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2927985db425SBarry Smith } 2928985db425SBarry Smith 2929d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A, Vec v, PetscInt idx[]) 2930d71ae5a4SJacob Faibussowitsch { 2931985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2932d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2933985db425SBarry Smith PetscScalar *x; 2934985db425SBarry Smith PetscReal atmp; 2935ca15aa20SStefano Zampini const PetscScalar *aa; 2936985db425SBarry Smith 2937985db425SBarry Smith PetscFunctionBegin; 293828b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29399566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29409566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 29419566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 294208401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2943985db425SBarry Smith for (i = 0; i < m; i++) { 29449189402eSHong Zhang x[i] = PetscAbsScalar(aa[i]); 2945985db425SBarry Smith for (j = 1; j < n; j++) { 2946ca15aa20SStefano Zampini atmp = PetscAbsScalar(aa[i + a->lda * j]); 29479371c9d4SSatish Balay if (PetscAbsScalar(x[i]) < atmp) { 29489371c9d4SSatish Balay x[i] = atmp; 29499371c9d4SSatish Balay if (idx) idx[i] = j; 29509371c9d4SSatish Balay } 2951985db425SBarry Smith } 2952985db425SBarry Smith } 29539566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 29549566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 29553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2956985db425SBarry Smith } 2957985db425SBarry Smith 2958d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMin_SeqDense(Mat A, Vec v, PetscInt idx[]) 2959d71ae5a4SJacob Faibussowitsch { 2960985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2961d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2962985db425SBarry Smith PetscScalar *x; 2963ca15aa20SStefano Zampini const PetscScalar *aa; 2964985db425SBarry Smith 2965985db425SBarry Smith PetscFunctionBegin; 296628b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29679566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 29689566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29699566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 297008401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2971985db425SBarry Smith for (i = 0; i < m; i++) { 29729371c9d4SSatish Balay x[i] = aa[i]; 29739371c9d4SSatish Balay if (idx) idx[i] = 0; 2974985db425SBarry Smith for (j = 1; j < n; j++) { 29759371c9d4SSatish Balay if (PetscRealPart(x[i]) > PetscRealPart(aa[i + a->lda * j])) { 29769371c9d4SSatish Balay x[i] = aa[i + a->lda * j]; 29779371c9d4SSatish Balay if (idx) idx[i] = j; 29789371c9d4SSatish Balay } 2979985db425SBarry Smith } 2980985db425SBarry Smith } 29819566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 29829566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 29833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2984985db425SBarry Smith } 2985985db425SBarry Smith 2986d71ae5a4SJacob Faibussowitsch PetscErrorCode MatGetColumnVector_SeqDense(Mat A, Vec v, PetscInt col) 2987d71ae5a4SJacob Faibussowitsch { 29888d0534beSBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 29898d0534beSBarry Smith PetscScalar *x; 2990ca15aa20SStefano Zampini const PetscScalar *aa; 29918d0534beSBarry Smith 29928d0534beSBarry Smith PetscFunctionBegin; 299328b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29949566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 29959566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29969566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(x, aa + col * a->lda, A->rmap->n)); 29979566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 29989566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 29993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30008d0534beSBarry Smith } 30018d0534beSBarry Smith 3002d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatGetColumnReductions_SeqDense(Mat A, PetscInt type, PetscReal *reductions) 3003d71ae5a4SJacob Faibussowitsch { 30040716a85fSBarry Smith PetscInt i, j, m, n; 30051683a169SBarry Smith const PetscScalar *a; 30060716a85fSBarry Smith 30070716a85fSBarry Smith PetscFunctionBegin; 30089566063dSJacob Faibussowitsch PetscCall(MatGetSize(A, &m, &n)); 30099566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(reductions, n)); 30109566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &a)); 3011857cbf51SRichard Tran Mills if (type == NORM_2) { 30120716a85fSBarry Smith for (i = 0; i < n; i++) { 3013ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j] * a[j]); 30140716a85fSBarry Smith a += m; 30150716a85fSBarry Smith } 3016857cbf51SRichard Tran Mills } else if (type == NORM_1) { 30170716a85fSBarry Smith for (i = 0; i < n; i++) { 3018ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j]); 30190716a85fSBarry Smith a += m; 30200716a85fSBarry Smith } 3021857cbf51SRichard Tran Mills } else if (type == NORM_INFINITY) { 30220716a85fSBarry Smith for (i = 0; i < n; i++) { 3023ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] = PetscMax(PetscAbsScalar(a[j]), reductions[i]); 30240716a85fSBarry Smith a += m; 30250716a85fSBarry Smith } 3026857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_REALPART || type == REDUCTION_MEAN_REALPART) { 3027a873a8cdSSam Reynolds for (i = 0; i < n; i++) { 3028ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscRealPart(a[j]); 3029a873a8cdSSam Reynolds a += m; 3030a873a8cdSSam Reynolds } 3031857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_IMAGINARYPART || type == REDUCTION_MEAN_IMAGINARYPART) { 3032857cbf51SRichard Tran Mills for (i = 0; i < n; i++) { 3033ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscImaginaryPart(a[j]); 3034857cbf51SRichard Tran Mills a += m; 3035857cbf51SRichard Tran Mills } 3036857cbf51SRichard Tran Mills } else SETERRQ(PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Unknown reduction type"); 30379566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &a)); 3038857cbf51SRichard Tran Mills if (type == NORM_2) { 3039a873a8cdSSam Reynolds for (i = 0; i < n; i++) reductions[i] = PetscSqrtReal(reductions[i]); 3040857cbf51SRichard Tran Mills } else if (type == REDUCTION_MEAN_REALPART || type == REDUCTION_MEAN_IMAGINARYPART) { 3041a873a8cdSSam Reynolds for (i = 0; i < n; i++) reductions[i] /= m; 30420716a85fSBarry Smith } 30433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30440716a85fSBarry Smith } 30450716a85fSBarry Smith 3046d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetRandom_SeqDense(Mat x, PetscRandom rctx) 3047d71ae5a4SJacob Faibussowitsch { 304873a71a0fSBarry Smith PetscScalar *a; 3049637a0070SStefano Zampini PetscInt lda, m, n, i, j; 305073a71a0fSBarry Smith 305173a71a0fSBarry Smith PetscFunctionBegin; 30529566063dSJacob Faibussowitsch PetscCall(MatGetSize(x, &m, &n)); 30539566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(x, &lda)); 30543faff063SStefano Zampini PetscCall(MatDenseGetArrayWrite(x, &a)); 3055637a0070SStefano Zampini for (j = 0; j < n; j++) { 305648a46eb9SPierre Jolivet for (i = 0; i < m; i++) PetscCall(PetscRandomGetValue(rctx, a + j * lda + i)); 305773a71a0fSBarry Smith } 30583faff063SStefano Zampini PetscCall(MatDenseRestoreArrayWrite(x, &a)); 30593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 306073a71a0fSBarry Smith } 306173a71a0fSBarry Smith 3062d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A, PetscBool *missing, PetscInt *d) 3063d71ae5a4SJacob Faibussowitsch { 30643b49f96aSBarry Smith PetscFunctionBegin; 30653b49f96aSBarry Smith *missing = PETSC_FALSE; 30663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30673b49f96aSBarry Smith } 306873a71a0fSBarry Smith 3069ca15aa20SStefano Zampini /* vals is not const */ 3070d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A, PetscInt col, PetscScalar **vals) 3071d71ae5a4SJacob Faibussowitsch { 307286aefd0dSHong Zhang Mat_SeqDense *a = (Mat_SeqDense *)A->data; 3073ca15aa20SStefano Zampini PetscScalar *v; 307486aefd0dSHong Zhang 307586aefd0dSHong Zhang PetscFunctionBegin; 307628b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 30779566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 3078ca15aa20SStefano Zampini *vals = v + col * a->lda; 30799566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 30803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 308186aefd0dSHong Zhang } 308286aefd0dSHong Zhang 3083d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A, PetscScalar **vals) 3084d71ae5a4SJacob Faibussowitsch { 308586aefd0dSHong Zhang PetscFunctionBegin; 3086742765d3SMatthew Knepley if (vals) *vals = NULL; /* user cannot accidentally use the array later */ 30873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 308886aefd0dSHong Zhang } 3089abc3b08eSStefano Zampini 3090a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqDense, 3091905e6a2fSBarry Smith MatGetRow_SeqDense, 3092905e6a2fSBarry Smith MatRestoreRow_SeqDense, 3093905e6a2fSBarry Smith MatMult_SeqDense, 309497304618SKris Buschelman /* 4*/ MatMultAdd_SeqDense, 30957c922b88SBarry Smith MatMultTranspose_SeqDense, 30967c922b88SBarry Smith MatMultTransposeAdd_SeqDense, 3097f4259b30SLisandro Dalcin NULL, 3098f4259b30SLisandro Dalcin NULL, 3099f4259b30SLisandro Dalcin NULL, 3100f4259b30SLisandro Dalcin /* 10*/ NULL, 3101905e6a2fSBarry Smith MatLUFactor_SeqDense, 3102905e6a2fSBarry Smith MatCholeskyFactor_SeqDense, 310341f059aeSBarry Smith MatSOR_SeqDense, 3104ec8511deSBarry Smith MatTranspose_SeqDense, 310597304618SKris Buschelman /* 15*/ MatGetInfo_SeqDense, 3106905e6a2fSBarry Smith MatEqual_SeqDense, 3107905e6a2fSBarry Smith MatGetDiagonal_SeqDense, 3108905e6a2fSBarry Smith MatDiagonalScale_SeqDense, 3109905e6a2fSBarry Smith MatNorm_SeqDense, 3110c0aa2d19SHong Zhang /* 20*/ MatAssemblyBegin_SeqDense, 3111c0aa2d19SHong Zhang MatAssemblyEnd_SeqDense, 3112905e6a2fSBarry Smith MatSetOption_SeqDense, 3113905e6a2fSBarry Smith MatZeroEntries_SeqDense, 3114d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqDense, 3115f4259b30SLisandro Dalcin NULL, 3116f4259b30SLisandro Dalcin NULL, 3117f4259b30SLisandro Dalcin NULL, 3118f4259b30SLisandro Dalcin NULL, 31194994cf47SJed Brown /* 29*/ MatSetUp_SeqDense, 3120f4259b30SLisandro Dalcin NULL, 3121f4259b30SLisandro Dalcin NULL, 3122f4259b30SLisandro Dalcin NULL, 3123f4259b30SLisandro Dalcin NULL, 3124d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqDense, 3125f4259b30SLisandro Dalcin NULL, 3126f4259b30SLisandro Dalcin NULL, 3127f4259b30SLisandro Dalcin NULL, 3128f4259b30SLisandro Dalcin NULL, 3129d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqDense, 31307dae84e0SHong Zhang MatCreateSubMatrices_SeqDense, 3131f4259b30SLisandro Dalcin NULL, 31324b0e389bSBarry Smith MatGetValues_SeqDense, 3133a5ae1ecdSBarry Smith MatCopy_SeqDense, 3134d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqDense, 3135a5ae1ecdSBarry Smith MatScale_SeqDense, 31362f605a99SJose E. Roman MatShift_SeqDense, 3137f4259b30SLisandro Dalcin NULL, 31383f49a652SStefano Zampini MatZeroRowsColumns_SeqDense, 313973a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqDense, 3140f4259b30SLisandro Dalcin NULL, 3141f4259b30SLisandro Dalcin NULL, 3142f4259b30SLisandro Dalcin NULL, 3143f4259b30SLisandro Dalcin NULL, 3144f4259b30SLisandro Dalcin /* 54*/ NULL, 3145f4259b30SLisandro Dalcin NULL, 3146f4259b30SLisandro Dalcin NULL, 3147f4259b30SLisandro Dalcin NULL, 3148f4259b30SLisandro Dalcin NULL, 3149023c16fcSToby Isaac /* 59*/ MatCreateSubMatrix_SeqDense, 3150e03a110bSBarry Smith MatDestroy_SeqDense, 3151e03a110bSBarry Smith MatView_SeqDense, 3152f4259b30SLisandro Dalcin NULL, 3153f4259b30SLisandro Dalcin NULL, 3154f4259b30SLisandro Dalcin /* 64*/ NULL, 3155f4259b30SLisandro Dalcin NULL, 3156f4259b30SLisandro Dalcin NULL, 3157f4259b30SLisandro Dalcin NULL, 3158f4259b30SLisandro Dalcin NULL, 3159d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqDense, 3160f4259b30SLisandro Dalcin NULL, 3161f4259b30SLisandro Dalcin NULL, 3162f4259b30SLisandro Dalcin NULL, 3163f4259b30SLisandro Dalcin NULL, 3164f4259b30SLisandro Dalcin /* 74*/ NULL, 3165f4259b30SLisandro Dalcin NULL, 3166f4259b30SLisandro Dalcin NULL, 3167f4259b30SLisandro Dalcin NULL, 3168f4259b30SLisandro Dalcin NULL, 3169f4259b30SLisandro Dalcin /* 79*/ NULL, 3170f4259b30SLisandro Dalcin NULL, 3171f4259b30SLisandro Dalcin NULL, 3172f4259b30SLisandro Dalcin NULL, 31735bba2384SShri Abhyankar /* 83*/ MatLoad_SeqDense, 3174637a0070SStefano Zampini MatIsSymmetric_SeqDense, 31751cbb95d3SBarry Smith MatIsHermitian_SeqDense, 3176f4259b30SLisandro Dalcin NULL, 3177f4259b30SLisandro Dalcin NULL, 3178f4259b30SLisandro Dalcin NULL, 3179f4259b30SLisandro Dalcin /* 89*/ NULL, 3180f4259b30SLisandro Dalcin NULL, 3181a9fe9ddaSSatish Balay MatMatMultNumeric_SeqDense_SeqDense, 3182f4259b30SLisandro Dalcin NULL, 3183f4259b30SLisandro Dalcin NULL, 3184f4259b30SLisandro Dalcin /* 94*/ NULL, 3185f4259b30SLisandro Dalcin NULL, 3186f4259b30SLisandro Dalcin NULL, 318769f65d41SStefano Zampini MatMatTransposeMultNumeric_SeqDense_SeqDense, 3188f4259b30SLisandro Dalcin NULL, 31894222ddf1SHong Zhang /* 99*/ MatProductSetFromOptions_SeqDense, 3190f4259b30SLisandro Dalcin NULL, 3191f4259b30SLisandro Dalcin NULL, 3192ba337c44SJed Brown MatConjugate_SeqDense, 3193f4259b30SLisandro Dalcin NULL, 3194f4259b30SLisandro Dalcin /*104*/ NULL, 3195ba337c44SJed Brown MatRealPart_SeqDense, 3196ba337c44SJed Brown MatImaginaryPart_SeqDense, 3197f4259b30SLisandro Dalcin NULL, 3198f4259b30SLisandro Dalcin NULL, 3199f4259b30SLisandro Dalcin /*109*/ NULL, 3200f4259b30SLisandro Dalcin NULL, 32018d0534beSBarry Smith MatGetRowMin_SeqDense, 3202aabbc4fbSShri Abhyankar MatGetColumnVector_SeqDense, 32033b49f96aSBarry Smith MatMissingDiagonal_SeqDense, 3204f4259b30SLisandro Dalcin /*114*/ NULL, 3205f4259b30SLisandro Dalcin NULL, 3206f4259b30SLisandro Dalcin NULL, 3207f4259b30SLisandro Dalcin NULL, 3208f4259b30SLisandro Dalcin NULL, 3209f4259b30SLisandro Dalcin /*119*/ NULL, 3210f4259b30SLisandro Dalcin NULL, 3211f4259b30SLisandro Dalcin NULL, 3212f4259b30SLisandro Dalcin NULL, 3213f4259b30SLisandro Dalcin NULL, 3214f4259b30SLisandro Dalcin /*124*/ NULL, 3215a873a8cdSSam Reynolds MatGetColumnReductions_SeqDense, 3216f4259b30SLisandro Dalcin NULL, 3217f4259b30SLisandro Dalcin NULL, 3218f4259b30SLisandro Dalcin NULL, 3219f4259b30SLisandro Dalcin /*129*/ NULL, 3220f4259b30SLisandro Dalcin NULL, 3221f4259b30SLisandro Dalcin NULL, 322275648e8dSHong Zhang MatTransposeMatMultNumeric_SeqDense_SeqDense, 3223f4259b30SLisandro Dalcin NULL, 3224f4259b30SLisandro Dalcin /*134*/ NULL, 3225f4259b30SLisandro Dalcin NULL, 3226f4259b30SLisandro Dalcin NULL, 3227f4259b30SLisandro Dalcin NULL, 3228f4259b30SLisandro Dalcin NULL, 3229f4259b30SLisandro Dalcin /*139*/ NULL, 3230f4259b30SLisandro Dalcin NULL, 3231f4259b30SLisandro Dalcin NULL, 3232f4259b30SLisandro Dalcin NULL, 3233f4259b30SLisandro Dalcin NULL, 32344222ddf1SHong Zhang MatCreateMPIMatConcatenateSeqMat_SeqDense, 3235f4259b30SLisandro Dalcin /*145*/ NULL, 3236f4259b30SLisandro Dalcin NULL, 323799a7f59eSMark Adams NULL, 323899a7f59eSMark Adams NULL, 32397fb60732SBarry Smith NULL, 3240dec0b466SHong Zhang /*150*/ NULL, 3241dec0b466SHong Zhang NULL}; 324290ace30eSBarry Smith 32434b828684SBarry Smith /*@C 324411a5261eSBarry Smith MatCreateSeqDense - Creates a `MATSEQDENSE` that 32452ef1f0ffSBarry Smith is stored in column major order (the usual Fortran manner). Many 3246d65003e9SLois Curfman McInnes of the matrix operations use the BLAS and LAPACK routines. 3247289bc588SBarry Smith 3248d083f849SBarry Smith Collective 3249db81eaa0SLois Curfman McInnes 325020563c6bSBarry Smith Input Parameters: 325111a5261eSBarry Smith + comm - MPI communicator, set to `PETSC_COMM_SELF` 32520c775827SLois Curfman McInnes . m - number of rows 325318f449edSLois Curfman McInnes . n - number of columns 32542ef1f0ffSBarry Smith - data - optional location of matrix data in column major order. Use `NULL` for PETSc 3255dfc5480cSLois Curfman McInnes to control all matrix memory allocation. 325620563c6bSBarry Smith 325720563c6bSBarry Smith Output Parameter: 325844cd7ae7SLois Curfman McInnes . A - the matrix 325920563c6bSBarry Smith 32602ef1f0ffSBarry Smith Level: intermediate 32612ef1f0ffSBarry Smith 326211a5261eSBarry Smith Note: 326318f449edSLois Curfman McInnes The data input variable is intended primarily for Fortran programmers 326418f449edSLois Curfman McInnes who wish to allocate their own matrix memory space. Most users should 32652ef1f0ffSBarry Smith set `data` = `NULL`. 326618f449edSLois Curfman McInnes 3267*1cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()` 326820563c6bSBarry Smith @*/ 3269d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateSeqDense(MPI_Comm comm, PetscInt m, PetscInt n, PetscScalar *data, Mat *A) 3270d71ae5a4SJacob Faibussowitsch { 32713a40ed3dSBarry Smith PetscFunctionBegin; 32729566063dSJacob Faibussowitsch PetscCall(MatCreate(comm, A)); 32739566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*A, m, n, m, n)); 32749566063dSJacob Faibussowitsch PetscCall(MatSetType(*A, MATSEQDENSE)); 32759566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(*A, data)); 32763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3277273d9f13SBarry Smith } 3278273d9f13SBarry Smith 3279273d9f13SBarry Smith /*@C 328011a5261eSBarry Smith MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements of a `MATSEQDENSE` matrix 3281273d9f13SBarry Smith 3282d083f849SBarry Smith Collective 3283273d9f13SBarry Smith 3284273d9f13SBarry Smith Input Parameters: 32851c4f3114SJed Brown + B - the matrix 32862ef1f0ffSBarry Smith - data - the array (or `NULL`) 32872ef1f0ffSBarry Smith 32882ef1f0ffSBarry Smith Level: intermediate 3289273d9f13SBarry Smith 329011a5261eSBarry Smith Note: 3291273d9f13SBarry Smith The data input variable is intended primarily for Fortran programmers 3292273d9f13SBarry Smith who wish to allocate their own matrix memory space. Most users should 3293284134d9SBarry Smith need not call this routine. 3294273d9f13SBarry Smith 3295*1cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()`, `MatDenseSetLDA()` 3296273d9f13SBarry Smith @*/ 3297d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation(Mat B, PetscScalar data[]) 3298d71ae5a4SJacob Faibussowitsch { 3299a23d5eceSKris Buschelman PetscFunctionBegin; 3300d5ea218eSStefano Zampini PetscValidHeaderSpecific(B, MAT_CLASSID, 1); 3301cac4c232SBarry Smith PetscTryMethod(B, "MatSeqDenseSetPreallocation_C", (Mat, PetscScalar[]), (B, data)); 33023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3303a23d5eceSKris Buschelman } 3304a23d5eceSKris Buschelman 3305d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation_SeqDense(Mat B, PetscScalar *data) 3306d71ae5a4SJacob Faibussowitsch { 3307ad16ce7aSStefano Zampini Mat_SeqDense *b = (Mat_SeqDense *)B->data; 3308273d9f13SBarry Smith 3309273d9f13SBarry Smith PetscFunctionBegin; 331028b400f6SJacob Faibussowitsch PetscCheck(!b->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3311273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 3312a868139aSShri Abhyankar 33139566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(B->rmap)); 33149566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(B->cmap)); 331534ef9618SShri Abhyankar 3316ad16ce7aSStefano Zampini if (b->lda <= 0) b->lda = B->rmap->n; 331786d161a7SShri Abhyankar 33189e8f95c4SLisandro Dalcin if (!data) { /* petsc-allocated storage */ 33199566063dSJacob Faibussowitsch if (!b->user_alloc) PetscCall(PetscFree(b->v)); 33209566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((size_t)b->lda * B->cmap->n, &b->v)); 33212205254eSKarl Rupp 33229e8f95c4SLisandro Dalcin b->user_alloc = PETSC_FALSE; 3323273d9f13SBarry Smith } else { /* user-allocated storage */ 33249566063dSJacob Faibussowitsch if (!b->user_alloc) PetscCall(PetscFree(b->v)); 3325273d9f13SBarry Smith b->v = data; 3326273d9f13SBarry Smith b->user_alloc = PETSC_TRUE; 3327273d9f13SBarry Smith } 33280450473dSBarry Smith B->assembled = PETSC_TRUE; 33293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3330273d9f13SBarry Smith } 3331273d9f13SBarry Smith 333265b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 3333d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) 3334d71ae5a4SJacob Faibussowitsch { 3335d77f618aSHong Zhang Mat mat_elemental; 33361683a169SBarry Smith const PetscScalar *array; 33371683a169SBarry Smith PetscScalar *v_colwise; 3338d77f618aSHong Zhang PetscInt M = A->rmap->N, N = A->cmap->N, i, j, k, *rows, *cols; 3339d77f618aSHong Zhang 33408baccfbdSHong Zhang PetscFunctionBegin; 33419566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(M * N, &v_colwise, M, &rows, N, &cols)); 33429566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &array)); 3343d77f618aSHong Zhang /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */ 3344d77f618aSHong Zhang k = 0; 3345d77f618aSHong Zhang for (j = 0; j < N; j++) { 3346d77f618aSHong Zhang cols[j] = j; 3347ad540459SPierre Jolivet for (i = 0; i < M; i++) v_colwise[j * M + i] = array[k++]; 3348d77f618aSHong Zhang } 3349ad540459SPierre Jolivet for (i = 0; i < M; i++) rows[i] = i; 33509566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &array)); 3351d77f618aSHong Zhang 33529566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental)); 33539566063dSJacob Faibussowitsch PetscCall(MatSetSizes(mat_elemental, PETSC_DECIDE, PETSC_DECIDE, M, N)); 33549566063dSJacob Faibussowitsch PetscCall(MatSetType(mat_elemental, MATELEMENTAL)); 33559566063dSJacob Faibussowitsch PetscCall(MatSetUp(mat_elemental)); 3356d77f618aSHong Zhang 3357d77f618aSHong Zhang /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */ 33589566063dSJacob Faibussowitsch PetscCall(MatSetValues(mat_elemental, M, rows, N, cols, v_colwise, ADD_VALUES)); 33599566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY)); 33609566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY)); 33619566063dSJacob Faibussowitsch PetscCall(PetscFree3(v_colwise, rows, cols)); 3362d77f618aSHong Zhang 3363511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 33649566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A, &mat_elemental)); 3365d77f618aSHong Zhang } else { 3366d77f618aSHong Zhang *newmat = mat_elemental; 3367d77f618aSHong Zhang } 33683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 33698baccfbdSHong Zhang } 337065b80a83SHong Zhang #endif 33718baccfbdSHong Zhang 3372d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA_SeqDense(Mat B, PetscInt lda) 3373d71ae5a4SJacob Faibussowitsch { 33741b807ce4Svictorle Mat_SeqDense *b = (Mat_SeqDense *)B->data; 33757422da62SJose E. Roman PetscBool data; 337621a2c019SBarry Smith 33771b807ce4Svictorle PetscFunctionBegin; 33787422da62SJose E. Roman data = (PetscBool)((B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE); 3379aed4548fSBarry Smith PetscCheck(b->user_alloc || !data || b->lda == lda, PETSC_COMM_SELF, PETSC_ERR_ORDER, "LDA cannot be changed after allocation of internal storage"); 338008401ef6SPierre 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); 33811b807ce4Svictorle b->lda = lda; 33823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 33831b807ce4Svictorle } 33841b807ce4Svictorle 3385d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm, Mat inmat, PetscInt n, MatReuse scall, Mat *outmat) 3386d71ae5a4SJacob Faibussowitsch { 3387d528f656SJakub Kruzik PetscFunctionBegin; 33889566063dSJacob Faibussowitsch PetscCall(MatCreateMPIMatConcatenateSeqMat_MPIDense(comm, inmat, n, scall, outmat)); 33893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3390d528f656SJakub Kruzik } 3391d528f656SJakub Kruzik 3392d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A, PetscInt col, Vec *v) 3393d71ae5a4SJacob Faibussowitsch { 33946947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 33956947451fSStefano Zampini 33966947451fSStefano Zampini PetscFunctionBegin; 339728b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 339828b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 33994dfa11a4SJacob Faibussowitsch if (!a->cvec) { PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec)); } 34006947451fSStefano Zampini a->vecinuse = col + 1; 34019566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, (PetscScalar **)&a->ptrinuse)); 34029566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda)); 34036947451fSStefano Zampini *v = a->cvec; 34043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34056947451fSStefano Zampini } 34066947451fSStefano Zampini 3407d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A, PetscInt col, Vec *v) 3408d71ae5a4SJacob Faibussowitsch { 34096947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34106947451fSStefano Zampini 34116947451fSStefano Zampini PetscFunctionBegin; 341228b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 341328b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 34146947451fSStefano Zampini a->vecinuse = 0; 34159566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, (PetscScalar **)&a->ptrinuse)); 34169566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 341775f6d85dSStefano Zampini if (v) *v = NULL; 34183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34196947451fSStefano Zampini } 34206947451fSStefano Zampini 3421d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v) 3422d71ae5a4SJacob Faibussowitsch { 34236947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34246947451fSStefano Zampini 34256947451fSStefano Zampini PetscFunctionBegin; 342628b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 342728b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 34284dfa11a4SJacob Faibussowitsch if (!a->cvec) { PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec)); } 34296947451fSStefano Zampini a->vecinuse = col + 1; 34309566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &a->ptrinuse)); 34319566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda)); 34329566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(a->cvec)); 34336947451fSStefano Zampini *v = a->cvec; 34343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34356947451fSStefano Zampini } 34366947451fSStefano Zampini 3437d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v) 3438d71ae5a4SJacob Faibussowitsch { 34396947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34406947451fSStefano Zampini 34416947451fSStefano Zampini PetscFunctionBegin; 344228b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 344328b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 34446947451fSStefano Zampini a->vecinuse = 0; 34459566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &a->ptrinuse)); 34469566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(a->cvec)); 34479566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 344875f6d85dSStefano Zampini if (v) *v = NULL; 34493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34506947451fSStefano Zampini } 34516947451fSStefano Zampini 3452d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v) 3453d71ae5a4SJacob Faibussowitsch { 34546947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34556947451fSStefano Zampini 34566947451fSStefano Zampini PetscFunctionBegin; 345728b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 345828b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3459aa624791SPierre Jolivet if (!a->cvec) PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec)); 34606947451fSStefano Zampini a->vecinuse = col + 1; 34619566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(A, (PetscScalar **)&a->ptrinuse)); 34629566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda)); 34636947451fSStefano Zampini *v = a->cvec; 34643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34656947451fSStefano Zampini } 34666947451fSStefano Zampini 3467d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v) 3468d71ae5a4SJacob Faibussowitsch { 34696947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34706947451fSStefano Zampini 34716947451fSStefano Zampini PetscFunctionBegin; 347228b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 347328b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 34746947451fSStefano Zampini a->vecinuse = 0; 34759566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(A, (PetscScalar **)&a->ptrinuse)); 34769566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 347775f6d85dSStefano Zampini if (v) *v = NULL; 34783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34796947451fSStefano Zampini } 34806947451fSStefano Zampini 3481d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) 3482d71ae5a4SJacob Faibussowitsch { 34835ea7661aSPierre Jolivet Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34845ea7661aSPierre Jolivet 34855ea7661aSPierre Jolivet PetscFunctionBegin; 348628b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 348728b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3488a2748737SPierre Jolivet if (a->cmat && (cend - cbegin != a->cmat->cmap->N || rend - rbegin != a->cmat->rmap->N)) PetscCall(MatDestroy(&a->cmat)); 34895ea7661aSPierre Jolivet if (!a->cmat) { 3490a2748737SPierre Jolivet PetscCall(MatCreateDense(PetscObjectComm((PetscObject)A), rend - rbegin, PETSC_DECIDE, rend - rbegin, cend - cbegin, a->v + rbegin + (size_t)cbegin * a->lda, &a->cmat)); 34915ea7661aSPierre Jolivet } else { 3492a2748737SPierre Jolivet PetscCall(MatDensePlaceArray(a->cmat, a->v + rbegin + (size_t)cbegin * a->lda)); 34935ea7661aSPierre Jolivet } 34949566063dSJacob Faibussowitsch PetscCall(MatDenseSetLDA(a->cmat, a->lda)); 34955ea7661aSPierre Jolivet a->matinuse = cbegin + 1; 34965ea7661aSPierre Jolivet *v = a->cmat; 349747d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 349875f6d85dSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 349975f6d85dSStefano Zampini #endif 35003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35015ea7661aSPierre Jolivet } 35025ea7661aSPierre Jolivet 3503d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A, Mat *v) 3504d71ae5a4SJacob Faibussowitsch { 35055ea7661aSPierre Jolivet Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35065ea7661aSPierre Jolivet 35075ea7661aSPierre Jolivet PetscFunctionBegin; 350828b400f6SJacob Faibussowitsch PetscCheck(a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetSubMatrix() first"); 350928b400f6SJacob Faibussowitsch PetscCheck(a->cmat, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column matrix"); 351008401ef6SPierre Jolivet PetscCheck(*v == a->cmat, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not the matrix obtained from MatDenseGetSubMatrix()"); 35115ea7661aSPierre Jolivet a->matinuse = 0; 35129566063dSJacob Faibussowitsch PetscCall(MatDenseResetArray(a->cmat)); 3513742765d3SMatthew Knepley if (v) *v = NULL; 351447d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 35153faff063SStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 35163faff063SStefano Zampini #endif 35173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35185ea7661aSPierre Jolivet } 35195ea7661aSPierre Jolivet 35200bad9183SKris Buschelman /*MC 3521fafad747SKris Buschelman MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices. 35220bad9183SKris Buschelman 35232ef1f0ffSBarry Smith Options Database Key: 352411a5261eSBarry Smith . -mat_type seqdense - sets the matrix type to `MATSEQDENSE` during a call to `MatSetFromOptions()` 35250bad9183SKris Buschelman 35260bad9183SKris Buschelman Level: beginner 35270bad9183SKris Buschelman 3528*1cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreateSeqDense()` 35290bad9183SKris Buschelman M*/ 3530d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreate_SeqDense(Mat B) 3531d71ae5a4SJacob Faibussowitsch { 3532273d9f13SBarry Smith Mat_SeqDense *b; 35337c334f02SBarry Smith PetscMPIInt size; 3534273d9f13SBarry Smith 3535273d9f13SBarry Smith PetscFunctionBegin; 35369566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)B), &size)); 353708401ef6SPierre Jolivet PetscCheck(size <= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Comm must be of size 1"); 353855659b69SBarry Smith 35394dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&b)); 35409566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(B->ops, &MatOps_Values, sizeof(struct _MatOps))); 354144cd7ae7SLois Curfman McInnes B->data = (void *)b; 354218f449edSLois Curfman McInnes 3543273d9f13SBarry Smith b->roworiented = PETSC_TRUE; 35444e220ebcSLois Curfman McInnes 35459566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatQRFactor_C", MatQRFactor_SeqDense)); 35469566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetLDA_C", MatDenseGetLDA_SeqDense)); 35479566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseSetLDA_C", MatDenseSetLDA_SeqDense)); 35489566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArray_C", MatDenseGetArray_SeqDense)); 35499566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArray_C", MatDenseRestoreArray_SeqDense)); 35509566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDensePlaceArray_C", MatDensePlaceArray_SeqDense)); 35519566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseResetArray_C", MatDenseResetArray_SeqDense)); 35529566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseReplaceArray_C", MatDenseReplaceArray_SeqDense)); 35539566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayRead_C", MatDenseGetArray_SeqDense)); 35549566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayRead_C", MatDenseRestoreArray_SeqDense)); 35559566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayWrite_C", MatDenseGetArray_SeqDense)); 35569566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayWrite_C", MatDenseRestoreArray_SeqDense)); 35579566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqaij_C", MatConvert_SeqDense_SeqAIJ)); 35588baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 35599566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_elemental_C", MatConvert_SeqDense_Elemental)); 35608baccfbdSHong Zhang #endif 3561d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 35629566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_scalapack_C", MatConvert_Dense_ScaLAPACK)); 3563d24d4204SJose E. Roman #endif 35642bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA) 35659566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensecuda_C", MatConvert_SeqDense_SeqDenseCUDA)); 35669566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", MatProductSetFromOptions_SeqDense)); 35679566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdense_C", MatProductSetFromOptions_SeqDense)); 35689566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensecuda_C", MatProductSetFromOptions_SeqDense)); 35692bf066beSStefano Zampini #endif 357047d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 357147d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensehip_C", MatConvert_SeqDense_SeqDenseHIP)); 357247d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensehip_seqdensehip_C", MatProductSetFromOptions_SeqDense)); 357347d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensehip_seqdense_C", MatProductSetFromOptions_SeqDense)); 357447d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensehip_C", MatProductSetFromOptions_SeqDense)); 357547d993e7Ssuyashtn #endif 35769566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSeqDenseSetPreallocation_C", MatSeqDenseSetPreallocation_SeqDense)); 35779566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqaij_seqdense_C", MatProductSetFromOptions_SeqAIJ_SeqDense)); 35789566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdense_C", MatProductSetFromOptions_SeqDense)); 35799566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense)); 35809566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqsbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense)); 358196e6d5c4SRichard Tran Mills 35829566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumn_C", MatDenseGetColumn_SeqDense)); 35839566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumn_C", MatDenseRestoreColumn_SeqDense)); 35849566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVec_C", MatDenseGetColumnVec_SeqDense)); 35859566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVec_C", MatDenseRestoreColumnVec_SeqDense)); 35869566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecRead_C", MatDenseGetColumnVecRead_SeqDense)); 35879566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecRead_C", MatDenseRestoreColumnVecRead_SeqDense)); 35889566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecWrite_C", MatDenseGetColumnVecWrite_SeqDense)); 35899566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecWrite_C", MatDenseRestoreColumnVecWrite_SeqDense)); 35909566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetSubMatrix_C", MatDenseGetSubMatrix_SeqDense)); 35919566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreSubMatrix_C", MatDenseRestoreSubMatrix_SeqDense)); 35929566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)B, MATSEQDENSE)); 35933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3594289bc588SBarry Smith } 359586aefd0dSHong Zhang 359686aefd0dSHong Zhang /*@C 359711a5261eSBarry 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. 359886aefd0dSHong Zhang 359986aefd0dSHong Zhang Not Collective 360086aefd0dSHong Zhang 36015ea7661aSPierre Jolivet Input Parameters: 360211a5261eSBarry Smith + mat - a `MATSEQDENSE` or `MATMPIDENSE` matrix 360386aefd0dSHong Zhang - col - column index 360486aefd0dSHong Zhang 360586aefd0dSHong Zhang Output Parameter: 360686aefd0dSHong Zhang . vals - pointer to the data 360786aefd0dSHong Zhang 360886aefd0dSHong Zhang Level: intermediate 360986aefd0dSHong Zhang 361011a5261eSBarry Smith Note: 361111a5261eSBarry Smith Use `MatDenseGetColumnVec()` to get access to a column of a `MATDENSE` treated as a `Vec` 361211a5261eSBarry Smith 3613*1cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreColumn()`, `MatDenseGetColumnVec()` 361486aefd0dSHong Zhang @*/ 3615d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumn(Mat A, PetscInt col, PetscScalar **vals) 3616d71ae5a4SJacob Faibussowitsch { 361786aefd0dSHong Zhang PetscFunctionBegin; 3618d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3619d5ea218eSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 3620d5ea218eSStefano Zampini PetscValidPointer(vals, 3); 3621cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumn_C", (Mat, PetscInt, PetscScalar **), (A, col, vals)); 36223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 362386aefd0dSHong Zhang } 362486aefd0dSHong Zhang 362586aefd0dSHong Zhang /*@C 362611a5261eSBarry Smith MatDenseRestoreColumn - returns access to a column of a `MATDENSE` matrix which is returned by `MatDenseGetColumn()`. 362786aefd0dSHong Zhang 362886aefd0dSHong Zhang Not Collective 362986aefd0dSHong Zhang 3630742765d3SMatthew Knepley Input Parameters: 363111a5261eSBarry Smith + mat - a `MATSEQDENSE` or `MATMPIDENSE` matrix 36322ef1f0ffSBarry Smith - vals - pointer to the data (may be `NULL`) 363386aefd0dSHong Zhang 363486aefd0dSHong Zhang Level: intermediate 363586aefd0dSHong Zhang 3636*1cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetColumn()` 363786aefd0dSHong Zhang @*/ 3638d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumn(Mat A, PetscScalar **vals) 3639d71ae5a4SJacob Faibussowitsch { 364086aefd0dSHong Zhang PetscFunctionBegin; 3641d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3642d5ea218eSStefano Zampini PetscValidPointer(vals, 2); 3643cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumn_C", (Mat, PetscScalar **), (A, vals)); 36443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 364586aefd0dSHong Zhang } 36466947451fSStefano Zampini 36470f74d2c1SSatish Balay /*@ 364811a5261eSBarry Smith MatDenseGetColumnVec - Gives read-write access to a column of a `MATDENSE` matrix, represented as a `Vec`. 36496947451fSStefano Zampini 36506947451fSStefano Zampini Collective 36516947451fSStefano Zampini 36525ea7661aSPierre Jolivet Input Parameters: 365311a5261eSBarry Smith + mat - the `Mat` object 36546947451fSStefano Zampini - col - the column index 36556947451fSStefano Zampini 36566947451fSStefano Zampini Output Parameter: 36576947451fSStefano Zampini . v - the vector 36586947451fSStefano Zampini 36592ef1f0ffSBarry Smith Level: intermediate 36602ef1f0ffSBarry Smith 36616947451fSStefano Zampini Notes: 366211a5261eSBarry Smith The vector is owned by PETSc. Users need to call `MatDenseRestoreColumnVec()` when the vector is no longer needed. 366311a5261eSBarry Smith 366411a5261eSBarry Smith Use `MatDenseGetColumnVecRead()` to obtain read-only access or `MatDenseGetColumnVecWrite()` for write-only access. 36656947451fSStefano Zampini 3666*1cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`, `MatDenseGetColumn()` 36676947451fSStefano Zampini @*/ 3668d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec(Mat A, PetscInt col, Vec *v) 3669d71ae5a4SJacob Faibussowitsch { 36706947451fSStefano Zampini PetscFunctionBegin; 36716947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 36726947451fSStefano Zampini PetscValidType(A, 1); 36736947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 36746947451fSStefano Zampini PetscValidPointer(v, 3); 367528b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 36762cf15c64SPierre 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); 3677cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v)); 36783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 36796947451fSStefano Zampini } 36806947451fSStefano Zampini 36810f74d2c1SSatish Balay /*@ 36826947451fSStefano Zampini MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVec(). 36836947451fSStefano Zampini 36846947451fSStefano Zampini Collective 36856947451fSStefano Zampini 36865ea7661aSPierre Jolivet Input Parameters: 36876947451fSStefano Zampini + mat - the Mat object 36886947451fSStefano Zampini . col - the column index 36892ef1f0ffSBarry Smith - v - the Vec object (may be `NULL`) 36906947451fSStefano Zampini 36916947451fSStefano Zampini Level: intermediate 36926947451fSStefano Zampini 3693*1cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 36946947451fSStefano Zampini @*/ 3695d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec(Mat A, PetscInt col, Vec *v) 3696d71ae5a4SJacob Faibussowitsch { 36976947451fSStefano Zampini PetscFunctionBegin; 36986947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 36996947451fSStefano Zampini PetscValidType(A, 1); 37006947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 370108401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 37022cf15c64SPierre 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); 3703cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v)); 37043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37056947451fSStefano Zampini } 37066947451fSStefano Zampini 37070f74d2c1SSatish Balay /*@ 37086947451fSStefano Zampini MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a Vec. 37096947451fSStefano Zampini 37106947451fSStefano Zampini Collective 37116947451fSStefano Zampini 37125ea7661aSPierre Jolivet Input Parameters: 37132ef1f0ffSBarry Smith + mat - the `Mat` object 37146947451fSStefano Zampini - col - the column index 37156947451fSStefano Zampini 37166947451fSStefano Zampini Output Parameter: 37176947451fSStefano Zampini . v - the vector 37186947451fSStefano Zampini 37192ef1f0ffSBarry Smith Level: intermediate 37202ef1f0ffSBarry Smith 37216947451fSStefano Zampini Notes: 37226947451fSStefano Zampini The vector is owned by PETSc and users cannot modify it. 372311a5261eSBarry Smith 37242ef1f0ffSBarry Smith Users need to call `MatDenseRestoreColumnVecRead()` when the vector is no longer needed. 372511a5261eSBarry Smith 37262ef1f0ffSBarry Smith Use `MatDenseGetColumnVec()` to obtain read-write access or `MatDenseGetColumnVecWrite()` for write-only access. 37276947451fSStefano Zampini 3728*1cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 37296947451fSStefano Zampini @*/ 3730d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead(Mat A, PetscInt col, Vec *v) 3731d71ae5a4SJacob Faibussowitsch { 37326947451fSStefano Zampini PetscFunctionBegin; 37336947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 37346947451fSStefano Zampini PetscValidType(A, 1); 37356947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 37366947451fSStefano Zampini PetscValidPointer(v, 3); 373728b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 37382cf15c64SPierre 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); 3739cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v)); 37403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37416947451fSStefano Zampini } 37426947451fSStefano Zampini 37430f74d2c1SSatish Balay /*@ 37446947451fSStefano Zampini MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecRead(). 37456947451fSStefano Zampini 37466947451fSStefano Zampini Collective 37476947451fSStefano Zampini 37485ea7661aSPierre Jolivet Input Parameters: 37492ef1f0ffSBarry Smith + mat - the `Mat` object 37506947451fSStefano Zampini . col - the column index 37512ef1f0ffSBarry Smith - v - the Vec object (may be `NULL`) 37526947451fSStefano Zampini 37536947451fSStefano Zampini Level: intermediate 37546947451fSStefano Zampini 3755*1cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecWrite()` 37566947451fSStefano Zampini @*/ 3757d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead(Mat A, PetscInt col, Vec *v) 3758d71ae5a4SJacob Faibussowitsch { 37596947451fSStefano Zampini PetscFunctionBegin; 37606947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 37616947451fSStefano Zampini PetscValidType(A, 1); 37626947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 376308401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 37642cf15c64SPierre Jolivet PetscCheck(col >= 0 && col < A->cmap->N, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")", col, A->cmap->N); 3765cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v)); 37663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37676947451fSStefano Zampini } 37686947451fSStefano Zampini 37690f74d2c1SSatish Balay /*@ 37706947451fSStefano Zampini MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a Vec. 37716947451fSStefano Zampini 37726947451fSStefano Zampini Collective 37736947451fSStefano Zampini 37745ea7661aSPierre Jolivet Input Parameters: 37752ef1f0ffSBarry Smith + mat - the `Mat` object 37766947451fSStefano Zampini - col - the column index 37776947451fSStefano Zampini 37786947451fSStefano Zampini Output Parameter: 37796947451fSStefano Zampini . v - the vector 37806947451fSStefano Zampini 37816947451fSStefano Zampini Level: intermediate 37826947451fSStefano Zampini 37832ef1f0ffSBarry Smith Notes: 37842ef1f0ffSBarry Smith The vector is owned by PETSc. Users need to call `MatDenseRestoreColumnVecWrite()` when the vector is no longer needed. 37852ef1f0ffSBarry Smith 37862ef1f0ffSBarry Smith Use `MatDenseGetColumnVec()` to obtain read-write access or `MatDenseGetColumnVecRead()` for read-only access. 37872ef1f0ffSBarry Smith 3788*1cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 37896947451fSStefano Zampini @*/ 3790d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite(Mat A, PetscInt col, Vec *v) 3791d71ae5a4SJacob Faibussowitsch { 37926947451fSStefano Zampini PetscFunctionBegin; 37936947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 37946947451fSStefano Zampini PetscValidType(A, 1); 37956947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 37966947451fSStefano Zampini PetscValidPointer(v, 3); 379728b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3798aed4548fSBarry 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); 3799cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v)); 38003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38016947451fSStefano Zampini } 38026947451fSStefano Zampini 38030f74d2c1SSatish Balay /*@ 38046947451fSStefano Zampini MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecWrite(). 38056947451fSStefano Zampini 38066947451fSStefano Zampini Collective 38076947451fSStefano Zampini 38085ea7661aSPierre Jolivet Input Parameters: 38092ef1f0ffSBarry Smith + mat - the `Mat` object 38106947451fSStefano Zampini . col - the column index 38112ef1f0ffSBarry Smith - v - the `Vec` object (may be `NULL`) 38126947451fSStefano Zampini 38136947451fSStefano Zampini Level: intermediate 38146947451fSStefano Zampini 3815*1cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()` 38166947451fSStefano Zampini @*/ 3817d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A, PetscInt col, Vec *v) 3818d71ae5a4SJacob Faibussowitsch { 38196947451fSStefano Zampini PetscFunctionBegin; 38206947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38216947451fSStefano Zampini PetscValidType(A, 1); 38226947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 382308401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3824aed4548fSBarry 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); 3825cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v)); 38263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38276947451fSStefano Zampini } 38285ea7661aSPierre Jolivet 38290f74d2c1SSatish Balay /*@ 3830a2748737SPierre Jolivet MatDenseGetSubMatrix - Gives access to a block of rows and columns of a dense matrix, represented as a Mat. 38315ea7661aSPierre Jolivet 38325ea7661aSPierre Jolivet Collective 38335ea7661aSPierre Jolivet 38345ea7661aSPierre Jolivet Input Parameters: 38355ea7661aSPierre Jolivet + mat - the Mat object 38362ef1f0ffSBarry Smith . rbegin - the first global row index in the block (if `PETSC_DECIDE`, is 0) 38372ef1f0ffSBarry Smith . rend - the global row index past the last one in the block (if `PETSC_DECIDE`, is `M`) 38382ef1f0ffSBarry Smith . cbegin - the first global column index in the block (if `PETSC_DECIDE`, is 0) 38392ef1f0ffSBarry Smith - cend - the global column index past the last one in the block (if `PETSC_DECIDE`, is `N`) 38405ea7661aSPierre Jolivet 38415ea7661aSPierre Jolivet Output Parameter: 38425ea7661aSPierre Jolivet . v - the matrix 38435ea7661aSPierre Jolivet 38445ea7661aSPierre Jolivet Level: intermediate 38455ea7661aSPierre Jolivet 38462ef1f0ffSBarry Smith Notes: 38472ef1f0ffSBarry Smith The matrix is owned by PETSc. Users need to call `MatDenseRestoreSubMatrix()` when the matrix is no longer needed. 38482ef1f0ffSBarry Smith 38492ef1f0ffSBarry 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. 38502ef1f0ffSBarry Smith 3851*1cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreSubMatrix()` 38525ea7661aSPierre Jolivet @*/ 3853d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) 3854d71ae5a4SJacob Faibussowitsch { 38555ea7661aSPierre Jolivet PetscFunctionBegin; 38565ea7661aSPierre Jolivet PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38575ea7661aSPierre Jolivet PetscValidType(A, 1); 3858a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, rbegin, 2); 3859a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, rend, 3); 3860a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, cbegin, 4); 3861a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, cend, 5); 3862a2748737SPierre Jolivet PetscValidPointer(v, 6); 3863a2748737SPierre Jolivet if (rbegin == PETSC_DECIDE) rbegin = 0; 3864a2748737SPierre Jolivet if (rend == PETSC_DECIDE) rend = A->rmap->N; 3865a2748737SPierre Jolivet if (cbegin == PETSC_DECIDE) cbegin = 0; 3866a2748737SPierre Jolivet if (cend == PETSC_DECIDE) cend = A->cmap->N; 386728b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3868a2748737SPierre 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); 3869a2748737SPierre 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); 3870a2748737SPierre 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); 3871a2748737SPierre 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); 3872a2748737SPierre Jolivet PetscUseMethod(A, "MatDenseGetSubMatrix_C", (Mat, PetscInt, PetscInt, PetscInt, PetscInt, Mat *), (A, rbegin, rend, cbegin, cend, v)); 38733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38745ea7661aSPierre Jolivet } 38755ea7661aSPierre Jolivet 38760f74d2c1SSatish Balay /*@ 38775ea7661aSPierre Jolivet MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from MatDenseGetSubMatrix(). 38785ea7661aSPierre Jolivet 38795ea7661aSPierre Jolivet Collective 38805ea7661aSPierre Jolivet 38815ea7661aSPierre Jolivet Input Parameters: 38822ef1f0ffSBarry Smith + mat - the `Mat` object 38832ef1f0ffSBarry Smith - v - the `Mat` object (may be `NULL`) 38845ea7661aSPierre Jolivet 38855ea7661aSPierre Jolivet Level: intermediate 38865ea7661aSPierre Jolivet 3887*1cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseGetSubMatrix()` 38885ea7661aSPierre Jolivet @*/ 3889d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix(Mat A, Mat *v) 3890d71ae5a4SJacob Faibussowitsch { 38915ea7661aSPierre Jolivet PetscFunctionBegin; 38925ea7661aSPierre Jolivet PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38935ea7661aSPierre Jolivet PetscValidType(A, 1); 38945ea7661aSPierre Jolivet PetscValidPointer(v, 2); 3895cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreSubMatrix_C", (Mat, Mat *), (A, v)); 38963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38975ea7661aSPierre Jolivet } 38988a9c020eSBarry Smith 38998a9c020eSBarry Smith #include <petscblaslapack.h> 39008a9c020eSBarry Smith #include <petsc/private/kernels/blockinvert.h> 39018a9c020eSBarry Smith 3902d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseInvert(Mat A) 3903d71ae5a4SJacob Faibussowitsch { 3904d63b1753SJacob Faibussowitsch PetscInt m; 39058a9c020eSBarry Smith const PetscReal shift = 0.0; 3906d63b1753SJacob Faibussowitsch PetscBool allowzeropivot, zeropivotdetected = PETSC_FALSE; 3907d63b1753SJacob Faibussowitsch PetscScalar *values; 39088a9c020eSBarry Smith 39098a9c020eSBarry Smith PetscFunctionBegin; 3910d63b1753SJacob Faibussowitsch PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3911d63b1753SJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &values)); 3912d63b1753SJacob Faibussowitsch PetscCall(MatGetLocalSize(A, &m, NULL)); 3913d63b1753SJacob Faibussowitsch allowzeropivot = PetscNot(A->erroriffailure); 39148a9c020eSBarry Smith /* factor and invert each block */ 3915d63b1753SJacob Faibussowitsch switch (m) { 3916d71ae5a4SJacob Faibussowitsch case 1: 3917d71ae5a4SJacob Faibussowitsch values[0] = (PetscScalar)1.0 / (values[0] + shift); 3918d71ae5a4SJacob Faibussowitsch break; 39198a9c020eSBarry Smith case 2: 39208a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_2(values, shift, allowzeropivot, &zeropivotdetected)); 39218a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39228a9c020eSBarry Smith break; 39238a9c020eSBarry Smith case 3: 39248a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_3(values, shift, allowzeropivot, &zeropivotdetected)); 39258a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39268a9c020eSBarry Smith break; 39278a9c020eSBarry Smith case 4: 39288a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_4(values, shift, allowzeropivot, &zeropivotdetected)); 39298a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39308a9c020eSBarry Smith break; 39319371c9d4SSatish Balay case 5: { 39328a9c020eSBarry Smith PetscScalar work[25]; 39338a9c020eSBarry Smith PetscInt ipvt[5]; 39348a9c020eSBarry Smith 39358a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_5(values, ipvt, work, shift, allowzeropivot, &zeropivotdetected)); 39368a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39379371c9d4SSatish Balay } break; 39388a9c020eSBarry Smith case 6: 39398a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_6(values, shift, allowzeropivot, &zeropivotdetected)); 39408a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39418a9c020eSBarry Smith break; 39428a9c020eSBarry Smith case 7: 39438a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_7(values, shift, allowzeropivot, &zeropivotdetected)); 39448a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39458a9c020eSBarry Smith break; 39469371c9d4SSatish Balay default: { 39478a9c020eSBarry Smith PetscInt *v_pivots, *IJ, j; 39488a9c020eSBarry Smith PetscScalar *v_work; 39498a9c020eSBarry Smith 3950d63b1753SJacob Faibussowitsch PetscCall(PetscMalloc3(m, &v_work, m, &v_pivots, m, &IJ)); 3951d63b1753SJacob Faibussowitsch for (j = 0; j < m; j++) IJ[j] = j; 3952d63b1753SJacob Faibussowitsch PetscCall(PetscKernel_A_gets_inverse_A(m, values, v_pivots, v_work, allowzeropivot, &zeropivotdetected)); 39538a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39548a9c020eSBarry Smith PetscCall(PetscFree3(v_work, v_pivots, IJ)); 39558a9c020eSBarry Smith } 39568a9c020eSBarry Smith } 3957d63b1753SJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &values)); 39583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 39598a9c020eSBarry Smith } 3960