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)); 159*f4f49eeaSPierre Jolivet 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)); 166*f4f49eeaSPierre Jolivet b = (Mat_SeqDense *)B->data; 167a13144ffSStefano Zampini } else { 168a13144ffSStefano Zampini b = (Mat_SeqDense *)((*newmat)->data); 169e1ea5af7SJose E. Roman for (i = 0; i < n; i++) PetscCall(PetscArrayzero(b->v + i * b->lda, m)); 170a13144ffSStefano Zampini } 1719566063dSJacob Faibussowitsch PetscCall(MatSeqAIJGetArrayRead(A, &av)); 172b49cda9fSStefano Zampini for (i = 0; i < m; i++) { 173b49cda9fSStefano Zampini PetscInt j; 174b49cda9fSStefano Zampini for (j = 0; j < ai[1] - ai[0]; j++) { 175e1ea5af7SJose E. Roman b->v[*aj * b->lda + i] = *av; 176b49cda9fSStefano Zampini aj++; 177b49cda9fSStefano Zampini av++; 178b49cda9fSStefano Zampini } 179b49cda9fSStefano Zampini ai++; 180b49cda9fSStefano Zampini } 1819566063dSJacob Faibussowitsch PetscCall(MatSeqAIJRestoreArrayRead(A, &av)); 182b49cda9fSStefano Zampini 183511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 1849566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 1859566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 1869566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A, &B)); 187b49cda9fSStefano Zampini } else { 188a13144ffSStefano Zampini if (B) *newmat = B; 1899566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(*newmat, MAT_FINAL_ASSEMBLY)); 1909566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(*newmat, MAT_FINAL_ASSEMBLY)); 191b49cda9fSStefano Zampini } 1923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 193b49cda9fSStefano Zampini } 194b49cda9fSStefano Zampini 195d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqDense_SeqAIJ(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) 196d71ae5a4SJacob Faibussowitsch { 1976d4ec7b0SPierre Jolivet Mat B = NULL; 1986a63e612SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1999399e1b8SMatthew G. Knepley PetscInt i, j; 2009399e1b8SMatthew G. Knepley PetscInt *rows, *nnz; 2019399e1b8SMatthew G. Knepley MatScalar *aa = a->v, *vals; 2026a63e612SBarry Smith 2036a63e612SBarry Smith PetscFunctionBegin; 2049566063dSJacob Faibussowitsch PetscCall(PetscCalloc3(A->rmap->n, &rows, A->rmap->n, &nnz, A->rmap->n, &vals)); 2056d4ec7b0SPierre Jolivet if (reuse != MAT_REUSE_MATRIX) { 2069566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B)); 2079566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B, A->rmap->n, A->cmap->n, A->rmap->N, A->cmap->N)); 2089566063dSJacob Faibussowitsch PetscCall(MatSetType(B, MATSEQAIJ)); 2099399e1b8SMatthew G. Knepley for (j = 0; j < A->cmap->n; j++) { 2109371c9d4SSatish Balay for (i = 0; i < A->rmap->n; i++) 2119371c9d4SSatish Balay if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) ++nnz[i]; 2126a63e612SBarry Smith aa += a->lda; 2136a63e612SBarry Smith } 2149566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(B, PETSC_DETERMINE, nnz)); 2156d4ec7b0SPierre Jolivet } else B = *newmat; 2169399e1b8SMatthew G. Knepley aa = a->v; 2179399e1b8SMatthew G. Knepley for (j = 0; j < A->cmap->n; j++) { 2189399e1b8SMatthew G. Knepley PetscInt numRows = 0; 2199371c9d4SSatish Balay for (i = 0; i < A->rmap->n; i++) 2209371c9d4SSatish Balay if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) { 2219371c9d4SSatish Balay rows[numRows] = i; 2229371c9d4SSatish Balay vals[numRows++] = aa[i]; 2239371c9d4SSatish Balay } 2249566063dSJacob Faibussowitsch PetscCall(MatSetValues(B, numRows, rows, 1, &j, vals, INSERT_VALUES)); 2259399e1b8SMatthew G. Knepley aa += a->lda; 2269399e1b8SMatthew G. Knepley } 2279566063dSJacob Faibussowitsch PetscCall(PetscFree3(rows, nnz, vals)); 2289566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 2299566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 2306a63e612SBarry Smith 231511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 2329566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A, &B)); 2336d4ec7b0SPierre Jolivet } else if (reuse != MAT_REUSE_MATRIX) *newmat = B; 2343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2356a63e612SBarry Smith } 2366a63e612SBarry Smith 237d71ae5a4SJacob Faibussowitsch PetscErrorCode MatAXPY_SeqDense(Mat Y, PetscScalar alpha, Mat X, MatStructure str) 238d71ae5a4SJacob Faibussowitsch { 2391987afe7SBarry Smith Mat_SeqDense *x = (Mat_SeqDense *)X->data, *y = (Mat_SeqDense *)Y->data; 240ca15aa20SStefano Zampini const PetscScalar *xv; 241ca15aa20SStefano Zampini PetscScalar *yv; 24223fff9afSBarry Smith PetscBLASInt N, m, ldax = 0, lday = 0, one = 1; 2433a40ed3dSBarry Smith 2443a40ed3dSBarry Smith PetscFunctionBegin; 2459566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(X, &xv)); 2469566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(Y, &yv)); 2479566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(X->rmap->n * X->cmap->n, &N)); 2489566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(X->rmap->n, &m)); 2499566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(x->lda, &ldax)); 2509566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(y->lda, &lday)); 251a5ce6ee0Svictorle if (ldax > m || lday > m) { 2528e3a54c0SPierre Jolivet for (PetscInt j = 0; j < X->cmap->n; j++) PetscCallBLAS("BLASaxpy", BLASaxpy_(&m, &alpha, PetscSafePointerPlusOffset(xv, j * ldax), &one, PetscSafePointerPlusOffset(yv, j * lday), &one)); 253a5ce6ee0Svictorle } else { 254792fecdfSBarry Smith PetscCallBLAS("BLASaxpy", BLASaxpy_(&N, &alpha, xv, &one, yv, &one)); 255a5ce6ee0Svictorle } 2569566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(X, &xv)); 2579566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(Y, &yv)); 2589566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(PetscMax(2.0 * N - 1, 0))); 2593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2601987afe7SBarry Smith } 2611987afe7SBarry Smith 262d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetInfo_SeqDense(Mat A, MatInfoType flag, MatInfo *info) 263d71ae5a4SJacob Faibussowitsch { 264ca15aa20SStefano Zampini PetscLogDouble N = A->rmap->n * A->cmap->n; 2653a40ed3dSBarry Smith 2663a40ed3dSBarry Smith PetscFunctionBegin; 2674e220ebcSLois Curfman McInnes info->block_size = 1.0; 268ca15aa20SStefano Zampini info->nz_allocated = N; 269ca15aa20SStefano Zampini info->nz_used = N; 270ca15aa20SStefano Zampini info->nz_unneeded = 0; 271ca15aa20SStefano Zampini info->assemblies = A->num_ass; 2724e220ebcSLois Curfman McInnes info->mallocs = 0; 2734dfa11a4SJacob Faibussowitsch info->memory = 0; /* REVIEW ME */ 2744e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 2754e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 2764e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 2773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 278289bc588SBarry Smith } 279289bc588SBarry Smith 280d71ae5a4SJacob Faibussowitsch PetscErrorCode MatScale_SeqDense(Mat A, PetscScalar alpha) 281d71ae5a4SJacob Faibussowitsch { 282273d9f13SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 283ca15aa20SStefano Zampini PetscScalar *v; 28423fff9afSBarry Smith PetscBLASInt one = 1, j, nz, lda = 0; 28580cd9d93SLois Curfman McInnes 2863a40ed3dSBarry Smith PetscFunctionBegin; 2879566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 2889566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(a->lda, &lda)); 289d0f46423SBarry Smith if (lda > A->rmap->n) { 2909566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &nz)); 29148a46eb9SPierre Jolivet for (j = 0; j < A->cmap->n; j++) PetscCallBLAS("BLASscal", BLASscal_(&nz, &alpha, v + j * lda, &one)); 292a5ce6ee0Svictorle } else { 2939566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n * A->cmap->n, &nz)); 294792fecdfSBarry Smith PetscCallBLAS("BLASscal", BLASscal_(&nz, &alpha, v, &one)); 295a5ce6ee0Svictorle } 29604cbc005SJose E. Roman PetscCall(PetscLogFlops(A->rmap->n * A->cmap->n)); 2979566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 2983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29980cd9d93SLois Curfman McInnes } 30080cd9d93SLois Curfman McInnes 301d71ae5a4SJacob Faibussowitsch PetscErrorCode MatShift_SeqDense(Mat A, PetscScalar alpha) 302d71ae5a4SJacob Faibussowitsch { 3032f605a99SJose E. Roman Mat_SeqDense *a = (Mat_SeqDense *)A->data; 3042f605a99SJose E. Roman PetscScalar *v; 3052f605a99SJose E. Roman PetscInt j, k; 3062f605a99SJose E. Roman 3072f605a99SJose E. Roman PetscFunctionBegin; 3082f605a99SJose E. Roman PetscCall(MatDenseGetArray(A, &v)); 3092f605a99SJose E. Roman k = PetscMin(A->rmap->n, A->cmap->n); 3102f605a99SJose E. Roman for (j = 0; j < k; j++) v[j + j * a->lda] += alpha; 3112f605a99SJose E. Roman PetscCall(PetscLogFlops(k)); 3122f605a99SJose E. Roman PetscCall(MatDenseRestoreArray(A, &v)); 3133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3142f605a99SJose E. Roman } 3152f605a99SJose E. Roman 316d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatIsHermitian_SeqDense(Mat A, PetscReal rtol, PetscBool *fl) 317d71ae5a4SJacob Faibussowitsch { 3181cbb95d3SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 319ca15aa20SStefano Zampini PetscInt i, j, m = A->rmap->n, N = a->lda; 320ca15aa20SStefano Zampini const PetscScalar *v; 3211cbb95d3SBarry Smith 3221cbb95d3SBarry Smith PetscFunctionBegin; 3231cbb95d3SBarry Smith *fl = PETSC_FALSE; 3243ba16761SJacob Faibussowitsch if (A->rmap->n != A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 3259566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 3261cbb95d3SBarry Smith for (i = 0; i < m; i++) { 327ca15aa20SStefano Zampini for (j = i; j < m; j++) { 328ad540459SPierre Jolivet if (PetscAbsScalar(v[i + j * N] - PetscConj(v[j + i * N])) > rtol) goto restore; 3291cbb95d3SBarry Smith } 330637a0070SStefano Zampini } 3311cbb95d3SBarry Smith *fl = PETSC_TRUE; 332637a0070SStefano Zampini restore: 3339566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 3343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 335637a0070SStefano Zampini } 336637a0070SStefano Zampini 337d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatIsSymmetric_SeqDense(Mat A, PetscReal rtol, PetscBool *fl) 338d71ae5a4SJacob Faibussowitsch { 339637a0070SStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 340637a0070SStefano Zampini PetscInt i, j, m = A->rmap->n, N = a->lda; 341637a0070SStefano Zampini const PetscScalar *v; 342637a0070SStefano Zampini 343637a0070SStefano Zampini PetscFunctionBegin; 344637a0070SStefano Zampini *fl = PETSC_FALSE; 3453ba16761SJacob Faibussowitsch if (A->rmap->n != A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 3469566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 347637a0070SStefano Zampini for (i = 0; i < m; i++) { 348637a0070SStefano Zampini for (j = i; j < m; j++) { 349ad540459SPierre Jolivet if (PetscAbsScalar(v[i + j * N] - v[j + i * N]) > rtol) goto restore; 350637a0070SStefano Zampini } 351637a0070SStefano Zampini } 352637a0070SStefano Zampini *fl = PETSC_TRUE; 353637a0070SStefano Zampini restore: 3549566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 3553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3561cbb95d3SBarry Smith } 3571cbb95d3SBarry Smith 358d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi, Mat A, MatDuplicateOption cpvalues) 359d71ae5a4SJacob Faibussowitsch { 360ca15aa20SStefano Zampini Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 36123fc5dcaSStefano Zampini PetscInt lda = (PetscInt)mat->lda, j, m, nlda = lda; 36275f6d85dSStefano Zampini PetscBool isdensecpu; 363b24902e0SBarry Smith 364b24902e0SBarry Smith PetscFunctionBegin; 3659566063dSJacob Faibussowitsch PetscCall(PetscLayoutReference(A->rmap, &newi->rmap)); 3669566063dSJacob Faibussowitsch PetscCall(PetscLayoutReference(A->cmap, &newi->cmap)); 36723fc5dcaSStefano Zampini if (cpvalues == MAT_SHARE_NONZERO_PATTERN) { /* propagate LDA */ 3689566063dSJacob Faibussowitsch PetscCall(MatDenseSetLDA(newi, lda)); 36923fc5dcaSStefano Zampini } 3709566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)newi, MATSEQDENSE, &isdensecpu)); 3719566063dSJacob Faibussowitsch if (isdensecpu) PetscCall(MatSeqDenseSetPreallocation(newi, NULL)); 372b24902e0SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 373ca15aa20SStefano Zampini const PetscScalar *av; 374ca15aa20SStefano Zampini PetscScalar *v; 375ca15aa20SStefano Zampini 3769566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 3779566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(newi, &v)); 3789566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(newi, &nlda)); 379d0f46423SBarry Smith m = A->rmap->n; 38023fc5dcaSStefano Zampini if (lda > m || nlda > m) { 3818e3a54c0SPierre Jolivet for (j = 0; j < A->cmap->n; j++) PetscCall(PetscArraycpy(PetscSafePointerPlusOffset(v, j * nlda), PetscSafePointerPlusOffset(av, j * lda), m)); 382b24902e0SBarry Smith } else { 3839566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(v, av, A->rmap->n * A->cmap->n)); 384b24902e0SBarry Smith } 3859566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(newi, &v)); 3869566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 387b24902e0SBarry Smith } 3883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 389b24902e0SBarry Smith } 390b24902e0SBarry Smith 391d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDuplicate_SeqDense(Mat A, MatDuplicateOption cpvalues, Mat *newmat) 392d71ae5a4SJacob Faibussowitsch { 3933a40ed3dSBarry Smith PetscFunctionBegin; 3949566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), newmat)); 3959566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*newmat, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n)); 3969566063dSJacob Faibussowitsch PetscCall(MatSetType(*newmat, ((PetscObject)A)->type_name)); 3979566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(*newmat, A, cpvalues)); 3983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 399b24902e0SBarry Smith } 400b24902e0SBarry Smith 401d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_LU(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T) 402d71ae5a4SJacob Faibussowitsch { 403c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4044396437dSToby Isaac PetscBLASInt info; 40567e560aaSBarry Smith 4063a40ed3dSBarry Smith PetscFunctionBegin; 4079566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 408792fecdfSBarry Smith PetscCallBLAS("LAPACKgetrs", LAPACKgetrs_(T ? "T" : "N", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info)); 4099566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 41005fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "GETRS - Bad solve %d", (int)info); 4119566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m))); 4123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4134396437dSToby Isaac } 4144396437dSToby Isaac 4154396437dSToby Isaac static PetscErrorCode MatConjugate_SeqDense(Mat); 4164396437dSToby Isaac 417d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_Cholesky(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T) 418d71ae5a4SJacob Faibussowitsch { 4194396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4204396437dSToby Isaac PetscBLASInt info; 4214396437dSToby Isaac 4224396437dSToby Isaac PetscFunctionBegin; 423b94d7dedSBarry Smith if (A->spd == PETSC_BOOL3_TRUE) { 4249566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A)); 4259566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 426792fecdfSBarry Smith PetscCallBLAS("LAPACKpotrs", LAPACKpotrs_("L", &m, &nrhs, mat->v, &mat->lda, x, &m, &info)); 4279566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 42805fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "POTRS Bad solve %d", (int)info); 4299566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A)); 430a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX) 431b94d7dedSBarry Smith } else if (A->hermitian == PETSC_BOOL3_TRUE) { 4329566063dSJacob Faibussowitsch if (T) PetscCall(MatConjugate_SeqDense(A)); 4339566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 434792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrs", LAPACKhetrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info)); 4359566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 43605fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "HETRS Bad solve %d", (int)info); 4379566063dSJacob Faibussowitsch if (T) PetscCall(MatConjugate_SeqDense(A)); 438a49dc2a2SStefano Zampini #endif 439a49dc2a2SStefano Zampini } else { /* symmetric case */ 4409566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 441792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrs", LAPACKsytrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info)); 4429566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 44305fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "SYTRS Bad solve %d", (int)info); 444a49dc2a2SStefano Zampini } 4459566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m))); 4463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4474396437dSToby Isaac } 44885e2c93fSHong Zhang 449d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k) 450d71ae5a4SJacob Faibussowitsch { 4514396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4524396437dSToby Isaac PetscBLASInt info; 4534396437dSToby Isaac char trans; 4544396437dSToby Isaac 4554396437dSToby Isaac PetscFunctionBegin; 4564905a7bcSToby Isaac if (PetscDefined(USE_COMPLEX)) { 4574905a7bcSToby Isaac trans = 'C'; 4584905a7bcSToby Isaac } else { 4594905a7bcSToby Isaac trans = 'T'; 4604905a7bcSToby Isaac } 4619566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 46205fcb23eSStefano Zampini { /* lwork depends on the number of right-hand sides */ 46305fcb23eSStefano Zampini PetscBLASInt nlfwork, lfwork = -1; 46405fcb23eSStefano Zampini PetscScalar fwork; 46505fcb23eSStefano Zampini 466792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info)); 46705fcb23eSStefano Zampini nlfwork = (PetscBLASInt)PetscRealPart(fwork); 46805fcb23eSStefano Zampini if (nlfwork > mat->lfwork) { 46905fcb23eSStefano Zampini mat->lfwork = nlfwork; 47005fcb23eSStefano Zampini PetscCall(PetscFree(mat->fwork)); 47105fcb23eSStefano Zampini PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 47205fcb23eSStefano Zampini } 47305fcb23eSStefano Zampini } 474792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info)); 4759566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 47605fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %d", (int)info); 4779566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 478792fecdfSBarry Smith PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "N", "N", &mat->rank, &nrhs, mat->v, &mat->lda, x, &ldx, &info)); 4799566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 48005fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %d", (int)info); 4814905a7bcSToby Isaac for (PetscInt j = 0; j < nrhs; j++) { 482ad540459SPierre Jolivet for (PetscInt i = mat->rank; i < k; i++) x[j * ldx + i] = 0.; 4834905a7bcSToby Isaac } 4849566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank)))); 4853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4864905a7bcSToby Isaac } 4874905a7bcSToby Isaac 488d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k) 489d71ae5a4SJacob Faibussowitsch { 4904396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4914396437dSToby Isaac PetscBLASInt info; 4924396437dSToby Isaac 4934396437dSToby Isaac PetscFunctionBegin; 4944396437dSToby Isaac if (A->rmap->n == A->cmap->n && mat->rank == A->rmap->n) { 4959566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 496792fecdfSBarry Smith PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "T", "N", &m, &nrhs, mat->v, &mat->lda, x, &ldx, &info)); 4979566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 49805fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %d", (int)info); 4999566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A)); 50005fcb23eSStefano Zampini { /* lwork depends on the number of right-hand sides */ 50105fcb23eSStefano Zampini PetscBLASInt nlfwork, lfwork = -1; 50205fcb23eSStefano Zampini PetscScalar fwork; 50305fcb23eSStefano Zampini 504792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info)); 50505fcb23eSStefano Zampini nlfwork = (PetscBLASInt)PetscRealPart(fwork); 50605fcb23eSStefano Zampini if (nlfwork > mat->lfwork) { 50705fcb23eSStefano Zampini mat->lfwork = nlfwork; 50805fcb23eSStefano Zampini PetscCall(PetscFree(mat->fwork)); 50905fcb23eSStefano Zampini PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 51005fcb23eSStefano Zampini } 51105fcb23eSStefano Zampini } 5129566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 513792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info)); 5149566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 51505fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %d", (int)info); 5169566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A)); 5174396437dSToby Isaac } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "QR factored matrix cannot be used for transpose solve"); 5189566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank)))); 5193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5204396437dSToby Isaac } 5214396437dSToby Isaac 522d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_SetUp(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k) 523d71ae5a4SJacob Faibussowitsch { 5244396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 5254905a7bcSToby Isaac PetscScalar *y; 5264905a7bcSToby Isaac PetscBLASInt m = 0, k = 0; 5274905a7bcSToby Isaac 5284905a7bcSToby Isaac PetscFunctionBegin; 5299566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 5309566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 5314905a7bcSToby Isaac if (k < m) { 5329566063dSJacob Faibussowitsch PetscCall(VecCopy(xx, mat->qrrhs)); 5339566063dSJacob Faibussowitsch PetscCall(VecGetArray(mat->qrrhs, &y)); 5344905a7bcSToby Isaac } else { 5359566063dSJacob Faibussowitsch PetscCall(VecCopy(xx, yy)); 5369566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &y)); 5374905a7bcSToby Isaac } 5384396437dSToby Isaac *_y = y; 5394396437dSToby Isaac *_k = k; 5404396437dSToby Isaac *_m = m; 5413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5424396437dSToby Isaac } 5434396437dSToby Isaac 544d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_TearDown(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k) 545d71ae5a4SJacob Faibussowitsch { 5464396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 54742e9364cSSatish Balay PetscScalar *y = NULL; 5484396437dSToby Isaac PetscBLASInt m, k; 5494396437dSToby Isaac 5504396437dSToby Isaac PetscFunctionBegin; 5514396437dSToby Isaac y = *_y; 5524396437dSToby Isaac *_y = NULL; 5534396437dSToby Isaac k = *_k; 5544396437dSToby Isaac m = *_m; 5554905a7bcSToby Isaac if (k < m) { 5564905a7bcSToby Isaac PetscScalar *yv; 5579566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &yv)); 5589566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(yv, y, k)); 5599566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &yv)); 5609566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(mat->qrrhs, &y)); 5614905a7bcSToby Isaac } else { 5629566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &y)); 5634905a7bcSToby Isaac } 5643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5654905a7bcSToby Isaac } 5664905a7bcSToby Isaac 567d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_LU(Mat A, Vec xx, Vec yy) 568d71ae5a4SJacob Faibussowitsch { 56942e9364cSSatish Balay PetscScalar *y = NULL; 57042e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 5714396437dSToby Isaac 5724396437dSToby Isaac PetscFunctionBegin; 5739566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 5749566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_FALSE)); 5759566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 5763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5774396437dSToby Isaac } 5784396437dSToby Isaac 579d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_LU(Mat A, Vec xx, Vec yy) 580d71ae5a4SJacob Faibussowitsch { 58142e9364cSSatish Balay PetscScalar *y = NULL; 58242e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 5834396437dSToby Isaac 5844396437dSToby Isaac PetscFunctionBegin; 5859566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 5869566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_TRUE)); 5879566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 5883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5894396437dSToby Isaac } 5904396437dSToby Isaac 591d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Cholesky(Mat A, Vec xx, Vec yy) 592d71ae5a4SJacob Faibussowitsch { 593e54beecaSStefano Zampini PetscScalar *y = NULL; 594e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 5954396437dSToby Isaac 5964396437dSToby Isaac PetscFunctionBegin; 5979566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 5989566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_FALSE)); 5999566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6014396437dSToby Isaac } 6024396437dSToby Isaac 603d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_Cholesky(Mat A, Vec xx, Vec yy) 604d71ae5a4SJacob Faibussowitsch { 605e54beecaSStefano Zampini PetscScalar *y = NULL; 606e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 6074396437dSToby Isaac 6084396437dSToby Isaac PetscFunctionBegin; 6099566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6109566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_TRUE)); 6119566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6134396437dSToby Isaac } 6144396437dSToby Isaac 615d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_QR(Mat A, Vec xx, Vec yy) 616d71ae5a4SJacob Faibussowitsch { 617e54beecaSStefano Zampini PetscScalar *y = NULL; 618e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 6194396437dSToby Isaac 6204396437dSToby Isaac PetscFunctionBegin; 6219566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6229566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k)); 6239566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6254396437dSToby Isaac } 6264396437dSToby Isaac 627d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_QR(Mat A, Vec xx, Vec yy) 628d71ae5a4SJacob Faibussowitsch { 62942e9364cSSatish Balay PetscScalar *y = NULL; 63042e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 6314396437dSToby Isaac 6324396437dSToby Isaac PetscFunctionBegin; 6339566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6349566063dSJacob Faibussowitsch PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k)); 6359566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6374396437dSToby Isaac } 6384396437dSToby Isaac 639d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_SetUp(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k) 640d71ae5a4SJacob Faibussowitsch { 6414905a7bcSToby Isaac const PetscScalar *b; 6424396437dSToby Isaac PetscScalar *y; 643bf5a80bcSToby Isaac PetscInt n, _ldb, _ldx; 644bf5a80bcSToby Isaac PetscBLASInt nrhs = 0, m = 0, k = 0, ldb = 0, ldx = 0, ldy = 0; 6454905a7bcSToby Isaac 6464905a7bcSToby Isaac PetscFunctionBegin; 6479371c9d4SSatish Balay *_ldy = 0; 6489371c9d4SSatish Balay *_m = 0; 6499371c9d4SSatish Balay *_nrhs = 0; 6509371c9d4SSatish Balay *_k = 0; 6519371c9d4SSatish Balay *_y = NULL; 6529566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 6539566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 6549566063dSJacob Faibussowitsch PetscCall(MatGetSize(B, NULL, &n)); 6559566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(n, &nrhs)); 6569566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(B, &_ldb)); 6579566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldb, &ldb)); 6589566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(X, &_ldx)); 6599566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldx, &ldx)); 660bf5a80bcSToby Isaac if (ldx < m) { 6619566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &b)); 6629566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nrhs * m, &y)); 663bf5a80bcSToby Isaac if (ldb == m) { 6649566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(y, b, ldb * nrhs)); 6654905a7bcSToby Isaac } else { 66648a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * m], &b[j * ldb], m)); 6674905a7bcSToby Isaac } 668bf5a80bcSToby Isaac ldy = m; 6699566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &b)); 6704905a7bcSToby Isaac } else { 671bf5a80bcSToby Isaac if (ldb == ldx) { 6729566063dSJacob Faibussowitsch PetscCall(MatCopy(B, X, SAME_NONZERO_PATTERN)); 6739566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &y)); 6744905a7bcSToby Isaac } else { 6759566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &y)); 6769566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &b)); 67748a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * ldx], &b[j * ldb], m)); 6789566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &b)); 6794905a7bcSToby Isaac } 680bf5a80bcSToby Isaac ldy = ldx; 6814905a7bcSToby Isaac } 6824396437dSToby Isaac *_y = y; 683bf5a80bcSToby Isaac *_ldy = ldy; 6844396437dSToby Isaac *_k = k; 6854396437dSToby Isaac *_m = m; 6864396437dSToby Isaac *_nrhs = nrhs; 6873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6884396437dSToby Isaac } 6894396437dSToby Isaac 690d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_TearDown(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k) 691d71ae5a4SJacob Faibussowitsch { 6924396437dSToby Isaac PetscScalar *y; 693bf5a80bcSToby Isaac PetscInt _ldx; 694bf5a80bcSToby Isaac PetscBLASInt k, ldy, nrhs, ldx = 0; 6954396437dSToby Isaac 6964396437dSToby Isaac PetscFunctionBegin; 6974396437dSToby Isaac y = *_y; 6984396437dSToby Isaac *_y = NULL; 6994396437dSToby Isaac k = *_k; 700bf5a80bcSToby Isaac ldy = *_ldy; 7014396437dSToby Isaac nrhs = *_nrhs; 7029566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(X, &_ldx)); 7039566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldx, &ldx)); 704bf5a80bcSToby Isaac if (ldx != ldy) { 7054905a7bcSToby Isaac PetscScalar *xv; 7069566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &xv)); 70748a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&xv[j * ldx], &y[j * ldy], k)); 7089566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(X, &xv)); 7099566063dSJacob Faibussowitsch PetscCall(PetscFree(y)); 7104905a7bcSToby Isaac } else { 7119566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(X, &y)); 7124905a7bcSToby Isaac } 7133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 71485e2c93fSHong Zhang } 71585e2c93fSHong Zhang 716d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_LU(Mat A, Mat B, Mat X) 717d71ae5a4SJacob Faibussowitsch { 7184396437dSToby Isaac PetscScalar *y; 719bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7204396437dSToby Isaac 7214396437dSToby Isaac PetscFunctionBegin; 7229566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7239566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_FALSE)); 7249566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7264396437dSToby Isaac } 7274396437dSToby Isaac 728d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_LU(Mat A, Mat B, Mat X) 729d71ae5a4SJacob Faibussowitsch { 7304396437dSToby Isaac PetscScalar *y; 731bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7324396437dSToby Isaac 7334396437dSToby Isaac PetscFunctionBegin; 7349566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7359566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_TRUE)); 7369566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7384396437dSToby Isaac } 7394396437dSToby Isaac 740d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_Cholesky(Mat A, Mat B, Mat X) 741d71ae5a4SJacob Faibussowitsch { 7424396437dSToby Isaac PetscScalar *y; 743bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7444396437dSToby Isaac 7454396437dSToby Isaac PetscFunctionBegin; 7469566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7479566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_FALSE)); 7489566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7504396437dSToby Isaac } 7514396437dSToby Isaac 752d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_Cholesky(Mat A, Mat B, Mat X) 753d71ae5a4SJacob Faibussowitsch { 7544396437dSToby Isaac PetscScalar *y; 755bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7564396437dSToby Isaac 7574396437dSToby Isaac PetscFunctionBegin; 7589566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7599566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_TRUE)); 7609566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7624396437dSToby Isaac } 7634396437dSToby Isaac 764d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_QR(Mat A, Mat B, Mat X) 765d71ae5a4SJacob Faibussowitsch { 7664396437dSToby Isaac PetscScalar *y; 767bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7684396437dSToby Isaac 7694396437dSToby Isaac PetscFunctionBegin; 7709566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7719566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k)); 7729566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7744396437dSToby Isaac } 7754396437dSToby Isaac 776d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_QR(Mat A, Mat B, Mat X) 777d71ae5a4SJacob Faibussowitsch { 7784396437dSToby Isaac PetscScalar *y; 779bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7804396437dSToby Isaac 7814396437dSToby Isaac PetscFunctionBegin; 7829566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7839566063dSJacob Faibussowitsch PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k)); 7849566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7864396437dSToby Isaac } 7874396437dSToby Isaac 788db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots, 789db4efbfdSBarry Smith rather than put it in the Mat->row slot.*/ 790d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLUFactor_SeqDense(Mat A, IS row, IS col, const MatFactorInfo *minfo) 791d71ae5a4SJacob Faibussowitsch { 792db4efbfdSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 793db4efbfdSBarry Smith PetscBLASInt n, m, info; 794db4efbfdSBarry Smith 795db4efbfdSBarry Smith PetscFunctionBegin; 7969566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 7979566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 7984dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); } 7993ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 8009566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 801792fecdfSBarry Smith PetscCallBLAS("LAPACKgetrf", LAPACKgetrf_(&m, &n, mat->v, &mat->lda, mat->pivots, &info)); 8029566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 8038e57ea43SSatish Balay 80405fcb23eSStefano Zampini PetscCheck(info >= 0, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to LU factorization %d", (int)info); 80505fcb23eSStefano Zampini PetscCheck(info <= 0, PETSC_COMM_SELF, PETSC_ERR_MAT_LU_ZRPVT, "Bad LU factorization %d", (int)info); 8068208b9aeSStefano Zampini 8074396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_LU; 8084396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_LU; 8094396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_LU; 8104396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_LU; 811d5f3da31SBarry Smith A->factortype = MAT_FACTOR_LU; 812db4efbfdSBarry Smith 8139566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 8149566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 815f6224b95SHong Zhang 8169566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((2.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3)); 8173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 818db4efbfdSBarry Smith } 819db4efbfdSBarry Smith 820d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) 821d71ae5a4SJacob Faibussowitsch { 8224396437dSToby Isaac MatFactorInfo info; 8234396437dSToby Isaac 8244396437dSToby Isaac PetscFunctionBegin; 8259566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 826dbbe0bcdSBarry Smith PetscUseTypeMethod(fact, lufactor, NULL, NULL, &info); 8273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8284396437dSToby Isaac } 8294396437dSToby Isaac 830d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, IS col, const MatFactorInfo *info) 831d71ae5a4SJacob Faibussowitsch { 8324396437dSToby Isaac PetscFunctionBegin; 8334396437dSToby Isaac fact->preallocated = PETSC_TRUE; 8344396437dSToby Isaac fact->assembled = PETSC_TRUE; 8354396437dSToby Isaac fact->ops->lufactornumeric = MatLUFactorNumeric_SeqDense; 8363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8374396437dSToby Isaac } 8384396437dSToby Isaac 839a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */ 840d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCholeskyFactor_SeqDense(Mat A, IS perm, const MatFactorInfo *factinfo) 841d71ae5a4SJacob Faibussowitsch { 842db4efbfdSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 843c5df96a5SBarry Smith PetscBLASInt info, n; 844db4efbfdSBarry Smith 845db4efbfdSBarry Smith PetscFunctionBegin; 8469566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 8473ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 848b94d7dedSBarry Smith if (A->spd == PETSC_BOOL3_TRUE) { 8499566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 850792fecdfSBarry Smith PetscCallBLAS("LAPACKpotrf", LAPACKpotrf_("L", &n, mat->v, &mat->lda, &info)); 8519566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 852a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX) 853b94d7dedSBarry Smith } else if (A->hermitian == PETSC_BOOL3_TRUE) { 8544dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); } 855a49dc2a2SStefano Zampini if (!mat->fwork) { 856a49dc2a2SStefano Zampini PetscScalar dummy; 857a49dc2a2SStefano Zampini 858a49dc2a2SStefano Zampini mat->lfwork = -1; 8599566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 860792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info)); 8619566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 862a49dc2a2SStefano Zampini mat->lfwork = (PetscInt)PetscRealPart(dummy); 8639566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 864a49dc2a2SStefano Zampini } 8659566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 866792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info)); 8679566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 868a49dc2a2SStefano Zampini #endif 869a49dc2a2SStefano Zampini } else { /* symmetric case */ 8704dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); } 871a49dc2a2SStefano Zampini if (!mat->fwork) { 872a49dc2a2SStefano Zampini PetscScalar dummy; 873a49dc2a2SStefano Zampini 874a49dc2a2SStefano Zampini mat->lfwork = -1; 8759566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 876792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info)); 8779566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 878a49dc2a2SStefano Zampini mat->lfwork = (PetscInt)PetscRealPart(dummy); 8799566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 880a49dc2a2SStefano Zampini } 8819566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 882792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info)); 8839566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 884a49dc2a2SStefano Zampini } 88528b400f6SJacob Faibussowitsch PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad factorization: zero pivot in row %" PetscInt_FMT, (PetscInt)info - 1); 8868208b9aeSStefano Zampini 8874396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_Cholesky; 8884396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_Cholesky; 8894396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_Cholesky; 8904396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_Cholesky; 891d5f3da31SBarry Smith A->factortype = MAT_FACTOR_CHOLESKY; 8922205254eSKarl Rupp 8939566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 8949566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 895f6224b95SHong Zhang 8969566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0)); 8973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 898db4efbfdSBarry Smith } 899db4efbfdSBarry Smith 900d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) 901d71ae5a4SJacob Faibussowitsch { 902db4efbfdSBarry Smith MatFactorInfo info; 903db4efbfdSBarry Smith 904db4efbfdSBarry Smith PetscFunctionBegin; 905db4efbfdSBarry Smith info.fill = 1.0; 9062205254eSKarl Rupp 9079566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 908dbbe0bcdSBarry Smith PetscUseTypeMethod(fact, choleskyfactor, NULL, &info); 9093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 910db4efbfdSBarry Smith } 911db4efbfdSBarry Smith 912d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info) 913d71ae5a4SJacob Faibussowitsch { 914db4efbfdSBarry Smith PetscFunctionBegin; 915c3ef05f6SHong Zhang fact->assembled = PETSC_TRUE; 9161bbcc794SSatish Balay fact->preallocated = PETSC_TRUE; 917719d5645SBarry Smith fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense; 9183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 919db4efbfdSBarry Smith } 920db4efbfdSBarry Smith 921d71ae5a4SJacob Faibussowitsch PetscErrorCode MatQRFactor_SeqDense(Mat A, IS col, const MatFactorInfo *minfo) 922d71ae5a4SJacob Faibussowitsch { 9234905a7bcSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 9244905a7bcSToby Isaac PetscBLASInt n, m, info, min, max; 9254905a7bcSToby Isaac 9264905a7bcSToby Isaac PetscFunctionBegin; 9279566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 9289566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 9294396437dSToby Isaac max = PetscMax(m, n); 9304396437dSToby Isaac min = PetscMin(m, n); 9314dfa11a4SJacob Faibussowitsch if (!mat->tau) { PetscCall(PetscMalloc1(min, &mat->tau)); } 9324dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(n, &mat->pivots)); } 933*f4f49eeaSPierre Jolivet if (!mat->qrrhs) PetscCall(MatCreateVecs(A, NULL, &mat->qrrhs)); 9343ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 9354905a7bcSToby Isaac if (!mat->fwork) { 9364905a7bcSToby Isaac PetscScalar dummy; 9374905a7bcSToby Isaac 9384905a7bcSToby Isaac mat->lfwork = -1; 9399566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 940792fecdfSBarry Smith PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, &dummy, &mat->lfwork, &info)); 9419566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 9424905a7bcSToby Isaac mat->lfwork = (PetscInt)PetscRealPart(dummy); 9439566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 9444905a7bcSToby Isaac } 9459566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 946792fecdfSBarry Smith PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, mat->fwork, &mat->lfwork, &info)); 9479566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 94805fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to QR factorization %d", (int)info); 9494905a7bcSToby Isaac // TODO: try to estimate rank or test for and use geqp3 for rank revealing QR. For now just say rank is min of m and n 9504905a7bcSToby Isaac mat->rank = min; 9514905a7bcSToby Isaac 9524396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_QR; 9534396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_QR; 9544905a7bcSToby Isaac A->factortype = MAT_FACTOR_QR; 9554905a7bcSToby Isaac if (m == n) { 9564396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_QR; 9574396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_QR; 9584905a7bcSToby Isaac } 9594905a7bcSToby Isaac 9609566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 9619566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 9624905a7bcSToby Isaac 9639566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * min * min * (max - min / 3.0))); 9643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9654905a7bcSToby Isaac } 9664905a7bcSToby Isaac 967d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatQRFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) 968d71ae5a4SJacob Faibussowitsch { 9694905a7bcSToby Isaac MatFactorInfo info; 9704905a7bcSToby Isaac 9714905a7bcSToby Isaac PetscFunctionBegin; 9724905a7bcSToby Isaac info.fill = 1.0; 9734905a7bcSToby Isaac 9749566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 975cac4c232SBarry Smith PetscUseMethod(fact, "MatQRFactor_C", (Mat, IS, const MatFactorInfo *), (fact, NULL, &info)); 9763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9774905a7bcSToby Isaac } 9784905a7bcSToby Isaac 979d71ae5a4SJacob Faibussowitsch PetscErrorCode MatQRFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info) 980d71ae5a4SJacob Faibussowitsch { 9814905a7bcSToby Isaac PetscFunctionBegin; 9824905a7bcSToby Isaac fact->assembled = PETSC_TRUE; 9834905a7bcSToby Isaac fact->preallocated = PETSC_TRUE; 9849566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)fact, "MatQRFactorNumeric_C", MatQRFactorNumeric_SeqDense)); 9853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 9864905a7bcSToby Isaac } 9874905a7bcSToby Isaac 988ca15aa20SStefano Zampini /* uses LAPACK */ 989d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A, MatFactorType ftype, Mat *fact) 990d71ae5a4SJacob Faibussowitsch { 991db4efbfdSBarry Smith PetscFunctionBegin; 9929566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), fact)); 9939566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*fact, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n)); 9949566063dSJacob Faibussowitsch PetscCall(MatSetType(*fact, MATDENSE)); 99566e17bc3SBarry Smith (*fact)->trivialsymbolic = PETSC_TRUE; 9962a350339SBarry Smith if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU) { 997db4efbfdSBarry Smith (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense; 9982a350339SBarry Smith (*fact)->ops->ilufactorsymbolic = MatLUFactorSymbolic_SeqDense; 999bf5a80bcSToby Isaac } else if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) { 1000db4efbfdSBarry Smith (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense; 1001bf5a80bcSToby Isaac } else if (ftype == MAT_FACTOR_QR) { 1002*f4f49eeaSPierre Jolivet PetscCall(PetscObjectComposeFunction((PetscObject)*fact, "MatQRFactorSymbolic_C", MatQRFactorSymbolic_SeqDense)); 1003db4efbfdSBarry Smith } 1004d5f3da31SBarry Smith (*fact)->factortype = ftype; 100500c67f3bSHong Zhang 10069566063dSJacob Faibussowitsch PetscCall(PetscFree((*fact)->solvertype)); 10079566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &(*fact)->solvertype)); 10089566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_LU])); 10099566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ILU])); 10109566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_CHOLESKY])); 10119566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ICC])); 10123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1013db4efbfdSBarry Smith } 1014db4efbfdSBarry Smith 1015d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSOR_SeqDense(Mat A, Vec bb, PetscReal omega, MatSORType flag, PetscReal shift, PetscInt its, PetscInt lits, Vec xx) 1016d71ae5a4SJacob Faibussowitsch { 1017c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1018d9ca1df4SBarry Smith PetscScalar *x, *v = mat->v, zero = 0.0, xt; 1019d9ca1df4SBarry Smith const PetscScalar *b; 1020d0f46423SBarry Smith PetscInt m = A->rmap->n, i; 102123fff9afSBarry Smith PetscBLASInt o = 1, bm = 0; 1022289bc588SBarry Smith 10233a40ed3dSBarry Smith PetscFunctionBegin; 102447d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 102508401ef6SPierre Jolivet PetscCheck(A->offloadmask != PETSC_OFFLOAD_GPU, PETSC_COMM_SELF, PETSC_ERR_SUP, "Not implemented"); 1026ca15aa20SStefano Zampini #endif 1027422a814eSBarry Smith if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */ 10289566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(m, &bm)); 1029289bc588SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 10303bffc371SBarry Smith /* this is a hack fix, should have another version without the second BLASdotu */ 10319566063dSJacob Faibussowitsch PetscCall(VecSet(xx, zero)); 1032289bc588SBarry Smith } 10339566063dSJacob Faibussowitsch PetscCall(VecGetArray(xx, &x)); 10349566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(bb, &b)); 1035b965ef7fSBarry Smith its = its * lits; 103608401ef6SPierre Jolivet PetscCheck(its > 0, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Relaxation requires global its %" PetscInt_FMT " and local its %" PetscInt_FMT " both positive", its, lits); 1037289bc588SBarry Smith while (its--) { 1038fccaa45eSBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 1039289bc588SBarry Smith for (i = 0; i < m; i++) { 1040792fecdfSBarry Smith PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o)); 104155a1b374SBarry Smith x[i] = (1. - omega) * x[i] + omega * (xt + v[i + i * m] * x[i]) / (v[i + i * m] + shift); 1042289bc588SBarry Smith } 1043289bc588SBarry Smith } 1044fccaa45eSBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 1045289bc588SBarry Smith for (i = m - 1; i >= 0; i--) { 1046792fecdfSBarry Smith PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o)); 104755a1b374SBarry Smith x[i] = (1. - omega) * x[i] + omega * (xt + v[i + i * m] * x[i]) / (v[i + i * m] + shift); 1048289bc588SBarry Smith } 1049289bc588SBarry Smith } 1050289bc588SBarry Smith } 10519566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(bb, &b)); 10529566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(xx, &x)); 10533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1054289bc588SBarry Smith } 1055289bc588SBarry Smith 1056459e8d23SBlanca Mellado Pinto static PetscErrorCode MatMultKernel_SeqDense(Mat A, Vec xx, Vec yy, PetscBool trans, PetscBool herm) 1057d71ae5a4SJacob Faibussowitsch { 1058c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1059d9ca1df4SBarry Smith PetscScalar *y, _DOne = 1.0, _DZero = 0.0; 10600805154bSBarry Smith PetscBLASInt m, n, _One = 1; 1061d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 10623a40ed3dSBarry Smith 10633a40ed3dSBarry Smith PetscFunctionBegin; 10649566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 10659566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 10669566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 10679566063dSJacob Faibussowitsch PetscCall(VecGetArrayWrite(yy, &y)); 10685ac36cfcSBarry Smith if (!A->rmap->n || !A->cmap->n) { 10695ac36cfcSBarry Smith PetscBLASInt i; 1070459e8d23SBlanca Mellado Pinto if (trans) 1071459e8d23SBlanca Mellado Pinto for (i = 0; i < n; i++) y[i] = 0.0; 1072459e8d23SBlanca Mellado Pinto else 10735ac36cfcSBarry Smith for (i = 0; i < m; i++) y[i] = 0.0; 10745ac36cfcSBarry Smith } else { 1075459e8d23SBlanca Mellado Pinto if (trans) { 1076*f4f49eeaSPierre Jolivet if (herm) PetscCallBLAS("BLASgemv", BLASgemv_("C", &m, &n, &_DOne, v, &mat->lda, x, &_One, &_DZero, y, &_One)); 1077*f4f49eeaSPierre Jolivet else PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v, &mat->lda, x, &_One, &_DZero, y, &_One)); 1078459e8d23SBlanca Mellado Pinto } else { 1079*f4f49eeaSPierre Jolivet PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v, &mat->lda, x, &_One, &_DZero, y, &_One)); 1080459e8d23SBlanca Mellado Pinto } 1081459e8d23SBlanca Mellado Pinto if (trans) PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n - A->cmap->n)); 1082459e8d23SBlanca Mellado Pinto else PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n - A->rmap->n)); 10835ac36cfcSBarry Smith } 10849566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 10859566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayWrite(yy, &y)); 10863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1087289bc588SBarry Smith } 10886ee01492SSatish Balay 1089459e8d23SBlanca Mellado Pinto PetscErrorCode MatMult_SeqDense(Mat A, Vec xx, Vec yy) 1090459e8d23SBlanca Mellado Pinto { 1091459e8d23SBlanca Mellado Pinto PetscFunctionBegin; 1092459e8d23SBlanca Mellado Pinto PetscCall(MatMultKernel_SeqDense(A, xx, yy, PETSC_FALSE, PETSC_FALSE)); 1093459e8d23SBlanca Mellado Pinto PetscFunctionReturn(PETSC_SUCCESS); 1094459e8d23SBlanca Mellado Pinto } 1095459e8d23SBlanca Mellado Pinto 1096459e8d23SBlanca Mellado Pinto PetscErrorCode MatMultTranspose_SeqDense(Mat A, Vec xx, Vec yy) 1097459e8d23SBlanca Mellado Pinto { 1098459e8d23SBlanca Mellado Pinto PetscFunctionBegin; 1099459e8d23SBlanca Mellado Pinto PetscCall(MatMultKernel_SeqDense(A, xx, yy, PETSC_TRUE, PETSC_FALSE)); 1100459e8d23SBlanca Mellado Pinto PetscFunctionReturn(PETSC_SUCCESS); 1101459e8d23SBlanca Mellado Pinto } 1102459e8d23SBlanca Mellado Pinto 1103459e8d23SBlanca Mellado Pinto PetscErrorCode MatMultHermitianTranspose_SeqDense(Mat A, Vec xx, Vec yy) 1104459e8d23SBlanca Mellado Pinto { 1105459e8d23SBlanca Mellado Pinto PetscFunctionBegin; 1106459e8d23SBlanca Mellado Pinto PetscCall(MatMultKernel_SeqDense(A, xx, yy, PETSC_TRUE, PETSC_TRUE)); 1107459e8d23SBlanca Mellado Pinto PetscFunctionReturn(PETSC_SUCCESS); 1108459e8d23SBlanca Mellado Pinto } 1109459e8d23SBlanca Mellado Pinto 1110459e8d23SBlanca Mellado Pinto static PetscErrorCode MatMultAddKernel_SeqDense(Mat A, Vec xx, Vec zz, Vec yy, PetscBool trans, PetscBool herm) 1111d71ae5a4SJacob Faibussowitsch { 1112c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1113d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 1114d9ca1df4SBarry Smith PetscScalar *y, _DOne = 1.0; 11150805154bSBarry Smith PetscBLASInt m, n, _One = 1; 11163a40ed3dSBarry Smith 11173a40ed3dSBarry Smith PetscFunctionBegin; 11189566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 11199566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 11209566063dSJacob Faibussowitsch PetscCall(VecCopy(zz, yy)); 11213ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 11229566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &y)); 1123459e8d23SBlanca Mellado Pinto PetscCall(VecGetArrayRead(xx, &x)); 1124459e8d23SBlanca Mellado Pinto if (trans) { 1125*f4f49eeaSPierre Jolivet if (herm) PetscCallBLAS("BLASgemv", BLASgemv_("C", &m, &n, &_DOne, v, &mat->lda, x, &_One, &_DOne, y, &_One)); 1126*f4f49eeaSPierre Jolivet else PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v, &mat->lda, x, &_One, &_DOne, y, &_One)); 1127459e8d23SBlanca Mellado Pinto } else { 1128*f4f49eeaSPierre Jolivet PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v, &mat->lda, x, &_One, &_DOne, y, &_One)); 1129459e8d23SBlanca Mellado Pinto } 11309566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 11319566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &y)); 11329566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n)); 11333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1134289bc588SBarry Smith } 11356ee01492SSatish Balay 1136459e8d23SBlanca Mellado Pinto PetscErrorCode MatMultAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) 1137459e8d23SBlanca Mellado Pinto { 1138459e8d23SBlanca Mellado Pinto PetscFunctionBegin; 1139459e8d23SBlanca Mellado Pinto PetscCall(MatMultAddKernel_SeqDense(A, xx, zz, yy, PETSC_FALSE, PETSC_FALSE)); 1140459e8d23SBlanca Mellado Pinto PetscFunctionReturn(PETSC_SUCCESS); 1141459e8d23SBlanca Mellado Pinto } 1142459e8d23SBlanca Mellado Pinto 1143d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) 1144d71ae5a4SJacob Faibussowitsch { 11453a40ed3dSBarry Smith PetscFunctionBegin; 1146459e8d23SBlanca Mellado Pinto PetscCall(MatMultAddKernel_SeqDense(A, xx, zz, yy, PETSC_TRUE, PETSC_FALSE)); 1147459e8d23SBlanca Mellado Pinto PetscFunctionReturn(PETSC_SUCCESS); 1148459e8d23SBlanca Mellado Pinto } 1149459e8d23SBlanca Mellado Pinto 1150459e8d23SBlanca Mellado Pinto PetscErrorCode MatMultHermitianTransposeAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) 1151459e8d23SBlanca Mellado Pinto { 1152459e8d23SBlanca Mellado Pinto PetscFunctionBegin; 1153459e8d23SBlanca Mellado Pinto PetscCall(MatMultAddKernel_SeqDense(A, xx, zz, yy, PETSC_TRUE, PETSC_TRUE)); 11543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1155289bc588SBarry Smith } 1156289bc588SBarry Smith 1157d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals) 1158d71ae5a4SJacob Faibussowitsch { 1159c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 116013f74950SBarry Smith PetscInt i; 116167e560aaSBarry Smith 11623a40ed3dSBarry Smith PetscFunctionBegin; 1163c3e1b152SPierre Jolivet if (ncols) *ncols = A->cmap->n; 1164289bc588SBarry Smith if (cols) { 11659566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->cmap->n, cols)); 1166d0f46423SBarry Smith for (i = 0; i < A->cmap->n; i++) (*cols)[i] = i; 1167289bc588SBarry Smith } 1168289bc588SBarry Smith if (vals) { 1169ca15aa20SStefano Zampini const PetscScalar *v; 1170ca15aa20SStefano Zampini 11719566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 11729566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->cmap->n, vals)); 1173ca15aa20SStefano Zampini v += row; 11749371c9d4SSatish Balay for (i = 0; i < A->cmap->n; i++) { 11759371c9d4SSatish Balay (*vals)[i] = *v; 11769371c9d4SSatish Balay v += mat->lda; 11779371c9d4SSatish Balay } 11789566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 1179289bc588SBarry Smith } 11803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1181289bc588SBarry Smith } 11826ee01492SSatish Balay 1183d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRestoreRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals) 1184d71ae5a4SJacob Faibussowitsch { 1185606d414cSSatish Balay PetscFunctionBegin; 11869566063dSJacob Faibussowitsch if (cols) PetscCall(PetscFree(*cols)); 11879566063dSJacob Faibussowitsch if (vals) PetscCall(PetscFree(*vals)); 11883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1189289bc588SBarry Smith } 11902ef1f0ffSBarry Smith 1191d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], const PetscScalar v[], InsertMode addv) 1192d71ae5a4SJacob Faibussowitsch { 1193c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1194ca15aa20SStefano Zampini PetscScalar *av; 119513f74950SBarry Smith PetscInt i, j, idx = 0; 119647d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1197c70f7ee4SJunchao Zhang PetscOffloadMask oldf; 1198ca15aa20SStefano Zampini #endif 1199d6dfbf8fSBarry Smith 12003a40ed3dSBarry Smith PetscFunctionBegin; 12019566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &av)); 1202289bc588SBarry Smith if (!mat->roworiented) { 1203dbb450caSBarry Smith if (addv == INSERT_VALUES) { 1204289bc588SBarry Smith for (j = 0; j < n; j++) { 12059371c9d4SSatish Balay if (indexn[j] < 0) { 12069371c9d4SSatish Balay idx += m; 12079371c9d4SSatish Balay continue; 12089371c9d4SSatish Balay } 12096bdcaf15SBarry 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); 1210289bc588SBarry Smith for (i = 0; i < m; i++) { 12119371c9d4SSatish Balay if (indexm[i] < 0) { 12129371c9d4SSatish Balay idx++; 12139371c9d4SSatish Balay continue; 12149371c9d4SSatish Balay } 12156bdcaf15SBarry 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); 1216ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] = v[idx++]; 1217289bc588SBarry Smith } 1218289bc588SBarry Smith } 12193a40ed3dSBarry Smith } else { 1220289bc588SBarry Smith for (j = 0; j < n; j++) { 12219371c9d4SSatish Balay if (indexn[j] < 0) { 12229371c9d4SSatish Balay idx += m; 12239371c9d4SSatish Balay continue; 12249371c9d4SSatish Balay } 12256bdcaf15SBarry 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); 1226289bc588SBarry Smith for (i = 0; i < m; i++) { 12279371c9d4SSatish Balay if (indexm[i] < 0) { 12289371c9d4SSatish Balay idx++; 12299371c9d4SSatish Balay continue; 12309371c9d4SSatish Balay } 12316bdcaf15SBarry 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); 1232ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] += v[idx++]; 1233289bc588SBarry Smith } 1234289bc588SBarry Smith } 1235289bc588SBarry Smith } 12363a40ed3dSBarry Smith } else { 1237dbb450caSBarry Smith if (addv == INSERT_VALUES) { 1238e8d4e0b9SBarry Smith for (i = 0; i < m; i++) { 12399371c9d4SSatish Balay if (indexm[i] < 0) { 12409371c9d4SSatish Balay idx += n; 12419371c9d4SSatish Balay continue; 12429371c9d4SSatish Balay } 12436bdcaf15SBarry 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); 1244e8d4e0b9SBarry Smith for (j = 0; j < n; j++) { 12459371c9d4SSatish Balay if (indexn[j] < 0) { 12469371c9d4SSatish Balay idx++; 12479371c9d4SSatish Balay continue; 12489371c9d4SSatish Balay } 12496bdcaf15SBarry Smith PetscCheck(indexn[j] < A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Column too large: col %" PetscInt_FMT " max %" PetscInt_FMT, indexn[j], A->cmap->n - 1); 1250ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] = v[idx++]; 1251e8d4e0b9SBarry Smith } 1252e8d4e0b9SBarry Smith } 12533a40ed3dSBarry Smith } else { 1254289bc588SBarry Smith for (i = 0; i < m; i++) { 12559371c9d4SSatish Balay if (indexm[i] < 0) { 12569371c9d4SSatish Balay idx += n; 12579371c9d4SSatish Balay continue; 12589371c9d4SSatish Balay } 12596bdcaf15SBarry 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); 1260289bc588SBarry Smith for (j = 0; j < n; j++) { 12619371c9d4SSatish Balay if (indexn[j] < 0) { 12629371c9d4SSatish Balay idx++; 12639371c9d4SSatish Balay continue; 12649371c9d4SSatish Balay } 12656bdcaf15SBarry 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); 1266ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] += v[idx++]; 1267289bc588SBarry Smith } 1268289bc588SBarry Smith } 1269289bc588SBarry Smith } 1270e8d4e0b9SBarry Smith } 1271ca15aa20SStefano Zampini /* hack to prevent unneeded copy to the GPU while returning the array */ 127247d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1273c70f7ee4SJunchao Zhang oldf = A->offloadmask; 1274c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_GPU; 1275ca15aa20SStefano Zampini #endif 12769566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &av)); 127747d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1278c70f7ee4SJunchao Zhang A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU); 1279ca15aa20SStefano Zampini #endif 12803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1281289bc588SBarry Smith } 1282e8d4e0b9SBarry Smith 1283d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], PetscScalar v[]) 1284d71ae5a4SJacob Faibussowitsch { 1285ae80bb75SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1286ca15aa20SStefano Zampini const PetscScalar *vv; 128713f74950SBarry Smith PetscInt i, j; 1288ae80bb75SLois Curfman McInnes 12893a40ed3dSBarry Smith PetscFunctionBegin; 12909566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &vv)); 1291ae80bb75SLois Curfman McInnes /* row-oriented output */ 1292ae80bb75SLois Curfman McInnes for (i = 0; i < m; i++) { 12939371c9d4SSatish Balay if (indexm[i] < 0) { 12949371c9d4SSatish Balay v += n; 12959371c9d4SSatish Balay continue; 12969371c9d4SSatish Balay } 129708401ef6SPierre 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); 1298ae80bb75SLois Curfman McInnes for (j = 0; j < n; j++) { 12999371c9d4SSatish Balay if (indexn[j] < 0) { 13009371c9d4SSatish Balay v++; 13019371c9d4SSatish Balay continue; 13029371c9d4SSatish Balay } 130308401ef6SPierre 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); 1304ca15aa20SStefano Zampini *v++ = vv[indexn[j] * mat->lda + indexm[i]]; 1305ae80bb75SLois Curfman McInnes } 1306ae80bb75SLois Curfman McInnes } 13079566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &vv)); 13083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1309ae80bb75SLois Curfman McInnes } 1310ae80bb75SLois Curfman McInnes 1311d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_Dense_Binary(Mat mat, PetscViewer viewer) 1312d71ae5a4SJacob Faibussowitsch { 13138491ab44SLisandro Dalcin PetscBool skipHeader; 13148491ab44SLisandro Dalcin PetscViewerFormat format; 13158491ab44SLisandro Dalcin PetscInt header[4], M, N, m, lda, i, j, k; 13168491ab44SLisandro Dalcin const PetscScalar *v; 13178491ab44SLisandro Dalcin PetscScalar *vwork; 1318aabbc4fbSShri Abhyankar 1319aabbc4fbSShri Abhyankar PetscFunctionBegin; 13209566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 13219566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader)); 13229566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 13238491ab44SLisandro Dalcin if (skipHeader) format = PETSC_VIEWER_NATIVE; 1324aabbc4fbSShri Abhyankar 13259566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &M, &N)); 13268491ab44SLisandro Dalcin 13278491ab44SLisandro Dalcin /* write matrix header */ 13289371c9d4SSatish Balay header[0] = MAT_FILE_CLASSID; 13299371c9d4SSatish Balay header[1] = M; 13309371c9d4SSatish Balay header[2] = N; 13318491ab44SLisandro Dalcin header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M * N; 13329566063dSJacob Faibussowitsch if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer, header, 4, PETSC_INT)); 13338491ab44SLisandro Dalcin 13349566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mat, &m, NULL)); 13358491ab44SLisandro Dalcin if (format != PETSC_VIEWER_NATIVE) { 13368491ab44SLisandro Dalcin PetscInt nnz = m * N, *iwork; 13378491ab44SLisandro Dalcin /* store row lengths for each row */ 13389566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz, &iwork)); 13398491ab44SLisandro Dalcin for (i = 0; i < m; i++) iwork[i] = N; 13409566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 13418491ab44SLisandro Dalcin /* store column indices (zero start index) */ 13428491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 13439371c9d4SSatish Balay for (j = 0; j < N; j++, k++) iwork[k] = j; 13449566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 13459566063dSJacob Faibussowitsch PetscCall(PetscFree(iwork)); 13468491ab44SLisandro Dalcin } 13478491ab44SLisandro Dalcin /* store matrix values as a dense matrix in row major order */ 13489566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m * N, &vwork)); 13499566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(mat, &v)); 13509566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(mat, &lda)); 13518491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 13529371c9d4SSatish Balay for (j = 0; j < N; j++, k++) vwork[k] = v[i + lda * j]; 13539566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(mat, &v)); 13549566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, vwork, m * N, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 13559566063dSJacob Faibussowitsch PetscCall(PetscFree(vwork)); 13563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13578491ab44SLisandro Dalcin } 13588491ab44SLisandro Dalcin 1359d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLoad_Dense_Binary(Mat mat, PetscViewer viewer) 1360d71ae5a4SJacob Faibussowitsch { 13618491ab44SLisandro Dalcin PetscBool skipHeader; 13628491ab44SLisandro Dalcin PetscInt header[4], M, N, m, nz, lda, i, j, k; 13638491ab44SLisandro Dalcin PetscInt rows, cols; 13648491ab44SLisandro Dalcin PetscScalar *v, *vwork; 13658491ab44SLisandro Dalcin 13668491ab44SLisandro Dalcin PetscFunctionBegin; 13679566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 13689566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader)); 13698491ab44SLisandro Dalcin 13708491ab44SLisandro Dalcin if (!skipHeader) { 13719566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, header, 4, NULL, PETSC_INT)); 137208401ef6SPierre Jolivet PetscCheck(header[0] == MAT_FILE_CLASSID, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Not a matrix object in file"); 13739371c9d4SSatish Balay M = header[1]; 13749371c9d4SSatish Balay N = header[2]; 137508401ef6SPierre Jolivet PetscCheck(M >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix row size (%" PetscInt_FMT ") in file is negative", M); 137608401ef6SPierre Jolivet PetscCheck(N >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix column size (%" PetscInt_FMT ") in file is negative", N); 13778491ab44SLisandro Dalcin nz = header[3]; 1378aed4548fSBarry Smith PetscCheck(nz == MATRIX_BINARY_FORMAT_DENSE || nz >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Unknown matrix format %" PetscInt_FMT " in file", nz); 1379aabbc4fbSShri Abhyankar } else { 13809566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &M, &N)); 1381aed4548fSBarry 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"); 13828491ab44SLisandro Dalcin nz = MATRIX_BINARY_FORMAT_DENSE; 1383e6324fbbSBarry Smith } 1384aabbc4fbSShri Abhyankar 13858491ab44SLisandro Dalcin /* setup global sizes if not set */ 13868491ab44SLisandro Dalcin if (mat->rmap->N < 0) mat->rmap->N = M; 13878491ab44SLisandro Dalcin if (mat->cmap->N < 0) mat->cmap->N = N; 13889566063dSJacob Faibussowitsch PetscCall(MatSetUp(mat)); 13898491ab44SLisandro Dalcin /* check if global sizes are correct */ 13909566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &rows, &cols)); 1391aed4548fSBarry 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); 1392aabbc4fbSShri Abhyankar 13939566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, NULL, &N)); 13949566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mat, &m, NULL)); 13959566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(mat, &v)); 13969566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(mat, &lda)); 13978491ab44SLisandro Dalcin if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense format */ 13988491ab44SLisandro Dalcin PetscInt nnz = m * N; 13998491ab44SLisandro Dalcin /* read in matrix values */ 14009566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz, &vwork)); 14019566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 14028491ab44SLisandro Dalcin /* store values in column major order */ 14038491ab44SLisandro Dalcin for (j = 0; j < N; j++) 14049371c9d4SSatish Balay for (i = 0; i < m; i++) v[i + lda * j] = vwork[i * N + j]; 14059566063dSJacob Faibussowitsch PetscCall(PetscFree(vwork)); 14068491ab44SLisandro Dalcin } else { /* matrix in file is sparse format */ 14078491ab44SLisandro Dalcin PetscInt nnz = 0, *rlens, *icols; 14088491ab44SLisandro Dalcin /* read in row lengths */ 14099566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m, &rlens)); 14109566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, rlens, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 14118491ab44SLisandro Dalcin for (i = 0; i < m; i++) nnz += rlens[i]; 14128491ab44SLisandro Dalcin /* read in column indices and values */ 14139566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(nnz, &icols, nnz, &vwork)); 14149566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, icols, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 14159566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 14168491ab44SLisandro Dalcin /* store values in column major order */ 14178491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 14189371c9d4SSatish Balay for (j = 0; j < rlens[i]; j++, k++) v[i + lda * icols[k]] = vwork[k]; 14199566063dSJacob Faibussowitsch PetscCall(PetscFree(rlens)); 14209566063dSJacob Faibussowitsch PetscCall(PetscFree2(icols, vwork)); 1421aabbc4fbSShri Abhyankar } 14229566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(mat, &v)); 14239566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY)); 14249566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY)); 14253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1426aabbc4fbSShri Abhyankar } 1427aabbc4fbSShri Abhyankar 142866976f2fSJacob Faibussowitsch static PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer) 1429d71ae5a4SJacob Faibussowitsch { 1430eb91f321SVaclav Hapla PetscBool isbinary, ishdf5; 1431eb91f321SVaclav Hapla 1432eb91f321SVaclav Hapla PetscFunctionBegin; 1433eb91f321SVaclav Hapla PetscValidHeaderSpecific(newMat, MAT_CLASSID, 1); 1434eb91f321SVaclav Hapla PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1435eb91f321SVaclav Hapla /* force binary viewer to load .info file if it has not yet done so */ 14369566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 14379566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 14389566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5)); 1439eb91f321SVaclav Hapla if (isbinary) { 14409566063dSJacob Faibussowitsch PetscCall(MatLoad_Dense_Binary(newMat, viewer)); 1441eb91f321SVaclav Hapla } else if (ishdf5) { 1442eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5) 14439566063dSJacob Faibussowitsch PetscCall(MatLoad_Dense_HDF5(newMat, viewer)); 1444eb91f321SVaclav Hapla #else 1445eb91f321SVaclav Hapla SETERRQ(PetscObjectComm((PetscObject)newMat), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1446eb91f321SVaclav Hapla #endif 1447eb91f321SVaclav Hapla } else { 144898921bdaSJacob 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); 1449eb91f321SVaclav Hapla } 14503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1451eb91f321SVaclav Hapla } 1452eb91f321SVaclav Hapla 1453d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_ASCII(Mat A, PetscViewer viewer) 1454d71ae5a4SJacob Faibussowitsch { 1455932b0c3eSLois Curfman McInnes Mat_SeqDense *a = (Mat_SeqDense *)A->data; 145613f74950SBarry Smith PetscInt i, j; 14572dcb1b2aSMatthew Knepley const char *name; 1458ca15aa20SStefano Zampini PetscScalar *v, *av; 1459f3ef73ceSBarry Smith PetscViewerFormat format; 14605f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX) 1461ace3abfcSBarry Smith PetscBool allreal = PETSC_TRUE; 14625f481a85SSatish Balay #endif 1463932b0c3eSLois Curfman McInnes 14643a40ed3dSBarry Smith PetscFunctionBegin; 14659566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&av)); 14669566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 1467456192e2SBarry Smith if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 14683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); /* do nothing for now */ 1469fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 14709566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE)); 1471d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 1472ca15aa20SStefano Zampini v = av + i; 14739566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "row %" PetscInt_FMT ":", i)); 1474d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1475aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 1476329f5518SBarry Smith if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) { 14779566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g + %g i) ", j, (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v))); 1478329f5518SBarry Smith } else if (PetscRealPart(*v)) { 14799566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)PetscRealPart(*v))); 14806831982aSBarry Smith } 148180cd9d93SLois Curfman McInnes #else 148248a46eb9SPierre Jolivet if (*v) PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)*v)); 148380cd9d93SLois Curfman McInnes #endif 14841b807ce4Svictorle v += a->lda; 148580cd9d93SLois Curfman McInnes } 14869566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 148780cd9d93SLois Curfman McInnes } 14889566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE)); 14893a40ed3dSBarry Smith } else { 14909566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE)); 1491aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 149247989497SBarry Smith /* determine if matrix has all real values */ 1493bcd8d3a4SJose E. Roman for (j = 0; j < A->cmap->n; j++) { 1494bcd8d3a4SJose E. Roman v = av + j * a->lda; 1495bcd8d3a4SJose E. Roman for (i = 0; i < A->rmap->n; i++) { 14969371c9d4SSatish Balay if (PetscImaginaryPart(v[i])) { 14979371c9d4SSatish Balay allreal = PETSC_FALSE; 14989371c9d4SSatish Balay break; 14999371c9d4SSatish Balay } 150047989497SBarry Smith } 1501bcd8d3a4SJose E. Roman } 150247989497SBarry Smith #endif 1503fb9695e5SSatish Balay if (format == PETSC_VIEWER_ASCII_MATLAB) { 15049566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)A, &name)); 15059566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%% Size = %" PetscInt_FMT " %" PetscInt_FMT " \n", A->rmap->n, A->cmap->n)); 15069566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%s = zeros(%" PetscInt_FMT ",%" PetscInt_FMT ");\n", name, A->rmap->n, A->cmap->n)); 15079566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%s = [\n", name)); 1508ffac6cdbSBarry Smith } 1509ffac6cdbSBarry Smith 1510d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 1511ca15aa20SStefano Zampini v = av + i; 1512d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1513aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 151447989497SBarry Smith if (allreal) { 15159566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)PetscRealPart(*v))); 151647989497SBarry Smith } else { 15179566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e + %18.16ei ", (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v))); 151847989497SBarry Smith } 1519289bc588SBarry Smith #else 15209566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)*v)); 1521289bc588SBarry Smith #endif 15221b807ce4Svictorle v += a->lda; 1523289bc588SBarry Smith } 15249566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 1525289bc588SBarry Smith } 152648a46eb9SPierre Jolivet if (format == PETSC_VIEWER_ASCII_MATLAB) PetscCall(PetscViewerASCIIPrintf(viewer, "];\n")); 15279566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE)); 1528da3a660dSBarry Smith } 15299566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&av)); 15309566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer)); 15313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1532289bc588SBarry Smith } 1533289bc588SBarry Smith 15349804daf3SBarry Smith #include <petscdraw.h> 1535d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw, void *Aa) 1536d71ae5a4SJacob Faibussowitsch { 1537f1af5d2fSBarry Smith Mat A = (Mat)Aa; 1538383922c3SLisandro Dalcin PetscInt m = A->rmap->n, n = A->cmap->n, i, j; 1539383922c3SLisandro Dalcin int color = PETSC_DRAW_WHITE; 1540ca15aa20SStefano Zampini const PetscScalar *v; 1541b0a32e0cSBarry Smith PetscViewer viewer; 1542b05fc000SLisandro Dalcin PetscReal xl, yl, xr, yr, x_l, x_r, y_l, y_r; 1543f3ef73ceSBarry Smith PetscViewerFormat format; 1544f1af5d2fSBarry Smith 1545f1af5d2fSBarry Smith PetscFunctionBegin; 15469566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)A, "Zoomviewer", (PetscObject *)&viewer)); 15479566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 15489566063dSJacob Faibussowitsch PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr)); 1549f1af5d2fSBarry Smith 1550f1af5d2fSBarry Smith /* Loop over matrix elements drawing boxes */ 15519566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 1552fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 1553d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 1554f1af5d2fSBarry Smith /* Blue for negative and Red for positive */ 1555f1af5d2fSBarry Smith for (j = 0; j < n; j++) { 15569371c9d4SSatish Balay x_l = j; 15579371c9d4SSatish Balay x_r = x_l + 1.0; 1558f1af5d2fSBarry Smith for (i = 0; i < m; i++) { 1559f1af5d2fSBarry Smith y_l = m - i - 1.0; 1560f1af5d2fSBarry Smith y_r = y_l + 1.0; 1561ca15aa20SStefano Zampini if (PetscRealPart(v[j * m + i]) > 0.) color = PETSC_DRAW_RED; 1562ca15aa20SStefano Zampini else if (PetscRealPart(v[j * m + i]) < 0.) color = PETSC_DRAW_BLUE; 1563ca15aa20SStefano Zampini else continue; 15649566063dSJacob Faibussowitsch PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color)); 1565f1af5d2fSBarry Smith } 1566f1af5d2fSBarry Smith } 1567d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 1568f1af5d2fSBarry Smith } else { 1569f1af5d2fSBarry Smith /* use contour shading to indicate magnitude of values */ 1570f1af5d2fSBarry Smith /* first determine max of all nonzero values */ 1571b05fc000SLisandro Dalcin PetscReal minv = 0.0, maxv = 0.0; 1572b05fc000SLisandro Dalcin PetscDraw popup; 1573b05fc000SLisandro Dalcin 1574f1af5d2fSBarry Smith for (i = 0; i < m * n; i++) { 1575f1af5d2fSBarry Smith if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]); 1576f1af5d2fSBarry Smith } 1577383922c3SLisandro Dalcin if (minv >= maxv) maxv = minv + PETSC_SMALL; 15789566063dSJacob Faibussowitsch PetscCall(PetscDrawGetPopup(draw, &popup)); 15799566063dSJacob Faibussowitsch PetscCall(PetscDrawScalePopup(popup, minv, maxv)); 1580383922c3SLisandro Dalcin 1581d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 1582f1af5d2fSBarry Smith for (j = 0; j < n; j++) { 1583f1af5d2fSBarry Smith x_l = j; 1584f1af5d2fSBarry Smith x_r = x_l + 1.0; 1585f1af5d2fSBarry Smith for (i = 0; i < m; i++) { 1586f1af5d2fSBarry Smith y_l = m - i - 1.0; 1587f1af5d2fSBarry Smith y_r = y_l + 1.0; 1588b05fc000SLisandro Dalcin color = PetscDrawRealToColor(PetscAbsScalar(v[j * m + i]), minv, maxv); 15899566063dSJacob Faibussowitsch PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color)); 1590f1af5d2fSBarry Smith } 1591f1af5d2fSBarry Smith } 1592d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 1593f1af5d2fSBarry Smith } 15949566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 15953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1596f1af5d2fSBarry Smith } 1597f1af5d2fSBarry Smith 1598d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw(Mat A, PetscViewer viewer) 1599d71ae5a4SJacob Faibussowitsch { 1600b0a32e0cSBarry Smith PetscDraw draw; 1601ace3abfcSBarry Smith PetscBool isnull; 1602329f5518SBarry Smith PetscReal xr, yr, xl, yl, h, w; 1603f1af5d2fSBarry Smith 1604f1af5d2fSBarry Smith PetscFunctionBegin; 16059566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 16069566063dSJacob Faibussowitsch PetscCall(PetscDrawIsNull(draw, &isnull)); 16073ba16761SJacob Faibussowitsch if (isnull) PetscFunctionReturn(PETSC_SUCCESS); 1608f1af5d2fSBarry Smith 16099371c9d4SSatish Balay xr = A->cmap->n; 16109371c9d4SSatish Balay yr = A->rmap->n; 16119371c9d4SSatish Balay h = yr / 10.0; 16129371c9d4SSatish Balay w = xr / 10.0; 16139371c9d4SSatish Balay xr += w; 16149371c9d4SSatish Balay yr += h; 16159371c9d4SSatish Balay xl = -w; 16169371c9d4SSatish Balay yl = -h; 16179566063dSJacob Faibussowitsch PetscCall(PetscDrawSetCoordinates(draw, xl, yl, xr, yr)); 16189566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", (PetscObject)viewer)); 16199566063dSJacob Faibussowitsch PetscCall(PetscDrawZoom(draw, MatView_SeqDense_Draw_Zoom, A)); 16209566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", NULL)); 16219566063dSJacob Faibussowitsch PetscCall(PetscDrawSave(draw)); 16223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1623f1af5d2fSBarry Smith } 1624f1af5d2fSBarry Smith 1625d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_SeqDense(Mat A, PetscViewer viewer) 1626d71ae5a4SJacob Faibussowitsch { 1627ace3abfcSBarry Smith PetscBool iascii, isbinary, isdraw; 1628932b0c3eSLois Curfman McInnes 16293a40ed3dSBarry Smith PetscFunctionBegin; 16309566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 16319566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 16329566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 16331baa6e33SBarry Smith if (iascii) PetscCall(MatView_SeqDense_ASCII(A, viewer)); 16341baa6e33SBarry Smith else if (isbinary) PetscCall(MatView_Dense_Binary(A, viewer)); 16351baa6e33SBarry Smith else if (isdraw) PetscCall(MatView_SeqDense_Draw(A, viewer)); 16363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1637932b0c3eSLois Curfman McInnes } 1638289bc588SBarry Smith 1639d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A, const PetscScalar *array) 1640d71ae5a4SJacob Faibussowitsch { 1641d3042a70SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1642d3042a70SBarry Smith 1643d3042a70SBarry Smith PetscFunctionBegin; 164428b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 164528b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 164628b400f6SJacob Faibussowitsch PetscCheck(!a->unplacedarray, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreArray() first"); 1647d3042a70SBarry Smith a->unplacedarray = a->v; 1648d3042a70SBarry Smith a->unplaced_user_alloc = a->user_alloc; 1649d3042a70SBarry Smith a->v = (PetscScalar *)array; 1650637a0070SStefano Zampini a->user_alloc = PETSC_TRUE; 165147d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1652c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_CPU; 1653ca15aa20SStefano Zampini #endif 16543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1655d3042a70SBarry Smith } 1656d3042a70SBarry Smith 1657d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseResetArray_SeqDense(Mat A) 1658d71ae5a4SJacob Faibussowitsch { 1659d3042a70SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1660d3042a70SBarry Smith 1661d3042a70SBarry Smith PetscFunctionBegin; 166228b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 166328b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 1664d3042a70SBarry Smith a->v = a->unplacedarray; 1665d3042a70SBarry Smith a->user_alloc = a->unplaced_user_alloc; 1666d3042a70SBarry Smith a->unplacedarray = NULL; 166747d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1668c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_CPU; 1669ca15aa20SStefano Zampini #endif 16703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1671d3042a70SBarry Smith } 1672d3042a70SBarry Smith 1673d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A, const PetscScalar *array) 1674d71ae5a4SJacob Faibussowitsch { 1675d5ea218eSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1676d5ea218eSStefano Zampini 1677d5ea218eSStefano Zampini PetscFunctionBegin; 167828b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 167928b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 16809566063dSJacob Faibussowitsch if (!a->user_alloc) PetscCall(PetscFree(a->v)); 1681d5ea218eSStefano Zampini a->v = (PetscScalar *)array; 1682d5ea218eSStefano Zampini a->user_alloc = PETSC_FALSE; 168347d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1684d5ea218eSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 1685d5ea218eSStefano Zampini #endif 16863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1687d5ea218eSStefano Zampini } 1688d5ea218eSStefano Zampini 1689d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDestroy_SeqDense(Mat mat) 1690d71ae5a4SJacob Faibussowitsch { 1691ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)mat->data; 169290f02eecSBarry Smith 16933a40ed3dSBarry Smith PetscFunctionBegin; 16943ba16761SJacob Faibussowitsch PetscCall(PetscLogObjectState((PetscObject)mat, "Rows %" PetscInt_FMT " Cols %" PetscInt_FMT, mat->rmap->n, mat->cmap->n)); 1695*f4f49eeaSPierre Jolivet PetscCall(VecDestroy(&l->qrrhs)); 16969566063dSJacob Faibussowitsch PetscCall(PetscFree(l->tau)); 16979566063dSJacob Faibussowitsch PetscCall(PetscFree(l->pivots)); 16989566063dSJacob Faibussowitsch PetscCall(PetscFree(l->fwork)); 16999566063dSJacob Faibussowitsch if (!l->user_alloc) PetscCall(PetscFree(l->v)); 17009566063dSJacob Faibussowitsch if (!l->unplaced_user_alloc) PetscCall(PetscFree(l->unplacedarray)); 170128b400f6SJacob Faibussowitsch PetscCheck(!l->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 170228b400f6SJacob Faibussowitsch PetscCheck(!l->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 17039566063dSJacob Faibussowitsch PetscCall(VecDestroy(&l->cvec)); 17049566063dSJacob Faibussowitsch PetscCall(MatDestroy(&l->cmat)); 17059566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->data)); 1706dbd8c25aSHong Zhang 17079566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)mat, NULL)); 17089566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactor_C", NULL)); 17092e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorSymbolic_C", NULL)); 17102e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorNumeric_C", NULL)); 17119566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetLDA_C", NULL)); 17129566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseSetLDA_C", NULL)); 17139566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArray_C", NULL)); 17149566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArray_C", NULL)); 17159566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDensePlaceArray_C", NULL)); 17169566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseResetArray_C", NULL)); 17179566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseReplaceArray_C", NULL)); 17189566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayRead_C", NULL)); 17199566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayRead_C", NULL)); 17209566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayWrite_C", NULL)); 17219566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayWrite_C", NULL)); 17229566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqaij_C", NULL)); 17238baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 17249566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_elemental_C", NULL)); 17258baccfbdSHong Zhang #endif 1726d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 17279566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_scalapack_C", NULL)); 1728d24d4204SJose E. Roman #endif 17292bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA) 17309566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensecuda_C", NULL)); 17319566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", NULL)); 17329566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdense_C", NULL)); 17332e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensecuda_C", NULL)); 17342bf066beSStefano Zampini #endif 173547d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 173647d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensehip_C", NULL)); 173747d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensehip_seqdensehip_C", NULL)); 173847d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensehip_seqdense_C", NULL)); 173947d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensehip_C", NULL)); 174047d993e7Ssuyashtn #endif 17419566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatSeqDenseSetPreallocation_C", NULL)); 17429566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqaij_seqdense_C", NULL)); 17439566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdense_C", NULL)); 17449566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqbaij_seqdense_C", NULL)); 17459566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqsbaij_seqdense_C", NULL)); 174652c5f739Sprj- 17479566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumn_C", NULL)); 17489566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumn_C", NULL)); 17499566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVec_C", NULL)); 17509566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVec_C", NULL)); 17519566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecRead_C", NULL)); 17529566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecRead_C", NULL)); 17539566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecWrite_C", NULL)); 17549566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecWrite_C", NULL)); 17559566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetSubMatrix_C", NULL)); 17569566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreSubMatrix_C", NULL)); 17573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1758289bc588SBarry Smith } 1759289bc588SBarry Smith 1760d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatTranspose_SeqDense(Mat A, MatReuse reuse, Mat *matout) 1761d71ae5a4SJacob Faibussowitsch { 1762c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 17636536e3caSStefano Zampini PetscInt k, j, m = A->rmap->n, M = mat->lda, n = A->cmap->n; 176487828ca2SBarry Smith PetscScalar *v, tmp; 176548b35521SBarry Smith 17663a40ed3dSBarry Smith PetscFunctionBegin; 17677fb60732SBarry Smith if (reuse == MAT_REUSE_MATRIX) PetscCall(MatTransposeCheckNonzeroState_Private(A, *matout)); 17686536e3caSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 17696536e3caSStefano Zampini if (m == n) { /* in place transpose */ 17709566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 1771d3e5ee88SLois Curfman McInnes for (j = 0; j < m; j++) { 1772289bc588SBarry Smith for (k = 0; k < j; k++) { 17731b807ce4Svictorle tmp = v[j + k * M]; 17741b807ce4Svictorle v[j + k * M] = v[k + j * M]; 17751b807ce4Svictorle v[k + j * M] = tmp; 1776289bc588SBarry Smith } 1777289bc588SBarry Smith } 17789566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 17796536e3caSStefano Zampini } else { /* reuse memory, temporary allocates new memory */ 17806536e3caSStefano Zampini PetscScalar *v2; 17816536e3caSStefano Zampini PetscLayout tmplayout; 17826536e3caSStefano Zampini 17839566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((size_t)m * n, &v2)); 17849566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 17856536e3caSStefano Zampini for (j = 0; j < n; j++) { 17866536e3caSStefano Zampini for (k = 0; k < m; k++) v2[j + (size_t)k * n] = v[k + (size_t)j * M]; 17876536e3caSStefano Zampini } 17889566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(v, v2, (size_t)m * n)); 17899566063dSJacob Faibussowitsch PetscCall(PetscFree(v2)); 17909566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 17916536e3caSStefano Zampini /* cleanup size dependent quantities */ 17929566063dSJacob Faibussowitsch PetscCall(VecDestroy(&mat->cvec)); 17939566063dSJacob Faibussowitsch PetscCall(MatDestroy(&mat->cmat)); 17949566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->pivots)); 17959566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->fwork)); 17966536e3caSStefano Zampini /* swap row/col layouts */ 17976536e3caSStefano Zampini mat->lda = n; 17986536e3caSStefano Zampini tmplayout = A->rmap; 17996536e3caSStefano Zampini A->rmap = A->cmap; 18006536e3caSStefano Zampini A->cmap = tmplayout; 18016536e3caSStefano Zampini } 18023a40ed3dSBarry Smith } else { /* out-of-place transpose */ 1803d3e5ee88SLois Curfman McInnes Mat tmat; 1804ec8511deSBarry Smith Mat_SeqDense *tmatd; 180587828ca2SBarry Smith PetscScalar *v2; 1806af36a384SStefano Zampini PetscInt M2; 1807ea709b57SSatish Balay 18086536e3caSStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 18099566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &tmat)); 18109566063dSJacob Faibussowitsch PetscCall(MatSetSizes(tmat, A->cmap->n, A->rmap->n, A->cmap->n, A->rmap->n)); 18119566063dSJacob Faibussowitsch PetscCall(MatSetType(tmat, ((PetscObject)A)->type_name)); 18129566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(tmat, NULL)); 1813ca15aa20SStefano Zampini } else tmat = *matout; 1814ca15aa20SStefano Zampini 18159566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&v)); 18169566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(tmat, &v2)); 1817ec8511deSBarry Smith tmatd = (Mat_SeqDense *)tmat->data; 1818ca15aa20SStefano Zampini M2 = tmatd->lda; 1819d3e5ee88SLois Curfman McInnes for (j = 0; j < n; j++) { 1820af36a384SStefano Zampini for (k = 0; k < m; k++) v2[j + k * M2] = v[k + j * M]; 1821d3e5ee88SLois Curfman McInnes } 18229566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(tmat, &v2)); 18239566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&v)); 18249566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(tmat, MAT_FINAL_ASSEMBLY)); 18259566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(tmat, MAT_FINAL_ASSEMBLY)); 18266536e3caSStefano Zampini *matout = tmat; 182748b35521SBarry Smith } 18283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1829289bc588SBarry Smith } 1830289bc588SBarry Smith 1831d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatEqual_SeqDense(Mat A1, Mat A2, PetscBool *flg) 1832d71ae5a4SJacob Faibussowitsch { 1833c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat1 = (Mat_SeqDense *)A1->data; 1834c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat2 = (Mat_SeqDense *)A2->data; 1835ca15aa20SStefano Zampini PetscInt i; 1836ca15aa20SStefano Zampini const PetscScalar *v1, *v2; 18379ea5d5aeSSatish Balay 18383a40ed3dSBarry Smith PetscFunctionBegin; 18399371c9d4SSatish Balay if (A1->rmap->n != A2->rmap->n) { 18409371c9d4SSatish Balay *flg = PETSC_FALSE; 18413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18429371c9d4SSatish Balay } 18439371c9d4SSatish Balay if (A1->cmap->n != A2->cmap->n) { 18449371c9d4SSatish Balay *flg = PETSC_FALSE; 18453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18469371c9d4SSatish Balay } 18479566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A1, &v1)); 18489566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A2, &v2)); 1849ca15aa20SStefano Zampini for (i = 0; i < A1->cmap->n; i++) { 18509566063dSJacob Faibussowitsch PetscCall(PetscArraycmp(v1, v2, A1->rmap->n, flg)); 18513ba16761SJacob Faibussowitsch if (*flg == PETSC_FALSE) PetscFunctionReturn(PETSC_SUCCESS); 1852ca15aa20SStefano Zampini v1 += mat1->lda; 1853ca15aa20SStefano Zampini v2 += mat2->lda; 18541b807ce4Svictorle } 18559566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A1, &v1)); 18569566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A2, &v2)); 185777c4ece6SBarry Smith *flg = PETSC_TRUE; 18583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1859289bc588SBarry Smith } 1860289bc588SBarry Smith 186114277c92SJacob Faibussowitsch PetscErrorCode MatGetDiagonal_SeqDense(Mat A, Vec v) 1862d71ae5a4SJacob Faibussowitsch { 1863c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 186413f74950SBarry Smith PetscInt i, n, len; 1865ca15aa20SStefano Zampini PetscScalar *x; 1866ca15aa20SStefano Zampini const PetscScalar *vv; 186744cd7ae7SLois Curfman McInnes 18683a40ed3dSBarry Smith PetscFunctionBegin; 18699566063dSJacob Faibussowitsch PetscCall(VecGetSize(v, &n)); 18709566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 1871d0f46423SBarry Smith len = PetscMin(A->rmap->n, A->cmap->n); 18729566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &vv)); 187308401ef6SPierre Jolivet PetscCheck(n == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming mat and vec"); 1874ad540459SPierre Jolivet for (i = 0; i < len; i++) x[i] = vv[i * mat->lda + i]; 18759566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &vv)); 18769566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 18773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1878289bc588SBarry Smith } 1879289bc588SBarry Smith 1880d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDiagonalScale_SeqDense(Mat A, Vec ll, Vec rr) 1881d71ae5a4SJacob Faibussowitsch { 1882c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1883f1ceaac6SMatthew G. Knepley const PetscScalar *l, *r; 1884ca15aa20SStefano Zampini PetscScalar x, *v, *vv; 1885d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n; 188655659b69SBarry Smith 18873a40ed3dSBarry Smith PetscFunctionBegin; 18889566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &vv)); 188928988994SBarry Smith if (ll) { 18909566063dSJacob Faibussowitsch PetscCall(VecGetSize(ll, &m)); 18919566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(ll, &l)); 189208401ef6SPierre Jolivet PetscCheck(m == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Left scaling vec wrong size"); 1893da3a660dSBarry Smith for (i = 0; i < m; i++) { 1894da3a660dSBarry Smith x = l[i]; 1895ca15aa20SStefano Zampini v = vv + i; 18969371c9d4SSatish Balay for (j = 0; j < n; j++) { 18979371c9d4SSatish Balay (*v) *= x; 18989371c9d4SSatish Balay v += mat->lda; 18999371c9d4SSatish Balay } 1900da3a660dSBarry Smith } 19019566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(ll, &l)); 19029566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * n * m)); 1903da3a660dSBarry Smith } 190428988994SBarry Smith if (rr) { 19059566063dSJacob Faibussowitsch PetscCall(VecGetSize(rr, &n)); 19069566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(rr, &r)); 190708401ef6SPierre Jolivet PetscCheck(n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Right scaling vec wrong size"); 1908da3a660dSBarry Smith for (i = 0; i < n; i++) { 1909da3a660dSBarry Smith x = r[i]; 1910ca15aa20SStefano Zampini v = vv + i * mat->lda; 19112205254eSKarl Rupp for (j = 0; j < m; j++) (*v++) *= x; 1912da3a660dSBarry Smith } 19139566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(rr, &r)); 19149566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * n * m)); 1915da3a660dSBarry Smith } 19169566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &vv)); 19173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1918289bc588SBarry Smith } 1919289bc588SBarry Smith 1920d71ae5a4SJacob Faibussowitsch PetscErrorCode MatNorm_SeqDense(Mat A, NormType type, PetscReal *nrm) 1921d71ae5a4SJacob Faibussowitsch { 1922c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1923ca15aa20SStefano Zampini PetscScalar *v, *vv; 1924329f5518SBarry Smith PetscReal sum = 0.0; 192575f6d85dSStefano Zampini PetscInt lda, m = A->rmap->n, i, j; 192655659b69SBarry Smith 19273a40ed3dSBarry Smith PetscFunctionBegin; 19289566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&vv)); 19299566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(A, &lda)); 1930ca15aa20SStefano Zampini v = vv; 1931289bc588SBarry Smith if (type == NORM_FROBENIUS) { 1932a5ce6ee0Svictorle if (lda > m) { 1933d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1934ca15aa20SStefano Zampini v = vv + j * lda; 1935a5ce6ee0Svictorle for (i = 0; i < m; i++) { 19369371c9d4SSatish Balay sum += PetscRealPart(PetscConj(*v) * (*v)); 19379371c9d4SSatish Balay v++; 1938a5ce6ee0Svictorle } 1939a5ce6ee0Svictorle } 1940a5ce6ee0Svictorle } else { 1941570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16) 1942570b7f6dSBarry Smith PetscBLASInt one = 1, cnt = A->cmap->n * A->rmap->n; 1943792fecdfSBarry Smith PetscCallBLAS("BLASnrm2", *nrm = BLASnrm2_(&cnt, v, &one)); 1944570b7f6dSBarry Smith } 1945570b7f6dSBarry Smith #else 1946d0f46423SBarry Smith for (i = 0; i < A->cmap->n * A->rmap->n; i++) { 19479371c9d4SSatish Balay sum += PetscRealPart(PetscConj(*v) * (*v)); 19489371c9d4SSatish Balay v++; 1949289bc588SBarry Smith } 1950a5ce6ee0Svictorle } 19518f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 1952570b7f6dSBarry Smith #endif 19539566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->cmap->n * A->rmap->n)); 19543a40ed3dSBarry Smith } else if (type == NORM_1) { 1955064f8208SBarry Smith *nrm = 0.0; 1956d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1957ca15aa20SStefano Zampini v = vv + j * mat->lda; 1958289bc588SBarry Smith sum = 0.0; 1959d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 19609371c9d4SSatish Balay sum += PetscAbsScalar(*v); 19619371c9d4SSatish Balay v++; 1962289bc588SBarry Smith } 1963064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 1964289bc588SBarry Smith } 19659566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n)); 19663a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 1967064f8208SBarry Smith *nrm = 0.0; 1968d0f46423SBarry Smith for (j = 0; j < A->rmap->n; j++) { 1969ca15aa20SStefano Zampini v = vv + j; 1970289bc588SBarry Smith sum = 0.0; 1971d0f46423SBarry Smith for (i = 0; i < A->cmap->n; i++) { 19729371c9d4SSatish Balay sum += PetscAbsScalar(*v); 19739371c9d4SSatish Balay v += mat->lda; 1974289bc588SBarry Smith } 1975064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 1976289bc588SBarry Smith } 19779566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n)); 1978e7e72b3dSBarry Smith } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "No two norm"); 19799566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&vv)); 19803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1981289bc588SBarry Smith } 1982289bc588SBarry Smith 1983d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetOption_SeqDense(Mat A, MatOption op, PetscBool flg) 1984d71ae5a4SJacob Faibussowitsch { 1985c0bbcb79SLois Curfman McInnes Mat_SeqDense *aij = (Mat_SeqDense *)A->data; 198667e560aaSBarry Smith 19873a40ed3dSBarry Smith PetscFunctionBegin; 1988b5a2b587SKris Buschelman switch (op) { 1989d71ae5a4SJacob Faibussowitsch case MAT_ROW_ORIENTED: 1990d71ae5a4SJacob Faibussowitsch aij->roworiented = flg; 1991d71ae5a4SJacob Faibussowitsch break; 1992512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 1993b5a2b587SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 19943971808eSMatthew Knepley case MAT_NEW_NONZERO_ALLOCATION_ERR: 19958c78258cSHong Zhang case MAT_FORCE_DIAGONAL_ENTRIES: 199613fa8e87SLisandro Dalcin case MAT_KEEP_NONZERO_PATTERN: 1997b5a2b587SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 1998b5a2b587SKris Buschelman case MAT_USE_HASH_TABLE: 19990f8fb01aSBarry Smith case MAT_IGNORE_ZERO_ENTRIES: 20005021d80fSJed Brown case MAT_IGNORE_LOWER_TRIANGULAR: 2001d71ae5a4SJacob Faibussowitsch case MAT_SORTED_FULL: 2002d71ae5a4SJacob Faibussowitsch PetscCall(PetscInfo(A, "Option %s ignored\n", MatOptions[op])); 2003d71ae5a4SJacob Faibussowitsch break; 20045021d80fSJed Brown case MAT_SPD: 200577e54ba9SKris Buschelman case MAT_SYMMETRIC: 200677e54ba9SKris Buschelman case MAT_STRUCTURALLY_SYMMETRIC: 20079a4540c5SBarry Smith case MAT_HERMITIAN: 20089a4540c5SBarry Smith case MAT_SYMMETRY_ETERNAL: 2009b94d7dedSBarry Smith case MAT_STRUCTURAL_SYMMETRY_ETERNAL: 2010d71ae5a4SJacob Faibussowitsch case MAT_SPD_ETERNAL: 2011d71ae5a4SJacob Faibussowitsch break; 2012d71ae5a4SJacob Faibussowitsch default: 2013d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "unknown option %s", MatOptions[op]); 20143a40ed3dSBarry Smith } 20153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2016289bc588SBarry Smith } 2017289bc588SBarry Smith 2018d71ae5a4SJacob Faibussowitsch PetscErrorCode MatZeroEntries_SeqDense(Mat A) 2019d71ae5a4SJacob Faibussowitsch { 2020ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)A->data; 20213d8925e7SStefano Zampini PetscInt lda = l->lda, m = A->rmap->n, n = A->cmap->n, j; 2022ca15aa20SStefano Zampini PetscScalar *v; 20233a40ed3dSBarry Smith 20243a40ed3dSBarry Smith PetscFunctionBegin; 20259566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(A, &v)); 2026a5ce6ee0Svictorle if (lda > m) { 202748a46eb9SPierre Jolivet for (j = 0; j < n; j++) PetscCall(PetscArrayzero(v + j * lda, m)); 2028a5ce6ee0Svictorle } else { 20299566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(v, PetscInt64Mult(m, n))); 2030a5ce6ee0Svictorle } 20319566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(A, &v)); 20323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 20336f0a148fSBarry Smith } 20346f0a148fSBarry Smith 2035d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatZeroRows_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) 2036d71ae5a4SJacob Faibussowitsch { 2037ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)A->data; 2038b9679d65SBarry Smith PetscInt m = l->lda, n = A->cmap->n, i, j; 2039ca15aa20SStefano Zampini PetscScalar *slot, *bb, *v; 204097b48c8fSBarry Smith const PetscScalar *xx; 204155659b69SBarry Smith 20423a40ed3dSBarry Smith PetscFunctionBegin; 204376bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 2044b9679d65SBarry Smith for (i = 0; i < N; i++) { 204508401ef6SPierre Jolivet PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed"); 204608401ef6SPierre 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); 2047b9679d65SBarry Smith } 204876bd3646SJed Brown } 20493ba16761SJacob Faibussowitsch if (!N) PetscFunctionReturn(PETSC_SUCCESS); 2050b9679d65SBarry Smith 205197b48c8fSBarry Smith /* fix right hand side if needed */ 205297b48c8fSBarry Smith if (x && b) { 20539566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 20549566063dSJacob Faibussowitsch PetscCall(VecGetArray(b, &bb)); 20552205254eSKarl Rupp for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]]; 20569566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 20579566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(b, &bb)); 205897b48c8fSBarry Smith } 205997b48c8fSBarry Smith 20609566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 20616f0a148fSBarry Smith for (i = 0; i < N; i++) { 2062ca15aa20SStefano Zampini slot = v + rows[i]; 20639371c9d4SSatish Balay for (j = 0; j < n; j++) { 20649371c9d4SSatish Balay *slot = 0.0; 20659371c9d4SSatish Balay slot += m; 20669371c9d4SSatish Balay } 20676f0a148fSBarry Smith } 2068f4df32b1SMatthew Knepley if (diag != 0.0) { 206908401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices"); 20706f0a148fSBarry Smith for (i = 0; i < N; i++) { 2071ca15aa20SStefano Zampini slot = v + (m + 1) * rows[i]; 2072f4df32b1SMatthew Knepley *slot = diag; 20736f0a148fSBarry Smith } 20746f0a148fSBarry Smith } 20759566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 20763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 20776f0a148fSBarry Smith } 2078557bce09SLois Curfman McInnes 2079d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A, PetscInt *lda) 2080d71ae5a4SJacob Faibussowitsch { 208149a6ff4bSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 208249a6ff4bSBarry Smith 208349a6ff4bSBarry Smith PetscFunctionBegin; 208449a6ff4bSBarry Smith *lda = mat->lda; 20853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 208649a6ff4bSBarry Smith } 208749a6ff4bSBarry Smith 2088d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArray_SeqDense(Mat A, PetscScalar **array) 2089d71ae5a4SJacob Faibussowitsch { 2090c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 20913a40ed3dSBarry Smith 20923a40ed3dSBarry Smith PetscFunctionBegin; 209328b400f6SJacob Faibussowitsch PetscCheck(!mat->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 209464e87e97SBarry Smith *array = mat->v; 20953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 209664e87e97SBarry Smith } 20970754003eSLois Curfman McInnes 2098d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A, PetscScalar **array) 2099d71ae5a4SJacob Faibussowitsch { 21003a40ed3dSBarry Smith PetscFunctionBegin; 210175f6d85dSStefano Zampini if (array) *array = NULL; 21023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2103ff14e315SSatish Balay } 21040754003eSLois Curfman McInnes 21050f74d2c1SSatish Balay /*@ 210611a5261eSBarry Smith MatDenseGetLDA - gets the leading dimension of the array returned from `MatDenseGetArray()` 210749a6ff4bSBarry Smith 21082ef1f0ffSBarry Smith Not Collective 210949a6ff4bSBarry Smith 211049a6ff4bSBarry Smith Input Parameter: 2111fe59aa6dSJacob Faibussowitsch . A - a `MATDENSE` or `MATDENSECUDA` matrix 211249a6ff4bSBarry Smith 211349a6ff4bSBarry Smith Output Parameter: 211449a6ff4bSBarry Smith . lda - the leading dimension 211549a6ff4bSBarry Smith 211649a6ff4bSBarry Smith Level: intermediate 211749a6ff4bSBarry Smith 21181cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseSetLDA()` 211949a6ff4bSBarry Smith @*/ 2120d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetLDA(Mat A, PetscInt *lda) 2121d71ae5a4SJacob Faibussowitsch { 212249a6ff4bSBarry Smith PetscFunctionBegin; 2123d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 21244f572ea9SToby Isaac PetscAssertPointer(lda, 2); 212575f6d85dSStefano Zampini MatCheckPreallocated(A, 1); 2126cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetLDA_C", (Mat, PetscInt *), (A, lda)); 21273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 212849a6ff4bSBarry Smith } 212949a6ff4bSBarry Smith 21300f74d2c1SSatish Balay /*@ 213111a5261eSBarry Smith MatDenseSetLDA - Sets the leading dimension of the array used by the `MATDENSE` matrix 2132ad16ce7aSStefano Zampini 21332323109cSBarry Smith Collective if the matrix layouts have not yet been setup 2134ad16ce7aSStefano Zampini 2135d8d19677SJose E. Roman Input Parameters: 2136fe59aa6dSJacob Faibussowitsch + A - a `MATDENSE` or `MATDENSECUDA` matrix 2137ad16ce7aSStefano Zampini - lda - the leading dimension 2138ad16ce7aSStefano Zampini 2139ad16ce7aSStefano Zampini Level: intermediate 2140ad16ce7aSStefano Zampini 21411cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetLDA()` 2142ad16ce7aSStefano Zampini @*/ 2143d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA(Mat A, PetscInt lda) 2144d71ae5a4SJacob Faibussowitsch { 2145ad16ce7aSStefano Zampini PetscFunctionBegin; 2146ad16ce7aSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2147cac4c232SBarry Smith PetscTryMethod(A, "MatDenseSetLDA_C", (Mat, PetscInt), (A, lda)); 21483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2149ad16ce7aSStefano Zampini } 2150ad16ce7aSStefano Zampini 2151ad16ce7aSStefano Zampini /*@C 215211a5261eSBarry Smith MatDenseGetArray - gives read-write access to the array where the data for a `MATDENSE` matrix is stored 215373a71a0fSBarry Smith 2154c3339decSBarry Smith Logically Collective 215573a71a0fSBarry Smith 215673a71a0fSBarry Smith Input Parameter: 2157fe59aa6dSJacob Faibussowitsch . A - a dense matrix 215873a71a0fSBarry Smith 215973a71a0fSBarry Smith Output Parameter: 216073a71a0fSBarry Smith . array - pointer to the data 216173a71a0fSBarry Smith 216273a71a0fSBarry Smith Level: intermediate 216373a71a0fSBarry Smith 2164fe59aa6dSJacob Faibussowitsch Fortran Notes: 21650ab4885dSBarry Smith `MatDenseGetArray()` Fortran binding is deprecated (since PETSc 3.19), use `MatDenseGetArrayF90()` 21660ab4885dSBarry Smith 21671cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 216873a71a0fSBarry Smith @*/ 2169d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArray(Mat A, PetscScalar **array) 2170d71ae5a4SJacob Faibussowitsch { 217173a71a0fSBarry Smith PetscFunctionBegin; 2172d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 21734f572ea9SToby Isaac PetscAssertPointer(array, 2); 2174cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array)); 21753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 217673a71a0fSBarry Smith } 217773a71a0fSBarry Smith 2178dec5eb66SMatthew G Knepley /*@C 217911a5261eSBarry Smith MatDenseRestoreArray - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArray()` 218073a71a0fSBarry Smith 2181c3339decSBarry Smith Logically Collective 21828572280aSBarry Smith 21838572280aSBarry Smith Input Parameters: 2184fe59aa6dSJacob Faibussowitsch + A - a dense matrix 21852ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`) 21868572280aSBarry Smith 21878572280aSBarry Smith Level: intermediate 21888572280aSBarry Smith 2189fe59aa6dSJacob Faibussowitsch Fortran Notes: 21900ab4885dSBarry Smith `MatDenseRestoreArray()` Fortran binding is deprecated (since PETSc 3.19), use `MatDenseRestoreArrayF90()` 21910ab4885dSBarry Smith 21921cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 21938572280aSBarry Smith @*/ 2194d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArray(Mat A, PetscScalar **array) 2195d71ae5a4SJacob Faibussowitsch { 21968572280aSBarry Smith PetscFunctionBegin; 2197d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 21984f572ea9SToby Isaac if (array) PetscAssertPointer(array, 2); 2199cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array)); 22009566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)A)); 220147d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 2202637a0070SStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 2203637a0070SStefano Zampini #endif 22043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22058572280aSBarry Smith } 22068572280aSBarry Smith 22078572280aSBarry Smith /*@C 220811a5261eSBarry Smith MatDenseGetArrayRead - gives read-only access to the array where the data for a `MATDENSE` matrix is stored 22098572280aSBarry Smith 2210fb850c59SBarry Smith Not Collective 22118572280aSBarry Smith 22128572280aSBarry Smith Input Parameter: 2213fe59aa6dSJacob Faibussowitsch . A - a dense matrix 22148572280aSBarry Smith 22158572280aSBarry Smith Output Parameter: 22168572280aSBarry Smith . array - pointer to the data 22178572280aSBarry Smith 22188572280aSBarry Smith Level: intermediate 22198572280aSBarry Smith 22201cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 22218572280aSBarry Smith @*/ 2222d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArrayRead(Mat A, const PetscScalar **array) 2223d71ae5a4SJacob Faibussowitsch { 22248572280aSBarry Smith PetscFunctionBegin; 2225d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22264f572ea9SToby Isaac PetscAssertPointer(array, 2); 22275c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 22283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22298572280aSBarry Smith } 22308572280aSBarry Smith 22318572280aSBarry Smith /*@C 223211a5261eSBarry Smith MatDenseRestoreArrayRead - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayRead()` 22338572280aSBarry Smith 2234fb850c59SBarry Smith Not Collective 223573a71a0fSBarry Smith 223673a71a0fSBarry Smith Input Parameters: 2237fe59aa6dSJacob Faibussowitsch + A - a dense matrix 22382ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`) 223973a71a0fSBarry Smith 224073a71a0fSBarry Smith Level: intermediate 224173a71a0fSBarry Smith 22421cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 224373a71a0fSBarry Smith @*/ 2244d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArrayRead(Mat A, const PetscScalar **array) 2245d71ae5a4SJacob Faibussowitsch { 224673a71a0fSBarry Smith PetscFunctionBegin; 2247d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22484f572ea9SToby Isaac if (array) PetscAssertPointer(array, 2); 22495c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 22503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 225173a71a0fSBarry Smith } 225273a71a0fSBarry Smith 22536947451fSStefano Zampini /*@C 225411a5261eSBarry Smith MatDenseGetArrayWrite - gives write-only access to the array where the data for a `MATDENSE` matrix is stored 22556947451fSStefano Zampini 2256fb850c59SBarry Smith Not Collective 22576947451fSStefano Zampini 22586947451fSStefano Zampini Input Parameter: 2259fe59aa6dSJacob Faibussowitsch . A - a dense matrix 22606947451fSStefano Zampini 22616947451fSStefano Zampini Output Parameter: 22626947451fSStefano Zampini . array - pointer to the data 22636947451fSStefano Zampini 22646947451fSStefano Zampini Level: intermediate 22656947451fSStefano Zampini 22661cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()` 22676947451fSStefano Zampini @*/ 2268d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArrayWrite(Mat A, PetscScalar **array) 2269d71ae5a4SJacob Faibussowitsch { 22706947451fSStefano Zampini PetscFunctionBegin; 2271d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22724f572ea9SToby Isaac PetscAssertPointer(array, 2); 2273cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array)); 22743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22756947451fSStefano Zampini } 22766947451fSStefano Zampini 22776947451fSStefano Zampini /*@C 227811a5261eSBarry Smith MatDenseRestoreArrayWrite - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayWrite()` 22796947451fSStefano Zampini 2280fb850c59SBarry Smith Not Collective 22816947451fSStefano Zampini 22826947451fSStefano Zampini Input Parameters: 2283fe59aa6dSJacob Faibussowitsch + A - a dense matrix 22842ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`) 22856947451fSStefano Zampini 22866947451fSStefano Zampini Level: intermediate 22876947451fSStefano Zampini 22881cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()` 22896947451fSStefano Zampini @*/ 2290d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArrayWrite(Mat A, PetscScalar **array) 2291d71ae5a4SJacob Faibussowitsch { 22926947451fSStefano Zampini PetscFunctionBegin; 2293d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22944f572ea9SToby Isaac if (array) PetscAssertPointer(array, 2); 2295cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array)); 22969566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)A)); 229747d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 22986947451fSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 22996947451fSStefano Zampini #endif 23003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23016947451fSStefano Zampini } 23026947451fSStefano Zampini 2303cd3f9d89SJunchao Zhang /*@C 2304cd3f9d89SJunchao Zhang MatDenseGetArrayAndMemType - gives read-write access to the array where the data for a `MATDENSE` matrix is stored 2305cd3f9d89SJunchao Zhang 2306cd3f9d89SJunchao Zhang Logically Collective 2307cd3f9d89SJunchao Zhang 2308cd3f9d89SJunchao Zhang Input Parameter: 2309fe59aa6dSJacob Faibussowitsch . A - a dense matrix 2310cd3f9d89SJunchao Zhang 2311cd3f9d89SJunchao Zhang Output Parameters: 2312cd3f9d89SJunchao Zhang + array - pointer to the data 2313cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer 2314cd3f9d89SJunchao Zhang 2315cd3f9d89SJunchao Zhang Level: intermediate 2316cd3f9d89SJunchao Zhang 2317fb850c59SBarry Smith Note: 23182ef1f0ffSBarry Smith If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc., 23192ef1f0ffSBarry Smith an array on device is always returned and is guaranteed to contain the matrix's latest data. 23202ef1f0ffSBarry Smith 23211cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayAndMemType()`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArrayWriteAndMemType()`, `MatDenseGetArrayRead()`, 2322cd3f9d89SJunchao Zhang `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()` 2323cd3f9d89SJunchao Zhang @*/ 2324cd3f9d89SJunchao Zhang PetscErrorCode MatDenseGetArrayAndMemType(Mat A, PetscScalar **array, PetscMemType *mtype) 2325cd3f9d89SJunchao Zhang { 2326cd3f9d89SJunchao Zhang PetscBool isMPI; 2327cd3f9d89SJunchao Zhang 2328cd3f9d89SJunchao Zhang PetscFunctionBegin; 2329cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 23304f572ea9SToby Isaac PetscAssertPointer(array, 2); 2331e865de01SJunchao 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 */ 2332cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2333cd3f9d89SJunchao Zhang if (isMPI) { 2334cd3f9d89SJunchao Zhang /* Dispatch here so that the code can be reused for all subclasses of MATDENSE */ 2335cd3f9d89SJunchao Zhang PetscCall(MatDenseGetArrayAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype)); 2336cd3f9d89SJunchao Zhang } else { 2337cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **, PetscMemType *); 23383ba16761SJacob Faibussowitsch 23393ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayAndMemType_C", &fptr)); 2340cd3f9d89SJunchao Zhang if (fptr) { 2341cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array, mtype)); 2342cd3f9d89SJunchao Zhang } else { 2343cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array)); 2344cd3f9d89SJunchao Zhang if (mtype) *mtype = PETSC_MEMTYPE_HOST; 2345cd3f9d89SJunchao Zhang } 2346cd3f9d89SJunchao Zhang } 23473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2348cd3f9d89SJunchao Zhang } 2349cd3f9d89SJunchao Zhang 2350cd3f9d89SJunchao Zhang /*@C 2351cd3f9d89SJunchao Zhang MatDenseRestoreArrayAndMemType - returns access to the array that is obtained by `MatDenseGetArrayAndMemType()` 2352cd3f9d89SJunchao Zhang 2353cd3f9d89SJunchao Zhang Logically Collective 2354cd3f9d89SJunchao Zhang 2355cd3f9d89SJunchao Zhang Input Parameters: 2356fe59aa6dSJacob Faibussowitsch + A - a dense matrix 2357cd3f9d89SJunchao Zhang - array - pointer to the data 2358cd3f9d89SJunchao Zhang 2359cd3f9d89SJunchao Zhang Level: intermediate 2360cd3f9d89SJunchao Zhang 23611cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 2362cd3f9d89SJunchao Zhang @*/ 2363cd3f9d89SJunchao Zhang PetscErrorCode MatDenseRestoreArrayAndMemType(Mat A, PetscScalar **array) 2364cd3f9d89SJunchao Zhang { 2365cd3f9d89SJunchao Zhang PetscBool isMPI; 2366cd3f9d89SJunchao Zhang 2367cd3f9d89SJunchao Zhang PetscFunctionBegin; 2368cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 23694f572ea9SToby Isaac PetscAssertPointer(array, 2); 2370cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2371cd3f9d89SJunchao Zhang if (isMPI) { 2372cd3f9d89SJunchao Zhang PetscCall(MatDenseRestoreArrayAndMemType(((Mat_MPIDense *)A->data)->A, array)); 2373cd3f9d89SJunchao Zhang } else { 2374cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **); 23753ba16761SJacob Faibussowitsch 23763ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayAndMemType_C", &fptr)); 2377cd3f9d89SJunchao Zhang if (fptr) { 2378cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array)); 2379cd3f9d89SJunchao Zhang } else { 2380cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array)); 2381cd3f9d89SJunchao Zhang } 2382cd3f9d89SJunchao Zhang *array = NULL; 2383cd3f9d89SJunchao Zhang } 2384cd3f9d89SJunchao Zhang PetscCall(PetscObjectStateIncrease((PetscObject)A)); 23853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2386cd3f9d89SJunchao Zhang } 2387cd3f9d89SJunchao Zhang 2388cd3f9d89SJunchao Zhang /*@C 2389cd3f9d89SJunchao Zhang MatDenseGetArrayReadAndMemType - gives read-only access to the array where the data for a `MATDENSE` matrix is stored 2390cd3f9d89SJunchao Zhang 2391cd3f9d89SJunchao Zhang Logically Collective 2392cd3f9d89SJunchao Zhang 2393cd3f9d89SJunchao Zhang Input Parameter: 2394fe59aa6dSJacob Faibussowitsch . A - a dense matrix 2395cd3f9d89SJunchao Zhang 2396cd3f9d89SJunchao Zhang Output Parameters: 2397cd3f9d89SJunchao Zhang + array - pointer to the data 2398cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer 2399cd3f9d89SJunchao Zhang 2400cd3f9d89SJunchao Zhang Level: intermediate 2401cd3f9d89SJunchao Zhang 2402fb850c59SBarry Smith Note: 24032ef1f0ffSBarry Smith If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc., 24042ef1f0ffSBarry Smith an array on device is always returned and is guaranteed to contain the matrix's latest data. 24052ef1f0ffSBarry Smith 24061cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayReadAndMemType()`, `MatDenseGetArrayWriteAndMemType()`, 2407cd3f9d89SJunchao Zhang `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()` 2408cd3f9d89SJunchao Zhang @*/ 2409cd3f9d89SJunchao Zhang PetscErrorCode MatDenseGetArrayReadAndMemType(Mat A, const PetscScalar **array, PetscMemType *mtype) 2410cd3f9d89SJunchao Zhang { 2411cd3f9d89SJunchao Zhang PetscBool isMPI; 2412cd3f9d89SJunchao Zhang 2413cd3f9d89SJunchao Zhang PetscFunctionBegin; 2414cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 24154f572ea9SToby Isaac PetscAssertPointer(array, 2); 2416e865de01SJunchao 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 */ 2417cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2418cd3f9d89SJunchao Zhang if (isMPI) { /* Dispatch here so that the code can be reused for all subclasses of MATDENSE */ 2419cd3f9d89SJunchao Zhang PetscCall(MatDenseGetArrayReadAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype)); 2420cd3f9d89SJunchao Zhang } else { 2421cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, const PetscScalar **, PetscMemType *); 24223ba16761SJacob Faibussowitsch 24233ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayReadAndMemType_C", &fptr)); 2424cd3f9d89SJunchao Zhang if (fptr) { 2425cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array, mtype)); 2426cd3f9d89SJunchao Zhang } else { 24275c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 2428cd3f9d89SJunchao Zhang if (mtype) *mtype = PETSC_MEMTYPE_HOST; 2429cd3f9d89SJunchao Zhang } 2430cd3f9d89SJunchao Zhang } 24313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2432cd3f9d89SJunchao Zhang } 2433cd3f9d89SJunchao Zhang 2434cd3f9d89SJunchao Zhang /*@C 2435cd3f9d89SJunchao Zhang MatDenseRestoreArrayReadAndMemType - returns access to the array that is obtained by `MatDenseGetArrayReadAndMemType()` 2436cd3f9d89SJunchao Zhang 2437cd3f9d89SJunchao Zhang Logically Collective 2438cd3f9d89SJunchao Zhang 2439cd3f9d89SJunchao Zhang Input Parameters: 2440fe59aa6dSJacob Faibussowitsch + A - a dense matrix 2441cd3f9d89SJunchao Zhang - array - pointer to the data 2442cd3f9d89SJunchao Zhang 2443cd3f9d89SJunchao Zhang Level: intermediate 2444cd3f9d89SJunchao Zhang 24451cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 2446cd3f9d89SJunchao Zhang @*/ 2447cd3f9d89SJunchao Zhang PetscErrorCode MatDenseRestoreArrayReadAndMemType(Mat A, const PetscScalar **array) 2448cd3f9d89SJunchao Zhang { 2449cd3f9d89SJunchao Zhang PetscBool isMPI; 2450cd3f9d89SJunchao Zhang 2451cd3f9d89SJunchao Zhang PetscFunctionBegin; 2452cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 24534f572ea9SToby Isaac PetscAssertPointer(array, 2); 2454cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2455cd3f9d89SJunchao Zhang if (isMPI) { 2456cd3f9d89SJunchao Zhang PetscCall(MatDenseRestoreArrayReadAndMemType(((Mat_MPIDense *)A->data)->A, array)); 2457cd3f9d89SJunchao Zhang } else { 2458cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, const PetscScalar **); 24593ba16761SJacob Faibussowitsch 24603ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayReadAndMemType_C", &fptr)); 2461cd3f9d89SJunchao Zhang if (fptr) { 2462cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array)); 2463cd3f9d89SJunchao Zhang } else { 24645c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 2465cd3f9d89SJunchao Zhang } 2466cd3f9d89SJunchao Zhang *array = NULL; 2467cd3f9d89SJunchao Zhang } 24683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2469cd3f9d89SJunchao Zhang } 2470cd3f9d89SJunchao Zhang 2471cd3f9d89SJunchao Zhang /*@C 2472cd3f9d89SJunchao Zhang MatDenseGetArrayWriteAndMemType - gives write-only access to the array where the data for a `MATDENSE` matrix is stored 2473cd3f9d89SJunchao Zhang 2474cd3f9d89SJunchao Zhang Logically Collective 2475cd3f9d89SJunchao Zhang 2476cd3f9d89SJunchao Zhang Input Parameter: 2477fe59aa6dSJacob Faibussowitsch . A - a dense matrix 2478cd3f9d89SJunchao Zhang 2479cd3f9d89SJunchao Zhang Output Parameters: 2480cd3f9d89SJunchao Zhang + array - pointer to the data 2481cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer 2482cd3f9d89SJunchao Zhang 2483cd3f9d89SJunchao Zhang Level: intermediate 2484cd3f9d89SJunchao Zhang 2485fb850c59SBarry Smith Note: 24862ef1f0ffSBarry Smith If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc., 24872ef1f0ffSBarry Smith an array on device is always returned and is guaranteed to contain the matrix's latest data. 24882ef1f0ffSBarry Smith 24891cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayWriteAndMemType()`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArrayRead()`, 2490cd3f9d89SJunchao Zhang `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()` 2491cd3f9d89SJunchao Zhang @*/ 2492cd3f9d89SJunchao Zhang PetscErrorCode MatDenseGetArrayWriteAndMemType(Mat A, PetscScalar **array, PetscMemType *mtype) 2493cd3f9d89SJunchao Zhang { 2494cd3f9d89SJunchao Zhang PetscBool isMPI; 2495cd3f9d89SJunchao Zhang 2496cd3f9d89SJunchao Zhang PetscFunctionBegin; 2497cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 24984f572ea9SToby Isaac PetscAssertPointer(array, 2); 2499e865de01SJunchao 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 */ 2500cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2501cd3f9d89SJunchao Zhang if (isMPI) { 2502cd3f9d89SJunchao Zhang PetscCall(MatDenseGetArrayWriteAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype)); 2503cd3f9d89SJunchao Zhang } else { 2504cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **, PetscMemType *); 25053ba16761SJacob Faibussowitsch 25063ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayWriteAndMemType_C", &fptr)); 2507cd3f9d89SJunchao Zhang if (fptr) { 2508cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array, mtype)); 2509cd3f9d89SJunchao Zhang } else { 2510cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array)); 2511cd3f9d89SJunchao Zhang if (mtype) *mtype = PETSC_MEMTYPE_HOST; 2512cd3f9d89SJunchao Zhang } 2513cd3f9d89SJunchao Zhang } 25143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2515cd3f9d89SJunchao Zhang } 2516cd3f9d89SJunchao Zhang 2517cd3f9d89SJunchao Zhang /*@C 2518cd3f9d89SJunchao Zhang MatDenseRestoreArrayWriteAndMemType - returns access to the array that is obtained by `MatDenseGetArrayReadAndMemType()` 2519cd3f9d89SJunchao Zhang 2520cd3f9d89SJunchao Zhang Logically Collective 2521cd3f9d89SJunchao Zhang 2522cd3f9d89SJunchao Zhang Input Parameters: 2523fe59aa6dSJacob Faibussowitsch + A - a dense matrix 2524cd3f9d89SJunchao Zhang - array - pointer to the data 2525cd3f9d89SJunchao Zhang 2526cd3f9d89SJunchao Zhang Level: intermediate 2527cd3f9d89SJunchao Zhang 25281cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayWriteAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 2529cd3f9d89SJunchao Zhang @*/ 2530cd3f9d89SJunchao Zhang PetscErrorCode MatDenseRestoreArrayWriteAndMemType(Mat A, PetscScalar **array) 2531cd3f9d89SJunchao Zhang { 2532cd3f9d89SJunchao Zhang PetscBool isMPI; 2533cd3f9d89SJunchao Zhang 2534cd3f9d89SJunchao Zhang PetscFunctionBegin; 2535cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 25364f572ea9SToby Isaac PetscAssertPointer(array, 2); 2537cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2538cd3f9d89SJunchao Zhang if (isMPI) { 2539cd3f9d89SJunchao Zhang PetscCall(MatDenseRestoreArrayWriteAndMemType(((Mat_MPIDense *)A->data)->A, array)); 2540cd3f9d89SJunchao Zhang } else { 2541cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **); 25423ba16761SJacob Faibussowitsch 25433ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayWriteAndMemType_C", &fptr)); 2544cd3f9d89SJunchao Zhang if (fptr) { 2545cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array)); 2546cd3f9d89SJunchao Zhang } else { 2547cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array)); 2548cd3f9d89SJunchao Zhang } 2549cd3f9d89SJunchao Zhang *array = NULL; 2550cd3f9d89SJunchao Zhang } 2551cd3f9d89SJunchao Zhang PetscCall(PetscObjectStateIncrease((PetscObject)A)); 25523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2553cd3f9d89SJunchao Zhang } 2554cd3f9d89SJunchao Zhang 2555d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A, IS isrow, IS iscol, MatReuse scall, Mat *B) 2556d71ae5a4SJacob Faibussowitsch { 2557c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 2558bf5a80bcSToby Isaac PetscInt i, j, nrows, ncols, ldb; 25595d0c19d7SBarry Smith const PetscInt *irow, *icol; 256087828ca2SBarry Smith PetscScalar *av, *bv, *v = mat->v; 25610754003eSLois Curfman McInnes Mat newmat; 25620754003eSLois Curfman McInnes 25633a40ed3dSBarry Smith PetscFunctionBegin; 25649566063dSJacob Faibussowitsch PetscCall(ISGetIndices(isrow, &irow)); 25659566063dSJacob Faibussowitsch PetscCall(ISGetIndices(iscol, &icol)); 25669566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(isrow, &nrows)); 25679566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(iscol, &ncols)); 25680754003eSLois Curfman McInnes 2569182d2002SSatish Balay /* Check submatrixcall */ 2570182d2002SSatish Balay if (scall == MAT_REUSE_MATRIX) { 257113f74950SBarry Smith PetscInt n_cols, n_rows; 25729566063dSJacob Faibussowitsch PetscCall(MatGetSize(*B, &n_rows, &n_cols)); 257321a2c019SBarry Smith if (n_rows != nrows || n_cols != ncols) { 2574f746d493SDmitry Karpeev /* resize the result matrix to match number of requested rows/columns */ 25759566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*B, nrows, ncols, nrows, ncols)); 257621a2c019SBarry Smith } 2577182d2002SSatish Balay newmat = *B; 2578182d2002SSatish Balay } else { 25790754003eSLois Curfman McInnes /* Create and fill new matrix */ 25809566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &newmat)); 25819566063dSJacob Faibussowitsch PetscCall(MatSetSizes(newmat, nrows, ncols, nrows, ncols)); 25829566063dSJacob Faibussowitsch PetscCall(MatSetType(newmat, ((PetscObject)A)->type_name)); 25839566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(newmat, NULL)); 2584182d2002SSatish Balay } 2585182d2002SSatish Balay 2586182d2002SSatish Balay /* Now extract the data pointers and do the copy,column at a time */ 25879566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(newmat, &bv)); 25889566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(newmat, &ldb)); 2589182d2002SSatish Balay for (i = 0; i < ncols; i++) { 25906de62eeeSBarry Smith av = v + mat->lda * icol[i]; 2591ca15aa20SStefano Zampini for (j = 0; j < nrows; j++) bv[j] = av[irow[j]]; 2592bf5a80bcSToby Isaac bv += ldb; 25930754003eSLois Curfman McInnes } 25949566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(newmat, &bv)); 2595182d2002SSatish Balay 2596182d2002SSatish Balay /* Assemble the matrices so that the correct flags are set */ 25979566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(newmat, MAT_FINAL_ASSEMBLY)); 25989566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(newmat, MAT_FINAL_ASSEMBLY)); 25990754003eSLois Curfman McInnes 26000754003eSLois Curfman McInnes /* Free work space */ 26019566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(isrow, &irow)); 26029566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(iscol, &icol)); 2603182d2002SSatish Balay *B = newmat; 26043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26050754003eSLois Curfman McInnes } 26060754003eSLois Curfman McInnes 2607d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A, PetscInt n, const IS irow[], const IS icol[], MatReuse scall, Mat *B[]) 2608d71ae5a4SJacob Faibussowitsch { 260913f74950SBarry Smith PetscInt i; 2610905e6a2fSBarry Smith 26113a40ed3dSBarry Smith PetscFunctionBegin; 261248a46eb9SPierre Jolivet if (scall == MAT_INITIAL_MATRIX) PetscCall(PetscCalloc1(n, B)); 2613905e6a2fSBarry Smith 261448a46eb9SPierre Jolivet for (i = 0; i < n; i++) PetscCall(MatCreateSubMatrix_SeqDense(A, irow[i], icol[i], scall, &(*B)[i])); 26153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2616905e6a2fSBarry Smith } 2617905e6a2fSBarry Smith 2618d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat, MatAssemblyType mode) 2619d71ae5a4SJacob Faibussowitsch { 2620c0aa2d19SHong Zhang PetscFunctionBegin; 26213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2622c0aa2d19SHong Zhang } 2623c0aa2d19SHong Zhang 2624d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat, MatAssemblyType mode) 2625d71ae5a4SJacob Faibussowitsch { 2626c0aa2d19SHong Zhang PetscFunctionBegin; 26273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2628c0aa2d19SHong Zhang } 2629c0aa2d19SHong Zhang 2630d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCopy_SeqDense(Mat A, Mat B, MatStructure str) 2631d71ae5a4SJacob Faibussowitsch { 26324b0e389bSBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data; 2633ca15aa20SStefano Zampini const PetscScalar *va; 2634ca15aa20SStefano Zampini PetscScalar *vb; 2635d0f46423SBarry Smith PetscInt lda1 = a->lda, lda2 = b->lda, m = A->rmap->n, n = A->cmap->n, j; 26363a40ed3dSBarry Smith 26373a40ed3dSBarry Smith PetscFunctionBegin; 263833f4a19fSKris Buschelman /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */ 263933f4a19fSKris Buschelman if (A->ops->copy != B->ops->copy) { 26409566063dSJacob Faibussowitsch PetscCall(MatCopy_Basic(A, B, str)); 26413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26423a40ed3dSBarry Smith } 2643aed4548fSBarry Smith PetscCheck(m == B->rmap->n && n == B->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "size(B) != size(A)"); 26449566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &va)); 26459566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(B, &vb)); 2646a5ce6ee0Svictorle if (lda1 > m || lda2 > m) { 264748a46eb9SPierre Jolivet for (j = 0; j < n; j++) PetscCall(PetscArraycpy(vb + j * lda2, va + j * lda1, m)); 2648a5ce6ee0Svictorle } else { 26499566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(vb, va, A->rmap->n * A->cmap->n)); 2650a5ce6ee0Svictorle } 26519566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(B, &vb)); 26529566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &va)); 26539566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 26549566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 26553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2656273d9f13SBarry Smith } 2657273d9f13SBarry Smith 2658d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetUp_SeqDense(Mat A) 2659d71ae5a4SJacob Faibussowitsch { 2660273d9f13SBarry Smith PetscFunctionBegin; 26619566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 26629566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 266348a46eb9SPierre Jolivet if (!A->preallocated) PetscCall(MatSeqDenseSetPreallocation(A, NULL)); 26643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26654b0e389bSBarry Smith } 26664b0e389bSBarry Smith 2667d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatConjugate_SeqDense(Mat A) 2668d71ae5a4SJacob Faibussowitsch { 26694396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 267006c5243aSJose E. Roman PetscInt i, j; 26714396437dSToby Isaac PetscInt min = PetscMin(A->rmap->n, A->cmap->n); 2672ca15aa20SStefano Zampini PetscScalar *aa; 2673ba337c44SJed Brown 2674ba337c44SJed Brown PetscFunctionBegin; 26759566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 267606c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 267706c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscConj(aa[i + j * mat->lda]); 267806c5243aSJose E. Roman } 26799566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 26809371c9d4SSatish Balay if (mat->tau) 26819371c9d4SSatish Balay for (i = 0; i < min; i++) mat->tau[i] = PetscConj(mat->tau[i]); 26823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2683ba337c44SJed Brown } 2684ba337c44SJed Brown 2685d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRealPart_SeqDense(Mat A) 2686d71ae5a4SJacob Faibussowitsch { 268706c5243aSJose E. Roman Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 268806c5243aSJose E. Roman PetscInt i, j; 2689ca15aa20SStefano Zampini PetscScalar *aa; 2690ba337c44SJed Brown 2691ba337c44SJed Brown PetscFunctionBegin; 26929566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 269306c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 269406c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscRealPart(aa[i + j * mat->lda]); 269506c5243aSJose E. Roman } 26969566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 26973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2698ba337c44SJed Brown } 2699ba337c44SJed Brown 2700d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatImaginaryPart_SeqDense(Mat A) 2701d71ae5a4SJacob Faibussowitsch { 270206c5243aSJose E. Roman Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 270306c5243aSJose E. Roman PetscInt i, j; 2704ca15aa20SStefano Zampini PetscScalar *aa; 2705ba337c44SJed Brown 2706ba337c44SJed Brown PetscFunctionBegin; 27079566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 270806c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 270906c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscImaginaryPart(aa[i + j * mat->lda]); 271006c5243aSJose E. Roman } 27119566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 27123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2713ba337c44SJed Brown } 2714284134d9SBarry Smith 2715d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2716d71ae5a4SJacob Faibussowitsch { 2717d0f46423SBarry Smith PetscInt m = A->rmap->n, n = B->cmap->n; 271847d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 2719a9fe9ddaSSatish Balay 2720ee16a9a1SHong Zhang PetscFunctionBegin; 27219566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 272247d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 27239566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 272447d993e7Ssuyashtn #endif 272547d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 272647d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 272747d993e7Ssuyashtn #endif 27287a3c3d58SStefano Zampini if (!cisdense) { 27297a3c3d58SStefano Zampini PetscBool flg; 27307a3c3d58SStefano Zampini 27319566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 27329566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 27337a3c3d58SStefano Zampini } 27349566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 27353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2736ee16a9a1SHong Zhang } 2737a9fe9ddaSSatish Balay 2738d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2739d71ae5a4SJacob Faibussowitsch { 27406718818eSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data, *c = (Mat_SeqDense *)C->data; 27410805154bSBarry Smith PetscBLASInt m, n, k; 2742ca15aa20SStefano Zampini const PetscScalar *av, *bv; 2743ca15aa20SStefano Zampini PetscScalar *cv; 2744a9fe9ddaSSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 2745a9fe9ddaSSatish Balay 2746a9fe9ddaSSatish Balay PetscFunctionBegin; 27479566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 27489566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 27499566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 27503ba16761SJacob Faibussowitsch if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS); 27519566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 27529566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 27539566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2754792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("N", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 27559566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 27569566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 27579566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 27589566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 27593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2760a9fe9ddaSSatish Balay } 2761a9fe9ddaSSatish Balay 2762d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2763d71ae5a4SJacob Faibussowitsch { 276469f65d41SStefano Zampini PetscInt m = A->rmap->n, n = B->rmap->n; 276547d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 276669f65d41SStefano Zampini 276769f65d41SStefano Zampini PetscFunctionBegin; 27689566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 276947d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 27709566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 277147d993e7Ssuyashtn #endif 277247d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 277347d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 277447d993e7Ssuyashtn #endif 27757a3c3d58SStefano Zampini if (!cisdense) { 27767a3c3d58SStefano Zampini PetscBool flg; 27777a3c3d58SStefano Zampini 27789566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 27799566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 27807a3c3d58SStefano Zampini } 27819566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 27823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 278369f65d41SStefano Zampini } 278469f65d41SStefano Zampini 2785d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2786d71ae5a4SJacob Faibussowitsch { 278769f65d41SStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 278869f65d41SStefano Zampini Mat_SeqDense *b = (Mat_SeqDense *)B->data; 278969f65d41SStefano Zampini Mat_SeqDense *c = (Mat_SeqDense *)C->data; 27906718818eSStefano Zampini const PetscScalar *av, *bv; 27916718818eSStefano Zampini PetscScalar *cv; 279269f65d41SStefano Zampini PetscBLASInt m, n, k; 279369f65d41SStefano Zampini PetscScalar _DOne = 1.0, _DZero = 0.0; 279469f65d41SStefano Zampini 279569f65d41SStefano Zampini PetscFunctionBegin; 27969566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 27979566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 27989566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 27993ba16761SJacob Faibussowitsch if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS); 28009566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 28019566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 28029566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2803792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("N", "T", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 28049566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 28059566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 28069566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 28079566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 28083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 280969f65d41SStefano Zampini } 281069f65d41SStefano Zampini 2811d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2812d71ae5a4SJacob Faibussowitsch { 2813d0f46423SBarry Smith PetscInt m = A->cmap->n, n = B->cmap->n; 281447d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 2815a9fe9ddaSSatish Balay 2816ee16a9a1SHong Zhang PetscFunctionBegin; 28179566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 281847d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 28199566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 282047d993e7Ssuyashtn #endif 282147d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 282247d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 282347d993e7Ssuyashtn #endif 28247a3c3d58SStefano Zampini if (!cisdense) { 28257a3c3d58SStefano Zampini PetscBool flg; 28267a3c3d58SStefano Zampini 28279566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 28289566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 28297a3c3d58SStefano Zampini } 28309566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 28313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2832ee16a9a1SHong Zhang } 2833a9fe9ddaSSatish Balay 2834d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2835d71ae5a4SJacob Faibussowitsch { 2836a9fe9ddaSSatish Balay Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2837a9fe9ddaSSatish Balay Mat_SeqDense *b = (Mat_SeqDense *)B->data; 2838a9fe9ddaSSatish Balay Mat_SeqDense *c = (Mat_SeqDense *)C->data; 28396718818eSStefano Zampini const PetscScalar *av, *bv; 28406718818eSStefano Zampini PetscScalar *cv; 28410805154bSBarry Smith PetscBLASInt m, n, k; 2842a9fe9ddaSSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 2843a9fe9ddaSSatish Balay 2844a9fe9ddaSSatish Balay PetscFunctionBegin; 28459566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 28469566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 28479566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &k)); 28483ba16761SJacob Faibussowitsch if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS); 28499566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 28509566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 28519566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2852792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("T", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 28539566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 28549566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 28559566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 28569566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 28573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2858a9fe9ddaSSatish Balay } 2859985db425SBarry Smith 2860d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C) 2861d71ae5a4SJacob Faibussowitsch { 28624222ddf1SHong Zhang PetscFunctionBegin; 28634222ddf1SHong Zhang C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense; 28644222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AB; 28653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28664222ddf1SHong Zhang } 28674222ddf1SHong Zhang 2868d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C) 2869d71ae5a4SJacob Faibussowitsch { 28704222ddf1SHong Zhang PetscFunctionBegin; 28714222ddf1SHong Zhang C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense; 28724222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AtB; 28733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28744222ddf1SHong Zhang } 28754222ddf1SHong Zhang 2876d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C) 2877d71ae5a4SJacob Faibussowitsch { 28784222ddf1SHong Zhang PetscFunctionBegin; 28794222ddf1SHong Zhang C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense; 28804222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_ABt; 28813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28824222ddf1SHong Zhang } 28834222ddf1SHong Zhang 2884d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C) 2885d71ae5a4SJacob Faibussowitsch { 28864222ddf1SHong Zhang Mat_Product *product = C->product; 28874222ddf1SHong Zhang 28884222ddf1SHong Zhang PetscFunctionBegin; 28894222ddf1SHong Zhang switch (product->type) { 2890d71ae5a4SJacob Faibussowitsch case MATPRODUCT_AB: 2891d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_AB(C)); 2892d71ae5a4SJacob Faibussowitsch break; 2893d71ae5a4SJacob Faibussowitsch case MATPRODUCT_AtB: 2894d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_AtB(C)); 2895d71ae5a4SJacob Faibussowitsch break; 2896d71ae5a4SJacob Faibussowitsch case MATPRODUCT_ABt: 2897d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_ABt(C)); 2898d71ae5a4SJacob Faibussowitsch break; 2899d71ae5a4SJacob Faibussowitsch default: 2900d71ae5a4SJacob Faibussowitsch break; 29014222ddf1SHong Zhang } 29023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29034222ddf1SHong Zhang } 29044222ddf1SHong Zhang 2905d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMax_SeqDense(Mat A, Vec v, PetscInt idx[]) 2906d71ae5a4SJacob Faibussowitsch { 2907985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2908d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2909985db425SBarry Smith PetscScalar *x; 2910ca15aa20SStefano Zampini const PetscScalar *aa; 2911985db425SBarry Smith 2912985db425SBarry Smith PetscFunctionBegin; 291328b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29149566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29159566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 29169566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 291708401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2918985db425SBarry Smith for (i = 0; i < m; i++) { 29199371c9d4SSatish Balay x[i] = aa[i]; 29209371c9d4SSatish Balay if (idx) idx[i] = 0; 2921985db425SBarry Smith for (j = 1; j < n; j++) { 29229371c9d4SSatish Balay if (PetscRealPart(x[i]) < PetscRealPart(aa[i + a->lda * j])) { 29239371c9d4SSatish Balay x[i] = aa[i + a->lda * j]; 29249371c9d4SSatish Balay if (idx) idx[i] = j; 29259371c9d4SSatish Balay } 2926985db425SBarry Smith } 2927985db425SBarry Smith } 29289566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 29299566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 29303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2931985db425SBarry Smith } 2932985db425SBarry Smith 2933d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A, Vec v, PetscInt idx[]) 2934d71ae5a4SJacob Faibussowitsch { 2935985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2936d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2937985db425SBarry Smith PetscScalar *x; 2938985db425SBarry Smith PetscReal atmp; 2939ca15aa20SStefano Zampini const PetscScalar *aa; 2940985db425SBarry Smith 2941985db425SBarry Smith PetscFunctionBegin; 294228b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29439566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29449566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 29459566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 294608401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2947985db425SBarry Smith for (i = 0; i < m; i++) { 29489189402eSHong Zhang x[i] = PetscAbsScalar(aa[i]); 2949985db425SBarry Smith for (j = 1; j < n; j++) { 2950ca15aa20SStefano Zampini atmp = PetscAbsScalar(aa[i + a->lda * j]); 29519371c9d4SSatish Balay if (PetscAbsScalar(x[i]) < atmp) { 29529371c9d4SSatish Balay x[i] = atmp; 29539371c9d4SSatish Balay if (idx) idx[i] = j; 29549371c9d4SSatish Balay } 2955985db425SBarry Smith } 2956985db425SBarry Smith } 29579566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 29589566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 29593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2960985db425SBarry Smith } 2961985db425SBarry Smith 2962d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMin_SeqDense(Mat A, Vec v, PetscInt idx[]) 2963d71ae5a4SJacob Faibussowitsch { 2964985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2965d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2966985db425SBarry Smith PetscScalar *x; 2967ca15aa20SStefano Zampini const PetscScalar *aa; 2968985db425SBarry Smith 2969985db425SBarry Smith PetscFunctionBegin; 297028b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29719566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 29729566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29739566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 297408401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2975985db425SBarry Smith for (i = 0; i < m; i++) { 29769371c9d4SSatish Balay x[i] = aa[i]; 29779371c9d4SSatish Balay if (idx) idx[i] = 0; 2978985db425SBarry Smith for (j = 1; j < n; j++) { 29799371c9d4SSatish Balay if (PetscRealPart(x[i]) > PetscRealPart(aa[i + a->lda * j])) { 29809371c9d4SSatish Balay x[i] = aa[i + a->lda * j]; 29819371c9d4SSatish Balay if (idx) idx[i] = j; 29829371c9d4SSatish Balay } 2983985db425SBarry Smith } 2984985db425SBarry Smith } 29859566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 29869566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 29873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2988985db425SBarry Smith } 2989985db425SBarry Smith 2990d71ae5a4SJacob Faibussowitsch PetscErrorCode MatGetColumnVector_SeqDense(Mat A, Vec v, PetscInt col) 2991d71ae5a4SJacob Faibussowitsch { 29928d0534beSBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 29938d0534beSBarry Smith PetscScalar *x; 2994ca15aa20SStefano Zampini const PetscScalar *aa; 29958d0534beSBarry Smith 29968d0534beSBarry Smith PetscFunctionBegin; 299728b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29989566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 29999566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 30009566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(x, aa + col * a->lda, A->rmap->n)); 30019566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 30029566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 30033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30048d0534beSBarry Smith } 30058d0534beSBarry Smith 3006d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatGetColumnReductions_SeqDense(Mat A, PetscInt type, PetscReal *reductions) 3007d71ae5a4SJacob Faibussowitsch { 30080716a85fSBarry Smith PetscInt i, j, m, n; 30091683a169SBarry Smith const PetscScalar *a; 30100716a85fSBarry Smith 30110716a85fSBarry Smith PetscFunctionBegin; 30129566063dSJacob Faibussowitsch PetscCall(MatGetSize(A, &m, &n)); 30139566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(reductions, n)); 30149566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &a)); 3015857cbf51SRichard Tran Mills if (type == NORM_2) { 30160716a85fSBarry Smith for (i = 0; i < n; i++) { 3017ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j] * a[j]); 301816cd844bSPierre Jolivet a = PetscSafePointerPlusOffset(a, m); 30190716a85fSBarry Smith } 3020857cbf51SRichard Tran Mills } else if (type == NORM_1) { 30210716a85fSBarry Smith for (i = 0; i < n; i++) { 3022ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j]); 302316cd844bSPierre Jolivet a = PetscSafePointerPlusOffset(a, m); 30240716a85fSBarry Smith } 3025857cbf51SRichard Tran Mills } else if (type == NORM_INFINITY) { 30260716a85fSBarry Smith for (i = 0; i < n; i++) { 3027ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] = PetscMax(PetscAbsScalar(a[j]), reductions[i]); 302816cd844bSPierre Jolivet a = PetscSafePointerPlusOffset(a, m); 30290716a85fSBarry Smith } 3030857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_REALPART || type == REDUCTION_MEAN_REALPART) { 3031a873a8cdSSam Reynolds for (i = 0; i < n; i++) { 3032ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscRealPart(a[j]); 303316cd844bSPierre Jolivet a = PetscSafePointerPlusOffset(a, m); 3034a873a8cdSSam Reynolds } 3035857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_IMAGINARYPART || type == REDUCTION_MEAN_IMAGINARYPART) { 3036857cbf51SRichard Tran Mills for (i = 0; i < n; i++) { 3037ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscImaginaryPart(a[j]); 303816cd844bSPierre Jolivet a = PetscSafePointerPlusOffset(a, m); 3039857cbf51SRichard Tran Mills } 3040857cbf51SRichard Tran Mills } else SETERRQ(PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Unknown reduction type"); 30419566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &a)); 3042857cbf51SRichard Tran Mills if (type == NORM_2) { 3043a873a8cdSSam Reynolds for (i = 0; i < n; i++) reductions[i] = PetscSqrtReal(reductions[i]); 3044857cbf51SRichard Tran Mills } else if (type == REDUCTION_MEAN_REALPART || type == REDUCTION_MEAN_IMAGINARYPART) { 3045a873a8cdSSam Reynolds for (i = 0; i < n; i++) reductions[i] /= m; 30460716a85fSBarry Smith } 30473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30480716a85fSBarry Smith } 30490716a85fSBarry Smith 3050d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetRandom_SeqDense(Mat x, PetscRandom rctx) 3051d71ae5a4SJacob Faibussowitsch { 305273a71a0fSBarry Smith PetscScalar *a; 3053637a0070SStefano Zampini PetscInt lda, m, n, i, j; 305473a71a0fSBarry Smith 305573a71a0fSBarry Smith PetscFunctionBegin; 30569566063dSJacob Faibussowitsch PetscCall(MatGetSize(x, &m, &n)); 30579566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(x, &lda)); 30583faff063SStefano Zampini PetscCall(MatDenseGetArrayWrite(x, &a)); 3059637a0070SStefano Zampini for (j = 0; j < n; j++) { 306048a46eb9SPierre Jolivet for (i = 0; i < m; i++) PetscCall(PetscRandomGetValue(rctx, a + j * lda + i)); 306173a71a0fSBarry Smith } 30623faff063SStefano Zampini PetscCall(MatDenseRestoreArrayWrite(x, &a)); 30633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 306473a71a0fSBarry Smith } 306573a71a0fSBarry Smith 3066d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A, PetscBool *missing, PetscInt *d) 3067d71ae5a4SJacob Faibussowitsch { 30683b49f96aSBarry Smith PetscFunctionBegin; 30693b49f96aSBarry Smith *missing = PETSC_FALSE; 30703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30713b49f96aSBarry Smith } 307273a71a0fSBarry Smith 3073ca15aa20SStefano Zampini /* vals is not const */ 3074d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A, PetscInt col, PetscScalar **vals) 3075d71ae5a4SJacob Faibussowitsch { 307686aefd0dSHong Zhang Mat_SeqDense *a = (Mat_SeqDense *)A->data; 3077ca15aa20SStefano Zampini PetscScalar *v; 307886aefd0dSHong Zhang 307986aefd0dSHong Zhang PetscFunctionBegin; 308028b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 30819566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 3082ca15aa20SStefano Zampini *vals = v + col * a->lda; 30839566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 30843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 308586aefd0dSHong Zhang } 308686aefd0dSHong Zhang 3087d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A, PetscScalar **vals) 3088d71ae5a4SJacob Faibussowitsch { 308986aefd0dSHong Zhang PetscFunctionBegin; 3090742765d3SMatthew Knepley if (vals) *vals = NULL; /* user cannot accidentally use the array later */ 30913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 309286aefd0dSHong Zhang } 3093abc3b08eSStefano Zampini 3094a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqDense, 3095905e6a2fSBarry Smith MatGetRow_SeqDense, 3096905e6a2fSBarry Smith MatRestoreRow_SeqDense, 3097905e6a2fSBarry Smith MatMult_SeqDense, 309897304618SKris Buschelman /* 4*/ MatMultAdd_SeqDense, 30997c922b88SBarry Smith MatMultTranspose_SeqDense, 31007c922b88SBarry Smith MatMultTransposeAdd_SeqDense, 3101f4259b30SLisandro Dalcin NULL, 3102f4259b30SLisandro Dalcin NULL, 3103f4259b30SLisandro Dalcin NULL, 3104f4259b30SLisandro Dalcin /* 10*/ NULL, 3105905e6a2fSBarry Smith MatLUFactor_SeqDense, 3106905e6a2fSBarry Smith MatCholeskyFactor_SeqDense, 310741f059aeSBarry Smith MatSOR_SeqDense, 3108ec8511deSBarry Smith MatTranspose_SeqDense, 310997304618SKris Buschelman /* 15*/ MatGetInfo_SeqDense, 3110905e6a2fSBarry Smith MatEqual_SeqDense, 3111905e6a2fSBarry Smith MatGetDiagonal_SeqDense, 3112905e6a2fSBarry Smith MatDiagonalScale_SeqDense, 3113905e6a2fSBarry Smith MatNorm_SeqDense, 3114c0aa2d19SHong Zhang /* 20*/ MatAssemblyBegin_SeqDense, 3115c0aa2d19SHong Zhang MatAssemblyEnd_SeqDense, 3116905e6a2fSBarry Smith MatSetOption_SeqDense, 3117905e6a2fSBarry Smith MatZeroEntries_SeqDense, 3118d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqDense, 3119f4259b30SLisandro Dalcin NULL, 3120f4259b30SLisandro Dalcin NULL, 3121f4259b30SLisandro Dalcin NULL, 3122f4259b30SLisandro Dalcin NULL, 31234994cf47SJed Brown /* 29*/ MatSetUp_SeqDense, 3124f4259b30SLisandro Dalcin NULL, 3125f4259b30SLisandro Dalcin NULL, 3126f4259b30SLisandro Dalcin NULL, 3127f4259b30SLisandro Dalcin NULL, 3128d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqDense, 3129f4259b30SLisandro Dalcin NULL, 3130f4259b30SLisandro Dalcin NULL, 3131f4259b30SLisandro Dalcin NULL, 3132f4259b30SLisandro Dalcin NULL, 3133d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqDense, 31347dae84e0SHong Zhang MatCreateSubMatrices_SeqDense, 3135f4259b30SLisandro Dalcin NULL, 31364b0e389bSBarry Smith MatGetValues_SeqDense, 3137a5ae1ecdSBarry Smith MatCopy_SeqDense, 3138d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqDense, 3139a5ae1ecdSBarry Smith MatScale_SeqDense, 31402f605a99SJose E. Roman MatShift_SeqDense, 3141f4259b30SLisandro Dalcin NULL, 31423f49a652SStefano Zampini MatZeroRowsColumns_SeqDense, 314373a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqDense, 3144f4259b30SLisandro Dalcin NULL, 3145f4259b30SLisandro Dalcin NULL, 3146f4259b30SLisandro Dalcin NULL, 3147f4259b30SLisandro Dalcin NULL, 3148f4259b30SLisandro Dalcin /* 54*/ NULL, 3149f4259b30SLisandro Dalcin NULL, 3150f4259b30SLisandro Dalcin NULL, 3151f4259b30SLisandro Dalcin NULL, 3152f4259b30SLisandro Dalcin NULL, 3153023c16fcSToby Isaac /* 59*/ MatCreateSubMatrix_SeqDense, 3154e03a110bSBarry Smith MatDestroy_SeqDense, 3155e03a110bSBarry Smith MatView_SeqDense, 3156f4259b30SLisandro Dalcin NULL, 3157f4259b30SLisandro Dalcin NULL, 3158f4259b30SLisandro Dalcin /* 64*/ NULL, 3159f4259b30SLisandro Dalcin NULL, 3160f4259b30SLisandro Dalcin NULL, 3161f4259b30SLisandro Dalcin NULL, 3162f4259b30SLisandro Dalcin NULL, 3163d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqDense, 3164f4259b30SLisandro Dalcin NULL, 3165f4259b30SLisandro Dalcin NULL, 3166f4259b30SLisandro Dalcin NULL, 3167f4259b30SLisandro Dalcin NULL, 3168f4259b30SLisandro Dalcin /* 74*/ NULL, 3169f4259b30SLisandro Dalcin NULL, 3170f4259b30SLisandro Dalcin NULL, 3171f4259b30SLisandro Dalcin NULL, 3172f4259b30SLisandro Dalcin NULL, 3173f4259b30SLisandro Dalcin /* 79*/ NULL, 3174f4259b30SLisandro Dalcin NULL, 3175f4259b30SLisandro Dalcin NULL, 3176f4259b30SLisandro Dalcin NULL, 31775bba2384SShri Abhyankar /* 83*/ MatLoad_SeqDense, 3178637a0070SStefano Zampini MatIsSymmetric_SeqDense, 31791cbb95d3SBarry Smith MatIsHermitian_SeqDense, 3180f4259b30SLisandro Dalcin NULL, 3181f4259b30SLisandro Dalcin NULL, 3182f4259b30SLisandro Dalcin NULL, 3183f4259b30SLisandro Dalcin /* 89*/ NULL, 3184f4259b30SLisandro Dalcin NULL, 3185a9fe9ddaSSatish Balay MatMatMultNumeric_SeqDense_SeqDense, 3186f4259b30SLisandro Dalcin NULL, 3187f4259b30SLisandro Dalcin NULL, 3188f4259b30SLisandro Dalcin /* 94*/ NULL, 3189f4259b30SLisandro Dalcin NULL, 3190f4259b30SLisandro Dalcin NULL, 319169f65d41SStefano Zampini MatMatTransposeMultNumeric_SeqDense_SeqDense, 3192f4259b30SLisandro Dalcin NULL, 31934222ddf1SHong Zhang /* 99*/ MatProductSetFromOptions_SeqDense, 3194f4259b30SLisandro Dalcin NULL, 3195f4259b30SLisandro Dalcin NULL, 3196ba337c44SJed Brown MatConjugate_SeqDense, 3197f4259b30SLisandro Dalcin NULL, 3198f4259b30SLisandro Dalcin /*104*/ NULL, 3199ba337c44SJed Brown MatRealPart_SeqDense, 3200ba337c44SJed Brown MatImaginaryPart_SeqDense, 3201f4259b30SLisandro Dalcin NULL, 3202f4259b30SLisandro Dalcin NULL, 3203f4259b30SLisandro Dalcin /*109*/ NULL, 3204f4259b30SLisandro Dalcin NULL, 32058d0534beSBarry Smith MatGetRowMin_SeqDense, 3206aabbc4fbSShri Abhyankar MatGetColumnVector_SeqDense, 32073b49f96aSBarry Smith MatMissingDiagonal_SeqDense, 3208f4259b30SLisandro Dalcin /*114*/ NULL, 3209f4259b30SLisandro Dalcin NULL, 3210f4259b30SLisandro Dalcin NULL, 3211f4259b30SLisandro Dalcin NULL, 3212f4259b30SLisandro Dalcin NULL, 3213f4259b30SLisandro Dalcin /*119*/ NULL, 3214f4259b30SLisandro Dalcin NULL, 3215459e8d23SBlanca Mellado Pinto MatMultHermitianTranspose_SeqDense, 3216459e8d23SBlanca Mellado Pinto MatMultHermitianTransposeAdd_SeqDense, 3217f4259b30SLisandro Dalcin NULL, 3218f4259b30SLisandro Dalcin /*124*/ NULL, 3219a873a8cdSSam Reynolds MatGetColumnReductions_SeqDense, 3220f4259b30SLisandro Dalcin NULL, 3221f4259b30SLisandro Dalcin NULL, 3222f4259b30SLisandro Dalcin NULL, 3223f4259b30SLisandro Dalcin /*129*/ NULL, 3224f4259b30SLisandro Dalcin NULL, 3225f4259b30SLisandro Dalcin NULL, 322675648e8dSHong Zhang MatTransposeMatMultNumeric_SeqDense_SeqDense, 3227f4259b30SLisandro Dalcin NULL, 3228f4259b30SLisandro Dalcin /*134*/ NULL, 3229f4259b30SLisandro Dalcin NULL, 3230f4259b30SLisandro Dalcin NULL, 3231f4259b30SLisandro Dalcin NULL, 3232f4259b30SLisandro Dalcin NULL, 3233f4259b30SLisandro Dalcin /*139*/ NULL, 3234f4259b30SLisandro Dalcin NULL, 3235f4259b30SLisandro Dalcin NULL, 3236f4259b30SLisandro Dalcin NULL, 3237f4259b30SLisandro Dalcin NULL, 32384222ddf1SHong Zhang MatCreateMPIMatConcatenateSeqMat_SeqDense, 3239f4259b30SLisandro Dalcin /*145*/ NULL, 3240f4259b30SLisandro Dalcin NULL, 324199a7f59eSMark Adams NULL, 324299a7f59eSMark Adams NULL, 32437fb60732SBarry Smith NULL, 3244dec0b466SHong Zhang /*150*/ NULL, 3245eede4a3fSMark Adams NULL, 3246dec0b466SHong Zhang NULL}; 324790ace30eSBarry Smith 32484b828684SBarry Smith /*@C 324911a5261eSBarry Smith MatCreateSeqDense - Creates a `MATSEQDENSE` that 3250fb850c59SBarry Smith is stored in column major order (the usual Fortran format). 3251289bc588SBarry Smith 3252d083f849SBarry Smith Collective 3253db81eaa0SLois Curfman McInnes 325420563c6bSBarry Smith Input Parameters: 325511a5261eSBarry Smith + comm - MPI communicator, set to `PETSC_COMM_SELF` 32560c775827SLois Curfman McInnes . m - number of rows 325718f449edSLois Curfman McInnes . n - number of columns 32582ef1f0ffSBarry Smith - data - optional location of matrix data in column major order. Use `NULL` for PETSc 3259dfc5480cSLois Curfman McInnes to control all matrix memory allocation. 326020563c6bSBarry Smith 326120563c6bSBarry Smith Output Parameter: 326244cd7ae7SLois Curfman McInnes . A - the matrix 326320563c6bSBarry Smith 32642ef1f0ffSBarry Smith Level: intermediate 32652ef1f0ffSBarry Smith 326611a5261eSBarry Smith Note: 326718f449edSLois Curfman McInnes The data input variable is intended primarily for Fortran programmers 326818f449edSLois Curfman McInnes who wish to allocate their own matrix memory space. Most users should 32692ef1f0ffSBarry Smith set `data` = `NULL`. 327018f449edSLois Curfman McInnes 3271fb850c59SBarry Smith Developer Note: 3272fb850c59SBarry Smith Many of the matrix operations for this variant use the BLAS and LAPACK routines. 3273fb850c59SBarry Smith 32741cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()` 327520563c6bSBarry Smith @*/ 3276d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateSeqDense(MPI_Comm comm, PetscInt m, PetscInt n, PetscScalar *data, Mat *A) 3277d71ae5a4SJacob Faibussowitsch { 32783a40ed3dSBarry Smith PetscFunctionBegin; 32799566063dSJacob Faibussowitsch PetscCall(MatCreate(comm, A)); 32809566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*A, m, n, m, n)); 32819566063dSJacob Faibussowitsch PetscCall(MatSetType(*A, MATSEQDENSE)); 32829566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(*A, data)); 32833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3284273d9f13SBarry Smith } 3285273d9f13SBarry Smith 3286273d9f13SBarry Smith /*@C 328711a5261eSBarry Smith MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements of a `MATSEQDENSE` matrix 3288273d9f13SBarry Smith 3289d083f849SBarry Smith Collective 3290273d9f13SBarry Smith 3291273d9f13SBarry Smith Input Parameters: 32921c4f3114SJed Brown + B - the matrix 32932ef1f0ffSBarry Smith - data - the array (or `NULL`) 32942ef1f0ffSBarry Smith 32952ef1f0ffSBarry Smith Level: intermediate 3296273d9f13SBarry Smith 329711a5261eSBarry Smith Note: 3298273d9f13SBarry Smith The data input variable is intended primarily for Fortran programmers 3299273d9f13SBarry Smith who wish to allocate their own matrix memory space. Most users should 3300284134d9SBarry Smith need not call this routine. 3301273d9f13SBarry Smith 33021cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()`, `MatDenseSetLDA()` 3303273d9f13SBarry Smith @*/ 3304d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation(Mat B, PetscScalar data[]) 3305d71ae5a4SJacob Faibussowitsch { 3306a23d5eceSKris Buschelman PetscFunctionBegin; 3307d5ea218eSStefano Zampini PetscValidHeaderSpecific(B, MAT_CLASSID, 1); 3308cac4c232SBarry Smith PetscTryMethod(B, "MatSeqDenseSetPreallocation_C", (Mat, PetscScalar[]), (B, data)); 33093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3310a23d5eceSKris Buschelman } 3311a23d5eceSKris Buschelman 3312d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation_SeqDense(Mat B, PetscScalar *data) 3313d71ae5a4SJacob Faibussowitsch { 3314ad16ce7aSStefano Zampini Mat_SeqDense *b = (Mat_SeqDense *)B->data; 3315273d9f13SBarry Smith 3316273d9f13SBarry Smith PetscFunctionBegin; 331728b400f6SJacob Faibussowitsch PetscCheck(!b->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3318273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 3319a868139aSShri Abhyankar 33209566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(B->rmap)); 33219566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(B->cmap)); 332234ef9618SShri Abhyankar 3323ad16ce7aSStefano Zampini if (b->lda <= 0) b->lda = B->rmap->n; 332486d161a7SShri Abhyankar 33259e8f95c4SLisandro Dalcin if (!data) { /* petsc-allocated storage */ 33269566063dSJacob Faibussowitsch if (!b->user_alloc) PetscCall(PetscFree(b->v)); 33279566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((size_t)b->lda * B->cmap->n, &b->v)); 33282205254eSKarl Rupp 33299e8f95c4SLisandro Dalcin b->user_alloc = PETSC_FALSE; 3330273d9f13SBarry Smith } else { /* user-allocated storage */ 33319566063dSJacob Faibussowitsch if (!b->user_alloc) PetscCall(PetscFree(b->v)); 3332273d9f13SBarry Smith b->v = data; 3333273d9f13SBarry Smith b->user_alloc = PETSC_TRUE; 3334273d9f13SBarry Smith } 33350450473dSBarry Smith B->assembled = PETSC_TRUE; 33363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3337273d9f13SBarry Smith } 3338273d9f13SBarry Smith 333965b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 3340d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) 3341d71ae5a4SJacob Faibussowitsch { 3342d77f618aSHong Zhang Mat mat_elemental; 33431683a169SBarry Smith const PetscScalar *array; 33441683a169SBarry Smith PetscScalar *v_colwise; 3345d77f618aSHong Zhang PetscInt M = A->rmap->N, N = A->cmap->N, i, j, k, *rows, *cols; 3346d77f618aSHong Zhang 33478baccfbdSHong Zhang PetscFunctionBegin; 33489566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(M * N, &v_colwise, M, &rows, N, &cols)); 33499566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &array)); 3350d77f618aSHong Zhang /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */ 3351d77f618aSHong Zhang k = 0; 3352d77f618aSHong Zhang for (j = 0; j < N; j++) { 3353d77f618aSHong Zhang cols[j] = j; 3354ad540459SPierre Jolivet for (i = 0; i < M; i++) v_colwise[j * M + i] = array[k++]; 3355d77f618aSHong Zhang } 3356ad540459SPierre Jolivet for (i = 0; i < M; i++) rows[i] = i; 33579566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &array)); 3358d77f618aSHong Zhang 33599566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental)); 33609566063dSJacob Faibussowitsch PetscCall(MatSetSizes(mat_elemental, PETSC_DECIDE, PETSC_DECIDE, M, N)); 33619566063dSJacob Faibussowitsch PetscCall(MatSetType(mat_elemental, MATELEMENTAL)); 33629566063dSJacob Faibussowitsch PetscCall(MatSetUp(mat_elemental)); 3363d77f618aSHong Zhang 3364d77f618aSHong Zhang /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */ 33659566063dSJacob Faibussowitsch PetscCall(MatSetValues(mat_elemental, M, rows, N, cols, v_colwise, ADD_VALUES)); 33669566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY)); 33679566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY)); 33689566063dSJacob Faibussowitsch PetscCall(PetscFree3(v_colwise, rows, cols)); 3369d77f618aSHong Zhang 3370511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 33719566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A, &mat_elemental)); 3372d77f618aSHong Zhang } else { 3373d77f618aSHong Zhang *newmat = mat_elemental; 3374d77f618aSHong Zhang } 33753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 33768baccfbdSHong Zhang } 337765b80a83SHong Zhang #endif 33788baccfbdSHong Zhang 3379d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA_SeqDense(Mat B, PetscInt lda) 3380d71ae5a4SJacob Faibussowitsch { 33811b807ce4Svictorle Mat_SeqDense *b = (Mat_SeqDense *)B->data; 33827422da62SJose E. Roman PetscBool data; 338321a2c019SBarry Smith 33841b807ce4Svictorle PetscFunctionBegin; 33857422da62SJose E. Roman data = (PetscBool)((B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE); 3386aed4548fSBarry Smith PetscCheck(b->user_alloc || !data || b->lda == lda, PETSC_COMM_SELF, PETSC_ERR_ORDER, "LDA cannot be changed after allocation of internal storage"); 338708401ef6SPierre 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); 33881b807ce4Svictorle b->lda = lda; 33893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 33901b807ce4Svictorle } 33911b807ce4Svictorle 3392d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm, Mat inmat, PetscInt n, MatReuse scall, Mat *outmat) 3393d71ae5a4SJacob Faibussowitsch { 3394d528f656SJakub Kruzik PetscFunctionBegin; 33959566063dSJacob Faibussowitsch PetscCall(MatCreateMPIMatConcatenateSeqMat_MPIDense(comm, inmat, n, scall, outmat)); 33963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3397d528f656SJakub Kruzik } 3398d528f656SJakub Kruzik 3399d16ceb75SStefano Zampini PetscErrorCode MatDenseCreateColumnVec_Private(Mat A, Vec *v) 3400d16ceb75SStefano Zampini { 3401d16ceb75SStefano Zampini PetscBool isstd, iskok, iscuda, iship; 3402d16ceb75SStefano Zampini PetscMPIInt size; 3403d16ceb75SStefano Zampini #if PetscDefined(HAVE_CUDA) || PetscDefined(HAVE_HIP) 3404d16ceb75SStefano Zampini /* we pass the data of A, to prevent allocating needless GPU memory the first time VecCUPMPlaceArray is called. */ 3405d16ceb75SStefano Zampini const PetscScalar *a; 3406d16ceb75SStefano Zampini #endif 3407d16ceb75SStefano Zampini 3408d16ceb75SStefano Zampini PetscFunctionBegin; 3409d16ceb75SStefano Zampini *v = NULL; 3410d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &isstd, VECSTANDARD, VECSEQ, VECMPI, "")); 3411d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &iskok, VECKOKKOS, VECSEQKOKKOS, VECMPIKOKKOS, "")); 3412d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &iscuda, VECCUDA, VECSEQCUDA, VECMPICUDA, "")); 3413d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &iship, VECHIP, VECSEQHIP, VECMPIHIP, "")); 3414d16ceb75SStefano Zampini PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A), &size)); 3415d16ceb75SStefano Zampini if (isstd) { 3416d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPIWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, v)); 3417d16ceb75SStefano Zampini else PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, v)); 3418d16ceb75SStefano Zampini } else if (iskok) { 3419d16ceb75SStefano Zampini PetscCheck(PetscDefined(HAVE_KOKKOS_KERNELS), PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Reconfigure using KOKKOS kernels support"); 3420d16ceb75SStefano Zampini #if PetscDefined(HAVE_KOKKOS_KERNELS) 3421d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPIKokkosWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, v)); 3422d16ceb75SStefano Zampini else PetscCall(VecCreateSeqKokkosWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, v)); 3423d16ceb75SStefano Zampini #endif 3424d16ceb75SStefano Zampini } else if (iscuda) { 3425d16ceb75SStefano Zampini PetscCheck(PetscDefined(HAVE_CUDA), PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Reconfigure using CUDA support"); 3426d16ceb75SStefano Zampini #if PetscDefined(HAVE_CUDA) 3427d16ceb75SStefano Zampini PetscCall(MatDenseCUDAGetArrayRead(A, &a)); 3428d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPICUDAWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, a, v)); 3429d16ceb75SStefano Zampini else PetscCall(VecCreateSeqCUDAWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, a, v)); 3430d16ceb75SStefano Zampini #endif 3431d16ceb75SStefano Zampini } else if (iship) { 3432d16ceb75SStefano Zampini PetscCheck(PetscDefined(HAVE_HIP), PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Reconfigure using HIP support"); 3433d16ceb75SStefano Zampini #if PetscDefined(HAVE_HIP) 3434d16ceb75SStefano Zampini PetscCall(MatDenseHIPGetArrayRead(A, &a)); 3435d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPIHIPWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, a, v)); 3436d16ceb75SStefano Zampini else PetscCall(VecCreateSeqHIPWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, a, v)); 3437d16ceb75SStefano Zampini #endif 3438d16ceb75SStefano Zampini } 3439d16ceb75SStefano Zampini PetscCheck(*v, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Not coded for type %s", A->defaultvectype); 3440d16ceb75SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 3441d16ceb75SStefano Zampini } 3442d16ceb75SStefano Zampini 3443d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A, PetscInt col, Vec *v) 3444d71ae5a4SJacob Faibussowitsch { 34456947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34466947451fSStefano Zampini 34476947451fSStefano Zampini PetscFunctionBegin; 344828b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 344928b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3450d16ceb75SStefano Zampini if (!a->cvec) PetscCall(MatDenseCreateColumnVec_Private(A, &a->cvec)); 34516947451fSStefano Zampini a->vecinuse = col + 1; 34529566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, (PetscScalar **)&a->ptrinuse)); 34539566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda)); 34546947451fSStefano Zampini *v = a->cvec; 34553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34566947451fSStefano Zampini } 34576947451fSStefano Zampini 3458d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A, PetscInt col, Vec *v) 3459d71ae5a4SJacob Faibussowitsch { 34606947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34616947451fSStefano Zampini 34626947451fSStefano Zampini PetscFunctionBegin; 346328b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 346428b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 34656947451fSStefano Zampini a->vecinuse = 0; 34669566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, (PetscScalar **)&a->ptrinuse)); 34679566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 346875f6d85dSStefano Zampini if (v) *v = NULL; 34693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34706947451fSStefano Zampini } 34716947451fSStefano Zampini 3472d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v) 3473d71ae5a4SJacob Faibussowitsch { 34746947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34756947451fSStefano Zampini 34766947451fSStefano Zampini PetscFunctionBegin; 347728b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 347828b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3479d16ceb75SStefano Zampini if (!a->cvec) PetscCall(MatDenseCreateColumnVec_Private(A, &a->cvec)); 34806947451fSStefano Zampini a->vecinuse = col + 1; 34819566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &a->ptrinuse)); 34828e3a54c0SPierre Jolivet PetscCall(VecPlaceArray(a->cvec, PetscSafePointerPlusOffset(a->ptrinuse, (size_t)col * (size_t)a->lda))); 34839566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(a->cvec)); 34846947451fSStefano Zampini *v = a->cvec; 34853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34866947451fSStefano Zampini } 34876947451fSStefano Zampini 3488d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v) 3489d71ae5a4SJacob Faibussowitsch { 34906947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34916947451fSStefano Zampini 34926947451fSStefano Zampini PetscFunctionBegin; 349328b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 349428b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 34956947451fSStefano Zampini a->vecinuse = 0; 34969566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &a->ptrinuse)); 34979566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(a->cvec)); 34989566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 349975f6d85dSStefano Zampini if (v) *v = NULL; 35003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35016947451fSStefano Zampini } 35026947451fSStefano Zampini 3503d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v) 3504d71ae5a4SJacob Faibussowitsch { 35056947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35066947451fSStefano Zampini 35076947451fSStefano Zampini PetscFunctionBegin; 350828b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 350928b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3510d16ceb75SStefano Zampini if (!a->cvec) PetscCall(MatDenseCreateColumnVec_Private(A, &a->cvec)); 35116947451fSStefano Zampini a->vecinuse = col + 1; 35129566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(A, (PetscScalar **)&a->ptrinuse)); 35138e3a54c0SPierre Jolivet PetscCall(VecPlaceArray(a->cvec, PetscSafePointerPlusOffset(a->ptrinuse, (size_t)col * (size_t)a->lda))); 35146947451fSStefano Zampini *v = a->cvec; 35153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35166947451fSStefano Zampini } 35176947451fSStefano Zampini 3518d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v) 3519d71ae5a4SJacob Faibussowitsch { 35206947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35216947451fSStefano Zampini 35226947451fSStefano Zampini PetscFunctionBegin; 352328b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 352428b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 35256947451fSStefano Zampini a->vecinuse = 0; 35269566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(A, (PetscScalar **)&a->ptrinuse)); 35279566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 352875f6d85dSStefano Zampini if (v) *v = NULL; 35293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35306947451fSStefano Zampini } 35316947451fSStefano Zampini 3532d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) 3533d71ae5a4SJacob Faibussowitsch { 35345ea7661aSPierre Jolivet Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35355ea7661aSPierre Jolivet 35365ea7661aSPierre Jolivet PetscFunctionBegin; 353728b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 353828b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3539a2748737SPierre Jolivet if (a->cmat && (cend - cbegin != a->cmat->cmap->N || rend - rbegin != a->cmat->rmap->N)) PetscCall(MatDestroy(&a->cmat)); 35405ea7661aSPierre Jolivet if (!a->cmat) { 35418e3a54c0SPierre Jolivet PetscCall(MatCreateDense(PetscObjectComm((PetscObject)A), rend - rbegin, PETSC_DECIDE, rend - rbegin, cend - cbegin, PetscSafePointerPlusOffset(a->v, rbegin + (size_t)cbegin * a->lda), &a->cmat)); 35425ea7661aSPierre Jolivet } else { 35438e3a54c0SPierre Jolivet PetscCall(MatDensePlaceArray(a->cmat, PetscSafePointerPlusOffset(a->v, rbegin + (size_t)cbegin * a->lda))); 35445ea7661aSPierre Jolivet } 35459566063dSJacob Faibussowitsch PetscCall(MatDenseSetLDA(a->cmat, a->lda)); 35465ea7661aSPierre Jolivet a->matinuse = cbegin + 1; 35475ea7661aSPierre Jolivet *v = a->cmat; 354847d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 354975f6d85dSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 355075f6d85dSStefano Zampini #endif 35513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35525ea7661aSPierre Jolivet } 35535ea7661aSPierre Jolivet 3554d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A, Mat *v) 3555d71ae5a4SJacob Faibussowitsch { 35565ea7661aSPierre Jolivet Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35575ea7661aSPierre Jolivet 35585ea7661aSPierre Jolivet PetscFunctionBegin; 355928b400f6SJacob Faibussowitsch PetscCheck(a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetSubMatrix() first"); 356028b400f6SJacob Faibussowitsch PetscCheck(a->cmat, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column matrix"); 356108401ef6SPierre Jolivet PetscCheck(*v == a->cmat, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not the matrix obtained from MatDenseGetSubMatrix()"); 35625ea7661aSPierre Jolivet a->matinuse = 0; 35639566063dSJacob Faibussowitsch PetscCall(MatDenseResetArray(a->cmat)); 3564742765d3SMatthew Knepley if (v) *v = NULL; 356547d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 35663faff063SStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 35673faff063SStefano Zampini #endif 35683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35695ea7661aSPierre Jolivet } 35705ea7661aSPierre Jolivet 35710bad9183SKris Buschelman /*MC 3572fafad747SKris Buschelman MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices. 35730bad9183SKris Buschelman 35742ef1f0ffSBarry Smith Options Database Key: 357511a5261eSBarry Smith . -mat_type seqdense - sets the matrix type to `MATSEQDENSE` during a call to `MatSetFromOptions()` 35760bad9183SKris Buschelman 35770bad9183SKris Buschelman Level: beginner 35780bad9183SKris Buschelman 35791cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreateSeqDense()` 35800bad9183SKris Buschelman M*/ 3581d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreate_SeqDense(Mat B) 3582d71ae5a4SJacob Faibussowitsch { 3583273d9f13SBarry Smith Mat_SeqDense *b; 35847c334f02SBarry Smith PetscMPIInt size; 3585273d9f13SBarry Smith 3586273d9f13SBarry Smith PetscFunctionBegin; 35879566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)B), &size)); 358808401ef6SPierre Jolivet PetscCheck(size <= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Comm must be of size 1"); 358955659b69SBarry Smith 35904dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&b)); 359144cd7ae7SLois Curfman McInnes B->data = (void *)b; 3592aea10558SJacob Faibussowitsch B->ops[0] = MatOps_Values; 359318f449edSLois Curfman McInnes 3594273d9f13SBarry Smith b->roworiented = PETSC_TRUE; 35954e220ebcSLois Curfman McInnes 35969566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatQRFactor_C", MatQRFactor_SeqDense)); 35979566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetLDA_C", MatDenseGetLDA_SeqDense)); 35989566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseSetLDA_C", MatDenseSetLDA_SeqDense)); 35999566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArray_C", MatDenseGetArray_SeqDense)); 36009566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArray_C", MatDenseRestoreArray_SeqDense)); 36019566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDensePlaceArray_C", MatDensePlaceArray_SeqDense)); 36029566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseResetArray_C", MatDenseResetArray_SeqDense)); 36039566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseReplaceArray_C", MatDenseReplaceArray_SeqDense)); 36049566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayRead_C", MatDenseGetArray_SeqDense)); 36059566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayRead_C", MatDenseRestoreArray_SeqDense)); 36069566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayWrite_C", MatDenseGetArray_SeqDense)); 36079566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayWrite_C", MatDenseRestoreArray_SeqDense)); 36089566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqaij_C", MatConvert_SeqDense_SeqAIJ)); 36098baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 36109566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_elemental_C", MatConvert_SeqDense_Elemental)); 36118baccfbdSHong Zhang #endif 3612d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 36139566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_scalapack_C", MatConvert_Dense_ScaLAPACK)); 3614d24d4204SJose E. Roman #endif 36152bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA) 36169566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensecuda_C", MatConvert_SeqDense_SeqDenseCUDA)); 36179566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", MatProductSetFromOptions_SeqDense)); 36189566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdense_C", MatProductSetFromOptions_SeqDense)); 36199566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensecuda_C", MatProductSetFromOptions_SeqDense)); 36202bf066beSStefano Zampini #endif 362147d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 362247d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensehip_C", MatConvert_SeqDense_SeqDenseHIP)); 362347d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensehip_seqdensehip_C", MatProductSetFromOptions_SeqDense)); 362447d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensehip_seqdense_C", MatProductSetFromOptions_SeqDense)); 362547d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensehip_C", MatProductSetFromOptions_SeqDense)); 362647d993e7Ssuyashtn #endif 36279566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSeqDenseSetPreallocation_C", MatSeqDenseSetPreallocation_SeqDense)); 36289566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqaij_seqdense_C", MatProductSetFromOptions_SeqAIJ_SeqDense)); 36299566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdense_C", MatProductSetFromOptions_SeqDense)); 36309566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense)); 36319566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqsbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense)); 363296e6d5c4SRichard Tran Mills 36339566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumn_C", MatDenseGetColumn_SeqDense)); 36349566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumn_C", MatDenseRestoreColumn_SeqDense)); 36359566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVec_C", MatDenseGetColumnVec_SeqDense)); 36369566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVec_C", MatDenseRestoreColumnVec_SeqDense)); 36379566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecRead_C", MatDenseGetColumnVecRead_SeqDense)); 36389566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecRead_C", MatDenseRestoreColumnVecRead_SeqDense)); 36399566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecWrite_C", MatDenseGetColumnVecWrite_SeqDense)); 36409566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecWrite_C", MatDenseRestoreColumnVecWrite_SeqDense)); 36419566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetSubMatrix_C", MatDenseGetSubMatrix_SeqDense)); 36429566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreSubMatrix_C", MatDenseRestoreSubMatrix_SeqDense)); 36439566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)B, MATSEQDENSE)); 36443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3645289bc588SBarry Smith } 364686aefd0dSHong Zhang 364786aefd0dSHong Zhang /*@C 364811a5261eSBarry 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. 364986aefd0dSHong Zhang 365086aefd0dSHong Zhang Not Collective 365186aefd0dSHong Zhang 36525ea7661aSPierre Jolivet Input Parameters: 3653fe59aa6dSJacob Faibussowitsch + A - a `MATSEQDENSE` or `MATMPIDENSE` matrix 365486aefd0dSHong Zhang - col - column index 365586aefd0dSHong Zhang 365686aefd0dSHong Zhang Output Parameter: 365786aefd0dSHong Zhang . vals - pointer to the data 365886aefd0dSHong Zhang 365986aefd0dSHong Zhang Level: intermediate 366086aefd0dSHong Zhang 366111a5261eSBarry Smith Note: 366211a5261eSBarry Smith Use `MatDenseGetColumnVec()` to get access to a column of a `MATDENSE` treated as a `Vec` 366311a5261eSBarry Smith 36641cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreColumn()`, `MatDenseGetColumnVec()` 366586aefd0dSHong Zhang @*/ 3666d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumn(Mat A, PetscInt col, PetscScalar **vals) 3667d71ae5a4SJacob Faibussowitsch { 366886aefd0dSHong Zhang PetscFunctionBegin; 3669d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3670d5ea218eSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 36714f572ea9SToby Isaac PetscAssertPointer(vals, 3); 3672cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumn_C", (Mat, PetscInt, PetscScalar **), (A, col, vals)); 36733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 367486aefd0dSHong Zhang } 367586aefd0dSHong Zhang 367686aefd0dSHong Zhang /*@C 367711a5261eSBarry Smith MatDenseRestoreColumn - returns access to a column of a `MATDENSE` matrix which is returned by `MatDenseGetColumn()`. 367886aefd0dSHong Zhang 367986aefd0dSHong Zhang Not Collective 368086aefd0dSHong Zhang 3681742765d3SMatthew Knepley Input Parameters: 3682fe59aa6dSJacob Faibussowitsch + A - a `MATSEQDENSE` or `MATMPIDENSE` matrix 36832ef1f0ffSBarry Smith - vals - pointer to the data (may be `NULL`) 368486aefd0dSHong Zhang 368586aefd0dSHong Zhang Level: intermediate 368686aefd0dSHong Zhang 36871cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetColumn()` 368886aefd0dSHong Zhang @*/ 3689d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumn(Mat A, PetscScalar **vals) 3690d71ae5a4SJacob Faibussowitsch { 369186aefd0dSHong Zhang PetscFunctionBegin; 3692d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 36934f572ea9SToby Isaac PetscAssertPointer(vals, 2); 3694cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumn_C", (Mat, PetscScalar **), (A, vals)); 36953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 369686aefd0dSHong Zhang } 36976947451fSStefano Zampini 36980f74d2c1SSatish Balay /*@ 369911a5261eSBarry Smith MatDenseGetColumnVec - Gives read-write access to a column of a `MATDENSE` matrix, represented as a `Vec`. 37006947451fSStefano Zampini 37016947451fSStefano Zampini Collective 37026947451fSStefano Zampini 37035ea7661aSPierre Jolivet Input Parameters: 3704fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 37056947451fSStefano Zampini - col - the column index 37066947451fSStefano Zampini 37076947451fSStefano Zampini Output Parameter: 37086947451fSStefano Zampini . v - the vector 37096947451fSStefano Zampini 37102ef1f0ffSBarry Smith Level: intermediate 37112ef1f0ffSBarry Smith 37126947451fSStefano Zampini Notes: 371311a5261eSBarry Smith The vector is owned by PETSc. Users need to call `MatDenseRestoreColumnVec()` when the vector is no longer needed. 371411a5261eSBarry Smith 371511a5261eSBarry Smith Use `MatDenseGetColumnVecRead()` to obtain read-only access or `MatDenseGetColumnVecWrite()` for write-only access. 37166947451fSStefano Zampini 37171cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`, `MatDenseGetColumn()` 37186947451fSStefano Zampini @*/ 3719d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec(Mat A, PetscInt col, Vec *v) 3720d71ae5a4SJacob Faibussowitsch { 37216947451fSStefano Zampini PetscFunctionBegin; 37226947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 37236947451fSStefano Zampini PetscValidType(A, 1); 37246947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 37254f572ea9SToby Isaac PetscAssertPointer(v, 3); 372628b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 37272cf15c64SPierre 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); 3728cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v)); 37293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37306947451fSStefano Zampini } 37316947451fSStefano Zampini 37320f74d2c1SSatish Balay /*@ 3733fb850c59SBarry Smith MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from `MatDenseGetColumnVec()`. 37346947451fSStefano Zampini 37356947451fSStefano Zampini Collective 37366947451fSStefano Zampini 37375ea7661aSPierre Jolivet Input Parameters: 3738fb850c59SBarry Smith + A - the `Mat` object 37396947451fSStefano Zampini . col - the column index 3740fb850c59SBarry Smith - v - the `Vec` object (may be `NULL`) 37416947451fSStefano Zampini 37426947451fSStefano Zampini Level: intermediate 37436947451fSStefano Zampini 37441cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 37456947451fSStefano Zampini @*/ 3746d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec(Mat A, PetscInt col, Vec *v) 3747d71ae5a4SJacob Faibussowitsch { 37486947451fSStefano Zampini PetscFunctionBegin; 37496947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 37506947451fSStefano Zampini PetscValidType(A, 1); 37516947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 375208401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 37532cf15c64SPierre 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); 3754cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v)); 37553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37566947451fSStefano Zampini } 37576947451fSStefano Zampini 37580f74d2c1SSatish Balay /*@ 3759fb850c59SBarry Smith MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a `Vec`. 37606947451fSStefano Zampini 37616947451fSStefano Zampini Collective 37626947451fSStefano Zampini 37635ea7661aSPierre Jolivet Input Parameters: 3764fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 37656947451fSStefano Zampini - col - the column index 37666947451fSStefano Zampini 37676947451fSStefano Zampini Output Parameter: 37686947451fSStefano Zampini . v - the vector 37696947451fSStefano Zampini 37702ef1f0ffSBarry Smith Level: intermediate 37712ef1f0ffSBarry Smith 37726947451fSStefano Zampini Notes: 37736947451fSStefano Zampini The vector is owned by PETSc and users cannot modify it. 377411a5261eSBarry Smith 37752ef1f0ffSBarry Smith Users need to call `MatDenseRestoreColumnVecRead()` when the vector is no longer needed. 377611a5261eSBarry Smith 37772ef1f0ffSBarry Smith Use `MatDenseGetColumnVec()` to obtain read-write access or `MatDenseGetColumnVecWrite()` for write-only access. 37786947451fSStefano Zampini 37791cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 37806947451fSStefano Zampini @*/ 3781d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead(Mat A, PetscInt col, Vec *v) 3782d71ae5a4SJacob Faibussowitsch { 37836947451fSStefano Zampini PetscFunctionBegin; 37846947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 37856947451fSStefano Zampini PetscValidType(A, 1); 37866947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 37874f572ea9SToby Isaac PetscAssertPointer(v, 3); 378828b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 37892cf15c64SPierre 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); 3790cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v)); 37913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37926947451fSStefano Zampini } 37936947451fSStefano Zampini 37940f74d2c1SSatish Balay /*@ 3795fb850c59SBarry Smith MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from `MatDenseGetColumnVecRead()`. 37966947451fSStefano Zampini 37976947451fSStefano Zampini Collective 37986947451fSStefano Zampini 37995ea7661aSPierre Jolivet Input Parameters: 3800fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 38016947451fSStefano Zampini . col - the column index 3802fb850c59SBarry Smith - v - the `Vec` object (may be `NULL`) 38036947451fSStefano Zampini 38046947451fSStefano Zampini Level: intermediate 38056947451fSStefano Zampini 38061cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecWrite()` 38076947451fSStefano Zampini @*/ 3808d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead(Mat A, PetscInt col, Vec *v) 3809d71ae5a4SJacob Faibussowitsch { 38106947451fSStefano Zampini PetscFunctionBegin; 38116947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38126947451fSStefano Zampini PetscValidType(A, 1); 38136947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 381408401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 38152cf15c64SPierre 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); 3816cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v)); 38173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38186947451fSStefano Zampini } 38196947451fSStefano Zampini 38200f74d2c1SSatish Balay /*@ 3821fb850c59SBarry Smith MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a `Vec`. 38226947451fSStefano Zampini 38236947451fSStefano Zampini Collective 38246947451fSStefano Zampini 38255ea7661aSPierre Jolivet Input Parameters: 3826fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 38276947451fSStefano Zampini - col - the column index 38286947451fSStefano Zampini 38296947451fSStefano Zampini Output Parameter: 38306947451fSStefano Zampini . v - the vector 38316947451fSStefano Zampini 38326947451fSStefano Zampini Level: intermediate 38336947451fSStefano Zampini 38342ef1f0ffSBarry Smith Notes: 38352ef1f0ffSBarry Smith The vector is owned by PETSc. Users need to call `MatDenseRestoreColumnVecWrite()` when the vector is no longer needed. 38362ef1f0ffSBarry Smith 38372ef1f0ffSBarry Smith Use `MatDenseGetColumnVec()` to obtain read-write access or `MatDenseGetColumnVecRead()` for read-only access. 38382ef1f0ffSBarry Smith 38391cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 38406947451fSStefano Zampini @*/ 3841d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite(Mat A, PetscInt col, Vec *v) 3842d71ae5a4SJacob Faibussowitsch { 38436947451fSStefano Zampini PetscFunctionBegin; 38446947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38456947451fSStefano Zampini PetscValidType(A, 1); 38466947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 38474f572ea9SToby Isaac PetscAssertPointer(v, 3); 384828b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3849aed4548fSBarry 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); 3850cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v)); 38513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38526947451fSStefano Zampini } 38536947451fSStefano Zampini 38540f74d2c1SSatish Balay /*@ 3855fb850c59SBarry Smith MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from `MatDenseGetColumnVecWrite()`. 38566947451fSStefano Zampini 38576947451fSStefano Zampini Collective 38586947451fSStefano Zampini 38595ea7661aSPierre Jolivet Input Parameters: 3860fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 38616947451fSStefano Zampini . col - the column index 38622ef1f0ffSBarry Smith - v - the `Vec` object (may be `NULL`) 38636947451fSStefano Zampini 38646947451fSStefano Zampini Level: intermediate 38656947451fSStefano Zampini 38661cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()` 38676947451fSStefano Zampini @*/ 3868d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A, PetscInt col, Vec *v) 3869d71ae5a4SJacob Faibussowitsch { 38706947451fSStefano Zampini PetscFunctionBegin; 38716947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38726947451fSStefano Zampini PetscValidType(A, 1); 38736947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 387408401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3875aed4548fSBarry 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); 3876cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v)); 38773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38786947451fSStefano Zampini } 38795ea7661aSPierre Jolivet 38800f74d2c1SSatish Balay /*@ 3881fb850c59SBarry Smith MatDenseGetSubMatrix - Gives access to a block of rows and columns of a dense matrix, represented as a `Mat`. 38825ea7661aSPierre Jolivet 38835ea7661aSPierre Jolivet Collective 38845ea7661aSPierre Jolivet 38855ea7661aSPierre Jolivet Input Parameters: 3886fb850c59SBarry Smith + A - the `Mat` object 38872ef1f0ffSBarry Smith . rbegin - the first global row index in the block (if `PETSC_DECIDE`, is 0) 38882ef1f0ffSBarry Smith . rend - the global row index past the last one in the block (if `PETSC_DECIDE`, is `M`) 38892ef1f0ffSBarry Smith . cbegin - the first global column index in the block (if `PETSC_DECIDE`, is 0) 38902ef1f0ffSBarry Smith - cend - the global column index past the last one in the block (if `PETSC_DECIDE`, is `N`) 38915ea7661aSPierre Jolivet 38925ea7661aSPierre Jolivet Output Parameter: 38935ea7661aSPierre Jolivet . v - the matrix 38945ea7661aSPierre Jolivet 38955ea7661aSPierre Jolivet Level: intermediate 38965ea7661aSPierre Jolivet 38972ef1f0ffSBarry Smith Notes: 38982ef1f0ffSBarry Smith The matrix is owned by PETSc. Users need to call `MatDenseRestoreSubMatrix()` when the matrix is no longer needed. 38992ef1f0ffSBarry Smith 39002ef1f0ffSBarry 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. 39012ef1f0ffSBarry Smith 39021cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreSubMatrix()` 39035ea7661aSPierre Jolivet @*/ 3904d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) 3905d71ae5a4SJacob Faibussowitsch { 39065ea7661aSPierre Jolivet PetscFunctionBegin; 39075ea7661aSPierre Jolivet PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 39085ea7661aSPierre Jolivet PetscValidType(A, 1); 3909a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, rbegin, 2); 3910a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, rend, 3); 3911a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, cbegin, 4); 3912a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, cend, 5); 39134f572ea9SToby Isaac PetscAssertPointer(v, 6); 3914a2748737SPierre Jolivet if (rbegin == PETSC_DECIDE) rbegin = 0; 3915a2748737SPierre Jolivet if (rend == PETSC_DECIDE) rend = A->rmap->N; 3916a2748737SPierre Jolivet if (cbegin == PETSC_DECIDE) cbegin = 0; 3917a2748737SPierre Jolivet if (cend == PETSC_DECIDE) cend = A->cmap->N; 391828b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3919a2748737SPierre 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); 3920a2748737SPierre 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); 3921a2748737SPierre 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); 3922a2748737SPierre 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); 3923a2748737SPierre Jolivet PetscUseMethod(A, "MatDenseGetSubMatrix_C", (Mat, PetscInt, PetscInt, PetscInt, PetscInt, Mat *), (A, rbegin, rend, cbegin, cend, v)); 39243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 39255ea7661aSPierre Jolivet } 39265ea7661aSPierre Jolivet 39270f74d2c1SSatish Balay /*@ 3928fb850c59SBarry Smith MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from `MatDenseGetSubMatrix()`. 39295ea7661aSPierre Jolivet 39305ea7661aSPierre Jolivet Collective 39315ea7661aSPierre Jolivet 39325ea7661aSPierre Jolivet Input Parameters: 3933fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 39342ef1f0ffSBarry Smith - v - the `Mat` object (may be `NULL`) 39355ea7661aSPierre Jolivet 39365ea7661aSPierre Jolivet Level: intermediate 39375ea7661aSPierre Jolivet 39381cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseGetSubMatrix()` 39395ea7661aSPierre Jolivet @*/ 3940d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix(Mat A, Mat *v) 3941d71ae5a4SJacob Faibussowitsch { 39425ea7661aSPierre Jolivet PetscFunctionBegin; 39435ea7661aSPierre Jolivet PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 39445ea7661aSPierre Jolivet PetscValidType(A, 1); 39454f572ea9SToby Isaac PetscAssertPointer(v, 2); 3946cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreSubMatrix_C", (Mat, Mat *), (A, v)); 39473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 39485ea7661aSPierre Jolivet } 39498a9c020eSBarry Smith 39508a9c020eSBarry Smith #include <petscblaslapack.h> 39518a9c020eSBarry Smith #include <petsc/private/kernels/blockinvert.h> 39528a9c020eSBarry Smith 3953d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseInvert(Mat A) 3954d71ae5a4SJacob Faibussowitsch { 3955d63b1753SJacob Faibussowitsch PetscInt m; 39568a9c020eSBarry Smith const PetscReal shift = 0.0; 3957d63b1753SJacob Faibussowitsch PetscBool allowzeropivot, zeropivotdetected = PETSC_FALSE; 3958d63b1753SJacob Faibussowitsch PetscScalar *values; 39598a9c020eSBarry Smith 39608a9c020eSBarry Smith PetscFunctionBegin; 3961d63b1753SJacob Faibussowitsch PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3962d63b1753SJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &values)); 3963d63b1753SJacob Faibussowitsch PetscCall(MatGetLocalSize(A, &m, NULL)); 3964d63b1753SJacob Faibussowitsch allowzeropivot = PetscNot(A->erroriffailure); 39658a9c020eSBarry Smith /* factor and invert each block */ 3966d63b1753SJacob Faibussowitsch switch (m) { 3967d71ae5a4SJacob Faibussowitsch case 1: 3968d71ae5a4SJacob Faibussowitsch values[0] = (PetscScalar)1.0 / (values[0] + shift); 3969d71ae5a4SJacob Faibussowitsch break; 39708a9c020eSBarry Smith case 2: 39718a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_2(values, shift, allowzeropivot, &zeropivotdetected)); 39728a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39738a9c020eSBarry Smith break; 39748a9c020eSBarry Smith case 3: 39758a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_3(values, shift, allowzeropivot, &zeropivotdetected)); 39768a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39778a9c020eSBarry Smith break; 39788a9c020eSBarry Smith case 4: 39798a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_4(values, shift, allowzeropivot, &zeropivotdetected)); 39808a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39818a9c020eSBarry Smith break; 39829371c9d4SSatish Balay case 5: { 39838a9c020eSBarry Smith PetscScalar work[25]; 39848a9c020eSBarry Smith PetscInt ipvt[5]; 39858a9c020eSBarry Smith 39868a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_5(values, ipvt, work, shift, allowzeropivot, &zeropivotdetected)); 39878a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39889371c9d4SSatish Balay } break; 39898a9c020eSBarry Smith case 6: 39908a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_6(values, shift, allowzeropivot, &zeropivotdetected)); 39918a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39928a9c020eSBarry Smith break; 39938a9c020eSBarry Smith case 7: 39948a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_7(values, shift, allowzeropivot, &zeropivotdetected)); 39958a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39968a9c020eSBarry Smith break; 39979371c9d4SSatish Balay default: { 39988a9c020eSBarry Smith PetscInt *v_pivots, *IJ, j; 39998a9c020eSBarry Smith PetscScalar *v_work; 40008a9c020eSBarry Smith 4001d63b1753SJacob Faibussowitsch PetscCall(PetscMalloc3(m, &v_work, m, &v_pivots, m, &IJ)); 4002d63b1753SJacob Faibussowitsch for (j = 0; j < m; j++) IJ[j] = j; 4003d63b1753SJacob Faibussowitsch PetscCall(PetscKernel_A_gets_inverse_A(m, values, v_pivots, v_work, allowzeropivot, &zeropivotdetected)); 40048a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 40058a9c020eSBarry Smith PetscCall(PetscFree3(v_work, v_pivots, IJ)); 40068a9c020eSBarry Smith } 40078a9c020eSBarry Smith } 4008d63b1753SJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &values)); 40093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 40108a9c020eSBarry Smith } 4011