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 107dd8e379bSPierre Jolivet /* 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)); 159f4f49eeaSPierre 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)); 166f4f49eeaSPierre 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)); } 933f4f49eeaSPierre 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) { 1002f4f49eeaSPierre 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 1056*0be0d8bdSHansol Suh static PetscErrorCode MatMultColumnRangeKernel_SeqDense(Mat A, Vec xx, Vec yy, PetscInt c_start, PetscInt c_end, 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)); 1065*0be0d8bdSHansol Suh PetscCall(PetscBLASIntCast(c_end - c_start, &n)); 10669566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 10679566063dSJacob Faibussowitsch PetscCall(VecGetArrayWrite(yy, &y)); 1068*0be0d8bdSHansol Suh if (!m || !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*0be0d8bdSHansol Suh if (herm) PetscCallBLAS("BLASgemv", BLASgemv_("C", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x, &_One, &_DZero, y + c_start, &_One)); 1077*0be0d8bdSHansol Suh else PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x, &_One, &_DZero, y + c_start, &_One)); 1078459e8d23SBlanca Mellado Pinto } else { 1079*0be0d8bdSHansol Suh PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x + c_start, &_One, &_DZero, y, &_One)); 1080459e8d23SBlanca Mellado Pinto } 1081*0be0d8bdSHansol Suh PetscCall(PetscLogFlops(2.0 * m * n - n)); 10825ac36cfcSBarry Smith } 10839566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 10849566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayWrite(yy, &y)); 10853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1086289bc588SBarry Smith } 10876ee01492SSatish Balay 1088*0be0d8bdSHansol Suh PetscErrorCode MatMultHermitianTransposeColumnRange_SeqDense(Mat A, Vec xx, Vec yy, PetscInt c_start, PetscInt c_end) 1089*0be0d8bdSHansol Suh { 1090*0be0d8bdSHansol Suh PetscFunctionBegin; 1091*0be0d8bdSHansol Suh PetscCall(MatMultColumnRangeKernel_SeqDense(A, xx, yy, c_start, c_end, PETSC_TRUE, PETSC_TRUE)); 1092*0be0d8bdSHansol Suh PetscFunctionReturn(PETSC_SUCCESS); 1093*0be0d8bdSHansol Suh } 1094*0be0d8bdSHansol Suh 1095459e8d23SBlanca Mellado Pinto PetscErrorCode MatMult_SeqDense(Mat A, Vec xx, Vec yy) 1096459e8d23SBlanca Mellado Pinto { 1097459e8d23SBlanca Mellado Pinto PetscFunctionBegin; 1098*0be0d8bdSHansol Suh PetscCall(MatMultColumnRangeKernel_SeqDense(A, xx, yy, 0, A->cmap->n, PETSC_FALSE, PETSC_FALSE)); 1099459e8d23SBlanca Mellado Pinto PetscFunctionReturn(PETSC_SUCCESS); 1100459e8d23SBlanca Mellado Pinto } 1101459e8d23SBlanca Mellado Pinto 1102459e8d23SBlanca Mellado Pinto PetscErrorCode MatMultTranspose_SeqDense(Mat A, Vec xx, Vec yy) 1103459e8d23SBlanca Mellado Pinto { 1104459e8d23SBlanca Mellado Pinto PetscFunctionBegin; 1105*0be0d8bdSHansol Suh PetscCall(MatMultColumnRangeKernel_SeqDense(A, xx, yy, 0, A->cmap->n, PETSC_TRUE, PETSC_FALSE)); 1106459e8d23SBlanca Mellado Pinto PetscFunctionReturn(PETSC_SUCCESS); 1107459e8d23SBlanca Mellado Pinto } 1108459e8d23SBlanca Mellado Pinto 1109459e8d23SBlanca Mellado Pinto PetscErrorCode MatMultHermitianTranspose_SeqDense(Mat A, Vec xx, Vec yy) 1110459e8d23SBlanca Mellado Pinto { 1111459e8d23SBlanca Mellado Pinto PetscFunctionBegin; 1112*0be0d8bdSHansol Suh PetscCall(MatMultColumnRangeKernel_SeqDense(A, xx, yy, 0, A->cmap->n, PETSC_TRUE, PETSC_TRUE)); 1113459e8d23SBlanca Mellado Pinto PetscFunctionReturn(PETSC_SUCCESS); 1114459e8d23SBlanca Mellado Pinto } 1115459e8d23SBlanca Mellado Pinto 1116*0be0d8bdSHansol Suh static PetscErrorCode MatMultAddColumnRangeKernel_SeqDense(Mat A, Vec xx, Vec zz, Vec yy, PetscInt c_start, PetscInt c_end, PetscBool trans, PetscBool herm) 1117d71ae5a4SJacob Faibussowitsch { 1118c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1119d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 1120d9ca1df4SBarry Smith PetscScalar *y, _DOne = 1.0; 11210805154bSBarry Smith PetscBLASInt m, n, _One = 1; 11223a40ed3dSBarry Smith 11233a40ed3dSBarry Smith PetscFunctionBegin; 11249566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 1125*0be0d8bdSHansol Suh PetscCall(PetscBLASIntCast(c_end - c_start, &n)); 11269566063dSJacob Faibussowitsch PetscCall(VecCopy(zz, yy)); 1127*0be0d8bdSHansol Suh if (!m || !n) PetscFunctionReturn(PETSC_SUCCESS); 11289566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &y)); 1129459e8d23SBlanca Mellado Pinto PetscCall(VecGetArrayRead(xx, &x)); 1130459e8d23SBlanca Mellado Pinto if (trans) { 1131*0be0d8bdSHansol Suh if (herm) PetscCallBLAS("BLASgemv", BLASgemv_("C", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x, &_One, &_DOne, y + c_start, &_One)); 1132*0be0d8bdSHansol Suh else PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x, &_One, &_DOne, y + c_start, &_One)); 1133459e8d23SBlanca Mellado Pinto } else { 1134*0be0d8bdSHansol Suh PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v + c_start * mat->lda, &mat->lda, x + c_start, &_One, &_DOne, y, &_One)); 1135459e8d23SBlanca Mellado Pinto } 11369566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 11379566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &y)); 1138*0be0d8bdSHansol Suh PetscCall(PetscLogFlops(2.0 * m * n)); 1139*0be0d8bdSHansol Suh PetscFunctionReturn(PETSC_SUCCESS); 1140*0be0d8bdSHansol Suh } 1141*0be0d8bdSHansol Suh 1142*0be0d8bdSHansol Suh PetscErrorCode MatMultAddColumnRange_SeqDense(Mat A, Vec xx, Vec zz, Vec yy, PetscInt c_start, PetscInt c_end) 1143*0be0d8bdSHansol Suh { 1144*0be0d8bdSHansol Suh PetscFunctionBegin; 1145*0be0d8bdSHansol Suh PetscCall(MatMultAddColumnRangeKernel_SeqDense(A, xx, zz, yy, c_start, c_end, PETSC_FALSE, PETSC_FALSE)); 1146*0be0d8bdSHansol Suh PetscFunctionReturn(PETSC_SUCCESS); 1147*0be0d8bdSHansol Suh } 1148*0be0d8bdSHansol Suh 1149*0be0d8bdSHansol Suh PetscErrorCode MatMultHermitianTransposeAddColumnRange_SeqDense(Mat A, Vec xx, Vec zz, Vec yy, PetscInt c_start, PetscInt c_end) 1150*0be0d8bdSHansol Suh { 1151*0be0d8bdSHansol Suh PetscFunctionBegin; 1152*0be0d8bdSHansol Suh PetscMPIInt rank; 1153*0be0d8bdSHansol Suh PetscCallMPI(MPI_Comm_rank(MPI_COMM_WORLD, &rank)); 1154*0be0d8bdSHansol Suh PetscCall(MatMultAddColumnRangeKernel_SeqDense(A, xx, zz, yy, c_start, c_end, PETSC_TRUE, PETSC_TRUE)); 11553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1156289bc588SBarry Smith } 11576ee01492SSatish Balay 1158459e8d23SBlanca Mellado Pinto PetscErrorCode MatMultAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) 1159459e8d23SBlanca Mellado Pinto { 1160459e8d23SBlanca Mellado Pinto PetscFunctionBegin; 1161*0be0d8bdSHansol Suh PetscCall(MatMultAddColumnRangeKernel_SeqDense(A, xx, zz, yy, 0, A->cmap->n, PETSC_FALSE, PETSC_FALSE)); 1162459e8d23SBlanca Mellado Pinto PetscFunctionReturn(PETSC_SUCCESS); 1163459e8d23SBlanca Mellado Pinto } 1164459e8d23SBlanca Mellado Pinto 1165d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) 1166d71ae5a4SJacob Faibussowitsch { 11673a40ed3dSBarry Smith PetscFunctionBegin; 1168*0be0d8bdSHansol Suh PetscCall(MatMultAddColumnRangeKernel_SeqDense(A, xx, zz, yy, 0, A->cmap->n, PETSC_TRUE, PETSC_FALSE)); 1169459e8d23SBlanca Mellado Pinto PetscFunctionReturn(PETSC_SUCCESS); 1170459e8d23SBlanca Mellado Pinto } 1171459e8d23SBlanca Mellado Pinto 1172459e8d23SBlanca Mellado Pinto PetscErrorCode MatMultHermitianTransposeAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) 1173459e8d23SBlanca Mellado Pinto { 1174459e8d23SBlanca Mellado Pinto PetscFunctionBegin; 1175*0be0d8bdSHansol Suh PetscCall(MatMultAddColumnRangeKernel_SeqDense(A, xx, zz, yy, 0, A->cmap->n, PETSC_TRUE, PETSC_TRUE)); 11763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1177289bc588SBarry Smith } 1178289bc588SBarry Smith 1179d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals) 1180d71ae5a4SJacob Faibussowitsch { 1181c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 118213f74950SBarry Smith PetscInt i; 118367e560aaSBarry Smith 11843a40ed3dSBarry Smith PetscFunctionBegin; 1185c3e1b152SPierre Jolivet if (ncols) *ncols = A->cmap->n; 1186289bc588SBarry Smith if (cols) { 11879566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->cmap->n, cols)); 1188d0f46423SBarry Smith for (i = 0; i < A->cmap->n; i++) (*cols)[i] = i; 1189289bc588SBarry Smith } 1190289bc588SBarry Smith if (vals) { 1191ca15aa20SStefano Zampini const PetscScalar *v; 1192ca15aa20SStefano Zampini 11939566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 11949566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->cmap->n, vals)); 1195ca15aa20SStefano Zampini v += row; 11969371c9d4SSatish Balay for (i = 0; i < A->cmap->n; i++) { 11979371c9d4SSatish Balay (*vals)[i] = *v; 11989371c9d4SSatish Balay v += mat->lda; 11999371c9d4SSatish Balay } 12009566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 1201289bc588SBarry Smith } 12023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1203289bc588SBarry Smith } 12046ee01492SSatish Balay 1205d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRestoreRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals) 1206d71ae5a4SJacob Faibussowitsch { 1207606d414cSSatish Balay PetscFunctionBegin; 12089566063dSJacob Faibussowitsch if (cols) PetscCall(PetscFree(*cols)); 12099566063dSJacob Faibussowitsch if (vals) PetscCall(PetscFree(*vals)); 12103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1211289bc588SBarry Smith } 12122ef1f0ffSBarry Smith 1213d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], const PetscScalar v[], InsertMode addv) 1214d71ae5a4SJacob Faibussowitsch { 1215c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1216ca15aa20SStefano Zampini PetscScalar *av; 121713f74950SBarry Smith PetscInt i, j, idx = 0; 121847d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1219c70f7ee4SJunchao Zhang PetscOffloadMask oldf; 1220ca15aa20SStefano Zampini #endif 1221d6dfbf8fSBarry Smith 12223a40ed3dSBarry Smith PetscFunctionBegin; 12239566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &av)); 1224289bc588SBarry Smith if (!mat->roworiented) { 1225dbb450caSBarry Smith if (addv == INSERT_VALUES) { 1226289bc588SBarry Smith for (j = 0; j < n; j++) { 12279371c9d4SSatish Balay if (indexn[j] < 0) { 12289371c9d4SSatish Balay idx += m; 12299371c9d4SSatish Balay continue; 12309371c9d4SSatish Balay } 12316bdcaf15SBarry 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); 1232289bc588SBarry Smith for (i = 0; i < m; i++) { 12339371c9d4SSatish Balay if (indexm[i] < 0) { 12349371c9d4SSatish Balay idx++; 12359371c9d4SSatish Balay continue; 12369371c9d4SSatish Balay } 12376bdcaf15SBarry Smith PetscCheck(indexm[i] < A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Row too large: row %" PetscInt_FMT " max %" PetscInt_FMT, indexm[i], A->rmap->n - 1); 1238*0be0d8bdSHansol Suh av[indexn[j] * mat->lda + indexm[i]] = v[idx++]; 1239289bc588SBarry Smith } 1240289bc588SBarry Smith } 1241*0be0d8bdSHansol Suh } else { 1242289bc588SBarry Smith for (j = 0; j < n; j++) { 12439371c9d4SSatish Balay if (indexn[j] < 0) { 12449371c9d4SSatish Balay idx += m; 12459371c9d4SSatish Balay continue; 12469371c9d4SSatish Balay } 12476bdcaf15SBarry 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); 1248289bc588SBarry Smith for (i = 0; i < m; i++) { 12499371c9d4SSatish Balay if (indexm[i] < 0) { 12509371c9d4SSatish Balay idx++; 12519371c9d4SSatish Balay continue; 12529371c9d4SSatish Balay } 12536bdcaf15SBarry Smith PetscCheck(indexm[i] < A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Row too large: row %" PetscInt_FMT " max %" PetscInt_FMT, indexm[i], A->rmap->n - 1); 1254ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] += v[idx++]; 1255289bc588SBarry Smith } 1256289bc588SBarry Smith } 1257289bc588SBarry Smith } 12583a40ed3dSBarry Smith } else { 1259dbb450caSBarry Smith if (addv == INSERT_VALUES) { 1260e8d4e0b9SBarry Smith for (i = 0; i < m; i++) { 12619371c9d4SSatish Balay if (indexm[i] < 0) { 12629371c9d4SSatish Balay idx += n; 12639371c9d4SSatish Balay continue; 12649371c9d4SSatish Balay } 12656bdcaf15SBarry 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); 1266e8d4e0b9SBarry Smith for (j = 0; j < n; j++) { 12679371c9d4SSatish Balay if (indexn[j] < 0) { 12689371c9d4SSatish Balay idx++; 12699371c9d4SSatish Balay continue; 12709371c9d4SSatish Balay } 12716bdcaf15SBarry 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); 1272*0be0d8bdSHansol Suh av[indexn[j] * mat->lda + indexm[i]] = v[idx++]; 1273e8d4e0b9SBarry Smith } 1274e8d4e0b9SBarry Smith } 1275*0be0d8bdSHansol Suh } else { 1276289bc588SBarry Smith for (i = 0; i < m; i++) { 12779371c9d4SSatish Balay if (indexm[i] < 0) { 12789371c9d4SSatish Balay idx += n; 12799371c9d4SSatish Balay continue; 12809371c9d4SSatish Balay } 12816bdcaf15SBarry 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); 1282289bc588SBarry Smith for (j = 0; j < n; j++) { 12839371c9d4SSatish Balay if (indexn[j] < 0) { 12849371c9d4SSatish Balay idx++; 12859371c9d4SSatish Balay continue; 12869371c9d4SSatish Balay } 12876bdcaf15SBarry 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); 1288ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] += v[idx++]; 1289289bc588SBarry Smith } 1290289bc588SBarry Smith } 1291289bc588SBarry Smith } 1292e8d4e0b9SBarry Smith } 1293ca15aa20SStefano Zampini /* hack to prevent unneeded copy to the GPU while returning the array */ 129447d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1295c70f7ee4SJunchao Zhang oldf = A->offloadmask; 1296c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_GPU; 1297ca15aa20SStefano Zampini #endif 12989566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &av)); 129947d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1300c70f7ee4SJunchao Zhang A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU); 1301ca15aa20SStefano Zampini #endif 13023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1303289bc588SBarry Smith } 1304e8d4e0b9SBarry Smith 1305d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], PetscScalar v[]) 1306d71ae5a4SJacob Faibussowitsch { 1307ae80bb75SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1308ca15aa20SStefano Zampini const PetscScalar *vv; 130913f74950SBarry Smith PetscInt i, j; 1310ae80bb75SLois Curfman McInnes 13113a40ed3dSBarry Smith PetscFunctionBegin; 13129566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &vv)); 1313ae80bb75SLois Curfman McInnes /* row-oriented output */ 1314ae80bb75SLois Curfman McInnes for (i = 0; i < m; i++) { 13159371c9d4SSatish Balay if (indexm[i] < 0) { 13169371c9d4SSatish Balay v += n; 13179371c9d4SSatish Balay continue; 13189371c9d4SSatish Balay } 131908401ef6SPierre 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); 1320ae80bb75SLois Curfman McInnes for (j = 0; j < n; j++) { 13219371c9d4SSatish Balay if (indexn[j] < 0) { 13229371c9d4SSatish Balay v++; 13239371c9d4SSatish Balay continue; 13249371c9d4SSatish Balay } 132508401ef6SPierre 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); 1326ca15aa20SStefano Zampini *v++ = vv[indexn[j] * mat->lda + indexm[i]]; 1327ae80bb75SLois Curfman McInnes } 1328ae80bb75SLois Curfman McInnes } 13299566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &vv)); 13303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1331ae80bb75SLois Curfman McInnes } 1332ae80bb75SLois Curfman McInnes 1333d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_Dense_Binary(Mat mat, PetscViewer viewer) 1334d71ae5a4SJacob Faibussowitsch { 13358491ab44SLisandro Dalcin PetscBool skipHeader; 13368491ab44SLisandro Dalcin PetscViewerFormat format; 13378491ab44SLisandro Dalcin PetscInt header[4], M, N, m, lda, i, j, k; 13388491ab44SLisandro Dalcin const PetscScalar *v; 13398491ab44SLisandro Dalcin PetscScalar *vwork; 1340aabbc4fbSShri Abhyankar 1341aabbc4fbSShri Abhyankar PetscFunctionBegin; 13429566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 13439566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader)); 13449566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 13458491ab44SLisandro Dalcin if (skipHeader) format = PETSC_VIEWER_NATIVE; 1346aabbc4fbSShri Abhyankar 13479566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &M, &N)); 13488491ab44SLisandro Dalcin 13498491ab44SLisandro Dalcin /* write matrix header */ 13509371c9d4SSatish Balay header[0] = MAT_FILE_CLASSID; 13519371c9d4SSatish Balay header[1] = M; 13529371c9d4SSatish Balay header[2] = N; 13538491ab44SLisandro Dalcin header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M * N; 13549566063dSJacob Faibussowitsch if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer, header, 4, PETSC_INT)); 13558491ab44SLisandro Dalcin 13569566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mat, &m, NULL)); 13578491ab44SLisandro Dalcin if (format != PETSC_VIEWER_NATIVE) { 13588491ab44SLisandro Dalcin PetscInt nnz = m * N, *iwork; 13598491ab44SLisandro Dalcin /* store row lengths for each row */ 13609566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz, &iwork)); 13618491ab44SLisandro Dalcin for (i = 0; i < m; i++) iwork[i] = N; 13629566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 13638491ab44SLisandro Dalcin /* store column indices (zero start index) */ 13648491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 13659371c9d4SSatish Balay for (j = 0; j < N; j++, k++) iwork[k] = j; 13669566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 13679566063dSJacob Faibussowitsch PetscCall(PetscFree(iwork)); 13688491ab44SLisandro Dalcin } 13698491ab44SLisandro Dalcin /* store matrix values as a dense matrix in row major order */ 13709566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m * N, &vwork)); 13719566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(mat, &v)); 13729566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(mat, &lda)); 13738491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 13749371c9d4SSatish Balay for (j = 0; j < N; j++, k++) vwork[k] = v[i + lda * j]; 13759566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(mat, &v)); 13769566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, vwork, m * N, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 13779566063dSJacob Faibussowitsch PetscCall(PetscFree(vwork)); 13783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13798491ab44SLisandro Dalcin } 13808491ab44SLisandro Dalcin 1381d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLoad_Dense_Binary(Mat mat, PetscViewer viewer) 1382d71ae5a4SJacob Faibussowitsch { 13838491ab44SLisandro Dalcin PetscBool skipHeader; 13848491ab44SLisandro Dalcin PetscInt header[4], M, N, m, nz, lda, i, j, k; 13858491ab44SLisandro Dalcin PetscInt rows, cols; 13868491ab44SLisandro Dalcin PetscScalar *v, *vwork; 13878491ab44SLisandro Dalcin 13888491ab44SLisandro Dalcin PetscFunctionBegin; 13899566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 13909566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader)); 13918491ab44SLisandro Dalcin 13928491ab44SLisandro Dalcin if (!skipHeader) { 13939566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, header, 4, NULL, PETSC_INT)); 139408401ef6SPierre Jolivet PetscCheck(header[0] == MAT_FILE_CLASSID, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Not a matrix object in file"); 13959371c9d4SSatish Balay M = header[1]; 13969371c9d4SSatish Balay N = header[2]; 139708401ef6SPierre Jolivet PetscCheck(M >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix row size (%" PetscInt_FMT ") in file is negative", M); 139808401ef6SPierre Jolivet PetscCheck(N >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix column size (%" PetscInt_FMT ") in file is negative", N); 13998491ab44SLisandro Dalcin nz = header[3]; 1400aed4548fSBarry Smith PetscCheck(nz == MATRIX_BINARY_FORMAT_DENSE || nz >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Unknown matrix format %" PetscInt_FMT " in file", nz); 1401aabbc4fbSShri Abhyankar } else { 14029566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &M, &N)); 1403aed4548fSBarry 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"); 14048491ab44SLisandro Dalcin nz = MATRIX_BINARY_FORMAT_DENSE; 1405e6324fbbSBarry Smith } 1406aabbc4fbSShri Abhyankar 14078491ab44SLisandro Dalcin /* setup global sizes if not set */ 14088491ab44SLisandro Dalcin if (mat->rmap->N < 0) mat->rmap->N = M; 14098491ab44SLisandro Dalcin if (mat->cmap->N < 0) mat->cmap->N = N; 14109566063dSJacob Faibussowitsch PetscCall(MatSetUp(mat)); 14118491ab44SLisandro Dalcin /* check if global sizes are correct */ 14129566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &rows, &cols)); 1413aed4548fSBarry 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); 1414aabbc4fbSShri Abhyankar 14159566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, NULL, &N)); 14169566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mat, &m, NULL)); 14179566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(mat, &v)); 14189566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(mat, &lda)); 14198491ab44SLisandro Dalcin if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense format */ 14208491ab44SLisandro Dalcin PetscInt nnz = m * N; 14218491ab44SLisandro Dalcin /* read in matrix values */ 14229566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz, &vwork)); 14239566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 14248491ab44SLisandro Dalcin /* store values in column major order */ 14258491ab44SLisandro Dalcin for (j = 0; j < N; j++) 14269371c9d4SSatish Balay for (i = 0; i < m; i++) v[i + lda * j] = vwork[i * N + j]; 14279566063dSJacob Faibussowitsch PetscCall(PetscFree(vwork)); 14288491ab44SLisandro Dalcin } else { /* matrix in file is sparse format */ 14298491ab44SLisandro Dalcin PetscInt nnz = 0, *rlens, *icols; 14308491ab44SLisandro Dalcin /* read in row lengths */ 14319566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m, &rlens)); 14329566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, rlens, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 14338491ab44SLisandro Dalcin for (i = 0; i < m; i++) nnz += rlens[i]; 14348491ab44SLisandro Dalcin /* read in column indices and values */ 14359566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(nnz, &icols, nnz, &vwork)); 14369566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, icols, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 14379566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 14388491ab44SLisandro Dalcin /* store values in column major order */ 14398491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 14409371c9d4SSatish Balay for (j = 0; j < rlens[i]; j++, k++) v[i + lda * icols[k]] = vwork[k]; 14419566063dSJacob Faibussowitsch PetscCall(PetscFree(rlens)); 14429566063dSJacob Faibussowitsch PetscCall(PetscFree2(icols, vwork)); 1443aabbc4fbSShri Abhyankar } 14449566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(mat, &v)); 14459566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY)); 14469566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY)); 14473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1448aabbc4fbSShri Abhyankar } 1449aabbc4fbSShri Abhyankar 145066976f2fSJacob Faibussowitsch static PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer) 1451d71ae5a4SJacob Faibussowitsch { 1452eb91f321SVaclav Hapla PetscBool isbinary, ishdf5; 1453eb91f321SVaclav Hapla 1454eb91f321SVaclav Hapla PetscFunctionBegin; 1455eb91f321SVaclav Hapla PetscValidHeaderSpecific(newMat, MAT_CLASSID, 1); 1456eb91f321SVaclav Hapla PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1457eb91f321SVaclav Hapla /* force binary viewer to load .info file if it has not yet done so */ 14589566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 14599566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 14609566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5)); 1461eb91f321SVaclav Hapla if (isbinary) { 14629566063dSJacob Faibussowitsch PetscCall(MatLoad_Dense_Binary(newMat, viewer)); 1463eb91f321SVaclav Hapla } else if (ishdf5) { 1464eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5) 14659566063dSJacob Faibussowitsch PetscCall(MatLoad_Dense_HDF5(newMat, viewer)); 1466eb91f321SVaclav Hapla #else 1467eb91f321SVaclav Hapla SETERRQ(PetscObjectComm((PetscObject)newMat), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1468eb91f321SVaclav Hapla #endif 1469eb91f321SVaclav Hapla } else { 147098921bdaSJacob 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); 1471eb91f321SVaclav Hapla } 14723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1473eb91f321SVaclav Hapla } 1474eb91f321SVaclav Hapla 1475d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_ASCII(Mat A, PetscViewer viewer) 1476d71ae5a4SJacob Faibussowitsch { 1477932b0c3eSLois Curfman McInnes Mat_SeqDense *a = (Mat_SeqDense *)A->data; 147813f74950SBarry Smith PetscInt i, j; 14792dcb1b2aSMatthew Knepley const char *name; 1480ca15aa20SStefano Zampini PetscScalar *v, *av; 1481f3ef73ceSBarry Smith PetscViewerFormat format; 14825f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX) 1483ace3abfcSBarry Smith PetscBool allreal = PETSC_TRUE; 14845f481a85SSatish Balay #endif 1485932b0c3eSLois Curfman McInnes 14863a40ed3dSBarry Smith PetscFunctionBegin; 14879566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&av)); 14889566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 1489456192e2SBarry Smith if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 14903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); /* do nothing for now */ 1491fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 14929566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE)); 1493d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 1494ca15aa20SStefano Zampini v = av + i; 14959566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "row %" PetscInt_FMT ":", i)); 1496d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1497aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 1498329f5518SBarry Smith if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) { 14999566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g + %g i) ", j, (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v))); 1500329f5518SBarry Smith } else if (PetscRealPart(*v)) { 15019566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)PetscRealPart(*v))); 15026831982aSBarry Smith } 150380cd9d93SLois Curfman McInnes #else 150448a46eb9SPierre Jolivet if (*v) PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)*v)); 150580cd9d93SLois Curfman McInnes #endif 15061b807ce4Svictorle v += a->lda; 150780cd9d93SLois Curfman McInnes } 15089566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 150980cd9d93SLois Curfman McInnes } 15109566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE)); 15113a40ed3dSBarry Smith } else { 15129566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE)); 1513aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 151447989497SBarry Smith /* determine if matrix has all real values */ 1515bcd8d3a4SJose E. Roman for (j = 0; j < A->cmap->n; j++) { 1516bcd8d3a4SJose E. Roman v = av + j * a->lda; 1517bcd8d3a4SJose E. Roman for (i = 0; i < A->rmap->n; i++) { 15189371c9d4SSatish Balay if (PetscImaginaryPart(v[i])) { 15199371c9d4SSatish Balay allreal = PETSC_FALSE; 15209371c9d4SSatish Balay break; 15219371c9d4SSatish Balay } 152247989497SBarry Smith } 1523bcd8d3a4SJose E. Roman } 152447989497SBarry Smith #endif 1525fb9695e5SSatish Balay if (format == PETSC_VIEWER_ASCII_MATLAB) { 15269566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)A, &name)); 15279566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%% Size = %" PetscInt_FMT " %" PetscInt_FMT " \n", A->rmap->n, A->cmap->n)); 15289566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%s = zeros(%" PetscInt_FMT ",%" PetscInt_FMT ");\n", name, A->rmap->n, A->cmap->n)); 15299566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%s = [\n", name)); 1530ffac6cdbSBarry Smith } 1531ffac6cdbSBarry Smith 1532d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 1533ca15aa20SStefano Zampini v = av + i; 1534d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1535aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 153647989497SBarry Smith if (allreal) { 15379566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)PetscRealPart(*v))); 153847989497SBarry Smith } else { 15399566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e + %18.16ei ", (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v))); 154047989497SBarry Smith } 1541289bc588SBarry Smith #else 15429566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)*v)); 1543289bc588SBarry Smith #endif 15441b807ce4Svictorle v += a->lda; 1545289bc588SBarry Smith } 15469566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 1547289bc588SBarry Smith } 154848a46eb9SPierre Jolivet if (format == PETSC_VIEWER_ASCII_MATLAB) PetscCall(PetscViewerASCIIPrintf(viewer, "];\n")); 15499566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE)); 1550da3a660dSBarry Smith } 15519566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&av)); 15529566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer)); 15533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1554289bc588SBarry Smith } 1555289bc588SBarry Smith 15569804daf3SBarry Smith #include <petscdraw.h> 1557d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw, void *Aa) 1558d71ae5a4SJacob Faibussowitsch { 1559f1af5d2fSBarry Smith Mat A = (Mat)Aa; 1560383922c3SLisandro Dalcin PetscInt m = A->rmap->n, n = A->cmap->n, i, j; 1561383922c3SLisandro Dalcin int color = PETSC_DRAW_WHITE; 1562ca15aa20SStefano Zampini const PetscScalar *v; 1563b0a32e0cSBarry Smith PetscViewer viewer; 1564b05fc000SLisandro Dalcin PetscReal xl, yl, xr, yr, x_l, x_r, y_l, y_r; 1565f3ef73ceSBarry Smith PetscViewerFormat format; 1566f1af5d2fSBarry Smith 1567f1af5d2fSBarry Smith PetscFunctionBegin; 15689566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)A, "Zoomviewer", (PetscObject *)&viewer)); 15699566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 15709566063dSJacob Faibussowitsch PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr)); 1571f1af5d2fSBarry Smith 1572f1af5d2fSBarry Smith /* Loop over matrix elements drawing boxes */ 15739566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 1574fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 1575d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 1576f1af5d2fSBarry Smith /* Blue for negative and Red for positive */ 1577f1af5d2fSBarry Smith for (j = 0; j < n; j++) { 15789371c9d4SSatish Balay x_l = j; 15799371c9d4SSatish Balay x_r = x_l + 1.0; 1580f1af5d2fSBarry Smith for (i = 0; i < m; i++) { 1581f1af5d2fSBarry Smith y_l = m - i - 1.0; 1582f1af5d2fSBarry Smith y_r = y_l + 1.0; 1583ca15aa20SStefano Zampini if (PetscRealPart(v[j * m + i]) > 0.) color = PETSC_DRAW_RED; 1584ca15aa20SStefano Zampini else if (PetscRealPart(v[j * m + i]) < 0.) color = PETSC_DRAW_BLUE; 1585ca15aa20SStefano Zampini else continue; 15869566063dSJacob Faibussowitsch PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color)); 1587f1af5d2fSBarry Smith } 1588f1af5d2fSBarry Smith } 1589d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 1590f1af5d2fSBarry Smith } else { 1591f1af5d2fSBarry Smith /* use contour shading to indicate magnitude of values */ 1592f1af5d2fSBarry Smith /* first determine max of all nonzero values */ 1593b05fc000SLisandro Dalcin PetscReal minv = 0.0, maxv = 0.0; 1594b05fc000SLisandro Dalcin PetscDraw popup; 1595b05fc000SLisandro Dalcin 1596f1af5d2fSBarry Smith for (i = 0; i < m * n; i++) { 1597f1af5d2fSBarry Smith if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]); 1598f1af5d2fSBarry Smith } 1599383922c3SLisandro Dalcin if (minv >= maxv) maxv = minv + PETSC_SMALL; 16009566063dSJacob Faibussowitsch PetscCall(PetscDrawGetPopup(draw, &popup)); 16019566063dSJacob Faibussowitsch PetscCall(PetscDrawScalePopup(popup, minv, maxv)); 1602383922c3SLisandro Dalcin 1603d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 1604f1af5d2fSBarry Smith for (j = 0; j < n; j++) { 1605f1af5d2fSBarry Smith x_l = j; 1606f1af5d2fSBarry Smith x_r = x_l + 1.0; 1607f1af5d2fSBarry Smith for (i = 0; i < m; i++) { 1608f1af5d2fSBarry Smith y_l = m - i - 1.0; 1609f1af5d2fSBarry Smith y_r = y_l + 1.0; 1610b05fc000SLisandro Dalcin color = PetscDrawRealToColor(PetscAbsScalar(v[j * m + i]), minv, maxv); 16119566063dSJacob Faibussowitsch PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color)); 1612f1af5d2fSBarry Smith } 1613f1af5d2fSBarry Smith } 1614d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 1615f1af5d2fSBarry Smith } 16169566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 16173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1618f1af5d2fSBarry Smith } 1619f1af5d2fSBarry Smith 1620d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw(Mat A, PetscViewer viewer) 1621d71ae5a4SJacob Faibussowitsch { 1622b0a32e0cSBarry Smith PetscDraw draw; 1623ace3abfcSBarry Smith PetscBool isnull; 1624329f5518SBarry Smith PetscReal xr, yr, xl, yl, h, w; 1625f1af5d2fSBarry Smith 1626f1af5d2fSBarry Smith PetscFunctionBegin; 16279566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 16289566063dSJacob Faibussowitsch PetscCall(PetscDrawIsNull(draw, &isnull)); 16293ba16761SJacob Faibussowitsch if (isnull) PetscFunctionReturn(PETSC_SUCCESS); 1630f1af5d2fSBarry Smith 16319371c9d4SSatish Balay xr = A->cmap->n; 16329371c9d4SSatish Balay yr = A->rmap->n; 16339371c9d4SSatish Balay h = yr / 10.0; 16349371c9d4SSatish Balay w = xr / 10.0; 16359371c9d4SSatish Balay xr += w; 16369371c9d4SSatish Balay yr += h; 16379371c9d4SSatish Balay xl = -w; 16389371c9d4SSatish Balay yl = -h; 16399566063dSJacob Faibussowitsch PetscCall(PetscDrawSetCoordinates(draw, xl, yl, xr, yr)); 16409566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", (PetscObject)viewer)); 16419566063dSJacob Faibussowitsch PetscCall(PetscDrawZoom(draw, MatView_SeqDense_Draw_Zoom, A)); 16429566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", NULL)); 16439566063dSJacob Faibussowitsch PetscCall(PetscDrawSave(draw)); 16443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1645f1af5d2fSBarry Smith } 1646f1af5d2fSBarry Smith 1647d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_SeqDense(Mat A, PetscViewer viewer) 1648d71ae5a4SJacob Faibussowitsch { 1649ace3abfcSBarry Smith PetscBool iascii, isbinary, isdraw; 1650932b0c3eSLois Curfman McInnes 16513a40ed3dSBarry Smith PetscFunctionBegin; 16529566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 16539566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 16549566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 16551baa6e33SBarry Smith if (iascii) PetscCall(MatView_SeqDense_ASCII(A, viewer)); 16561baa6e33SBarry Smith else if (isbinary) PetscCall(MatView_Dense_Binary(A, viewer)); 16571baa6e33SBarry Smith else if (isdraw) PetscCall(MatView_SeqDense_Draw(A, viewer)); 16583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1659932b0c3eSLois Curfman McInnes } 1660289bc588SBarry Smith 1661d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A, const PetscScalar *array) 1662d71ae5a4SJacob Faibussowitsch { 1663d3042a70SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1664d3042a70SBarry Smith 1665d3042a70SBarry Smith PetscFunctionBegin; 166628b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 166728b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 166828b400f6SJacob Faibussowitsch PetscCheck(!a->unplacedarray, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreArray() first"); 1669d3042a70SBarry Smith a->unplacedarray = a->v; 1670d3042a70SBarry Smith a->unplaced_user_alloc = a->user_alloc; 1671d3042a70SBarry Smith a->v = (PetscScalar *)array; 1672637a0070SStefano Zampini a->user_alloc = PETSC_TRUE; 167347d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1674c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_CPU; 1675ca15aa20SStefano Zampini #endif 16763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1677d3042a70SBarry Smith } 1678d3042a70SBarry Smith 1679d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseResetArray_SeqDense(Mat A) 1680d71ae5a4SJacob Faibussowitsch { 1681d3042a70SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1682d3042a70SBarry Smith 1683d3042a70SBarry Smith PetscFunctionBegin; 168428b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 168528b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 1686d3042a70SBarry Smith a->v = a->unplacedarray; 1687d3042a70SBarry Smith a->user_alloc = a->unplaced_user_alloc; 1688d3042a70SBarry Smith a->unplacedarray = NULL; 168947d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1690c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_CPU; 1691ca15aa20SStefano Zampini #endif 16923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1693d3042a70SBarry Smith } 1694d3042a70SBarry Smith 1695d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A, const PetscScalar *array) 1696d71ae5a4SJacob Faibussowitsch { 1697d5ea218eSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1698d5ea218eSStefano Zampini 1699d5ea218eSStefano Zampini PetscFunctionBegin; 170028b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 170128b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 17029566063dSJacob Faibussowitsch if (!a->user_alloc) PetscCall(PetscFree(a->v)); 1703d5ea218eSStefano Zampini a->v = (PetscScalar *)array; 1704d5ea218eSStefano Zampini a->user_alloc = PETSC_FALSE; 170547d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1706d5ea218eSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 1707d5ea218eSStefano Zampini #endif 17083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1709d5ea218eSStefano Zampini } 1710d5ea218eSStefano Zampini 1711d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDestroy_SeqDense(Mat mat) 1712d71ae5a4SJacob Faibussowitsch { 1713ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)mat->data; 171490f02eecSBarry Smith 17153a40ed3dSBarry Smith PetscFunctionBegin; 17163ba16761SJacob Faibussowitsch PetscCall(PetscLogObjectState((PetscObject)mat, "Rows %" PetscInt_FMT " Cols %" PetscInt_FMT, mat->rmap->n, mat->cmap->n)); 1717f4f49eeaSPierre Jolivet PetscCall(VecDestroy(&l->qrrhs)); 17189566063dSJacob Faibussowitsch PetscCall(PetscFree(l->tau)); 17199566063dSJacob Faibussowitsch PetscCall(PetscFree(l->pivots)); 17209566063dSJacob Faibussowitsch PetscCall(PetscFree(l->fwork)); 17219566063dSJacob Faibussowitsch if (!l->user_alloc) PetscCall(PetscFree(l->v)); 17229566063dSJacob Faibussowitsch if (!l->unplaced_user_alloc) PetscCall(PetscFree(l->unplacedarray)); 172328b400f6SJacob Faibussowitsch PetscCheck(!l->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 172428b400f6SJacob Faibussowitsch PetscCheck(!l->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 17259566063dSJacob Faibussowitsch PetscCall(VecDestroy(&l->cvec)); 17269566063dSJacob Faibussowitsch PetscCall(MatDestroy(&l->cmat)); 17279566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->data)); 1728dbd8c25aSHong Zhang 17299566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)mat, NULL)); 17309566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactor_C", NULL)); 17312e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorSymbolic_C", NULL)); 17322e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorNumeric_C", NULL)); 17339566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetLDA_C", NULL)); 17349566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseSetLDA_C", NULL)); 17359566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArray_C", NULL)); 17369566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArray_C", NULL)); 17379566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDensePlaceArray_C", NULL)); 17389566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseResetArray_C", NULL)); 17399566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseReplaceArray_C", NULL)); 17409566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayRead_C", NULL)); 17419566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayRead_C", NULL)); 17429566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayWrite_C", NULL)); 17439566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayWrite_C", NULL)); 17449566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqaij_C", NULL)); 17458baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 17469566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_elemental_C", NULL)); 17478baccfbdSHong Zhang #endif 1748d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 17499566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_scalapack_C", NULL)); 1750d24d4204SJose E. Roman #endif 17512bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA) 17529566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensecuda_C", NULL)); 17539566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", NULL)); 17549566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdense_C", NULL)); 17552e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensecuda_C", NULL)); 17562bf066beSStefano Zampini #endif 175747d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 175847d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensehip_C", NULL)); 175947d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensehip_seqdensehip_C", NULL)); 176047d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensehip_seqdense_C", NULL)); 176147d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensehip_C", NULL)); 176247d993e7Ssuyashtn #endif 17639566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatSeqDenseSetPreallocation_C", NULL)); 17649566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqaij_seqdense_C", NULL)); 17659566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdense_C", NULL)); 17669566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqbaij_seqdense_C", NULL)); 17679566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqsbaij_seqdense_C", NULL)); 176852c5f739Sprj- 17699566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumn_C", NULL)); 17709566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumn_C", NULL)); 17719566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVec_C", NULL)); 17729566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVec_C", NULL)); 17739566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecRead_C", NULL)); 17749566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecRead_C", NULL)); 17759566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecWrite_C", NULL)); 17769566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecWrite_C", NULL)); 17779566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetSubMatrix_C", NULL)); 17789566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreSubMatrix_C", NULL)); 1779*0be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatMultAddColumnRange_C", NULL)); 1780*0be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatMultHermitianTransposeColumnRange_C", NULL)); 1781*0be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatMultHermitianTransposeAddColumnRange_C", NULL)); 17823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1783289bc588SBarry Smith } 1784289bc588SBarry Smith 1785d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatTranspose_SeqDense(Mat A, MatReuse reuse, Mat *matout) 1786d71ae5a4SJacob Faibussowitsch { 1787c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 17886536e3caSStefano Zampini PetscInt k, j, m = A->rmap->n, M = mat->lda, n = A->cmap->n; 178987828ca2SBarry Smith PetscScalar *v, tmp; 179048b35521SBarry Smith 17913a40ed3dSBarry Smith PetscFunctionBegin; 17927fb60732SBarry Smith if (reuse == MAT_REUSE_MATRIX) PetscCall(MatTransposeCheckNonzeroState_Private(A, *matout)); 17936536e3caSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 17946536e3caSStefano Zampini if (m == n) { /* in place transpose */ 17959566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 1796d3e5ee88SLois Curfman McInnes for (j = 0; j < m; j++) { 1797289bc588SBarry Smith for (k = 0; k < j; k++) { 17981b807ce4Svictorle tmp = v[j + k * M]; 17991b807ce4Svictorle v[j + k * M] = v[k + j * M]; 18001b807ce4Svictorle v[k + j * M] = tmp; 1801289bc588SBarry Smith } 1802289bc588SBarry Smith } 18039566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 18046536e3caSStefano Zampini } else { /* reuse memory, temporary allocates new memory */ 18056536e3caSStefano Zampini PetscScalar *v2; 18066536e3caSStefano Zampini PetscLayout tmplayout; 18076536e3caSStefano Zampini 18089566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((size_t)m * n, &v2)); 18099566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 18106536e3caSStefano Zampini for (j = 0; j < n; j++) { 18116536e3caSStefano Zampini for (k = 0; k < m; k++) v2[j + (size_t)k * n] = v[k + (size_t)j * M]; 18126536e3caSStefano Zampini } 18139566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(v, v2, (size_t)m * n)); 18149566063dSJacob Faibussowitsch PetscCall(PetscFree(v2)); 18159566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 18166536e3caSStefano Zampini /* cleanup size dependent quantities */ 18179566063dSJacob Faibussowitsch PetscCall(VecDestroy(&mat->cvec)); 18189566063dSJacob Faibussowitsch PetscCall(MatDestroy(&mat->cmat)); 18199566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->pivots)); 18209566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->fwork)); 18216536e3caSStefano Zampini /* swap row/col layouts */ 18226536e3caSStefano Zampini mat->lda = n; 18236536e3caSStefano Zampini tmplayout = A->rmap; 18246536e3caSStefano Zampini A->rmap = A->cmap; 18256536e3caSStefano Zampini A->cmap = tmplayout; 18266536e3caSStefano Zampini } 18273a40ed3dSBarry Smith } else { /* out-of-place transpose */ 1828d3e5ee88SLois Curfman McInnes Mat tmat; 1829ec8511deSBarry Smith Mat_SeqDense *tmatd; 183087828ca2SBarry Smith PetscScalar *v2; 1831af36a384SStefano Zampini PetscInt M2; 1832ea709b57SSatish Balay 18336536e3caSStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 18349566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &tmat)); 18359566063dSJacob Faibussowitsch PetscCall(MatSetSizes(tmat, A->cmap->n, A->rmap->n, A->cmap->n, A->rmap->n)); 18369566063dSJacob Faibussowitsch PetscCall(MatSetType(tmat, ((PetscObject)A)->type_name)); 18379566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(tmat, NULL)); 1838ca15aa20SStefano Zampini } else tmat = *matout; 1839ca15aa20SStefano Zampini 18409566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&v)); 18419566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(tmat, &v2)); 1842ec8511deSBarry Smith tmatd = (Mat_SeqDense *)tmat->data; 1843ca15aa20SStefano Zampini M2 = tmatd->lda; 1844d3e5ee88SLois Curfman McInnes for (j = 0; j < n; j++) { 1845af36a384SStefano Zampini for (k = 0; k < m; k++) v2[j + k * M2] = v[k + j * M]; 1846d3e5ee88SLois Curfman McInnes } 18479566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(tmat, &v2)); 18489566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&v)); 18499566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(tmat, MAT_FINAL_ASSEMBLY)); 18509566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(tmat, MAT_FINAL_ASSEMBLY)); 18516536e3caSStefano Zampini *matout = tmat; 185248b35521SBarry Smith } 18533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1854289bc588SBarry Smith } 1855289bc588SBarry Smith 1856d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatEqual_SeqDense(Mat A1, Mat A2, PetscBool *flg) 1857d71ae5a4SJacob Faibussowitsch { 1858c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat1 = (Mat_SeqDense *)A1->data; 1859c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat2 = (Mat_SeqDense *)A2->data; 1860ca15aa20SStefano Zampini PetscInt i; 1861ca15aa20SStefano Zampini const PetscScalar *v1, *v2; 18629ea5d5aeSSatish Balay 18633a40ed3dSBarry Smith PetscFunctionBegin; 18649371c9d4SSatish Balay if (A1->rmap->n != A2->rmap->n) { 18659371c9d4SSatish Balay *flg = PETSC_FALSE; 18663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18679371c9d4SSatish Balay } 18689371c9d4SSatish Balay if (A1->cmap->n != A2->cmap->n) { 18699371c9d4SSatish Balay *flg = PETSC_FALSE; 18703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18719371c9d4SSatish Balay } 18729566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A1, &v1)); 18739566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A2, &v2)); 1874ca15aa20SStefano Zampini for (i = 0; i < A1->cmap->n; i++) { 18759566063dSJacob Faibussowitsch PetscCall(PetscArraycmp(v1, v2, A1->rmap->n, flg)); 18763ba16761SJacob Faibussowitsch if (*flg == PETSC_FALSE) PetscFunctionReturn(PETSC_SUCCESS); 1877ca15aa20SStefano Zampini v1 += mat1->lda; 1878ca15aa20SStefano Zampini v2 += mat2->lda; 18791b807ce4Svictorle } 18809566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A1, &v1)); 18819566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A2, &v2)); 188277c4ece6SBarry Smith *flg = PETSC_TRUE; 18833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1884289bc588SBarry Smith } 1885289bc588SBarry Smith 188614277c92SJacob Faibussowitsch PetscErrorCode MatGetDiagonal_SeqDense(Mat A, Vec v) 1887d71ae5a4SJacob Faibussowitsch { 1888c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 188913f74950SBarry Smith PetscInt i, n, len; 1890ca15aa20SStefano Zampini PetscScalar *x; 1891ca15aa20SStefano Zampini const PetscScalar *vv; 189244cd7ae7SLois Curfman McInnes 18933a40ed3dSBarry Smith PetscFunctionBegin; 18949566063dSJacob Faibussowitsch PetscCall(VecGetSize(v, &n)); 18959566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 1896d0f46423SBarry Smith len = PetscMin(A->rmap->n, A->cmap->n); 18979566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &vv)); 189808401ef6SPierre Jolivet PetscCheck(n == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming mat and vec"); 1899ad540459SPierre Jolivet for (i = 0; i < len; i++) x[i] = vv[i * mat->lda + i]; 19009566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &vv)); 19019566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 19023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1903289bc588SBarry Smith } 1904289bc588SBarry Smith 1905d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDiagonalScale_SeqDense(Mat A, Vec ll, Vec rr) 1906d71ae5a4SJacob Faibussowitsch { 1907c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1908f1ceaac6SMatthew G. Knepley const PetscScalar *l, *r; 1909ca15aa20SStefano Zampini PetscScalar x, *v, *vv; 1910d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n; 191155659b69SBarry Smith 19123a40ed3dSBarry Smith PetscFunctionBegin; 19139566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &vv)); 191428988994SBarry Smith if (ll) { 19159566063dSJacob Faibussowitsch PetscCall(VecGetSize(ll, &m)); 19169566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(ll, &l)); 191708401ef6SPierre Jolivet PetscCheck(m == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Left scaling vec wrong size"); 1918da3a660dSBarry Smith for (i = 0; i < m; i++) { 1919da3a660dSBarry Smith x = l[i]; 1920ca15aa20SStefano Zampini v = vv + i; 19219371c9d4SSatish Balay for (j = 0; j < n; j++) { 19229371c9d4SSatish Balay (*v) *= x; 19239371c9d4SSatish Balay v += mat->lda; 19249371c9d4SSatish Balay } 1925da3a660dSBarry Smith } 19269566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(ll, &l)); 19279566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * n * m)); 1928da3a660dSBarry Smith } 192928988994SBarry Smith if (rr) { 19309566063dSJacob Faibussowitsch PetscCall(VecGetSize(rr, &n)); 19319566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(rr, &r)); 193208401ef6SPierre Jolivet PetscCheck(n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Right scaling vec wrong size"); 1933da3a660dSBarry Smith for (i = 0; i < n; i++) { 1934da3a660dSBarry Smith x = r[i]; 1935ca15aa20SStefano Zampini v = vv + i * mat->lda; 19362205254eSKarl Rupp for (j = 0; j < m; j++) (*v++) *= x; 1937da3a660dSBarry Smith } 19389566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(rr, &r)); 19399566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * n * m)); 1940da3a660dSBarry Smith } 19419566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &vv)); 19423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1943289bc588SBarry Smith } 1944289bc588SBarry Smith 1945d71ae5a4SJacob Faibussowitsch PetscErrorCode MatNorm_SeqDense(Mat A, NormType type, PetscReal *nrm) 1946d71ae5a4SJacob Faibussowitsch { 1947c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1948ca15aa20SStefano Zampini PetscScalar *v, *vv; 1949329f5518SBarry Smith PetscReal sum = 0.0; 195075f6d85dSStefano Zampini PetscInt lda, m = A->rmap->n, i, j; 195155659b69SBarry Smith 19523a40ed3dSBarry Smith PetscFunctionBegin; 19539566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&vv)); 19549566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(A, &lda)); 1955ca15aa20SStefano Zampini v = vv; 1956289bc588SBarry Smith if (type == NORM_FROBENIUS) { 1957a5ce6ee0Svictorle if (lda > m) { 1958d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1959ca15aa20SStefano Zampini v = vv + j * lda; 1960a5ce6ee0Svictorle for (i = 0; i < m; i++) { 19619371c9d4SSatish Balay sum += PetscRealPart(PetscConj(*v) * (*v)); 19629371c9d4SSatish Balay v++; 1963a5ce6ee0Svictorle } 1964a5ce6ee0Svictorle } 1965a5ce6ee0Svictorle } else { 1966570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16) 1967570b7f6dSBarry Smith PetscBLASInt one = 1, cnt = A->cmap->n * A->rmap->n; 1968792fecdfSBarry Smith PetscCallBLAS("BLASnrm2", *nrm = BLASnrm2_(&cnt, v, &one)); 1969570b7f6dSBarry Smith } 1970570b7f6dSBarry Smith #else 1971d0f46423SBarry Smith for (i = 0; i < A->cmap->n * A->rmap->n; i++) { 19729371c9d4SSatish Balay sum += PetscRealPart(PetscConj(*v) * (*v)); 19739371c9d4SSatish Balay v++; 1974289bc588SBarry Smith } 1975a5ce6ee0Svictorle } 19768f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 1977570b7f6dSBarry Smith #endif 19789566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->cmap->n * A->rmap->n)); 19793a40ed3dSBarry Smith } else if (type == NORM_1) { 1980064f8208SBarry Smith *nrm = 0.0; 1981d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1982ca15aa20SStefano Zampini v = vv + j * mat->lda; 1983289bc588SBarry Smith sum = 0.0; 1984d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 19859371c9d4SSatish Balay sum += PetscAbsScalar(*v); 19869371c9d4SSatish Balay v++; 1987289bc588SBarry Smith } 1988064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 1989289bc588SBarry Smith } 19909566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n)); 19913a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 1992064f8208SBarry Smith *nrm = 0.0; 1993d0f46423SBarry Smith for (j = 0; j < A->rmap->n; j++) { 1994ca15aa20SStefano Zampini v = vv + j; 1995289bc588SBarry Smith sum = 0.0; 1996d0f46423SBarry Smith for (i = 0; i < A->cmap->n; i++) { 19979371c9d4SSatish Balay sum += PetscAbsScalar(*v); 19989371c9d4SSatish Balay v += mat->lda; 1999289bc588SBarry Smith } 2000064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 2001289bc588SBarry Smith } 20029566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n)); 2003e7e72b3dSBarry Smith } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "No two norm"); 20049566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&vv)); 20053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2006289bc588SBarry Smith } 2007289bc588SBarry Smith 2008d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetOption_SeqDense(Mat A, MatOption op, PetscBool flg) 2009d71ae5a4SJacob Faibussowitsch { 2010c0bbcb79SLois Curfman McInnes Mat_SeqDense *aij = (Mat_SeqDense *)A->data; 201167e560aaSBarry Smith 20123a40ed3dSBarry Smith PetscFunctionBegin; 2013b5a2b587SKris Buschelman switch (op) { 2014d71ae5a4SJacob Faibussowitsch case MAT_ROW_ORIENTED: 2015d71ae5a4SJacob Faibussowitsch aij->roworiented = flg; 2016d71ae5a4SJacob Faibussowitsch break; 2017512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 2018b5a2b587SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 20193971808eSMatthew Knepley case MAT_NEW_NONZERO_ALLOCATION_ERR: 20208c78258cSHong Zhang case MAT_FORCE_DIAGONAL_ENTRIES: 202113fa8e87SLisandro Dalcin case MAT_KEEP_NONZERO_PATTERN: 2022b5a2b587SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 2023b5a2b587SKris Buschelman case MAT_USE_HASH_TABLE: 20240f8fb01aSBarry Smith case MAT_IGNORE_ZERO_ENTRIES: 20255021d80fSJed Brown case MAT_IGNORE_LOWER_TRIANGULAR: 2026d71ae5a4SJacob Faibussowitsch case MAT_SORTED_FULL: 2027d71ae5a4SJacob Faibussowitsch PetscCall(PetscInfo(A, "Option %s ignored\n", MatOptions[op])); 2028d71ae5a4SJacob Faibussowitsch break; 20295021d80fSJed Brown case MAT_SPD: 203077e54ba9SKris Buschelman case MAT_SYMMETRIC: 203177e54ba9SKris Buschelman case MAT_STRUCTURALLY_SYMMETRIC: 20329a4540c5SBarry Smith case MAT_HERMITIAN: 20339a4540c5SBarry Smith case MAT_SYMMETRY_ETERNAL: 2034b94d7dedSBarry Smith case MAT_STRUCTURAL_SYMMETRY_ETERNAL: 2035d71ae5a4SJacob Faibussowitsch case MAT_SPD_ETERNAL: 2036d71ae5a4SJacob Faibussowitsch break; 2037d71ae5a4SJacob Faibussowitsch default: 2038d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "unknown option %s", MatOptions[op]); 20393a40ed3dSBarry Smith } 20403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2041289bc588SBarry Smith } 2042289bc588SBarry Smith 2043d71ae5a4SJacob Faibussowitsch PetscErrorCode MatZeroEntries_SeqDense(Mat A) 2044d71ae5a4SJacob Faibussowitsch { 2045ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)A->data; 20463d8925e7SStefano Zampini PetscInt lda = l->lda, m = A->rmap->n, n = A->cmap->n, j; 2047ca15aa20SStefano Zampini PetscScalar *v; 20483a40ed3dSBarry Smith 20493a40ed3dSBarry Smith PetscFunctionBegin; 20509566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(A, &v)); 2051a5ce6ee0Svictorle if (lda > m) { 205248a46eb9SPierre Jolivet for (j = 0; j < n; j++) PetscCall(PetscArrayzero(v + j * lda, m)); 2053a5ce6ee0Svictorle } else { 20549566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(v, PetscInt64Mult(m, n))); 2055a5ce6ee0Svictorle } 20569566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(A, &v)); 20573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 20586f0a148fSBarry Smith } 20596f0a148fSBarry Smith 2060d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatZeroRows_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) 2061d71ae5a4SJacob Faibussowitsch { 2062ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)A->data; 2063b9679d65SBarry Smith PetscInt m = l->lda, n = A->cmap->n, i, j; 2064ca15aa20SStefano Zampini PetscScalar *slot, *bb, *v; 206597b48c8fSBarry Smith const PetscScalar *xx; 206655659b69SBarry Smith 20673a40ed3dSBarry Smith PetscFunctionBegin; 206876bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 2069b9679d65SBarry Smith for (i = 0; i < N; i++) { 207008401ef6SPierre Jolivet PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed"); 207108401ef6SPierre 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); 2072b9679d65SBarry Smith } 207376bd3646SJed Brown } 20743ba16761SJacob Faibussowitsch if (!N) PetscFunctionReturn(PETSC_SUCCESS); 2075b9679d65SBarry Smith 2076dd8e379bSPierre Jolivet /* fix right-hand side if needed */ 207797b48c8fSBarry Smith if (x && b) { 20789566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 20799566063dSJacob Faibussowitsch PetscCall(VecGetArray(b, &bb)); 20802205254eSKarl Rupp for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]]; 20819566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 20829566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(b, &bb)); 208397b48c8fSBarry Smith } 208497b48c8fSBarry Smith 20859566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 20866f0a148fSBarry Smith for (i = 0; i < N; i++) { 2087ca15aa20SStefano Zampini slot = v + rows[i]; 20889371c9d4SSatish Balay for (j = 0; j < n; j++) { 20899371c9d4SSatish Balay *slot = 0.0; 20909371c9d4SSatish Balay slot += m; 20919371c9d4SSatish Balay } 20926f0a148fSBarry Smith } 2093f4df32b1SMatthew Knepley if (diag != 0.0) { 209408401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices"); 20956f0a148fSBarry Smith for (i = 0; i < N; i++) { 2096ca15aa20SStefano Zampini slot = v + (m + 1) * rows[i]; 2097f4df32b1SMatthew Knepley *slot = diag; 20986f0a148fSBarry Smith } 20996f0a148fSBarry Smith } 21009566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 21013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 21026f0a148fSBarry Smith } 2103557bce09SLois Curfman McInnes 2104d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A, PetscInt *lda) 2105d71ae5a4SJacob Faibussowitsch { 210649a6ff4bSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 210749a6ff4bSBarry Smith 210849a6ff4bSBarry Smith PetscFunctionBegin; 210949a6ff4bSBarry Smith *lda = mat->lda; 21103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 211149a6ff4bSBarry Smith } 211249a6ff4bSBarry Smith 2113d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArray_SeqDense(Mat A, PetscScalar **array) 2114d71ae5a4SJacob Faibussowitsch { 2115c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 21163a40ed3dSBarry Smith 21173a40ed3dSBarry Smith PetscFunctionBegin; 211828b400f6SJacob Faibussowitsch PetscCheck(!mat->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 211964e87e97SBarry Smith *array = mat->v; 21203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 212164e87e97SBarry Smith } 21220754003eSLois Curfman McInnes 2123d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A, PetscScalar **array) 2124d71ae5a4SJacob Faibussowitsch { 21253a40ed3dSBarry Smith PetscFunctionBegin; 212675f6d85dSStefano Zampini if (array) *array = NULL; 21273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2128ff14e315SSatish Balay } 21290754003eSLois Curfman McInnes 21300f74d2c1SSatish Balay /*@ 213111a5261eSBarry Smith MatDenseGetLDA - gets the leading dimension of the array returned from `MatDenseGetArray()` 213249a6ff4bSBarry Smith 21332ef1f0ffSBarry Smith Not Collective 213449a6ff4bSBarry Smith 213549a6ff4bSBarry Smith Input Parameter: 2136fe59aa6dSJacob Faibussowitsch . A - a `MATDENSE` or `MATDENSECUDA` matrix 213749a6ff4bSBarry Smith 213849a6ff4bSBarry Smith Output Parameter: 213949a6ff4bSBarry Smith . lda - the leading dimension 214049a6ff4bSBarry Smith 214149a6ff4bSBarry Smith Level: intermediate 214249a6ff4bSBarry Smith 21431cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseSetLDA()` 214449a6ff4bSBarry Smith @*/ 2145d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetLDA(Mat A, PetscInt *lda) 2146d71ae5a4SJacob Faibussowitsch { 214749a6ff4bSBarry Smith PetscFunctionBegin; 2148d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 21494f572ea9SToby Isaac PetscAssertPointer(lda, 2); 215075f6d85dSStefano Zampini MatCheckPreallocated(A, 1); 2151cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetLDA_C", (Mat, PetscInt *), (A, lda)); 21523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 215349a6ff4bSBarry Smith } 215449a6ff4bSBarry Smith 21550f74d2c1SSatish Balay /*@ 215611a5261eSBarry Smith MatDenseSetLDA - Sets the leading dimension of the array used by the `MATDENSE` matrix 2157ad16ce7aSStefano Zampini 21582323109cSBarry Smith Collective if the matrix layouts have not yet been setup 2159ad16ce7aSStefano Zampini 2160d8d19677SJose E. Roman Input Parameters: 2161fe59aa6dSJacob Faibussowitsch + A - a `MATDENSE` or `MATDENSECUDA` matrix 2162ad16ce7aSStefano Zampini - lda - the leading dimension 2163ad16ce7aSStefano Zampini 2164ad16ce7aSStefano Zampini Level: intermediate 2165ad16ce7aSStefano Zampini 21661cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetLDA()` 2167ad16ce7aSStefano Zampini @*/ 2168d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA(Mat A, PetscInt lda) 2169d71ae5a4SJacob Faibussowitsch { 2170ad16ce7aSStefano Zampini PetscFunctionBegin; 2171ad16ce7aSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2172cac4c232SBarry Smith PetscTryMethod(A, "MatDenseSetLDA_C", (Mat, PetscInt), (A, lda)); 21733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2174ad16ce7aSStefano Zampini } 2175ad16ce7aSStefano Zampini 2176ad16ce7aSStefano Zampini /*@C 217711a5261eSBarry Smith MatDenseGetArray - gives read-write access to the array where the data for a `MATDENSE` matrix is stored 217873a71a0fSBarry Smith 2179c3339decSBarry Smith Logically Collective 218073a71a0fSBarry Smith 218173a71a0fSBarry Smith Input Parameter: 2182fe59aa6dSJacob Faibussowitsch . A - a dense matrix 218373a71a0fSBarry Smith 218473a71a0fSBarry Smith Output Parameter: 218573a71a0fSBarry Smith . array - pointer to the data 218673a71a0fSBarry Smith 218773a71a0fSBarry Smith Level: intermediate 218873a71a0fSBarry Smith 2189fe59aa6dSJacob Faibussowitsch Fortran Notes: 21900ab4885dSBarry Smith `MatDenseGetArray()` Fortran binding is deprecated (since PETSc 3.19), use `MatDenseGetArrayF90()` 21910ab4885dSBarry Smith 21921cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 219373a71a0fSBarry Smith @*/ 2194d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArray(Mat A, PetscScalar **array) 2195d71ae5a4SJacob Faibussowitsch { 219673a71a0fSBarry Smith PetscFunctionBegin; 2197d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 21984f572ea9SToby Isaac PetscAssertPointer(array, 2); 2199cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array)); 22003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 220173a71a0fSBarry Smith } 220273a71a0fSBarry Smith 2203dec5eb66SMatthew G Knepley /*@C 220411a5261eSBarry Smith MatDenseRestoreArray - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArray()` 220573a71a0fSBarry Smith 2206c3339decSBarry Smith Logically Collective 22078572280aSBarry Smith 22088572280aSBarry Smith Input Parameters: 2209fe59aa6dSJacob Faibussowitsch + A - a dense matrix 22102ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`) 22118572280aSBarry Smith 22128572280aSBarry Smith Level: intermediate 22138572280aSBarry Smith 2214fe59aa6dSJacob Faibussowitsch Fortran Notes: 22150ab4885dSBarry Smith `MatDenseRestoreArray()` Fortran binding is deprecated (since PETSc 3.19), use `MatDenseRestoreArrayF90()` 22160ab4885dSBarry Smith 22171cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 22188572280aSBarry Smith @*/ 2219d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArray(Mat A, PetscScalar **array) 2220d71ae5a4SJacob Faibussowitsch { 22218572280aSBarry Smith PetscFunctionBegin; 2222d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22234f572ea9SToby Isaac if (array) PetscAssertPointer(array, 2); 2224cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array)); 22259566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)A)); 222647d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 2227637a0070SStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 2228637a0070SStefano Zampini #endif 22293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22308572280aSBarry Smith } 22318572280aSBarry Smith 22328572280aSBarry Smith /*@C 223311a5261eSBarry Smith MatDenseGetArrayRead - gives read-only access to the array where the data for a `MATDENSE` matrix is stored 22348572280aSBarry Smith 2235fb850c59SBarry Smith Not Collective 22368572280aSBarry Smith 22378572280aSBarry Smith Input Parameter: 2238fe59aa6dSJacob Faibussowitsch . A - a dense matrix 22398572280aSBarry Smith 22408572280aSBarry Smith Output Parameter: 22418572280aSBarry Smith . array - pointer to the data 22428572280aSBarry Smith 22438572280aSBarry Smith Level: intermediate 22448572280aSBarry Smith 22451cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 22468572280aSBarry Smith @*/ 2247d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArrayRead(Mat A, const PetscScalar **array) 2248d71ae5a4SJacob Faibussowitsch { 22498572280aSBarry Smith PetscFunctionBegin; 2250d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22514f572ea9SToby Isaac PetscAssertPointer(array, 2); 22525c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 22533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22548572280aSBarry Smith } 22558572280aSBarry Smith 22568572280aSBarry Smith /*@C 225711a5261eSBarry Smith MatDenseRestoreArrayRead - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayRead()` 22588572280aSBarry Smith 2259fb850c59SBarry Smith Not Collective 226073a71a0fSBarry Smith 226173a71a0fSBarry Smith Input Parameters: 2262fe59aa6dSJacob Faibussowitsch + A - a dense matrix 22632ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`) 226473a71a0fSBarry Smith 226573a71a0fSBarry Smith Level: intermediate 226673a71a0fSBarry Smith 22671cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 226873a71a0fSBarry Smith @*/ 2269d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArrayRead(Mat A, const PetscScalar **array) 2270d71ae5a4SJacob Faibussowitsch { 227173a71a0fSBarry Smith PetscFunctionBegin; 2272d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22734f572ea9SToby Isaac if (array) PetscAssertPointer(array, 2); 22745c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 22753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 227673a71a0fSBarry Smith } 227773a71a0fSBarry Smith 22786947451fSStefano Zampini /*@C 227911a5261eSBarry Smith MatDenseGetArrayWrite - gives write-only access to the array where the data for a `MATDENSE` matrix is stored 22806947451fSStefano Zampini 2281fb850c59SBarry Smith Not Collective 22826947451fSStefano Zampini 22836947451fSStefano Zampini Input Parameter: 2284fe59aa6dSJacob Faibussowitsch . A - a dense matrix 22856947451fSStefano Zampini 22866947451fSStefano Zampini Output Parameter: 22876947451fSStefano Zampini . array - pointer to the data 22886947451fSStefano Zampini 22896947451fSStefano Zampini Level: intermediate 22906947451fSStefano Zampini 22911cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()` 22926947451fSStefano Zampini @*/ 2293d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArrayWrite(Mat A, PetscScalar **array) 2294d71ae5a4SJacob Faibussowitsch { 22956947451fSStefano Zampini PetscFunctionBegin; 2296d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 22974f572ea9SToby Isaac PetscAssertPointer(array, 2); 2298cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array)); 22993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23006947451fSStefano Zampini } 23016947451fSStefano Zampini 23026947451fSStefano Zampini /*@C 230311a5261eSBarry Smith MatDenseRestoreArrayWrite - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayWrite()` 23046947451fSStefano Zampini 2305fb850c59SBarry Smith Not Collective 23066947451fSStefano Zampini 23076947451fSStefano Zampini Input Parameters: 2308fe59aa6dSJacob Faibussowitsch + A - a dense matrix 23092ef1f0ffSBarry Smith - array - pointer to the data (may be `NULL`) 23106947451fSStefano Zampini 23116947451fSStefano Zampini Level: intermediate 23126947451fSStefano Zampini 23131cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()` 23146947451fSStefano Zampini @*/ 2315d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArrayWrite(Mat A, PetscScalar **array) 2316d71ae5a4SJacob Faibussowitsch { 23176947451fSStefano Zampini PetscFunctionBegin; 2318d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 23194f572ea9SToby Isaac if (array) PetscAssertPointer(array, 2); 2320cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array)); 23219566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)A)); 232247d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 23236947451fSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 23246947451fSStefano Zampini #endif 23253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23266947451fSStefano Zampini } 23276947451fSStefano Zampini 2328cd3f9d89SJunchao Zhang /*@C 2329cd3f9d89SJunchao Zhang MatDenseGetArrayAndMemType - gives read-write access to the array where the data for a `MATDENSE` matrix is stored 2330cd3f9d89SJunchao Zhang 2331cd3f9d89SJunchao Zhang Logically Collective 2332cd3f9d89SJunchao Zhang 2333cd3f9d89SJunchao Zhang Input Parameter: 2334fe59aa6dSJacob Faibussowitsch . A - a dense matrix 2335cd3f9d89SJunchao Zhang 2336cd3f9d89SJunchao Zhang Output Parameters: 2337cd3f9d89SJunchao Zhang + array - pointer to the data 2338cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer 2339cd3f9d89SJunchao Zhang 2340cd3f9d89SJunchao Zhang Level: intermediate 2341cd3f9d89SJunchao Zhang 2342fb850c59SBarry Smith Note: 23432ef1f0ffSBarry Smith If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc., 23442ef1f0ffSBarry Smith an array on device is always returned and is guaranteed to contain the matrix's latest data. 23452ef1f0ffSBarry Smith 23461cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayAndMemType()`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArrayWriteAndMemType()`, `MatDenseGetArrayRead()`, 2347cd3f9d89SJunchao Zhang `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()` 2348cd3f9d89SJunchao Zhang @*/ 2349cd3f9d89SJunchao Zhang PetscErrorCode MatDenseGetArrayAndMemType(Mat A, PetscScalar **array, PetscMemType *mtype) 2350cd3f9d89SJunchao Zhang { 2351cd3f9d89SJunchao Zhang PetscBool isMPI; 2352cd3f9d89SJunchao Zhang 2353cd3f9d89SJunchao Zhang PetscFunctionBegin; 2354cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 23554f572ea9SToby Isaac PetscAssertPointer(array, 2); 2356e865de01SJunchao 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 */ 2357cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2358cd3f9d89SJunchao Zhang if (isMPI) { 2359cd3f9d89SJunchao Zhang /* Dispatch here so that the code can be reused for all subclasses of MATDENSE */ 2360cd3f9d89SJunchao Zhang PetscCall(MatDenseGetArrayAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype)); 2361cd3f9d89SJunchao Zhang } else { 2362cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **, PetscMemType *); 23633ba16761SJacob Faibussowitsch 23643ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayAndMemType_C", &fptr)); 2365cd3f9d89SJunchao Zhang if (fptr) { 2366cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array, mtype)); 2367cd3f9d89SJunchao Zhang } else { 2368cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array)); 2369cd3f9d89SJunchao Zhang if (mtype) *mtype = PETSC_MEMTYPE_HOST; 2370cd3f9d89SJunchao Zhang } 2371cd3f9d89SJunchao Zhang } 23723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2373cd3f9d89SJunchao Zhang } 2374cd3f9d89SJunchao Zhang 2375cd3f9d89SJunchao Zhang /*@C 2376cd3f9d89SJunchao Zhang MatDenseRestoreArrayAndMemType - returns access to the array that is obtained by `MatDenseGetArrayAndMemType()` 2377cd3f9d89SJunchao Zhang 2378cd3f9d89SJunchao Zhang Logically Collective 2379cd3f9d89SJunchao Zhang 2380cd3f9d89SJunchao Zhang Input Parameters: 2381fe59aa6dSJacob Faibussowitsch + A - a dense matrix 2382cd3f9d89SJunchao Zhang - array - pointer to the data 2383cd3f9d89SJunchao Zhang 2384cd3f9d89SJunchao Zhang Level: intermediate 2385cd3f9d89SJunchao Zhang 23861cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 2387cd3f9d89SJunchao Zhang @*/ 2388cd3f9d89SJunchao Zhang PetscErrorCode MatDenseRestoreArrayAndMemType(Mat A, PetscScalar **array) 2389cd3f9d89SJunchao Zhang { 2390cd3f9d89SJunchao Zhang PetscBool isMPI; 2391cd3f9d89SJunchao Zhang 2392cd3f9d89SJunchao Zhang PetscFunctionBegin; 2393cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 23944f572ea9SToby Isaac PetscAssertPointer(array, 2); 2395cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2396cd3f9d89SJunchao Zhang if (isMPI) { 2397cd3f9d89SJunchao Zhang PetscCall(MatDenseRestoreArrayAndMemType(((Mat_MPIDense *)A->data)->A, array)); 2398cd3f9d89SJunchao Zhang } else { 2399cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **); 24003ba16761SJacob Faibussowitsch 24013ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayAndMemType_C", &fptr)); 2402cd3f9d89SJunchao Zhang if (fptr) { 2403cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array)); 2404cd3f9d89SJunchao Zhang } else { 2405cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array)); 2406cd3f9d89SJunchao Zhang } 2407cd3f9d89SJunchao Zhang *array = NULL; 2408cd3f9d89SJunchao Zhang } 2409cd3f9d89SJunchao Zhang PetscCall(PetscObjectStateIncrease((PetscObject)A)); 24103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2411cd3f9d89SJunchao Zhang } 2412cd3f9d89SJunchao Zhang 2413cd3f9d89SJunchao Zhang /*@C 2414cd3f9d89SJunchao Zhang MatDenseGetArrayReadAndMemType - gives read-only access to the array where the data for a `MATDENSE` matrix is stored 2415cd3f9d89SJunchao Zhang 2416cd3f9d89SJunchao Zhang Logically Collective 2417cd3f9d89SJunchao Zhang 2418cd3f9d89SJunchao Zhang Input Parameter: 2419fe59aa6dSJacob Faibussowitsch . A - a dense matrix 2420cd3f9d89SJunchao Zhang 2421cd3f9d89SJunchao Zhang Output Parameters: 2422cd3f9d89SJunchao Zhang + array - pointer to the data 2423cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer 2424cd3f9d89SJunchao Zhang 2425cd3f9d89SJunchao Zhang Level: intermediate 2426cd3f9d89SJunchao Zhang 2427fb850c59SBarry Smith Note: 24282ef1f0ffSBarry Smith If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc., 24292ef1f0ffSBarry Smith an array on device is always returned and is guaranteed to contain the matrix's latest data. 24302ef1f0ffSBarry Smith 24311cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayReadAndMemType()`, `MatDenseGetArrayWriteAndMemType()`, 2432cd3f9d89SJunchao Zhang `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()` 2433cd3f9d89SJunchao Zhang @*/ 2434cd3f9d89SJunchao Zhang PetscErrorCode MatDenseGetArrayReadAndMemType(Mat A, const PetscScalar **array, PetscMemType *mtype) 2435cd3f9d89SJunchao Zhang { 2436cd3f9d89SJunchao Zhang PetscBool isMPI; 2437cd3f9d89SJunchao Zhang 2438cd3f9d89SJunchao Zhang PetscFunctionBegin; 2439cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 24404f572ea9SToby Isaac PetscAssertPointer(array, 2); 2441e865de01SJunchao 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 */ 2442cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2443cd3f9d89SJunchao Zhang if (isMPI) { /* Dispatch here so that the code can be reused for all subclasses of MATDENSE */ 2444cd3f9d89SJunchao Zhang PetscCall(MatDenseGetArrayReadAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype)); 2445cd3f9d89SJunchao Zhang } else { 2446cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, const PetscScalar **, PetscMemType *); 24473ba16761SJacob Faibussowitsch 24483ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayReadAndMemType_C", &fptr)); 2449cd3f9d89SJunchao Zhang if (fptr) { 2450cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array, mtype)); 2451cd3f9d89SJunchao Zhang } else { 24525c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 2453cd3f9d89SJunchao Zhang if (mtype) *mtype = PETSC_MEMTYPE_HOST; 2454cd3f9d89SJunchao Zhang } 2455cd3f9d89SJunchao Zhang } 24563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2457cd3f9d89SJunchao Zhang } 2458cd3f9d89SJunchao Zhang 2459cd3f9d89SJunchao Zhang /*@C 2460cd3f9d89SJunchao Zhang MatDenseRestoreArrayReadAndMemType - returns access to the array that is obtained by `MatDenseGetArrayReadAndMemType()` 2461cd3f9d89SJunchao Zhang 2462cd3f9d89SJunchao Zhang Logically Collective 2463cd3f9d89SJunchao Zhang 2464cd3f9d89SJunchao Zhang Input Parameters: 2465fe59aa6dSJacob Faibussowitsch + A - a dense matrix 2466cd3f9d89SJunchao Zhang - array - pointer to the data 2467cd3f9d89SJunchao Zhang 2468cd3f9d89SJunchao Zhang Level: intermediate 2469cd3f9d89SJunchao Zhang 24701cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 2471cd3f9d89SJunchao Zhang @*/ 2472cd3f9d89SJunchao Zhang PetscErrorCode MatDenseRestoreArrayReadAndMemType(Mat A, const PetscScalar **array) 2473cd3f9d89SJunchao Zhang { 2474cd3f9d89SJunchao Zhang PetscBool isMPI; 2475cd3f9d89SJunchao Zhang 2476cd3f9d89SJunchao Zhang PetscFunctionBegin; 2477cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 24784f572ea9SToby Isaac PetscAssertPointer(array, 2); 2479cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2480cd3f9d89SJunchao Zhang if (isMPI) { 2481cd3f9d89SJunchao Zhang PetscCall(MatDenseRestoreArrayReadAndMemType(((Mat_MPIDense *)A->data)->A, array)); 2482cd3f9d89SJunchao Zhang } else { 2483cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, const PetscScalar **); 24843ba16761SJacob Faibussowitsch 24853ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayReadAndMemType_C", &fptr)); 2486cd3f9d89SJunchao Zhang if (fptr) { 2487cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array)); 2488cd3f9d89SJunchao Zhang } else { 24895c0db29aSPierre Jolivet PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, PetscScalar **), (A, (PetscScalar **)array)); 2490cd3f9d89SJunchao Zhang } 2491cd3f9d89SJunchao Zhang *array = NULL; 2492cd3f9d89SJunchao Zhang } 24933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2494cd3f9d89SJunchao Zhang } 2495cd3f9d89SJunchao Zhang 2496cd3f9d89SJunchao Zhang /*@C 2497cd3f9d89SJunchao Zhang MatDenseGetArrayWriteAndMemType - gives write-only access to the array where the data for a `MATDENSE` matrix is stored 2498cd3f9d89SJunchao Zhang 2499cd3f9d89SJunchao Zhang Logically Collective 2500cd3f9d89SJunchao Zhang 2501cd3f9d89SJunchao Zhang Input Parameter: 2502fe59aa6dSJacob Faibussowitsch . A - a dense matrix 2503cd3f9d89SJunchao Zhang 2504cd3f9d89SJunchao Zhang Output Parameters: 2505cd3f9d89SJunchao Zhang + array - pointer to the data 2506cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer 2507cd3f9d89SJunchao Zhang 2508cd3f9d89SJunchao Zhang Level: intermediate 2509cd3f9d89SJunchao Zhang 2510fb850c59SBarry Smith Note: 25112ef1f0ffSBarry Smith If the matrix is of a device type such as `MATDENSECUDA`, `MATDENSEHIP`, etc., 25122ef1f0ffSBarry Smith an array on device is always returned and is guaranteed to contain the matrix's latest data. 25132ef1f0ffSBarry Smith 25141cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreArrayWriteAndMemType()`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArrayRead()`, 2515cd3f9d89SJunchao Zhang `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()` 2516cd3f9d89SJunchao Zhang @*/ 2517cd3f9d89SJunchao Zhang PetscErrorCode MatDenseGetArrayWriteAndMemType(Mat A, PetscScalar **array, PetscMemType *mtype) 2518cd3f9d89SJunchao Zhang { 2519cd3f9d89SJunchao Zhang PetscBool isMPI; 2520cd3f9d89SJunchao Zhang 2521cd3f9d89SJunchao Zhang PetscFunctionBegin; 2522cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 25234f572ea9SToby Isaac PetscAssertPointer(array, 2); 2524e865de01SJunchao 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 */ 2525cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2526cd3f9d89SJunchao Zhang if (isMPI) { 2527cd3f9d89SJunchao Zhang PetscCall(MatDenseGetArrayWriteAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype)); 2528cd3f9d89SJunchao Zhang } else { 2529cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **, PetscMemType *); 25303ba16761SJacob Faibussowitsch 25313ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayWriteAndMemType_C", &fptr)); 2532cd3f9d89SJunchao Zhang if (fptr) { 2533cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array, mtype)); 2534cd3f9d89SJunchao Zhang } else { 2535cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array)); 2536cd3f9d89SJunchao Zhang if (mtype) *mtype = PETSC_MEMTYPE_HOST; 2537cd3f9d89SJunchao Zhang } 2538cd3f9d89SJunchao Zhang } 25393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2540cd3f9d89SJunchao Zhang } 2541cd3f9d89SJunchao Zhang 2542cd3f9d89SJunchao Zhang /*@C 2543cd3f9d89SJunchao Zhang MatDenseRestoreArrayWriteAndMemType - returns access to the array that is obtained by `MatDenseGetArrayReadAndMemType()` 2544cd3f9d89SJunchao Zhang 2545cd3f9d89SJunchao Zhang Logically Collective 2546cd3f9d89SJunchao Zhang 2547cd3f9d89SJunchao Zhang Input Parameters: 2548fe59aa6dSJacob Faibussowitsch + A - a dense matrix 2549cd3f9d89SJunchao Zhang - array - pointer to the data 2550cd3f9d89SJunchao Zhang 2551cd3f9d89SJunchao Zhang Level: intermediate 2552cd3f9d89SJunchao Zhang 25531cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetArrayWriteAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 2554cd3f9d89SJunchao Zhang @*/ 2555cd3f9d89SJunchao Zhang PetscErrorCode MatDenseRestoreArrayWriteAndMemType(Mat A, PetscScalar **array) 2556cd3f9d89SJunchao Zhang { 2557cd3f9d89SJunchao Zhang PetscBool isMPI; 2558cd3f9d89SJunchao Zhang 2559cd3f9d89SJunchao Zhang PetscFunctionBegin; 2560cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 25614f572ea9SToby Isaac PetscAssertPointer(array, 2); 2562cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2563cd3f9d89SJunchao Zhang if (isMPI) { 2564cd3f9d89SJunchao Zhang PetscCall(MatDenseRestoreArrayWriteAndMemType(((Mat_MPIDense *)A->data)->A, array)); 2565cd3f9d89SJunchao Zhang } else { 2566cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **); 25673ba16761SJacob Faibussowitsch 25683ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayWriteAndMemType_C", &fptr)); 2569cd3f9d89SJunchao Zhang if (fptr) { 2570cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array)); 2571cd3f9d89SJunchao Zhang } else { 2572cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array)); 2573cd3f9d89SJunchao Zhang } 2574cd3f9d89SJunchao Zhang *array = NULL; 2575cd3f9d89SJunchao Zhang } 2576cd3f9d89SJunchao Zhang PetscCall(PetscObjectStateIncrease((PetscObject)A)); 25773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2578cd3f9d89SJunchao Zhang } 2579cd3f9d89SJunchao Zhang 2580d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A, IS isrow, IS iscol, MatReuse scall, Mat *B) 2581d71ae5a4SJacob Faibussowitsch { 2582c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 2583bf5a80bcSToby Isaac PetscInt i, j, nrows, ncols, ldb; 25845d0c19d7SBarry Smith const PetscInt *irow, *icol; 258587828ca2SBarry Smith PetscScalar *av, *bv, *v = mat->v; 25860754003eSLois Curfman McInnes Mat newmat; 25870754003eSLois Curfman McInnes 25883a40ed3dSBarry Smith PetscFunctionBegin; 25899566063dSJacob Faibussowitsch PetscCall(ISGetIndices(isrow, &irow)); 25909566063dSJacob Faibussowitsch PetscCall(ISGetIndices(iscol, &icol)); 25919566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(isrow, &nrows)); 25929566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(iscol, &ncols)); 25930754003eSLois Curfman McInnes 2594182d2002SSatish Balay /* Check submatrixcall */ 2595182d2002SSatish Balay if (scall == MAT_REUSE_MATRIX) { 259613f74950SBarry Smith PetscInt n_cols, n_rows; 25979566063dSJacob Faibussowitsch PetscCall(MatGetSize(*B, &n_rows, &n_cols)); 259821a2c019SBarry Smith if (n_rows != nrows || n_cols != ncols) { 2599f746d493SDmitry Karpeev /* resize the result matrix to match number of requested rows/columns */ 26009566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*B, nrows, ncols, nrows, ncols)); 260121a2c019SBarry Smith } 2602182d2002SSatish Balay newmat = *B; 2603182d2002SSatish Balay } else { 26040754003eSLois Curfman McInnes /* Create and fill new matrix */ 26059566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &newmat)); 26069566063dSJacob Faibussowitsch PetscCall(MatSetSizes(newmat, nrows, ncols, nrows, ncols)); 26079566063dSJacob Faibussowitsch PetscCall(MatSetType(newmat, ((PetscObject)A)->type_name)); 26089566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(newmat, NULL)); 2609182d2002SSatish Balay } 2610182d2002SSatish Balay 2611182d2002SSatish Balay /* Now extract the data pointers and do the copy,column at a time */ 26129566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(newmat, &bv)); 26139566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(newmat, &ldb)); 2614182d2002SSatish Balay for (i = 0; i < ncols; i++) { 26156de62eeeSBarry Smith av = v + mat->lda * icol[i]; 2616ca15aa20SStefano Zampini for (j = 0; j < nrows; j++) bv[j] = av[irow[j]]; 2617bf5a80bcSToby Isaac bv += ldb; 26180754003eSLois Curfman McInnes } 26199566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(newmat, &bv)); 2620182d2002SSatish Balay 2621182d2002SSatish Balay /* Assemble the matrices so that the correct flags are set */ 26229566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(newmat, MAT_FINAL_ASSEMBLY)); 26239566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(newmat, MAT_FINAL_ASSEMBLY)); 26240754003eSLois Curfman McInnes 26250754003eSLois Curfman McInnes /* Free work space */ 26269566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(isrow, &irow)); 26279566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(iscol, &icol)); 2628182d2002SSatish Balay *B = newmat; 26293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26300754003eSLois Curfman McInnes } 26310754003eSLois Curfman McInnes 2632d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A, PetscInt n, const IS irow[], const IS icol[], MatReuse scall, Mat *B[]) 2633d71ae5a4SJacob Faibussowitsch { 263413f74950SBarry Smith PetscInt i; 2635905e6a2fSBarry Smith 26363a40ed3dSBarry Smith PetscFunctionBegin; 263748a46eb9SPierre Jolivet if (scall == MAT_INITIAL_MATRIX) PetscCall(PetscCalloc1(n, B)); 2638905e6a2fSBarry Smith 263948a46eb9SPierre Jolivet for (i = 0; i < n; i++) PetscCall(MatCreateSubMatrix_SeqDense(A, irow[i], icol[i], scall, &(*B)[i])); 26403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2641905e6a2fSBarry Smith } 2642905e6a2fSBarry Smith 2643d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat, MatAssemblyType mode) 2644d71ae5a4SJacob Faibussowitsch { 2645c0aa2d19SHong Zhang PetscFunctionBegin; 26463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2647c0aa2d19SHong Zhang } 2648c0aa2d19SHong Zhang 2649d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat, MatAssemblyType mode) 2650d71ae5a4SJacob Faibussowitsch { 2651c0aa2d19SHong Zhang PetscFunctionBegin; 26523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2653c0aa2d19SHong Zhang } 2654c0aa2d19SHong Zhang 2655d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCopy_SeqDense(Mat A, Mat B, MatStructure str) 2656d71ae5a4SJacob Faibussowitsch { 26574b0e389bSBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data; 2658ca15aa20SStefano Zampini const PetscScalar *va; 2659ca15aa20SStefano Zampini PetscScalar *vb; 2660d0f46423SBarry Smith PetscInt lda1 = a->lda, lda2 = b->lda, m = A->rmap->n, n = A->cmap->n, j; 26613a40ed3dSBarry Smith 26623a40ed3dSBarry Smith PetscFunctionBegin; 266333f4a19fSKris Buschelman /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */ 266433f4a19fSKris Buschelman if (A->ops->copy != B->ops->copy) { 26659566063dSJacob Faibussowitsch PetscCall(MatCopy_Basic(A, B, str)); 26663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26673a40ed3dSBarry Smith } 2668aed4548fSBarry Smith PetscCheck(m == B->rmap->n && n == B->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "size(B) != size(A)"); 26699566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &va)); 26709566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(B, &vb)); 2671a5ce6ee0Svictorle if (lda1 > m || lda2 > m) { 267248a46eb9SPierre Jolivet for (j = 0; j < n; j++) PetscCall(PetscArraycpy(vb + j * lda2, va + j * lda1, m)); 2673a5ce6ee0Svictorle } else { 26749566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(vb, va, A->rmap->n * A->cmap->n)); 2675a5ce6ee0Svictorle } 26769566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(B, &vb)); 26779566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &va)); 26789566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 26799566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 26803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2681273d9f13SBarry Smith } 2682273d9f13SBarry Smith 2683d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetUp_SeqDense(Mat A) 2684d71ae5a4SJacob Faibussowitsch { 2685273d9f13SBarry Smith PetscFunctionBegin; 26869566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 26879566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 268848a46eb9SPierre Jolivet if (!A->preallocated) PetscCall(MatSeqDenseSetPreallocation(A, NULL)); 26893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26904b0e389bSBarry Smith } 26914b0e389bSBarry Smith 2692d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatConjugate_SeqDense(Mat A) 2693d71ae5a4SJacob Faibussowitsch { 26944396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 269506c5243aSJose E. Roman PetscInt i, j; 26964396437dSToby Isaac PetscInt min = PetscMin(A->rmap->n, A->cmap->n); 2697ca15aa20SStefano Zampini PetscScalar *aa; 2698ba337c44SJed Brown 2699ba337c44SJed Brown PetscFunctionBegin; 27009566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 270106c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 270206c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscConj(aa[i + j * mat->lda]); 270306c5243aSJose E. Roman } 27049566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 27059371c9d4SSatish Balay if (mat->tau) 27069371c9d4SSatish Balay for (i = 0; i < min; i++) mat->tau[i] = PetscConj(mat->tau[i]); 27073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2708ba337c44SJed Brown } 2709ba337c44SJed Brown 2710d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRealPart_SeqDense(Mat A) 2711d71ae5a4SJacob Faibussowitsch { 271206c5243aSJose E. Roman Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 271306c5243aSJose E. Roman PetscInt i, j; 2714ca15aa20SStefano Zampini PetscScalar *aa; 2715ba337c44SJed Brown 2716ba337c44SJed Brown PetscFunctionBegin; 27179566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 271806c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 271906c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscRealPart(aa[i + j * mat->lda]); 272006c5243aSJose E. Roman } 27219566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 27223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2723ba337c44SJed Brown } 2724ba337c44SJed Brown 2725d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatImaginaryPart_SeqDense(Mat A) 2726d71ae5a4SJacob Faibussowitsch { 272706c5243aSJose E. Roman Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 272806c5243aSJose E. Roman PetscInt i, j; 2729ca15aa20SStefano Zampini PetscScalar *aa; 2730ba337c44SJed Brown 2731ba337c44SJed Brown PetscFunctionBegin; 27329566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 273306c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 273406c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscImaginaryPart(aa[i + j * mat->lda]); 273506c5243aSJose E. Roman } 27369566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 27373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2738ba337c44SJed Brown } 2739284134d9SBarry Smith 2740d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2741d71ae5a4SJacob Faibussowitsch { 2742d0f46423SBarry Smith PetscInt m = A->rmap->n, n = B->cmap->n; 274347d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 2744a9fe9ddaSSatish Balay 2745ee16a9a1SHong Zhang PetscFunctionBegin; 27469566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 274747d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 27489566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 274947d993e7Ssuyashtn #endif 275047d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 275147d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 275247d993e7Ssuyashtn #endif 27537a3c3d58SStefano Zampini if (!cisdense) { 27547a3c3d58SStefano Zampini PetscBool flg; 27557a3c3d58SStefano Zampini 27569566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 27579566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 27587a3c3d58SStefano Zampini } 27599566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 27603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2761ee16a9a1SHong Zhang } 2762a9fe9ddaSSatish Balay 2763d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2764d71ae5a4SJacob Faibussowitsch { 27656718818eSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data, *c = (Mat_SeqDense *)C->data; 27660805154bSBarry Smith PetscBLASInt m, n, k; 2767ca15aa20SStefano Zampini const PetscScalar *av, *bv; 2768ca15aa20SStefano Zampini PetscScalar *cv; 2769a9fe9ddaSSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 2770a9fe9ddaSSatish Balay 2771a9fe9ddaSSatish Balay PetscFunctionBegin; 27729566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 27739566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 27749566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 27753ba16761SJacob Faibussowitsch if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS); 27769566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 27779566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 27789566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2779792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("N", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 27809566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 27819566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 27829566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 27839566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 27843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2785a9fe9ddaSSatish Balay } 2786a9fe9ddaSSatish Balay 2787d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2788d71ae5a4SJacob Faibussowitsch { 278969f65d41SStefano Zampini PetscInt m = A->rmap->n, n = B->rmap->n; 279047d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 279169f65d41SStefano Zampini 279269f65d41SStefano Zampini PetscFunctionBegin; 27939566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 279447d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 27959566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 279647d993e7Ssuyashtn #endif 279747d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 279847d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 279947d993e7Ssuyashtn #endif 28007a3c3d58SStefano Zampini if (!cisdense) { 28017a3c3d58SStefano Zampini PetscBool flg; 28027a3c3d58SStefano Zampini 28039566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 28049566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 28057a3c3d58SStefano Zampini } 28069566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 28073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 280869f65d41SStefano Zampini } 280969f65d41SStefano Zampini 2810d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2811d71ae5a4SJacob Faibussowitsch { 281269f65d41SStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 281369f65d41SStefano Zampini Mat_SeqDense *b = (Mat_SeqDense *)B->data; 281469f65d41SStefano Zampini Mat_SeqDense *c = (Mat_SeqDense *)C->data; 28156718818eSStefano Zampini const PetscScalar *av, *bv; 28166718818eSStefano Zampini PetscScalar *cv; 281769f65d41SStefano Zampini PetscBLASInt m, n, k; 281869f65d41SStefano Zampini PetscScalar _DOne = 1.0, _DZero = 0.0; 281969f65d41SStefano Zampini 282069f65d41SStefano Zampini PetscFunctionBegin; 28219566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 28229566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 28239566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 28243ba16761SJacob Faibussowitsch if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS); 28259566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 28269566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 28279566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2828792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("N", "T", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 28299566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 28309566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 28319566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 28329566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 28333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 283469f65d41SStefano Zampini } 283569f65d41SStefano Zampini 2836d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2837d71ae5a4SJacob Faibussowitsch { 2838d0f46423SBarry Smith PetscInt m = A->cmap->n, n = B->cmap->n; 283947d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 2840a9fe9ddaSSatish Balay 2841ee16a9a1SHong Zhang PetscFunctionBegin; 28429566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 284347d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 28449566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 284547d993e7Ssuyashtn #endif 284647d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 284747d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 284847d993e7Ssuyashtn #endif 28497a3c3d58SStefano Zampini if (!cisdense) { 28507a3c3d58SStefano Zampini PetscBool flg; 28517a3c3d58SStefano Zampini 28529566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 28539566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 28547a3c3d58SStefano Zampini } 28559566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 28563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2857ee16a9a1SHong Zhang } 2858a9fe9ddaSSatish Balay 2859d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2860d71ae5a4SJacob Faibussowitsch { 2861a9fe9ddaSSatish Balay Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2862a9fe9ddaSSatish Balay Mat_SeqDense *b = (Mat_SeqDense *)B->data; 2863a9fe9ddaSSatish Balay Mat_SeqDense *c = (Mat_SeqDense *)C->data; 28646718818eSStefano Zampini const PetscScalar *av, *bv; 28656718818eSStefano Zampini PetscScalar *cv; 28660805154bSBarry Smith PetscBLASInt m, n, k; 2867a9fe9ddaSSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 2868a9fe9ddaSSatish Balay 2869a9fe9ddaSSatish Balay PetscFunctionBegin; 28709566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 28719566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 28729566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &k)); 28733ba16761SJacob Faibussowitsch if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS); 28749566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 28759566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 28769566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2877792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("T", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 28789566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 28799566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 28809566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 28819566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 28823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2883a9fe9ddaSSatish Balay } 2884985db425SBarry Smith 2885d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C) 2886d71ae5a4SJacob Faibussowitsch { 28874222ddf1SHong Zhang PetscFunctionBegin; 28884222ddf1SHong Zhang C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense; 28894222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AB; 28903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28914222ddf1SHong Zhang } 28924222ddf1SHong Zhang 2893d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C) 2894d71ae5a4SJacob Faibussowitsch { 28954222ddf1SHong Zhang PetscFunctionBegin; 28964222ddf1SHong Zhang C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense; 28974222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AtB; 28983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 28994222ddf1SHong Zhang } 29004222ddf1SHong Zhang 2901d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C) 2902d71ae5a4SJacob Faibussowitsch { 29034222ddf1SHong Zhang PetscFunctionBegin; 29044222ddf1SHong Zhang C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense; 29054222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_ABt; 29063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29074222ddf1SHong Zhang } 29084222ddf1SHong Zhang 2909d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C) 2910d71ae5a4SJacob Faibussowitsch { 29114222ddf1SHong Zhang Mat_Product *product = C->product; 29124222ddf1SHong Zhang 29134222ddf1SHong Zhang PetscFunctionBegin; 29144222ddf1SHong Zhang switch (product->type) { 2915d71ae5a4SJacob Faibussowitsch case MATPRODUCT_AB: 2916d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_AB(C)); 2917d71ae5a4SJacob Faibussowitsch break; 2918d71ae5a4SJacob Faibussowitsch case MATPRODUCT_AtB: 2919d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_AtB(C)); 2920d71ae5a4SJacob Faibussowitsch break; 2921d71ae5a4SJacob Faibussowitsch case MATPRODUCT_ABt: 2922d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_ABt(C)); 2923d71ae5a4SJacob Faibussowitsch break; 2924d71ae5a4SJacob Faibussowitsch default: 2925d71ae5a4SJacob Faibussowitsch break; 29264222ddf1SHong Zhang } 29273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29284222ddf1SHong Zhang } 29294222ddf1SHong Zhang 2930d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMax_SeqDense(Mat A, Vec v, PetscInt idx[]) 2931d71ae5a4SJacob Faibussowitsch { 2932985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2933d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2934985db425SBarry Smith PetscScalar *x; 2935ca15aa20SStefano Zampini const PetscScalar *aa; 2936985db425SBarry Smith 2937985db425SBarry Smith PetscFunctionBegin; 293828b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29399566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29409566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 29419566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 294208401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2943985db425SBarry Smith for (i = 0; i < m; i++) { 29449371c9d4SSatish Balay x[i] = aa[i]; 29459371c9d4SSatish Balay if (idx) idx[i] = 0; 2946985db425SBarry Smith for (j = 1; j < n; j++) { 29479371c9d4SSatish Balay if (PetscRealPart(x[i]) < PetscRealPart(aa[i + a->lda * j])) { 29489371c9d4SSatish Balay x[i] = aa[i + a->lda * j]; 29499371c9d4SSatish Balay if (idx) idx[i] = j; 29509371c9d4SSatish Balay } 2951985db425SBarry Smith } 2952985db425SBarry Smith } 29539566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 29549566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 29553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2956985db425SBarry Smith } 2957985db425SBarry Smith 2958d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A, Vec v, PetscInt idx[]) 2959d71ae5a4SJacob Faibussowitsch { 2960985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2961d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2962985db425SBarry Smith PetscScalar *x; 2963985db425SBarry Smith PetscReal atmp; 2964ca15aa20SStefano Zampini const PetscScalar *aa; 2965985db425SBarry Smith 2966985db425SBarry Smith PetscFunctionBegin; 296728b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29689566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29699566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 29709566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 297108401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2972985db425SBarry Smith for (i = 0; i < m; i++) { 29739189402eSHong Zhang x[i] = PetscAbsScalar(aa[i]); 2974985db425SBarry Smith for (j = 1; j < n; j++) { 2975ca15aa20SStefano Zampini atmp = PetscAbsScalar(aa[i + a->lda * j]); 29769371c9d4SSatish Balay if (PetscAbsScalar(x[i]) < atmp) { 29779371c9d4SSatish Balay x[i] = atmp; 29789371c9d4SSatish Balay if (idx) idx[i] = j; 29799371c9d4SSatish Balay } 2980985db425SBarry Smith } 2981985db425SBarry Smith } 29829566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 29839566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 29843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2985985db425SBarry Smith } 2986985db425SBarry Smith 2987d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMin_SeqDense(Mat A, Vec v, PetscInt idx[]) 2988d71ae5a4SJacob Faibussowitsch { 2989985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2990d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2991985db425SBarry Smith PetscScalar *x; 2992ca15aa20SStefano Zampini const PetscScalar *aa; 2993985db425SBarry Smith 2994985db425SBarry Smith PetscFunctionBegin; 299528b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29969566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 29979566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29989566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 299908401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 3000985db425SBarry Smith for (i = 0; i < m; i++) { 30019371c9d4SSatish Balay x[i] = aa[i]; 30029371c9d4SSatish Balay if (idx) idx[i] = 0; 3003985db425SBarry Smith for (j = 1; j < n; j++) { 30049371c9d4SSatish Balay if (PetscRealPart(x[i]) > PetscRealPart(aa[i + a->lda * j])) { 30059371c9d4SSatish Balay x[i] = aa[i + a->lda * j]; 30069371c9d4SSatish Balay if (idx) idx[i] = j; 30079371c9d4SSatish Balay } 3008985db425SBarry Smith } 3009985db425SBarry Smith } 30109566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 30119566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 30123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3013985db425SBarry Smith } 3014985db425SBarry Smith 3015d71ae5a4SJacob Faibussowitsch PetscErrorCode MatGetColumnVector_SeqDense(Mat A, Vec v, PetscInt col) 3016d71ae5a4SJacob Faibussowitsch { 30178d0534beSBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 30188d0534beSBarry Smith PetscScalar *x; 3019ca15aa20SStefano Zampini const PetscScalar *aa; 30208d0534beSBarry Smith 30218d0534beSBarry Smith PetscFunctionBegin; 302228b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 30239566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 30249566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 30259566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(x, aa + col * a->lda, A->rmap->n)); 30269566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 30279566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 30283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30298d0534beSBarry Smith } 30308d0534beSBarry Smith 3031d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatGetColumnReductions_SeqDense(Mat A, PetscInt type, PetscReal *reductions) 3032d71ae5a4SJacob Faibussowitsch { 30330716a85fSBarry Smith PetscInt i, j, m, n; 30341683a169SBarry Smith const PetscScalar *a; 30350716a85fSBarry Smith 30360716a85fSBarry Smith PetscFunctionBegin; 30379566063dSJacob Faibussowitsch PetscCall(MatGetSize(A, &m, &n)); 30389566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(reductions, n)); 30399566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &a)); 3040857cbf51SRichard Tran Mills if (type == NORM_2) { 30410716a85fSBarry Smith for (i = 0; i < n; i++) { 3042ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j] * a[j]); 304316cd844bSPierre Jolivet a = PetscSafePointerPlusOffset(a, m); 30440716a85fSBarry Smith } 3045857cbf51SRichard Tran Mills } else if (type == NORM_1) { 30460716a85fSBarry Smith for (i = 0; i < n; i++) { 3047ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j]); 304816cd844bSPierre Jolivet a = PetscSafePointerPlusOffset(a, m); 30490716a85fSBarry Smith } 3050857cbf51SRichard Tran Mills } else if (type == NORM_INFINITY) { 30510716a85fSBarry Smith for (i = 0; i < n; i++) { 3052ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] = PetscMax(PetscAbsScalar(a[j]), reductions[i]); 305316cd844bSPierre Jolivet a = PetscSafePointerPlusOffset(a, m); 30540716a85fSBarry Smith } 3055857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_REALPART || type == REDUCTION_MEAN_REALPART) { 3056a873a8cdSSam Reynolds for (i = 0; i < n; i++) { 3057ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscRealPart(a[j]); 305816cd844bSPierre Jolivet a = PetscSafePointerPlusOffset(a, m); 3059a873a8cdSSam Reynolds } 3060857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_IMAGINARYPART || type == REDUCTION_MEAN_IMAGINARYPART) { 3061857cbf51SRichard Tran Mills for (i = 0; i < n; i++) { 3062ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscImaginaryPart(a[j]); 306316cd844bSPierre Jolivet a = PetscSafePointerPlusOffset(a, m); 3064857cbf51SRichard Tran Mills } 3065857cbf51SRichard Tran Mills } else SETERRQ(PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Unknown reduction type"); 30669566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &a)); 3067857cbf51SRichard Tran Mills if (type == NORM_2) { 3068a873a8cdSSam Reynolds for (i = 0; i < n; i++) reductions[i] = PetscSqrtReal(reductions[i]); 3069857cbf51SRichard Tran Mills } else if (type == REDUCTION_MEAN_REALPART || type == REDUCTION_MEAN_IMAGINARYPART) { 3070a873a8cdSSam Reynolds for (i = 0; i < n; i++) reductions[i] /= m; 30710716a85fSBarry Smith } 30723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30730716a85fSBarry Smith } 30740716a85fSBarry Smith 3075d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetRandom_SeqDense(Mat x, PetscRandom rctx) 3076d71ae5a4SJacob Faibussowitsch { 307773a71a0fSBarry Smith PetscScalar *a; 3078637a0070SStefano Zampini PetscInt lda, m, n, i, j; 307973a71a0fSBarry Smith 308073a71a0fSBarry Smith PetscFunctionBegin; 30819566063dSJacob Faibussowitsch PetscCall(MatGetSize(x, &m, &n)); 30829566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(x, &lda)); 30833faff063SStefano Zampini PetscCall(MatDenseGetArrayWrite(x, &a)); 3084637a0070SStefano Zampini for (j = 0; j < n; j++) { 308548a46eb9SPierre Jolivet for (i = 0; i < m; i++) PetscCall(PetscRandomGetValue(rctx, a + j * lda + i)); 308673a71a0fSBarry Smith } 30873faff063SStefano Zampini PetscCall(MatDenseRestoreArrayWrite(x, &a)); 30883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 308973a71a0fSBarry Smith } 309073a71a0fSBarry Smith 3091d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A, PetscBool *missing, PetscInt *d) 3092d71ae5a4SJacob Faibussowitsch { 30933b49f96aSBarry Smith PetscFunctionBegin; 30943b49f96aSBarry Smith *missing = PETSC_FALSE; 30953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30963b49f96aSBarry Smith } 309773a71a0fSBarry Smith 3098ca15aa20SStefano Zampini /* vals is not const */ 3099d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A, PetscInt col, PetscScalar **vals) 3100d71ae5a4SJacob Faibussowitsch { 310186aefd0dSHong Zhang Mat_SeqDense *a = (Mat_SeqDense *)A->data; 3102ca15aa20SStefano Zampini PetscScalar *v; 310386aefd0dSHong Zhang 310486aefd0dSHong Zhang PetscFunctionBegin; 310528b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 31069566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 3107ca15aa20SStefano Zampini *vals = v + col * a->lda; 31089566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 31093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 311086aefd0dSHong Zhang } 311186aefd0dSHong Zhang 3112d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A, PetscScalar **vals) 3113d71ae5a4SJacob Faibussowitsch { 311486aefd0dSHong Zhang PetscFunctionBegin; 3115742765d3SMatthew Knepley if (vals) *vals = NULL; /* user cannot accidentally use the array later */ 31163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 311786aefd0dSHong Zhang } 3118abc3b08eSStefano Zampini 3119a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqDense, 3120905e6a2fSBarry Smith MatGetRow_SeqDense, 3121905e6a2fSBarry Smith MatRestoreRow_SeqDense, 3122905e6a2fSBarry Smith MatMult_SeqDense, 312397304618SKris Buschelman /* 4*/ MatMultAdd_SeqDense, 31247c922b88SBarry Smith MatMultTranspose_SeqDense, 31257c922b88SBarry Smith MatMultTransposeAdd_SeqDense, 3126f4259b30SLisandro Dalcin NULL, 3127f4259b30SLisandro Dalcin NULL, 3128f4259b30SLisandro Dalcin NULL, 3129f4259b30SLisandro Dalcin /* 10*/ NULL, 3130905e6a2fSBarry Smith MatLUFactor_SeqDense, 3131905e6a2fSBarry Smith MatCholeskyFactor_SeqDense, 313241f059aeSBarry Smith MatSOR_SeqDense, 3133ec8511deSBarry Smith MatTranspose_SeqDense, 313497304618SKris Buschelman /* 15*/ MatGetInfo_SeqDense, 3135905e6a2fSBarry Smith MatEqual_SeqDense, 3136905e6a2fSBarry Smith MatGetDiagonal_SeqDense, 3137905e6a2fSBarry Smith MatDiagonalScale_SeqDense, 3138905e6a2fSBarry Smith MatNorm_SeqDense, 3139c0aa2d19SHong Zhang /* 20*/ MatAssemblyBegin_SeqDense, 3140c0aa2d19SHong Zhang MatAssemblyEnd_SeqDense, 3141905e6a2fSBarry Smith MatSetOption_SeqDense, 3142905e6a2fSBarry Smith MatZeroEntries_SeqDense, 3143d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqDense, 3144f4259b30SLisandro Dalcin NULL, 3145f4259b30SLisandro Dalcin NULL, 3146f4259b30SLisandro Dalcin NULL, 3147f4259b30SLisandro Dalcin NULL, 31484994cf47SJed Brown /* 29*/ MatSetUp_SeqDense, 3149f4259b30SLisandro Dalcin NULL, 3150f4259b30SLisandro Dalcin NULL, 3151f4259b30SLisandro Dalcin NULL, 3152f4259b30SLisandro Dalcin NULL, 3153d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqDense, 3154f4259b30SLisandro Dalcin NULL, 3155f4259b30SLisandro Dalcin NULL, 3156f4259b30SLisandro Dalcin NULL, 3157f4259b30SLisandro Dalcin NULL, 3158d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqDense, 31597dae84e0SHong Zhang MatCreateSubMatrices_SeqDense, 3160f4259b30SLisandro Dalcin NULL, 31614b0e389bSBarry Smith MatGetValues_SeqDense, 3162a5ae1ecdSBarry Smith MatCopy_SeqDense, 3163d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqDense, 3164a5ae1ecdSBarry Smith MatScale_SeqDense, 31652f605a99SJose E. Roman MatShift_SeqDense, 3166f4259b30SLisandro Dalcin NULL, 31673f49a652SStefano Zampini MatZeroRowsColumns_SeqDense, 316873a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqDense, 3169f4259b30SLisandro Dalcin NULL, 3170f4259b30SLisandro Dalcin NULL, 3171f4259b30SLisandro Dalcin NULL, 3172f4259b30SLisandro Dalcin NULL, 3173f4259b30SLisandro Dalcin /* 54*/ NULL, 3174f4259b30SLisandro Dalcin NULL, 3175f4259b30SLisandro Dalcin NULL, 3176f4259b30SLisandro Dalcin NULL, 3177f4259b30SLisandro Dalcin NULL, 3178023c16fcSToby Isaac /* 59*/ MatCreateSubMatrix_SeqDense, 3179e03a110bSBarry Smith MatDestroy_SeqDense, 3180e03a110bSBarry Smith MatView_SeqDense, 3181f4259b30SLisandro Dalcin NULL, 3182f4259b30SLisandro Dalcin NULL, 3183f4259b30SLisandro Dalcin /* 64*/ NULL, 3184f4259b30SLisandro Dalcin NULL, 3185f4259b30SLisandro Dalcin NULL, 3186f4259b30SLisandro Dalcin NULL, 3187f4259b30SLisandro Dalcin NULL, 3188d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqDense, 3189f4259b30SLisandro Dalcin NULL, 3190f4259b30SLisandro Dalcin NULL, 3191f4259b30SLisandro Dalcin NULL, 3192f4259b30SLisandro Dalcin NULL, 3193f4259b30SLisandro Dalcin /* 74*/ NULL, 3194f4259b30SLisandro Dalcin NULL, 3195f4259b30SLisandro Dalcin NULL, 3196f4259b30SLisandro Dalcin NULL, 3197f4259b30SLisandro Dalcin NULL, 3198f4259b30SLisandro Dalcin /* 79*/ NULL, 3199f4259b30SLisandro Dalcin NULL, 3200f4259b30SLisandro Dalcin NULL, 3201f4259b30SLisandro Dalcin NULL, 32025bba2384SShri Abhyankar /* 83*/ MatLoad_SeqDense, 3203637a0070SStefano Zampini MatIsSymmetric_SeqDense, 32041cbb95d3SBarry Smith MatIsHermitian_SeqDense, 3205f4259b30SLisandro Dalcin NULL, 3206f4259b30SLisandro Dalcin NULL, 3207f4259b30SLisandro Dalcin NULL, 3208f4259b30SLisandro Dalcin /* 89*/ NULL, 3209f4259b30SLisandro Dalcin NULL, 3210a9fe9ddaSSatish Balay MatMatMultNumeric_SeqDense_SeqDense, 3211f4259b30SLisandro Dalcin NULL, 3212f4259b30SLisandro Dalcin NULL, 3213f4259b30SLisandro Dalcin /* 94*/ NULL, 3214f4259b30SLisandro Dalcin NULL, 3215f4259b30SLisandro Dalcin NULL, 321669f65d41SStefano Zampini MatMatTransposeMultNumeric_SeqDense_SeqDense, 3217f4259b30SLisandro Dalcin NULL, 32184222ddf1SHong Zhang /* 99*/ MatProductSetFromOptions_SeqDense, 3219f4259b30SLisandro Dalcin NULL, 3220f4259b30SLisandro Dalcin NULL, 3221ba337c44SJed Brown MatConjugate_SeqDense, 3222f4259b30SLisandro Dalcin NULL, 3223f4259b30SLisandro Dalcin /*104*/ NULL, 3224ba337c44SJed Brown MatRealPart_SeqDense, 3225ba337c44SJed Brown MatImaginaryPart_SeqDense, 3226f4259b30SLisandro Dalcin NULL, 3227f4259b30SLisandro Dalcin NULL, 3228f4259b30SLisandro Dalcin /*109*/ NULL, 3229f4259b30SLisandro Dalcin NULL, 32308d0534beSBarry Smith MatGetRowMin_SeqDense, 3231aabbc4fbSShri Abhyankar MatGetColumnVector_SeqDense, 32323b49f96aSBarry Smith MatMissingDiagonal_SeqDense, 3233f4259b30SLisandro Dalcin /*114*/ NULL, 3234f4259b30SLisandro Dalcin NULL, 3235f4259b30SLisandro Dalcin NULL, 3236f4259b30SLisandro Dalcin NULL, 3237f4259b30SLisandro Dalcin NULL, 3238f4259b30SLisandro Dalcin /*119*/ NULL, 3239f4259b30SLisandro Dalcin NULL, 3240459e8d23SBlanca Mellado Pinto MatMultHermitianTranspose_SeqDense, 3241459e8d23SBlanca Mellado Pinto MatMultHermitianTransposeAdd_SeqDense, 3242f4259b30SLisandro Dalcin NULL, 3243f4259b30SLisandro Dalcin /*124*/ NULL, 3244a873a8cdSSam Reynolds MatGetColumnReductions_SeqDense, 3245f4259b30SLisandro Dalcin NULL, 3246f4259b30SLisandro Dalcin NULL, 3247f4259b30SLisandro Dalcin NULL, 3248f4259b30SLisandro Dalcin /*129*/ NULL, 3249f4259b30SLisandro Dalcin NULL, 3250f4259b30SLisandro Dalcin NULL, 325175648e8dSHong Zhang MatTransposeMatMultNumeric_SeqDense_SeqDense, 3252f4259b30SLisandro Dalcin NULL, 3253f4259b30SLisandro Dalcin /*134*/ NULL, 3254f4259b30SLisandro Dalcin NULL, 3255f4259b30SLisandro Dalcin NULL, 3256f4259b30SLisandro Dalcin NULL, 3257f4259b30SLisandro Dalcin NULL, 3258f4259b30SLisandro Dalcin /*139*/ NULL, 3259f4259b30SLisandro Dalcin NULL, 3260f4259b30SLisandro Dalcin NULL, 3261f4259b30SLisandro Dalcin NULL, 3262f4259b30SLisandro Dalcin NULL, 32634222ddf1SHong Zhang MatCreateMPIMatConcatenateSeqMat_SeqDense, 3264f4259b30SLisandro Dalcin /*145*/ NULL, 3265f4259b30SLisandro Dalcin NULL, 326699a7f59eSMark Adams NULL, 326799a7f59eSMark Adams NULL, 32687fb60732SBarry Smith NULL, 3269dec0b466SHong Zhang /*150*/ NULL, 3270eede4a3fSMark Adams NULL, 3271dec0b466SHong Zhang NULL}; 327290ace30eSBarry Smith 32734b828684SBarry Smith /*@C 327411a5261eSBarry Smith MatCreateSeqDense - Creates a `MATSEQDENSE` that 3275fb850c59SBarry Smith is stored in column major order (the usual Fortran format). 3276289bc588SBarry Smith 3277d083f849SBarry Smith Collective 3278db81eaa0SLois Curfman McInnes 327920563c6bSBarry Smith Input Parameters: 328011a5261eSBarry Smith + comm - MPI communicator, set to `PETSC_COMM_SELF` 32810c775827SLois Curfman McInnes . m - number of rows 328218f449edSLois Curfman McInnes . n - number of columns 32832ef1f0ffSBarry Smith - data - optional location of matrix data in column major order. Use `NULL` for PETSc 3284dfc5480cSLois Curfman McInnes to control all matrix memory allocation. 328520563c6bSBarry Smith 328620563c6bSBarry Smith Output Parameter: 328744cd7ae7SLois Curfman McInnes . A - the matrix 328820563c6bSBarry Smith 32892ef1f0ffSBarry Smith Level: intermediate 32902ef1f0ffSBarry Smith 329111a5261eSBarry Smith Note: 329218f449edSLois Curfman McInnes The data input variable is intended primarily for Fortran programmers 329318f449edSLois Curfman McInnes who wish to allocate their own matrix memory space. Most users should 32942ef1f0ffSBarry Smith set `data` = `NULL`. 329518f449edSLois Curfman McInnes 3296fb850c59SBarry Smith Developer Note: 3297fb850c59SBarry Smith Many of the matrix operations for this variant use the BLAS and LAPACK routines. 3298fb850c59SBarry Smith 32991cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()` 330020563c6bSBarry Smith @*/ 3301d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateSeqDense(MPI_Comm comm, PetscInt m, PetscInt n, PetscScalar *data, Mat *A) 3302d71ae5a4SJacob Faibussowitsch { 33033a40ed3dSBarry Smith PetscFunctionBegin; 33049566063dSJacob Faibussowitsch PetscCall(MatCreate(comm, A)); 33059566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*A, m, n, m, n)); 33069566063dSJacob Faibussowitsch PetscCall(MatSetType(*A, MATSEQDENSE)); 33079566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(*A, data)); 33083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3309273d9f13SBarry Smith } 3310273d9f13SBarry Smith 3311273d9f13SBarry Smith /*@C 331211a5261eSBarry Smith MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements of a `MATSEQDENSE` matrix 3313273d9f13SBarry Smith 3314d083f849SBarry Smith Collective 3315273d9f13SBarry Smith 3316273d9f13SBarry Smith Input Parameters: 33171c4f3114SJed Brown + B - the matrix 33182ef1f0ffSBarry Smith - data - the array (or `NULL`) 33192ef1f0ffSBarry Smith 33202ef1f0ffSBarry Smith Level: intermediate 3321273d9f13SBarry Smith 332211a5261eSBarry Smith Note: 3323273d9f13SBarry Smith The data input variable is intended primarily for Fortran programmers 3324273d9f13SBarry Smith who wish to allocate their own matrix memory space. Most users should 3325284134d9SBarry Smith need not call this routine. 3326273d9f13SBarry Smith 33271cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()`, `MatDenseSetLDA()` 3328273d9f13SBarry Smith @*/ 3329d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation(Mat B, PetscScalar data[]) 3330d71ae5a4SJacob Faibussowitsch { 3331a23d5eceSKris Buschelman PetscFunctionBegin; 3332d5ea218eSStefano Zampini PetscValidHeaderSpecific(B, MAT_CLASSID, 1); 3333cac4c232SBarry Smith PetscTryMethod(B, "MatSeqDenseSetPreallocation_C", (Mat, PetscScalar[]), (B, data)); 33343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3335a23d5eceSKris Buschelman } 3336a23d5eceSKris Buschelman 3337d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation_SeqDense(Mat B, PetscScalar *data) 3338d71ae5a4SJacob Faibussowitsch { 3339ad16ce7aSStefano Zampini Mat_SeqDense *b = (Mat_SeqDense *)B->data; 3340273d9f13SBarry Smith 3341273d9f13SBarry Smith PetscFunctionBegin; 334228b400f6SJacob Faibussowitsch PetscCheck(!b->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3343273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 3344a868139aSShri Abhyankar 33459566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(B->rmap)); 33469566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(B->cmap)); 334734ef9618SShri Abhyankar 3348ad16ce7aSStefano Zampini if (b->lda <= 0) b->lda = B->rmap->n; 334986d161a7SShri Abhyankar 33509e8f95c4SLisandro Dalcin if (!data) { /* petsc-allocated storage */ 33519566063dSJacob Faibussowitsch if (!b->user_alloc) PetscCall(PetscFree(b->v)); 33529566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((size_t)b->lda * B->cmap->n, &b->v)); 33532205254eSKarl Rupp 33549e8f95c4SLisandro Dalcin b->user_alloc = PETSC_FALSE; 3355273d9f13SBarry Smith } else { /* user-allocated storage */ 33569566063dSJacob Faibussowitsch if (!b->user_alloc) PetscCall(PetscFree(b->v)); 3357273d9f13SBarry Smith b->v = data; 3358273d9f13SBarry Smith b->user_alloc = PETSC_TRUE; 3359273d9f13SBarry Smith } 33600450473dSBarry Smith B->assembled = PETSC_TRUE; 33613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3362273d9f13SBarry Smith } 3363273d9f13SBarry Smith 336465b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 3365d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) 3366d71ae5a4SJacob Faibussowitsch { 3367d77f618aSHong Zhang Mat mat_elemental; 33681683a169SBarry Smith const PetscScalar *array; 33691683a169SBarry Smith PetscScalar *v_colwise; 3370d77f618aSHong Zhang PetscInt M = A->rmap->N, N = A->cmap->N, i, j, k, *rows, *cols; 3371d77f618aSHong Zhang 33728baccfbdSHong Zhang PetscFunctionBegin; 33739566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(M * N, &v_colwise, M, &rows, N, &cols)); 33749566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &array)); 3375d77f618aSHong Zhang /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */ 3376d77f618aSHong Zhang k = 0; 3377d77f618aSHong Zhang for (j = 0; j < N; j++) { 3378d77f618aSHong Zhang cols[j] = j; 3379ad540459SPierre Jolivet for (i = 0; i < M; i++) v_colwise[j * M + i] = array[k++]; 3380d77f618aSHong Zhang } 3381ad540459SPierre Jolivet for (i = 0; i < M; i++) rows[i] = i; 33829566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &array)); 3383d77f618aSHong Zhang 33849566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental)); 33859566063dSJacob Faibussowitsch PetscCall(MatSetSizes(mat_elemental, PETSC_DECIDE, PETSC_DECIDE, M, N)); 33869566063dSJacob Faibussowitsch PetscCall(MatSetType(mat_elemental, MATELEMENTAL)); 33879566063dSJacob Faibussowitsch PetscCall(MatSetUp(mat_elemental)); 3388d77f618aSHong Zhang 3389d77f618aSHong Zhang /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */ 33909566063dSJacob Faibussowitsch PetscCall(MatSetValues(mat_elemental, M, rows, N, cols, v_colwise, ADD_VALUES)); 33919566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY)); 33929566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY)); 33939566063dSJacob Faibussowitsch PetscCall(PetscFree3(v_colwise, rows, cols)); 3394d77f618aSHong Zhang 3395511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 33969566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A, &mat_elemental)); 3397d77f618aSHong Zhang } else { 3398d77f618aSHong Zhang *newmat = mat_elemental; 3399d77f618aSHong Zhang } 34003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34018baccfbdSHong Zhang } 340265b80a83SHong Zhang #endif 34038baccfbdSHong Zhang 3404d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA_SeqDense(Mat B, PetscInt lda) 3405d71ae5a4SJacob Faibussowitsch { 34061b807ce4Svictorle Mat_SeqDense *b = (Mat_SeqDense *)B->data; 34077422da62SJose E. Roman PetscBool data; 340821a2c019SBarry Smith 34091b807ce4Svictorle PetscFunctionBegin; 34107422da62SJose E. Roman data = (PetscBool)((B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE); 3411aed4548fSBarry Smith PetscCheck(b->user_alloc || !data || b->lda == lda, PETSC_COMM_SELF, PETSC_ERR_ORDER, "LDA cannot be changed after allocation of internal storage"); 341208401ef6SPierre 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); 34131b807ce4Svictorle b->lda = lda; 34143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34151b807ce4Svictorle } 34161b807ce4Svictorle 3417d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm, Mat inmat, PetscInt n, MatReuse scall, Mat *outmat) 3418d71ae5a4SJacob Faibussowitsch { 3419d528f656SJakub Kruzik PetscFunctionBegin; 34209566063dSJacob Faibussowitsch PetscCall(MatCreateMPIMatConcatenateSeqMat_MPIDense(comm, inmat, n, scall, outmat)); 34213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3422d528f656SJakub Kruzik } 3423d528f656SJakub Kruzik 3424d16ceb75SStefano Zampini PetscErrorCode MatDenseCreateColumnVec_Private(Mat A, Vec *v) 3425d16ceb75SStefano Zampini { 3426d16ceb75SStefano Zampini PetscBool isstd, iskok, iscuda, iship; 3427d16ceb75SStefano Zampini PetscMPIInt size; 3428d16ceb75SStefano Zampini #if PetscDefined(HAVE_CUDA) || PetscDefined(HAVE_HIP) 3429d16ceb75SStefano Zampini /* we pass the data of A, to prevent allocating needless GPU memory the first time VecCUPMPlaceArray is called. */ 3430d16ceb75SStefano Zampini const PetscScalar *a; 3431d16ceb75SStefano Zampini #endif 3432d16ceb75SStefano Zampini 3433d16ceb75SStefano Zampini PetscFunctionBegin; 3434d16ceb75SStefano Zampini *v = NULL; 3435d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &isstd, VECSTANDARD, VECSEQ, VECMPI, "")); 3436d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &iskok, VECKOKKOS, VECSEQKOKKOS, VECMPIKOKKOS, "")); 3437d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &iscuda, VECCUDA, VECSEQCUDA, VECMPICUDA, "")); 3438d16ceb75SStefano Zampini PetscCall(PetscStrcmpAny(A->defaultvectype, &iship, VECHIP, VECSEQHIP, VECMPIHIP, "")); 3439d16ceb75SStefano Zampini PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)A), &size)); 3440d16ceb75SStefano Zampini if (isstd) { 3441d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPIWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, v)); 3442d16ceb75SStefano Zampini else PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, v)); 3443d16ceb75SStefano Zampini } else if (iskok) { 3444d16ceb75SStefano Zampini PetscCheck(PetscDefined(HAVE_KOKKOS_KERNELS), PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Reconfigure using KOKKOS kernels support"); 3445d16ceb75SStefano Zampini #if PetscDefined(HAVE_KOKKOS_KERNELS) 3446d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPIKokkosWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, v)); 3447d16ceb75SStefano Zampini else PetscCall(VecCreateSeqKokkosWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, v)); 3448d16ceb75SStefano Zampini #endif 3449d16ceb75SStefano Zampini } else if (iscuda) { 3450d16ceb75SStefano Zampini PetscCheck(PetscDefined(HAVE_CUDA), PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Reconfigure using CUDA support"); 3451d16ceb75SStefano Zampini #if PetscDefined(HAVE_CUDA) 3452d16ceb75SStefano Zampini PetscCall(MatDenseCUDAGetArrayRead(A, &a)); 3453d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPICUDAWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, a, v)); 3454d16ceb75SStefano Zampini else PetscCall(VecCreateSeqCUDAWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, a, v)); 3455d16ceb75SStefano Zampini #endif 3456d16ceb75SStefano Zampini } else if (iship) { 3457d16ceb75SStefano Zampini PetscCheck(PetscDefined(HAVE_HIP), PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Reconfigure using HIP support"); 3458d16ceb75SStefano Zampini #if PetscDefined(HAVE_HIP) 3459d16ceb75SStefano Zampini PetscCall(MatDenseHIPGetArrayRead(A, &a)); 3460d16ceb75SStefano Zampini if (size > 1) PetscCall(VecCreateMPIHIPWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, A->rmap->N, NULL, a, v)); 3461d16ceb75SStefano Zampini else PetscCall(VecCreateSeqHIPWithArrays(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, a, v)); 3462d16ceb75SStefano Zampini #endif 3463d16ceb75SStefano Zampini } 3464d16ceb75SStefano Zampini PetscCheck(*v, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Not coded for type %s", A->defaultvectype); 3465d16ceb75SStefano Zampini PetscFunctionReturn(PETSC_SUCCESS); 3466d16ceb75SStefano Zampini } 3467d16ceb75SStefano Zampini 3468d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A, PetscInt col, Vec *v) 3469d71ae5a4SJacob Faibussowitsch { 34706947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34716947451fSStefano Zampini 34726947451fSStefano Zampini PetscFunctionBegin; 347328b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 347428b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3475d16ceb75SStefano Zampini if (!a->cvec) PetscCall(MatDenseCreateColumnVec_Private(A, &a->cvec)); 34766947451fSStefano Zampini a->vecinuse = col + 1; 34779566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, (PetscScalar **)&a->ptrinuse)); 34789566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda)); 34796947451fSStefano Zampini *v = a->cvec; 34803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34816947451fSStefano Zampini } 34826947451fSStefano Zampini 3483d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A, PetscInt col, Vec *v) 3484d71ae5a4SJacob Faibussowitsch { 34856947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34866947451fSStefano Zampini 34876947451fSStefano Zampini PetscFunctionBegin; 348828b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 348928b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 34906947451fSStefano Zampini a->vecinuse = 0; 34919566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, (PetscScalar **)&a->ptrinuse)); 34929566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 349375f6d85dSStefano Zampini if (v) *v = NULL; 34943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34956947451fSStefano Zampini } 34966947451fSStefano Zampini 3497d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v) 3498d71ae5a4SJacob Faibussowitsch { 34996947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35006947451fSStefano Zampini 35016947451fSStefano Zampini PetscFunctionBegin; 350228b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 350328b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3504d16ceb75SStefano Zampini if (!a->cvec) PetscCall(MatDenseCreateColumnVec_Private(A, &a->cvec)); 35056947451fSStefano Zampini a->vecinuse = col + 1; 35069566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &a->ptrinuse)); 35078e3a54c0SPierre Jolivet PetscCall(VecPlaceArray(a->cvec, PetscSafePointerPlusOffset(a->ptrinuse, (size_t)col * (size_t)a->lda))); 35089566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(a->cvec)); 35096947451fSStefano Zampini *v = a->cvec; 35103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35116947451fSStefano Zampini } 35126947451fSStefano Zampini 3513d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v) 3514d71ae5a4SJacob Faibussowitsch { 35156947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35166947451fSStefano Zampini 35176947451fSStefano Zampini PetscFunctionBegin; 351828b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 351928b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 35206947451fSStefano Zampini a->vecinuse = 0; 35219566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &a->ptrinuse)); 35229566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(a->cvec)); 35239566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 352475f6d85dSStefano Zampini if (v) *v = NULL; 35253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35266947451fSStefano Zampini } 35276947451fSStefano Zampini 3528d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v) 3529d71ae5a4SJacob Faibussowitsch { 35306947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35316947451fSStefano Zampini 35326947451fSStefano Zampini PetscFunctionBegin; 353328b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 353428b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3535d16ceb75SStefano Zampini if (!a->cvec) PetscCall(MatDenseCreateColumnVec_Private(A, &a->cvec)); 35366947451fSStefano Zampini a->vecinuse = col + 1; 35379566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(A, (PetscScalar **)&a->ptrinuse)); 35388e3a54c0SPierre Jolivet PetscCall(VecPlaceArray(a->cvec, PetscSafePointerPlusOffset(a->ptrinuse, (size_t)col * (size_t)a->lda))); 35396947451fSStefano Zampini *v = a->cvec; 35403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35416947451fSStefano Zampini } 35426947451fSStefano Zampini 3543d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v) 3544d71ae5a4SJacob Faibussowitsch { 35456947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35466947451fSStefano Zampini 35476947451fSStefano Zampini PetscFunctionBegin; 354828b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 354928b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 35506947451fSStefano Zampini a->vecinuse = 0; 35519566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(A, (PetscScalar **)&a->ptrinuse)); 35529566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 355375f6d85dSStefano Zampini if (v) *v = NULL; 35543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35556947451fSStefano Zampini } 35566947451fSStefano Zampini 3557d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) 3558d71ae5a4SJacob Faibussowitsch { 35595ea7661aSPierre Jolivet Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35605ea7661aSPierre Jolivet 35615ea7661aSPierre Jolivet PetscFunctionBegin; 356228b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 356328b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3564a2748737SPierre Jolivet if (a->cmat && (cend - cbegin != a->cmat->cmap->N || rend - rbegin != a->cmat->rmap->N)) PetscCall(MatDestroy(&a->cmat)); 35655ea7661aSPierre Jolivet if (!a->cmat) { 35668e3a54c0SPierre 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)); 35675ea7661aSPierre Jolivet } else { 35688e3a54c0SPierre Jolivet PetscCall(MatDensePlaceArray(a->cmat, PetscSafePointerPlusOffset(a->v, rbegin + (size_t)cbegin * a->lda))); 35695ea7661aSPierre Jolivet } 35709566063dSJacob Faibussowitsch PetscCall(MatDenseSetLDA(a->cmat, a->lda)); 35715ea7661aSPierre Jolivet a->matinuse = cbegin + 1; 35725ea7661aSPierre Jolivet *v = a->cmat; 357347d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 357475f6d85dSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 357575f6d85dSStefano Zampini #endif 35763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35775ea7661aSPierre Jolivet } 35785ea7661aSPierre Jolivet 3579d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A, Mat *v) 3580d71ae5a4SJacob Faibussowitsch { 35815ea7661aSPierre Jolivet Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35825ea7661aSPierre Jolivet 35835ea7661aSPierre Jolivet PetscFunctionBegin; 358428b400f6SJacob Faibussowitsch PetscCheck(a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetSubMatrix() first"); 358528b400f6SJacob Faibussowitsch PetscCheck(a->cmat, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column matrix"); 358608401ef6SPierre Jolivet PetscCheck(*v == a->cmat, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not the matrix obtained from MatDenseGetSubMatrix()"); 35875ea7661aSPierre Jolivet a->matinuse = 0; 35889566063dSJacob Faibussowitsch PetscCall(MatDenseResetArray(a->cmat)); 3589742765d3SMatthew Knepley if (v) *v = NULL; 359047d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 35913faff063SStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 35923faff063SStefano Zampini #endif 35933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35945ea7661aSPierre Jolivet } 35955ea7661aSPierre Jolivet 35960bad9183SKris Buschelman /*MC 3597fafad747SKris Buschelman MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices. 35980bad9183SKris Buschelman 35992ef1f0ffSBarry Smith Options Database Key: 360011a5261eSBarry Smith . -mat_type seqdense - sets the matrix type to `MATSEQDENSE` during a call to `MatSetFromOptions()` 36010bad9183SKris Buschelman 36020bad9183SKris Buschelman Level: beginner 36030bad9183SKris Buschelman 36041cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATSEQDENSE`, `MatCreateSeqDense()` 36050bad9183SKris Buschelman M*/ 3606d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreate_SeqDense(Mat B) 3607d71ae5a4SJacob Faibussowitsch { 3608273d9f13SBarry Smith Mat_SeqDense *b; 36097c334f02SBarry Smith PetscMPIInt size; 3610273d9f13SBarry Smith 3611273d9f13SBarry Smith PetscFunctionBegin; 36129566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)B), &size)); 361308401ef6SPierre Jolivet PetscCheck(size <= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Comm must be of size 1"); 361455659b69SBarry Smith 36154dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&b)); 361644cd7ae7SLois Curfman McInnes B->data = (void *)b; 3617aea10558SJacob Faibussowitsch B->ops[0] = MatOps_Values; 361818f449edSLois Curfman McInnes 3619273d9f13SBarry Smith b->roworiented = PETSC_TRUE; 36204e220ebcSLois Curfman McInnes 36219566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatQRFactor_C", MatQRFactor_SeqDense)); 36229566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetLDA_C", MatDenseGetLDA_SeqDense)); 36239566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseSetLDA_C", MatDenseSetLDA_SeqDense)); 36249566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArray_C", MatDenseGetArray_SeqDense)); 36259566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArray_C", MatDenseRestoreArray_SeqDense)); 36269566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDensePlaceArray_C", MatDensePlaceArray_SeqDense)); 36279566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseResetArray_C", MatDenseResetArray_SeqDense)); 36289566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseReplaceArray_C", MatDenseReplaceArray_SeqDense)); 36299566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayRead_C", MatDenseGetArray_SeqDense)); 36309566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayRead_C", MatDenseRestoreArray_SeqDense)); 36319566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayWrite_C", MatDenseGetArray_SeqDense)); 36329566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayWrite_C", MatDenseRestoreArray_SeqDense)); 36339566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqaij_C", MatConvert_SeqDense_SeqAIJ)); 36348baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 36359566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_elemental_C", MatConvert_SeqDense_Elemental)); 36368baccfbdSHong Zhang #endif 3637d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 36389566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_scalapack_C", MatConvert_Dense_ScaLAPACK)); 3639d24d4204SJose E. Roman #endif 36402bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA) 36419566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensecuda_C", MatConvert_SeqDense_SeqDenseCUDA)); 36429566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", MatProductSetFromOptions_SeqDense)); 36439566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdense_C", MatProductSetFromOptions_SeqDense)); 36449566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensecuda_C", MatProductSetFromOptions_SeqDense)); 36452bf066beSStefano Zampini #endif 364647d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 364747d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensehip_C", MatConvert_SeqDense_SeqDenseHIP)); 364847d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensehip_seqdensehip_C", MatProductSetFromOptions_SeqDense)); 364947d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensehip_seqdense_C", MatProductSetFromOptions_SeqDense)); 365047d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensehip_C", MatProductSetFromOptions_SeqDense)); 365147d993e7Ssuyashtn #endif 36529566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSeqDenseSetPreallocation_C", MatSeqDenseSetPreallocation_SeqDense)); 36539566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqaij_seqdense_C", MatProductSetFromOptions_SeqAIJ_SeqDense)); 36549566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdense_C", MatProductSetFromOptions_SeqDense)); 36559566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense)); 36569566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqsbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense)); 365796e6d5c4SRichard Tran Mills 36589566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumn_C", MatDenseGetColumn_SeqDense)); 36599566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumn_C", MatDenseRestoreColumn_SeqDense)); 36609566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVec_C", MatDenseGetColumnVec_SeqDense)); 36619566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVec_C", MatDenseRestoreColumnVec_SeqDense)); 36629566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecRead_C", MatDenseGetColumnVecRead_SeqDense)); 36639566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecRead_C", MatDenseRestoreColumnVecRead_SeqDense)); 36649566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecWrite_C", MatDenseGetColumnVecWrite_SeqDense)); 36659566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecWrite_C", MatDenseRestoreColumnVecWrite_SeqDense)); 36669566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetSubMatrix_C", MatDenseGetSubMatrix_SeqDense)); 36679566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreSubMatrix_C", MatDenseRestoreSubMatrix_SeqDense)); 3668*0be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatMultAddColumnRange_C", MatMultAddColumnRange_SeqDense)); 3669*0be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatMultHermitianTransposeColumnRange_C", MatMultHermitianTransposeColumnRange_SeqDense)); 3670*0be0d8bdSHansol Suh PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatMultHermitianTransposeAddColumnRange_C", MatMultHermitianTransposeAddColumnRange_SeqDense)); 36719566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)B, MATSEQDENSE)); 36723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3673289bc588SBarry Smith } 367486aefd0dSHong Zhang 367586aefd0dSHong Zhang /*@C 367611a5261eSBarry 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. 367786aefd0dSHong Zhang 367886aefd0dSHong Zhang Not Collective 367986aefd0dSHong Zhang 36805ea7661aSPierre Jolivet Input Parameters: 3681fe59aa6dSJacob Faibussowitsch + A - a `MATSEQDENSE` or `MATMPIDENSE` matrix 368286aefd0dSHong Zhang - col - column index 368386aefd0dSHong Zhang 368486aefd0dSHong Zhang Output Parameter: 368586aefd0dSHong Zhang . vals - pointer to the data 368686aefd0dSHong Zhang 368786aefd0dSHong Zhang Level: intermediate 368886aefd0dSHong Zhang 368911a5261eSBarry Smith Note: 369011a5261eSBarry Smith Use `MatDenseGetColumnVec()` to get access to a column of a `MATDENSE` treated as a `Vec` 369111a5261eSBarry Smith 36921cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseRestoreColumn()`, `MatDenseGetColumnVec()` 369386aefd0dSHong Zhang @*/ 3694d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumn(Mat A, PetscInt col, PetscScalar **vals) 3695d71ae5a4SJacob Faibussowitsch { 369686aefd0dSHong Zhang PetscFunctionBegin; 3697d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3698d5ea218eSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 36994f572ea9SToby Isaac PetscAssertPointer(vals, 3); 3700cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumn_C", (Mat, PetscInt, PetscScalar **), (A, col, vals)); 37013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 370286aefd0dSHong Zhang } 370386aefd0dSHong Zhang 370486aefd0dSHong Zhang /*@C 370511a5261eSBarry Smith MatDenseRestoreColumn - returns access to a column of a `MATDENSE` matrix which is returned by `MatDenseGetColumn()`. 370686aefd0dSHong Zhang 370786aefd0dSHong Zhang Not Collective 370886aefd0dSHong Zhang 3709742765d3SMatthew Knepley Input Parameters: 3710fe59aa6dSJacob Faibussowitsch + A - a `MATSEQDENSE` or `MATMPIDENSE` matrix 37112ef1f0ffSBarry Smith - vals - pointer to the data (may be `NULL`) 371286aefd0dSHong Zhang 371386aefd0dSHong Zhang Level: intermediate 371486aefd0dSHong Zhang 37151cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MatDenseGetColumn()` 371686aefd0dSHong Zhang @*/ 3717d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumn(Mat A, PetscScalar **vals) 3718d71ae5a4SJacob Faibussowitsch { 371986aefd0dSHong Zhang PetscFunctionBegin; 3720d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 37214f572ea9SToby Isaac PetscAssertPointer(vals, 2); 3722cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumn_C", (Mat, PetscScalar **), (A, vals)); 37233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 372486aefd0dSHong Zhang } 37256947451fSStefano Zampini 37260f74d2c1SSatish Balay /*@ 372711a5261eSBarry Smith MatDenseGetColumnVec - Gives read-write access to a column of a `MATDENSE` matrix, represented as a `Vec`. 37286947451fSStefano Zampini 37296947451fSStefano Zampini Collective 37306947451fSStefano Zampini 37315ea7661aSPierre Jolivet Input Parameters: 3732fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 37336947451fSStefano Zampini - col - the column index 37346947451fSStefano Zampini 37356947451fSStefano Zampini Output Parameter: 37366947451fSStefano Zampini . v - the vector 37376947451fSStefano Zampini 37382ef1f0ffSBarry Smith Level: intermediate 37392ef1f0ffSBarry Smith 37406947451fSStefano Zampini Notes: 374111a5261eSBarry Smith The vector is owned by PETSc. Users need to call `MatDenseRestoreColumnVec()` when the vector is no longer needed. 374211a5261eSBarry Smith 374311a5261eSBarry Smith Use `MatDenseGetColumnVecRead()` to obtain read-only access or `MatDenseGetColumnVecWrite()` for write-only access. 37446947451fSStefano Zampini 37451cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`, `MatDenseGetColumn()` 37466947451fSStefano Zampini @*/ 3747d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec(Mat A, PetscInt col, Vec *v) 3748d71ae5a4SJacob Faibussowitsch { 37496947451fSStefano Zampini PetscFunctionBegin; 37506947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 37516947451fSStefano Zampini PetscValidType(A, 1); 37526947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 37534f572ea9SToby Isaac PetscAssertPointer(v, 3); 375428b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 37552cf15c64SPierre 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); 3756cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v)); 37573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37586947451fSStefano Zampini } 37596947451fSStefano Zampini 37600f74d2c1SSatish Balay /*@ 3761fb850c59SBarry Smith MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from `MatDenseGetColumnVec()`. 37626947451fSStefano Zampini 37636947451fSStefano Zampini Collective 37646947451fSStefano Zampini 37655ea7661aSPierre Jolivet Input Parameters: 3766fb850c59SBarry Smith + A - the `Mat` object 37676947451fSStefano Zampini . col - the column index 3768fb850c59SBarry Smith - v - the `Vec` object (may be `NULL`) 37696947451fSStefano Zampini 37706947451fSStefano Zampini Level: intermediate 37716947451fSStefano Zampini 37721cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 37736947451fSStefano Zampini @*/ 3774d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec(Mat A, PetscInt col, Vec *v) 3775d71ae5a4SJacob Faibussowitsch { 37766947451fSStefano Zampini PetscFunctionBegin; 37776947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 37786947451fSStefano Zampini PetscValidType(A, 1); 37796947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 378008401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 37812cf15c64SPierre 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); 3782cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v)); 37833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37846947451fSStefano Zampini } 37856947451fSStefano Zampini 37860f74d2c1SSatish Balay /*@ 3787fb850c59SBarry Smith MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a `Vec`. 37886947451fSStefano Zampini 37896947451fSStefano Zampini Collective 37906947451fSStefano Zampini 37915ea7661aSPierre Jolivet Input Parameters: 3792fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 37936947451fSStefano Zampini - col - the column index 37946947451fSStefano Zampini 37956947451fSStefano Zampini Output Parameter: 37966947451fSStefano Zampini . v - the vector 37976947451fSStefano Zampini 37982ef1f0ffSBarry Smith Level: intermediate 37992ef1f0ffSBarry Smith 38006947451fSStefano Zampini Notes: 38016947451fSStefano Zampini The vector is owned by PETSc and users cannot modify it. 380211a5261eSBarry Smith 38032ef1f0ffSBarry Smith Users need to call `MatDenseRestoreColumnVecRead()` when the vector is no longer needed. 380411a5261eSBarry Smith 38052ef1f0ffSBarry Smith Use `MatDenseGetColumnVec()` to obtain read-write access or `MatDenseGetColumnVecWrite()` for write-only access. 38066947451fSStefano Zampini 38071cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 38086947451fSStefano Zampini @*/ 3809d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead(Mat A, PetscInt col, Vec *v) 3810d71ae5a4SJacob Faibussowitsch { 38116947451fSStefano Zampini PetscFunctionBegin; 38126947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38136947451fSStefano Zampini PetscValidType(A, 1); 38146947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 38154f572ea9SToby Isaac PetscAssertPointer(v, 3); 381628b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 38172cf15c64SPierre 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); 3818cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v)); 38193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38206947451fSStefano Zampini } 38216947451fSStefano Zampini 38220f74d2c1SSatish Balay /*@ 3823fb850c59SBarry Smith MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from `MatDenseGetColumnVecRead()`. 38246947451fSStefano Zampini 38256947451fSStefano Zampini Collective 38266947451fSStefano Zampini 38275ea7661aSPierre Jolivet Input Parameters: 3828fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 38296947451fSStefano Zampini . col - the column index 3830fb850c59SBarry Smith - v - the `Vec` object (may be `NULL`) 38316947451fSStefano Zampini 38326947451fSStefano Zampini Level: intermediate 38336947451fSStefano Zampini 38341cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecWrite()` 38356947451fSStefano Zampini @*/ 3836d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead(Mat A, PetscInt col, Vec *v) 3837d71ae5a4SJacob Faibussowitsch { 38386947451fSStefano Zampini PetscFunctionBegin; 38396947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38406947451fSStefano Zampini PetscValidType(A, 1); 38416947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 384208401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 38432cf15c64SPierre 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); 3844cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v)); 38453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38466947451fSStefano Zampini } 38476947451fSStefano Zampini 38480f74d2c1SSatish Balay /*@ 3849fb850c59SBarry Smith MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a `Vec`. 38506947451fSStefano Zampini 38516947451fSStefano Zampini Collective 38526947451fSStefano Zampini 38535ea7661aSPierre Jolivet Input Parameters: 3854fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 38556947451fSStefano Zampini - col - the column index 38566947451fSStefano Zampini 38576947451fSStefano Zampini Output Parameter: 38586947451fSStefano Zampini . v - the vector 38596947451fSStefano Zampini 38606947451fSStefano Zampini Level: intermediate 38616947451fSStefano Zampini 38622ef1f0ffSBarry Smith Notes: 38632ef1f0ffSBarry Smith The vector is owned by PETSc. Users need to call `MatDenseRestoreColumnVecWrite()` when the vector is no longer needed. 38642ef1f0ffSBarry Smith 38652ef1f0ffSBarry Smith Use `MatDenseGetColumnVec()` to obtain read-write access or `MatDenseGetColumnVecRead()` for read-only access. 38662ef1f0ffSBarry Smith 38671cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 38686947451fSStefano Zampini @*/ 3869d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite(Mat A, PetscInt col, Vec *v) 3870d71ae5a4SJacob Faibussowitsch { 38716947451fSStefano Zampini PetscFunctionBegin; 38726947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38736947451fSStefano Zampini PetscValidType(A, 1); 38746947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 38754f572ea9SToby Isaac PetscAssertPointer(v, 3); 387628b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3877aed4548fSBarry 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); 3878cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v)); 38793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38806947451fSStefano Zampini } 38816947451fSStefano Zampini 38820f74d2c1SSatish Balay /*@ 3883fb850c59SBarry Smith MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from `MatDenseGetColumnVecWrite()`. 38846947451fSStefano Zampini 38856947451fSStefano Zampini Collective 38866947451fSStefano Zampini 38875ea7661aSPierre Jolivet Input Parameters: 3888fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 38896947451fSStefano Zampini . col - the column index 38902ef1f0ffSBarry Smith - v - the `Vec` object (may be `NULL`) 38916947451fSStefano Zampini 38926947451fSStefano Zampini Level: intermediate 38936947451fSStefano Zampini 38941cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()` 38956947451fSStefano Zampini @*/ 3896d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A, PetscInt col, Vec *v) 3897d71ae5a4SJacob Faibussowitsch { 38986947451fSStefano Zampini PetscFunctionBegin; 38996947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 39006947451fSStefano Zampini PetscValidType(A, 1); 39016947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 390208401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3903aed4548fSBarry 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); 3904cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v)); 39053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 39066947451fSStefano Zampini } 39075ea7661aSPierre Jolivet 39080f74d2c1SSatish Balay /*@ 3909fb850c59SBarry Smith MatDenseGetSubMatrix - Gives access to a block of rows and columns of a dense matrix, represented as a `Mat`. 39105ea7661aSPierre Jolivet 39115ea7661aSPierre Jolivet Collective 39125ea7661aSPierre Jolivet 39135ea7661aSPierre Jolivet Input Parameters: 3914fb850c59SBarry Smith + A - the `Mat` object 39152ef1f0ffSBarry Smith . rbegin - the first global row index in the block (if `PETSC_DECIDE`, is 0) 39162ef1f0ffSBarry Smith . rend - the global row index past the last one in the block (if `PETSC_DECIDE`, is `M`) 39172ef1f0ffSBarry Smith . cbegin - the first global column index in the block (if `PETSC_DECIDE`, is 0) 39182ef1f0ffSBarry Smith - cend - the global column index past the last one in the block (if `PETSC_DECIDE`, is `N`) 39195ea7661aSPierre Jolivet 39205ea7661aSPierre Jolivet Output Parameter: 39215ea7661aSPierre Jolivet . v - the matrix 39225ea7661aSPierre Jolivet 39235ea7661aSPierre Jolivet Level: intermediate 39245ea7661aSPierre Jolivet 39252ef1f0ffSBarry Smith Notes: 39262ef1f0ffSBarry Smith The matrix is owned by PETSc. Users need to call `MatDenseRestoreSubMatrix()` when the matrix is no longer needed. 39272ef1f0ffSBarry Smith 39282ef1f0ffSBarry 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. 39292ef1f0ffSBarry Smith 39301cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreSubMatrix()` 39315ea7661aSPierre Jolivet @*/ 3932d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) 3933d71ae5a4SJacob Faibussowitsch { 39345ea7661aSPierre Jolivet PetscFunctionBegin; 39355ea7661aSPierre Jolivet PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 39365ea7661aSPierre Jolivet PetscValidType(A, 1); 3937a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, rbegin, 2); 3938a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, rend, 3); 3939a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, cbegin, 4); 3940a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, cend, 5); 39414f572ea9SToby Isaac PetscAssertPointer(v, 6); 3942a2748737SPierre Jolivet if (rbegin == PETSC_DECIDE) rbegin = 0; 3943a2748737SPierre Jolivet if (rend == PETSC_DECIDE) rend = A->rmap->N; 3944a2748737SPierre Jolivet if (cbegin == PETSC_DECIDE) cbegin = 0; 3945a2748737SPierre Jolivet if (cend == PETSC_DECIDE) cend = A->cmap->N; 394628b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3947a2748737SPierre 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); 3948a2748737SPierre 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); 3949a2748737SPierre 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); 3950a2748737SPierre 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); 3951a2748737SPierre Jolivet PetscUseMethod(A, "MatDenseGetSubMatrix_C", (Mat, PetscInt, PetscInt, PetscInt, PetscInt, Mat *), (A, rbegin, rend, cbegin, cend, v)); 39523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 39535ea7661aSPierre Jolivet } 39545ea7661aSPierre Jolivet 39550f74d2c1SSatish Balay /*@ 3956fb850c59SBarry Smith MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from `MatDenseGetSubMatrix()`. 39575ea7661aSPierre Jolivet 39585ea7661aSPierre Jolivet Collective 39595ea7661aSPierre Jolivet 39605ea7661aSPierre Jolivet Input Parameters: 3961fe59aa6dSJacob Faibussowitsch + A - the `Mat` object 39622ef1f0ffSBarry Smith - v - the `Mat` object (may be `NULL`) 39635ea7661aSPierre Jolivet 39645ea7661aSPierre Jolivet Level: intermediate 39655ea7661aSPierre Jolivet 39661cc06b55SBarry Smith .seealso: [](ch_matrices), `Mat`, `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseGetSubMatrix()` 39675ea7661aSPierre Jolivet @*/ 3968d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix(Mat A, Mat *v) 3969d71ae5a4SJacob Faibussowitsch { 39705ea7661aSPierre Jolivet PetscFunctionBegin; 39715ea7661aSPierre Jolivet PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 39725ea7661aSPierre Jolivet PetscValidType(A, 1); 39734f572ea9SToby Isaac PetscAssertPointer(v, 2); 3974cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreSubMatrix_C", (Mat, Mat *), (A, v)); 39753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 39765ea7661aSPierre Jolivet } 39778a9c020eSBarry Smith 39788a9c020eSBarry Smith #include <petscblaslapack.h> 39798a9c020eSBarry Smith #include <petsc/private/kernels/blockinvert.h> 39808a9c020eSBarry Smith 3981d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseInvert(Mat A) 3982d71ae5a4SJacob Faibussowitsch { 3983d63b1753SJacob Faibussowitsch PetscInt m; 39848a9c020eSBarry Smith const PetscReal shift = 0.0; 3985d63b1753SJacob Faibussowitsch PetscBool allowzeropivot, zeropivotdetected = PETSC_FALSE; 3986d63b1753SJacob Faibussowitsch PetscScalar *values; 39878a9c020eSBarry Smith 39888a9c020eSBarry Smith PetscFunctionBegin; 3989d63b1753SJacob Faibussowitsch PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3990d63b1753SJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &values)); 3991d63b1753SJacob Faibussowitsch PetscCall(MatGetLocalSize(A, &m, NULL)); 3992d63b1753SJacob Faibussowitsch allowzeropivot = PetscNot(A->erroriffailure); 39938a9c020eSBarry Smith /* factor and invert each block */ 3994d63b1753SJacob Faibussowitsch switch (m) { 3995d71ae5a4SJacob Faibussowitsch case 1: 3996d71ae5a4SJacob Faibussowitsch values[0] = (PetscScalar)1.0 / (values[0] + shift); 3997d71ae5a4SJacob Faibussowitsch break; 39988a9c020eSBarry Smith case 2: 39998a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_2(values, shift, allowzeropivot, &zeropivotdetected)); 40008a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 40018a9c020eSBarry Smith break; 40028a9c020eSBarry Smith case 3: 40038a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_3(values, shift, allowzeropivot, &zeropivotdetected)); 40048a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 40058a9c020eSBarry Smith break; 40068a9c020eSBarry Smith case 4: 40078a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_4(values, shift, allowzeropivot, &zeropivotdetected)); 40088a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 40098a9c020eSBarry Smith break; 40109371c9d4SSatish Balay case 5: { 40118a9c020eSBarry Smith PetscScalar work[25]; 40128a9c020eSBarry Smith PetscInt ipvt[5]; 40138a9c020eSBarry Smith 40148a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_5(values, ipvt, work, shift, allowzeropivot, &zeropivotdetected)); 40158a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 40169371c9d4SSatish Balay } break; 40178a9c020eSBarry Smith case 6: 40188a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_6(values, shift, allowzeropivot, &zeropivotdetected)); 40198a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 40208a9c020eSBarry Smith break; 40218a9c020eSBarry Smith case 7: 40228a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_7(values, shift, allowzeropivot, &zeropivotdetected)); 40238a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 40248a9c020eSBarry Smith break; 40259371c9d4SSatish Balay default: { 40268a9c020eSBarry Smith PetscInt *v_pivots, *IJ, j; 40278a9c020eSBarry Smith PetscScalar *v_work; 40288a9c020eSBarry Smith 4029d63b1753SJacob Faibussowitsch PetscCall(PetscMalloc3(m, &v_work, m, &v_pivots, m, &IJ)); 4030d63b1753SJacob Faibussowitsch for (j = 0; j < m; j++) IJ[j] = j; 4031d63b1753SJacob Faibussowitsch PetscCall(PetscKernel_A_gets_inverse_A(m, values, v_pivots, v_work, allowzeropivot, &zeropivotdetected)); 40328a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 40338a9c020eSBarry Smith PetscCall(PetscFree3(v_work, v_pivots, IJ)); 40348a9c020eSBarry Smith } 40358a9c020eSBarry Smith } 4036d63b1753SJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &values)); 40373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 40388a9c020eSBarry Smith } 4039