167e560aaSBarry Smith /* 267e560aaSBarry Smith Defines the basic matrix operations for sequential dense. 347d993e7Ssuyashtn Portions of this code are under: 447d993e7Ssuyashtn Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved. 567e560aaSBarry Smith */ 6289bc588SBarry Smith 7dec5eb66SMatthew G Knepley #include <../src/mat/impls/dense/seq/dense.h> /*I "petscmat.h" I*/ 8cd3f9d89SJunchao Zhang #include <../src/mat/impls/dense/mpi/mpidense.h> 9c6db04a5SJed Brown #include <petscblaslapack.h> 106a63e612SBarry Smith #include <../src/mat/impls/aij/seq/aij.h> 11b2573a8aSBarry Smith 12d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSymmetrize_Private(Mat A, PetscBool hermitian) 13d71ae5a4SJacob Faibussowitsch { 148c178816SStefano Zampini Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 158c178816SStefano Zampini PetscInt j, k, n = A->rmap->n; 16ca15aa20SStefano Zampini PetscScalar *v; 178c178816SStefano Zampini 188c178816SStefano Zampini PetscFunctionBegin; 1908401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Cannot symmetrize a rectangular matrix"); 209566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 218c178816SStefano Zampini if (!hermitian) { 228c178816SStefano Zampini for (k = 0; k < n; k++) { 23ad540459SPierre Jolivet for (j = k; j < n; j++) v[j * mat->lda + k] = v[k * mat->lda + j]; 248c178816SStefano Zampini } 258c178816SStefano Zampini } else { 268c178816SStefano Zampini for (k = 0; k < n; k++) { 27ad540459SPierre Jolivet for (j = k; j < n; j++) v[j * mat->lda + k] = PetscConj(v[k * mat->lda + j]); 288c178816SStefano Zampini } 298c178816SStefano Zampini } 309566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 328c178816SStefano Zampini } 338c178816SStefano Zampini 34ff6a9541SJacob Faibussowitsch PetscErrorCode MatSeqDenseInvertFactors_Private(Mat A) 35d71ae5a4SJacob Faibussowitsch { 368c178816SStefano Zampini Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 378c178816SStefano Zampini PetscBLASInt info, n; 388c178816SStefano Zampini 398c178816SStefano Zampini PetscFunctionBegin; 403ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 419566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 428c178816SStefano Zampini if (A->factortype == MAT_FACTOR_LU) { 4328b400f6SJacob Faibussowitsch PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present"); 448c178816SStefano Zampini if (!mat->fwork) { 458c178816SStefano Zampini mat->lfwork = n; 469566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 478c178816SStefano Zampini } 489566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 49792fecdfSBarry Smith PetscCallBLAS("LAPACKgetri", LAPACKgetri_(&n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info)); 509566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 519566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0)); 528c178816SStefano Zampini } else if (A->factortype == MAT_FACTOR_CHOLESKY) { 53b94d7dedSBarry Smith if (A->spd == PETSC_BOOL3_TRUE) { 549566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 55792fecdfSBarry Smith PetscCallBLAS("LAPACKpotri", LAPACKpotri_("L", &n, mat->v, &mat->lda, &info)); 569566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 579566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_TRUE)); 588c178816SStefano Zampini #if defined(PETSC_USE_COMPLEX) 59b94d7dedSBarry Smith } else if (A->hermitian == PETSC_BOOL3_TRUE) { 6028b400f6SJacob Faibussowitsch PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present"); 6128b400f6SJacob Faibussowitsch PetscCheck(mat->fwork, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Fwork not present"); 629566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 63792fecdfSBarry Smith PetscCallBLAS("LAPACKhetri", LAPACKhetri_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &info)); 649566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 659566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_TRUE)); 668c178816SStefano Zampini #endif 678c178816SStefano Zampini } else { /* symmetric case */ 6828b400f6SJacob Faibussowitsch PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present"); 6928b400f6SJacob Faibussowitsch PetscCheck(mat->fwork, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Fwork not present"); 709566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 71792fecdfSBarry Smith PetscCallBLAS("LAPACKsytri", LAPACKsytri_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &info)); 729566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 739566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_FALSE)); 748c178816SStefano Zampini } 7528b400f6SJacob Faibussowitsch PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad Inversion: zero pivot in row %" PetscInt_FMT, (PetscInt)info - 1); 769566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0)); 778c178816SStefano Zampini } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Matrix must be factored to solve"); 788c178816SStefano Zampini 798c178816SStefano Zampini A->ops->solve = NULL; 808c178816SStefano Zampini A->ops->matsolve = NULL; 818c178816SStefano Zampini A->ops->solvetranspose = NULL; 828c178816SStefano Zampini A->ops->matsolvetranspose = NULL; 838c178816SStefano Zampini A->ops->solveadd = NULL; 848c178816SStefano Zampini A->ops->solvetransposeadd = NULL; 858c178816SStefano Zampini A->factortype = MAT_FACTOR_NONE; 869566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 888c178816SStefano Zampini } 898c178816SStefano Zampini 9066976f2fSJacob Faibussowitsch static PetscErrorCode MatZeroRowsColumns_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) 91d71ae5a4SJacob Faibussowitsch { 923f49a652SStefano Zampini Mat_SeqDense *l = (Mat_SeqDense *)A->data; 933f49a652SStefano Zampini PetscInt m = l->lda, n = A->cmap->n, r = A->rmap->n, i, j; 94ca15aa20SStefano Zampini PetscScalar *slot, *bb, *v; 953f49a652SStefano Zampini const PetscScalar *xx; 963f49a652SStefano Zampini 973f49a652SStefano Zampini PetscFunctionBegin; 9876bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 993f49a652SStefano Zampini for (i = 0; i < N; i++) { 10008401ef6SPierre Jolivet PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed"); 10108401ef6SPierre Jolivet PetscCheck(rows[i] < A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Row %" PetscInt_FMT " requested to be zeroed greater than or equal number of rows %" PetscInt_FMT, rows[i], A->rmap->n); 10208401ef6SPierre Jolivet PetscCheck(rows[i] < A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Col %" PetscInt_FMT " requested to be zeroed greater than or equal number of cols %" PetscInt_FMT, rows[i], A->cmap->n); 1033f49a652SStefano Zampini } 10476bd3646SJed Brown } 1053ba16761SJacob Faibussowitsch if (!N) PetscFunctionReturn(PETSC_SUCCESS); 1063f49a652SStefano Zampini 1073f49a652SStefano Zampini /* fix right hand side if needed */ 1083f49a652SStefano Zampini if (x && b) { 1096c4d906cSStefano Zampini Vec xt; 1106c4d906cSStefano Zampini 11108401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices"); 1129566063dSJacob Faibussowitsch PetscCall(VecDuplicate(x, &xt)); 1139566063dSJacob Faibussowitsch PetscCall(VecCopy(x, xt)); 1149566063dSJacob Faibussowitsch PetscCall(VecScale(xt, -1.0)); 1159566063dSJacob Faibussowitsch PetscCall(MatMultAdd(A, xt, b, b)); 1169566063dSJacob Faibussowitsch PetscCall(VecDestroy(&xt)); 1179566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 1189566063dSJacob Faibussowitsch PetscCall(VecGetArray(b, &bb)); 1193f49a652SStefano Zampini for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]]; 1209566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 1219566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(b, &bb)); 1223f49a652SStefano Zampini } 1233f49a652SStefano Zampini 1249566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 1253f49a652SStefano Zampini for (i = 0; i < N; i++) { 126ca15aa20SStefano Zampini slot = v + rows[i] * m; 1279566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(slot, r)); 1283f49a652SStefano Zampini } 1293f49a652SStefano Zampini for (i = 0; i < N; i++) { 130ca15aa20SStefano Zampini slot = v + rows[i]; 1319371c9d4SSatish Balay for (j = 0; j < n; j++) { 1329371c9d4SSatish Balay *slot = 0.0; 1339371c9d4SSatish Balay slot += m; 1349371c9d4SSatish Balay } 1353f49a652SStefano Zampini } 1363f49a652SStefano Zampini if (diag != 0.0) { 13708401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices"); 1383f49a652SStefano Zampini for (i = 0; i < N; i++) { 139ca15aa20SStefano Zampini slot = v + (m + 1) * rows[i]; 1403f49a652SStefano Zampini *slot = diag; 1413f49a652SStefano Zampini } 1423f49a652SStefano Zampini } 1439566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 1443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1453f49a652SStefano Zampini } 1463f49a652SStefano Zampini 147d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) 148d71ae5a4SJacob Faibussowitsch { 149a13144ffSStefano Zampini Mat B = NULL; 150b49cda9fSStefano Zampini Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data; 151b49cda9fSStefano Zampini Mat_SeqDense *b; 152b49cda9fSStefano Zampini PetscInt *ai = a->i, *aj = a->j, m = A->rmap->N, n = A->cmap->N, i; 1532e5835c6SStefano Zampini const MatScalar *av; 154a13144ffSStefano Zampini PetscBool isseqdense; 155b49cda9fSStefano Zampini 156b49cda9fSStefano Zampini PetscFunctionBegin; 157a13144ffSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 1589566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)*newmat, MATSEQDENSE, &isseqdense)); 15928b400f6SJacob Faibussowitsch PetscCheck(isseqdense, PetscObjectComm((PetscObject)*newmat), PETSC_ERR_USER, "Cannot reuse matrix of type %s", ((PetscObject)(*newmat))->type_name); 160a13144ffSStefano Zampini } 161a13144ffSStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 1629566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B)); 1639566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B, m, n, m, n)); 1649566063dSJacob Faibussowitsch PetscCall(MatSetType(B, MATSEQDENSE)); 1659566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(B, NULL)); 166b49cda9fSStefano Zampini b = (Mat_SeqDense *)(B->data); 167a13144ffSStefano Zampini } else { 168a13144ffSStefano Zampini b = (Mat_SeqDense *)((*newmat)->data); 169*e1ea5af7SJose E. Roman for (i = 0; i < n; i++) PetscCall(PetscArrayzero(b->v + i * b->lda, m)); 170a13144ffSStefano Zampini } 1719566063dSJacob Faibussowitsch PetscCall(MatSeqAIJGetArrayRead(A, &av)); 172b49cda9fSStefano Zampini for (i = 0; i < m; i++) { 173b49cda9fSStefano Zampini PetscInt j; 174b49cda9fSStefano Zampini for (j = 0; j < ai[1] - ai[0]; j++) { 175*e1ea5af7SJose E. Roman b->v[*aj * b->lda + i] = *av; 176b49cda9fSStefano Zampini aj++; 177b49cda9fSStefano Zampini av++; 178b49cda9fSStefano Zampini } 179b49cda9fSStefano Zampini ai++; 180b49cda9fSStefano Zampini } 1819566063dSJacob Faibussowitsch PetscCall(MatSeqAIJRestoreArrayRead(A, &av)); 182b49cda9fSStefano Zampini 183511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 1849566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 1859566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 1869566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A, &B)); 187b49cda9fSStefano Zampini } else { 188a13144ffSStefano Zampini if (B) *newmat = B; 1899566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(*newmat, MAT_FINAL_ASSEMBLY)); 1909566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(*newmat, MAT_FINAL_ASSEMBLY)); 191b49cda9fSStefano Zampini } 1923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 193b49cda9fSStefano Zampini } 194b49cda9fSStefano Zampini 195d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqDense_SeqAIJ(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) 196d71ae5a4SJacob Faibussowitsch { 1976d4ec7b0SPierre Jolivet Mat B = NULL; 1986a63e612SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1999399e1b8SMatthew G. Knepley PetscInt i, j; 2009399e1b8SMatthew G. Knepley PetscInt *rows, *nnz; 2019399e1b8SMatthew G. Knepley MatScalar *aa = a->v, *vals; 2026a63e612SBarry Smith 2036a63e612SBarry Smith PetscFunctionBegin; 2049566063dSJacob Faibussowitsch PetscCall(PetscCalloc3(A->rmap->n, &rows, A->rmap->n, &nnz, A->rmap->n, &vals)); 2056d4ec7b0SPierre Jolivet if (reuse != MAT_REUSE_MATRIX) { 2069566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B)); 2079566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B, A->rmap->n, A->cmap->n, A->rmap->N, A->cmap->N)); 2089566063dSJacob Faibussowitsch PetscCall(MatSetType(B, MATSEQAIJ)); 2099399e1b8SMatthew G. Knepley for (j = 0; j < A->cmap->n; j++) { 2109371c9d4SSatish Balay for (i = 0; i < A->rmap->n; i++) 2119371c9d4SSatish Balay if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) ++nnz[i]; 2126a63e612SBarry Smith aa += a->lda; 2136a63e612SBarry Smith } 2149566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(B, PETSC_DETERMINE, nnz)); 2156d4ec7b0SPierre Jolivet } else B = *newmat; 2169399e1b8SMatthew G. Knepley aa = a->v; 2179399e1b8SMatthew G. Knepley for (j = 0; j < A->cmap->n; j++) { 2189399e1b8SMatthew G. Knepley PetscInt numRows = 0; 2199371c9d4SSatish Balay for (i = 0; i < A->rmap->n; i++) 2209371c9d4SSatish Balay if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) { 2219371c9d4SSatish Balay rows[numRows] = i; 2229371c9d4SSatish Balay vals[numRows++] = aa[i]; 2239371c9d4SSatish Balay } 2249566063dSJacob Faibussowitsch PetscCall(MatSetValues(B, numRows, rows, 1, &j, vals, INSERT_VALUES)); 2259399e1b8SMatthew G. Knepley aa += a->lda; 2269399e1b8SMatthew G. Knepley } 2279566063dSJacob Faibussowitsch PetscCall(PetscFree3(rows, nnz, vals)); 2289566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 2299566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 2306a63e612SBarry Smith 231511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 2329566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A, &B)); 2336d4ec7b0SPierre Jolivet } else if (reuse != MAT_REUSE_MATRIX) *newmat = B; 2343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2356a63e612SBarry Smith } 2366a63e612SBarry Smith 237d71ae5a4SJacob Faibussowitsch PetscErrorCode MatAXPY_SeqDense(Mat Y, PetscScalar alpha, Mat X, MatStructure str) 238d71ae5a4SJacob Faibussowitsch { 2391987afe7SBarry Smith Mat_SeqDense *x = (Mat_SeqDense *)X->data, *y = (Mat_SeqDense *)Y->data; 240ca15aa20SStefano Zampini const PetscScalar *xv; 241ca15aa20SStefano Zampini PetscScalar *yv; 24223fff9afSBarry Smith PetscBLASInt N, m, ldax = 0, lday = 0, one = 1; 2433a40ed3dSBarry Smith 2443a40ed3dSBarry Smith PetscFunctionBegin; 2459566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(X, &xv)); 2469566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(Y, &yv)); 2479566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(X->rmap->n * X->cmap->n, &N)); 2489566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(X->rmap->n, &m)); 2499566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(x->lda, &ldax)); 2509566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(y->lda, &lday)); 251a5ce6ee0Svictorle if (ldax > m || lday > m) { 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; 1156c3e1b152SPierre Jolivet if (ncols) *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; 11799566063dSJacob Faibussowitsch if (cols) PetscCall(PetscFree(*cols)); 11809566063dSJacob Faibussowitsch if (vals) PetscCall(PetscFree(*vals)); 11813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1182289bc588SBarry Smith } 11832ef1f0ffSBarry Smith 1184d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], const PetscScalar v[], InsertMode addv) 1185d71ae5a4SJacob Faibussowitsch { 1186c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1187ca15aa20SStefano Zampini PetscScalar *av; 118813f74950SBarry Smith PetscInt i, j, idx = 0; 118947d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1190c70f7ee4SJunchao Zhang PetscOffloadMask oldf; 1191ca15aa20SStefano Zampini #endif 1192d6dfbf8fSBarry Smith 11933a40ed3dSBarry Smith PetscFunctionBegin; 11949566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &av)); 1195289bc588SBarry Smith if (!mat->roworiented) { 1196dbb450caSBarry Smith if (addv == INSERT_VALUES) { 1197289bc588SBarry Smith for (j = 0; j < n; j++) { 11989371c9d4SSatish Balay if (indexn[j] < 0) { 11999371c9d4SSatish Balay idx += m; 12009371c9d4SSatish Balay continue; 12019371c9d4SSatish Balay } 12026bdcaf15SBarry 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); 1203289bc588SBarry Smith for (i = 0; i < m; i++) { 12049371c9d4SSatish Balay if (indexm[i] < 0) { 12059371c9d4SSatish Balay idx++; 12069371c9d4SSatish Balay continue; 12079371c9d4SSatish Balay } 12086bdcaf15SBarry 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); 1209ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] = v[idx++]; 1210289bc588SBarry Smith } 1211289bc588SBarry Smith } 12123a40ed3dSBarry Smith } else { 1213289bc588SBarry Smith for (j = 0; j < n; j++) { 12149371c9d4SSatish Balay if (indexn[j] < 0) { 12159371c9d4SSatish Balay idx += m; 12169371c9d4SSatish Balay continue; 12179371c9d4SSatish Balay } 12186bdcaf15SBarry 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); 1219289bc588SBarry Smith for (i = 0; i < m; i++) { 12209371c9d4SSatish Balay if (indexm[i] < 0) { 12219371c9d4SSatish Balay idx++; 12229371c9d4SSatish Balay continue; 12239371c9d4SSatish Balay } 12246bdcaf15SBarry 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); 1225ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] += v[idx++]; 1226289bc588SBarry Smith } 1227289bc588SBarry Smith } 1228289bc588SBarry Smith } 12293a40ed3dSBarry Smith } else { 1230dbb450caSBarry Smith if (addv == INSERT_VALUES) { 1231e8d4e0b9SBarry Smith for (i = 0; i < m; i++) { 12329371c9d4SSatish Balay if (indexm[i] < 0) { 12339371c9d4SSatish Balay idx += n; 12349371c9d4SSatish Balay continue; 12359371c9d4SSatish Balay } 12366bdcaf15SBarry 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); 1237e8d4e0b9SBarry Smith for (j = 0; j < n; j++) { 12389371c9d4SSatish Balay if (indexn[j] < 0) { 12399371c9d4SSatish Balay idx++; 12409371c9d4SSatish Balay continue; 12419371c9d4SSatish Balay } 12426bdcaf15SBarry 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); 1243ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] = v[idx++]; 1244e8d4e0b9SBarry Smith } 1245e8d4e0b9SBarry Smith } 12463a40ed3dSBarry Smith } else { 1247289bc588SBarry Smith for (i = 0; i < m; i++) { 12489371c9d4SSatish Balay if (indexm[i] < 0) { 12499371c9d4SSatish Balay idx += n; 12509371c9d4SSatish Balay continue; 12519371c9d4SSatish Balay } 12526bdcaf15SBarry 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); 1253289bc588SBarry Smith for (j = 0; j < n; j++) { 12549371c9d4SSatish Balay if (indexn[j] < 0) { 12559371c9d4SSatish Balay idx++; 12569371c9d4SSatish Balay continue; 12579371c9d4SSatish Balay } 12586bdcaf15SBarry 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); 1259ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] += v[idx++]; 1260289bc588SBarry Smith } 1261289bc588SBarry Smith } 1262289bc588SBarry Smith } 1263e8d4e0b9SBarry Smith } 1264ca15aa20SStefano Zampini /* hack to prevent unneeded copy to the GPU while returning the array */ 126547d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1266c70f7ee4SJunchao Zhang oldf = A->offloadmask; 1267c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_GPU; 1268ca15aa20SStefano Zampini #endif 12699566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &av)); 127047d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1271c70f7ee4SJunchao Zhang A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU); 1272ca15aa20SStefano Zampini #endif 12733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1274289bc588SBarry Smith } 1275e8d4e0b9SBarry Smith 1276d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], PetscScalar v[]) 1277d71ae5a4SJacob Faibussowitsch { 1278ae80bb75SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1279ca15aa20SStefano Zampini const PetscScalar *vv; 128013f74950SBarry Smith PetscInt i, j; 1281ae80bb75SLois Curfman McInnes 12823a40ed3dSBarry Smith PetscFunctionBegin; 12839566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &vv)); 1284ae80bb75SLois Curfman McInnes /* row-oriented output */ 1285ae80bb75SLois Curfman McInnes for (i = 0; i < m; i++) { 12869371c9d4SSatish Balay if (indexm[i] < 0) { 12879371c9d4SSatish Balay v += n; 12889371c9d4SSatish Balay continue; 12899371c9d4SSatish Balay } 129008401ef6SPierre 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); 1291ae80bb75SLois Curfman McInnes for (j = 0; j < n; j++) { 12929371c9d4SSatish Balay if (indexn[j] < 0) { 12939371c9d4SSatish Balay v++; 12949371c9d4SSatish Balay continue; 12959371c9d4SSatish Balay } 129608401ef6SPierre 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); 1297ca15aa20SStefano Zampini *v++ = vv[indexn[j] * mat->lda + indexm[i]]; 1298ae80bb75SLois Curfman McInnes } 1299ae80bb75SLois Curfman McInnes } 13009566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &vv)); 13013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1302ae80bb75SLois Curfman McInnes } 1303ae80bb75SLois Curfman McInnes 1304d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_Dense_Binary(Mat mat, PetscViewer viewer) 1305d71ae5a4SJacob Faibussowitsch { 13068491ab44SLisandro Dalcin PetscBool skipHeader; 13078491ab44SLisandro Dalcin PetscViewerFormat format; 13088491ab44SLisandro Dalcin PetscInt header[4], M, N, m, lda, i, j, k; 13098491ab44SLisandro Dalcin const PetscScalar *v; 13108491ab44SLisandro Dalcin PetscScalar *vwork; 1311aabbc4fbSShri Abhyankar 1312aabbc4fbSShri Abhyankar PetscFunctionBegin; 13139566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 13149566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader)); 13159566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 13168491ab44SLisandro Dalcin if (skipHeader) format = PETSC_VIEWER_NATIVE; 1317aabbc4fbSShri Abhyankar 13189566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &M, &N)); 13198491ab44SLisandro Dalcin 13208491ab44SLisandro Dalcin /* write matrix header */ 13219371c9d4SSatish Balay header[0] = MAT_FILE_CLASSID; 13229371c9d4SSatish Balay header[1] = M; 13239371c9d4SSatish Balay header[2] = N; 13248491ab44SLisandro Dalcin header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M * N; 13259566063dSJacob Faibussowitsch if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer, header, 4, PETSC_INT)); 13268491ab44SLisandro Dalcin 13279566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mat, &m, NULL)); 13288491ab44SLisandro Dalcin if (format != PETSC_VIEWER_NATIVE) { 13298491ab44SLisandro Dalcin PetscInt nnz = m * N, *iwork; 13308491ab44SLisandro Dalcin /* store row lengths for each row */ 13319566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz, &iwork)); 13328491ab44SLisandro Dalcin for (i = 0; i < m; i++) iwork[i] = N; 13339566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 13348491ab44SLisandro Dalcin /* store column indices (zero start index) */ 13358491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 13369371c9d4SSatish Balay for (j = 0; j < N; j++, k++) iwork[k] = j; 13379566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 13389566063dSJacob Faibussowitsch PetscCall(PetscFree(iwork)); 13398491ab44SLisandro Dalcin } 13408491ab44SLisandro Dalcin /* store matrix values as a dense matrix in row major order */ 13419566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m * N, &vwork)); 13429566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(mat, &v)); 13439566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(mat, &lda)); 13448491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 13459371c9d4SSatish Balay for (j = 0; j < N; j++, k++) vwork[k] = v[i + lda * j]; 13469566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(mat, &v)); 13479566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, vwork, m * N, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 13489566063dSJacob Faibussowitsch PetscCall(PetscFree(vwork)); 13493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13508491ab44SLisandro Dalcin } 13518491ab44SLisandro Dalcin 1352d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLoad_Dense_Binary(Mat mat, PetscViewer viewer) 1353d71ae5a4SJacob Faibussowitsch { 13548491ab44SLisandro Dalcin PetscBool skipHeader; 13558491ab44SLisandro Dalcin PetscInt header[4], M, N, m, nz, lda, i, j, k; 13568491ab44SLisandro Dalcin PetscInt rows, cols; 13578491ab44SLisandro Dalcin PetscScalar *v, *vwork; 13588491ab44SLisandro Dalcin 13598491ab44SLisandro Dalcin PetscFunctionBegin; 13609566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 13619566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader)); 13628491ab44SLisandro Dalcin 13638491ab44SLisandro Dalcin if (!skipHeader) { 13649566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, header, 4, NULL, PETSC_INT)); 136508401ef6SPierre Jolivet PetscCheck(header[0] == MAT_FILE_CLASSID, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Not a matrix object in file"); 13669371c9d4SSatish Balay M = header[1]; 13679371c9d4SSatish Balay N = header[2]; 136808401ef6SPierre Jolivet PetscCheck(M >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix row size (%" PetscInt_FMT ") in file is negative", M); 136908401ef6SPierre Jolivet PetscCheck(N >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix column size (%" PetscInt_FMT ") in file is negative", N); 13708491ab44SLisandro Dalcin nz = header[3]; 1371aed4548fSBarry Smith PetscCheck(nz == MATRIX_BINARY_FORMAT_DENSE || nz >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Unknown matrix format %" PetscInt_FMT " in file", nz); 1372aabbc4fbSShri Abhyankar } else { 13739566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &M, &N)); 1374aed4548fSBarry 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"); 13758491ab44SLisandro Dalcin nz = MATRIX_BINARY_FORMAT_DENSE; 1376e6324fbbSBarry Smith } 1377aabbc4fbSShri Abhyankar 13788491ab44SLisandro Dalcin /* setup global sizes if not set */ 13798491ab44SLisandro Dalcin if (mat->rmap->N < 0) mat->rmap->N = M; 13808491ab44SLisandro Dalcin if (mat->cmap->N < 0) mat->cmap->N = N; 13819566063dSJacob Faibussowitsch PetscCall(MatSetUp(mat)); 13828491ab44SLisandro Dalcin /* check if global sizes are correct */ 13839566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &rows, &cols)); 1384aed4548fSBarry 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); 1385aabbc4fbSShri Abhyankar 13869566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, NULL, &N)); 13879566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mat, &m, NULL)); 13889566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(mat, &v)); 13899566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(mat, &lda)); 13908491ab44SLisandro Dalcin if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense format */ 13918491ab44SLisandro Dalcin PetscInt nnz = m * N; 13928491ab44SLisandro Dalcin /* read in matrix values */ 13939566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz, &vwork)); 13949566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 13958491ab44SLisandro Dalcin /* store values in column major order */ 13968491ab44SLisandro Dalcin for (j = 0; j < N; j++) 13979371c9d4SSatish Balay for (i = 0; i < m; i++) v[i + lda * j] = vwork[i * N + j]; 13989566063dSJacob Faibussowitsch PetscCall(PetscFree(vwork)); 13998491ab44SLisandro Dalcin } else { /* matrix in file is sparse format */ 14008491ab44SLisandro Dalcin PetscInt nnz = 0, *rlens, *icols; 14018491ab44SLisandro Dalcin /* read in row lengths */ 14029566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m, &rlens)); 14039566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, rlens, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 14048491ab44SLisandro Dalcin for (i = 0; i < m; i++) nnz += rlens[i]; 14058491ab44SLisandro Dalcin /* read in column indices and values */ 14069566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(nnz, &icols, nnz, &vwork)); 14079566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, icols, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 14089566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 14098491ab44SLisandro Dalcin /* store values in column major order */ 14108491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 14119371c9d4SSatish Balay for (j = 0; j < rlens[i]; j++, k++) v[i + lda * icols[k]] = vwork[k]; 14129566063dSJacob Faibussowitsch PetscCall(PetscFree(rlens)); 14139566063dSJacob Faibussowitsch PetscCall(PetscFree2(icols, vwork)); 1414aabbc4fbSShri Abhyankar } 14159566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(mat, &v)); 14169566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY)); 14179566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY)); 14183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1419aabbc4fbSShri Abhyankar } 1420aabbc4fbSShri Abhyankar 142166976f2fSJacob Faibussowitsch static PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer) 1422d71ae5a4SJacob Faibussowitsch { 1423eb91f321SVaclav Hapla PetscBool isbinary, ishdf5; 1424eb91f321SVaclav Hapla 1425eb91f321SVaclav Hapla PetscFunctionBegin; 1426eb91f321SVaclav Hapla PetscValidHeaderSpecific(newMat, MAT_CLASSID, 1); 1427eb91f321SVaclav Hapla PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1428eb91f321SVaclav Hapla /* force binary viewer to load .info file if it has not yet done so */ 14299566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 14309566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 14319566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5)); 1432eb91f321SVaclav Hapla if (isbinary) { 14339566063dSJacob Faibussowitsch PetscCall(MatLoad_Dense_Binary(newMat, viewer)); 1434eb91f321SVaclav Hapla } else if (ishdf5) { 1435eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5) 14369566063dSJacob Faibussowitsch PetscCall(MatLoad_Dense_HDF5(newMat, viewer)); 1437eb91f321SVaclav Hapla #else 1438eb91f321SVaclav Hapla SETERRQ(PetscObjectComm((PetscObject)newMat), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1439eb91f321SVaclav Hapla #endif 1440eb91f321SVaclav Hapla } else { 144198921bdaSJacob 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); 1442eb91f321SVaclav Hapla } 14433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1444eb91f321SVaclav Hapla } 1445eb91f321SVaclav Hapla 1446d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_ASCII(Mat A, PetscViewer viewer) 1447d71ae5a4SJacob Faibussowitsch { 1448932b0c3eSLois Curfman McInnes Mat_SeqDense *a = (Mat_SeqDense *)A->data; 144913f74950SBarry Smith PetscInt i, j; 14502dcb1b2aSMatthew Knepley const char *name; 1451ca15aa20SStefano Zampini PetscScalar *v, *av; 1452f3ef73ceSBarry Smith PetscViewerFormat format; 14535f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX) 1454ace3abfcSBarry Smith PetscBool allreal = PETSC_TRUE; 14555f481a85SSatish Balay #endif 1456932b0c3eSLois Curfman McInnes 14573a40ed3dSBarry Smith PetscFunctionBegin; 14589566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&av)); 14599566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 1460456192e2SBarry Smith if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 14613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); /* do nothing for now */ 1462fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 14639566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE)); 1464d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 1465ca15aa20SStefano Zampini v = av + i; 14669566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "row %" PetscInt_FMT ":", i)); 1467d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1468aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 1469329f5518SBarry Smith if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) { 14709566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g + %g i) ", j, (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v))); 1471329f5518SBarry Smith } else if (PetscRealPart(*v)) { 14729566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)PetscRealPart(*v))); 14736831982aSBarry Smith } 147480cd9d93SLois Curfman McInnes #else 147548a46eb9SPierre Jolivet if (*v) PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)*v)); 147680cd9d93SLois Curfman McInnes #endif 14771b807ce4Svictorle v += a->lda; 147880cd9d93SLois Curfman McInnes } 14799566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 148080cd9d93SLois Curfman McInnes } 14819566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE)); 14823a40ed3dSBarry Smith } else { 14839566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE)); 1484aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 148547989497SBarry Smith /* determine if matrix has all real values */ 1486bcd8d3a4SJose E. Roman for (j = 0; j < A->cmap->n; j++) { 1487bcd8d3a4SJose E. Roman v = av + j * a->lda; 1488bcd8d3a4SJose E. Roman for (i = 0; i < A->rmap->n; i++) { 14899371c9d4SSatish Balay if (PetscImaginaryPart(v[i])) { 14909371c9d4SSatish Balay allreal = PETSC_FALSE; 14919371c9d4SSatish Balay break; 14929371c9d4SSatish Balay } 149347989497SBarry Smith } 1494bcd8d3a4SJose E. Roman } 149547989497SBarry Smith #endif 1496fb9695e5SSatish Balay if (format == PETSC_VIEWER_ASCII_MATLAB) { 14979566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)A, &name)); 14989566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%% Size = %" PetscInt_FMT " %" PetscInt_FMT " \n", A->rmap->n, A->cmap->n)); 14999566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%s = zeros(%" PetscInt_FMT ",%" PetscInt_FMT ");\n", name, A->rmap->n, A->cmap->n)); 15009566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%s = [\n", name)); 1501ffac6cdbSBarry Smith } 1502ffac6cdbSBarry Smith 1503d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 1504ca15aa20SStefano Zampini v = av + i; 1505d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1506aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 150747989497SBarry Smith if (allreal) { 15089566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)PetscRealPart(*v))); 150947989497SBarry Smith } else { 15109566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e + %18.16ei ", (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v))); 151147989497SBarry Smith } 1512289bc588SBarry Smith #else 15139566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)*v)); 1514289bc588SBarry Smith #endif 15151b807ce4Svictorle v += a->lda; 1516289bc588SBarry Smith } 15179566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 1518289bc588SBarry Smith } 151948a46eb9SPierre Jolivet if (format == PETSC_VIEWER_ASCII_MATLAB) PetscCall(PetscViewerASCIIPrintf(viewer, "];\n")); 15209566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE)); 1521da3a660dSBarry Smith } 15229566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&av)); 15239566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer)); 15243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1525289bc588SBarry Smith } 1526289bc588SBarry Smith 15279804daf3SBarry Smith #include <petscdraw.h> 1528d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw, void *Aa) 1529d71ae5a4SJacob Faibussowitsch { 1530f1af5d2fSBarry Smith Mat A = (Mat)Aa; 1531383922c3SLisandro Dalcin PetscInt m = A->rmap->n, n = A->cmap->n, i, j; 1532383922c3SLisandro Dalcin int color = PETSC_DRAW_WHITE; 1533ca15aa20SStefano Zampini const PetscScalar *v; 1534b0a32e0cSBarry Smith PetscViewer viewer; 1535b05fc000SLisandro Dalcin PetscReal xl, yl, xr, yr, x_l, x_r, y_l, y_r; 1536f3ef73ceSBarry Smith PetscViewerFormat format; 1537f1af5d2fSBarry Smith 1538f1af5d2fSBarry Smith PetscFunctionBegin; 15399566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)A, "Zoomviewer", (PetscObject *)&viewer)); 15409566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 15419566063dSJacob Faibussowitsch PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr)); 1542f1af5d2fSBarry Smith 1543f1af5d2fSBarry Smith /* Loop over matrix elements drawing boxes */ 15449566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 1545fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 1546d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 1547f1af5d2fSBarry Smith /* Blue for negative and Red for positive */ 1548f1af5d2fSBarry Smith for (j = 0; j < n; j++) { 15499371c9d4SSatish Balay x_l = j; 15509371c9d4SSatish Balay x_r = x_l + 1.0; 1551f1af5d2fSBarry Smith for (i = 0; i < m; i++) { 1552f1af5d2fSBarry Smith y_l = m - i - 1.0; 1553f1af5d2fSBarry Smith y_r = y_l + 1.0; 1554ca15aa20SStefano Zampini if (PetscRealPart(v[j * m + i]) > 0.) color = PETSC_DRAW_RED; 1555ca15aa20SStefano Zampini else if (PetscRealPart(v[j * m + i]) < 0.) color = PETSC_DRAW_BLUE; 1556ca15aa20SStefano Zampini else continue; 15579566063dSJacob Faibussowitsch PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color)); 1558f1af5d2fSBarry Smith } 1559f1af5d2fSBarry Smith } 1560d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 1561f1af5d2fSBarry Smith } else { 1562f1af5d2fSBarry Smith /* use contour shading to indicate magnitude of values */ 1563f1af5d2fSBarry Smith /* first determine max of all nonzero values */ 1564b05fc000SLisandro Dalcin PetscReal minv = 0.0, maxv = 0.0; 1565b05fc000SLisandro Dalcin PetscDraw popup; 1566b05fc000SLisandro Dalcin 1567f1af5d2fSBarry Smith for (i = 0; i < m * n; i++) { 1568f1af5d2fSBarry Smith if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]); 1569f1af5d2fSBarry Smith } 1570383922c3SLisandro Dalcin if (minv >= maxv) maxv = minv + PETSC_SMALL; 15719566063dSJacob Faibussowitsch PetscCall(PetscDrawGetPopup(draw, &popup)); 15729566063dSJacob Faibussowitsch PetscCall(PetscDrawScalePopup(popup, minv, maxv)); 1573383922c3SLisandro Dalcin 1574d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 1575f1af5d2fSBarry Smith for (j = 0; j < n; j++) { 1576f1af5d2fSBarry Smith x_l = j; 1577f1af5d2fSBarry Smith x_r = x_l + 1.0; 1578f1af5d2fSBarry Smith for (i = 0; i < m; i++) { 1579f1af5d2fSBarry Smith y_l = m - i - 1.0; 1580f1af5d2fSBarry Smith y_r = y_l + 1.0; 1581b05fc000SLisandro Dalcin color = PetscDrawRealToColor(PetscAbsScalar(v[j * m + i]), minv, maxv); 15829566063dSJacob Faibussowitsch PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color)); 1583f1af5d2fSBarry Smith } 1584f1af5d2fSBarry Smith } 1585d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 1586f1af5d2fSBarry Smith } 15879566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 15883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1589f1af5d2fSBarry Smith } 1590f1af5d2fSBarry Smith 1591d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw(Mat A, PetscViewer viewer) 1592d71ae5a4SJacob Faibussowitsch { 1593b0a32e0cSBarry Smith PetscDraw draw; 1594ace3abfcSBarry Smith PetscBool isnull; 1595329f5518SBarry Smith PetscReal xr, yr, xl, yl, h, w; 1596f1af5d2fSBarry Smith 1597f1af5d2fSBarry Smith PetscFunctionBegin; 15989566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 15999566063dSJacob Faibussowitsch PetscCall(PetscDrawIsNull(draw, &isnull)); 16003ba16761SJacob Faibussowitsch if (isnull) PetscFunctionReturn(PETSC_SUCCESS); 1601f1af5d2fSBarry Smith 16029371c9d4SSatish Balay xr = A->cmap->n; 16039371c9d4SSatish Balay yr = A->rmap->n; 16049371c9d4SSatish Balay h = yr / 10.0; 16059371c9d4SSatish Balay w = xr / 10.0; 16069371c9d4SSatish Balay xr += w; 16079371c9d4SSatish Balay yr += h; 16089371c9d4SSatish Balay xl = -w; 16099371c9d4SSatish Balay yl = -h; 16109566063dSJacob Faibussowitsch PetscCall(PetscDrawSetCoordinates(draw, xl, yl, xr, yr)); 16119566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", (PetscObject)viewer)); 16129566063dSJacob Faibussowitsch PetscCall(PetscDrawZoom(draw, MatView_SeqDense_Draw_Zoom, A)); 16139566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", NULL)); 16149566063dSJacob Faibussowitsch PetscCall(PetscDrawSave(draw)); 16153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1616f1af5d2fSBarry Smith } 1617f1af5d2fSBarry Smith 1618d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_SeqDense(Mat A, PetscViewer viewer) 1619d71ae5a4SJacob Faibussowitsch { 1620ace3abfcSBarry Smith PetscBool iascii, isbinary, isdraw; 1621932b0c3eSLois Curfman McInnes 16223a40ed3dSBarry Smith PetscFunctionBegin; 16239566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 16249566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 16259566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 16261baa6e33SBarry Smith if (iascii) PetscCall(MatView_SeqDense_ASCII(A, viewer)); 16271baa6e33SBarry Smith else if (isbinary) PetscCall(MatView_Dense_Binary(A, viewer)); 16281baa6e33SBarry Smith else if (isdraw) PetscCall(MatView_SeqDense_Draw(A, viewer)); 16293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1630932b0c3eSLois Curfman McInnes } 1631289bc588SBarry Smith 1632d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A, const PetscScalar *array) 1633d71ae5a4SJacob Faibussowitsch { 1634d3042a70SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1635d3042a70SBarry Smith 1636d3042a70SBarry Smith PetscFunctionBegin; 163728b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 163828b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 163928b400f6SJacob Faibussowitsch PetscCheck(!a->unplacedarray, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreArray() first"); 1640d3042a70SBarry Smith a->unplacedarray = a->v; 1641d3042a70SBarry Smith a->unplaced_user_alloc = a->user_alloc; 1642d3042a70SBarry Smith a->v = (PetscScalar *)array; 1643637a0070SStefano Zampini a->user_alloc = PETSC_TRUE; 164447d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1645c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_CPU; 1646ca15aa20SStefano Zampini #endif 16473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1648d3042a70SBarry Smith } 1649d3042a70SBarry Smith 1650d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseResetArray_SeqDense(Mat A) 1651d71ae5a4SJacob Faibussowitsch { 1652d3042a70SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1653d3042a70SBarry Smith 1654d3042a70SBarry Smith PetscFunctionBegin; 165528b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 165628b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 1657d3042a70SBarry Smith a->v = a->unplacedarray; 1658d3042a70SBarry Smith a->user_alloc = a->unplaced_user_alloc; 1659d3042a70SBarry Smith a->unplacedarray = NULL; 166047d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1661c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_CPU; 1662ca15aa20SStefano Zampini #endif 16633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1664d3042a70SBarry Smith } 1665d3042a70SBarry Smith 1666d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A, const PetscScalar *array) 1667d71ae5a4SJacob Faibussowitsch { 1668d5ea218eSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1669d5ea218eSStefano Zampini 1670d5ea218eSStefano Zampini PetscFunctionBegin; 167128b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 167228b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 16739566063dSJacob Faibussowitsch if (!a->user_alloc) PetscCall(PetscFree(a->v)); 1674d5ea218eSStefano Zampini a->v = (PetscScalar *)array; 1675d5ea218eSStefano Zampini a->user_alloc = PETSC_FALSE; 167647d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1677d5ea218eSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 1678d5ea218eSStefano Zampini #endif 16793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1680d5ea218eSStefano Zampini } 1681d5ea218eSStefano Zampini 1682d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDestroy_SeqDense(Mat mat) 1683d71ae5a4SJacob Faibussowitsch { 1684ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)mat->data; 168590f02eecSBarry Smith 16863a40ed3dSBarry Smith PetscFunctionBegin; 16873ba16761SJacob Faibussowitsch PetscCall(PetscLogObjectState((PetscObject)mat, "Rows %" PetscInt_FMT " Cols %" PetscInt_FMT, mat->rmap->n, mat->cmap->n)); 16889566063dSJacob Faibussowitsch PetscCall(VecDestroy(&(l->qrrhs))); 16899566063dSJacob Faibussowitsch PetscCall(PetscFree(l->tau)); 16909566063dSJacob Faibussowitsch PetscCall(PetscFree(l->pivots)); 16919566063dSJacob Faibussowitsch PetscCall(PetscFree(l->fwork)); 16929566063dSJacob Faibussowitsch if (!l->user_alloc) PetscCall(PetscFree(l->v)); 16939566063dSJacob Faibussowitsch if (!l->unplaced_user_alloc) PetscCall(PetscFree(l->unplacedarray)); 169428b400f6SJacob Faibussowitsch PetscCheck(!l->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 169528b400f6SJacob Faibussowitsch PetscCheck(!l->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 16969566063dSJacob Faibussowitsch PetscCall(VecDestroy(&l->cvec)); 16979566063dSJacob Faibussowitsch PetscCall(MatDestroy(&l->cmat)); 16989566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->data)); 1699dbd8c25aSHong Zhang 17009566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)mat, NULL)); 17019566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactor_C", NULL)); 17022e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorSymbolic_C", NULL)); 17032e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorNumeric_C", NULL)); 17049566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetLDA_C", NULL)); 17059566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseSetLDA_C", NULL)); 17069566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArray_C", NULL)); 17079566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArray_C", NULL)); 17089566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDensePlaceArray_C", NULL)); 17099566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseResetArray_C", NULL)); 17109566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseReplaceArray_C", NULL)); 17119566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayRead_C", NULL)); 17129566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayRead_C", NULL)); 17139566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayWrite_C", NULL)); 17149566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayWrite_C", NULL)); 17159566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqaij_C", NULL)); 17168baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 17179566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_elemental_C", NULL)); 17188baccfbdSHong Zhang #endif 1719d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 17209566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_scalapack_C", NULL)); 1721d24d4204SJose E. Roman #endif 17222bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA) 17239566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensecuda_C", NULL)); 17249566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", NULL)); 17259566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdense_C", NULL)); 17262e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensecuda_C", NULL)); 17272bf066beSStefano Zampini #endif 172847d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 172947d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensehip_C", NULL)); 173047d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensehip_seqdensehip_C", NULL)); 173147d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensehip_seqdense_C", NULL)); 173247d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensehip_C", NULL)); 173347d993e7Ssuyashtn #endif 17349566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatSeqDenseSetPreallocation_C", NULL)); 17359566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqaij_seqdense_C", NULL)); 17369566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdense_C", NULL)); 17379566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqbaij_seqdense_C", NULL)); 17389566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqsbaij_seqdense_C", NULL)); 173952c5f739Sprj- 17409566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumn_C", NULL)); 17419566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumn_C", NULL)); 17429566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVec_C", NULL)); 17439566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVec_C", NULL)); 17449566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecRead_C", NULL)); 17459566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecRead_C", NULL)); 17469566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecWrite_C", NULL)); 17479566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecWrite_C", NULL)); 17489566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetSubMatrix_C", NULL)); 17499566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreSubMatrix_C", NULL)); 17503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1751289bc588SBarry Smith } 1752289bc588SBarry Smith 1753d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatTranspose_SeqDense(Mat A, MatReuse reuse, Mat *matout) 1754d71ae5a4SJacob Faibussowitsch { 1755c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 17566536e3caSStefano Zampini PetscInt k, j, m = A->rmap->n, M = mat->lda, n = A->cmap->n; 175787828ca2SBarry Smith PetscScalar *v, tmp; 175848b35521SBarry Smith 17593a40ed3dSBarry Smith PetscFunctionBegin; 17607fb60732SBarry Smith if (reuse == MAT_REUSE_MATRIX) PetscCall(MatTransposeCheckNonzeroState_Private(A, *matout)); 17616536e3caSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 17626536e3caSStefano Zampini if (m == n) { /* in place transpose */ 17639566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 1764d3e5ee88SLois Curfman McInnes for (j = 0; j < m; j++) { 1765289bc588SBarry Smith for (k = 0; k < j; k++) { 17661b807ce4Svictorle tmp = v[j + k * M]; 17671b807ce4Svictorle v[j + k * M] = v[k + j * M]; 17681b807ce4Svictorle v[k + j * M] = tmp; 1769289bc588SBarry Smith } 1770289bc588SBarry Smith } 17719566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 17726536e3caSStefano Zampini } else { /* reuse memory, temporary allocates new memory */ 17736536e3caSStefano Zampini PetscScalar *v2; 17746536e3caSStefano Zampini PetscLayout tmplayout; 17756536e3caSStefano Zampini 17769566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((size_t)m * n, &v2)); 17779566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 17786536e3caSStefano Zampini for (j = 0; j < n; j++) { 17796536e3caSStefano Zampini for (k = 0; k < m; k++) v2[j + (size_t)k * n] = v[k + (size_t)j * M]; 17806536e3caSStefano Zampini } 17819566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(v, v2, (size_t)m * n)); 17829566063dSJacob Faibussowitsch PetscCall(PetscFree(v2)); 17839566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 17846536e3caSStefano Zampini /* cleanup size dependent quantities */ 17859566063dSJacob Faibussowitsch PetscCall(VecDestroy(&mat->cvec)); 17869566063dSJacob Faibussowitsch PetscCall(MatDestroy(&mat->cmat)); 17879566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->pivots)); 17889566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->fwork)); 17896536e3caSStefano Zampini /* swap row/col layouts */ 17906536e3caSStefano Zampini mat->lda = n; 17916536e3caSStefano Zampini tmplayout = A->rmap; 17926536e3caSStefano Zampini A->rmap = A->cmap; 17936536e3caSStefano Zampini A->cmap = tmplayout; 17946536e3caSStefano Zampini } 17953a40ed3dSBarry Smith } else { /* out-of-place transpose */ 1796d3e5ee88SLois Curfman McInnes Mat tmat; 1797ec8511deSBarry Smith Mat_SeqDense *tmatd; 179887828ca2SBarry Smith PetscScalar *v2; 1799af36a384SStefano Zampini PetscInt M2; 1800ea709b57SSatish Balay 18016536e3caSStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 18029566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &tmat)); 18039566063dSJacob Faibussowitsch PetscCall(MatSetSizes(tmat, A->cmap->n, A->rmap->n, A->cmap->n, A->rmap->n)); 18049566063dSJacob Faibussowitsch PetscCall(MatSetType(tmat, ((PetscObject)A)->type_name)); 18059566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(tmat, NULL)); 1806ca15aa20SStefano Zampini } else tmat = *matout; 1807ca15aa20SStefano Zampini 18089566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&v)); 18099566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(tmat, &v2)); 1810ec8511deSBarry Smith tmatd = (Mat_SeqDense *)tmat->data; 1811ca15aa20SStefano Zampini M2 = tmatd->lda; 1812d3e5ee88SLois Curfman McInnes for (j = 0; j < n; j++) { 1813af36a384SStefano Zampini for (k = 0; k < m; k++) v2[j + k * M2] = v[k + j * M]; 1814d3e5ee88SLois Curfman McInnes } 18159566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(tmat, &v2)); 18169566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&v)); 18179566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(tmat, MAT_FINAL_ASSEMBLY)); 18189566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(tmat, MAT_FINAL_ASSEMBLY)); 18196536e3caSStefano Zampini *matout = tmat; 182048b35521SBarry Smith } 18213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1822289bc588SBarry Smith } 1823289bc588SBarry Smith 1824d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatEqual_SeqDense(Mat A1, Mat A2, PetscBool *flg) 1825d71ae5a4SJacob Faibussowitsch { 1826c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat1 = (Mat_SeqDense *)A1->data; 1827c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat2 = (Mat_SeqDense *)A2->data; 1828ca15aa20SStefano Zampini PetscInt i; 1829ca15aa20SStefano Zampini const PetscScalar *v1, *v2; 18309ea5d5aeSSatish Balay 18313a40ed3dSBarry Smith PetscFunctionBegin; 18329371c9d4SSatish Balay if (A1->rmap->n != A2->rmap->n) { 18339371c9d4SSatish Balay *flg = PETSC_FALSE; 18343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18359371c9d4SSatish Balay } 18369371c9d4SSatish Balay if (A1->cmap->n != A2->cmap->n) { 18379371c9d4SSatish Balay *flg = PETSC_FALSE; 18383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18399371c9d4SSatish Balay } 18409566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A1, &v1)); 18419566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A2, &v2)); 1842ca15aa20SStefano Zampini for (i = 0; i < A1->cmap->n; i++) { 18439566063dSJacob Faibussowitsch PetscCall(PetscArraycmp(v1, v2, A1->rmap->n, flg)); 18443ba16761SJacob Faibussowitsch if (*flg == PETSC_FALSE) PetscFunctionReturn(PETSC_SUCCESS); 1845ca15aa20SStefano Zampini v1 += mat1->lda; 1846ca15aa20SStefano Zampini v2 += mat2->lda; 18471b807ce4Svictorle } 18489566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A1, &v1)); 18499566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A2, &v2)); 185077c4ece6SBarry Smith *flg = PETSC_TRUE; 18513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1852289bc588SBarry Smith } 1853289bc588SBarry Smith 185414277c92SJacob Faibussowitsch PetscErrorCode MatGetDiagonal_SeqDense(Mat A, Vec v) 1855d71ae5a4SJacob Faibussowitsch { 1856c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 185713f74950SBarry Smith PetscInt i, n, len; 1858ca15aa20SStefano Zampini PetscScalar *x; 1859ca15aa20SStefano Zampini const PetscScalar *vv; 186044cd7ae7SLois Curfman McInnes 18613a40ed3dSBarry Smith PetscFunctionBegin; 18629566063dSJacob Faibussowitsch PetscCall(VecGetSize(v, &n)); 18639566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 1864d0f46423SBarry Smith len = PetscMin(A->rmap->n, A->cmap->n); 18659566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &vv)); 186608401ef6SPierre Jolivet PetscCheck(n == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming mat and vec"); 1867ad540459SPierre Jolivet for (i = 0; i < len; i++) x[i] = vv[i * mat->lda + i]; 18689566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &vv)); 18699566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 18703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1871289bc588SBarry Smith } 1872289bc588SBarry Smith 1873d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDiagonalScale_SeqDense(Mat A, Vec ll, Vec rr) 1874d71ae5a4SJacob Faibussowitsch { 1875c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1876f1ceaac6SMatthew G. Knepley const PetscScalar *l, *r; 1877ca15aa20SStefano Zampini PetscScalar x, *v, *vv; 1878d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n; 187955659b69SBarry Smith 18803a40ed3dSBarry Smith PetscFunctionBegin; 18819566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &vv)); 188228988994SBarry Smith if (ll) { 18839566063dSJacob Faibussowitsch PetscCall(VecGetSize(ll, &m)); 18849566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(ll, &l)); 188508401ef6SPierre Jolivet PetscCheck(m == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Left scaling vec wrong size"); 1886da3a660dSBarry Smith for (i = 0; i < m; i++) { 1887da3a660dSBarry Smith x = l[i]; 1888ca15aa20SStefano Zampini v = vv + i; 18899371c9d4SSatish Balay for (j = 0; j < n; j++) { 18909371c9d4SSatish Balay (*v) *= x; 18919371c9d4SSatish Balay v += mat->lda; 18929371c9d4SSatish Balay } 1893da3a660dSBarry Smith } 18949566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(ll, &l)); 18959566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * n * m)); 1896da3a660dSBarry Smith } 189728988994SBarry Smith if (rr) { 18989566063dSJacob Faibussowitsch PetscCall(VecGetSize(rr, &n)); 18999566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(rr, &r)); 190008401ef6SPierre Jolivet PetscCheck(n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Right scaling vec wrong size"); 1901da3a660dSBarry Smith for (i = 0; i < n; i++) { 1902da3a660dSBarry Smith x = r[i]; 1903ca15aa20SStefano Zampini v = vv + i * mat->lda; 19042205254eSKarl Rupp for (j = 0; j < m; j++) (*v++) *= x; 1905da3a660dSBarry Smith } 19069566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(rr, &r)); 19079566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * n * m)); 1908da3a660dSBarry Smith } 19099566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &vv)); 19103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1911289bc588SBarry Smith } 1912289bc588SBarry Smith 1913d71ae5a4SJacob Faibussowitsch PetscErrorCode MatNorm_SeqDense(Mat A, NormType type, PetscReal *nrm) 1914d71ae5a4SJacob Faibussowitsch { 1915c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1916ca15aa20SStefano Zampini PetscScalar *v, *vv; 1917329f5518SBarry Smith PetscReal sum = 0.0; 191875f6d85dSStefano Zampini PetscInt lda, m = A->rmap->n, i, j; 191955659b69SBarry Smith 19203a40ed3dSBarry Smith PetscFunctionBegin; 19219566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&vv)); 19229566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(A, &lda)); 1923ca15aa20SStefano Zampini v = vv; 1924289bc588SBarry Smith if (type == NORM_FROBENIUS) { 1925a5ce6ee0Svictorle if (lda > m) { 1926d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1927ca15aa20SStefano Zampini v = vv + j * lda; 1928a5ce6ee0Svictorle for (i = 0; i < m; i++) { 19299371c9d4SSatish Balay sum += PetscRealPart(PetscConj(*v) * (*v)); 19309371c9d4SSatish Balay v++; 1931a5ce6ee0Svictorle } 1932a5ce6ee0Svictorle } 1933a5ce6ee0Svictorle } else { 1934570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16) 1935570b7f6dSBarry Smith PetscBLASInt one = 1, cnt = A->cmap->n * A->rmap->n; 1936792fecdfSBarry Smith PetscCallBLAS("BLASnrm2", *nrm = BLASnrm2_(&cnt, v, &one)); 1937570b7f6dSBarry Smith } 1938570b7f6dSBarry Smith #else 1939d0f46423SBarry Smith for (i = 0; i < A->cmap->n * A->rmap->n; i++) { 19409371c9d4SSatish Balay sum += PetscRealPart(PetscConj(*v) * (*v)); 19419371c9d4SSatish Balay v++; 1942289bc588SBarry Smith } 1943a5ce6ee0Svictorle } 19448f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 1945570b7f6dSBarry Smith #endif 19469566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->cmap->n * A->rmap->n)); 19473a40ed3dSBarry Smith } else if (type == NORM_1) { 1948064f8208SBarry Smith *nrm = 0.0; 1949d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1950ca15aa20SStefano Zampini v = vv + j * mat->lda; 1951289bc588SBarry Smith sum = 0.0; 1952d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 19539371c9d4SSatish Balay sum += PetscAbsScalar(*v); 19549371c9d4SSatish Balay v++; 1955289bc588SBarry Smith } 1956064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 1957289bc588SBarry Smith } 19589566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n)); 19593a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 1960064f8208SBarry Smith *nrm = 0.0; 1961d0f46423SBarry Smith for (j = 0; j < A->rmap->n; j++) { 1962ca15aa20SStefano Zampini v = vv + j; 1963289bc588SBarry Smith sum = 0.0; 1964d0f46423SBarry Smith for (i = 0; i < A->cmap->n; i++) { 19659371c9d4SSatish Balay sum += PetscAbsScalar(*v); 19669371c9d4SSatish Balay v += mat->lda; 1967289bc588SBarry Smith } 1968064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 1969289bc588SBarry Smith } 19709566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n)); 1971e7e72b3dSBarry Smith } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "No two norm"); 19729566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&vv)); 19733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1974289bc588SBarry Smith } 1975289bc588SBarry Smith 1976d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetOption_SeqDense(Mat A, MatOption op, PetscBool flg) 1977d71ae5a4SJacob Faibussowitsch { 1978c0bbcb79SLois Curfman McInnes Mat_SeqDense *aij = (Mat_SeqDense *)A->data; 197967e560aaSBarry Smith 19803a40ed3dSBarry Smith PetscFunctionBegin; 1981b5a2b587SKris Buschelman switch (op) { 1982d71ae5a4SJacob Faibussowitsch case MAT_ROW_ORIENTED: 1983d71ae5a4SJacob Faibussowitsch aij->roworiented = flg; 1984d71ae5a4SJacob Faibussowitsch break; 1985512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 1986b5a2b587SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 19873971808eSMatthew Knepley case MAT_NEW_NONZERO_ALLOCATION_ERR: 19888c78258cSHong Zhang case MAT_FORCE_DIAGONAL_ENTRIES: 198913fa8e87SLisandro Dalcin case MAT_KEEP_NONZERO_PATTERN: 1990b5a2b587SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 1991b5a2b587SKris Buschelman case MAT_USE_HASH_TABLE: 19920f8fb01aSBarry Smith case MAT_IGNORE_ZERO_ENTRIES: 19935021d80fSJed Brown case MAT_IGNORE_LOWER_TRIANGULAR: 1994d71ae5a4SJacob Faibussowitsch case MAT_SORTED_FULL: 1995d71ae5a4SJacob Faibussowitsch PetscCall(PetscInfo(A, "Option %s ignored\n", MatOptions[op])); 1996d71ae5a4SJacob Faibussowitsch break; 19975021d80fSJed Brown case MAT_SPD: 199877e54ba9SKris Buschelman case MAT_SYMMETRIC: 199977e54ba9SKris Buschelman case MAT_STRUCTURALLY_SYMMETRIC: 20009a4540c5SBarry Smith case MAT_HERMITIAN: 20019a4540c5SBarry Smith case MAT_SYMMETRY_ETERNAL: 2002b94d7dedSBarry Smith case MAT_STRUCTURAL_SYMMETRY_ETERNAL: 2003d71ae5a4SJacob Faibussowitsch case MAT_SPD_ETERNAL: 2004d71ae5a4SJacob Faibussowitsch break; 2005d71ae5a4SJacob Faibussowitsch default: 2006d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "unknown option %s", MatOptions[op]); 20073a40ed3dSBarry Smith } 20083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2009289bc588SBarry Smith } 2010289bc588SBarry Smith 2011d71ae5a4SJacob Faibussowitsch PetscErrorCode MatZeroEntries_SeqDense(Mat A) 2012d71ae5a4SJacob Faibussowitsch { 2013ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)A->data; 20143d8925e7SStefano Zampini PetscInt lda = l->lda, m = A->rmap->n, n = A->cmap->n, j; 2015ca15aa20SStefano Zampini PetscScalar *v; 20163a40ed3dSBarry Smith 20173a40ed3dSBarry Smith PetscFunctionBegin; 20189566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(A, &v)); 2019a5ce6ee0Svictorle if (lda > m) { 202048a46eb9SPierre Jolivet for (j = 0; j < n; j++) PetscCall(PetscArrayzero(v + j * lda, m)); 2021a5ce6ee0Svictorle } else { 20229566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(v, PetscInt64Mult(m, n))); 2023a5ce6ee0Svictorle } 20249566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(A, &v)); 20253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 20266f0a148fSBarry Smith } 20276f0a148fSBarry Smith 2028d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatZeroRows_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) 2029d71ae5a4SJacob Faibussowitsch { 2030ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)A->data; 2031b9679d65SBarry Smith PetscInt m = l->lda, n = A->cmap->n, i, j; 2032ca15aa20SStefano Zampini PetscScalar *slot, *bb, *v; 203397b48c8fSBarry Smith const PetscScalar *xx; 203455659b69SBarry Smith 20353a40ed3dSBarry Smith PetscFunctionBegin; 203676bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 2037b9679d65SBarry Smith for (i = 0; i < N; i++) { 203808401ef6SPierre Jolivet PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed"); 203908401ef6SPierre 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); 2040b9679d65SBarry Smith } 204176bd3646SJed Brown } 20423ba16761SJacob Faibussowitsch if (!N) PetscFunctionReturn(PETSC_SUCCESS); 2043b9679d65SBarry Smith 204497b48c8fSBarry Smith /* fix right hand side if needed */ 204597b48c8fSBarry Smith if (x && b) { 20469566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 20479566063dSJacob Faibussowitsch PetscCall(VecGetArray(b, &bb)); 20482205254eSKarl Rupp for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]]; 20499566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 20509566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(b, &bb)); 205197b48c8fSBarry Smith } 205297b48c8fSBarry Smith 20539566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 20546f0a148fSBarry Smith for (i = 0; i < N; i++) { 2055ca15aa20SStefano Zampini slot = v + rows[i]; 20569371c9d4SSatish Balay for (j = 0; j < n; j++) { 20579371c9d4SSatish Balay *slot = 0.0; 20589371c9d4SSatish Balay slot += m; 20599371c9d4SSatish Balay } 20606f0a148fSBarry Smith } 2061f4df32b1SMatthew Knepley if (diag != 0.0) { 206208401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices"); 20636f0a148fSBarry Smith for (i = 0; i < N; i++) { 2064ca15aa20SStefano Zampini slot = v + (m + 1) * rows[i]; 2065f4df32b1SMatthew Knepley *slot = diag; 20666f0a148fSBarry Smith } 20676f0a148fSBarry Smith } 20689566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 20693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 20706f0a148fSBarry Smith } 2071557bce09SLois Curfman McInnes 2072d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A, PetscInt *lda) 2073d71ae5a4SJacob Faibussowitsch { 207449a6ff4bSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 207549a6ff4bSBarry Smith 207649a6ff4bSBarry Smith PetscFunctionBegin; 207749a6ff4bSBarry Smith *lda = mat->lda; 20783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 207949a6ff4bSBarry Smith } 208049a6ff4bSBarry Smith 2081d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArray_SeqDense(Mat A, PetscScalar **array) 2082d71ae5a4SJacob Faibussowitsch { 2083c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 20843a40ed3dSBarry Smith 20853a40ed3dSBarry Smith PetscFunctionBegin; 208628b400f6SJacob Faibussowitsch PetscCheck(!mat->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 208764e87e97SBarry Smith *array = mat->v; 20883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 208964e87e97SBarry Smith } 20900754003eSLois Curfman McInnes 2091d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A, PetscScalar **array) 2092d71ae5a4SJacob Faibussowitsch { 20933a40ed3dSBarry Smith PetscFunctionBegin; 209475f6d85dSStefano Zampini if (array) *array = NULL; 20953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2096ff14e315SSatish Balay } 20970754003eSLois Curfman McInnes 20980f74d2c1SSatish Balay /*@ 209911a5261eSBarry Smith MatDenseGetLDA - gets the leading dimension of the array returned from `MatDenseGetArray()` 210049a6ff4bSBarry Smith 21012ef1f0ffSBarry Smith Not Collective 210249a6ff4bSBarry Smith 210349a6ff4bSBarry Smith Input Parameter: 2104fe59aa6dSJacob Faibussowitsch . A - a `MATDENSE` or `MATDENSECUDA` matrix 210549a6ff4bSBarry Smith 210649a6ff4bSBarry Smith Output Parameter: 210749a6ff4bSBarry Smith . lda - the leading dimension 210849a6ff4bSBarry Smith 210949a6ff4bSBarry Smith Level: intermediate 211049a6ff4bSBarry Smith 21111cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseSetLDA()` 211249a6ff4bSBarry Smith @*/ 2113d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetLDA(Mat A, PetscInt *lda) 2114d71ae5a4SJacob Faibussowitsch { 211549a6ff4bSBarry Smith PetscFunctionBegin; 2116d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 21174f572ea9SToby Isaac PetscAssertPointer(lda, 2); 211875f6d85dSStefano Zampini MatCheckPreallocated(A, 1); 2119cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetLDA_C", (Mat, PetscInt *), (A, lda)); 21203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 212149a6ff4bSBarry Smith } 212249a6ff4bSBarry Smith 21230f74d2c1SSatish Balay /*@ 212411a5261eSBarry Smith MatDenseSetLDA - Sets the leading dimension of the array used by the `MATDENSE` matrix 2125ad16ce7aSStefano Zampini 21262ef1f0ffSBarry Smith Not Collective 2127ad16ce7aSStefano Zampini 2128d8d19677SJose E. Roman Input Parameters: 2129fe59aa6dSJacob Faibussowitsch + A - a `MATDENSE` or `MATDENSECUDA` matrix 2130ad16ce7aSStefano Zampini - lda - the leading dimension 2131ad16ce7aSStefano Zampini 2132ad16ce7aSStefano Zampini Level: intermediate 2133ad16ce7aSStefano Zampini 21341cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetLDA()` 2135ad16ce7aSStefano Zampini @*/ 2136d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA(Mat A, PetscInt lda) 2137d71ae5a4SJacob Faibussowitsch { 2138ad16ce7aSStefano Zampini PetscFunctionBegin; 2139ad16ce7aSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2140cac4c232SBarry Smith PetscTryMethod(A, "MatDenseSetLDA_C", (Mat, PetscInt), (A, lda)); 21413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2142ad16ce7aSStefano Zampini } 2143ad16ce7aSStefano Zampini 2144ad16ce7aSStefano Zampini /*@C 214511a5261eSBarry Smith MatDenseGetArray - gives read-write access to the array where the data for a `MATDENSE` matrix is stored 214673a71a0fSBarry Smith 2147c3339decSBarry Smith Logically Collective 214873a71a0fSBarry Smith 214973a71a0fSBarry Smith Input Parameter: 2150fe59aa6dSJacob Faibussowitsch . A - a dense matrix 215173a71a0fSBarry Smith 215273a71a0fSBarry Smith Output Parameter: 215373a71a0fSBarry Smith . array - pointer to the data 215473a71a0fSBarry Smith 215573a71a0fSBarry Smith Level: intermediate 215673a71a0fSBarry Smith 2157fe59aa6dSJacob Faibussowitsch Fortran Notes: 21580ab4885dSBarry Smith `MatDenseGetArray()` Fortran binding is deprecated (since PETSc 3.19), use `MatDenseGetArrayF90()` 21590ab4885dSBarry Smith 21601cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 216173a71a0fSBarry Smith @*/ 2162d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArray(Mat A, PetscScalar **array) 2163d71ae5a4SJacob Faibussowitsch { 216473a71a0fSBarry Smith PetscFunctionBegin; 2165d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 21664f572ea9SToby Isaac PetscAssertPointer(array, 2); 2167cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array)); 21683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 216973a71a0fSBarry Smith } 217073a71a0fSBarry Smith 2171dec5eb66SMatthew G Knepley /*@C 217211a5261eSBarry Smith MatDenseRestoreArray - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArray()` 217373a71a0fSBarry Smith 2174c3339decSBarry Smith Logically Collective 21758572280aSBarry Smith 21768572280aSBarry Smith Input Parameters: 2177fe59aa6dSJacob Faibussowitsch + A - a dense matrix 21782ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`) 21798572280aSBarry Smith 21808572280aSBarry Smith Level: intermediate 21818572280aSBarry Smith 2182fe59aa6dSJacob Faibussowitsch Fortran Notes: 21830ab4885dSBarry Smith `MatDenseRestoreArray()` Fortran binding is deprecated (since PETSc 3.19), use `MatDenseRestoreArrayF90()` 21840ab4885dSBarry Smith 21851cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 21868572280aSBarry Smith @*/ 2187d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArray(Mat A, PetscScalar **array) 2188d71ae5a4SJacob Faibussowitsch { 21898572280aSBarry Smith PetscFunctionBegin; 2190d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 21914f572ea9SToby Isaac if (array) PetscAssertPointer(array, 2); 2192cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array)); 21939566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)A)); 219447d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 2195637a0070SStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 2196637a0070SStefano Zampini #endif 21973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 21988572280aSBarry Smith } 21998572280aSBarry Smith 22008572280aSBarry Smith /*@C 220111a5261eSBarry Smith MatDenseGetArrayRead - gives read-only access to the array where the data for a `MATDENSE` matrix is stored 22028572280aSBarry Smith 22030ab4885dSBarry Smith Not Collective; No Fortran Support 22048572280aSBarry Smith 22058572280aSBarry Smith Input Parameter: 2206fe59aa6dSJacob Faibussowitsch . A - a dense matrix 22078572280aSBarry Smith 22088572280aSBarry Smith Output Parameter: 22098572280aSBarry Smith . array - pointer to the data 22108572280aSBarry Smith 22118572280aSBarry Smith Level: intermediate 22128572280aSBarry Smith 22131cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 22148572280aSBarry Smith @*/ 2215d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArrayRead(Mat A, const PetscScalar **array) 2216d71ae5a4SJacob Faibussowitsch { 22178572280aSBarry Smith PetscFunctionBegin; 2218d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22194f572ea9SToby Isaac PetscAssertPointer(array, 2); 22205c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 22213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22228572280aSBarry Smith } 22238572280aSBarry Smith 22248572280aSBarry Smith /*@C 222511a5261eSBarry Smith MatDenseRestoreArrayRead - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayRead()` 22268572280aSBarry Smith 22270ab4885dSBarry Smith Not Collective; No Fortran Support 222873a71a0fSBarry Smith 222973a71a0fSBarry Smith Input Parameters: 2230fe59aa6dSJacob Faibussowitsch + A - a dense matrix 22312ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`) 223273a71a0fSBarry Smith 223373a71a0fSBarry Smith Level: intermediate 223473a71a0fSBarry Smith 22351cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 223673a71a0fSBarry Smith @*/ 2237d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArrayRead(Mat A, const PetscScalar **array) 2238d71ae5a4SJacob Faibussowitsch { 223973a71a0fSBarry Smith PetscFunctionBegin; 2240d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22414f572ea9SToby Isaac if (array) PetscAssertPointer(array, 2); 22425c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 22433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 224473a71a0fSBarry Smith } 224573a71a0fSBarry Smith 22466947451fSStefano Zampini /*@C 224711a5261eSBarry Smith MatDenseGetArrayWrite - gives write-only access to the array where the data for a `MATDENSE` matrix is stored 22486947451fSStefano Zampini 22490ab4885dSBarry Smith Not Collective; No Fortran Support 22506947451fSStefano Zampini 22516947451fSStefano Zampini Input Parameter: 2252fe59aa6dSJacob Faibussowitsch . A - a dense matrix 22536947451fSStefano Zampini 22546947451fSStefano Zampini Output Parameter: 22556947451fSStefano Zampini . array - pointer to the data 22566947451fSStefano Zampini 22576947451fSStefano Zampini Level: intermediate 22586947451fSStefano Zampini 22591cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()` 22606947451fSStefano Zampini @*/ 2261d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArrayWrite(Mat A, PetscScalar **array) 2262d71ae5a4SJacob Faibussowitsch { 22636947451fSStefano Zampini PetscFunctionBegin; 2264d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22654f572ea9SToby Isaac PetscAssertPointer(array, 2); 2266cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array)); 22673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22686947451fSStefano Zampini } 22696947451fSStefano Zampini 22706947451fSStefano Zampini /*@C 227111a5261eSBarry Smith MatDenseRestoreArrayWrite - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayWrite()` 22726947451fSStefano Zampini 22730ab4885dSBarry Smith Not Collective; No Fortran Support 22746947451fSStefano Zampini 22756947451fSStefano Zampini Input Parameters: 2276fe59aa6dSJacob Faibussowitsch + A - a dense matrix 22772ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`) 22786947451fSStefano Zampini 22796947451fSStefano Zampini Level: intermediate 22806947451fSStefano Zampini 22811cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()` 22826947451fSStefano Zampini @*/ 2283d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArrayWrite(Mat A, PetscScalar **array) 2284d71ae5a4SJacob Faibussowitsch { 22856947451fSStefano Zampini PetscFunctionBegin; 2286d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22874f572ea9SToby Isaac if (array) PetscAssertPointer(array, 2); 2288cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array)); 22899566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)A)); 229047d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 22916947451fSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 22926947451fSStefano Zampini #endif 22933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22946947451fSStefano Zampini } 22956947451fSStefano Zampini 2296cd3f9d89SJunchao Zhang /*@C 2297cd3f9d89SJunchao Zhang MatDenseGetArrayAndMemType - gives read-write access to the array where the data for a `MATDENSE` matrix is stored 2298cd3f9d89SJunchao Zhang 2299cd3f9d89SJunchao Zhang Logically Collective 2300cd3f9d89SJunchao Zhang 2301cd3f9d89SJunchao Zhang Input Parameter: 2302fe59aa6dSJacob Faibussowitsch . A - a dense matrix 2303cd3f9d89SJunchao Zhang 2304cd3f9d89SJunchao Zhang Output Parameters: 2305cd3f9d89SJunchao Zhang + array - pointer to the data 2306cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer 2307cd3f9d89SJunchao Zhang 2308cd3f9d89SJunchao Zhang Level: intermediate 2309cd3f9d89SJunchao Zhang 23102ef1f0ffSBarry Smith Notes: 23112ef1f0ffSBarry Smith If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc., 23122ef1f0ffSBarry Smith an array on device is always returned and is guaranteed to contain the matrix's latest data. 23132ef1f0ffSBarry Smith 23141cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayAndMemType()`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArrayWriteAndMemType()`, `MatDenseGetArrayRead()`, 2315cd3f9d89SJunchao Zhang `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()` 2316cd3f9d89SJunchao Zhang @*/ 2317cd3f9d89SJunchao Zhang PetscErrorCode MatDenseGetArrayAndMemType(Mat A, PetscScalar **array, PetscMemType *mtype) 2318cd3f9d89SJunchao Zhang { 2319cd3f9d89SJunchao Zhang PetscBool isMPI; 2320cd3f9d89SJunchao Zhang 2321cd3f9d89SJunchao Zhang PetscFunctionBegin; 2322cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 23234f572ea9SToby Isaac PetscAssertPointer(array, 2); 2324e865de01SJunchao 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 */ 2325cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2326cd3f9d89SJunchao Zhang if (isMPI) { 2327cd3f9d89SJunchao Zhang /* Dispatch here so that the code can be reused for all subclasses of MATDENSE */ 2328cd3f9d89SJunchao Zhang PetscCall(MatDenseGetArrayAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype)); 2329cd3f9d89SJunchao Zhang } else { 2330cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **, PetscMemType *); 23313ba16761SJacob Faibussowitsch 23323ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayAndMemType_C", &fptr)); 2333cd3f9d89SJunchao Zhang if (fptr) { 2334cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array, mtype)); 2335cd3f9d89SJunchao Zhang } else { 2336cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array)); 2337cd3f9d89SJunchao Zhang if (mtype) *mtype = PETSC_MEMTYPE_HOST; 2338cd3f9d89SJunchao Zhang } 2339cd3f9d89SJunchao Zhang } 23403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2341cd3f9d89SJunchao Zhang } 2342cd3f9d89SJunchao Zhang 2343cd3f9d89SJunchao Zhang /*@C 2344cd3f9d89SJunchao Zhang MatDenseRestoreArrayAndMemType - returns access to the array that is obtained by `MatDenseGetArrayAndMemType()` 2345cd3f9d89SJunchao Zhang 2346cd3f9d89SJunchao Zhang Logically Collective 2347cd3f9d89SJunchao Zhang 2348cd3f9d89SJunchao Zhang Input Parameters: 2349fe59aa6dSJacob Faibussowitsch + A - a dense matrix 2350cd3f9d89SJunchao Zhang - array - pointer to the data 2351cd3f9d89SJunchao Zhang 2352cd3f9d89SJunchao Zhang Level: intermediate 2353cd3f9d89SJunchao Zhang 23541cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 2355cd3f9d89SJunchao Zhang @*/ 2356cd3f9d89SJunchao Zhang PetscErrorCode MatDenseRestoreArrayAndMemType(Mat A, PetscScalar **array) 2357cd3f9d89SJunchao Zhang { 2358cd3f9d89SJunchao Zhang PetscBool isMPI; 2359cd3f9d89SJunchao Zhang 2360cd3f9d89SJunchao Zhang PetscFunctionBegin; 2361cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 23624f572ea9SToby Isaac PetscAssertPointer(array, 2); 2363cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2364cd3f9d89SJunchao Zhang if (isMPI) { 2365cd3f9d89SJunchao Zhang PetscCall(MatDenseRestoreArrayAndMemType(((Mat_MPIDense *)A->data)->A, array)); 2366cd3f9d89SJunchao Zhang } else { 2367cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **); 23683ba16761SJacob Faibussowitsch 23693ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayAndMemType_C", &fptr)); 2370cd3f9d89SJunchao Zhang if (fptr) { 2371cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array)); 2372cd3f9d89SJunchao Zhang } else { 2373cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array)); 2374cd3f9d89SJunchao Zhang } 2375cd3f9d89SJunchao Zhang *array = NULL; 2376cd3f9d89SJunchao Zhang } 2377cd3f9d89SJunchao Zhang PetscCall(PetscObjectStateIncrease((PetscObject)A)); 23783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2379cd3f9d89SJunchao Zhang } 2380cd3f9d89SJunchao Zhang 2381cd3f9d89SJunchao Zhang /*@C 2382cd3f9d89SJunchao Zhang MatDenseGetArrayReadAndMemType - gives read-only access to the array where the data for a `MATDENSE` matrix is stored 2383cd3f9d89SJunchao Zhang 2384cd3f9d89SJunchao Zhang Logically Collective 2385cd3f9d89SJunchao Zhang 2386cd3f9d89SJunchao Zhang Input Parameter: 2387fe59aa6dSJacob Faibussowitsch . A - a dense matrix 2388cd3f9d89SJunchao Zhang 2389cd3f9d89SJunchao Zhang Output Parameters: 2390cd3f9d89SJunchao Zhang + array - pointer to the data 2391cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer 2392cd3f9d89SJunchao Zhang 2393cd3f9d89SJunchao Zhang Level: intermediate 2394cd3f9d89SJunchao Zhang 23952ef1f0ffSBarry Smith Notes: 23962ef1f0ffSBarry Smith If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc., 23972ef1f0ffSBarry Smith an array on device is always returned and is guaranteed to contain the matrix's latest data. 23982ef1f0ffSBarry Smith 23991cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayReadAndMemType()`, `MatDenseGetArrayWriteAndMemType()`, 2400cd3f9d89SJunchao Zhang `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()` 2401cd3f9d89SJunchao Zhang @*/ 2402cd3f9d89SJunchao Zhang PetscErrorCode MatDenseGetArrayReadAndMemType(Mat A, const PetscScalar **array, PetscMemType *mtype) 2403cd3f9d89SJunchao Zhang { 2404cd3f9d89SJunchao Zhang PetscBool isMPI; 2405cd3f9d89SJunchao Zhang 2406cd3f9d89SJunchao Zhang PetscFunctionBegin; 2407cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 24084f572ea9SToby Isaac PetscAssertPointer(array, 2); 2409e865de01SJunchao 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 */ 2410cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2411cd3f9d89SJunchao Zhang if (isMPI) { /* Dispatch here so that the code can be reused for all subclasses of MATDENSE */ 2412cd3f9d89SJunchao Zhang PetscCall(MatDenseGetArrayReadAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype)); 2413cd3f9d89SJunchao Zhang } else { 2414cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, const PetscScalar **, PetscMemType *); 24153ba16761SJacob Faibussowitsch 24163ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayReadAndMemType_C", &fptr)); 2417cd3f9d89SJunchao Zhang if (fptr) { 2418cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array, mtype)); 2419cd3f9d89SJunchao Zhang } else { 24205c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 2421cd3f9d89SJunchao Zhang if (mtype) *mtype = PETSC_MEMTYPE_HOST; 2422cd3f9d89SJunchao Zhang } 2423cd3f9d89SJunchao Zhang } 24243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2425cd3f9d89SJunchao Zhang } 2426cd3f9d89SJunchao Zhang 2427cd3f9d89SJunchao Zhang /*@C 2428cd3f9d89SJunchao Zhang MatDenseRestoreArrayReadAndMemType - returns access to the array that is obtained by `MatDenseGetArrayReadAndMemType()` 2429cd3f9d89SJunchao Zhang 2430cd3f9d89SJunchao Zhang Logically Collective 2431cd3f9d89SJunchao Zhang 2432cd3f9d89SJunchao Zhang Input Parameters: 2433fe59aa6dSJacob Faibussowitsch + A - a dense matrix 2434cd3f9d89SJunchao Zhang - array - pointer to the data 2435cd3f9d89SJunchao Zhang 2436cd3f9d89SJunchao Zhang Level: intermediate 2437cd3f9d89SJunchao Zhang 24381cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 2439cd3f9d89SJunchao Zhang @*/ 2440cd3f9d89SJunchao Zhang PetscErrorCode MatDenseRestoreArrayReadAndMemType(Mat A, const PetscScalar **array) 2441cd3f9d89SJunchao Zhang { 2442cd3f9d89SJunchao Zhang PetscBool isMPI; 2443cd3f9d89SJunchao Zhang 2444cd3f9d89SJunchao Zhang PetscFunctionBegin; 2445cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 24464f572ea9SToby Isaac PetscAssertPointer(array, 2); 2447cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2448cd3f9d89SJunchao Zhang if (isMPI) { 2449cd3f9d89SJunchao Zhang PetscCall(MatDenseRestoreArrayReadAndMemType(((Mat_MPIDense *)A->data)->A, array)); 2450cd3f9d89SJunchao Zhang } else { 2451cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, const PetscScalar **); 24523ba16761SJacob Faibussowitsch 24533ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayReadAndMemType_C", &fptr)); 2454cd3f9d89SJunchao Zhang if (fptr) { 2455cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array)); 2456cd3f9d89SJunchao Zhang } else { 24575c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 2458cd3f9d89SJunchao Zhang } 2459cd3f9d89SJunchao Zhang *array = NULL; 2460cd3f9d89SJunchao Zhang } 24613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2462cd3f9d89SJunchao Zhang } 2463cd3f9d89SJunchao Zhang 2464cd3f9d89SJunchao Zhang /*@C 2465cd3f9d89SJunchao Zhang MatDenseGetArrayWriteAndMemType - gives write-only access to the array where the data for a `MATDENSE` matrix is stored 2466cd3f9d89SJunchao Zhang 2467cd3f9d89SJunchao Zhang Logically Collective 2468cd3f9d89SJunchao Zhang 2469cd3f9d89SJunchao Zhang Input Parameter: 2470fe59aa6dSJacob Faibussowitsch . A - a dense matrix 2471cd3f9d89SJunchao Zhang 2472cd3f9d89SJunchao Zhang Output Parameters: 2473cd3f9d89SJunchao Zhang + array - pointer to the data 2474cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer 2475cd3f9d89SJunchao Zhang 2476cd3f9d89SJunchao Zhang Level: intermediate 2477cd3f9d89SJunchao Zhang 24782ef1f0ffSBarry Smith Notes: 24792ef1f0ffSBarry Smith If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc., 24802ef1f0ffSBarry Smith an array on device is always returned and is guaranteed to contain the matrix's latest data. 24812ef1f0ffSBarry Smith 24821cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayWriteAndMemType()`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArrayRead()`, 2483cd3f9d89SJunchao Zhang `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()` 2484cd3f9d89SJunchao Zhang @*/ 2485cd3f9d89SJunchao Zhang PetscErrorCode MatDenseGetArrayWriteAndMemType(Mat A, PetscScalar **array, PetscMemType *mtype) 2486cd3f9d89SJunchao Zhang { 2487cd3f9d89SJunchao Zhang PetscBool isMPI; 2488cd3f9d89SJunchao Zhang 2489cd3f9d89SJunchao Zhang PetscFunctionBegin; 2490cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 24914f572ea9SToby Isaac PetscAssertPointer(array, 2); 2492e865de01SJunchao 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 */ 2493cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2494cd3f9d89SJunchao Zhang if (isMPI) { 2495cd3f9d89SJunchao Zhang PetscCall(MatDenseGetArrayWriteAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype)); 2496cd3f9d89SJunchao Zhang } else { 2497cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **, PetscMemType *); 24983ba16761SJacob Faibussowitsch 24993ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayWriteAndMemType_C", &fptr)); 2500cd3f9d89SJunchao Zhang if (fptr) { 2501cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array, mtype)); 2502cd3f9d89SJunchao Zhang } else { 2503cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array)); 2504cd3f9d89SJunchao Zhang if (mtype) *mtype = PETSC_MEMTYPE_HOST; 2505cd3f9d89SJunchao Zhang } 2506cd3f9d89SJunchao Zhang } 25073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2508cd3f9d89SJunchao Zhang } 2509cd3f9d89SJunchao Zhang 2510cd3f9d89SJunchao Zhang /*@C 2511cd3f9d89SJunchao Zhang MatDenseRestoreArrayWriteAndMemType - returns access to the array that is obtained by `MatDenseGetArrayReadAndMemType()` 2512cd3f9d89SJunchao Zhang 2513cd3f9d89SJunchao Zhang Logically Collective 2514cd3f9d89SJunchao Zhang 2515cd3f9d89SJunchao Zhang Input Parameters: 2516fe59aa6dSJacob Faibussowitsch + A - a dense matrix 2517cd3f9d89SJunchao Zhang - array - pointer to the data 2518cd3f9d89SJunchao Zhang 2519cd3f9d89SJunchao Zhang Level: intermediate 2520cd3f9d89SJunchao Zhang 25211cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayWriteAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 2522cd3f9d89SJunchao Zhang @*/ 2523cd3f9d89SJunchao Zhang PetscErrorCode MatDenseRestoreArrayWriteAndMemType(Mat A, PetscScalar **array) 2524cd3f9d89SJunchao Zhang { 2525cd3f9d89SJunchao Zhang PetscBool isMPI; 2526cd3f9d89SJunchao Zhang 2527cd3f9d89SJunchao Zhang PetscFunctionBegin; 2528cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 25294f572ea9SToby Isaac PetscAssertPointer(array, 2); 2530cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2531cd3f9d89SJunchao Zhang if (isMPI) { 2532cd3f9d89SJunchao Zhang PetscCall(MatDenseRestoreArrayWriteAndMemType(((Mat_MPIDense *)A->data)->A, array)); 2533cd3f9d89SJunchao Zhang } else { 2534cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **); 25353ba16761SJacob Faibussowitsch 25363ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayWriteAndMemType_C", &fptr)); 2537cd3f9d89SJunchao Zhang if (fptr) { 2538cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array)); 2539cd3f9d89SJunchao Zhang } else { 2540cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array)); 2541cd3f9d89SJunchao Zhang } 2542cd3f9d89SJunchao Zhang *array = NULL; 2543cd3f9d89SJunchao Zhang } 2544cd3f9d89SJunchao Zhang PetscCall(PetscObjectStateIncrease((PetscObject)A)); 25453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2546cd3f9d89SJunchao Zhang } 2547cd3f9d89SJunchao Zhang 2548d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A, IS isrow, IS iscol, MatReuse scall, Mat *B) 2549d71ae5a4SJacob Faibussowitsch { 2550c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 2551bf5a80bcSToby Isaac PetscInt i, j, nrows, ncols, ldb; 25525d0c19d7SBarry Smith const PetscInt *irow, *icol; 255387828ca2SBarry Smith PetscScalar *av, *bv, *v = mat->v; 25540754003eSLois Curfman McInnes Mat newmat; 25550754003eSLois Curfman McInnes 25563a40ed3dSBarry Smith PetscFunctionBegin; 25579566063dSJacob Faibussowitsch PetscCall(ISGetIndices(isrow, &irow)); 25589566063dSJacob Faibussowitsch PetscCall(ISGetIndices(iscol, &icol)); 25599566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(isrow, &nrows)); 25609566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(iscol, &ncols)); 25610754003eSLois Curfman McInnes 2562182d2002SSatish Balay /* Check submatrixcall */ 2563182d2002SSatish Balay if (scall == MAT_REUSE_MATRIX) { 256413f74950SBarry Smith PetscInt n_cols, n_rows; 25659566063dSJacob Faibussowitsch PetscCall(MatGetSize(*B, &n_rows, &n_cols)); 256621a2c019SBarry Smith if (n_rows != nrows || n_cols != ncols) { 2567f746d493SDmitry Karpeev /* resize the result matrix to match number of requested rows/columns */ 25689566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*B, nrows, ncols, nrows, ncols)); 256921a2c019SBarry Smith } 2570182d2002SSatish Balay newmat = *B; 2571182d2002SSatish Balay } else { 25720754003eSLois Curfman McInnes /* Create and fill new matrix */ 25739566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &newmat)); 25749566063dSJacob Faibussowitsch PetscCall(MatSetSizes(newmat, nrows, ncols, nrows, ncols)); 25759566063dSJacob Faibussowitsch PetscCall(MatSetType(newmat, ((PetscObject)A)->type_name)); 25769566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(newmat, NULL)); 2577182d2002SSatish Balay } 2578182d2002SSatish Balay 2579182d2002SSatish Balay /* Now extract the data pointers and do the copy,column at a time */ 25809566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(newmat, &bv)); 25819566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(newmat, &ldb)); 2582182d2002SSatish Balay for (i = 0; i < ncols; i++) { 25836de62eeeSBarry Smith av = v + mat->lda * icol[i]; 2584ca15aa20SStefano Zampini for (j = 0; j < nrows; j++) bv[j] = av[irow[j]]; 2585bf5a80bcSToby Isaac bv += ldb; 25860754003eSLois Curfman McInnes } 25879566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(newmat, &bv)); 2588182d2002SSatish Balay 2589182d2002SSatish Balay /* Assemble the matrices so that the correct flags are set */ 25909566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(newmat, MAT_FINAL_ASSEMBLY)); 25919566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(newmat, MAT_FINAL_ASSEMBLY)); 25920754003eSLois Curfman McInnes 25930754003eSLois Curfman McInnes /* Free work space */ 25949566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(isrow, &irow)); 25959566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(iscol, &icol)); 2596182d2002SSatish Balay *B = newmat; 25973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 25980754003eSLois Curfman McInnes } 25990754003eSLois Curfman McInnes 2600d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A, PetscInt n, const IS irow[], const IS icol[], MatReuse scall, Mat *B[]) 2601d71ae5a4SJacob Faibussowitsch { 260213f74950SBarry Smith PetscInt i; 2603905e6a2fSBarry Smith 26043a40ed3dSBarry Smith PetscFunctionBegin; 260548a46eb9SPierre Jolivet if (scall == MAT_INITIAL_MATRIX) PetscCall(PetscCalloc1(n, B)); 2606905e6a2fSBarry Smith 260748a46eb9SPierre Jolivet for (i = 0; i < n; i++) PetscCall(MatCreateSubMatrix_SeqDense(A, irow[i], icol[i], scall, &(*B)[i])); 26083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2609905e6a2fSBarry Smith } 2610905e6a2fSBarry Smith 2611d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat, MatAssemblyType mode) 2612d71ae5a4SJacob Faibussowitsch { 2613c0aa2d19SHong Zhang PetscFunctionBegin; 26143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2615c0aa2d19SHong Zhang } 2616c0aa2d19SHong Zhang 2617d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat, MatAssemblyType mode) 2618d71ae5a4SJacob Faibussowitsch { 2619c0aa2d19SHong Zhang PetscFunctionBegin; 26203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2621c0aa2d19SHong Zhang } 2622c0aa2d19SHong Zhang 2623d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCopy_SeqDense(Mat A, Mat B, MatStructure str) 2624d71ae5a4SJacob Faibussowitsch { 26254b0e389bSBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data; 2626ca15aa20SStefano Zampini const PetscScalar *va; 2627ca15aa20SStefano Zampini PetscScalar *vb; 2628d0f46423SBarry Smith PetscInt lda1 = a->lda, lda2 = b->lda, m = A->rmap->n, n = A->cmap->n, j; 26293a40ed3dSBarry Smith 26303a40ed3dSBarry Smith PetscFunctionBegin; 263133f4a19fSKris Buschelman /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */ 263233f4a19fSKris Buschelman if (A->ops->copy != B->ops->copy) { 26339566063dSJacob Faibussowitsch PetscCall(MatCopy_Basic(A, B, str)); 26343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26353a40ed3dSBarry Smith } 2636aed4548fSBarry Smith PetscCheck(m == B->rmap->n && n == B->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "size(B) != size(A)"); 26379566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &va)); 26389566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(B, &vb)); 2639a5ce6ee0Svictorle if (lda1 > m || lda2 > m) { 264048a46eb9SPierre Jolivet for (j = 0; j < n; j++) PetscCall(PetscArraycpy(vb + j * lda2, va + j * lda1, m)); 2641a5ce6ee0Svictorle } else { 26429566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(vb, va, A->rmap->n * A->cmap->n)); 2643a5ce6ee0Svictorle } 26449566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(B, &vb)); 26459566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &va)); 26469566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 26479566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 26483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2649273d9f13SBarry Smith } 2650273d9f13SBarry Smith 2651d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetUp_SeqDense(Mat A) 2652d71ae5a4SJacob Faibussowitsch { 2653273d9f13SBarry Smith PetscFunctionBegin; 26549566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 26559566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 265648a46eb9SPierre Jolivet if (!A->preallocated) PetscCall(MatSeqDenseSetPreallocation(A, NULL)); 26573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26584b0e389bSBarry Smith } 26594b0e389bSBarry Smith 2660d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatConjugate_SeqDense(Mat A) 2661d71ae5a4SJacob Faibussowitsch { 26624396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 266306c5243aSJose E. Roman PetscInt i, j; 26644396437dSToby Isaac PetscInt min = PetscMin(A->rmap->n, A->cmap->n); 2665ca15aa20SStefano Zampini PetscScalar *aa; 2666ba337c44SJed Brown 2667ba337c44SJed Brown PetscFunctionBegin; 26689566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 266906c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 267006c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscConj(aa[i + j * mat->lda]); 267106c5243aSJose E. Roman } 26729566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 26739371c9d4SSatish Balay if (mat->tau) 26749371c9d4SSatish Balay for (i = 0; i < min; i++) mat->tau[i] = PetscConj(mat->tau[i]); 26753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2676ba337c44SJed Brown } 2677ba337c44SJed Brown 2678d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRealPart_SeqDense(Mat A) 2679d71ae5a4SJacob Faibussowitsch { 268006c5243aSJose E. Roman Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 268106c5243aSJose E. Roman PetscInt i, j; 2682ca15aa20SStefano Zampini PetscScalar *aa; 2683ba337c44SJed Brown 2684ba337c44SJed Brown PetscFunctionBegin; 26859566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 268606c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 268706c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscRealPart(aa[i + j * mat->lda]); 268806c5243aSJose E. Roman } 26899566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 26903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2691ba337c44SJed Brown } 2692ba337c44SJed Brown 2693d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatImaginaryPart_SeqDense(Mat A) 2694d71ae5a4SJacob Faibussowitsch { 269506c5243aSJose E. Roman Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 269606c5243aSJose E. Roman PetscInt i, j; 2697ca15aa20SStefano Zampini PetscScalar *aa; 2698ba337c44SJed Brown 2699ba337c44SJed Brown PetscFunctionBegin; 27009566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 270106c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 270206c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscImaginaryPart(aa[i + j * mat->lda]); 270306c5243aSJose E. Roman } 27049566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 27053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2706ba337c44SJed Brown } 2707284134d9SBarry Smith 2708d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2709d71ae5a4SJacob Faibussowitsch { 2710d0f46423SBarry Smith PetscInt m = A->rmap->n, n = B->cmap->n; 271147d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 2712a9fe9ddaSSatish Balay 2713ee16a9a1SHong Zhang PetscFunctionBegin; 27149566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 271547d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 27169566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 271747d993e7Ssuyashtn #endif 271847d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 271947d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 272047d993e7Ssuyashtn #endif 27217a3c3d58SStefano Zampini if (!cisdense) { 27227a3c3d58SStefano Zampini PetscBool flg; 27237a3c3d58SStefano Zampini 27249566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 27259566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 27267a3c3d58SStefano Zampini } 27279566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 27283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2729ee16a9a1SHong Zhang } 2730a9fe9ddaSSatish Balay 2731d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2732d71ae5a4SJacob Faibussowitsch { 27336718818eSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data, *c = (Mat_SeqDense *)C->data; 27340805154bSBarry Smith PetscBLASInt m, n, k; 2735ca15aa20SStefano Zampini const PetscScalar *av, *bv; 2736ca15aa20SStefano Zampini PetscScalar *cv; 2737a9fe9ddaSSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 2738a9fe9ddaSSatish Balay 2739a9fe9ddaSSatish Balay PetscFunctionBegin; 27409566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 27419566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 27429566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 27433ba16761SJacob Faibussowitsch if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS); 27449566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 27459566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 27469566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2747792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("N", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 27489566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 27499566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 27509566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 27519566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 27523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2753a9fe9ddaSSatish Balay } 2754a9fe9ddaSSatish Balay 2755d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2756d71ae5a4SJacob Faibussowitsch { 275769f65d41SStefano Zampini PetscInt m = A->rmap->n, n = B->rmap->n; 275847d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 275969f65d41SStefano Zampini 276069f65d41SStefano Zampini PetscFunctionBegin; 27619566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 276247d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 27639566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 276447d993e7Ssuyashtn #endif 276547d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 276647d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 276747d993e7Ssuyashtn #endif 27687a3c3d58SStefano Zampini if (!cisdense) { 27697a3c3d58SStefano Zampini PetscBool flg; 27707a3c3d58SStefano Zampini 27719566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 27729566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 27737a3c3d58SStefano Zampini } 27749566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 27753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 277669f65d41SStefano Zampini } 277769f65d41SStefano Zampini 2778d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2779d71ae5a4SJacob Faibussowitsch { 278069f65d41SStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 278169f65d41SStefano Zampini Mat_SeqDense *b = (Mat_SeqDense *)B->data; 278269f65d41SStefano Zampini Mat_SeqDense *c = (Mat_SeqDense *)C->data; 27836718818eSStefano Zampini const PetscScalar *av, *bv; 27846718818eSStefano Zampini PetscScalar *cv; 278569f65d41SStefano Zampini PetscBLASInt m, n, k; 278669f65d41SStefano Zampini PetscScalar _DOne = 1.0, _DZero = 0.0; 278769f65d41SStefano Zampini 278869f65d41SStefano Zampini PetscFunctionBegin; 27899566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 27909566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 27919566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 27923ba16761SJacob Faibussowitsch if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS); 27939566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 27949566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 27959566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2796792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("N", "T", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 27979566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 27989566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 27999566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 28009566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 28013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 280269f65d41SStefano Zampini } 280369f65d41SStefano Zampini 2804d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2805d71ae5a4SJacob Faibussowitsch { 2806d0f46423SBarry Smith PetscInt m = A->cmap->n, n = B->cmap->n; 280747d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 2808a9fe9ddaSSatish Balay 2809ee16a9a1SHong Zhang PetscFunctionBegin; 28109566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 281147d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 28129566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 281347d993e7Ssuyashtn #endif 281447d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 281547d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 281647d993e7Ssuyashtn #endif 28177a3c3d58SStefano Zampini if (!cisdense) { 28187a3c3d58SStefano Zampini PetscBool flg; 28197a3c3d58SStefano Zampini 28209566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 28219566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 28227a3c3d58SStefano Zampini } 28239566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 28243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2825ee16a9a1SHong Zhang } 2826a9fe9ddaSSatish Balay 2827d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2828d71ae5a4SJacob Faibussowitsch { 2829a9fe9ddaSSatish Balay Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2830a9fe9ddaSSatish Balay Mat_SeqDense *b = (Mat_SeqDense *)B->data; 2831a9fe9ddaSSatish Balay Mat_SeqDense *c = (Mat_SeqDense *)C->data; 28326718818eSStefano Zampini const PetscScalar *av, *bv; 28336718818eSStefano Zampini PetscScalar *cv; 28340805154bSBarry Smith PetscBLASInt m, n, k; 2835a9fe9ddaSSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 2836a9fe9ddaSSatish Balay 2837a9fe9ddaSSatish Balay PetscFunctionBegin; 28389566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 28399566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 28409566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &k)); 28413ba16761SJacob Faibussowitsch if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS); 28429566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 28439566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 28449566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2845792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("T", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 28469566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 28479566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 28489566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 28499566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 28503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2851a9fe9ddaSSatish Balay } 2852985db425SBarry Smith 2853d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C) 2854d71ae5a4SJacob Faibussowitsch { 28554222ddf1SHong Zhang PetscFunctionBegin; 28564222ddf1SHong Zhang C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense; 28574222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AB; 28583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28594222ddf1SHong Zhang } 28604222ddf1SHong Zhang 2861d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C) 2862d71ae5a4SJacob Faibussowitsch { 28634222ddf1SHong Zhang PetscFunctionBegin; 28644222ddf1SHong Zhang C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense; 28654222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AtB; 28663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28674222ddf1SHong Zhang } 28684222ddf1SHong Zhang 2869d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C) 2870d71ae5a4SJacob Faibussowitsch { 28714222ddf1SHong Zhang PetscFunctionBegin; 28724222ddf1SHong Zhang C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense; 28734222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_ABt; 28743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28754222ddf1SHong Zhang } 28764222ddf1SHong Zhang 2877d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C) 2878d71ae5a4SJacob Faibussowitsch { 28794222ddf1SHong Zhang Mat_Product *product = C->product; 28804222ddf1SHong Zhang 28814222ddf1SHong Zhang PetscFunctionBegin; 28824222ddf1SHong Zhang switch (product->type) { 2883d71ae5a4SJacob Faibussowitsch case MATPRODUCT_AB: 2884d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_AB(C)); 2885d71ae5a4SJacob Faibussowitsch break; 2886d71ae5a4SJacob Faibussowitsch case MATPRODUCT_AtB: 2887d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_AtB(C)); 2888d71ae5a4SJacob Faibussowitsch break; 2889d71ae5a4SJacob Faibussowitsch case MATPRODUCT_ABt: 2890d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_ABt(C)); 2891d71ae5a4SJacob Faibussowitsch break; 2892d71ae5a4SJacob Faibussowitsch default: 2893d71ae5a4SJacob Faibussowitsch break; 28944222ddf1SHong Zhang } 28953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28964222ddf1SHong Zhang } 28974222ddf1SHong Zhang 2898d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMax_SeqDense(Mat A, Vec v, PetscInt idx[]) 2899d71ae5a4SJacob Faibussowitsch { 2900985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2901d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2902985db425SBarry Smith PetscScalar *x; 2903ca15aa20SStefano Zampini const PetscScalar *aa; 2904985db425SBarry Smith 2905985db425SBarry Smith PetscFunctionBegin; 290628b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29079566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29089566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 29099566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 291008401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2911985db425SBarry Smith for (i = 0; i < m; i++) { 29129371c9d4SSatish Balay x[i] = aa[i]; 29139371c9d4SSatish Balay if (idx) idx[i] = 0; 2914985db425SBarry Smith for (j = 1; j < n; j++) { 29159371c9d4SSatish Balay if (PetscRealPart(x[i]) < PetscRealPart(aa[i + a->lda * j])) { 29169371c9d4SSatish Balay x[i] = aa[i + a->lda * j]; 29179371c9d4SSatish Balay if (idx) idx[i] = j; 29189371c9d4SSatish Balay } 2919985db425SBarry Smith } 2920985db425SBarry Smith } 29219566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 29229566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 29233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2924985db425SBarry Smith } 2925985db425SBarry Smith 2926d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A, Vec v, PetscInt idx[]) 2927d71ae5a4SJacob Faibussowitsch { 2928985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2929d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2930985db425SBarry Smith PetscScalar *x; 2931985db425SBarry Smith PetscReal atmp; 2932ca15aa20SStefano Zampini const PetscScalar *aa; 2933985db425SBarry Smith 2934985db425SBarry Smith PetscFunctionBegin; 293528b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29369566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29379566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 29389566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 293908401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2940985db425SBarry Smith for (i = 0; i < m; i++) { 29419189402eSHong Zhang x[i] = PetscAbsScalar(aa[i]); 2942985db425SBarry Smith for (j = 1; j < n; j++) { 2943ca15aa20SStefano Zampini atmp = PetscAbsScalar(aa[i + a->lda * j]); 29449371c9d4SSatish Balay if (PetscAbsScalar(x[i]) < atmp) { 29459371c9d4SSatish Balay x[i] = atmp; 29469371c9d4SSatish Balay if (idx) idx[i] = j; 29479371c9d4SSatish Balay } 2948985db425SBarry Smith } 2949985db425SBarry Smith } 29509566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 29519566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 29523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2953985db425SBarry Smith } 2954985db425SBarry Smith 2955d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMin_SeqDense(Mat A, Vec v, PetscInt idx[]) 2956d71ae5a4SJacob Faibussowitsch { 2957985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2958d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2959985db425SBarry Smith PetscScalar *x; 2960ca15aa20SStefano Zampini const PetscScalar *aa; 2961985db425SBarry Smith 2962985db425SBarry Smith PetscFunctionBegin; 296328b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29649566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 29659566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29669566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 296708401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2968985db425SBarry Smith for (i = 0; i < m; i++) { 29699371c9d4SSatish Balay x[i] = aa[i]; 29709371c9d4SSatish Balay if (idx) idx[i] = 0; 2971985db425SBarry Smith for (j = 1; j < n; j++) { 29729371c9d4SSatish Balay if (PetscRealPart(x[i]) > PetscRealPart(aa[i + a->lda * j])) { 29739371c9d4SSatish Balay x[i] = aa[i + a->lda * j]; 29749371c9d4SSatish Balay if (idx) idx[i] = j; 29759371c9d4SSatish Balay } 2976985db425SBarry Smith } 2977985db425SBarry Smith } 29789566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 29799566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 29803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2981985db425SBarry Smith } 2982985db425SBarry Smith 2983d71ae5a4SJacob Faibussowitsch PetscErrorCode MatGetColumnVector_SeqDense(Mat A, Vec v, PetscInt col) 2984d71ae5a4SJacob Faibussowitsch { 29858d0534beSBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 29868d0534beSBarry Smith PetscScalar *x; 2987ca15aa20SStefano Zampini const PetscScalar *aa; 29888d0534beSBarry Smith 29898d0534beSBarry Smith PetscFunctionBegin; 299028b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29919566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 29929566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29939566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(x, aa + col * a->lda, A->rmap->n)); 29949566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 29959566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 29963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29978d0534beSBarry Smith } 29988d0534beSBarry Smith 2999d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatGetColumnReductions_SeqDense(Mat A, PetscInt type, PetscReal *reductions) 3000d71ae5a4SJacob Faibussowitsch { 30010716a85fSBarry Smith PetscInt i, j, m, n; 30021683a169SBarry Smith const PetscScalar *a; 30030716a85fSBarry Smith 30040716a85fSBarry Smith PetscFunctionBegin; 30059566063dSJacob Faibussowitsch PetscCall(MatGetSize(A, &m, &n)); 30069566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(reductions, n)); 30079566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &a)); 3008857cbf51SRichard Tran Mills if (type == NORM_2) { 30090716a85fSBarry Smith for (i = 0; i < n; i++) { 3010ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j] * a[j]); 30110716a85fSBarry Smith a += m; 30120716a85fSBarry Smith } 3013857cbf51SRichard Tran Mills } else if (type == NORM_1) { 30140716a85fSBarry Smith for (i = 0; i < n; i++) { 3015ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j]); 30160716a85fSBarry Smith a += m; 30170716a85fSBarry Smith } 3018857cbf51SRichard Tran Mills } else if (type == NORM_INFINITY) { 30190716a85fSBarry Smith for (i = 0; i < n; i++) { 3020ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] = PetscMax(PetscAbsScalar(a[j]), reductions[i]); 30210716a85fSBarry Smith a += m; 30220716a85fSBarry Smith } 3023857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_REALPART || type == REDUCTION_MEAN_REALPART) { 3024a873a8cdSSam Reynolds for (i = 0; i < n; i++) { 3025ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscRealPart(a[j]); 3026a873a8cdSSam Reynolds a += m; 3027a873a8cdSSam Reynolds } 3028857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_IMAGINARYPART || type == REDUCTION_MEAN_IMAGINARYPART) { 3029857cbf51SRichard Tran Mills for (i = 0; i < n; i++) { 3030ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscImaginaryPart(a[j]); 3031857cbf51SRichard Tran Mills a += m; 3032857cbf51SRichard Tran Mills } 3033857cbf51SRichard Tran Mills } else SETERRQ(PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Unknown reduction type"); 30349566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &a)); 3035857cbf51SRichard Tran Mills if (type == NORM_2) { 3036a873a8cdSSam Reynolds for (i = 0; i < n; i++) reductions[i] = PetscSqrtReal(reductions[i]); 3037857cbf51SRichard Tran Mills } else if (type == REDUCTION_MEAN_REALPART || type == REDUCTION_MEAN_IMAGINARYPART) { 3038a873a8cdSSam Reynolds for (i = 0; i < n; i++) reductions[i] /= m; 30390716a85fSBarry Smith } 30403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30410716a85fSBarry Smith } 30420716a85fSBarry Smith 3043d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetRandom_SeqDense(Mat x, PetscRandom rctx) 3044d71ae5a4SJacob Faibussowitsch { 304573a71a0fSBarry Smith PetscScalar *a; 3046637a0070SStefano Zampini PetscInt lda, m, n, i, j; 304773a71a0fSBarry Smith 304873a71a0fSBarry Smith PetscFunctionBegin; 30499566063dSJacob Faibussowitsch PetscCall(MatGetSize(x, &m, &n)); 30509566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(x, &lda)); 30513faff063SStefano Zampini PetscCall(MatDenseGetArrayWrite(x, &a)); 3052637a0070SStefano Zampini for (j = 0; j < n; j++) { 305348a46eb9SPierre Jolivet for (i = 0; i < m; i++) PetscCall(PetscRandomGetValue(rctx, a + j * lda + i)); 305473a71a0fSBarry Smith } 30553faff063SStefano Zampini PetscCall(MatDenseRestoreArrayWrite(x, &a)); 30563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 305773a71a0fSBarry Smith } 305873a71a0fSBarry Smith 3059d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A, PetscBool *missing, PetscInt *d) 3060d71ae5a4SJacob Faibussowitsch { 30613b49f96aSBarry Smith PetscFunctionBegin; 30623b49f96aSBarry Smith *missing = PETSC_FALSE; 30633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30643b49f96aSBarry Smith } 306573a71a0fSBarry Smith 3066ca15aa20SStefano Zampini /* vals is not const */ 3067d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A, PetscInt col, PetscScalar **vals) 3068d71ae5a4SJacob Faibussowitsch { 306986aefd0dSHong Zhang Mat_SeqDense *a = (Mat_SeqDense *)A->data; 3070ca15aa20SStefano Zampini PetscScalar *v; 307186aefd0dSHong Zhang 307286aefd0dSHong Zhang PetscFunctionBegin; 307328b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 30749566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 3075ca15aa20SStefano Zampini *vals = v + col * a->lda; 30769566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 30773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 307886aefd0dSHong Zhang } 307986aefd0dSHong Zhang 3080d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A, PetscScalar **vals) 3081d71ae5a4SJacob Faibussowitsch { 308286aefd0dSHong Zhang PetscFunctionBegin; 3083742765d3SMatthew Knepley if (vals) *vals = NULL; /* user cannot accidentally use the array later */ 30843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 308586aefd0dSHong Zhang } 3086abc3b08eSStefano Zampini 3087a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqDense, 3088905e6a2fSBarry Smith MatGetRow_SeqDense, 3089905e6a2fSBarry Smith MatRestoreRow_SeqDense, 3090905e6a2fSBarry Smith MatMult_SeqDense, 309197304618SKris Buschelman /* 4*/ MatMultAdd_SeqDense, 30927c922b88SBarry Smith MatMultTranspose_SeqDense, 30937c922b88SBarry Smith MatMultTransposeAdd_SeqDense, 3094f4259b30SLisandro Dalcin NULL, 3095f4259b30SLisandro Dalcin NULL, 3096f4259b30SLisandro Dalcin NULL, 3097f4259b30SLisandro Dalcin /* 10*/ NULL, 3098905e6a2fSBarry Smith MatLUFactor_SeqDense, 3099905e6a2fSBarry Smith MatCholeskyFactor_SeqDense, 310041f059aeSBarry Smith MatSOR_SeqDense, 3101ec8511deSBarry Smith MatTranspose_SeqDense, 310297304618SKris Buschelman /* 15*/ MatGetInfo_SeqDense, 3103905e6a2fSBarry Smith MatEqual_SeqDense, 3104905e6a2fSBarry Smith MatGetDiagonal_SeqDense, 3105905e6a2fSBarry Smith MatDiagonalScale_SeqDense, 3106905e6a2fSBarry Smith MatNorm_SeqDense, 3107c0aa2d19SHong Zhang /* 20*/ MatAssemblyBegin_SeqDense, 3108c0aa2d19SHong Zhang MatAssemblyEnd_SeqDense, 3109905e6a2fSBarry Smith MatSetOption_SeqDense, 3110905e6a2fSBarry Smith MatZeroEntries_SeqDense, 3111d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqDense, 3112f4259b30SLisandro Dalcin NULL, 3113f4259b30SLisandro Dalcin NULL, 3114f4259b30SLisandro Dalcin NULL, 3115f4259b30SLisandro Dalcin NULL, 31164994cf47SJed Brown /* 29*/ MatSetUp_SeqDense, 3117f4259b30SLisandro Dalcin NULL, 3118f4259b30SLisandro Dalcin NULL, 3119f4259b30SLisandro Dalcin NULL, 3120f4259b30SLisandro Dalcin NULL, 3121d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqDense, 3122f4259b30SLisandro Dalcin NULL, 3123f4259b30SLisandro Dalcin NULL, 3124f4259b30SLisandro Dalcin NULL, 3125f4259b30SLisandro Dalcin NULL, 3126d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqDense, 31277dae84e0SHong Zhang MatCreateSubMatrices_SeqDense, 3128f4259b30SLisandro Dalcin NULL, 31294b0e389bSBarry Smith MatGetValues_SeqDense, 3130a5ae1ecdSBarry Smith MatCopy_SeqDense, 3131d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqDense, 3132a5ae1ecdSBarry Smith MatScale_SeqDense, 31332f605a99SJose E. Roman MatShift_SeqDense, 3134f4259b30SLisandro Dalcin NULL, 31353f49a652SStefano Zampini MatZeroRowsColumns_SeqDense, 313673a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqDense, 3137f4259b30SLisandro Dalcin NULL, 3138f4259b30SLisandro Dalcin NULL, 3139f4259b30SLisandro Dalcin NULL, 3140f4259b30SLisandro Dalcin NULL, 3141f4259b30SLisandro Dalcin /* 54*/ NULL, 3142f4259b30SLisandro Dalcin NULL, 3143f4259b30SLisandro Dalcin NULL, 3144f4259b30SLisandro Dalcin NULL, 3145f4259b30SLisandro Dalcin NULL, 3146023c16fcSToby Isaac /* 59*/ MatCreateSubMatrix_SeqDense, 3147e03a110bSBarry Smith MatDestroy_SeqDense, 3148e03a110bSBarry Smith MatView_SeqDense, 3149f4259b30SLisandro Dalcin NULL, 3150f4259b30SLisandro Dalcin NULL, 3151f4259b30SLisandro Dalcin /* 64*/ NULL, 3152f4259b30SLisandro Dalcin NULL, 3153f4259b30SLisandro Dalcin NULL, 3154f4259b30SLisandro Dalcin NULL, 3155f4259b30SLisandro Dalcin NULL, 3156d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqDense, 3157f4259b30SLisandro Dalcin NULL, 3158f4259b30SLisandro Dalcin NULL, 3159f4259b30SLisandro Dalcin NULL, 3160f4259b30SLisandro Dalcin NULL, 3161f4259b30SLisandro Dalcin /* 74*/ NULL, 3162f4259b30SLisandro Dalcin NULL, 3163f4259b30SLisandro Dalcin NULL, 3164f4259b30SLisandro Dalcin NULL, 3165f4259b30SLisandro Dalcin NULL, 3166f4259b30SLisandro Dalcin /* 79*/ NULL, 3167f4259b30SLisandro Dalcin NULL, 3168f4259b30SLisandro Dalcin NULL, 3169f4259b30SLisandro Dalcin NULL, 31705bba2384SShri Abhyankar /* 83*/ MatLoad_SeqDense, 3171637a0070SStefano Zampini MatIsSymmetric_SeqDense, 31721cbb95d3SBarry Smith MatIsHermitian_SeqDense, 3173f4259b30SLisandro Dalcin NULL, 3174f4259b30SLisandro Dalcin NULL, 3175f4259b30SLisandro Dalcin NULL, 3176f4259b30SLisandro Dalcin /* 89*/ NULL, 3177f4259b30SLisandro Dalcin NULL, 3178a9fe9ddaSSatish Balay MatMatMultNumeric_SeqDense_SeqDense, 3179f4259b30SLisandro Dalcin NULL, 3180f4259b30SLisandro Dalcin NULL, 3181f4259b30SLisandro Dalcin /* 94*/ NULL, 3182f4259b30SLisandro Dalcin NULL, 3183f4259b30SLisandro Dalcin NULL, 318469f65d41SStefano Zampini MatMatTransposeMultNumeric_SeqDense_SeqDense, 3185f4259b30SLisandro Dalcin NULL, 31864222ddf1SHong Zhang /* 99*/ MatProductSetFromOptions_SeqDense, 3187f4259b30SLisandro Dalcin NULL, 3188f4259b30SLisandro Dalcin NULL, 3189ba337c44SJed Brown MatConjugate_SeqDense, 3190f4259b30SLisandro Dalcin NULL, 3191f4259b30SLisandro Dalcin /*104*/ NULL, 3192ba337c44SJed Brown MatRealPart_SeqDense, 3193ba337c44SJed Brown MatImaginaryPart_SeqDense, 3194f4259b30SLisandro Dalcin NULL, 3195f4259b30SLisandro Dalcin NULL, 3196f4259b30SLisandro Dalcin /*109*/ NULL, 3197f4259b30SLisandro Dalcin NULL, 31988d0534beSBarry Smith MatGetRowMin_SeqDense, 3199aabbc4fbSShri Abhyankar MatGetColumnVector_SeqDense, 32003b49f96aSBarry Smith MatMissingDiagonal_SeqDense, 3201f4259b30SLisandro Dalcin /*114*/ NULL, 3202f4259b30SLisandro Dalcin NULL, 3203f4259b30SLisandro Dalcin NULL, 3204f4259b30SLisandro Dalcin NULL, 3205f4259b30SLisandro Dalcin NULL, 3206f4259b30SLisandro Dalcin /*119*/ NULL, 3207f4259b30SLisandro Dalcin NULL, 3208f4259b30SLisandro Dalcin NULL, 3209f4259b30SLisandro Dalcin NULL, 3210f4259b30SLisandro Dalcin NULL, 3211f4259b30SLisandro Dalcin /*124*/ NULL, 3212a873a8cdSSam Reynolds MatGetColumnReductions_SeqDense, 3213f4259b30SLisandro Dalcin NULL, 3214f4259b30SLisandro Dalcin NULL, 3215f4259b30SLisandro Dalcin NULL, 3216f4259b30SLisandro Dalcin /*129*/ NULL, 3217f4259b30SLisandro Dalcin NULL, 3218f4259b30SLisandro Dalcin NULL, 321975648e8dSHong Zhang MatTransposeMatMultNumeric_SeqDense_SeqDense, 3220f4259b30SLisandro Dalcin NULL, 3221f4259b30SLisandro Dalcin /*134*/ NULL, 3222f4259b30SLisandro Dalcin NULL, 3223f4259b30SLisandro Dalcin NULL, 3224f4259b30SLisandro Dalcin NULL, 3225f4259b30SLisandro Dalcin NULL, 3226f4259b30SLisandro Dalcin /*139*/ NULL, 3227f4259b30SLisandro Dalcin NULL, 3228f4259b30SLisandro Dalcin NULL, 3229f4259b30SLisandro Dalcin NULL, 3230f4259b30SLisandro Dalcin NULL, 32314222ddf1SHong Zhang MatCreateMPIMatConcatenateSeqMat_SeqDense, 3232f4259b30SLisandro Dalcin /*145*/ NULL, 3233f4259b30SLisandro Dalcin NULL, 323499a7f59eSMark Adams NULL, 323599a7f59eSMark Adams NULL, 32367fb60732SBarry Smith NULL, 3237dec0b466SHong Zhang /*150*/ NULL, 3238dec0b466SHong Zhang NULL}; 323990ace30eSBarry Smith 32404b828684SBarry Smith /*@C 324111a5261eSBarry Smith MatCreateSeqDense - Creates a `MATSEQDENSE` that 32422ef1f0ffSBarry Smith is stored in column major order (the usual Fortran manner). Many 3243d65003e9SLois Curfman McInnes of the matrix operations use the BLAS and LAPACK routines. 3244289bc588SBarry Smith 3245d083f849SBarry Smith Collective 3246db81eaa0SLois Curfman McInnes 324720563c6bSBarry Smith Input Parameters: 324811a5261eSBarry Smith + comm - MPI communicator, set to `PETSC_COMM_SELF` 32490c775827SLois Curfman McInnes . m - number of rows 325018f449edSLois Curfman McInnes . n - number of columns 32512ef1f0ffSBarry Smith - data - optional location of matrix data in column major order. Use `NULL` for PETSc 3252dfc5480cSLois Curfman McInnes to control all matrix memory allocation. 325320563c6bSBarry Smith 325420563c6bSBarry Smith Output Parameter: 325544cd7ae7SLois Curfman McInnes . A - the matrix 325620563c6bSBarry Smith 32572ef1f0ffSBarry Smith Level: intermediate 32582ef1f0ffSBarry Smith 325911a5261eSBarry Smith Note: 326018f449edSLois Curfman McInnes The data input variable is intended primarily for Fortran programmers 326118f449edSLois Curfman McInnes who wish to allocate their own matrix memory space. Most users should 32622ef1f0ffSBarry Smith set `data` = `NULL`. 326318f449edSLois Curfman McInnes 32641cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()` 326520563c6bSBarry Smith @*/ 3266d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateSeqDense(MPI_Comm comm, PetscInt m, PetscInt n, PetscScalar *data, Mat *A) 3267d71ae5a4SJacob Faibussowitsch { 32683a40ed3dSBarry Smith PetscFunctionBegin; 32699566063dSJacob Faibussowitsch PetscCall(MatCreate(comm, A)); 32709566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*A, m, n, m, n)); 32719566063dSJacob Faibussowitsch PetscCall(MatSetType(*A, MATSEQDENSE)); 32729566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(*A, data)); 32733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3274273d9f13SBarry Smith } 3275273d9f13SBarry Smith 3276273d9f13SBarry Smith /*@C 327711a5261eSBarry Smith MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements of a `MATSEQDENSE` matrix 3278273d9f13SBarry Smith 3279d083f849SBarry Smith Collective 3280273d9f13SBarry Smith 3281273d9f13SBarry Smith Input Parameters: 32821c4f3114SJed Brown + B - the matrix 32832ef1f0ffSBarry Smith - data - the array (or `NULL`) 32842ef1f0ffSBarry Smith 32852ef1f0ffSBarry Smith Level: intermediate 3286273d9f13SBarry Smith 328711a5261eSBarry Smith Note: 3288273d9f13SBarry Smith The data input variable is intended primarily for Fortran programmers 3289273d9f13SBarry Smith who wish to allocate their own matrix memory space. Most users should 3290284134d9SBarry Smith need not call this routine. 3291273d9f13SBarry Smith 32921cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()`, `MatDenseSetLDA()` 3293273d9f13SBarry Smith @*/ 3294d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation(Mat B, PetscScalar data[]) 3295d71ae5a4SJacob Faibussowitsch { 3296a23d5eceSKris Buschelman PetscFunctionBegin; 3297d5ea218eSStefano Zampini PetscValidHeaderSpecific(B, MAT_CLASSID, 1); 3298cac4c232SBarry Smith PetscTryMethod(B, "MatSeqDenseSetPreallocation_C", (Mat, PetscScalar[]), (B, data)); 32993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3300a23d5eceSKris Buschelman } 3301a23d5eceSKris Buschelman 3302d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation_SeqDense(Mat B, PetscScalar *data) 3303d71ae5a4SJacob Faibussowitsch { 3304ad16ce7aSStefano Zampini Mat_SeqDense *b = (Mat_SeqDense *)B->data; 3305273d9f13SBarry Smith 3306273d9f13SBarry Smith PetscFunctionBegin; 330728b400f6SJacob Faibussowitsch PetscCheck(!b->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3308273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 3309a868139aSShri Abhyankar 33109566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(B->rmap)); 33119566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(B->cmap)); 331234ef9618SShri Abhyankar 3313ad16ce7aSStefano Zampini if (b->lda <= 0) b->lda = B->rmap->n; 331486d161a7SShri Abhyankar 33159e8f95c4SLisandro Dalcin if (!data) { /* petsc-allocated storage */ 33169566063dSJacob Faibussowitsch if (!b->user_alloc) PetscCall(PetscFree(b->v)); 33179566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((size_t)b->lda * B->cmap->n, &b->v)); 33182205254eSKarl Rupp 33199e8f95c4SLisandro Dalcin b->user_alloc = PETSC_FALSE; 3320273d9f13SBarry Smith } else { /* user-allocated storage */ 33219566063dSJacob Faibussowitsch if (!b->user_alloc) PetscCall(PetscFree(b->v)); 3322273d9f13SBarry Smith b->v = data; 3323273d9f13SBarry Smith b->user_alloc = PETSC_TRUE; 3324273d9f13SBarry Smith } 33250450473dSBarry Smith B->assembled = PETSC_TRUE; 33263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3327273d9f13SBarry Smith } 3328273d9f13SBarry Smith 332965b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 3330d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) 3331d71ae5a4SJacob Faibussowitsch { 3332d77f618aSHong Zhang Mat mat_elemental; 33331683a169SBarry Smith const PetscScalar *array; 33341683a169SBarry Smith PetscScalar *v_colwise; 3335d77f618aSHong Zhang PetscInt M = A->rmap->N, N = A->cmap->N, i, j, k, *rows, *cols; 3336d77f618aSHong Zhang 33378baccfbdSHong Zhang PetscFunctionBegin; 33389566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(M * N, &v_colwise, M, &rows, N, &cols)); 33399566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &array)); 3340d77f618aSHong Zhang /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */ 3341d77f618aSHong Zhang k = 0; 3342d77f618aSHong Zhang for (j = 0; j < N; j++) { 3343d77f618aSHong Zhang cols[j] = j; 3344ad540459SPierre Jolivet for (i = 0; i < M; i++) v_colwise[j * M + i] = array[k++]; 3345d77f618aSHong Zhang } 3346ad540459SPierre Jolivet for (i = 0; i < M; i++) rows[i] = i; 33479566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &array)); 3348d77f618aSHong Zhang 33499566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental)); 33509566063dSJacob Faibussowitsch PetscCall(MatSetSizes(mat_elemental, PETSC_DECIDE, PETSC_DECIDE, M, N)); 33519566063dSJacob Faibussowitsch PetscCall(MatSetType(mat_elemental, MATELEMENTAL)); 33529566063dSJacob Faibussowitsch PetscCall(MatSetUp(mat_elemental)); 3353d77f618aSHong Zhang 3354d77f618aSHong Zhang /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */ 33559566063dSJacob Faibussowitsch PetscCall(MatSetValues(mat_elemental, M, rows, N, cols, v_colwise, ADD_VALUES)); 33569566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY)); 33579566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY)); 33589566063dSJacob Faibussowitsch PetscCall(PetscFree3(v_colwise, rows, cols)); 3359d77f618aSHong Zhang 3360511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 33619566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A, &mat_elemental)); 3362d77f618aSHong Zhang } else { 3363d77f618aSHong Zhang *newmat = mat_elemental; 3364d77f618aSHong Zhang } 33653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 33668baccfbdSHong Zhang } 336765b80a83SHong Zhang #endif 33688baccfbdSHong Zhang 3369d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA_SeqDense(Mat B, PetscInt lda) 3370d71ae5a4SJacob Faibussowitsch { 33711b807ce4Svictorle Mat_SeqDense *b = (Mat_SeqDense *)B->data; 33727422da62SJose E. Roman PetscBool data; 337321a2c019SBarry Smith 33741b807ce4Svictorle PetscFunctionBegin; 33757422da62SJose E. Roman data = (PetscBool)((B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE); 3376aed4548fSBarry Smith PetscCheck(b->user_alloc || !data || b->lda == lda, PETSC_COMM_SELF, PETSC_ERR_ORDER, "LDA cannot be changed after allocation of internal storage"); 337708401ef6SPierre Jolivet PetscCheck(lda >= B->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "LDA %" PetscInt_FMT " must be at least matrix dimension %" PetscInt_FMT, lda, B->rmap->n); 33781b807ce4Svictorle b->lda = lda; 33793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 33801b807ce4Svictorle } 33811b807ce4Svictorle 3382d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm, Mat inmat, PetscInt n, MatReuse scall, Mat *outmat) 3383d71ae5a4SJacob Faibussowitsch { 3384d528f656SJakub Kruzik PetscFunctionBegin; 33859566063dSJacob Faibussowitsch PetscCall(MatCreateMPIMatConcatenateSeqMat_MPIDense(comm, inmat, n, scall, outmat)); 33863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3387d528f656SJakub Kruzik } 3388d528f656SJakub Kruzik 3389d16ceb75SStefano Zampini PetscErrorCode MatDenseCreateColumnVec_Private(Mat A, Vec *v) 3390d16ceb75SStefano Zampini { 3391d16ceb75SStefano Zampini PetscBool isstd, iskok, iscuda, iship; 3392d16ceb75SStefano Zampini PetscMPIInt size; 3393d16ceb75SStefano Zampini #if PetscDefined(HAVE_CUDA) || PetscDefined(HAVE_HIP) 3394d16ceb75SStefano Zampini /* we pass the data of A, to prevent allocating needless GPU memory the first time VecCUPMPlaceArray is called. */ 3395d16ceb75SStefano Zampini const PetscScalar *a; 3396d16ceb75SStefano Zampini #endif 3397d16ceb75SStefano Zampini 3398d16ceb75SStefano Zampini PetscFunctionBegin; 3399d16ceb75SStefano Zampini *v = NULL; 3400d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &isstd, VECSTANDARD, VECSEQ, VECMPI, "")); 3401d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &iskok, VECKOKKOS, VECSEQKOKKOS, VECMPIKOKKOS, "")); 3402d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &iscuda, VECCUDA, VECSEQCUDA, VECMPICUDA, "")); 3403d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &iship, VECHIP, VECSEQHIP, VECMPIHIP, "")); 3404d16ceb75SStefano Zampini PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A), &size)); 3405d16ceb75SStefano Zampini if (isstd) { 3406d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPIWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, v)); 3407d16ceb75SStefano Zampini else PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, v)); 3408d16ceb75SStefano Zampini } else if (iskok) { 3409d16ceb75SStefano Zampini PetscCheck(PetscDefined(HAVE_KOKKOS_KERNELS), PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Reconfigure using KOKKOS kernels support"); 3410d16ceb75SStefano Zampini #if PetscDefined(HAVE_KOKKOS_KERNELS) 3411d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPIKokkosWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, v)); 3412d16ceb75SStefano Zampini else PetscCall(VecCreateSeqKokkosWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, v)); 3413d16ceb75SStefano Zampini #endif 3414d16ceb75SStefano Zampini } else if (iscuda) { 3415d16ceb75SStefano Zampini PetscCheck(PetscDefined(HAVE_CUDA), PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Reconfigure using CUDA support"); 3416d16ceb75SStefano Zampini #if PetscDefined(HAVE_CUDA) 3417d16ceb75SStefano Zampini PetscCall(MatDenseCUDAGetArrayRead(A, &a)); 3418d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPICUDAWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, a, v)); 3419d16ceb75SStefano Zampini else PetscCall(VecCreateSeqCUDAWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, a, v)); 3420d16ceb75SStefano Zampini #endif 3421d16ceb75SStefano Zampini } else if (iship) { 3422d16ceb75SStefano Zampini PetscCheck(PetscDefined(HAVE_HIP), PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Reconfigure using HIP support"); 3423d16ceb75SStefano Zampini #if PetscDefined(HAVE_HIP) 3424d16ceb75SStefano Zampini PetscCall(MatDenseHIPGetArrayRead(A, &a)); 3425d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPIHIPWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, a, v)); 3426d16ceb75SStefano Zampini else PetscCall(VecCreateSeqHIPWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, a, v)); 3427d16ceb75SStefano Zampini #endif 3428d16ceb75SStefano Zampini } 3429d16ceb75SStefano Zampini PetscCheck(*v, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Not coded for type %s", A->defaultvectype); 3430d16ceb75SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 3431d16ceb75SStefano Zampini } 3432d16ceb75SStefano Zampini 3433d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A, PetscInt col, Vec *v) 3434d71ae5a4SJacob Faibussowitsch { 34356947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34366947451fSStefano Zampini 34376947451fSStefano Zampini PetscFunctionBegin; 343828b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 343928b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3440d16ceb75SStefano Zampini if (!a->cvec) PetscCall(MatDenseCreateColumnVec_Private(A, &a->cvec)); 34416947451fSStefano Zampini a->vecinuse = col + 1; 34429566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, (PetscScalar **)&a->ptrinuse)); 34439566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda)); 34446947451fSStefano Zampini *v = a->cvec; 34453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34466947451fSStefano Zampini } 34476947451fSStefano Zampini 3448d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A, PetscInt col, Vec *v) 3449d71ae5a4SJacob Faibussowitsch { 34506947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34516947451fSStefano Zampini 34526947451fSStefano Zampini PetscFunctionBegin; 345328b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 345428b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 34556947451fSStefano Zampini a->vecinuse = 0; 34569566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, (PetscScalar **)&a->ptrinuse)); 34579566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 345875f6d85dSStefano Zampini if (v) *v = NULL; 34593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34606947451fSStefano Zampini } 34616947451fSStefano Zampini 3462d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v) 3463d71ae5a4SJacob Faibussowitsch { 34646947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34656947451fSStefano Zampini 34666947451fSStefano Zampini PetscFunctionBegin; 346728b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 346828b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3469d16ceb75SStefano Zampini if (!a->cvec) PetscCall(MatDenseCreateColumnVec_Private(A, &a->cvec)); 34706947451fSStefano Zampini a->vecinuse = col + 1; 34719566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &a->ptrinuse)); 34729566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda)); 34739566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(a->cvec)); 34746947451fSStefano Zampini *v = a->cvec; 34753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34766947451fSStefano Zampini } 34776947451fSStefano Zampini 3478d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v) 3479d71ae5a4SJacob Faibussowitsch { 34806947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34816947451fSStefano Zampini 34826947451fSStefano Zampini PetscFunctionBegin; 348328b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 348428b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 34856947451fSStefano Zampini a->vecinuse = 0; 34869566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &a->ptrinuse)); 34879566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(a->cvec)); 34889566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 348975f6d85dSStefano Zampini if (v) *v = NULL; 34903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34916947451fSStefano Zampini } 34926947451fSStefano Zampini 3493d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v) 3494d71ae5a4SJacob Faibussowitsch { 34956947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34966947451fSStefano Zampini 34976947451fSStefano Zampini PetscFunctionBegin; 349828b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 349928b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3500d16ceb75SStefano Zampini if (!a->cvec) PetscCall(MatDenseCreateColumnVec_Private(A, &a->cvec)); 35016947451fSStefano Zampini a->vecinuse = col + 1; 35029566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(A, (PetscScalar **)&a->ptrinuse)); 35039566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda)); 35046947451fSStefano Zampini *v = a->cvec; 35053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35066947451fSStefano Zampini } 35076947451fSStefano Zampini 3508d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v) 3509d71ae5a4SJacob Faibussowitsch { 35106947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35116947451fSStefano Zampini 35126947451fSStefano Zampini PetscFunctionBegin; 351328b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 351428b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 35156947451fSStefano Zampini a->vecinuse = 0; 35169566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(A, (PetscScalar **)&a->ptrinuse)); 35179566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 351875f6d85dSStefano Zampini if (v) *v = NULL; 35193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35206947451fSStefano Zampini } 35216947451fSStefano Zampini 3522d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) 3523d71ae5a4SJacob Faibussowitsch { 35245ea7661aSPierre Jolivet Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35255ea7661aSPierre Jolivet 35265ea7661aSPierre Jolivet PetscFunctionBegin; 352728b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 352828b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3529a2748737SPierre Jolivet if (a->cmat && (cend - cbegin != a->cmat->cmap->N || rend - rbegin != a->cmat->rmap->N)) PetscCall(MatDestroy(&a->cmat)); 35305ea7661aSPierre Jolivet if (!a->cmat) { 35315c0db29aSPierre Jolivet PetscCall(MatCreateDense(PetscObjectComm((PetscObject)A), rend - rbegin, PETSC_DECIDE, rend - rbegin, cend - cbegin, a->v ? a->v + rbegin + (size_t)cbegin * a->lda : NULL, &a->cmat)); 35325ea7661aSPierre Jolivet } else { 35335c0db29aSPierre Jolivet PetscCall(MatDensePlaceArray(a->cmat, a->v ? a->v + rbegin + (size_t)cbegin * a->lda : NULL)); 35345ea7661aSPierre Jolivet } 35359566063dSJacob Faibussowitsch PetscCall(MatDenseSetLDA(a->cmat, a->lda)); 35365ea7661aSPierre Jolivet a->matinuse = cbegin + 1; 35375ea7661aSPierre Jolivet *v = a->cmat; 353847d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 353975f6d85dSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 354075f6d85dSStefano Zampini #endif 35413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35425ea7661aSPierre Jolivet } 35435ea7661aSPierre Jolivet 3544d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A, Mat *v) 3545d71ae5a4SJacob Faibussowitsch { 35465ea7661aSPierre Jolivet Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35475ea7661aSPierre Jolivet 35485ea7661aSPierre Jolivet PetscFunctionBegin; 354928b400f6SJacob Faibussowitsch PetscCheck(a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetSubMatrix() first"); 355028b400f6SJacob Faibussowitsch PetscCheck(a->cmat, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column matrix"); 355108401ef6SPierre Jolivet PetscCheck(*v == a->cmat, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not the matrix obtained from MatDenseGetSubMatrix()"); 35525ea7661aSPierre Jolivet a->matinuse = 0; 35539566063dSJacob Faibussowitsch PetscCall(MatDenseResetArray(a->cmat)); 3554742765d3SMatthew Knepley if (v) *v = NULL; 355547d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 35563faff063SStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 35573faff063SStefano Zampini #endif 35583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35595ea7661aSPierre Jolivet } 35605ea7661aSPierre Jolivet 35610bad9183SKris Buschelman /*MC 3562fafad747SKris Buschelman MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices. 35630bad9183SKris Buschelman 35642ef1f0ffSBarry Smith Options Database Key: 356511a5261eSBarry Smith . -mat_type seqdense - sets the matrix type to `MATSEQDENSE` during a call to `MatSetFromOptions()` 35660bad9183SKris Buschelman 35670bad9183SKris Buschelman Level: beginner 35680bad9183SKris Buschelman 35691cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreateSeqDense()` 35700bad9183SKris Buschelman M*/ 3571d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreate_SeqDense(Mat B) 3572d71ae5a4SJacob Faibussowitsch { 3573273d9f13SBarry Smith Mat_SeqDense *b; 35747c334f02SBarry Smith PetscMPIInt size; 3575273d9f13SBarry Smith 3576273d9f13SBarry Smith PetscFunctionBegin; 35779566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)B), &size)); 357808401ef6SPierre Jolivet PetscCheck(size <= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Comm must be of size 1"); 357955659b69SBarry Smith 35804dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&b)); 358144cd7ae7SLois Curfman McInnes B->data = (void *)b; 3582aea10558SJacob Faibussowitsch B->ops[0] = MatOps_Values; 358318f449edSLois Curfman McInnes 3584273d9f13SBarry Smith b->roworiented = PETSC_TRUE; 35854e220ebcSLois Curfman McInnes 35869566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatQRFactor_C", MatQRFactor_SeqDense)); 35879566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetLDA_C", MatDenseGetLDA_SeqDense)); 35889566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseSetLDA_C", MatDenseSetLDA_SeqDense)); 35899566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArray_C", MatDenseGetArray_SeqDense)); 35909566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArray_C", MatDenseRestoreArray_SeqDense)); 35919566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDensePlaceArray_C", MatDensePlaceArray_SeqDense)); 35929566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseResetArray_C", MatDenseResetArray_SeqDense)); 35939566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseReplaceArray_C", MatDenseReplaceArray_SeqDense)); 35949566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayRead_C", MatDenseGetArray_SeqDense)); 35959566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayRead_C", MatDenseRestoreArray_SeqDense)); 35969566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayWrite_C", MatDenseGetArray_SeqDense)); 35979566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayWrite_C", MatDenseRestoreArray_SeqDense)); 35989566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqaij_C", MatConvert_SeqDense_SeqAIJ)); 35998baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 36009566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_elemental_C", MatConvert_SeqDense_Elemental)); 36018baccfbdSHong Zhang #endif 3602d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 36039566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_scalapack_C", MatConvert_Dense_ScaLAPACK)); 3604d24d4204SJose E. Roman #endif 36052bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA) 36069566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensecuda_C", MatConvert_SeqDense_SeqDenseCUDA)); 36079566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", MatProductSetFromOptions_SeqDense)); 36089566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdense_C", MatProductSetFromOptions_SeqDense)); 36099566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensecuda_C", MatProductSetFromOptions_SeqDense)); 36102bf066beSStefano Zampini #endif 361147d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 361247d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensehip_C", MatConvert_SeqDense_SeqDenseHIP)); 361347d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensehip_seqdensehip_C", MatProductSetFromOptions_SeqDense)); 361447d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensehip_seqdense_C", MatProductSetFromOptions_SeqDense)); 361547d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensehip_C", MatProductSetFromOptions_SeqDense)); 361647d993e7Ssuyashtn #endif 36179566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSeqDenseSetPreallocation_C", MatSeqDenseSetPreallocation_SeqDense)); 36189566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqaij_seqdense_C", MatProductSetFromOptions_SeqAIJ_SeqDense)); 36199566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdense_C", MatProductSetFromOptions_SeqDense)); 36209566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense)); 36219566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqsbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense)); 362296e6d5c4SRichard Tran Mills 36239566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumn_C", MatDenseGetColumn_SeqDense)); 36249566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumn_C", MatDenseRestoreColumn_SeqDense)); 36259566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVec_C", MatDenseGetColumnVec_SeqDense)); 36269566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVec_C", MatDenseRestoreColumnVec_SeqDense)); 36279566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecRead_C", MatDenseGetColumnVecRead_SeqDense)); 36289566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecRead_C", MatDenseRestoreColumnVecRead_SeqDense)); 36299566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecWrite_C", MatDenseGetColumnVecWrite_SeqDense)); 36309566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecWrite_C", MatDenseRestoreColumnVecWrite_SeqDense)); 36319566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetSubMatrix_C", MatDenseGetSubMatrix_SeqDense)); 36329566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreSubMatrix_C", MatDenseRestoreSubMatrix_SeqDense)); 36339566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)B, MATSEQDENSE)); 36343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3635289bc588SBarry Smith } 363686aefd0dSHong Zhang 363786aefd0dSHong Zhang /*@C 363811a5261eSBarry Smith MatDenseGetColumn - gives access to a column of a dense matrix. This is only the local part of the column. You MUST call `MatDenseRestoreColumn()` to avoid memory bleeding. 363986aefd0dSHong Zhang 364086aefd0dSHong Zhang Not Collective 364186aefd0dSHong Zhang 36425ea7661aSPierre Jolivet Input Parameters: 3643fe59aa6dSJacob Faibussowitsch + A - a `MATSEQDENSE` or `MATMPIDENSE` matrix 364486aefd0dSHong Zhang - col - column index 364586aefd0dSHong Zhang 364686aefd0dSHong Zhang Output Parameter: 364786aefd0dSHong Zhang . vals - pointer to the data 364886aefd0dSHong Zhang 364986aefd0dSHong Zhang Level: intermediate 365086aefd0dSHong Zhang 365111a5261eSBarry Smith Note: 365211a5261eSBarry Smith Use `MatDenseGetColumnVec()` to get access to a column of a `MATDENSE` treated as a `Vec` 365311a5261eSBarry Smith 36541cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreColumn()`, `MatDenseGetColumnVec()` 365586aefd0dSHong Zhang @*/ 3656d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumn(Mat A, PetscInt col, PetscScalar **vals) 3657d71ae5a4SJacob Faibussowitsch { 365886aefd0dSHong Zhang PetscFunctionBegin; 3659d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3660d5ea218eSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 36614f572ea9SToby Isaac PetscAssertPointer(vals, 3); 3662cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumn_C", (Mat, PetscInt, PetscScalar **), (A, col, vals)); 36633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 366486aefd0dSHong Zhang } 366586aefd0dSHong Zhang 366686aefd0dSHong Zhang /*@C 366711a5261eSBarry Smith MatDenseRestoreColumn - returns access to a column of a `MATDENSE` matrix which is returned by `MatDenseGetColumn()`. 366886aefd0dSHong Zhang 366986aefd0dSHong Zhang Not Collective 367086aefd0dSHong Zhang 3671742765d3SMatthew Knepley Input Parameters: 3672fe59aa6dSJacob Faibussowitsch + A - a `MATSEQDENSE` or `MATMPIDENSE` matrix 36732ef1f0ffSBarry Smith - vals - pointer to the data (may be `NULL`) 367486aefd0dSHong Zhang 367586aefd0dSHong Zhang Level: intermediate 367686aefd0dSHong Zhang 36771cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetColumn()` 367886aefd0dSHong Zhang @*/ 3679d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumn(Mat A, PetscScalar **vals) 3680d71ae5a4SJacob Faibussowitsch { 368186aefd0dSHong Zhang PetscFunctionBegin; 3682d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 36834f572ea9SToby Isaac PetscAssertPointer(vals, 2); 3684cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumn_C", (Mat, PetscScalar **), (A, vals)); 36853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 368686aefd0dSHong Zhang } 36876947451fSStefano Zampini 36880f74d2c1SSatish Balay /*@ 368911a5261eSBarry Smith MatDenseGetColumnVec - Gives read-write access to a column of a `MATDENSE` matrix, represented as a `Vec`. 36906947451fSStefano Zampini 36916947451fSStefano Zampini Collective 36926947451fSStefano Zampini 36935ea7661aSPierre Jolivet Input Parameters: 3694fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 36956947451fSStefano Zampini - col - the column index 36966947451fSStefano Zampini 36976947451fSStefano Zampini Output Parameter: 36986947451fSStefano Zampini . v - the vector 36996947451fSStefano Zampini 37002ef1f0ffSBarry Smith Level: intermediate 37012ef1f0ffSBarry Smith 37026947451fSStefano Zampini Notes: 370311a5261eSBarry Smith The vector is owned by PETSc. Users need to call `MatDenseRestoreColumnVec()` when the vector is no longer needed. 370411a5261eSBarry Smith 370511a5261eSBarry Smith Use `MatDenseGetColumnVecRead()` to obtain read-only access or `MatDenseGetColumnVecWrite()` for write-only access. 37066947451fSStefano Zampini 37071cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`, `MatDenseGetColumn()` 37086947451fSStefano Zampini @*/ 3709d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec(Mat A, PetscInt col, Vec *v) 3710d71ae5a4SJacob Faibussowitsch { 37116947451fSStefano Zampini PetscFunctionBegin; 37126947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 37136947451fSStefano Zampini PetscValidType(A, 1); 37146947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 37154f572ea9SToby Isaac PetscAssertPointer(v, 3); 371628b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 37172cf15c64SPierre Jolivet PetscCheck(col >= 0 && col < A->cmap->N, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")", col, A->cmap->N); 3718cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v)); 37193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37206947451fSStefano Zampini } 37216947451fSStefano Zampini 37220f74d2c1SSatish Balay /*@ 37236947451fSStefano Zampini MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVec(). 37246947451fSStefano Zampini 37256947451fSStefano Zampini Collective 37266947451fSStefano Zampini 37275ea7661aSPierre Jolivet Input Parameters: 3728fe59aa6dSJacob Faibussowitsch + A - the Mat object 37296947451fSStefano Zampini . col - the column index 37302ef1f0ffSBarry Smith - v - the Vec object (may be `NULL`) 37316947451fSStefano Zampini 37326947451fSStefano Zampini Level: intermediate 37336947451fSStefano Zampini 37341cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 37356947451fSStefano Zampini @*/ 3736d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec(Mat A, PetscInt col, Vec *v) 3737d71ae5a4SJacob Faibussowitsch { 37386947451fSStefano Zampini PetscFunctionBegin; 37396947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 37406947451fSStefano Zampini PetscValidType(A, 1); 37416947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 374208401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 37432cf15c64SPierre Jolivet PetscCheck(col >= 0 && col < A->cmap->N, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")", col, A->cmap->N); 3744cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v)); 37453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37466947451fSStefano Zampini } 37476947451fSStefano Zampini 37480f74d2c1SSatish Balay /*@ 37496947451fSStefano Zampini MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a Vec. 37506947451fSStefano Zampini 37516947451fSStefano Zampini Collective 37526947451fSStefano Zampini 37535ea7661aSPierre Jolivet Input Parameters: 3754fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 37556947451fSStefano Zampini - col - the column index 37566947451fSStefano Zampini 37576947451fSStefano Zampini Output Parameter: 37586947451fSStefano Zampini . v - the vector 37596947451fSStefano Zampini 37602ef1f0ffSBarry Smith Level: intermediate 37612ef1f0ffSBarry Smith 37626947451fSStefano Zampini Notes: 37636947451fSStefano Zampini The vector is owned by PETSc and users cannot modify it. 376411a5261eSBarry Smith 37652ef1f0ffSBarry Smith Users need to call `MatDenseRestoreColumnVecRead()` when the vector is no longer needed. 376611a5261eSBarry Smith 37672ef1f0ffSBarry Smith Use `MatDenseGetColumnVec()` to obtain read-write access or `MatDenseGetColumnVecWrite()` for write-only access. 37686947451fSStefano Zampini 37691cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 37706947451fSStefano Zampini @*/ 3771d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead(Mat A, PetscInt col, Vec *v) 3772d71ae5a4SJacob Faibussowitsch { 37736947451fSStefano Zampini PetscFunctionBegin; 37746947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 37756947451fSStefano Zampini PetscValidType(A, 1); 37766947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 37774f572ea9SToby Isaac PetscAssertPointer(v, 3); 377828b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 37792cf15c64SPierre Jolivet PetscCheck(col >= 0 && col < A->cmap->N, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")", col, A->cmap->N); 3780cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v)); 37813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37826947451fSStefano Zampini } 37836947451fSStefano Zampini 37840f74d2c1SSatish Balay /*@ 37856947451fSStefano Zampini MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecRead(). 37866947451fSStefano Zampini 37876947451fSStefano Zampini Collective 37886947451fSStefano Zampini 37895ea7661aSPierre Jolivet Input Parameters: 3790fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 37916947451fSStefano Zampini . col - the column index 37922ef1f0ffSBarry Smith - v - the Vec object (may be `NULL`) 37936947451fSStefano Zampini 37946947451fSStefano Zampini Level: intermediate 37956947451fSStefano Zampini 37961cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecWrite()` 37976947451fSStefano Zampini @*/ 3798d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead(Mat A, PetscInt col, Vec *v) 3799d71ae5a4SJacob Faibussowitsch { 38006947451fSStefano Zampini PetscFunctionBegin; 38016947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38026947451fSStefano Zampini PetscValidType(A, 1); 38036947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 380408401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 38052cf15c64SPierre Jolivet PetscCheck(col >= 0 && col < A->cmap->N, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")", col, A->cmap->N); 3806cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v)); 38073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38086947451fSStefano Zampini } 38096947451fSStefano Zampini 38100f74d2c1SSatish Balay /*@ 38116947451fSStefano Zampini MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a Vec. 38126947451fSStefano Zampini 38136947451fSStefano Zampini Collective 38146947451fSStefano Zampini 38155ea7661aSPierre Jolivet Input Parameters: 3816fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 38176947451fSStefano Zampini - col - the column index 38186947451fSStefano Zampini 38196947451fSStefano Zampini Output Parameter: 38206947451fSStefano Zampini . v - the vector 38216947451fSStefano Zampini 38226947451fSStefano Zampini Level: intermediate 38236947451fSStefano Zampini 38242ef1f0ffSBarry Smith Notes: 38252ef1f0ffSBarry Smith The vector is owned by PETSc. Users need to call `MatDenseRestoreColumnVecWrite()` when the vector is no longer needed. 38262ef1f0ffSBarry Smith 38272ef1f0ffSBarry Smith Use `MatDenseGetColumnVec()` to obtain read-write access or `MatDenseGetColumnVecRead()` for read-only access. 38282ef1f0ffSBarry Smith 38291cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 38306947451fSStefano Zampini @*/ 3831d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite(Mat A, PetscInt col, Vec *v) 3832d71ae5a4SJacob Faibussowitsch { 38336947451fSStefano Zampini PetscFunctionBegin; 38346947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38356947451fSStefano Zampini PetscValidType(A, 1); 38366947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 38374f572ea9SToby Isaac PetscAssertPointer(v, 3); 383828b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3839aed4548fSBarry Smith PetscCheck(col >= 0 && col < A->cmap->N, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")", col, A->cmap->N); 3840cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v)); 38413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38426947451fSStefano Zampini } 38436947451fSStefano Zampini 38440f74d2c1SSatish Balay /*@ 38456947451fSStefano Zampini MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecWrite(). 38466947451fSStefano Zampini 38476947451fSStefano Zampini Collective 38486947451fSStefano Zampini 38495ea7661aSPierre Jolivet Input Parameters: 3850fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 38516947451fSStefano Zampini . col - the column index 38522ef1f0ffSBarry Smith - v - the `Vec` object (may be `NULL`) 38536947451fSStefano Zampini 38546947451fSStefano Zampini Level: intermediate 38556947451fSStefano Zampini 38561cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()` 38576947451fSStefano Zampini @*/ 3858d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A, PetscInt col, Vec *v) 3859d71ae5a4SJacob Faibussowitsch { 38606947451fSStefano Zampini PetscFunctionBegin; 38616947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38626947451fSStefano Zampini PetscValidType(A, 1); 38636947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 386408401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3865aed4548fSBarry Smith PetscCheck(col >= 0 && col < A->cmap->N, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")", col, A->cmap->N); 3866cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v)); 38673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38686947451fSStefano Zampini } 38695ea7661aSPierre Jolivet 38700f74d2c1SSatish Balay /*@ 3871a2748737SPierre Jolivet MatDenseGetSubMatrix - Gives access to a block of rows and columns of a dense matrix, represented as a Mat. 38725ea7661aSPierre Jolivet 38735ea7661aSPierre Jolivet Collective 38745ea7661aSPierre Jolivet 38755ea7661aSPierre Jolivet Input Parameters: 3876fe59aa6dSJacob Faibussowitsch + A - the Mat object 38772ef1f0ffSBarry Smith . rbegin - the first global row index in the block (if `PETSC_DECIDE`, is 0) 38782ef1f0ffSBarry Smith . rend - the global row index past the last one in the block (if `PETSC_DECIDE`, is `M`) 38792ef1f0ffSBarry Smith . cbegin - the first global column index in the block (if `PETSC_DECIDE`, is 0) 38802ef1f0ffSBarry Smith - cend - the global column index past the last one in the block (if `PETSC_DECIDE`, is `N`) 38815ea7661aSPierre Jolivet 38825ea7661aSPierre Jolivet Output Parameter: 38835ea7661aSPierre Jolivet . v - the matrix 38845ea7661aSPierre Jolivet 38855ea7661aSPierre Jolivet Level: intermediate 38865ea7661aSPierre Jolivet 38872ef1f0ffSBarry Smith Notes: 38882ef1f0ffSBarry Smith The matrix is owned by PETSc. Users need to call `MatDenseRestoreSubMatrix()` when the matrix is no longer needed. 38892ef1f0ffSBarry Smith 38902ef1f0ffSBarry Smith The output matrix is not redistributed by PETSc, so depending on the values of `rbegin` and `rend`, some processes may have no local rows. 38912ef1f0ffSBarry Smith 38921cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreSubMatrix()` 38935ea7661aSPierre Jolivet @*/ 3894d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) 3895d71ae5a4SJacob Faibussowitsch { 38965ea7661aSPierre Jolivet PetscFunctionBegin; 38975ea7661aSPierre Jolivet PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38985ea7661aSPierre Jolivet PetscValidType(A, 1); 3899a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, rbegin, 2); 3900a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, rend, 3); 3901a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, cbegin, 4); 3902a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, cend, 5); 39034f572ea9SToby Isaac PetscAssertPointer(v, 6); 3904a2748737SPierre Jolivet if (rbegin == PETSC_DECIDE) rbegin = 0; 3905a2748737SPierre Jolivet if (rend == PETSC_DECIDE) rend = A->rmap->N; 3906a2748737SPierre Jolivet if (cbegin == PETSC_DECIDE) cbegin = 0; 3907a2748737SPierre Jolivet if (cend == PETSC_DECIDE) cend = A->cmap->N; 390828b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3909a2748737SPierre Jolivet PetscCheck(rbegin >= 0 && rbegin <= A->rmap->N, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Invalid rbegin %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT "]", rbegin, A->rmap->N); 3910a2748737SPierre Jolivet PetscCheck(rend >= rbegin && rend <= A->rmap->N, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Invalid rend %" PetscInt_FMT ", should be in [%" PetscInt_FMT ",%" PetscInt_FMT "]", rend, rbegin, A->rmap->N); 3911a2748737SPierre Jolivet PetscCheck(cbegin >= 0 && cbegin <= A->cmap->N, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Invalid cbegin %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT "]", cbegin, A->cmap->N); 3912a2748737SPierre Jolivet PetscCheck(cend >= cbegin && cend <= A->cmap->N, PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Invalid cend %" PetscInt_FMT ", should be in [%" PetscInt_FMT ",%" PetscInt_FMT "]", cend, cbegin, A->cmap->N); 3913a2748737SPierre Jolivet PetscUseMethod(A, "MatDenseGetSubMatrix_C", (Mat, PetscInt, PetscInt, PetscInt, PetscInt, Mat *), (A, rbegin, rend, cbegin, cend, v)); 39143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 39155ea7661aSPierre Jolivet } 39165ea7661aSPierre Jolivet 39170f74d2c1SSatish Balay /*@ 39185ea7661aSPierre Jolivet MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from MatDenseGetSubMatrix(). 39195ea7661aSPierre Jolivet 39205ea7661aSPierre Jolivet Collective 39215ea7661aSPierre Jolivet 39225ea7661aSPierre Jolivet Input Parameters: 3923fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 39242ef1f0ffSBarry Smith - v - the `Mat` object (may be `NULL`) 39255ea7661aSPierre Jolivet 39265ea7661aSPierre Jolivet Level: intermediate 39275ea7661aSPierre Jolivet 39281cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseGetSubMatrix()` 39295ea7661aSPierre Jolivet @*/ 3930d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix(Mat A, Mat *v) 3931d71ae5a4SJacob Faibussowitsch { 39325ea7661aSPierre Jolivet PetscFunctionBegin; 39335ea7661aSPierre Jolivet PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 39345ea7661aSPierre Jolivet PetscValidType(A, 1); 39354f572ea9SToby Isaac PetscAssertPointer(v, 2); 3936cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreSubMatrix_C", (Mat, Mat *), (A, v)); 39373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 39385ea7661aSPierre Jolivet } 39398a9c020eSBarry Smith 39408a9c020eSBarry Smith #include <petscblaslapack.h> 39418a9c020eSBarry Smith #include <petsc/private/kernels/blockinvert.h> 39428a9c020eSBarry Smith 3943d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseInvert(Mat A) 3944d71ae5a4SJacob Faibussowitsch { 3945d63b1753SJacob Faibussowitsch PetscInt m; 39468a9c020eSBarry Smith const PetscReal shift = 0.0; 3947d63b1753SJacob Faibussowitsch PetscBool allowzeropivot, zeropivotdetected = PETSC_FALSE; 3948d63b1753SJacob Faibussowitsch PetscScalar *values; 39498a9c020eSBarry Smith 39508a9c020eSBarry Smith PetscFunctionBegin; 3951d63b1753SJacob Faibussowitsch PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3952d63b1753SJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &values)); 3953d63b1753SJacob Faibussowitsch PetscCall(MatGetLocalSize(A, &m, NULL)); 3954d63b1753SJacob Faibussowitsch allowzeropivot = PetscNot(A->erroriffailure); 39558a9c020eSBarry Smith /* factor and invert each block */ 3956d63b1753SJacob Faibussowitsch switch (m) { 3957d71ae5a4SJacob Faibussowitsch case 1: 3958d71ae5a4SJacob Faibussowitsch values[0] = (PetscScalar)1.0 / (values[0] + shift); 3959d71ae5a4SJacob Faibussowitsch break; 39608a9c020eSBarry Smith case 2: 39618a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_2(values, shift, allowzeropivot, &zeropivotdetected)); 39628a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39638a9c020eSBarry Smith break; 39648a9c020eSBarry Smith case 3: 39658a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_3(values, shift, allowzeropivot, &zeropivotdetected)); 39668a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39678a9c020eSBarry Smith break; 39688a9c020eSBarry Smith case 4: 39698a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_4(values, shift, allowzeropivot, &zeropivotdetected)); 39708a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39718a9c020eSBarry Smith break; 39729371c9d4SSatish Balay case 5: { 39738a9c020eSBarry Smith PetscScalar work[25]; 39748a9c020eSBarry Smith PetscInt ipvt[5]; 39758a9c020eSBarry Smith 39768a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_5(values, ipvt, work, shift, allowzeropivot, &zeropivotdetected)); 39778a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39789371c9d4SSatish Balay } break; 39798a9c020eSBarry Smith case 6: 39808a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_6(values, shift, allowzeropivot, &zeropivotdetected)); 39818a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39828a9c020eSBarry Smith break; 39838a9c020eSBarry Smith case 7: 39848a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_7(values, shift, allowzeropivot, &zeropivotdetected)); 39858a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39868a9c020eSBarry Smith break; 39879371c9d4SSatish Balay default: { 39888a9c020eSBarry Smith PetscInt *v_pivots, *IJ, j; 39898a9c020eSBarry Smith PetscScalar *v_work; 39908a9c020eSBarry Smith 3991d63b1753SJacob Faibussowitsch PetscCall(PetscMalloc3(m, &v_work, m, &v_pivots, m, &IJ)); 3992d63b1753SJacob Faibussowitsch for (j = 0; j < m; j++) IJ[j] = j; 3993d63b1753SJacob Faibussowitsch PetscCall(PetscKernel_A_gets_inverse_A(m, values, v_pivots, v_work, allowzeropivot, &zeropivotdetected)); 39948a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39958a9c020eSBarry Smith PetscCall(PetscFree3(v_work, v_pivots, IJ)); 39968a9c020eSBarry Smith } 39978a9c020eSBarry Smith } 3998d63b1753SJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &values)); 39993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 40008a9c020eSBarry Smith } 4001