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*/ 8c6db04a5SJed Brown #include <petscblaslapack.h> 96a63e612SBarry Smith #include <../src/mat/impls/aij/seq/aij.h> 10b2573a8aSBarry Smith 11d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSymmetrize_Private(Mat A, PetscBool hermitian) 12d71ae5a4SJacob Faibussowitsch { 138c178816SStefano Zampini Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 148c178816SStefano Zampini PetscInt j, k, n = A->rmap->n; 15ca15aa20SStefano Zampini PetscScalar *v; 168c178816SStefano Zampini 178c178816SStefano Zampini PetscFunctionBegin; 1808401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Cannot symmetrize a rectangular matrix"); 199566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 208c178816SStefano Zampini if (!hermitian) { 218c178816SStefano Zampini for (k = 0; k < n; k++) { 22ad540459SPierre Jolivet for (j = k; j < n; j++) v[j * mat->lda + k] = v[k * mat->lda + j]; 238c178816SStefano Zampini } 248c178816SStefano Zampini } else { 258c178816SStefano Zampini for (k = 0; k < n; k++) { 26ad540459SPierre Jolivet for (j = k; j < n; j++) v[j * mat->lda + k] = PetscConj(v[k * mat->lda + j]); 278c178816SStefano Zampini } 288c178816SStefano Zampini } 299566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 308c178816SStefano Zampini PetscFunctionReturn(0); 318c178816SStefano Zampini } 328c178816SStefano Zampini 33d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode MatSeqDenseInvertFactors_Private(Mat A) 34d71ae5a4SJacob Faibussowitsch { 358c178816SStefano Zampini Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 368c178816SStefano Zampini PetscBLASInt info, n; 378c178816SStefano Zampini 388c178816SStefano Zampini PetscFunctionBegin; 398c178816SStefano Zampini if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 409566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 418c178816SStefano Zampini if (A->factortype == MAT_FACTOR_LU) { 4228b400f6SJacob Faibussowitsch PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present"); 438c178816SStefano Zampini if (!mat->fwork) { 448c178816SStefano Zampini mat->lfwork = n; 459566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 468c178816SStefano Zampini } 479566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 48792fecdfSBarry Smith PetscCallBLAS("LAPACKgetri", LAPACKgetri_(&n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info)); 499566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 509566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0)); 518c178816SStefano Zampini } else if (A->factortype == MAT_FACTOR_CHOLESKY) { 52b94d7dedSBarry Smith if (A->spd == PETSC_BOOL3_TRUE) { 539566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 54792fecdfSBarry Smith PetscCallBLAS("LAPACKpotri", LAPACKpotri_("L", &n, mat->v, &mat->lda, &info)); 559566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 569566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_TRUE)); 578c178816SStefano Zampini #if defined(PETSC_USE_COMPLEX) 58b94d7dedSBarry Smith } else if (A->hermitian == PETSC_BOOL3_TRUE) { 5928b400f6SJacob Faibussowitsch PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present"); 6028b400f6SJacob Faibussowitsch PetscCheck(mat->fwork, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Fwork not present"); 619566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 62792fecdfSBarry Smith PetscCallBLAS("LAPACKhetri", LAPACKhetri_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &info)); 639566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 649566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_TRUE)); 658c178816SStefano Zampini #endif 668c178816SStefano Zampini } else { /* symmetric case */ 6728b400f6SJacob Faibussowitsch PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present"); 6828b400f6SJacob Faibussowitsch PetscCheck(mat->fwork, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Fwork not present"); 699566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 70792fecdfSBarry Smith PetscCallBLAS("LAPACKsytri", LAPACKsytri_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &info)); 719566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 729566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_FALSE)); 738c178816SStefano Zampini } 7428b400f6SJacob Faibussowitsch PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad Inversion: zero pivot in row %" PetscInt_FMT, (PetscInt)info - 1); 759566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0)); 768c178816SStefano Zampini } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Matrix must be factored to solve"); 778c178816SStefano Zampini 788c178816SStefano Zampini A->ops->solve = NULL; 798c178816SStefano Zampini A->ops->matsolve = NULL; 808c178816SStefano Zampini A->ops->solvetranspose = NULL; 818c178816SStefano Zampini A->ops->matsolvetranspose = NULL; 828c178816SStefano Zampini A->ops->solveadd = NULL; 838c178816SStefano Zampini A->ops->solvetransposeadd = NULL; 848c178816SStefano Zampini A->factortype = MAT_FACTOR_NONE; 859566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 868c178816SStefano Zampini PetscFunctionReturn(0); 878c178816SStefano Zampini } 888c178816SStefano Zampini 89d71ae5a4SJacob Faibussowitsch PetscErrorCode MatZeroRowsColumns_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) 90d71ae5a4SJacob Faibussowitsch { 913f49a652SStefano Zampini Mat_SeqDense *l = (Mat_SeqDense *)A->data; 923f49a652SStefano Zampini PetscInt m = l->lda, n = A->cmap->n, r = A->rmap->n, i, j; 93ca15aa20SStefano Zampini PetscScalar *slot, *bb, *v; 943f49a652SStefano Zampini const PetscScalar *xx; 953f49a652SStefano Zampini 963f49a652SStefano Zampini PetscFunctionBegin; 9776bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 983f49a652SStefano Zampini for (i = 0; i < N; i++) { 9908401ef6SPierre Jolivet PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed"); 10008401ef6SPierre 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); 10108401ef6SPierre 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); 1023f49a652SStefano Zampini } 10376bd3646SJed Brown } 104ca15aa20SStefano Zampini if (!N) PetscFunctionReturn(0); 1053f49a652SStefano Zampini 1063f49a652SStefano Zampini /* fix right hand side if needed */ 1073f49a652SStefano Zampini if (x && b) { 1086c4d906cSStefano Zampini Vec xt; 1096c4d906cSStefano Zampini 11008401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices"); 1119566063dSJacob Faibussowitsch PetscCall(VecDuplicate(x, &xt)); 1129566063dSJacob Faibussowitsch PetscCall(VecCopy(x, xt)); 1139566063dSJacob Faibussowitsch PetscCall(VecScale(xt, -1.0)); 1149566063dSJacob Faibussowitsch PetscCall(MatMultAdd(A, xt, b, b)); 1159566063dSJacob Faibussowitsch PetscCall(VecDestroy(&xt)); 1169566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 1179566063dSJacob Faibussowitsch PetscCall(VecGetArray(b, &bb)); 1183f49a652SStefano Zampini for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]]; 1199566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 1209566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(b, &bb)); 1213f49a652SStefano Zampini } 1223f49a652SStefano Zampini 1239566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 1243f49a652SStefano Zampini for (i = 0; i < N; i++) { 125ca15aa20SStefano Zampini slot = v + rows[i] * m; 1269566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(slot, r)); 1273f49a652SStefano Zampini } 1283f49a652SStefano Zampini for (i = 0; i < N; i++) { 129ca15aa20SStefano Zampini slot = v + rows[i]; 1309371c9d4SSatish Balay for (j = 0; j < n; j++) { 1319371c9d4SSatish Balay *slot = 0.0; 1329371c9d4SSatish Balay slot += m; 1339371c9d4SSatish Balay } 1343f49a652SStefano Zampini } 1353f49a652SStefano Zampini if (diag != 0.0) { 13608401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices"); 1373f49a652SStefano Zampini for (i = 0; i < N; i++) { 138ca15aa20SStefano Zampini slot = v + (m + 1) * rows[i]; 1393f49a652SStefano Zampini *slot = diag; 1403f49a652SStefano Zampini } 1413f49a652SStefano Zampini } 1429566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 1433f49a652SStefano Zampini PetscFunctionReturn(0); 1443f49a652SStefano Zampini } 1453f49a652SStefano Zampini 146d71ae5a4SJacob Faibussowitsch PetscErrorCode MatPtAPNumeric_SeqDense_SeqDense(Mat A, Mat P, Mat C) 147d71ae5a4SJacob Faibussowitsch { 148abc3b08eSStefano Zampini Mat_SeqDense *c = (Mat_SeqDense *)(C->data); 149abc3b08eSStefano Zampini 150abc3b08eSStefano Zampini PetscFunctionBegin; 151ca15aa20SStefano Zampini if (c->ptapwork) { 1529566063dSJacob Faibussowitsch PetscCall((*C->ops->matmultnumeric)(A, P, c->ptapwork)); 1539566063dSJacob Faibussowitsch PetscCall((*C->ops->transposematmultnumeric)(P, c->ptapwork, C)); 1544222ddf1SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)C), PETSC_ERR_SUP, "Must call MatPtAPSymbolic_SeqDense_SeqDense() first"); 155abc3b08eSStefano Zampini PetscFunctionReturn(0); 156abc3b08eSStefano Zampini } 157abc3b08eSStefano Zampini 158d71ae5a4SJacob Faibussowitsch PetscErrorCode MatPtAPSymbolic_SeqDense_SeqDense(Mat A, Mat P, PetscReal fill, Mat C) 159d71ae5a4SJacob Faibussowitsch { 160abc3b08eSStefano Zampini Mat_SeqDense *c; 16147d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 162abc3b08eSStefano Zampini 163abc3b08eSStefano Zampini PetscFunctionBegin; 1649566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, P->cmap->n, P->cmap->n, P->cmap->N, P->cmap->N)); 16547d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 1669566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 16747d993e7Ssuyashtn #elif (PETSC_HAVE_HIP) 16847d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 16947d993e7Ssuyashtn #endif 17047d993e7Ssuyashtn 1717a3c3d58SStefano Zampini if (!cisdense) { 1727a3c3d58SStefano Zampini PetscBool flg; 1737a3c3d58SStefano Zampini 1749566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)P, ((PetscObject)A)->type_name, &flg)); 1759566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 1767a3c3d58SStefano Zampini } 1779566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 1784222ddf1SHong Zhang c = (Mat_SeqDense *)C->data; 1799566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &c->ptapwork)); 1809566063dSJacob Faibussowitsch PetscCall(MatSetSizes(c->ptapwork, A->rmap->n, P->cmap->n, A->rmap->N, P->cmap->N)); 1819566063dSJacob Faibussowitsch PetscCall(MatSetType(c->ptapwork, ((PetscObject)C)->type_name)); 1829566063dSJacob Faibussowitsch PetscCall(MatSetUp(c->ptapwork)); 183abc3b08eSStefano Zampini PetscFunctionReturn(0); 184abc3b08eSStefano Zampini } 185abc3b08eSStefano Zampini 186d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) 187d71ae5a4SJacob Faibussowitsch { 188a13144ffSStefano Zampini Mat B = NULL; 189b49cda9fSStefano Zampini Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data; 190b49cda9fSStefano Zampini Mat_SeqDense *b; 191b49cda9fSStefano Zampini PetscInt *ai = a->i, *aj = a->j, m = A->rmap->N, n = A->cmap->N, i; 1922e5835c6SStefano Zampini const MatScalar *av; 193a13144ffSStefano Zampini PetscBool isseqdense; 194b49cda9fSStefano Zampini 195b49cda9fSStefano Zampini PetscFunctionBegin; 196a13144ffSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 1979566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)*newmat, MATSEQDENSE, &isseqdense)); 19828b400f6SJacob Faibussowitsch PetscCheck(isseqdense, PetscObjectComm((PetscObject)*newmat), PETSC_ERR_USER, "Cannot reuse matrix of type %s", ((PetscObject)(*newmat))->type_name); 199a13144ffSStefano Zampini } 200a13144ffSStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 2019566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B)); 2029566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B, m, n, m, n)); 2039566063dSJacob Faibussowitsch PetscCall(MatSetType(B, MATSEQDENSE)); 2049566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(B, NULL)); 205b49cda9fSStefano Zampini b = (Mat_SeqDense *)(B->data); 206a13144ffSStefano Zampini } else { 207a13144ffSStefano Zampini b = (Mat_SeqDense *)((*newmat)->data); 2089566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(b->v, m * n)); 209a13144ffSStefano Zampini } 2109566063dSJacob Faibussowitsch PetscCall(MatSeqAIJGetArrayRead(A, &av)); 211b49cda9fSStefano Zampini for (i = 0; i < m; i++) { 212b49cda9fSStefano Zampini PetscInt j; 213b49cda9fSStefano Zampini for (j = 0; j < ai[1] - ai[0]; j++) { 214b49cda9fSStefano Zampini b->v[*aj * m + i] = *av; 215b49cda9fSStefano Zampini aj++; 216b49cda9fSStefano Zampini av++; 217b49cda9fSStefano Zampini } 218b49cda9fSStefano Zampini ai++; 219b49cda9fSStefano Zampini } 2209566063dSJacob Faibussowitsch PetscCall(MatSeqAIJRestoreArrayRead(A, &av)); 221b49cda9fSStefano Zampini 222511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 2239566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 2249566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 2259566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A, &B)); 226b49cda9fSStefano Zampini } else { 227a13144ffSStefano Zampini if (B) *newmat = B; 2289566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(*newmat, MAT_FINAL_ASSEMBLY)); 2299566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(*newmat, MAT_FINAL_ASSEMBLY)); 230b49cda9fSStefano Zampini } 231b49cda9fSStefano Zampini PetscFunctionReturn(0); 232b49cda9fSStefano Zampini } 233b49cda9fSStefano Zampini 234d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqDense_SeqAIJ(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) 235d71ae5a4SJacob Faibussowitsch { 2366d4ec7b0SPierre Jolivet Mat B = NULL; 2376a63e612SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2389399e1b8SMatthew G. Knepley PetscInt i, j; 2399399e1b8SMatthew G. Knepley PetscInt *rows, *nnz; 2409399e1b8SMatthew G. Knepley MatScalar *aa = a->v, *vals; 2416a63e612SBarry Smith 2426a63e612SBarry Smith PetscFunctionBegin; 2439566063dSJacob Faibussowitsch PetscCall(PetscCalloc3(A->rmap->n, &rows, A->rmap->n, &nnz, A->rmap->n, &vals)); 2446d4ec7b0SPierre Jolivet if (reuse != MAT_REUSE_MATRIX) { 2459566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B)); 2469566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B, A->rmap->n, A->cmap->n, A->rmap->N, A->cmap->N)); 2479566063dSJacob Faibussowitsch PetscCall(MatSetType(B, MATSEQAIJ)); 2489399e1b8SMatthew G. Knepley for (j = 0; j < A->cmap->n; j++) { 2499371c9d4SSatish Balay for (i = 0; i < A->rmap->n; i++) 2509371c9d4SSatish Balay if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) ++nnz[i]; 2516a63e612SBarry Smith aa += a->lda; 2526a63e612SBarry Smith } 2539566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(B, PETSC_DETERMINE, nnz)); 2546d4ec7b0SPierre Jolivet } else B = *newmat; 2559399e1b8SMatthew G. Knepley aa = a->v; 2569399e1b8SMatthew G. Knepley for (j = 0; j < A->cmap->n; j++) { 2579399e1b8SMatthew G. Knepley PetscInt numRows = 0; 2589371c9d4SSatish Balay for (i = 0; i < A->rmap->n; i++) 2599371c9d4SSatish Balay if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) { 2609371c9d4SSatish Balay rows[numRows] = i; 2619371c9d4SSatish Balay vals[numRows++] = aa[i]; 2629371c9d4SSatish Balay } 2639566063dSJacob Faibussowitsch PetscCall(MatSetValues(B, numRows, rows, 1, &j, vals, INSERT_VALUES)); 2649399e1b8SMatthew G. Knepley aa += a->lda; 2659399e1b8SMatthew G. Knepley } 2669566063dSJacob Faibussowitsch PetscCall(PetscFree3(rows, nnz, vals)); 2679566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 2689566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 2696a63e612SBarry Smith 270511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 2719566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A, &B)); 2726d4ec7b0SPierre Jolivet } else if (reuse != MAT_REUSE_MATRIX) *newmat = B; 2736a63e612SBarry Smith PetscFunctionReturn(0); 2746a63e612SBarry Smith } 2756a63e612SBarry Smith 276d71ae5a4SJacob Faibussowitsch PetscErrorCode MatAXPY_SeqDense(Mat Y, PetscScalar alpha, Mat X, MatStructure str) 277d71ae5a4SJacob Faibussowitsch { 2781987afe7SBarry Smith Mat_SeqDense *x = (Mat_SeqDense *)X->data, *y = (Mat_SeqDense *)Y->data; 279ca15aa20SStefano Zampini const PetscScalar *xv; 280ca15aa20SStefano Zampini PetscScalar *yv; 28123fff9afSBarry Smith PetscBLASInt N, m, ldax = 0, lday = 0, one = 1; 2823a40ed3dSBarry Smith 2833a40ed3dSBarry Smith PetscFunctionBegin; 2849566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(X, &xv)); 2859566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(Y, &yv)); 2869566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(X->rmap->n * X->cmap->n, &N)); 2879566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(X->rmap->n, &m)); 2889566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(x->lda, &ldax)); 2899566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(y->lda, &lday)); 290a5ce6ee0Svictorle if (ldax > m || lday > m) { 291ca15aa20SStefano Zampini PetscInt j; 292ca15aa20SStefano Zampini 29348a46eb9SPierre Jolivet for (j = 0; j < X->cmap->n; j++) PetscCallBLAS("BLASaxpy", BLASaxpy_(&m, &alpha, xv + j * ldax, &one, yv + j * lday, &one)); 294a5ce6ee0Svictorle } else { 295792fecdfSBarry Smith PetscCallBLAS("BLASaxpy", BLASaxpy_(&N, &alpha, xv, &one, yv, &one)); 296a5ce6ee0Svictorle } 2979566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(X, &xv)); 2989566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(Y, &yv)); 2999566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(PetscMax(2.0 * N - 1, 0))); 3003a40ed3dSBarry Smith PetscFunctionReturn(0); 3011987afe7SBarry Smith } 3021987afe7SBarry Smith 303d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetInfo_SeqDense(Mat A, MatInfoType flag, MatInfo *info) 304d71ae5a4SJacob Faibussowitsch { 305ca15aa20SStefano Zampini PetscLogDouble N = A->rmap->n * A->cmap->n; 3063a40ed3dSBarry Smith 3073a40ed3dSBarry Smith PetscFunctionBegin; 3084e220ebcSLois Curfman McInnes info->block_size = 1.0; 309ca15aa20SStefano Zampini info->nz_allocated = N; 310ca15aa20SStefano Zampini info->nz_used = N; 311ca15aa20SStefano Zampini info->nz_unneeded = 0; 312ca15aa20SStefano Zampini info->assemblies = A->num_ass; 3134e220ebcSLois Curfman McInnes info->mallocs = 0; 3144dfa11a4SJacob Faibussowitsch info->memory = 0; /* REVIEW ME */ 3154e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 3164e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 3174e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 3183a40ed3dSBarry Smith PetscFunctionReturn(0); 319289bc588SBarry Smith } 320289bc588SBarry Smith 321d71ae5a4SJacob Faibussowitsch PetscErrorCode MatScale_SeqDense(Mat A, PetscScalar alpha) 322d71ae5a4SJacob Faibussowitsch { 323273d9f13SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 324ca15aa20SStefano Zampini PetscScalar *v; 32523fff9afSBarry Smith PetscBLASInt one = 1, j, nz, lda = 0; 32680cd9d93SLois Curfman McInnes 3273a40ed3dSBarry Smith PetscFunctionBegin; 3289566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 3299566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(a->lda, &lda)); 330d0f46423SBarry Smith if (lda > A->rmap->n) { 3319566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &nz)); 33248a46eb9SPierre Jolivet for (j = 0; j < A->cmap->n; j++) PetscCallBLAS("BLASscal", BLASscal_(&nz, &alpha, v + j * lda, &one)); 333a5ce6ee0Svictorle } else { 3349566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n * A->cmap->n, &nz)); 335792fecdfSBarry Smith PetscCallBLAS("BLASscal", BLASscal_(&nz, &alpha, v, &one)); 336a5ce6ee0Svictorle } 33704cbc005SJose E. Roman PetscCall(PetscLogFlops(A->rmap->n * A->cmap->n)); 3389566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 3393a40ed3dSBarry Smith PetscFunctionReturn(0); 34080cd9d93SLois Curfman McInnes } 34180cd9d93SLois Curfman McInnes 342d71ae5a4SJacob Faibussowitsch PetscErrorCode MatShift_SeqDense(Mat A, PetscScalar alpha) 343d71ae5a4SJacob Faibussowitsch { 3442f605a99SJose E. Roman Mat_SeqDense *a = (Mat_SeqDense *)A->data; 3452f605a99SJose E. Roman PetscScalar *v; 3462f605a99SJose E. Roman PetscInt j, k; 3472f605a99SJose E. Roman 3482f605a99SJose E. Roman PetscFunctionBegin; 3492f605a99SJose E. Roman PetscCall(MatDenseGetArray(A, &v)); 3502f605a99SJose E. Roman k = PetscMin(A->rmap->n, A->cmap->n); 3512f605a99SJose E. Roman for (j = 0; j < k; j++) v[j + j * a->lda] += alpha; 3522f605a99SJose E. Roman PetscCall(PetscLogFlops(k)); 3532f605a99SJose E. Roman PetscCall(MatDenseRestoreArray(A, &v)); 3542f605a99SJose E. Roman PetscFunctionReturn(0); 3552f605a99SJose E. Roman } 3562f605a99SJose E. Roman 357d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatIsHermitian_SeqDense(Mat A, PetscReal rtol, PetscBool *fl) 358d71ae5a4SJacob Faibussowitsch { 3591cbb95d3SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 360ca15aa20SStefano Zampini PetscInt i, j, m = A->rmap->n, N = a->lda; 361ca15aa20SStefano Zampini const PetscScalar *v; 3621cbb95d3SBarry Smith 3631cbb95d3SBarry Smith PetscFunctionBegin; 3641cbb95d3SBarry Smith *fl = PETSC_FALSE; 365d0f46423SBarry Smith if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0); 3669566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 3671cbb95d3SBarry Smith for (i = 0; i < m; i++) { 368ca15aa20SStefano Zampini for (j = i; j < m; j++) { 369ad540459SPierre Jolivet if (PetscAbsScalar(v[i + j * N] - PetscConj(v[j + i * N])) > rtol) goto restore; 3701cbb95d3SBarry Smith } 371637a0070SStefano Zampini } 3721cbb95d3SBarry Smith *fl = PETSC_TRUE; 373637a0070SStefano Zampini restore: 3749566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 375637a0070SStefano Zampini PetscFunctionReturn(0); 376637a0070SStefano Zampini } 377637a0070SStefano Zampini 378d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatIsSymmetric_SeqDense(Mat A, PetscReal rtol, PetscBool *fl) 379d71ae5a4SJacob Faibussowitsch { 380637a0070SStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 381637a0070SStefano Zampini PetscInt i, j, m = A->rmap->n, N = a->lda; 382637a0070SStefano Zampini const PetscScalar *v; 383637a0070SStefano Zampini 384637a0070SStefano Zampini PetscFunctionBegin; 385637a0070SStefano Zampini *fl = PETSC_FALSE; 386637a0070SStefano Zampini if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0); 3879566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 388637a0070SStefano Zampini for (i = 0; i < m; i++) { 389637a0070SStefano Zampini for (j = i; j < m; j++) { 390ad540459SPierre Jolivet if (PetscAbsScalar(v[i + j * N] - v[j + i * N]) > rtol) goto restore; 391637a0070SStefano Zampini } 392637a0070SStefano Zampini } 393637a0070SStefano Zampini *fl = PETSC_TRUE; 394637a0070SStefano Zampini restore: 3959566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 3961cbb95d3SBarry Smith PetscFunctionReturn(0); 3971cbb95d3SBarry Smith } 3981cbb95d3SBarry Smith 399d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi, Mat A, MatDuplicateOption cpvalues) 400d71ae5a4SJacob Faibussowitsch { 401ca15aa20SStefano Zampini Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 40223fc5dcaSStefano Zampini PetscInt lda = (PetscInt)mat->lda, j, m, nlda = lda; 40375f6d85dSStefano Zampini PetscBool isdensecpu; 404b24902e0SBarry Smith 405b24902e0SBarry Smith PetscFunctionBegin; 4069566063dSJacob Faibussowitsch PetscCall(PetscLayoutReference(A->rmap, &newi->rmap)); 4079566063dSJacob Faibussowitsch PetscCall(PetscLayoutReference(A->cmap, &newi->cmap)); 40823fc5dcaSStefano Zampini if (cpvalues == MAT_SHARE_NONZERO_PATTERN) { /* propagate LDA */ 4099566063dSJacob Faibussowitsch PetscCall(MatDenseSetLDA(newi, lda)); 41023fc5dcaSStefano Zampini } 4119566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)newi, MATSEQDENSE, &isdensecpu)); 4129566063dSJacob Faibussowitsch if (isdensecpu) PetscCall(MatSeqDenseSetPreallocation(newi, NULL)); 413b24902e0SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 414ca15aa20SStefano Zampini const PetscScalar *av; 415ca15aa20SStefano Zampini PetscScalar *v; 416ca15aa20SStefano Zampini 4179566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 4189566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(newi, &v)); 4199566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(newi, &nlda)); 420d0f46423SBarry Smith m = A->rmap->n; 42123fc5dcaSStefano Zampini if (lda > m || nlda > m) { 42248a46eb9SPierre Jolivet for (j = 0; j < A->cmap->n; j++) PetscCall(PetscArraycpy(v + j * nlda, av + j * lda, m)); 423b24902e0SBarry Smith } else { 4249566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(v, av, A->rmap->n * A->cmap->n)); 425b24902e0SBarry Smith } 4269566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(newi, &v)); 4279566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 428b24902e0SBarry Smith } 429b24902e0SBarry Smith PetscFunctionReturn(0); 430b24902e0SBarry Smith } 431b24902e0SBarry Smith 432d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDuplicate_SeqDense(Mat A, MatDuplicateOption cpvalues, Mat *newmat) 433d71ae5a4SJacob Faibussowitsch { 4343a40ed3dSBarry Smith PetscFunctionBegin; 4359566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), newmat)); 4369566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*newmat, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n)); 4379566063dSJacob Faibussowitsch PetscCall(MatSetType(*newmat, ((PetscObject)A)->type_name)); 4389566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(*newmat, A, cpvalues)); 439b24902e0SBarry Smith PetscFunctionReturn(0); 440b24902e0SBarry Smith } 441b24902e0SBarry Smith 442d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_LU(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T) 443d71ae5a4SJacob Faibussowitsch { 444c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4454396437dSToby Isaac PetscBLASInt info; 44667e560aaSBarry Smith 4473a40ed3dSBarry Smith PetscFunctionBegin; 4489566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 449792fecdfSBarry Smith PetscCallBLAS("LAPACKgetrs", LAPACKgetrs_(T ? "T" : "N", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info)); 4509566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 45105fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "GETRS - Bad solve %d", (int)info); 4529566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m))); 4534396437dSToby Isaac PetscFunctionReturn(0); 4544396437dSToby Isaac } 4554396437dSToby Isaac 4564396437dSToby Isaac static PetscErrorCode MatConjugate_SeqDense(Mat); 4574396437dSToby Isaac 458d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_Cholesky(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T) 459d71ae5a4SJacob Faibussowitsch { 4604396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4614396437dSToby Isaac PetscBLASInt info; 4624396437dSToby Isaac 4634396437dSToby Isaac PetscFunctionBegin; 464b94d7dedSBarry Smith if (A->spd == PETSC_BOOL3_TRUE) { 4659566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A)); 4669566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 467792fecdfSBarry Smith PetscCallBLAS("LAPACKpotrs", LAPACKpotrs_("L", &m, &nrhs, mat->v, &mat->lda, x, &m, &info)); 4689566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 46905fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "POTRS Bad solve %d", (int)info); 4709566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A)); 471a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX) 472b94d7dedSBarry Smith } else if (A->hermitian == PETSC_BOOL3_TRUE) { 4739566063dSJacob Faibussowitsch if (T) PetscCall(MatConjugate_SeqDense(A)); 4749566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 475792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrs", LAPACKhetrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info)); 4769566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 47705fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "HETRS Bad solve %d", (int)info); 4789566063dSJacob Faibussowitsch if (T) PetscCall(MatConjugate_SeqDense(A)); 479a49dc2a2SStefano Zampini #endif 480a49dc2a2SStefano Zampini } else { /* symmetric case */ 4819566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 482792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrs", LAPACKsytrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info)); 4839566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 48405fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "SYTRS Bad solve %d", (int)info); 485a49dc2a2SStefano Zampini } 4869566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m))); 4874396437dSToby Isaac PetscFunctionReturn(0); 4884396437dSToby Isaac } 48985e2c93fSHong Zhang 490d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k) 491d71ae5a4SJacob Faibussowitsch { 4924396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4934396437dSToby Isaac PetscBLASInt info; 4944396437dSToby Isaac char trans; 4954396437dSToby Isaac 4964396437dSToby Isaac PetscFunctionBegin; 4974905a7bcSToby Isaac if (PetscDefined(USE_COMPLEX)) { 4984905a7bcSToby Isaac trans = 'C'; 4994905a7bcSToby Isaac } else { 5004905a7bcSToby Isaac trans = 'T'; 5014905a7bcSToby Isaac } 5029566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 50305fcb23eSStefano Zampini { /* lwork depends on the number of right-hand sides */ 50405fcb23eSStefano Zampini PetscBLASInt nlfwork, lfwork = -1; 50505fcb23eSStefano Zampini PetscScalar fwork; 50605fcb23eSStefano Zampini 507792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info)); 50805fcb23eSStefano Zampini nlfwork = (PetscBLASInt)PetscRealPart(fwork); 50905fcb23eSStefano Zampini if (nlfwork > mat->lfwork) { 51005fcb23eSStefano Zampini mat->lfwork = nlfwork; 51105fcb23eSStefano Zampini PetscCall(PetscFree(mat->fwork)); 51205fcb23eSStefano Zampini PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 51305fcb23eSStefano Zampini } 51405fcb23eSStefano Zampini } 515792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info)); 5169566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 51705fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %d", (int)info); 5189566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 519792fecdfSBarry Smith PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "N", "N", &mat->rank, &nrhs, mat->v, &mat->lda, x, &ldx, &info)); 5209566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 52105fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %d", (int)info); 5224905a7bcSToby Isaac for (PetscInt j = 0; j < nrhs; j++) { 523ad540459SPierre Jolivet for (PetscInt i = mat->rank; i < k; i++) x[j * ldx + i] = 0.; 5244905a7bcSToby Isaac } 5259566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank)))); 5264905a7bcSToby Isaac PetscFunctionReturn(0); 5274905a7bcSToby Isaac } 5284905a7bcSToby Isaac 529d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k) 530d71ae5a4SJacob Faibussowitsch { 5314396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 5324396437dSToby Isaac PetscBLASInt info; 5334396437dSToby Isaac 5344396437dSToby Isaac PetscFunctionBegin; 5354396437dSToby Isaac if (A->rmap->n == A->cmap->n && mat->rank == A->rmap->n) { 5369566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 537792fecdfSBarry Smith PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "T", "N", &m, &nrhs, mat->v, &mat->lda, x, &ldx, &info)); 5389566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 53905fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %d", (int)info); 5409566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A)); 54105fcb23eSStefano Zampini { /* lwork depends on the number of right-hand sides */ 54205fcb23eSStefano Zampini PetscBLASInt nlfwork, lfwork = -1; 54305fcb23eSStefano Zampini PetscScalar fwork; 54405fcb23eSStefano Zampini 545792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info)); 54605fcb23eSStefano Zampini nlfwork = (PetscBLASInt)PetscRealPart(fwork); 54705fcb23eSStefano Zampini if (nlfwork > mat->lfwork) { 54805fcb23eSStefano Zampini mat->lfwork = nlfwork; 54905fcb23eSStefano Zampini PetscCall(PetscFree(mat->fwork)); 55005fcb23eSStefano Zampini PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 55105fcb23eSStefano Zampini } 55205fcb23eSStefano Zampini } 5539566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 554792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info)); 5559566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 55605fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %d", (int)info); 5579566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A)); 5584396437dSToby Isaac } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "QR factored matrix cannot be used for transpose solve"); 5599566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank)))); 5604396437dSToby Isaac PetscFunctionReturn(0); 5614396437dSToby Isaac } 5624396437dSToby Isaac 563d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_SetUp(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k) 564d71ae5a4SJacob Faibussowitsch { 5654396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 5664905a7bcSToby Isaac PetscScalar *y; 5674905a7bcSToby Isaac PetscBLASInt m = 0, k = 0; 5684905a7bcSToby Isaac 5694905a7bcSToby Isaac PetscFunctionBegin; 5709566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 5719566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 5724905a7bcSToby Isaac if (k < m) { 5739566063dSJacob Faibussowitsch PetscCall(VecCopy(xx, mat->qrrhs)); 5749566063dSJacob Faibussowitsch PetscCall(VecGetArray(mat->qrrhs, &y)); 5754905a7bcSToby Isaac } else { 5769566063dSJacob Faibussowitsch PetscCall(VecCopy(xx, yy)); 5779566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &y)); 5784905a7bcSToby Isaac } 5794396437dSToby Isaac *_y = y; 5804396437dSToby Isaac *_k = k; 5814396437dSToby Isaac *_m = m; 5824396437dSToby Isaac PetscFunctionReturn(0); 5834396437dSToby Isaac } 5844396437dSToby Isaac 585d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_TearDown(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k) 586d71ae5a4SJacob Faibussowitsch { 5874396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 58842e9364cSSatish Balay PetscScalar *y = NULL; 5894396437dSToby Isaac PetscBLASInt m, k; 5904396437dSToby Isaac 5914396437dSToby Isaac PetscFunctionBegin; 5924396437dSToby Isaac y = *_y; 5934396437dSToby Isaac *_y = NULL; 5944396437dSToby Isaac k = *_k; 5954396437dSToby Isaac m = *_m; 5964905a7bcSToby Isaac if (k < m) { 5974905a7bcSToby Isaac PetscScalar *yv; 5989566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &yv)); 5999566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(yv, y, k)); 6009566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &yv)); 6019566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(mat->qrrhs, &y)); 6024905a7bcSToby Isaac } else { 6039566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &y)); 6044905a7bcSToby Isaac } 6054905a7bcSToby Isaac PetscFunctionReturn(0); 6064905a7bcSToby Isaac } 6074905a7bcSToby Isaac 608d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_LU(Mat A, Vec xx, Vec yy) 609d71ae5a4SJacob Faibussowitsch { 61042e9364cSSatish Balay PetscScalar *y = NULL; 61142e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 6124396437dSToby Isaac 6134396437dSToby Isaac PetscFunctionBegin; 6149566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6159566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_FALSE)); 6169566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6174396437dSToby Isaac PetscFunctionReturn(0); 6184396437dSToby Isaac } 6194396437dSToby Isaac 620d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_LU(Mat A, Vec xx, Vec yy) 621d71ae5a4SJacob Faibussowitsch { 62242e9364cSSatish Balay PetscScalar *y = NULL; 62342e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 6244396437dSToby Isaac 6254396437dSToby Isaac PetscFunctionBegin; 6269566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6279566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_TRUE)); 6289566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6294396437dSToby Isaac PetscFunctionReturn(0); 6304396437dSToby Isaac } 6314396437dSToby Isaac 632d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Cholesky(Mat A, Vec xx, Vec yy) 633d71ae5a4SJacob Faibussowitsch { 634e54beecaSStefano Zampini PetscScalar *y = NULL; 635e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 6364396437dSToby Isaac 6374396437dSToby Isaac PetscFunctionBegin; 6389566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6399566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_FALSE)); 6409566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6414396437dSToby Isaac PetscFunctionReturn(0); 6424396437dSToby Isaac } 6434396437dSToby Isaac 644d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_Cholesky(Mat A, Vec xx, Vec yy) 645d71ae5a4SJacob Faibussowitsch { 646e54beecaSStefano Zampini PetscScalar *y = NULL; 647e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 6484396437dSToby Isaac 6494396437dSToby Isaac PetscFunctionBegin; 6509566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6519566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_TRUE)); 6529566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6534396437dSToby Isaac PetscFunctionReturn(0); 6544396437dSToby Isaac } 6554396437dSToby Isaac 656d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_QR(Mat A, Vec xx, Vec yy) 657d71ae5a4SJacob Faibussowitsch { 658e54beecaSStefano Zampini PetscScalar *y = NULL; 659e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 6604396437dSToby Isaac 6614396437dSToby Isaac PetscFunctionBegin; 6629566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6639566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k)); 6649566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6654396437dSToby Isaac PetscFunctionReturn(0); 6664396437dSToby Isaac } 6674396437dSToby Isaac 668d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_QR(Mat A, Vec xx, Vec yy) 669d71ae5a4SJacob Faibussowitsch { 67042e9364cSSatish Balay PetscScalar *y = NULL; 67142e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 6724396437dSToby Isaac 6734396437dSToby Isaac PetscFunctionBegin; 6749566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6759566063dSJacob Faibussowitsch PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k)); 6769566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6774396437dSToby Isaac PetscFunctionReturn(0); 6784396437dSToby Isaac } 6794396437dSToby Isaac 680d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_SetUp(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k) 681d71ae5a4SJacob Faibussowitsch { 6824905a7bcSToby Isaac const PetscScalar *b; 6834396437dSToby Isaac PetscScalar *y; 684bf5a80bcSToby Isaac PetscInt n, _ldb, _ldx; 685bf5a80bcSToby Isaac PetscBLASInt nrhs = 0, m = 0, k = 0, ldb = 0, ldx = 0, ldy = 0; 6864905a7bcSToby Isaac 6874905a7bcSToby Isaac PetscFunctionBegin; 6889371c9d4SSatish Balay *_ldy = 0; 6899371c9d4SSatish Balay *_m = 0; 6909371c9d4SSatish Balay *_nrhs = 0; 6919371c9d4SSatish Balay *_k = 0; 6929371c9d4SSatish Balay *_y = NULL; 6939566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 6949566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 6959566063dSJacob Faibussowitsch PetscCall(MatGetSize(B, NULL, &n)); 6969566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(n, &nrhs)); 6979566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(B, &_ldb)); 6989566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldb, &ldb)); 6999566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(X, &_ldx)); 7009566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldx, &ldx)); 701bf5a80bcSToby Isaac if (ldx < m) { 7029566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &b)); 7039566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nrhs * m, &y)); 704bf5a80bcSToby Isaac if (ldb == m) { 7059566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(y, b, ldb * nrhs)); 7064905a7bcSToby Isaac } else { 70748a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * m], &b[j * ldb], m)); 7084905a7bcSToby Isaac } 709bf5a80bcSToby Isaac ldy = m; 7109566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &b)); 7114905a7bcSToby Isaac } else { 712bf5a80bcSToby Isaac if (ldb == ldx) { 7139566063dSJacob Faibussowitsch PetscCall(MatCopy(B, X, SAME_NONZERO_PATTERN)); 7149566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &y)); 7154905a7bcSToby Isaac } else { 7169566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &y)); 7179566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &b)); 71848a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * ldx], &b[j * ldb], m)); 7199566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &b)); 7204905a7bcSToby Isaac } 721bf5a80bcSToby Isaac ldy = ldx; 7224905a7bcSToby Isaac } 7234396437dSToby Isaac *_y = y; 724bf5a80bcSToby Isaac *_ldy = ldy; 7254396437dSToby Isaac *_k = k; 7264396437dSToby Isaac *_m = m; 7274396437dSToby Isaac *_nrhs = nrhs; 7284396437dSToby Isaac PetscFunctionReturn(0); 7294396437dSToby Isaac } 7304396437dSToby Isaac 731d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_TearDown(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k) 732d71ae5a4SJacob Faibussowitsch { 7334396437dSToby Isaac PetscScalar *y; 734bf5a80bcSToby Isaac PetscInt _ldx; 735bf5a80bcSToby Isaac PetscBLASInt k, ldy, nrhs, ldx = 0; 7364396437dSToby Isaac 7374396437dSToby Isaac PetscFunctionBegin; 7384396437dSToby Isaac y = *_y; 7394396437dSToby Isaac *_y = NULL; 7404396437dSToby Isaac k = *_k; 741bf5a80bcSToby Isaac ldy = *_ldy; 7424396437dSToby Isaac nrhs = *_nrhs; 7439566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(X, &_ldx)); 7449566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldx, &ldx)); 745bf5a80bcSToby Isaac if (ldx != ldy) { 7464905a7bcSToby Isaac PetscScalar *xv; 7479566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &xv)); 74848a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&xv[j * ldx], &y[j * ldy], k)); 7499566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(X, &xv)); 7509566063dSJacob Faibussowitsch PetscCall(PetscFree(y)); 7514905a7bcSToby Isaac } else { 7529566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(X, &y)); 7534905a7bcSToby Isaac } 75485e2c93fSHong Zhang PetscFunctionReturn(0); 75585e2c93fSHong Zhang } 75685e2c93fSHong Zhang 757d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_LU(Mat A, Mat B, Mat X) 758d71ae5a4SJacob Faibussowitsch { 7594396437dSToby Isaac PetscScalar *y; 760bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7614396437dSToby Isaac 7624396437dSToby Isaac PetscFunctionBegin; 7639566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7649566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_FALSE)); 7659566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7664396437dSToby Isaac PetscFunctionReturn(0); 7674396437dSToby Isaac } 7684396437dSToby Isaac 769d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_LU(Mat A, Mat B, Mat X) 770d71ae5a4SJacob Faibussowitsch { 7714396437dSToby Isaac PetscScalar *y; 772bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7734396437dSToby Isaac 7744396437dSToby Isaac PetscFunctionBegin; 7759566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7769566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_TRUE)); 7779566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7784396437dSToby Isaac PetscFunctionReturn(0); 7794396437dSToby Isaac } 7804396437dSToby Isaac 781d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_Cholesky(Mat A, Mat B, Mat X) 782d71ae5a4SJacob Faibussowitsch { 7834396437dSToby Isaac PetscScalar *y; 784bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7854396437dSToby Isaac 7864396437dSToby Isaac PetscFunctionBegin; 7879566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7889566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_FALSE)); 7899566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7904396437dSToby Isaac PetscFunctionReturn(0); 7914396437dSToby Isaac } 7924396437dSToby Isaac 793d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_Cholesky(Mat A, Mat B, Mat X) 794d71ae5a4SJacob Faibussowitsch { 7954396437dSToby Isaac PetscScalar *y; 796bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7974396437dSToby Isaac 7984396437dSToby Isaac PetscFunctionBegin; 7999566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 8009566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_TRUE)); 8019566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 8024396437dSToby Isaac PetscFunctionReturn(0); 8034396437dSToby Isaac } 8044396437dSToby Isaac 805d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_QR(Mat A, Mat B, Mat X) 806d71ae5a4SJacob Faibussowitsch { 8074396437dSToby Isaac PetscScalar *y; 808bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 8094396437dSToby Isaac 8104396437dSToby Isaac PetscFunctionBegin; 8119566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 8129566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k)); 8139566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 8144396437dSToby Isaac PetscFunctionReturn(0); 8154396437dSToby Isaac } 8164396437dSToby Isaac 817d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_QR(Mat A, Mat B, Mat X) 818d71ae5a4SJacob Faibussowitsch { 8194396437dSToby Isaac PetscScalar *y; 820bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 8214396437dSToby Isaac 8224396437dSToby Isaac PetscFunctionBegin; 8239566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 8249566063dSJacob Faibussowitsch PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k)); 8259566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 8264396437dSToby Isaac PetscFunctionReturn(0); 8274396437dSToby Isaac } 8284396437dSToby Isaac 829db4efbfdSBarry Smith /* ---------------------------------------------------------------*/ 830db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots, 831db4efbfdSBarry Smith rather than put it in the Mat->row slot.*/ 832d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLUFactor_SeqDense(Mat A, IS row, IS col, const MatFactorInfo *minfo) 833d71ae5a4SJacob Faibussowitsch { 834db4efbfdSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 835db4efbfdSBarry Smith PetscBLASInt n, m, info; 836db4efbfdSBarry Smith 837db4efbfdSBarry Smith PetscFunctionBegin; 8389566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 8399566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 8404dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); } 841db4efbfdSBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 8429566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 843792fecdfSBarry Smith PetscCallBLAS("LAPACKgetrf", LAPACKgetrf_(&m, &n, mat->v, &mat->lda, mat->pivots, &info)); 8449566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 8458e57ea43SSatish Balay 84605fcb23eSStefano Zampini PetscCheck(info >= 0, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to LU factorization %d", (int)info); 84705fcb23eSStefano Zampini PetscCheck(info <= 0, PETSC_COMM_SELF, PETSC_ERR_MAT_LU_ZRPVT, "Bad LU factorization %d", (int)info); 8488208b9aeSStefano Zampini 8494396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_LU; 8504396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_LU; 8514396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_LU; 8524396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_LU; 853d5f3da31SBarry Smith A->factortype = MAT_FACTOR_LU; 854db4efbfdSBarry Smith 8559566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 8569566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 857f6224b95SHong Zhang 8589566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((2.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3)); 859db4efbfdSBarry Smith PetscFunctionReturn(0); 860db4efbfdSBarry Smith } 861db4efbfdSBarry Smith 862d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) 863d71ae5a4SJacob Faibussowitsch { 8644396437dSToby Isaac MatFactorInfo info; 8654396437dSToby Isaac 8664396437dSToby Isaac PetscFunctionBegin; 8679566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 868dbbe0bcdSBarry Smith PetscUseTypeMethod(fact, lufactor, NULL, NULL, &info); 8694396437dSToby Isaac PetscFunctionReturn(0); 8704396437dSToby Isaac } 8714396437dSToby Isaac 872d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, IS col, const MatFactorInfo *info) 873d71ae5a4SJacob Faibussowitsch { 8744396437dSToby Isaac PetscFunctionBegin; 8754396437dSToby Isaac fact->preallocated = PETSC_TRUE; 8764396437dSToby Isaac fact->assembled = PETSC_TRUE; 8774396437dSToby Isaac fact->ops->lufactornumeric = MatLUFactorNumeric_SeqDense; 8784396437dSToby Isaac PetscFunctionReturn(0); 8794396437dSToby Isaac } 8804396437dSToby Isaac 881a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */ 882d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCholeskyFactor_SeqDense(Mat A, IS perm, const MatFactorInfo *factinfo) 883d71ae5a4SJacob Faibussowitsch { 884db4efbfdSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 885c5df96a5SBarry Smith PetscBLASInt info, n; 886db4efbfdSBarry Smith 887db4efbfdSBarry Smith PetscFunctionBegin; 8889566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 889db4efbfdSBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 890b94d7dedSBarry Smith if (A->spd == PETSC_BOOL3_TRUE) { 8919566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 892792fecdfSBarry Smith PetscCallBLAS("LAPACKpotrf", LAPACKpotrf_("L", &n, mat->v, &mat->lda, &info)); 8939566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 894a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX) 895b94d7dedSBarry Smith } else if (A->hermitian == PETSC_BOOL3_TRUE) { 8964dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); } 897a49dc2a2SStefano Zampini if (!mat->fwork) { 898a49dc2a2SStefano Zampini PetscScalar dummy; 899a49dc2a2SStefano Zampini 900a49dc2a2SStefano Zampini mat->lfwork = -1; 9019566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 902792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info)); 9039566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 904a49dc2a2SStefano Zampini mat->lfwork = (PetscInt)PetscRealPart(dummy); 9059566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 906a49dc2a2SStefano Zampini } 9079566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 908792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info)); 9099566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 910a49dc2a2SStefano Zampini #endif 911a49dc2a2SStefano Zampini } else { /* symmetric case */ 9124dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); } 913a49dc2a2SStefano Zampini if (!mat->fwork) { 914a49dc2a2SStefano Zampini PetscScalar dummy; 915a49dc2a2SStefano Zampini 916a49dc2a2SStefano Zampini mat->lfwork = -1; 9179566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 918792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info)); 9199566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 920a49dc2a2SStefano Zampini mat->lfwork = (PetscInt)PetscRealPart(dummy); 9219566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 922a49dc2a2SStefano Zampini } 9239566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 924792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info)); 9259566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 926a49dc2a2SStefano Zampini } 92728b400f6SJacob Faibussowitsch PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad factorization: zero pivot in row %" PetscInt_FMT, (PetscInt)info - 1); 9288208b9aeSStefano Zampini 9294396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_Cholesky; 9304396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_Cholesky; 9314396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_Cholesky; 9324396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_Cholesky; 933d5f3da31SBarry Smith A->factortype = MAT_FACTOR_CHOLESKY; 9342205254eSKarl Rupp 9359566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 9369566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 937f6224b95SHong Zhang 9389566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0)); 939db4efbfdSBarry Smith PetscFunctionReturn(0); 940db4efbfdSBarry Smith } 941db4efbfdSBarry Smith 942d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) 943d71ae5a4SJacob Faibussowitsch { 944db4efbfdSBarry Smith MatFactorInfo info; 945db4efbfdSBarry Smith 946db4efbfdSBarry Smith PetscFunctionBegin; 947db4efbfdSBarry Smith info.fill = 1.0; 9482205254eSKarl Rupp 9499566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 950dbbe0bcdSBarry Smith PetscUseTypeMethod(fact, choleskyfactor, NULL, &info); 951db4efbfdSBarry Smith PetscFunctionReturn(0); 952db4efbfdSBarry Smith } 953db4efbfdSBarry Smith 954d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info) 955d71ae5a4SJacob Faibussowitsch { 956db4efbfdSBarry Smith PetscFunctionBegin; 957c3ef05f6SHong Zhang fact->assembled = PETSC_TRUE; 9581bbcc794SSatish Balay fact->preallocated = PETSC_TRUE; 959719d5645SBarry Smith fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense; 960db4efbfdSBarry Smith PetscFunctionReturn(0); 961db4efbfdSBarry Smith } 962db4efbfdSBarry Smith 963d71ae5a4SJacob Faibussowitsch PetscErrorCode MatQRFactor_SeqDense(Mat A, IS col, const MatFactorInfo *minfo) 964d71ae5a4SJacob Faibussowitsch { 9654905a7bcSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 9664905a7bcSToby Isaac PetscBLASInt n, m, info, min, max; 9674905a7bcSToby Isaac 9684905a7bcSToby Isaac PetscFunctionBegin; 9699566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 9709566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 9714396437dSToby Isaac max = PetscMax(m, n); 9724396437dSToby Isaac min = PetscMin(m, n); 9734dfa11a4SJacob Faibussowitsch if (!mat->tau) { PetscCall(PetscMalloc1(min, &mat->tau)); } 9744dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(n, &mat->pivots)); } 97548a46eb9SPierre Jolivet if (!mat->qrrhs) PetscCall(MatCreateVecs(A, NULL, &(mat->qrrhs))); 9764905a7bcSToby Isaac if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 9774905a7bcSToby Isaac if (!mat->fwork) { 9784905a7bcSToby Isaac PetscScalar dummy; 9794905a7bcSToby Isaac 9804905a7bcSToby Isaac mat->lfwork = -1; 9819566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 982792fecdfSBarry Smith PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, &dummy, &mat->lfwork, &info)); 9839566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 9844905a7bcSToby Isaac mat->lfwork = (PetscInt)PetscRealPart(dummy); 9859566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 9864905a7bcSToby Isaac } 9879566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 988792fecdfSBarry Smith PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, mat->fwork, &mat->lfwork, &info)); 9899566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 99005fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to QR factorization %d", (int)info); 9914905a7bcSToby 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 9924905a7bcSToby Isaac mat->rank = min; 9934905a7bcSToby Isaac 9944396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_QR; 9954396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_QR; 9964905a7bcSToby Isaac A->factortype = MAT_FACTOR_QR; 9974905a7bcSToby Isaac if (m == n) { 9984396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_QR; 9994396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_QR; 10004905a7bcSToby Isaac } 10014905a7bcSToby Isaac 10029566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 10039566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 10044905a7bcSToby Isaac 10059566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * min * min * (max - min / 3.0))); 10064905a7bcSToby Isaac PetscFunctionReturn(0); 10074905a7bcSToby Isaac } 10084905a7bcSToby Isaac 1009d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatQRFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) 1010d71ae5a4SJacob Faibussowitsch { 10114905a7bcSToby Isaac MatFactorInfo info; 10124905a7bcSToby Isaac 10134905a7bcSToby Isaac PetscFunctionBegin; 10144905a7bcSToby Isaac info.fill = 1.0; 10154905a7bcSToby Isaac 10169566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 1017cac4c232SBarry Smith PetscUseMethod(fact, "MatQRFactor_C", (Mat, IS, const MatFactorInfo *), (fact, NULL, &info)); 10184905a7bcSToby Isaac PetscFunctionReturn(0); 10194905a7bcSToby Isaac } 10204905a7bcSToby Isaac 1021d71ae5a4SJacob Faibussowitsch PetscErrorCode MatQRFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info) 1022d71ae5a4SJacob Faibussowitsch { 10234905a7bcSToby Isaac PetscFunctionBegin; 10244905a7bcSToby Isaac fact->assembled = PETSC_TRUE; 10254905a7bcSToby Isaac fact->preallocated = PETSC_TRUE; 10269566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)fact, "MatQRFactorNumeric_C", MatQRFactorNumeric_SeqDense)); 10274905a7bcSToby Isaac PetscFunctionReturn(0); 10284905a7bcSToby Isaac } 10294905a7bcSToby Isaac 1030ca15aa20SStefano Zampini /* uses LAPACK */ 1031d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A, MatFactorType ftype, Mat *fact) 1032d71ae5a4SJacob Faibussowitsch { 1033db4efbfdSBarry Smith PetscFunctionBegin; 10349566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), fact)); 10359566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*fact, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n)); 10369566063dSJacob Faibussowitsch PetscCall(MatSetType(*fact, MATDENSE)); 103766e17bc3SBarry Smith (*fact)->trivialsymbolic = PETSC_TRUE; 10382a350339SBarry Smith if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU) { 1039db4efbfdSBarry Smith (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense; 10402a350339SBarry Smith (*fact)->ops->ilufactorsymbolic = MatLUFactorSymbolic_SeqDense; 1041bf5a80bcSToby Isaac } else if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) { 1042db4efbfdSBarry Smith (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense; 1043bf5a80bcSToby Isaac } else if (ftype == MAT_FACTOR_QR) { 10449566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)(*fact), "MatQRFactorSymbolic_C", MatQRFactorSymbolic_SeqDense)); 1045db4efbfdSBarry Smith } 1046d5f3da31SBarry Smith (*fact)->factortype = ftype; 104700c67f3bSHong Zhang 10489566063dSJacob Faibussowitsch PetscCall(PetscFree((*fact)->solvertype)); 10499566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &(*fact)->solvertype)); 10509566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_LU])); 10519566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ILU])); 10529566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_CHOLESKY])); 10539566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ICC])); 1054db4efbfdSBarry Smith PetscFunctionReturn(0); 1055db4efbfdSBarry Smith } 1056db4efbfdSBarry Smith 1057289bc588SBarry Smith /* ------------------------------------------------------------------*/ 1058d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSOR_SeqDense(Mat A, Vec bb, PetscReal omega, MatSORType flag, PetscReal shift, PetscInt its, PetscInt lits, Vec xx) 1059d71ae5a4SJacob Faibussowitsch { 1060c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1061d9ca1df4SBarry Smith PetscScalar *x, *v = mat->v, zero = 0.0, xt; 1062d9ca1df4SBarry Smith const PetscScalar *b; 1063d0f46423SBarry Smith PetscInt m = A->rmap->n, i; 106423fff9afSBarry Smith PetscBLASInt o = 1, bm = 0; 1065289bc588SBarry Smith 10663a40ed3dSBarry Smith PetscFunctionBegin; 106747d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 106808401ef6SPierre Jolivet PetscCheck(A->offloadmask != PETSC_OFFLOAD_GPU, PETSC_COMM_SELF, PETSC_ERR_SUP, "Not implemented"); 1069ca15aa20SStefano Zampini #endif 1070422a814eSBarry Smith if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */ 10719566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(m, &bm)); 1072289bc588SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 10733bffc371SBarry Smith /* this is a hack fix, should have another version without the second BLASdotu */ 10749566063dSJacob Faibussowitsch PetscCall(VecSet(xx, zero)); 1075289bc588SBarry Smith } 10769566063dSJacob Faibussowitsch PetscCall(VecGetArray(xx, &x)); 10779566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(bb, &b)); 1078b965ef7fSBarry Smith its = its * lits; 107908401ef6SPierre 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); 1080289bc588SBarry Smith while (its--) { 1081fccaa45eSBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 1082289bc588SBarry Smith for (i = 0; i < m; i++) { 1083792fecdfSBarry Smith PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o)); 108455a1b374SBarry Smith x[i] = (1. - omega) * x[i] + omega * (xt + v[i + i * m] * x[i]) / (v[i + i * m] + shift); 1085289bc588SBarry Smith } 1086289bc588SBarry Smith } 1087fccaa45eSBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 1088289bc588SBarry Smith for (i = m - 1; i >= 0; i--) { 1089792fecdfSBarry Smith PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o)); 109055a1b374SBarry Smith x[i] = (1. - omega) * x[i] + omega * (xt + v[i + i * m] * x[i]) / (v[i + i * m] + shift); 1091289bc588SBarry Smith } 1092289bc588SBarry Smith } 1093289bc588SBarry Smith } 10949566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(bb, &b)); 10959566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(xx, &x)); 10963a40ed3dSBarry Smith PetscFunctionReturn(0); 1097289bc588SBarry Smith } 1098289bc588SBarry Smith 1099289bc588SBarry Smith /* -----------------------------------------------------------------*/ 1100d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultTranspose_SeqDense(Mat A, Vec xx, Vec yy) 1101d71ae5a4SJacob Faibussowitsch { 1102c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1103d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 1104d9ca1df4SBarry Smith PetscScalar *y; 11050805154bSBarry Smith PetscBLASInt m, n, _One = 1; 1106ea709b57SSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 11073a40ed3dSBarry Smith 11083a40ed3dSBarry Smith PetscFunctionBegin; 11099566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 11109566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 11119566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 11129566063dSJacob Faibussowitsch PetscCall(VecGetArrayWrite(yy, &y)); 11135ac36cfcSBarry Smith if (!A->rmap->n || !A->cmap->n) { 11145ac36cfcSBarry Smith PetscBLASInt i; 11155ac36cfcSBarry Smith for (i = 0; i < n; i++) y[i] = 0.0; 11165ac36cfcSBarry Smith } else { 1117792fecdfSBarry Smith PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v, &mat->lda, x, &_One, &_DZero, y, &_One)); 11189566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n - A->cmap->n)); 11195ac36cfcSBarry Smith } 11209566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 11219566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayWrite(yy, &y)); 11223a40ed3dSBarry Smith PetscFunctionReturn(0); 1123289bc588SBarry Smith } 1124800995b7SMatthew Knepley 1125d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMult_SeqDense(Mat A, Vec xx, Vec yy) 1126d71ae5a4SJacob Faibussowitsch { 1127c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1128d9ca1df4SBarry Smith PetscScalar *y, _DOne = 1.0, _DZero = 0.0; 11290805154bSBarry Smith PetscBLASInt m, n, _One = 1; 1130d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 11313a40ed3dSBarry Smith 11323a40ed3dSBarry Smith PetscFunctionBegin; 11339566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 11349566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 11359566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 11369566063dSJacob Faibussowitsch PetscCall(VecGetArrayWrite(yy, &y)); 11375ac36cfcSBarry Smith if (!A->rmap->n || !A->cmap->n) { 11385ac36cfcSBarry Smith PetscBLASInt i; 11395ac36cfcSBarry Smith for (i = 0; i < m; i++) y[i] = 0.0; 11405ac36cfcSBarry Smith } else { 1141792fecdfSBarry Smith PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DZero, y, &_One)); 11429566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n - A->rmap->n)); 11435ac36cfcSBarry Smith } 11449566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 11459566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayWrite(yy, &y)); 11463a40ed3dSBarry Smith PetscFunctionReturn(0); 1147289bc588SBarry Smith } 11486ee01492SSatish Balay 1149d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) 1150d71ae5a4SJacob Faibussowitsch { 1151c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1152d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 1153d9ca1df4SBarry Smith PetscScalar *y, _DOne = 1.0; 11540805154bSBarry Smith PetscBLASInt m, n, _One = 1; 11553a40ed3dSBarry Smith 11563a40ed3dSBarry Smith PetscFunctionBegin; 11579566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 11589566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 11599566063dSJacob Faibussowitsch PetscCall(VecCopy(zz, yy)); 1160d0f46423SBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 11619566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 11629566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &y)); 1163792fecdfSBarry Smith PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DOne, y, &_One)); 11649566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 11659566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &y)); 11669566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n)); 11673a40ed3dSBarry Smith PetscFunctionReturn(0); 1168289bc588SBarry Smith } 11696ee01492SSatish Balay 1170d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) 1171d71ae5a4SJacob Faibussowitsch { 1172c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1173d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 1174d9ca1df4SBarry Smith PetscScalar *y; 11750805154bSBarry Smith PetscBLASInt m, n, _One = 1; 117687828ca2SBarry Smith PetscScalar _DOne = 1.0; 11773a40ed3dSBarry Smith 11783a40ed3dSBarry Smith PetscFunctionBegin; 11799566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 11809566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 11819566063dSJacob Faibussowitsch PetscCall(VecCopy(zz, yy)); 1182d0f46423SBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 11839566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 11849566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &y)); 1185792fecdfSBarry Smith PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DOne, y, &_One)); 11869566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 11879566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &y)); 11889566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n)); 11893a40ed3dSBarry Smith PetscFunctionReturn(0); 1190289bc588SBarry Smith } 1191289bc588SBarry Smith 1192289bc588SBarry Smith /* -----------------------------------------------------------------*/ 1193d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals) 1194d71ae5a4SJacob Faibussowitsch { 1195c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 119613f74950SBarry Smith PetscInt i; 119767e560aaSBarry Smith 11983a40ed3dSBarry Smith PetscFunctionBegin; 1199d0f46423SBarry Smith *ncols = A->cmap->n; 1200289bc588SBarry Smith if (cols) { 12019566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->cmap->n, cols)); 1202d0f46423SBarry Smith for (i = 0; i < A->cmap->n; i++) (*cols)[i] = i; 1203289bc588SBarry Smith } 1204289bc588SBarry Smith if (vals) { 1205ca15aa20SStefano Zampini const PetscScalar *v; 1206ca15aa20SStefano Zampini 12079566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 12089566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->cmap->n, vals)); 1209ca15aa20SStefano Zampini v += row; 12109371c9d4SSatish Balay for (i = 0; i < A->cmap->n; i++) { 12119371c9d4SSatish Balay (*vals)[i] = *v; 12129371c9d4SSatish Balay v += mat->lda; 12139371c9d4SSatish Balay } 12149566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 1215289bc588SBarry Smith } 12163a40ed3dSBarry Smith PetscFunctionReturn(0); 1217289bc588SBarry Smith } 12186ee01492SSatish Balay 1219d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRestoreRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals) 1220d71ae5a4SJacob Faibussowitsch { 1221606d414cSSatish Balay PetscFunctionBegin; 1222cb4a9cd9SHong Zhang if (ncols) *ncols = 0; 12239566063dSJacob Faibussowitsch if (cols) PetscCall(PetscFree(*cols)); 12249566063dSJacob Faibussowitsch if (vals) PetscCall(PetscFree(*vals)); 12253a40ed3dSBarry Smith PetscFunctionReturn(0); 1226289bc588SBarry Smith } 1227289bc588SBarry Smith /* ----------------------------------------------------------------*/ 1228d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], const PetscScalar v[], InsertMode addv) 1229d71ae5a4SJacob Faibussowitsch { 1230c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1231ca15aa20SStefano Zampini PetscScalar *av; 123213f74950SBarry Smith PetscInt i, j, idx = 0; 123347d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1234c70f7ee4SJunchao Zhang PetscOffloadMask oldf; 1235ca15aa20SStefano Zampini #endif 1236d6dfbf8fSBarry Smith 12373a40ed3dSBarry Smith PetscFunctionBegin; 12389566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &av)); 1239289bc588SBarry Smith if (!mat->roworiented) { 1240dbb450caSBarry Smith if (addv == INSERT_VALUES) { 1241289bc588SBarry Smith for (j = 0; j < n; j++) { 12429371c9d4SSatish Balay if (indexn[j] < 0) { 12439371c9d4SSatish Balay idx += m; 12449371c9d4SSatish Balay continue; 12459371c9d4SSatish Balay } 12466bdcaf15SBarry 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); 1247289bc588SBarry Smith for (i = 0; i < m; i++) { 12489371c9d4SSatish Balay if (indexm[i] < 0) { 12499371c9d4SSatish Balay idx++; 12509371c9d4SSatish Balay continue; 12519371c9d4SSatish Balay } 12526bdcaf15SBarry Smith PetscCheck(indexm[i] < A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Row too large: row %" PetscInt_FMT " max %" PetscInt_FMT, indexm[i], A->rmap->n - 1); 1253ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] = v[idx++]; 1254289bc588SBarry Smith } 1255289bc588SBarry Smith } 12563a40ed3dSBarry Smith } else { 1257289bc588SBarry Smith for (j = 0; j < n; j++) { 12589371c9d4SSatish Balay if (indexn[j] < 0) { 12599371c9d4SSatish Balay idx += m; 12609371c9d4SSatish Balay continue; 12619371c9d4SSatish Balay } 12626bdcaf15SBarry 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); 1263289bc588SBarry Smith for (i = 0; i < m; i++) { 12649371c9d4SSatish Balay if (indexm[i] < 0) { 12659371c9d4SSatish Balay idx++; 12669371c9d4SSatish Balay continue; 12679371c9d4SSatish Balay } 12686bdcaf15SBarry 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); 1269ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] += v[idx++]; 1270289bc588SBarry Smith } 1271289bc588SBarry Smith } 1272289bc588SBarry Smith } 12733a40ed3dSBarry Smith } else { 1274dbb450caSBarry Smith if (addv == INSERT_VALUES) { 1275e8d4e0b9SBarry Smith for (i = 0; i < m; i++) { 12769371c9d4SSatish Balay if (indexm[i] < 0) { 12779371c9d4SSatish Balay idx += n; 12789371c9d4SSatish Balay continue; 12799371c9d4SSatish Balay } 12806bdcaf15SBarry 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); 1281e8d4e0b9SBarry Smith for (j = 0; j < n; j++) { 12829371c9d4SSatish Balay if (indexn[j] < 0) { 12839371c9d4SSatish Balay idx++; 12849371c9d4SSatish Balay continue; 12859371c9d4SSatish Balay } 12866bdcaf15SBarry 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); 1287ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] = v[idx++]; 1288e8d4e0b9SBarry Smith } 1289e8d4e0b9SBarry Smith } 12903a40ed3dSBarry Smith } else { 1291289bc588SBarry Smith for (i = 0; i < m; i++) { 12929371c9d4SSatish Balay if (indexm[i] < 0) { 12939371c9d4SSatish Balay idx += n; 12949371c9d4SSatish Balay continue; 12959371c9d4SSatish Balay } 12966bdcaf15SBarry 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); 1297289bc588SBarry Smith for (j = 0; j < n; j++) { 12989371c9d4SSatish Balay if (indexn[j] < 0) { 12999371c9d4SSatish Balay idx++; 13009371c9d4SSatish Balay continue; 13019371c9d4SSatish Balay } 13026bdcaf15SBarry 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); 1303ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] += v[idx++]; 1304289bc588SBarry Smith } 1305289bc588SBarry Smith } 1306289bc588SBarry Smith } 1307e8d4e0b9SBarry Smith } 1308ca15aa20SStefano Zampini /* hack to prevent unneeded copy to the GPU while returning the array */ 130947d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1310c70f7ee4SJunchao Zhang oldf = A->offloadmask; 1311c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_GPU; 1312ca15aa20SStefano Zampini #endif 13139566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &av)); 131447d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1315c70f7ee4SJunchao Zhang A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU); 1316ca15aa20SStefano Zampini #endif 13173a40ed3dSBarry Smith PetscFunctionReturn(0); 1318289bc588SBarry Smith } 1319e8d4e0b9SBarry Smith 1320d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], PetscScalar v[]) 1321d71ae5a4SJacob Faibussowitsch { 1322ae80bb75SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1323ca15aa20SStefano Zampini const PetscScalar *vv; 132413f74950SBarry Smith PetscInt i, j; 1325ae80bb75SLois Curfman McInnes 13263a40ed3dSBarry Smith PetscFunctionBegin; 13279566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &vv)); 1328ae80bb75SLois Curfman McInnes /* row-oriented output */ 1329ae80bb75SLois Curfman McInnes for (i = 0; i < m; i++) { 13309371c9d4SSatish Balay if (indexm[i] < 0) { 13319371c9d4SSatish Balay v += n; 13329371c9d4SSatish Balay continue; 13339371c9d4SSatish Balay } 133408401ef6SPierre 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); 1335ae80bb75SLois Curfman McInnes for (j = 0; j < n; j++) { 13369371c9d4SSatish Balay if (indexn[j] < 0) { 13379371c9d4SSatish Balay v++; 13389371c9d4SSatish Balay continue; 13399371c9d4SSatish Balay } 134008401ef6SPierre 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); 1341ca15aa20SStefano Zampini *v++ = vv[indexn[j] * mat->lda + indexm[i]]; 1342ae80bb75SLois Curfman McInnes } 1343ae80bb75SLois Curfman McInnes } 13449566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &vv)); 13453a40ed3dSBarry Smith PetscFunctionReturn(0); 1346ae80bb75SLois Curfman McInnes } 1347ae80bb75SLois Curfman McInnes 1348289bc588SBarry Smith /* -----------------------------------------------------------------*/ 1349289bc588SBarry Smith 1350d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_Dense_Binary(Mat mat, PetscViewer viewer) 1351d71ae5a4SJacob Faibussowitsch { 13528491ab44SLisandro Dalcin PetscBool skipHeader; 13538491ab44SLisandro Dalcin PetscViewerFormat format; 13548491ab44SLisandro Dalcin PetscInt header[4], M, N, m, lda, i, j, k; 13558491ab44SLisandro Dalcin const PetscScalar *v; 13568491ab44SLisandro Dalcin PetscScalar *vwork; 1357aabbc4fbSShri Abhyankar 1358aabbc4fbSShri Abhyankar PetscFunctionBegin; 13599566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 13609566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader)); 13619566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 13628491ab44SLisandro Dalcin if (skipHeader) format = PETSC_VIEWER_NATIVE; 1363aabbc4fbSShri Abhyankar 13649566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &M, &N)); 13658491ab44SLisandro Dalcin 13668491ab44SLisandro Dalcin /* write matrix header */ 13679371c9d4SSatish Balay header[0] = MAT_FILE_CLASSID; 13689371c9d4SSatish Balay header[1] = M; 13699371c9d4SSatish Balay header[2] = N; 13708491ab44SLisandro Dalcin header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M * N; 13719566063dSJacob Faibussowitsch if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer, header, 4, PETSC_INT)); 13728491ab44SLisandro Dalcin 13739566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mat, &m, NULL)); 13748491ab44SLisandro Dalcin if (format != PETSC_VIEWER_NATIVE) { 13758491ab44SLisandro Dalcin PetscInt nnz = m * N, *iwork; 13768491ab44SLisandro Dalcin /* store row lengths for each row */ 13779566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz, &iwork)); 13788491ab44SLisandro Dalcin for (i = 0; i < m; i++) iwork[i] = N; 13799566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 13808491ab44SLisandro Dalcin /* store column indices (zero start index) */ 13818491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 13829371c9d4SSatish Balay for (j = 0; j < N; j++, k++) iwork[k] = j; 13839566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 13849566063dSJacob Faibussowitsch PetscCall(PetscFree(iwork)); 13858491ab44SLisandro Dalcin } 13868491ab44SLisandro Dalcin /* store matrix values as a dense matrix in row major order */ 13879566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m * N, &vwork)); 13889566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(mat, &v)); 13899566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(mat, &lda)); 13908491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 13919371c9d4SSatish Balay for (j = 0; j < N; j++, k++) vwork[k] = v[i + lda * j]; 13929566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(mat, &v)); 13939566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, vwork, m * N, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 13949566063dSJacob Faibussowitsch PetscCall(PetscFree(vwork)); 13958491ab44SLisandro Dalcin PetscFunctionReturn(0); 13968491ab44SLisandro Dalcin } 13978491ab44SLisandro Dalcin 1398d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLoad_Dense_Binary(Mat mat, PetscViewer viewer) 1399d71ae5a4SJacob Faibussowitsch { 14008491ab44SLisandro Dalcin PetscBool skipHeader; 14018491ab44SLisandro Dalcin PetscInt header[4], M, N, m, nz, lda, i, j, k; 14028491ab44SLisandro Dalcin PetscInt rows, cols; 14038491ab44SLisandro Dalcin PetscScalar *v, *vwork; 14048491ab44SLisandro Dalcin 14058491ab44SLisandro Dalcin PetscFunctionBegin; 14069566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 14079566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader)); 14088491ab44SLisandro Dalcin 14098491ab44SLisandro Dalcin if (!skipHeader) { 14109566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, header, 4, NULL, PETSC_INT)); 141108401ef6SPierre Jolivet PetscCheck(header[0] == MAT_FILE_CLASSID, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Not a matrix object in file"); 14129371c9d4SSatish Balay M = header[1]; 14139371c9d4SSatish Balay N = header[2]; 141408401ef6SPierre Jolivet PetscCheck(M >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix row size (%" PetscInt_FMT ") in file is negative", M); 141508401ef6SPierre Jolivet PetscCheck(N >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix column size (%" PetscInt_FMT ") in file is negative", N); 14168491ab44SLisandro Dalcin nz = header[3]; 1417aed4548fSBarry Smith PetscCheck(nz == MATRIX_BINARY_FORMAT_DENSE || nz >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Unknown matrix format %" PetscInt_FMT " in file", nz); 1418aabbc4fbSShri Abhyankar } else { 14199566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &M, &N)); 1420aed4548fSBarry 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"); 14218491ab44SLisandro Dalcin nz = MATRIX_BINARY_FORMAT_DENSE; 1422e6324fbbSBarry Smith } 1423aabbc4fbSShri Abhyankar 14248491ab44SLisandro Dalcin /* setup global sizes if not set */ 14258491ab44SLisandro Dalcin if (mat->rmap->N < 0) mat->rmap->N = M; 14268491ab44SLisandro Dalcin if (mat->cmap->N < 0) mat->cmap->N = N; 14279566063dSJacob Faibussowitsch PetscCall(MatSetUp(mat)); 14288491ab44SLisandro Dalcin /* check if global sizes are correct */ 14299566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &rows, &cols)); 1430aed4548fSBarry 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); 1431aabbc4fbSShri Abhyankar 14329566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, NULL, &N)); 14339566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mat, &m, NULL)); 14349566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(mat, &v)); 14359566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(mat, &lda)); 14368491ab44SLisandro Dalcin if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense format */ 14378491ab44SLisandro Dalcin PetscInt nnz = m * N; 14388491ab44SLisandro Dalcin /* read in matrix values */ 14399566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz, &vwork)); 14409566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 14418491ab44SLisandro Dalcin /* store values in column major order */ 14428491ab44SLisandro Dalcin for (j = 0; j < N; j++) 14439371c9d4SSatish Balay for (i = 0; i < m; i++) v[i + lda * j] = vwork[i * N + j]; 14449566063dSJacob Faibussowitsch PetscCall(PetscFree(vwork)); 14458491ab44SLisandro Dalcin } else { /* matrix in file is sparse format */ 14468491ab44SLisandro Dalcin PetscInt nnz = 0, *rlens, *icols; 14478491ab44SLisandro Dalcin /* read in row lengths */ 14489566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m, &rlens)); 14499566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, rlens, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 14508491ab44SLisandro Dalcin for (i = 0; i < m; i++) nnz += rlens[i]; 14518491ab44SLisandro Dalcin /* read in column indices and values */ 14529566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(nnz, &icols, nnz, &vwork)); 14539566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, icols, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 14549566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 14558491ab44SLisandro Dalcin /* store values in column major order */ 14568491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 14579371c9d4SSatish Balay for (j = 0; j < rlens[i]; j++, k++) v[i + lda * icols[k]] = vwork[k]; 14589566063dSJacob Faibussowitsch PetscCall(PetscFree(rlens)); 14599566063dSJacob Faibussowitsch PetscCall(PetscFree2(icols, vwork)); 1460aabbc4fbSShri Abhyankar } 14619566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(mat, &v)); 14629566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY)); 14639566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY)); 1464aabbc4fbSShri Abhyankar PetscFunctionReturn(0); 1465aabbc4fbSShri Abhyankar } 1466aabbc4fbSShri Abhyankar 1467d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer) 1468d71ae5a4SJacob Faibussowitsch { 1469eb91f321SVaclav Hapla PetscBool isbinary, ishdf5; 1470eb91f321SVaclav Hapla 1471eb91f321SVaclav Hapla PetscFunctionBegin; 1472eb91f321SVaclav Hapla PetscValidHeaderSpecific(newMat, MAT_CLASSID, 1); 1473eb91f321SVaclav Hapla PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1474eb91f321SVaclav Hapla /* force binary viewer to load .info file if it has not yet done so */ 14759566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 14769566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 14779566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5)); 1478eb91f321SVaclav Hapla if (isbinary) { 14799566063dSJacob Faibussowitsch PetscCall(MatLoad_Dense_Binary(newMat, viewer)); 1480eb91f321SVaclav Hapla } else if (ishdf5) { 1481eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5) 14829566063dSJacob Faibussowitsch PetscCall(MatLoad_Dense_HDF5(newMat, viewer)); 1483eb91f321SVaclav Hapla #else 1484eb91f321SVaclav Hapla SETERRQ(PetscObjectComm((PetscObject)newMat), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1485eb91f321SVaclav Hapla #endif 1486eb91f321SVaclav Hapla } else { 148798921bdaSJacob 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); 1488eb91f321SVaclav Hapla } 1489eb91f321SVaclav Hapla PetscFunctionReturn(0); 1490eb91f321SVaclav Hapla } 1491eb91f321SVaclav Hapla 1492d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_ASCII(Mat A, PetscViewer viewer) 1493d71ae5a4SJacob Faibussowitsch { 1494932b0c3eSLois Curfman McInnes Mat_SeqDense *a = (Mat_SeqDense *)A->data; 149513f74950SBarry Smith PetscInt i, j; 14962dcb1b2aSMatthew Knepley const char *name; 1497ca15aa20SStefano Zampini PetscScalar *v, *av; 1498f3ef73ceSBarry Smith PetscViewerFormat format; 14995f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX) 1500ace3abfcSBarry Smith PetscBool allreal = PETSC_TRUE; 15015f481a85SSatish Balay #endif 1502932b0c3eSLois Curfman McInnes 15033a40ed3dSBarry Smith PetscFunctionBegin; 15049566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&av)); 15059566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 1506456192e2SBarry Smith if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 15073a40ed3dSBarry Smith PetscFunctionReturn(0); /* do nothing for now */ 1508fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 15099566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE)); 1510d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 1511ca15aa20SStefano Zampini v = av + i; 15129566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "row %" PetscInt_FMT ":", i)); 1513d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1514aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 1515329f5518SBarry Smith if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) { 15169566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g + %g i) ", j, (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v))); 1517329f5518SBarry Smith } else if (PetscRealPart(*v)) { 15189566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)PetscRealPart(*v))); 15196831982aSBarry Smith } 152080cd9d93SLois Curfman McInnes #else 152148a46eb9SPierre Jolivet if (*v) PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)*v)); 152280cd9d93SLois Curfman McInnes #endif 15231b807ce4Svictorle v += a->lda; 152480cd9d93SLois Curfman McInnes } 15259566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 152680cd9d93SLois Curfman McInnes } 15279566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE)); 15283a40ed3dSBarry Smith } else { 15299566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE)); 1530aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 153147989497SBarry Smith /* determine if matrix has all real values */ 1532bcd8d3a4SJose E. Roman for (j = 0; j < A->cmap->n; j++) { 1533bcd8d3a4SJose E. Roman v = av + j * a->lda; 1534bcd8d3a4SJose E. Roman for (i = 0; i < A->rmap->n; i++) { 15359371c9d4SSatish Balay if (PetscImaginaryPart(v[i])) { 15369371c9d4SSatish Balay allreal = PETSC_FALSE; 15379371c9d4SSatish Balay break; 15389371c9d4SSatish Balay } 153947989497SBarry Smith } 1540bcd8d3a4SJose E. Roman } 154147989497SBarry Smith #endif 1542fb9695e5SSatish Balay if (format == PETSC_VIEWER_ASCII_MATLAB) { 15439566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)A, &name)); 15449566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%% Size = %" PetscInt_FMT " %" PetscInt_FMT " \n", A->rmap->n, A->cmap->n)); 15459566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%s = zeros(%" PetscInt_FMT ",%" PetscInt_FMT ");\n", name, A->rmap->n, A->cmap->n)); 15469566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%s = [\n", name)); 1547ffac6cdbSBarry Smith } 1548ffac6cdbSBarry Smith 1549d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 1550ca15aa20SStefano Zampini v = av + i; 1551d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1552aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 155347989497SBarry Smith if (allreal) { 15549566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)PetscRealPart(*v))); 155547989497SBarry Smith } else { 15569566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e + %18.16ei ", (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v))); 155747989497SBarry Smith } 1558289bc588SBarry Smith #else 15599566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)*v)); 1560289bc588SBarry Smith #endif 15611b807ce4Svictorle v += a->lda; 1562289bc588SBarry Smith } 15639566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 1564289bc588SBarry Smith } 156548a46eb9SPierre Jolivet if (format == PETSC_VIEWER_ASCII_MATLAB) PetscCall(PetscViewerASCIIPrintf(viewer, "];\n")); 15669566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE)); 1567da3a660dSBarry Smith } 15689566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&av)); 15699566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer)); 15703a40ed3dSBarry Smith PetscFunctionReturn(0); 1571289bc588SBarry Smith } 1572289bc588SBarry Smith 15739804daf3SBarry Smith #include <petscdraw.h> 1574d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw, void *Aa) 1575d71ae5a4SJacob Faibussowitsch { 1576f1af5d2fSBarry Smith Mat A = (Mat)Aa; 1577383922c3SLisandro Dalcin PetscInt m = A->rmap->n, n = A->cmap->n, i, j; 1578383922c3SLisandro Dalcin int color = PETSC_DRAW_WHITE; 1579ca15aa20SStefano Zampini const PetscScalar *v; 1580b0a32e0cSBarry Smith PetscViewer viewer; 1581b05fc000SLisandro Dalcin PetscReal xl, yl, xr, yr, x_l, x_r, y_l, y_r; 1582f3ef73ceSBarry Smith PetscViewerFormat format; 1583f1af5d2fSBarry Smith 1584f1af5d2fSBarry Smith PetscFunctionBegin; 15859566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)A, "Zoomviewer", (PetscObject *)&viewer)); 15869566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 15879566063dSJacob Faibussowitsch PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr)); 1588f1af5d2fSBarry Smith 1589f1af5d2fSBarry Smith /* Loop over matrix elements drawing boxes */ 15909566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 1591fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 1592d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 1593f1af5d2fSBarry Smith /* Blue for negative and Red for positive */ 1594f1af5d2fSBarry Smith for (j = 0; j < n; j++) { 15959371c9d4SSatish Balay x_l = j; 15969371c9d4SSatish Balay x_r = x_l + 1.0; 1597f1af5d2fSBarry Smith for (i = 0; i < m; i++) { 1598f1af5d2fSBarry Smith y_l = m - i - 1.0; 1599f1af5d2fSBarry Smith y_r = y_l + 1.0; 1600ca15aa20SStefano Zampini if (PetscRealPart(v[j * m + i]) > 0.) color = PETSC_DRAW_RED; 1601ca15aa20SStefano Zampini else if (PetscRealPart(v[j * m + i]) < 0.) color = PETSC_DRAW_BLUE; 1602ca15aa20SStefano Zampini else continue; 16039566063dSJacob Faibussowitsch PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color)); 1604f1af5d2fSBarry Smith } 1605f1af5d2fSBarry Smith } 1606d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 1607f1af5d2fSBarry Smith } else { 1608f1af5d2fSBarry Smith /* use contour shading to indicate magnitude of values */ 1609f1af5d2fSBarry Smith /* first determine max of all nonzero values */ 1610b05fc000SLisandro Dalcin PetscReal minv = 0.0, maxv = 0.0; 1611b05fc000SLisandro Dalcin PetscDraw popup; 1612b05fc000SLisandro Dalcin 1613f1af5d2fSBarry Smith for (i = 0; i < m * n; i++) { 1614f1af5d2fSBarry Smith if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]); 1615f1af5d2fSBarry Smith } 1616383922c3SLisandro Dalcin if (minv >= maxv) maxv = minv + PETSC_SMALL; 16179566063dSJacob Faibussowitsch PetscCall(PetscDrawGetPopup(draw, &popup)); 16189566063dSJacob Faibussowitsch PetscCall(PetscDrawScalePopup(popup, minv, maxv)); 1619383922c3SLisandro Dalcin 1620d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 1621f1af5d2fSBarry Smith for (j = 0; j < n; j++) { 1622f1af5d2fSBarry Smith x_l = j; 1623f1af5d2fSBarry Smith x_r = x_l + 1.0; 1624f1af5d2fSBarry Smith for (i = 0; i < m; i++) { 1625f1af5d2fSBarry Smith y_l = m - i - 1.0; 1626f1af5d2fSBarry Smith y_r = y_l + 1.0; 1627b05fc000SLisandro Dalcin color = PetscDrawRealToColor(PetscAbsScalar(v[j * m + i]), minv, maxv); 16289566063dSJacob Faibussowitsch PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color)); 1629f1af5d2fSBarry Smith } 1630f1af5d2fSBarry Smith } 1631d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 1632f1af5d2fSBarry Smith } 16339566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 1634f1af5d2fSBarry Smith PetscFunctionReturn(0); 1635f1af5d2fSBarry Smith } 1636f1af5d2fSBarry Smith 1637d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw(Mat A, PetscViewer viewer) 1638d71ae5a4SJacob Faibussowitsch { 1639b0a32e0cSBarry Smith PetscDraw draw; 1640ace3abfcSBarry Smith PetscBool isnull; 1641329f5518SBarry Smith PetscReal xr, yr, xl, yl, h, w; 1642f1af5d2fSBarry Smith 1643f1af5d2fSBarry Smith PetscFunctionBegin; 16449566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 16459566063dSJacob Faibussowitsch PetscCall(PetscDrawIsNull(draw, &isnull)); 1646abc0a331SBarry Smith if (isnull) PetscFunctionReturn(0); 1647f1af5d2fSBarry Smith 16489371c9d4SSatish Balay xr = A->cmap->n; 16499371c9d4SSatish Balay yr = A->rmap->n; 16509371c9d4SSatish Balay h = yr / 10.0; 16519371c9d4SSatish Balay w = xr / 10.0; 16529371c9d4SSatish Balay xr += w; 16539371c9d4SSatish Balay yr += h; 16549371c9d4SSatish Balay xl = -w; 16559371c9d4SSatish Balay yl = -h; 16569566063dSJacob Faibussowitsch PetscCall(PetscDrawSetCoordinates(draw, xl, yl, xr, yr)); 16579566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", (PetscObject)viewer)); 16589566063dSJacob Faibussowitsch PetscCall(PetscDrawZoom(draw, MatView_SeqDense_Draw_Zoom, A)); 16599566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", NULL)); 16609566063dSJacob Faibussowitsch PetscCall(PetscDrawSave(draw)); 1661f1af5d2fSBarry Smith PetscFunctionReturn(0); 1662f1af5d2fSBarry Smith } 1663f1af5d2fSBarry Smith 1664d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_SeqDense(Mat A, PetscViewer viewer) 1665d71ae5a4SJacob Faibussowitsch { 1666ace3abfcSBarry Smith PetscBool iascii, isbinary, isdraw; 1667932b0c3eSLois Curfman McInnes 16683a40ed3dSBarry Smith PetscFunctionBegin; 16699566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 16709566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 16719566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 16721baa6e33SBarry Smith if (iascii) PetscCall(MatView_SeqDense_ASCII(A, viewer)); 16731baa6e33SBarry Smith else if (isbinary) PetscCall(MatView_Dense_Binary(A, viewer)); 16741baa6e33SBarry Smith else if (isdraw) PetscCall(MatView_SeqDense_Draw(A, viewer)); 16753a40ed3dSBarry Smith PetscFunctionReturn(0); 1676932b0c3eSLois Curfman McInnes } 1677289bc588SBarry Smith 1678d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A, const PetscScalar *array) 1679d71ae5a4SJacob Faibussowitsch { 1680d3042a70SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1681d3042a70SBarry Smith 1682d3042a70SBarry Smith PetscFunctionBegin; 168328b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 168428b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 168528b400f6SJacob Faibussowitsch PetscCheck(!a->unplacedarray, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreArray() first"); 1686d3042a70SBarry Smith a->unplacedarray = a->v; 1687d3042a70SBarry Smith a->unplaced_user_alloc = a->user_alloc; 1688d3042a70SBarry Smith a->v = (PetscScalar *)array; 1689637a0070SStefano Zampini a->user_alloc = PETSC_TRUE; 169047d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1691c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_CPU; 1692ca15aa20SStefano Zampini #endif 1693d3042a70SBarry Smith PetscFunctionReturn(0); 1694d3042a70SBarry Smith } 1695d3042a70SBarry Smith 1696d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseResetArray_SeqDense(Mat A) 1697d71ae5a4SJacob Faibussowitsch { 1698d3042a70SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1699d3042a70SBarry Smith 1700d3042a70SBarry Smith PetscFunctionBegin; 170128b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 170228b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 1703d3042a70SBarry Smith a->v = a->unplacedarray; 1704d3042a70SBarry Smith a->user_alloc = a->unplaced_user_alloc; 1705d3042a70SBarry Smith a->unplacedarray = NULL; 170647d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1707c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_CPU; 1708ca15aa20SStefano Zampini #endif 1709d3042a70SBarry Smith PetscFunctionReturn(0); 1710d3042a70SBarry Smith } 1711d3042a70SBarry Smith 1712d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A, const PetscScalar *array) 1713d71ae5a4SJacob Faibussowitsch { 1714d5ea218eSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1715d5ea218eSStefano Zampini 1716d5ea218eSStefano Zampini PetscFunctionBegin; 171728b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 171828b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 17199566063dSJacob Faibussowitsch if (!a->user_alloc) PetscCall(PetscFree(a->v)); 1720d5ea218eSStefano Zampini a->v = (PetscScalar *)array; 1721d5ea218eSStefano Zampini a->user_alloc = PETSC_FALSE; 172247d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1723d5ea218eSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 1724d5ea218eSStefano Zampini #endif 1725d5ea218eSStefano Zampini PetscFunctionReturn(0); 1726d5ea218eSStefano Zampini } 1727d5ea218eSStefano Zampini 1728d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDestroy_SeqDense(Mat mat) 1729d71ae5a4SJacob Faibussowitsch { 1730ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)mat->data; 173190f02eecSBarry Smith 17323a40ed3dSBarry Smith PetscFunctionBegin; 1733aa482453SBarry Smith #if defined(PETSC_USE_LOG) 1734c0aa6a63SJacob Faibussowitsch PetscLogObjectState((PetscObject)mat, "Rows %" PetscInt_FMT " Cols %" PetscInt_FMT, mat->rmap->n, mat->cmap->n); 1735a5a9c739SBarry Smith #endif 17369566063dSJacob Faibussowitsch PetscCall(VecDestroy(&(l->qrrhs))); 17379566063dSJacob Faibussowitsch PetscCall(PetscFree(l->tau)); 17389566063dSJacob Faibussowitsch PetscCall(PetscFree(l->pivots)); 17399566063dSJacob Faibussowitsch PetscCall(PetscFree(l->fwork)); 17409566063dSJacob Faibussowitsch PetscCall(MatDestroy(&l->ptapwork)); 17419566063dSJacob Faibussowitsch if (!l->user_alloc) PetscCall(PetscFree(l->v)); 17429566063dSJacob Faibussowitsch if (!l->unplaced_user_alloc) PetscCall(PetscFree(l->unplacedarray)); 174328b400f6SJacob Faibussowitsch PetscCheck(!l->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 174428b400f6SJacob Faibussowitsch PetscCheck(!l->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 17459566063dSJacob Faibussowitsch PetscCall(VecDestroy(&l->cvec)); 17469566063dSJacob Faibussowitsch PetscCall(MatDestroy(&l->cmat)); 17479566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->data)); 1748dbd8c25aSHong Zhang 17499566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)mat, NULL)); 17509566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactor_C", NULL)); 17512e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorSymbolic_C", NULL)); 17522e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorNumeric_C", NULL)); 17539566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetLDA_C", NULL)); 17549566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseSetLDA_C", NULL)); 17559566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArray_C", NULL)); 17569566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArray_C", NULL)); 17579566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDensePlaceArray_C", NULL)); 17589566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseResetArray_C", NULL)); 17599566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseReplaceArray_C", NULL)); 17609566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayRead_C", NULL)); 17619566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayRead_C", NULL)); 17629566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayWrite_C", NULL)); 17639566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayWrite_C", NULL)); 17649566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqaij_C", NULL)); 17658baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 17669566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_elemental_C", NULL)); 17678baccfbdSHong Zhang #endif 1768d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 17699566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_scalapack_C", NULL)); 1770d24d4204SJose E. Roman #endif 17712bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA) 17729566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensecuda_C", NULL)); 17739566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", NULL)); 17749566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdense_C", NULL)); 17752e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensecuda_C", NULL)); 17762bf066beSStefano Zampini #endif 177747d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 177847d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensehip_C", NULL)); 177947d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensehip_seqdensehip_C", NULL)); 178047d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensehip_seqdense_C", NULL)); 178147d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensehip_C", NULL)); 178247d993e7Ssuyashtn #endif 17839566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatSeqDenseSetPreallocation_C", NULL)); 17849566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqaij_seqdense_C", NULL)); 17859566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdense_C", NULL)); 17869566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqbaij_seqdense_C", NULL)); 17879566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqsbaij_seqdense_C", NULL)); 178852c5f739Sprj- 17899566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumn_C", NULL)); 17909566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumn_C", NULL)); 17919566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVec_C", NULL)); 17929566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVec_C", NULL)); 17939566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecRead_C", NULL)); 17949566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecRead_C", NULL)); 17959566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecWrite_C", NULL)); 17969566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecWrite_C", NULL)); 17979566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetSubMatrix_C", NULL)); 17989566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreSubMatrix_C", NULL)); 17993a40ed3dSBarry Smith PetscFunctionReturn(0); 1800289bc588SBarry Smith } 1801289bc588SBarry Smith 1802d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatTranspose_SeqDense(Mat A, MatReuse reuse, Mat *matout) 1803d71ae5a4SJacob Faibussowitsch { 1804c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 18056536e3caSStefano Zampini PetscInt k, j, m = A->rmap->n, M = mat->lda, n = A->cmap->n; 180687828ca2SBarry Smith PetscScalar *v, tmp; 180748b35521SBarry Smith 18083a40ed3dSBarry Smith PetscFunctionBegin; 18097fb60732SBarry Smith if (reuse == MAT_REUSE_MATRIX) PetscCall(MatTransposeCheckNonzeroState_Private(A, *matout)); 18106536e3caSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 18116536e3caSStefano Zampini if (m == n) { /* in place transpose */ 18129566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 1813d3e5ee88SLois Curfman McInnes for (j = 0; j < m; j++) { 1814289bc588SBarry Smith for (k = 0; k < j; k++) { 18151b807ce4Svictorle tmp = v[j + k * M]; 18161b807ce4Svictorle v[j + k * M] = v[k + j * M]; 18171b807ce4Svictorle v[k + j * M] = tmp; 1818289bc588SBarry Smith } 1819289bc588SBarry Smith } 18209566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 18216536e3caSStefano Zampini } else { /* reuse memory, temporary allocates new memory */ 18226536e3caSStefano Zampini PetscScalar *v2; 18236536e3caSStefano Zampini PetscLayout tmplayout; 18246536e3caSStefano Zampini 18259566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((size_t)m * n, &v2)); 18269566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 18276536e3caSStefano Zampini for (j = 0; j < n; j++) { 18286536e3caSStefano Zampini for (k = 0; k < m; k++) v2[j + (size_t)k * n] = v[k + (size_t)j * M]; 18296536e3caSStefano Zampini } 18309566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(v, v2, (size_t)m * n)); 18319566063dSJacob Faibussowitsch PetscCall(PetscFree(v2)); 18329566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 18336536e3caSStefano Zampini /* cleanup size dependent quantities */ 18349566063dSJacob Faibussowitsch PetscCall(VecDestroy(&mat->cvec)); 18359566063dSJacob Faibussowitsch PetscCall(MatDestroy(&mat->cmat)); 18369566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->pivots)); 18379566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->fwork)); 18389566063dSJacob Faibussowitsch PetscCall(MatDestroy(&mat->ptapwork)); 18396536e3caSStefano Zampini /* swap row/col layouts */ 18406536e3caSStefano Zampini mat->lda = n; 18416536e3caSStefano Zampini tmplayout = A->rmap; 18426536e3caSStefano Zampini A->rmap = A->cmap; 18436536e3caSStefano Zampini A->cmap = tmplayout; 18446536e3caSStefano Zampini } 18453a40ed3dSBarry Smith } else { /* out-of-place transpose */ 1846d3e5ee88SLois Curfman McInnes Mat tmat; 1847ec8511deSBarry Smith Mat_SeqDense *tmatd; 184887828ca2SBarry Smith PetscScalar *v2; 1849af36a384SStefano Zampini PetscInt M2; 1850ea709b57SSatish Balay 18516536e3caSStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 18529566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &tmat)); 18539566063dSJacob Faibussowitsch PetscCall(MatSetSizes(tmat, A->cmap->n, A->rmap->n, A->cmap->n, A->rmap->n)); 18549566063dSJacob Faibussowitsch PetscCall(MatSetType(tmat, ((PetscObject)A)->type_name)); 18559566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(tmat, NULL)); 1856ca15aa20SStefano Zampini } else tmat = *matout; 1857ca15aa20SStefano Zampini 18589566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&v)); 18599566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(tmat, &v2)); 1860ec8511deSBarry Smith tmatd = (Mat_SeqDense *)tmat->data; 1861ca15aa20SStefano Zampini M2 = tmatd->lda; 1862d3e5ee88SLois Curfman McInnes for (j = 0; j < n; j++) { 1863af36a384SStefano Zampini for (k = 0; k < m; k++) v2[j + k * M2] = v[k + j * M]; 1864d3e5ee88SLois Curfman McInnes } 18659566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(tmat, &v2)); 18669566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&v)); 18679566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(tmat, MAT_FINAL_ASSEMBLY)); 18689566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(tmat, MAT_FINAL_ASSEMBLY)); 18696536e3caSStefano Zampini *matout = tmat; 187048b35521SBarry Smith } 18713a40ed3dSBarry Smith PetscFunctionReturn(0); 1872289bc588SBarry Smith } 1873289bc588SBarry Smith 1874d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatEqual_SeqDense(Mat A1, Mat A2, PetscBool *flg) 1875d71ae5a4SJacob Faibussowitsch { 1876c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat1 = (Mat_SeqDense *)A1->data; 1877c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat2 = (Mat_SeqDense *)A2->data; 1878ca15aa20SStefano Zampini PetscInt i; 1879ca15aa20SStefano Zampini const PetscScalar *v1, *v2; 18809ea5d5aeSSatish Balay 18813a40ed3dSBarry Smith PetscFunctionBegin; 18829371c9d4SSatish Balay if (A1->rmap->n != A2->rmap->n) { 18839371c9d4SSatish Balay *flg = PETSC_FALSE; 18849371c9d4SSatish Balay PetscFunctionReturn(0); 18859371c9d4SSatish Balay } 18869371c9d4SSatish Balay if (A1->cmap->n != A2->cmap->n) { 18879371c9d4SSatish Balay *flg = PETSC_FALSE; 18889371c9d4SSatish Balay PetscFunctionReturn(0); 18899371c9d4SSatish Balay } 18909566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A1, &v1)); 18919566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A2, &v2)); 1892ca15aa20SStefano Zampini for (i = 0; i < A1->cmap->n; i++) { 18939566063dSJacob Faibussowitsch PetscCall(PetscArraycmp(v1, v2, A1->rmap->n, flg)); 1894ca15aa20SStefano Zampini if (*flg == PETSC_FALSE) PetscFunctionReturn(0); 1895ca15aa20SStefano Zampini v1 += mat1->lda; 1896ca15aa20SStefano Zampini v2 += mat2->lda; 18971b807ce4Svictorle } 18989566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A1, &v1)); 18999566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A2, &v2)); 190077c4ece6SBarry Smith *flg = PETSC_TRUE; 19013a40ed3dSBarry Smith PetscFunctionReturn(0); 1902289bc588SBarry Smith } 1903289bc588SBarry Smith 1904d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetDiagonal_SeqDense(Mat A, Vec v) 1905d71ae5a4SJacob Faibussowitsch { 1906c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 190713f74950SBarry Smith PetscInt i, n, len; 1908ca15aa20SStefano Zampini PetscScalar *x; 1909ca15aa20SStefano Zampini const PetscScalar *vv; 191044cd7ae7SLois Curfman McInnes 19113a40ed3dSBarry Smith PetscFunctionBegin; 19129566063dSJacob Faibussowitsch PetscCall(VecGetSize(v, &n)); 19139566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 1914d0f46423SBarry Smith len = PetscMin(A->rmap->n, A->cmap->n); 19159566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &vv)); 191608401ef6SPierre Jolivet PetscCheck(n == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming mat and vec"); 1917ad540459SPierre Jolivet for (i = 0; i < len; i++) x[i] = vv[i * mat->lda + i]; 19189566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &vv)); 19199566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 19203a40ed3dSBarry Smith PetscFunctionReturn(0); 1921289bc588SBarry Smith } 1922289bc588SBarry Smith 1923d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDiagonalScale_SeqDense(Mat A, Vec ll, Vec rr) 1924d71ae5a4SJacob Faibussowitsch { 1925c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1926f1ceaac6SMatthew G. Knepley const PetscScalar *l, *r; 1927ca15aa20SStefano Zampini PetscScalar x, *v, *vv; 1928d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n; 192955659b69SBarry Smith 19303a40ed3dSBarry Smith PetscFunctionBegin; 19319566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &vv)); 193228988994SBarry Smith if (ll) { 19339566063dSJacob Faibussowitsch PetscCall(VecGetSize(ll, &m)); 19349566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(ll, &l)); 193508401ef6SPierre Jolivet PetscCheck(m == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Left scaling vec wrong size"); 1936da3a660dSBarry Smith for (i = 0; i < m; i++) { 1937da3a660dSBarry Smith x = l[i]; 1938ca15aa20SStefano Zampini v = vv + i; 19399371c9d4SSatish Balay for (j = 0; j < n; j++) { 19409371c9d4SSatish Balay (*v) *= x; 19419371c9d4SSatish Balay v += mat->lda; 19429371c9d4SSatish Balay } 1943da3a660dSBarry Smith } 19449566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(ll, &l)); 19459566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * n * m)); 1946da3a660dSBarry Smith } 194728988994SBarry Smith if (rr) { 19489566063dSJacob Faibussowitsch PetscCall(VecGetSize(rr, &n)); 19499566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(rr, &r)); 195008401ef6SPierre Jolivet PetscCheck(n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Right scaling vec wrong size"); 1951da3a660dSBarry Smith for (i = 0; i < n; i++) { 1952da3a660dSBarry Smith x = r[i]; 1953ca15aa20SStefano Zampini v = vv + i * mat->lda; 19542205254eSKarl Rupp for (j = 0; j < m; j++) (*v++) *= x; 1955da3a660dSBarry Smith } 19569566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(rr, &r)); 19579566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * n * m)); 1958da3a660dSBarry Smith } 19599566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &vv)); 19603a40ed3dSBarry Smith PetscFunctionReturn(0); 1961289bc588SBarry Smith } 1962289bc588SBarry Smith 1963d71ae5a4SJacob Faibussowitsch PetscErrorCode MatNorm_SeqDense(Mat A, NormType type, PetscReal *nrm) 1964d71ae5a4SJacob Faibussowitsch { 1965c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1966ca15aa20SStefano Zampini PetscScalar *v, *vv; 1967329f5518SBarry Smith PetscReal sum = 0.0; 196875f6d85dSStefano Zampini PetscInt lda, m = A->rmap->n, i, j; 196955659b69SBarry Smith 19703a40ed3dSBarry Smith PetscFunctionBegin; 19719566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&vv)); 19729566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(A, &lda)); 1973ca15aa20SStefano Zampini v = vv; 1974289bc588SBarry Smith if (type == NORM_FROBENIUS) { 1975a5ce6ee0Svictorle if (lda > m) { 1976d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1977ca15aa20SStefano Zampini v = vv + j * lda; 1978a5ce6ee0Svictorle for (i = 0; i < m; i++) { 19799371c9d4SSatish Balay sum += PetscRealPart(PetscConj(*v) * (*v)); 19809371c9d4SSatish Balay v++; 1981a5ce6ee0Svictorle } 1982a5ce6ee0Svictorle } 1983a5ce6ee0Svictorle } else { 1984570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16) 1985570b7f6dSBarry Smith PetscBLASInt one = 1, cnt = A->cmap->n * A->rmap->n; 1986792fecdfSBarry Smith PetscCallBLAS("BLASnrm2", *nrm = BLASnrm2_(&cnt, v, &one)); 1987570b7f6dSBarry Smith } 1988570b7f6dSBarry Smith #else 1989d0f46423SBarry Smith for (i = 0; i < A->cmap->n * A->rmap->n; i++) { 19909371c9d4SSatish Balay sum += PetscRealPart(PetscConj(*v) * (*v)); 19919371c9d4SSatish Balay v++; 1992289bc588SBarry Smith } 1993a5ce6ee0Svictorle } 19948f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 1995570b7f6dSBarry Smith #endif 19969566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->cmap->n * A->rmap->n)); 19973a40ed3dSBarry Smith } else if (type == NORM_1) { 1998064f8208SBarry Smith *nrm = 0.0; 1999d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 2000ca15aa20SStefano Zampini v = vv + j * mat->lda; 2001289bc588SBarry Smith sum = 0.0; 2002d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 20039371c9d4SSatish Balay sum += PetscAbsScalar(*v); 20049371c9d4SSatish Balay v++; 2005289bc588SBarry Smith } 2006064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 2007289bc588SBarry Smith } 20089566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n)); 20093a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 2010064f8208SBarry Smith *nrm = 0.0; 2011d0f46423SBarry Smith for (j = 0; j < A->rmap->n; j++) { 2012ca15aa20SStefano Zampini v = vv + j; 2013289bc588SBarry Smith sum = 0.0; 2014d0f46423SBarry Smith for (i = 0; i < A->cmap->n; i++) { 20159371c9d4SSatish Balay sum += PetscAbsScalar(*v); 20169371c9d4SSatish Balay v += mat->lda; 2017289bc588SBarry Smith } 2018064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 2019289bc588SBarry Smith } 20209566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n)); 2021e7e72b3dSBarry Smith } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "No two norm"); 20229566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&vv)); 20233a40ed3dSBarry Smith PetscFunctionReturn(0); 2024289bc588SBarry Smith } 2025289bc588SBarry Smith 2026d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetOption_SeqDense(Mat A, MatOption op, PetscBool flg) 2027d71ae5a4SJacob Faibussowitsch { 2028c0bbcb79SLois Curfman McInnes Mat_SeqDense *aij = (Mat_SeqDense *)A->data; 202967e560aaSBarry Smith 20303a40ed3dSBarry Smith PetscFunctionBegin; 2031b5a2b587SKris Buschelman switch (op) { 2032d71ae5a4SJacob Faibussowitsch case MAT_ROW_ORIENTED: 2033d71ae5a4SJacob Faibussowitsch aij->roworiented = flg; 2034d71ae5a4SJacob Faibussowitsch break; 2035512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 2036b5a2b587SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 20373971808eSMatthew Knepley case MAT_NEW_NONZERO_ALLOCATION_ERR: 20388c78258cSHong Zhang case MAT_FORCE_DIAGONAL_ENTRIES: 203913fa8e87SLisandro Dalcin case MAT_KEEP_NONZERO_PATTERN: 2040b5a2b587SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 2041b5a2b587SKris Buschelman case MAT_USE_HASH_TABLE: 20420f8fb01aSBarry Smith case MAT_IGNORE_ZERO_ENTRIES: 20435021d80fSJed Brown case MAT_IGNORE_LOWER_TRIANGULAR: 2044d71ae5a4SJacob Faibussowitsch case MAT_SORTED_FULL: 2045d71ae5a4SJacob Faibussowitsch PetscCall(PetscInfo(A, "Option %s ignored\n", MatOptions[op])); 2046d71ae5a4SJacob Faibussowitsch break; 20475021d80fSJed Brown case MAT_SPD: 204877e54ba9SKris Buschelman case MAT_SYMMETRIC: 204977e54ba9SKris Buschelman case MAT_STRUCTURALLY_SYMMETRIC: 20509a4540c5SBarry Smith case MAT_HERMITIAN: 20519a4540c5SBarry Smith case MAT_SYMMETRY_ETERNAL: 2052b94d7dedSBarry Smith case MAT_STRUCTURAL_SYMMETRY_ETERNAL: 2053d71ae5a4SJacob Faibussowitsch case MAT_SPD_ETERNAL: 2054d71ae5a4SJacob Faibussowitsch break; 2055d71ae5a4SJacob Faibussowitsch default: 2056d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "unknown option %s", MatOptions[op]); 20573a40ed3dSBarry Smith } 20583a40ed3dSBarry Smith PetscFunctionReturn(0); 2059289bc588SBarry Smith } 2060289bc588SBarry Smith 2061d71ae5a4SJacob Faibussowitsch PetscErrorCode MatZeroEntries_SeqDense(Mat A) 2062d71ae5a4SJacob Faibussowitsch { 2063ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)A->data; 20643d8925e7SStefano Zampini PetscInt lda = l->lda, m = A->rmap->n, n = A->cmap->n, j; 2065ca15aa20SStefano Zampini PetscScalar *v; 20663a40ed3dSBarry Smith 20673a40ed3dSBarry Smith PetscFunctionBegin; 20689566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(A, &v)); 2069a5ce6ee0Svictorle if (lda > m) { 207048a46eb9SPierre Jolivet for (j = 0; j < n; j++) PetscCall(PetscArrayzero(v + j * lda, m)); 2071a5ce6ee0Svictorle } else { 20729566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(v, PetscInt64Mult(m, n))); 2073a5ce6ee0Svictorle } 20749566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(A, &v)); 20753a40ed3dSBarry Smith PetscFunctionReturn(0); 20766f0a148fSBarry Smith } 20776f0a148fSBarry Smith 2078d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatZeroRows_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) 2079d71ae5a4SJacob Faibussowitsch { 2080ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)A->data; 2081b9679d65SBarry Smith PetscInt m = l->lda, n = A->cmap->n, i, j; 2082ca15aa20SStefano Zampini PetscScalar *slot, *bb, *v; 208397b48c8fSBarry Smith const PetscScalar *xx; 208455659b69SBarry Smith 20853a40ed3dSBarry Smith PetscFunctionBegin; 208676bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 2087b9679d65SBarry Smith for (i = 0; i < N; i++) { 208808401ef6SPierre Jolivet PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed"); 208908401ef6SPierre 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); 2090b9679d65SBarry Smith } 209176bd3646SJed Brown } 2092ca15aa20SStefano Zampini if (!N) PetscFunctionReturn(0); 2093b9679d65SBarry Smith 209497b48c8fSBarry Smith /* fix right hand side if needed */ 209597b48c8fSBarry Smith if (x && b) { 20969566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 20979566063dSJacob Faibussowitsch PetscCall(VecGetArray(b, &bb)); 20982205254eSKarl Rupp for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]]; 20999566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 21009566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(b, &bb)); 210197b48c8fSBarry Smith } 210297b48c8fSBarry Smith 21039566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 21046f0a148fSBarry Smith for (i = 0; i < N; i++) { 2105ca15aa20SStefano Zampini slot = v + rows[i]; 21069371c9d4SSatish Balay for (j = 0; j < n; j++) { 21079371c9d4SSatish Balay *slot = 0.0; 21089371c9d4SSatish Balay slot += m; 21099371c9d4SSatish Balay } 21106f0a148fSBarry Smith } 2111f4df32b1SMatthew Knepley if (diag != 0.0) { 211208401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices"); 21136f0a148fSBarry Smith for (i = 0; i < N; i++) { 2114ca15aa20SStefano Zampini slot = v + (m + 1) * rows[i]; 2115f4df32b1SMatthew Knepley *slot = diag; 21166f0a148fSBarry Smith } 21176f0a148fSBarry Smith } 21189566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 21193a40ed3dSBarry Smith PetscFunctionReturn(0); 21206f0a148fSBarry Smith } 2121557bce09SLois Curfman McInnes 2122d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A, PetscInt *lda) 2123d71ae5a4SJacob Faibussowitsch { 212449a6ff4bSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 212549a6ff4bSBarry Smith 212649a6ff4bSBarry Smith PetscFunctionBegin; 212749a6ff4bSBarry Smith *lda = mat->lda; 212849a6ff4bSBarry Smith PetscFunctionReturn(0); 212949a6ff4bSBarry Smith } 213049a6ff4bSBarry Smith 2131d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArray_SeqDense(Mat A, PetscScalar **array) 2132d71ae5a4SJacob Faibussowitsch { 2133c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 21343a40ed3dSBarry Smith 21353a40ed3dSBarry Smith PetscFunctionBegin; 213628b400f6SJacob Faibussowitsch PetscCheck(!mat->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 213764e87e97SBarry Smith *array = mat->v; 21383a40ed3dSBarry Smith PetscFunctionReturn(0); 213964e87e97SBarry Smith } 21400754003eSLois Curfman McInnes 2141d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A, PetscScalar **array) 2142d71ae5a4SJacob Faibussowitsch { 21433a40ed3dSBarry Smith PetscFunctionBegin; 214475f6d85dSStefano Zampini if (array) *array = NULL; 21453a40ed3dSBarry Smith PetscFunctionReturn(0); 2146ff14e315SSatish Balay } 21470754003eSLois Curfman McInnes 21480f74d2c1SSatish Balay /*@ 214911a5261eSBarry Smith MatDenseGetLDA - gets the leading dimension of the array returned from `MatDenseGetArray()` 215049a6ff4bSBarry Smith 2151ad16ce7aSStefano Zampini Not collective 215249a6ff4bSBarry Smith 215349a6ff4bSBarry Smith Input Parameter: 215411a5261eSBarry Smith . mat - a `MATDENSE` or `MATDENSECUDA` matrix 215549a6ff4bSBarry Smith 215649a6ff4bSBarry Smith Output Parameter: 215749a6ff4bSBarry Smith . lda - the leading dimension 215849a6ff4bSBarry Smith 215949a6ff4bSBarry Smith Level: intermediate 216049a6ff4bSBarry Smith 216111a5261eSBarry Smith .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseSetLDA()` 216249a6ff4bSBarry Smith @*/ 2163d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetLDA(Mat A, PetscInt *lda) 2164d71ae5a4SJacob Faibussowitsch { 216549a6ff4bSBarry Smith PetscFunctionBegin; 2166d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2167dadcf809SJacob Faibussowitsch PetscValidIntPointer(lda, 2); 216875f6d85dSStefano Zampini MatCheckPreallocated(A, 1); 2169cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetLDA_C", (Mat, PetscInt *), (A, lda)); 217049a6ff4bSBarry Smith PetscFunctionReturn(0); 217149a6ff4bSBarry Smith } 217249a6ff4bSBarry Smith 21730f74d2c1SSatish Balay /*@ 217411a5261eSBarry Smith MatDenseSetLDA - Sets the leading dimension of the array used by the `MATDENSE` matrix 2175ad16ce7aSStefano Zampini 2176ad16ce7aSStefano Zampini Not collective 2177ad16ce7aSStefano Zampini 2178d8d19677SJose E. Roman Input Parameters: 217911a5261eSBarry Smith + mat - a `MATDENSE` or `MATDENSECUDA` matrix 2180ad16ce7aSStefano Zampini - lda - the leading dimension 2181ad16ce7aSStefano Zampini 2182ad16ce7aSStefano Zampini Level: intermediate 2183ad16ce7aSStefano Zampini 218411a5261eSBarry Smith .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetLDA()` 2185ad16ce7aSStefano Zampini @*/ 2186d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA(Mat A, PetscInt lda) 2187d71ae5a4SJacob Faibussowitsch { 2188ad16ce7aSStefano Zampini PetscFunctionBegin; 2189ad16ce7aSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2190cac4c232SBarry Smith PetscTryMethod(A, "MatDenseSetLDA_C", (Mat, PetscInt), (A, lda)); 2191ad16ce7aSStefano Zampini PetscFunctionReturn(0); 2192ad16ce7aSStefano Zampini } 2193ad16ce7aSStefano Zampini 2194ad16ce7aSStefano Zampini /*@C 219511a5261eSBarry Smith MatDenseGetArray - gives read-write access to the array where the data for a `MATDENSE` matrix is stored 219673a71a0fSBarry Smith 219711a5261eSBarry Smith Logically Collective on A 219873a71a0fSBarry Smith 219973a71a0fSBarry Smith Input Parameter: 22006947451fSStefano Zampini . mat - a dense matrix 220173a71a0fSBarry Smith 220273a71a0fSBarry Smith Output Parameter: 220373a71a0fSBarry Smith . array - pointer to the data 220473a71a0fSBarry Smith 220573a71a0fSBarry Smith Level: intermediate 220673a71a0fSBarry Smith 220711a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 220873a71a0fSBarry Smith @*/ 2209d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArray(Mat A, PetscScalar **array) 2210d71ae5a4SJacob Faibussowitsch { 221173a71a0fSBarry Smith PetscFunctionBegin; 2212d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2213d5ea218eSStefano Zampini PetscValidPointer(array, 2); 2214cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array)); 221573a71a0fSBarry Smith PetscFunctionReturn(0); 221673a71a0fSBarry Smith } 221773a71a0fSBarry Smith 2218dec5eb66SMatthew G Knepley /*@C 221911a5261eSBarry Smith MatDenseRestoreArray - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArray()` 222073a71a0fSBarry Smith 222111a5261eSBarry Smith Logically Collective on A 22228572280aSBarry Smith 22238572280aSBarry Smith Input Parameters: 22246947451fSStefano Zampini + mat - a dense matrix 2225742765d3SMatthew Knepley - array - pointer to the data (may be NULL) 22268572280aSBarry Smith 22278572280aSBarry Smith Level: intermediate 22288572280aSBarry Smith 222911a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 22308572280aSBarry Smith @*/ 2231d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArray(Mat A, PetscScalar **array) 2232d71ae5a4SJacob Faibussowitsch { 22338572280aSBarry Smith PetscFunctionBegin; 2234d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2235d5ea218eSStefano Zampini PetscValidPointer(array, 2); 2236cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array)); 22379566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)A)); 223847d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 2239637a0070SStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 2240637a0070SStefano Zampini #endif 22418572280aSBarry Smith PetscFunctionReturn(0); 22428572280aSBarry Smith } 22438572280aSBarry Smith 22448572280aSBarry Smith /*@C 224511a5261eSBarry Smith MatDenseGetArrayRead - gives read-only access to the array where the data for a `MATDENSE` matrix is stored 22468572280aSBarry Smith 22478572280aSBarry Smith Not Collective 22488572280aSBarry Smith 22498572280aSBarry Smith Input Parameter: 22506947451fSStefano Zampini . mat - a dense matrix 22518572280aSBarry Smith 22528572280aSBarry Smith Output Parameter: 22538572280aSBarry Smith . array - pointer to the data 22548572280aSBarry Smith 22558572280aSBarry Smith Level: intermediate 22568572280aSBarry Smith 225711a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 22588572280aSBarry Smith @*/ 2259d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArrayRead(Mat A, const PetscScalar **array) 2260d71ae5a4SJacob Faibussowitsch { 22618572280aSBarry Smith PetscFunctionBegin; 2262d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2263d5ea218eSStefano Zampini PetscValidPointer(array, 2); 2264cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, const PetscScalar **), (A, array)); 22658572280aSBarry Smith PetscFunctionReturn(0); 22668572280aSBarry Smith } 22678572280aSBarry Smith 22688572280aSBarry Smith /*@C 226911a5261eSBarry Smith MatDenseRestoreArrayRead - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayRead()` 22708572280aSBarry Smith 227173a71a0fSBarry Smith Not Collective 227273a71a0fSBarry Smith 227373a71a0fSBarry Smith Input Parameters: 22746947451fSStefano Zampini + mat - a dense matrix 2275742765d3SMatthew Knepley - array - pointer to the data (may be NULL) 227673a71a0fSBarry Smith 227773a71a0fSBarry Smith Level: intermediate 227873a71a0fSBarry Smith 227911a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 228073a71a0fSBarry Smith @*/ 2281d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArrayRead(Mat A, const PetscScalar **array) 2282d71ae5a4SJacob Faibussowitsch { 228373a71a0fSBarry Smith PetscFunctionBegin; 2284d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2285d5ea218eSStefano Zampini PetscValidPointer(array, 2); 2286cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, const PetscScalar **), (A, array)); 228773a71a0fSBarry Smith PetscFunctionReturn(0); 228873a71a0fSBarry Smith } 228973a71a0fSBarry Smith 22906947451fSStefano Zampini /*@C 229111a5261eSBarry Smith MatDenseGetArrayWrite - gives write-only access to the array where the data for a `MATDENSE` matrix is stored 22926947451fSStefano Zampini 22936947451fSStefano Zampini Not Collective 22946947451fSStefano Zampini 22956947451fSStefano Zampini Input Parameter: 22966947451fSStefano Zampini . mat - a dense matrix 22976947451fSStefano Zampini 22986947451fSStefano Zampini Output Parameter: 22996947451fSStefano Zampini . array - pointer to the data 23006947451fSStefano Zampini 23016947451fSStefano Zampini Level: intermediate 23026947451fSStefano Zampini 230311a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()` 23046947451fSStefano Zampini @*/ 2305d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArrayWrite(Mat A, PetscScalar **array) 2306d71ae5a4SJacob Faibussowitsch { 23076947451fSStefano Zampini PetscFunctionBegin; 2308d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2309d5ea218eSStefano Zampini PetscValidPointer(array, 2); 2310cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array)); 23116947451fSStefano Zampini PetscFunctionReturn(0); 23126947451fSStefano Zampini } 23136947451fSStefano Zampini 23146947451fSStefano Zampini /*@C 231511a5261eSBarry Smith MatDenseRestoreArrayWrite - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayWrite()` 23166947451fSStefano Zampini 23176947451fSStefano Zampini Not Collective 23186947451fSStefano Zampini 23196947451fSStefano Zampini Input Parameters: 23206947451fSStefano Zampini + mat - a dense matrix 2321742765d3SMatthew Knepley - array - pointer to the data (may be NULL) 23226947451fSStefano Zampini 23236947451fSStefano Zampini Level: intermediate 23246947451fSStefano Zampini 232511a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()` 23266947451fSStefano Zampini @*/ 2327d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArrayWrite(Mat A, PetscScalar **array) 2328d71ae5a4SJacob Faibussowitsch { 23296947451fSStefano Zampini PetscFunctionBegin; 2330d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2331d5ea218eSStefano Zampini PetscValidPointer(array, 2); 2332cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array)); 23339566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)A)); 233447d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 23356947451fSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 23366947451fSStefano Zampini #endif 23376947451fSStefano Zampini PetscFunctionReturn(0); 23386947451fSStefano Zampini } 23396947451fSStefano Zampini 2340d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A, IS isrow, IS iscol, MatReuse scall, Mat *B) 2341d71ae5a4SJacob Faibussowitsch { 2342c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 2343bf5a80bcSToby Isaac PetscInt i, j, nrows, ncols, ldb; 23445d0c19d7SBarry Smith const PetscInt *irow, *icol; 234587828ca2SBarry Smith PetscScalar *av, *bv, *v = mat->v; 23460754003eSLois Curfman McInnes Mat newmat; 23470754003eSLois Curfman McInnes 23483a40ed3dSBarry Smith PetscFunctionBegin; 23499566063dSJacob Faibussowitsch PetscCall(ISGetIndices(isrow, &irow)); 23509566063dSJacob Faibussowitsch PetscCall(ISGetIndices(iscol, &icol)); 23519566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(isrow, &nrows)); 23529566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(iscol, &ncols)); 23530754003eSLois Curfman McInnes 2354182d2002SSatish Balay /* Check submatrixcall */ 2355182d2002SSatish Balay if (scall == MAT_REUSE_MATRIX) { 235613f74950SBarry Smith PetscInt n_cols, n_rows; 23579566063dSJacob Faibussowitsch PetscCall(MatGetSize(*B, &n_rows, &n_cols)); 235821a2c019SBarry Smith if (n_rows != nrows || n_cols != ncols) { 2359f746d493SDmitry Karpeev /* resize the result matrix to match number of requested rows/columns */ 23609566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*B, nrows, ncols, nrows, ncols)); 236121a2c019SBarry Smith } 2362182d2002SSatish Balay newmat = *B; 2363182d2002SSatish Balay } else { 23640754003eSLois Curfman McInnes /* Create and fill new matrix */ 23659566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &newmat)); 23669566063dSJacob Faibussowitsch PetscCall(MatSetSizes(newmat, nrows, ncols, nrows, ncols)); 23679566063dSJacob Faibussowitsch PetscCall(MatSetType(newmat, ((PetscObject)A)->type_name)); 23689566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(newmat, NULL)); 2369182d2002SSatish Balay } 2370182d2002SSatish Balay 2371182d2002SSatish Balay /* Now extract the data pointers and do the copy,column at a time */ 23729566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(newmat, &bv)); 23739566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(newmat, &ldb)); 2374182d2002SSatish Balay for (i = 0; i < ncols; i++) { 23756de62eeeSBarry Smith av = v + mat->lda * icol[i]; 2376ca15aa20SStefano Zampini for (j = 0; j < nrows; j++) bv[j] = av[irow[j]]; 2377bf5a80bcSToby Isaac bv += ldb; 23780754003eSLois Curfman McInnes } 23799566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(newmat, &bv)); 2380182d2002SSatish Balay 2381182d2002SSatish Balay /* Assemble the matrices so that the correct flags are set */ 23829566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(newmat, MAT_FINAL_ASSEMBLY)); 23839566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(newmat, MAT_FINAL_ASSEMBLY)); 23840754003eSLois Curfman McInnes 23850754003eSLois Curfman McInnes /* Free work space */ 23869566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(isrow, &irow)); 23879566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(iscol, &icol)); 2388182d2002SSatish Balay *B = newmat; 23893a40ed3dSBarry Smith PetscFunctionReturn(0); 23900754003eSLois Curfman McInnes } 23910754003eSLois Curfman McInnes 2392d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A, PetscInt n, const IS irow[], const IS icol[], MatReuse scall, Mat *B[]) 2393d71ae5a4SJacob Faibussowitsch { 239413f74950SBarry Smith PetscInt i; 2395905e6a2fSBarry Smith 23963a40ed3dSBarry Smith PetscFunctionBegin; 239748a46eb9SPierre Jolivet if (scall == MAT_INITIAL_MATRIX) PetscCall(PetscCalloc1(n, B)); 2398905e6a2fSBarry Smith 239948a46eb9SPierre Jolivet for (i = 0; i < n; i++) PetscCall(MatCreateSubMatrix_SeqDense(A, irow[i], icol[i], scall, &(*B)[i])); 24003a40ed3dSBarry Smith PetscFunctionReturn(0); 2401905e6a2fSBarry Smith } 2402905e6a2fSBarry Smith 2403d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat, MatAssemblyType mode) 2404d71ae5a4SJacob Faibussowitsch { 2405c0aa2d19SHong Zhang PetscFunctionBegin; 2406c0aa2d19SHong Zhang PetscFunctionReturn(0); 2407c0aa2d19SHong Zhang } 2408c0aa2d19SHong Zhang 2409d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat, MatAssemblyType mode) 2410d71ae5a4SJacob Faibussowitsch { 2411c0aa2d19SHong Zhang PetscFunctionBegin; 2412c0aa2d19SHong Zhang PetscFunctionReturn(0); 2413c0aa2d19SHong Zhang } 2414c0aa2d19SHong Zhang 2415d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCopy_SeqDense(Mat A, Mat B, MatStructure str) 2416d71ae5a4SJacob Faibussowitsch { 24174b0e389bSBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data; 2418ca15aa20SStefano Zampini const PetscScalar *va; 2419ca15aa20SStefano Zampini PetscScalar *vb; 2420d0f46423SBarry Smith PetscInt lda1 = a->lda, lda2 = b->lda, m = A->rmap->n, n = A->cmap->n, j; 24213a40ed3dSBarry Smith 24223a40ed3dSBarry Smith PetscFunctionBegin; 242333f4a19fSKris Buschelman /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */ 242433f4a19fSKris Buschelman if (A->ops->copy != B->ops->copy) { 24259566063dSJacob Faibussowitsch PetscCall(MatCopy_Basic(A, B, str)); 24263a40ed3dSBarry Smith PetscFunctionReturn(0); 24273a40ed3dSBarry Smith } 2428aed4548fSBarry Smith PetscCheck(m == B->rmap->n && n == B->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "size(B) != size(A)"); 24299566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &va)); 24309566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(B, &vb)); 2431a5ce6ee0Svictorle if (lda1 > m || lda2 > m) { 243248a46eb9SPierre Jolivet for (j = 0; j < n; j++) PetscCall(PetscArraycpy(vb + j * lda2, va + j * lda1, m)); 2433a5ce6ee0Svictorle } else { 24349566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(vb, va, A->rmap->n * A->cmap->n)); 2435a5ce6ee0Svictorle } 24369566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(B, &vb)); 24379566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &va)); 24389566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 24399566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 2440273d9f13SBarry Smith PetscFunctionReturn(0); 2441273d9f13SBarry Smith } 2442273d9f13SBarry Smith 2443d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetUp_SeqDense(Mat A) 2444d71ae5a4SJacob Faibussowitsch { 2445273d9f13SBarry Smith PetscFunctionBegin; 24469566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 24479566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 244848a46eb9SPierre Jolivet if (!A->preallocated) PetscCall(MatSeqDenseSetPreallocation(A, NULL)); 24493a40ed3dSBarry Smith PetscFunctionReturn(0); 24504b0e389bSBarry Smith } 24514b0e389bSBarry Smith 2452d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatConjugate_SeqDense(Mat A) 2453d71ae5a4SJacob Faibussowitsch { 24544396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 245506c5243aSJose E. Roman PetscInt i, j; 24564396437dSToby Isaac PetscInt min = PetscMin(A->rmap->n, A->cmap->n); 2457ca15aa20SStefano Zampini PetscScalar *aa; 2458ba337c44SJed Brown 2459ba337c44SJed Brown PetscFunctionBegin; 24609566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 246106c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 246206c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscConj(aa[i + j * mat->lda]); 246306c5243aSJose E. Roman } 24649566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 24659371c9d4SSatish Balay if (mat->tau) 24669371c9d4SSatish Balay for (i = 0; i < min; i++) mat->tau[i] = PetscConj(mat->tau[i]); 2467ba337c44SJed Brown PetscFunctionReturn(0); 2468ba337c44SJed Brown } 2469ba337c44SJed Brown 2470d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRealPart_SeqDense(Mat A) 2471d71ae5a4SJacob Faibussowitsch { 247206c5243aSJose E. Roman Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 247306c5243aSJose E. Roman PetscInt i, j; 2474ca15aa20SStefano Zampini PetscScalar *aa; 2475ba337c44SJed Brown 2476ba337c44SJed Brown PetscFunctionBegin; 24779566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 247806c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 247906c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscRealPart(aa[i + j * mat->lda]); 248006c5243aSJose E. Roman } 24819566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 2482ba337c44SJed Brown PetscFunctionReturn(0); 2483ba337c44SJed Brown } 2484ba337c44SJed Brown 2485d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatImaginaryPart_SeqDense(Mat A) 2486d71ae5a4SJacob Faibussowitsch { 248706c5243aSJose E. Roman Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 248806c5243aSJose E. Roman PetscInt i, j; 2489ca15aa20SStefano Zampini PetscScalar *aa; 2490ba337c44SJed Brown 2491ba337c44SJed Brown PetscFunctionBegin; 24929566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 249306c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 249406c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscImaginaryPart(aa[i + j * mat->lda]); 249506c5243aSJose E. Roman } 24969566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 2497ba337c44SJed Brown PetscFunctionReturn(0); 2498ba337c44SJed Brown } 2499284134d9SBarry Smith 2500a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/ 2501d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2502d71ae5a4SJacob Faibussowitsch { 2503d0f46423SBarry Smith PetscInt m = A->rmap->n, n = B->cmap->n; 250447d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 2505a9fe9ddaSSatish Balay 2506ee16a9a1SHong Zhang PetscFunctionBegin; 25079566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 250847d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 25099566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 251047d993e7Ssuyashtn #endif 251147d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 251247d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 251347d993e7Ssuyashtn #endif 25147a3c3d58SStefano Zampini if (!cisdense) { 25157a3c3d58SStefano Zampini PetscBool flg; 25167a3c3d58SStefano Zampini 25179566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 25189566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 25197a3c3d58SStefano Zampini } 25209566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 2521ee16a9a1SHong Zhang PetscFunctionReturn(0); 2522ee16a9a1SHong Zhang } 2523a9fe9ddaSSatish Balay 2524d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2525d71ae5a4SJacob Faibussowitsch { 25266718818eSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data, *c = (Mat_SeqDense *)C->data; 25270805154bSBarry Smith PetscBLASInt m, n, k; 2528ca15aa20SStefano Zampini const PetscScalar *av, *bv; 2529ca15aa20SStefano Zampini PetscScalar *cv; 2530a9fe9ddaSSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 2531a9fe9ddaSSatish Balay 2532a9fe9ddaSSatish Balay PetscFunctionBegin; 25339566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 25349566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 25359566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 253649d0e964SStefano Zampini if (!m || !n || !k) PetscFunctionReturn(0); 25379566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 25389566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 25399566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2540792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("N", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 25419566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 25429566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 25439566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 25449566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 2545a9fe9ddaSSatish Balay PetscFunctionReturn(0); 2546a9fe9ddaSSatish Balay } 2547a9fe9ddaSSatish Balay 2548d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2549d71ae5a4SJacob Faibussowitsch { 255069f65d41SStefano Zampini PetscInt m = A->rmap->n, n = B->rmap->n; 255147d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 255269f65d41SStefano Zampini 255369f65d41SStefano Zampini PetscFunctionBegin; 25549566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 255547d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 25569566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 255747d993e7Ssuyashtn #endif 255847d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 255947d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 256047d993e7Ssuyashtn #endif 25617a3c3d58SStefano Zampini if (!cisdense) { 25627a3c3d58SStefano Zampini PetscBool flg; 25637a3c3d58SStefano Zampini 25649566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 25659566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 25667a3c3d58SStefano Zampini } 25679566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 256869f65d41SStefano Zampini PetscFunctionReturn(0); 256969f65d41SStefano Zampini } 257069f65d41SStefano Zampini 2571d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2572d71ae5a4SJacob Faibussowitsch { 257369f65d41SStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 257469f65d41SStefano Zampini Mat_SeqDense *b = (Mat_SeqDense *)B->data; 257569f65d41SStefano Zampini Mat_SeqDense *c = (Mat_SeqDense *)C->data; 25766718818eSStefano Zampini const PetscScalar *av, *bv; 25776718818eSStefano Zampini PetscScalar *cv; 257869f65d41SStefano Zampini PetscBLASInt m, n, k; 257969f65d41SStefano Zampini PetscScalar _DOne = 1.0, _DZero = 0.0; 258069f65d41SStefano Zampini 258169f65d41SStefano Zampini PetscFunctionBegin; 25829566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 25839566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 25849566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 258549d0e964SStefano Zampini if (!m || !n || !k) PetscFunctionReturn(0); 25869566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 25879566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 25889566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2589792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("N", "T", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 25909566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 25919566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 25929566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 25939566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 259469f65d41SStefano Zampini PetscFunctionReturn(0); 259569f65d41SStefano Zampini } 259669f65d41SStefano Zampini 2597d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2598d71ae5a4SJacob Faibussowitsch { 2599d0f46423SBarry Smith PetscInt m = A->cmap->n, n = B->cmap->n; 260047d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 2601a9fe9ddaSSatish Balay 2602ee16a9a1SHong Zhang PetscFunctionBegin; 26039566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 260447d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 26059566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 260647d993e7Ssuyashtn #endif 260747d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 260847d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 260947d993e7Ssuyashtn #endif 26107a3c3d58SStefano Zampini if (!cisdense) { 26117a3c3d58SStefano Zampini PetscBool flg; 26127a3c3d58SStefano Zampini 26139566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 26149566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 26157a3c3d58SStefano Zampini } 26169566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 2617ee16a9a1SHong Zhang PetscFunctionReturn(0); 2618ee16a9a1SHong Zhang } 2619a9fe9ddaSSatish Balay 2620d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2621d71ae5a4SJacob Faibussowitsch { 2622a9fe9ddaSSatish Balay Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2623a9fe9ddaSSatish Balay Mat_SeqDense *b = (Mat_SeqDense *)B->data; 2624a9fe9ddaSSatish Balay Mat_SeqDense *c = (Mat_SeqDense *)C->data; 26256718818eSStefano Zampini const PetscScalar *av, *bv; 26266718818eSStefano Zampini PetscScalar *cv; 26270805154bSBarry Smith PetscBLASInt m, n, k; 2628a9fe9ddaSSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 2629a9fe9ddaSSatish Balay 2630a9fe9ddaSSatish Balay PetscFunctionBegin; 26319566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 26329566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 26339566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &k)); 263449d0e964SStefano Zampini if (!m || !n || !k) PetscFunctionReturn(0); 26359566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 26369566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 26379566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2638792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("T", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 26399566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 26409566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 26419566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 26429566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 2643a9fe9ddaSSatish Balay PetscFunctionReturn(0); 2644a9fe9ddaSSatish Balay } 2645985db425SBarry Smith 26464222ddf1SHong Zhang /* ----------------------------------------------- */ 2647d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C) 2648d71ae5a4SJacob Faibussowitsch { 26494222ddf1SHong Zhang PetscFunctionBegin; 26504222ddf1SHong Zhang C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense; 26514222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AB; 26524222ddf1SHong Zhang PetscFunctionReturn(0); 26534222ddf1SHong Zhang } 26544222ddf1SHong Zhang 2655d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C) 2656d71ae5a4SJacob Faibussowitsch { 26574222ddf1SHong Zhang PetscFunctionBegin; 26584222ddf1SHong Zhang C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense; 26594222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AtB; 26604222ddf1SHong Zhang PetscFunctionReturn(0); 26614222ddf1SHong Zhang } 26624222ddf1SHong Zhang 2663d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C) 2664d71ae5a4SJacob Faibussowitsch { 26654222ddf1SHong Zhang PetscFunctionBegin; 26664222ddf1SHong Zhang C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense; 26674222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_ABt; 26684222ddf1SHong Zhang PetscFunctionReturn(0); 26694222ddf1SHong Zhang } 26704222ddf1SHong Zhang 2671d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C) 2672d71ae5a4SJacob Faibussowitsch { 26734222ddf1SHong Zhang Mat_Product *product = C->product; 26744222ddf1SHong Zhang 26754222ddf1SHong Zhang PetscFunctionBegin; 26764222ddf1SHong Zhang switch (product->type) { 2677d71ae5a4SJacob Faibussowitsch case MATPRODUCT_AB: 2678d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_AB(C)); 2679d71ae5a4SJacob Faibussowitsch break; 2680d71ae5a4SJacob Faibussowitsch case MATPRODUCT_AtB: 2681d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_AtB(C)); 2682d71ae5a4SJacob Faibussowitsch break; 2683d71ae5a4SJacob Faibussowitsch case MATPRODUCT_ABt: 2684d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_ABt(C)); 2685d71ae5a4SJacob Faibussowitsch break; 2686d71ae5a4SJacob Faibussowitsch default: 2687d71ae5a4SJacob Faibussowitsch break; 26884222ddf1SHong Zhang } 26894222ddf1SHong Zhang PetscFunctionReturn(0); 26904222ddf1SHong Zhang } 26914222ddf1SHong Zhang /* ----------------------------------------------- */ 26924222ddf1SHong Zhang 2693d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMax_SeqDense(Mat A, Vec v, PetscInt idx[]) 2694d71ae5a4SJacob Faibussowitsch { 2695985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2696d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2697985db425SBarry Smith PetscScalar *x; 2698ca15aa20SStefano Zampini const PetscScalar *aa; 2699985db425SBarry Smith 2700985db425SBarry Smith PetscFunctionBegin; 270128b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 27029566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 27039566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 27049566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 270508401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2706985db425SBarry Smith for (i = 0; i < m; i++) { 27079371c9d4SSatish Balay x[i] = aa[i]; 27089371c9d4SSatish Balay if (idx) idx[i] = 0; 2709985db425SBarry Smith for (j = 1; j < n; j++) { 27109371c9d4SSatish Balay if (PetscRealPart(x[i]) < PetscRealPart(aa[i + a->lda * j])) { 27119371c9d4SSatish Balay x[i] = aa[i + a->lda * j]; 27129371c9d4SSatish Balay if (idx) idx[i] = j; 27139371c9d4SSatish Balay } 2714985db425SBarry Smith } 2715985db425SBarry Smith } 27169566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 27179566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 2718985db425SBarry Smith PetscFunctionReturn(0); 2719985db425SBarry Smith } 2720985db425SBarry Smith 2721d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A, Vec v, PetscInt idx[]) 2722d71ae5a4SJacob Faibussowitsch { 2723985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2724d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2725985db425SBarry Smith PetscScalar *x; 2726985db425SBarry Smith PetscReal atmp; 2727ca15aa20SStefano Zampini const PetscScalar *aa; 2728985db425SBarry Smith 2729985db425SBarry Smith PetscFunctionBegin; 273028b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 27319566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 27329566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 27339566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 273408401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2735985db425SBarry Smith for (i = 0; i < m; i++) { 27369189402eSHong Zhang x[i] = PetscAbsScalar(aa[i]); 2737985db425SBarry Smith for (j = 1; j < n; j++) { 2738ca15aa20SStefano Zampini atmp = PetscAbsScalar(aa[i + a->lda * j]); 27399371c9d4SSatish Balay if (PetscAbsScalar(x[i]) < atmp) { 27409371c9d4SSatish Balay x[i] = atmp; 27419371c9d4SSatish Balay if (idx) idx[i] = j; 27429371c9d4SSatish Balay } 2743985db425SBarry Smith } 2744985db425SBarry Smith } 27459566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 27469566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 2747985db425SBarry Smith PetscFunctionReturn(0); 2748985db425SBarry Smith } 2749985db425SBarry Smith 2750d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMin_SeqDense(Mat A, Vec v, PetscInt idx[]) 2751d71ae5a4SJacob Faibussowitsch { 2752985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2753d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2754985db425SBarry Smith PetscScalar *x; 2755ca15aa20SStefano Zampini const PetscScalar *aa; 2756985db425SBarry Smith 2757985db425SBarry Smith PetscFunctionBegin; 275828b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 27599566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 27609566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 27619566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 276208401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2763985db425SBarry Smith for (i = 0; i < m; i++) { 27649371c9d4SSatish Balay x[i] = aa[i]; 27659371c9d4SSatish Balay if (idx) idx[i] = 0; 2766985db425SBarry Smith for (j = 1; j < n; j++) { 27679371c9d4SSatish Balay if (PetscRealPart(x[i]) > PetscRealPart(aa[i + a->lda * j])) { 27689371c9d4SSatish Balay x[i] = aa[i + a->lda * j]; 27699371c9d4SSatish Balay if (idx) idx[i] = j; 27709371c9d4SSatish Balay } 2771985db425SBarry Smith } 2772985db425SBarry Smith } 27739566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 27749566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 2775985db425SBarry Smith PetscFunctionReturn(0); 2776985db425SBarry Smith } 2777985db425SBarry Smith 2778d71ae5a4SJacob Faibussowitsch PetscErrorCode MatGetColumnVector_SeqDense(Mat A, Vec v, PetscInt col) 2779d71ae5a4SJacob Faibussowitsch { 27808d0534beSBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 27818d0534beSBarry Smith PetscScalar *x; 2782ca15aa20SStefano Zampini const PetscScalar *aa; 27838d0534beSBarry Smith 27848d0534beSBarry Smith PetscFunctionBegin; 278528b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 27869566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 27879566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 27889566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(x, aa + col * a->lda, A->rmap->n)); 27899566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 27909566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 27918d0534beSBarry Smith PetscFunctionReturn(0); 27928d0534beSBarry Smith } 27938d0534beSBarry Smith 2794d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatGetColumnReductions_SeqDense(Mat A, PetscInt type, PetscReal *reductions) 2795d71ae5a4SJacob Faibussowitsch { 27960716a85fSBarry Smith PetscInt i, j, m, n; 27971683a169SBarry Smith const PetscScalar *a; 27980716a85fSBarry Smith 27990716a85fSBarry Smith PetscFunctionBegin; 28009566063dSJacob Faibussowitsch PetscCall(MatGetSize(A, &m, &n)); 28019566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(reductions, n)); 28029566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &a)); 2803857cbf51SRichard Tran Mills if (type == NORM_2) { 28040716a85fSBarry Smith for (i = 0; i < n; i++) { 2805ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j] * a[j]); 28060716a85fSBarry Smith a += m; 28070716a85fSBarry Smith } 2808857cbf51SRichard Tran Mills } else if (type == NORM_1) { 28090716a85fSBarry Smith for (i = 0; i < n; i++) { 2810ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j]); 28110716a85fSBarry Smith a += m; 28120716a85fSBarry Smith } 2813857cbf51SRichard Tran Mills } else if (type == NORM_INFINITY) { 28140716a85fSBarry Smith for (i = 0; i < n; i++) { 2815ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] = PetscMax(PetscAbsScalar(a[j]), reductions[i]); 28160716a85fSBarry Smith a += m; 28170716a85fSBarry Smith } 2818857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_REALPART || type == REDUCTION_MEAN_REALPART) { 2819a873a8cdSSam Reynolds for (i = 0; i < n; i++) { 2820ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscRealPart(a[j]); 2821a873a8cdSSam Reynolds a += m; 2822a873a8cdSSam Reynolds } 2823857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_IMAGINARYPART || type == REDUCTION_MEAN_IMAGINARYPART) { 2824857cbf51SRichard Tran Mills for (i = 0; i < n; i++) { 2825ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscImaginaryPart(a[j]); 2826857cbf51SRichard Tran Mills a += m; 2827857cbf51SRichard Tran Mills } 2828857cbf51SRichard Tran Mills } else SETERRQ(PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Unknown reduction type"); 28299566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &a)); 2830857cbf51SRichard Tran Mills if (type == NORM_2) { 2831a873a8cdSSam Reynolds for (i = 0; i < n; i++) reductions[i] = PetscSqrtReal(reductions[i]); 2832857cbf51SRichard Tran Mills } else if (type == REDUCTION_MEAN_REALPART || type == REDUCTION_MEAN_IMAGINARYPART) { 2833a873a8cdSSam Reynolds for (i = 0; i < n; i++) reductions[i] /= m; 28340716a85fSBarry Smith } 28350716a85fSBarry Smith PetscFunctionReturn(0); 28360716a85fSBarry Smith } 28370716a85fSBarry Smith 2838d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetRandom_SeqDense(Mat x, PetscRandom rctx) 2839d71ae5a4SJacob Faibussowitsch { 284073a71a0fSBarry Smith PetscScalar *a; 2841637a0070SStefano Zampini PetscInt lda, m, n, i, j; 284273a71a0fSBarry Smith 284373a71a0fSBarry Smith PetscFunctionBegin; 28449566063dSJacob Faibussowitsch PetscCall(MatGetSize(x, &m, &n)); 28459566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(x, &lda)); 28463faff063SStefano Zampini PetscCall(MatDenseGetArrayWrite(x, &a)); 2847637a0070SStefano Zampini for (j = 0; j < n; j++) { 284848a46eb9SPierre Jolivet for (i = 0; i < m; i++) PetscCall(PetscRandomGetValue(rctx, a + j * lda + i)); 284973a71a0fSBarry Smith } 28503faff063SStefano Zampini PetscCall(MatDenseRestoreArrayWrite(x, &a)); 285173a71a0fSBarry Smith PetscFunctionReturn(0); 285273a71a0fSBarry Smith } 285373a71a0fSBarry Smith 2854d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A, PetscBool *missing, PetscInt *d) 2855d71ae5a4SJacob Faibussowitsch { 28563b49f96aSBarry Smith PetscFunctionBegin; 28573b49f96aSBarry Smith *missing = PETSC_FALSE; 28583b49f96aSBarry Smith PetscFunctionReturn(0); 28593b49f96aSBarry Smith } 286073a71a0fSBarry Smith 2861ca15aa20SStefano Zampini /* vals is not const */ 2862d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A, PetscInt col, PetscScalar **vals) 2863d71ae5a4SJacob Faibussowitsch { 286486aefd0dSHong Zhang Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2865ca15aa20SStefano Zampini PetscScalar *v; 286686aefd0dSHong Zhang 286786aefd0dSHong Zhang PetscFunctionBegin; 286828b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 28699566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 2870ca15aa20SStefano Zampini *vals = v + col * a->lda; 28719566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 287286aefd0dSHong Zhang PetscFunctionReturn(0); 287386aefd0dSHong Zhang } 287486aefd0dSHong Zhang 2875d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A, PetscScalar **vals) 2876d71ae5a4SJacob Faibussowitsch { 287786aefd0dSHong Zhang PetscFunctionBegin; 2878742765d3SMatthew Knepley if (vals) *vals = NULL; /* user cannot accidentally use the array later */ 287986aefd0dSHong Zhang PetscFunctionReturn(0); 288086aefd0dSHong Zhang } 2881abc3b08eSStefano Zampini 2882289bc588SBarry Smith /* -------------------------------------------------------------------*/ 2883a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqDense, 2884905e6a2fSBarry Smith MatGetRow_SeqDense, 2885905e6a2fSBarry Smith MatRestoreRow_SeqDense, 2886905e6a2fSBarry Smith MatMult_SeqDense, 288797304618SKris Buschelman /* 4*/ MatMultAdd_SeqDense, 28887c922b88SBarry Smith MatMultTranspose_SeqDense, 28897c922b88SBarry Smith MatMultTransposeAdd_SeqDense, 2890f4259b30SLisandro Dalcin NULL, 2891f4259b30SLisandro Dalcin NULL, 2892f4259b30SLisandro Dalcin NULL, 2893f4259b30SLisandro Dalcin /* 10*/ NULL, 2894905e6a2fSBarry Smith MatLUFactor_SeqDense, 2895905e6a2fSBarry Smith MatCholeskyFactor_SeqDense, 289641f059aeSBarry Smith MatSOR_SeqDense, 2897ec8511deSBarry Smith MatTranspose_SeqDense, 289897304618SKris Buschelman /* 15*/ MatGetInfo_SeqDense, 2899905e6a2fSBarry Smith MatEqual_SeqDense, 2900905e6a2fSBarry Smith MatGetDiagonal_SeqDense, 2901905e6a2fSBarry Smith MatDiagonalScale_SeqDense, 2902905e6a2fSBarry Smith MatNorm_SeqDense, 2903c0aa2d19SHong Zhang /* 20*/ MatAssemblyBegin_SeqDense, 2904c0aa2d19SHong Zhang MatAssemblyEnd_SeqDense, 2905905e6a2fSBarry Smith MatSetOption_SeqDense, 2906905e6a2fSBarry Smith MatZeroEntries_SeqDense, 2907d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqDense, 2908f4259b30SLisandro Dalcin NULL, 2909f4259b30SLisandro Dalcin NULL, 2910f4259b30SLisandro Dalcin NULL, 2911f4259b30SLisandro Dalcin NULL, 29124994cf47SJed Brown /* 29*/ MatSetUp_SeqDense, 2913f4259b30SLisandro Dalcin NULL, 2914f4259b30SLisandro Dalcin NULL, 2915f4259b30SLisandro Dalcin NULL, 2916f4259b30SLisandro Dalcin NULL, 2917d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqDense, 2918f4259b30SLisandro Dalcin NULL, 2919f4259b30SLisandro Dalcin NULL, 2920f4259b30SLisandro Dalcin NULL, 2921f4259b30SLisandro Dalcin NULL, 2922d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqDense, 29237dae84e0SHong Zhang MatCreateSubMatrices_SeqDense, 2924f4259b30SLisandro Dalcin NULL, 29254b0e389bSBarry Smith MatGetValues_SeqDense, 2926a5ae1ecdSBarry Smith MatCopy_SeqDense, 2927d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqDense, 2928a5ae1ecdSBarry Smith MatScale_SeqDense, 29292f605a99SJose E. Roman MatShift_SeqDense, 2930f4259b30SLisandro Dalcin NULL, 29313f49a652SStefano Zampini MatZeroRowsColumns_SeqDense, 293273a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqDense, 2933f4259b30SLisandro Dalcin NULL, 2934f4259b30SLisandro Dalcin NULL, 2935f4259b30SLisandro Dalcin NULL, 2936f4259b30SLisandro Dalcin NULL, 2937f4259b30SLisandro Dalcin /* 54*/ NULL, 2938f4259b30SLisandro Dalcin NULL, 2939f4259b30SLisandro Dalcin NULL, 2940f4259b30SLisandro Dalcin NULL, 2941f4259b30SLisandro Dalcin NULL, 2942023c16fcSToby Isaac /* 59*/ MatCreateSubMatrix_SeqDense, 2943e03a110bSBarry Smith MatDestroy_SeqDense, 2944e03a110bSBarry Smith MatView_SeqDense, 2945f4259b30SLisandro Dalcin NULL, 2946f4259b30SLisandro Dalcin NULL, 2947f4259b30SLisandro Dalcin /* 64*/ NULL, 2948f4259b30SLisandro Dalcin NULL, 2949f4259b30SLisandro Dalcin NULL, 2950f4259b30SLisandro Dalcin NULL, 2951f4259b30SLisandro Dalcin NULL, 2952d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqDense, 2953f4259b30SLisandro Dalcin NULL, 2954f4259b30SLisandro Dalcin NULL, 2955f4259b30SLisandro Dalcin NULL, 2956f4259b30SLisandro Dalcin NULL, 2957f4259b30SLisandro Dalcin /* 74*/ NULL, 2958f4259b30SLisandro Dalcin NULL, 2959f4259b30SLisandro Dalcin NULL, 2960f4259b30SLisandro Dalcin NULL, 2961f4259b30SLisandro Dalcin NULL, 2962f4259b30SLisandro Dalcin /* 79*/ NULL, 2963f4259b30SLisandro Dalcin NULL, 2964f4259b30SLisandro Dalcin NULL, 2965f4259b30SLisandro Dalcin NULL, 29665bba2384SShri Abhyankar /* 83*/ MatLoad_SeqDense, 2967637a0070SStefano Zampini MatIsSymmetric_SeqDense, 29681cbb95d3SBarry Smith MatIsHermitian_SeqDense, 2969f4259b30SLisandro Dalcin NULL, 2970f4259b30SLisandro Dalcin NULL, 2971f4259b30SLisandro Dalcin NULL, 2972f4259b30SLisandro Dalcin /* 89*/ NULL, 2973f4259b30SLisandro Dalcin NULL, 2974a9fe9ddaSSatish Balay MatMatMultNumeric_SeqDense_SeqDense, 2975f4259b30SLisandro Dalcin NULL, 2976f4259b30SLisandro Dalcin NULL, 2977f4259b30SLisandro Dalcin /* 94*/ NULL, 2978f4259b30SLisandro Dalcin NULL, 2979f4259b30SLisandro Dalcin NULL, 298069f65d41SStefano Zampini MatMatTransposeMultNumeric_SeqDense_SeqDense, 2981f4259b30SLisandro Dalcin NULL, 29824222ddf1SHong Zhang /* 99*/ MatProductSetFromOptions_SeqDense, 2983f4259b30SLisandro Dalcin NULL, 2984f4259b30SLisandro Dalcin NULL, 2985ba337c44SJed Brown MatConjugate_SeqDense, 2986f4259b30SLisandro Dalcin NULL, 2987f4259b30SLisandro Dalcin /*104*/ NULL, 2988ba337c44SJed Brown MatRealPart_SeqDense, 2989ba337c44SJed Brown MatImaginaryPart_SeqDense, 2990f4259b30SLisandro Dalcin NULL, 2991f4259b30SLisandro Dalcin NULL, 2992f4259b30SLisandro Dalcin /*109*/ NULL, 2993f4259b30SLisandro Dalcin NULL, 29948d0534beSBarry Smith MatGetRowMin_SeqDense, 2995aabbc4fbSShri Abhyankar MatGetColumnVector_SeqDense, 29963b49f96aSBarry Smith MatMissingDiagonal_SeqDense, 2997f4259b30SLisandro Dalcin /*114*/ NULL, 2998f4259b30SLisandro Dalcin NULL, 2999f4259b30SLisandro Dalcin NULL, 3000f4259b30SLisandro Dalcin NULL, 3001f4259b30SLisandro Dalcin NULL, 3002f4259b30SLisandro Dalcin /*119*/ NULL, 3003f4259b30SLisandro Dalcin NULL, 3004f4259b30SLisandro Dalcin NULL, 3005f4259b30SLisandro Dalcin NULL, 3006f4259b30SLisandro Dalcin NULL, 3007f4259b30SLisandro Dalcin /*124*/ NULL, 3008a873a8cdSSam Reynolds MatGetColumnReductions_SeqDense, 3009f4259b30SLisandro Dalcin NULL, 3010f4259b30SLisandro Dalcin NULL, 3011f4259b30SLisandro Dalcin NULL, 3012f4259b30SLisandro Dalcin /*129*/ NULL, 3013f4259b30SLisandro Dalcin NULL, 3014f4259b30SLisandro Dalcin NULL, 301575648e8dSHong Zhang MatTransposeMatMultNumeric_SeqDense_SeqDense, 3016f4259b30SLisandro Dalcin NULL, 3017f4259b30SLisandro Dalcin /*134*/ NULL, 3018f4259b30SLisandro Dalcin NULL, 3019f4259b30SLisandro Dalcin NULL, 3020f4259b30SLisandro Dalcin NULL, 3021f4259b30SLisandro Dalcin NULL, 3022f4259b30SLisandro Dalcin /*139*/ NULL, 3023f4259b30SLisandro Dalcin NULL, 3024f4259b30SLisandro Dalcin NULL, 3025f4259b30SLisandro Dalcin NULL, 3026f4259b30SLisandro Dalcin NULL, 30274222ddf1SHong Zhang MatCreateMPIMatConcatenateSeqMat_SeqDense, 3028f4259b30SLisandro Dalcin /*145*/ NULL, 3029f4259b30SLisandro Dalcin NULL, 303099a7f59eSMark Adams NULL, 303199a7f59eSMark Adams NULL, 30327fb60732SBarry Smith NULL, 3033*dec0b466SHong Zhang /*150*/ NULL, 3034*dec0b466SHong Zhang NULL}; 303590ace30eSBarry Smith 30364b828684SBarry Smith /*@C 303711a5261eSBarry Smith MatCreateSeqDense - Creates a `MATSEQDENSE` that 3038d65003e9SLois Curfman McInnes is stored in column major order (the usual Fortran 77 manner). Many 3039d65003e9SLois Curfman McInnes of the matrix operations use the BLAS and LAPACK routines. 3040289bc588SBarry Smith 3041d083f849SBarry Smith Collective 3042db81eaa0SLois Curfman McInnes 304320563c6bSBarry Smith Input Parameters: 304411a5261eSBarry Smith + comm - MPI communicator, set to `PETSC_COMM_SELF` 30450c775827SLois Curfman McInnes . m - number of rows 304618f449edSLois Curfman McInnes . n - number of columns 30470298fd71SBarry Smith - data - optional location of matrix data in column major order. Set data=NULL for PETSc 3048dfc5480cSLois Curfman McInnes to control all matrix memory allocation. 304920563c6bSBarry Smith 305020563c6bSBarry Smith Output Parameter: 305144cd7ae7SLois Curfman McInnes . A - the matrix 305220563c6bSBarry Smith 305311a5261eSBarry Smith Note: 305418f449edSLois Curfman McInnes The data input variable is intended primarily for Fortran programmers 305518f449edSLois Curfman McInnes who wish to allocate their own matrix memory space. Most users should 30560298fd71SBarry Smith set data=NULL. 305718f449edSLois Curfman McInnes 3058027ccd11SLois Curfman McInnes Level: intermediate 3059027ccd11SLois Curfman McInnes 306011a5261eSBarry Smith .seealso: `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()` 306120563c6bSBarry Smith @*/ 3062d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateSeqDense(MPI_Comm comm, PetscInt m, PetscInt n, PetscScalar *data, Mat *A) 3063d71ae5a4SJacob Faibussowitsch { 30643a40ed3dSBarry Smith PetscFunctionBegin; 30659566063dSJacob Faibussowitsch PetscCall(MatCreate(comm, A)); 30669566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*A, m, n, m, n)); 30679566063dSJacob Faibussowitsch PetscCall(MatSetType(*A, MATSEQDENSE)); 30689566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(*A, data)); 3069273d9f13SBarry Smith PetscFunctionReturn(0); 3070273d9f13SBarry Smith } 3071273d9f13SBarry Smith 3072273d9f13SBarry Smith /*@C 307311a5261eSBarry Smith MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements of a `MATSEQDENSE` matrix 3074273d9f13SBarry Smith 3075d083f849SBarry Smith Collective 3076273d9f13SBarry Smith 3077273d9f13SBarry Smith Input Parameters: 30781c4f3114SJed Brown + B - the matrix 30790298fd71SBarry Smith - data - the array (or NULL) 3080273d9f13SBarry Smith 308111a5261eSBarry Smith Note: 3082273d9f13SBarry Smith The data input variable is intended primarily for Fortran programmers 3083273d9f13SBarry Smith who wish to allocate their own matrix memory space. Most users should 3084284134d9SBarry Smith need not call this routine. 3085273d9f13SBarry Smith 3086273d9f13SBarry Smith Level: intermediate 3087273d9f13SBarry Smith 308811a5261eSBarry Smith .seealso: `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()`, `MatDenseSetLDA()` 3089273d9f13SBarry Smith @*/ 3090d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation(Mat B, PetscScalar data[]) 3091d71ae5a4SJacob Faibussowitsch { 3092a23d5eceSKris Buschelman PetscFunctionBegin; 3093d5ea218eSStefano Zampini PetscValidHeaderSpecific(B, MAT_CLASSID, 1); 3094cac4c232SBarry Smith PetscTryMethod(B, "MatSeqDenseSetPreallocation_C", (Mat, PetscScalar[]), (B, data)); 3095a23d5eceSKris Buschelman PetscFunctionReturn(0); 3096a23d5eceSKris Buschelman } 3097a23d5eceSKris Buschelman 3098d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation_SeqDense(Mat B, PetscScalar *data) 3099d71ae5a4SJacob Faibussowitsch { 3100ad16ce7aSStefano Zampini Mat_SeqDense *b = (Mat_SeqDense *)B->data; 3101273d9f13SBarry Smith 3102273d9f13SBarry Smith PetscFunctionBegin; 310328b400f6SJacob Faibussowitsch PetscCheck(!b->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3104273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 3105a868139aSShri Abhyankar 31069566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(B->rmap)); 31079566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(B->cmap)); 310834ef9618SShri Abhyankar 3109ad16ce7aSStefano Zampini if (b->lda <= 0) b->lda = B->rmap->n; 311086d161a7SShri Abhyankar 31119e8f95c4SLisandro Dalcin if (!data) { /* petsc-allocated storage */ 31129566063dSJacob Faibussowitsch if (!b->user_alloc) PetscCall(PetscFree(b->v)); 31139566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((size_t)b->lda * B->cmap->n, &b->v)); 31142205254eSKarl Rupp 31159e8f95c4SLisandro Dalcin b->user_alloc = PETSC_FALSE; 3116273d9f13SBarry Smith } else { /* user-allocated storage */ 31179566063dSJacob Faibussowitsch if (!b->user_alloc) PetscCall(PetscFree(b->v)); 3118273d9f13SBarry Smith b->v = data; 3119273d9f13SBarry Smith b->user_alloc = PETSC_TRUE; 3120273d9f13SBarry Smith } 31210450473dSBarry Smith B->assembled = PETSC_TRUE; 3122273d9f13SBarry Smith PetscFunctionReturn(0); 3123273d9f13SBarry Smith } 3124273d9f13SBarry Smith 312565b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 3126d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) 3127d71ae5a4SJacob Faibussowitsch { 3128d77f618aSHong Zhang Mat mat_elemental; 31291683a169SBarry Smith const PetscScalar *array; 31301683a169SBarry Smith PetscScalar *v_colwise; 3131d77f618aSHong Zhang PetscInt M = A->rmap->N, N = A->cmap->N, i, j, k, *rows, *cols; 3132d77f618aSHong Zhang 31338baccfbdSHong Zhang PetscFunctionBegin; 31349566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(M * N, &v_colwise, M, &rows, N, &cols)); 31359566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &array)); 3136d77f618aSHong Zhang /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */ 3137d77f618aSHong Zhang k = 0; 3138d77f618aSHong Zhang for (j = 0; j < N; j++) { 3139d77f618aSHong Zhang cols[j] = j; 3140ad540459SPierre Jolivet for (i = 0; i < M; i++) v_colwise[j * M + i] = array[k++]; 3141d77f618aSHong Zhang } 3142ad540459SPierre Jolivet for (i = 0; i < M; i++) rows[i] = i; 31439566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &array)); 3144d77f618aSHong Zhang 31459566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental)); 31469566063dSJacob Faibussowitsch PetscCall(MatSetSizes(mat_elemental, PETSC_DECIDE, PETSC_DECIDE, M, N)); 31479566063dSJacob Faibussowitsch PetscCall(MatSetType(mat_elemental, MATELEMENTAL)); 31489566063dSJacob Faibussowitsch PetscCall(MatSetUp(mat_elemental)); 3149d77f618aSHong Zhang 3150d77f618aSHong Zhang /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */ 31519566063dSJacob Faibussowitsch PetscCall(MatSetValues(mat_elemental, M, rows, N, cols, v_colwise, ADD_VALUES)); 31529566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY)); 31539566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY)); 31549566063dSJacob Faibussowitsch PetscCall(PetscFree3(v_colwise, rows, cols)); 3155d77f618aSHong Zhang 3156511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 31579566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A, &mat_elemental)); 3158d77f618aSHong Zhang } else { 3159d77f618aSHong Zhang *newmat = mat_elemental; 3160d77f618aSHong Zhang } 31618baccfbdSHong Zhang PetscFunctionReturn(0); 31628baccfbdSHong Zhang } 316365b80a83SHong Zhang #endif 31648baccfbdSHong Zhang 3165d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA_SeqDense(Mat B, PetscInt lda) 3166d71ae5a4SJacob Faibussowitsch { 31671b807ce4Svictorle Mat_SeqDense *b = (Mat_SeqDense *)B->data; 31687422da62SJose E. Roman PetscBool data; 316921a2c019SBarry Smith 31701b807ce4Svictorle PetscFunctionBegin; 31717422da62SJose E. Roman data = (PetscBool)((B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE); 3172aed4548fSBarry Smith PetscCheck(b->user_alloc || !data || b->lda == lda, PETSC_COMM_SELF, PETSC_ERR_ORDER, "LDA cannot be changed after allocation of internal storage"); 317308401ef6SPierre 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); 31741b807ce4Svictorle b->lda = lda; 31751b807ce4Svictorle PetscFunctionReturn(0); 31761b807ce4Svictorle } 31771b807ce4Svictorle 3178d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm, Mat inmat, PetscInt n, MatReuse scall, Mat *outmat) 3179d71ae5a4SJacob Faibussowitsch { 3180d528f656SJakub Kruzik PetscFunctionBegin; 31819566063dSJacob Faibussowitsch PetscCall(MatCreateMPIMatConcatenateSeqMat_MPIDense(comm, inmat, n, scall, outmat)); 3182d528f656SJakub Kruzik PetscFunctionReturn(0); 3183d528f656SJakub Kruzik } 3184d528f656SJakub Kruzik 3185d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A, PetscInt col, Vec *v) 3186d71ae5a4SJacob Faibussowitsch { 31876947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 31886947451fSStefano Zampini 31896947451fSStefano Zampini PetscFunctionBegin; 319028b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 319128b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 31924dfa11a4SJacob Faibussowitsch if (!a->cvec) { PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec)); } 31936947451fSStefano Zampini a->vecinuse = col + 1; 31949566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, (PetscScalar **)&a->ptrinuse)); 31959566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda)); 31966947451fSStefano Zampini *v = a->cvec; 31976947451fSStefano Zampini PetscFunctionReturn(0); 31986947451fSStefano Zampini } 31996947451fSStefano Zampini 3200d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A, PetscInt col, Vec *v) 3201d71ae5a4SJacob Faibussowitsch { 32026947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 32036947451fSStefano Zampini 32046947451fSStefano Zampini PetscFunctionBegin; 320528b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 320628b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 32076947451fSStefano Zampini a->vecinuse = 0; 32089566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, (PetscScalar **)&a->ptrinuse)); 32099566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 321075f6d85dSStefano Zampini if (v) *v = NULL; 32116947451fSStefano Zampini PetscFunctionReturn(0); 32126947451fSStefano Zampini } 32136947451fSStefano Zampini 3214d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v) 3215d71ae5a4SJacob Faibussowitsch { 32166947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 32176947451fSStefano Zampini 32186947451fSStefano Zampini PetscFunctionBegin; 321928b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 322028b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 32214dfa11a4SJacob Faibussowitsch if (!a->cvec) { PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec)); } 32226947451fSStefano Zampini a->vecinuse = col + 1; 32239566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &a->ptrinuse)); 32249566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda)); 32259566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(a->cvec)); 32266947451fSStefano Zampini *v = a->cvec; 32276947451fSStefano Zampini PetscFunctionReturn(0); 32286947451fSStefano Zampini } 32296947451fSStefano Zampini 3230d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v) 3231d71ae5a4SJacob Faibussowitsch { 32326947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 32336947451fSStefano Zampini 32346947451fSStefano Zampini PetscFunctionBegin; 323528b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 323628b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 32376947451fSStefano Zampini a->vecinuse = 0; 32389566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &a->ptrinuse)); 32399566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(a->cvec)); 32409566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 324175f6d85dSStefano Zampini if (v) *v = NULL; 32426947451fSStefano Zampini PetscFunctionReturn(0); 32436947451fSStefano Zampini } 32446947451fSStefano Zampini 3245d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v) 3246d71ae5a4SJacob Faibussowitsch { 32476947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 32486947451fSStefano Zampini 32496947451fSStefano Zampini PetscFunctionBegin; 325028b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 325128b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 32524dfa11a4SJacob Faibussowitsch if (!a->cvec) { PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec)); } 32536947451fSStefano Zampini a->vecinuse = col + 1; 32549566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(A, (PetscScalar **)&a->ptrinuse)); 32559566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda)); 32566947451fSStefano Zampini *v = a->cvec; 32576947451fSStefano Zampini PetscFunctionReturn(0); 32586947451fSStefano Zampini } 32596947451fSStefano Zampini 3260d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v) 3261d71ae5a4SJacob Faibussowitsch { 32626947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 32636947451fSStefano Zampini 32646947451fSStefano Zampini PetscFunctionBegin; 326528b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 326628b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 32676947451fSStefano Zampini a->vecinuse = 0; 32689566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(A, (PetscScalar **)&a->ptrinuse)); 32699566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 327075f6d85dSStefano Zampini if (v) *v = NULL; 32716947451fSStefano Zampini PetscFunctionReturn(0); 32726947451fSStefano Zampini } 32736947451fSStefano Zampini 3274d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) 3275d71ae5a4SJacob Faibussowitsch { 32765ea7661aSPierre Jolivet Mat_SeqDense *a = (Mat_SeqDense *)A->data; 32775ea7661aSPierre Jolivet 32785ea7661aSPierre Jolivet PetscFunctionBegin; 327928b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 328028b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3281a2748737SPierre Jolivet if (a->cmat && (cend - cbegin != a->cmat->cmap->N || rend - rbegin != a->cmat->rmap->N)) PetscCall(MatDestroy(&a->cmat)); 32825ea7661aSPierre Jolivet if (!a->cmat) { 3283a2748737SPierre Jolivet PetscCall(MatCreateDense(PetscObjectComm((PetscObject)A), rend - rbegin, PETSC_DECIDE, rend - rbegin, cend - cbegin, a->v + rbegin + (size_t)cbegin * a->lda, &a->cmat)); 32845ea7661aSPierre Jolivet } else { 3285a2748737SPierre Jolivet PetscCall(MatDensePlaceArray(a->cmat, a->v + rbegin + (size_t)cbegin * a->lda)); 32865ea7661aSPierre Jolivet } 32879566063dSJacob Faibussowitsch PetscCall(MatDenseSetLDA(a->cmat, a->lda)); 32885ea7661aSPierre Jolivet a->matinuse = cbegin + 1; 32895ea7661aSPierre Jolivet *v = a->cmat; 329047d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 329175f6d85dSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 329275f6d85dSStefano Zampini #endif 32935ea7661aSPierre Jolivet PetscFunctionReturn(0); 32945ea7661aSPierre Jolivet } 32955ea7661aSPierre Jolivet 3296d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A, Mat *v) 3297d71ae5a4SJacob Faibussowitsch { 32985ea7661aSPierre Jolivet Mat_SeqDense *a = (Mat_SeqDense *)A->data; 32995ea7661aSPierre Jolivet 33005ea7661aSPierre Jolivet PetscFunctionBegin; 330128b400f6SJacob Faibussowitsch PetscCheck(a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetSubMatrix() first"); 330228b400f6SJacob Faibussowitsch PetscCheck(a->cmat, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column matrix"); 330308401ef6SPierre Jolivet PetscCheck(*v == a->cmat, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not the matrix obtained from MatDenseGetSubMatrix()"); 33045ea7661aSPierre Jolivet a->matinuse = 0; 33059566063dSJacob Faibussowitsch PetscCall(MatDenseResetArray(a->cmat)); 3306742765d3SMatthew Knepley if (v) *v = NULL; 330747d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 33083faff063SStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 33093faff063SStefano Zampini #endif 33105ea7661aSPierre Jolivet PetscFunctionReturn(0); 33115ea7661aSPierre Jolivet } 33125ea7661aSPierre Jolivet 33130bad9183SKris Buschelman /*MC 3314fafad747SKris Buschelman MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices. 33150bad9183SKris Buschelman 33160bad9183SKris Buschelman Options Database Keys: 331711a5261eSBarry Smith . -mat_type seqdense - sets the matrix type to `MATSEQDENSE` during a call to `MatSetFromOptions()` 33180bad9183SKris Buschelman 33190bad9183SKris Buschelman Level: beginner 33200bad9183SKris Buschelman 332111a5261eSBarry Smith .seealso: `MATSEQDENSE`, `MatCreateSeqDense()` 33220bad9183SKris Buschelman M*/ 3323d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreate_SeqDense(Mat B) 3324d71ae5a4SJacob Faibussowitsch { 3325273d9f13SBarry Smith Mat_SeqDense *b; 33267c334f02SBarry Smith PetscMPIInt size; 3327273d9f13SBarry Smith 3328273d9f13SBarry Smith PetscFunctionBegin; 33299566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)B), &size)); 333008401ef6SPierre Jolivet PetscCheck(size <= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Comm must be of size 1"); 333155659b69SBarry Smith 33324dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&b)); 33339566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(B->ops, &MatOps_Values, sizeof(struct _MatOps))); 333444cd7ae7SLois Curfman McInnes B->data = (void *)b; 333518f449edSLois Curfman McInnes 3336273d9f13SBarry Smith b->roworiented = PETSC_TRUE; 33374e220ebcSLois Curfman McInnes 33389566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatQRFactor_C", MatQRFactor_SeqDense)); 33399566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetLDA_C", MatDenseGetLDA_SeqDense)); 33409566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseSetLDA_C", MatDenseSetLDA_SeqDense)); 33419566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArray_C", MatDenseGetArray_SeqDense)); 33429566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArray_C", MatDenseRestoreArray_SeqDense)); 33439566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDensePlaceArray_C", MatDensePlaceArray_SeqDense)); 33449566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseResetArray_C", MatDenseResetArray_SeqDense)); 33459566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseReplaceArray_C", MatDenseReplaceArray_SeqDense)); 33469566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayRead_C", MatDenseGetArray_SeqDense)); 33479566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayRead_C", MatDenseRestoreArray_SeqDense)); 33489566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayWrite_C", MatDenseGetArray_SeqDense)); 33499566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayWrite_C", MatDenseRestoreArray_SeqDense)); 33509566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqaij_C", MatConvert_SeqDense_SeqAIJ)); 33518baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 33529566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_elemental_C", MatConvert_SeqDense_Elemental)); 33538baccfbdSHong Zhang #endif 3354d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 33559566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_scalapack_C", MatConvert_Dense_ScaLAPACK)); 3356d24d4204SJose E. Roman #endif 33572bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA) 33589566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensecuda_C", MatConvert_SeqDense_SeqDenseCUDA)); 33599566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", MatProductSetFromOptions_SeqDense)); 33609566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdense_C", MatProductSetFromOptions_SeqDense)); 33619566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensecuda_C", MatProductSetFromOptions_SeqDense)); 33622bf066beSStefano Zampini #endif 336347d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 336447d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensehip_C", MatConvert_SeqDense_SeqDenseHIP)); 336547d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensehip_seqdensehip_C", MatProductSetFromOptions_SeqDense)); 336647d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensehip_seqdense_C", MatProductSetFromOptions_SeqDense)); 336747d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensehip_C", MatProductSetFromOptions_SeqDense)); 336847d993e7Ssuyashtn #endif 33699566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSeqDenseSetPreallocation_C", MatSeqDenseSetPreallocation_SeqDense)); 33709566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqaij_seqdense_C", MatProductSetFromOptions_SeqAIJ_SeqDense)); 33719566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdense_C", MatProductSetFromOptions_SeqDense)); 33729566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense)); 33739566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqsbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense)); 337496e6d5c4SRichard Tran Mills 33759566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumn_C", MatDenseGetColumn_SeqDense)); 33769566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumn_C", MatDenseRestoreColumn_SeqDense)); 33779566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVec_C", MatDenseGetColumnVec_SeqDense)); 33789566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVec_C", MatDenseRestoreColumnVec_SeqDense)); 33799566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecRead_C", MatDenseGetColumnVecRead_SeqDense)); 33809566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecRead_C", MatDenseRestoreColumnVecRead_SeqDense)); 33819566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecWrite_C", MatDenseGetColumnVecWrite_SeqDense)); 33829566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecWrite_C", MatDenseRestoreColumnVecWrite_SeqDense)); 33839566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetSubMatrix_C", MatDenseGetSubMatrix_SeqDense)); 33849566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreSubMatrix_C", MatDenseRestoreSubMatrix_SeqDense)); 33859566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)B, MATSEQDENSE)); 33863a40ed3dSBarry Smith PetscFunctionReturn(0); 3387289bc588SBarry Smith } 338886aefd0dSHong Zhang 338986aefd0dSHong Zhang /*@C 339011a5261eSBarry 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. 339186aefd0dSHong Zhang 339286aefd0dSHong Zhang Not Collective 339386aefd0dSHong Zhang 33945ea7661aSPierre Jolivet Input Parameters: 339511a5261eSBarry Smith + mat - a `MATSEQDENSE` or `MATMPIDENSE` matrix 339686aefd0dSHong Zhang - col - column index 339786aefd0dSHong Zhang 339886aefd0dSHong Zhang Output Parameter: 339986aefd0dSHong Zhang . vals - pointer to the data 340086aefd0dSHong Zhang 340186aefd0dSHong Zhang Level: intermediate 340286aefd0dSHong Zhang 340311a5261eSBarry Smith Note: 340411a5261eSBarry Smith Use `MatDenseGetColumnVec()` to get access to a column of a `MATDENSE` treated as a `Vec` 340511a5261eSBarry Smith 340611a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreColumn()`, `MatDenseGetColumnVec()` 340786aefd0dSHong Zhang @*/ 3408d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumn(Mat A, PetscInt col, PetscScalar **vals) 3409d71ae5a4SJacob Faibussowitsch { 341086aefd0dSHong Zhang PetscFunctionBegin; 3411d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3412d5ea218eSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 3413d5ea218eSStefano Zampini PetscValidPointer(vals, 3); 3414cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumn_C", (Mat, PetscInt, PetscScalar **), (A, col, vals)); 341586aefd0dSHong Zhang PetscFunctionReturn(0); 341686aefd0dSHong Zhang } 341786aefd0dSHong Zhang 341886aefd0dSHong Zhang /*@C 341911a5261eSBarry Smith MatDenseRestoreColumn - returns access to a column of a `MATDENSE` matrix which is returned by `MatDenseGetColumn()`. 342086aefd0dSHong Zhang 342186aefd0dSHong Zhang Not Collective 342286aefd0dSHong Zhang 3423742765d3SMatthew Knepley Input Parameters: 342411a5261eSBarry Smith + mat - a `MATSEQDENSE` or `MATMPIDENSE` matrix 3425742765d3SMatthew Knepley - vals - pointer to the data (may be NULL) 342686aefd0dSHong Zhang 342786aefd0dSHong Zhang Level: intermediate 342886aefd0dSHong Zhang 342911a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetColumn()` 343086aefd0dSHong Zhang @*/ 3431d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumn(Mat A, PetscScalar **vals) 3432d71ae5a4SJacob Faibussowitsch { 343386aefd0dSHong Zhang PetscFunctionBegin; 3434d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3435d5ea218eSStefano Zampini PetscValidPointer(vals, 2); 3436cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumn_C", (Mat, PetscScalar **), (A, vals)); 343786aefd0dSHong Zhang PetscFunctionReturn(0); 343886aefd0dSHong Zhang } 34396947451fSStefano Zampini 34400f74d2c1SSatish Balay /*@ 344111a5261eSBarry Smith MatDenseGetColumnVec - Gives read-write access to a column of a `MATDENSE` matrix, represented as a `Vec`. 34426947451fSStefano Zampini 34436947451fSStefano Zampini Collective 34446947451fSStefano Zampini 34455ea7661aSPierre Jolivet Input Parameters: 344611a5261eSBarry Smith + mat - the `Mat` object 34476947451fSStefano Zampini - col - the column index 34486947451fSStefano Zampini 34496947451fSStefano Zampini Output Parameter: 34506947451fSStefano Zampini . v - the vector 34516947451fSStefano Zampini 34526947451fSStefano Zampini Notes: 345311a5261eSBarry Smith The vector is owned by PETSc. Users need to call `MatDenseRestoreColumnVec()` when the vector is no longer needed. 345411a5261eSBarry Smith 345511a5261eSBarry Smith Use `MatDenseGetColumnVecRead()` to obtain read-only access or `MatDenseGetColumnVecWrite()` for write-only access. 34566947451fSStefano Zampini 34576947451fSStefano Zampini Level: intermediate 34586947451fSStefano Zampini 345947d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`, `MatDenseGetColumn()` 34606947451fSStefano Zampini @*/ 3461d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec(Mat A, PetscInt col, Vec *v) 3462d71ae5a4SJacob Faibussowitsch { 34636947451fSStefano Zampini PetscFunctionBegin; 34646947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 34656947451fSStefano Zampini PetscValidType(A, 1); 34666947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 34676947451fSStefano Zampini PetscValidPointer(v, 3); 346828b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 34692cf15c64SPierre 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); 3470cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v)); 34716947451fSStefano Zampini PetscFunctionReturn(0); 34726947451fSStefano Zampini } 34736947451fSStefano Zampini 34740f74d2c1SSatish Balay /*@ 34756947451fSStefano Zampini MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVec(). 34766947451fSStefano Zampini 34776947451fSStefano Zampini Collective 34786947451fSStefano Zampini 34795ea7661aSPierre Jolivet Input Parameters: 34806947451fSStefano Zampini + mat - the Mat object 34816947451fSStefano Zampini . col - the column index 3482742765d3SMatthew Knepley - v - the Vec object (may be NULL) 34836947451fSStefano Zampini 34846947451fSStefano Zampini Level: intermediate 34856947451fSStefano Zampini 348647d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVecRead()`,`MatDenseRestoreColumnVecWrite()` 34876947451fSStefano Zampini @*/ 3488d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec(Mat A, PetscInt col, Vec *v) 3489d71ae5a4SJacob Faibussowitsch { 34906947451fSStefano Zampini PetscFunctionBegin; 34916947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 34926947451fSStefano Zampini PetscValidType(A, 1); 34936947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 349408401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 34952cf15c64SPierre 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); 3496cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v)); 34976947451fSStefano Zampini PetscFunctionReturn(0); 34986947451fSStefano Zampini } 34996947451fSStefano Zampini 35000f74d2c1SSatish Balay /*@ 35016947451fSStefano Zampini MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a Vec. 35026947451fSStefano Zampini 35036947451fSStefano Zampini Collective 35046947451fSStefano Zampini 35055ea7661aSPierre Jolivet Input Parameters: 35066947451fSStefano Zampini + mat - the Mat object 35076947451fSStefano Zampini - col - the column index 35086947451fSStefano Zampini 35096947451fSStefano Zampini Output Parameter: 35106947451fSStefano Zampini . v - the vector 35116947451fSStefano Zampini 35126947451fSStefano Zampini Notes: 35136947451fSStefano Zampini The vector is owned by PETSc and users cannot modify it. 351411a5261eSBarry Smith 35156947451fSStefano Zampini Users need to call MatDenseRestoreColumnVecRead() when the vector is no longer needed. 351611a5261eSBarry Smith 35176947451fSStefano Zampini Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecWrite() for write-only access. 35186947451fSStefano Zampini 35196947451fSStefano Zampini Level: intermediate 35206947451fSStefano Zampini 352147d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 35226947451fSStefano Zampini @*/ 3523d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead(Mat A, PetscInt col, Vec *v) 3524d71ae5a4SJacob Faibussowitsch { 35256947451fSStefano Zampini PetscFunctionBegin; 35266947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 35276947451fSStefano Zampini PetscValidType(A, 1); 35286947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 35296947451fSStefano Zampini PetscValidPointer(v, 3); 353028b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 35312cf15c64SPierre 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); 3532cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v)); 35336947451fSStefano Zampini PetscFunctionReturn(0); 35346947451fSStefano Zampini } 35356947451fSStefano Zampini 35360f74d2c1SSatish Balay /*@ 35376947451fSStefano Zampini MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecRead(). 35386947451fSStefano Zampini 35396947451fSStefano Zampini Collective 35406947451fSStefano Zampini 35415ea7661aSPierre Jolivet Input Parameters: 35426947451fSStefano Zampini + mat - the Mat object 35436947451fSStefano Zampini . col - the column index 3544742765d3SMatthew Knepley - v - the Vec object (may be NULL) 35456947451fSStefano Zampini 35466947451fSStefano Zampini Level: intermediate 35476947451fSStefano Zampini 354847d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecWrite()` 35496947451fSStefano Zampini @*/ 3550d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead(Mat A, PetscInt col, Vec *v) 3551d71ae5a4SJacob Faibussowitsch { 35526947451fSStefano Zampini PetscFunctionBegin; 35536947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 35546947451fSStefano Zampini PetscValidType(A, 1); 35556947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 355608401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 35572cf15c64SPierre 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); 3558cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v)); 35596947451fSStefano Zampini PetscFunctionReturn(0); 35606947451fSStefano Zampini } 35616947451fSStefano Zampini 35620f74d2c1SSatish Balay /*@ 35636947451fSStefano Zampini MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a Vec. 35646947451fSStefano Zampini 35656947451fSStefano Zampini Collective 35666947451fSStefano Zampini 35675ea7661aSPierre Jolivet Input Parameters: 35686947451fSStefano Zampini + mat - the Mat object 35696947451fSStefano Zampini - col - the column index 35706947451fSStefano Zampini 35716947451fSStefano Zampini Output Parameter: 35726947451fSStefano Zampini . v - the vector 35736947451fSStefano Zampini 35746947451fSStefano Zampini Notes: 35756947451fSStefano Zampini The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVecWrite() when the vector is no longer needed. 357611a5261eSBarry Smith 35776947451fSStefano Zampini Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecRead() for read-only access. 35786947451fSStefano Zampini 35796947451fSStefano Zampini Level: intermediate 35806947451fSStefano Zampini 358147d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 35826947451fSStefano Zampini @*/ 3583d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite(Mat A, PetscInt col, Vec *v) 3584d71ae5a4SJacob Faibussowitsch { 35856947451fSStefano Zampini PetscFunctionBegin; 35866947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 35876947451fSStefano Zampini PetscValidType(A, 1); 35886947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 35896947451fSStefano Zampini PetscValidPointer(v, 3); 359028b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3591aed4548fSBarry 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); 3592cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v)); 35936947451fSStefano Zampini PetscFunctionReturn(0); 35946947451fSStefano Zampini } 35956947451fSStefano Zampini 35960f74d2c1SSatish Balay /*@ 35976947451fSStefano Zampini MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecWrite(). 35986947451fSStefano Zampini 35996947451fSStefano Zampini Collective 36006947451fSStefano Zampini 36015ea7661aSPierre Jolivet Input Parameters: 36026947451fSStefano Zampini + mat - the Mat object 36036947451fSStefano Zampini . col - the column index 3604742765d3SMatthew Knepley - v - the Vec object (may be NULL) 36056947451fSStefano Zampini 36066947451fSStefano Zampini Level: intermediate 36076947451fSStefano Zampini 360847d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`,`MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()` 36096947451fSStefano Zampini @*/ 3610d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A, PetscInt col, Vec *v) 3611d71ae5a4SJacob Faibussowitsch { 36126947451fSStefano Zampini PetscFunctionBegin; 36136947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 36146947451fSStefano Zampini PetscValidType(A, 1); 36156947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 361608401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3617aed4548fSBarry 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); 3618cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v)); 36196947451fSStefano Zampini PetscFunctionReturn(0); 36206947451fSStefano Zampini } 36215ea7661aSPierre Jolivet 36220f74d2c1SSatish Balay /*@ 3623a2748737SPierre Jolivet MatDenseGetSubMatrix - Gives access to a block of rows and columns of a dense matrix, represented as a Mat. 36245ea7661aSPierre Jolivet 36255ea7661aSPierre Jolivet Collective 36265ea7661aSPierre Jolivet 36275ea7661aSPierre Jolivet Input Parameters: 36285ea7661aSPierre Jolivet + mat - the Mat object 3629a2748737SPierre Jolivet . rbegin - the first global row index in the block (if PETSC_DECIDE, is 0) 3630a2748737SPierre Jolivet . rend - the global row index past the last one in the block (if PETSC_DECIDE, is M) 3631a2748737SPierre Jolivet . cbegin - the first global column index in the block (if PETSC_DECIDE, is 0) 3632a2748737SPierre Jolivet - cend - the global column index past the last one in the block (if PETSC_DECIDE, is N) 36335ea7661aSPierre Jolivet 36345ea7661aSPierre Jolivet Output Parameter: 36355ea7661aSPierre Jolivet . v - the matrix 36365ea7661aSPierre Jolivet 36375ea7661aSPierre Jolivet Notes: 36385ea7661aSPierre Jolivet The matrix is owned by PETSc. Users need to call MatDenseRestoreSubMatrix() when the matrix is no longer needed. 363911a5261eSBarry Smith 3640a2748737SPierre Jolivet The output matrix is not redistributed by PETSc, so depending on the values of rbegin and rend, some processes may have no local rows. 36415ea7661aSPierre Jolivet 36425ea7661aSPierre Jolivet Level: intermediate 36435ea7661aSPierre Jolivet 364447d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreSubMatrix()` 36455ea7661aSPierre Jolivet @*/ 3646d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) 3647d71ae5a4SJacob Faibussowitsch { 36485ea7661aSPierre Jolivet PetscFunctionBegin; 36495ea7661aSPierre Jolivet PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 36505ea7661aSPierre Jolivet PetscValidType(A, 1); 3651a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, rbegin, 2); 3652a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, rend, 3); 3653a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, cbegin, 4); 3654a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, cend, 5); 3655a2748737SPierre Jolivet PetscValidPointer(v, 6); 3656a2748737SPierre Jolivet if (rbegin == PETSC_DECIDE) rbegin = 0; 3657a2748737SPierre Jolivet if (rend == PETSC_DECIDE) rend = A->rmap->N; 3658a2748737SPierre Jolivet if (cbegin == PETSC_DECIDE) cbegin = 0; 3659a2748737SPierre Jolivet if (cend == PETSC_DECIDE) cend = A->cmap->N; 366028b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3661a2748737SPierre 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); 3662a2748737SPierre 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); 3663a2748737SPierre 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); 3664a2748737SPierre 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); 3665a2748737SPierre Jolivet PetscUseMethod(A, "MatDenseGetSubMatrix_C", (Mat, PetscInt, PetscInt, PetscInt, PetscInt, Mat *), (A, rbegin, rend, cbegin, cend, v)); 36665ea7661aSPierre Jolivet PetscFunctionReturn(0); 36675ea7661aSPierre Jolivet } 36685ea7661aSPierre Jolivet 36690f74d2c1SSatish Balay /*@ 36705ea7661aSPierre Jolivet MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from MatDenseGetSubMatrix(). 36715ea7661aSPierre Jolivet 36725ea7661aSPierre Jolivet Collective 36735ea7661aSPierre Jolivet 36745ea7661aSPierre Jolivet Input Parameters: 36755ea7661aSPierre Jolivet + mat - the Mat object 3676742765d3SMatthew Knepley - v - the Mat object (may be NULL) 36775ea7661aSPierre Jolivet 36785ea7661aSPierre Jolivet Level: intermediate 36795ea7661aSPierre Jolivet 368047d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseGetSubMatrix()` 36815ea7661aSPierre Jolivet @*/ 3682d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix(Mat A, Mat *v) 3683d71ae5a4SJacob Faibussowitsch { 36845ea7661aSPierre Jolivet PetscFunctionBegin; 36855ea7661aSPierre Jolivet PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 36865ea7661aSPierre Jolivet PetscValidType(A, 1); 36875ea7661aSPierre Jolivet PetscValidPointer(v, 2); 3688cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreSubMatrix_C", (Mat, Mat *), (A, v)); 36895ea7661aSPierre Jolivet PetscFunctionReturn(0); 36905ea7661aSPierre Jolivet } 36918a9c020eSBarry Smith 36928a9c020eSBarry Smith #include <petscblaslapack.h> 36938a9c020eSBarry Smith #include <petsc/private/kernels/blockinvert.h> 36948a9c020eSBarry Smith 3695d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseInvert(Mat A) 3696d71ae5a4SJacob Faibussowitsch { 36978a9c020eSBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 36988a9c020eSBarry Smith PetscInt bs = A->rmap->n; 36998a9c020eSBarry Smith MatScalar *values = a->v; 37008a9c020eSBarry Smith const PetscReal shift = 0.0; 37018a9c020eSBarry Smith PetscBool allowzeropivot = PetscNot(A->erroriffailure), zeropivotdetected = PETSC_FALSE; 37028a9c020eSBarry Smith 37038a9c020eSBarry Smith PetscFunctionBegin; 37048a9c020eSBarry Smith /* factor and invert each block */ 37058a9c020eSBarry Smith switch (bs) { 3706d71ae5a4SJacob Faibussowitsch case 1: 3707d71ae5a4SJacob Faibussowitsch values[0] = (PetscScalar)1.0 / (values[0] + shift); 3708d71ae5a4SJacob Faibussowitsch break; 37098a9c020eSBarry Smith case 2: 37108a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_2(values, shift, allowzeropivot, &zeropivotdetected)); 37118a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 37128a9c020eSBarry Smith break; 37138a9c020eSBarry Smith case 3: 37148a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_3(values, shift, allowzeropivot, &zeropivotdetected)); 37158a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 37168a9c020eSBarry Smith break; 37178a9c020eSBarry Smith case 4: 37188a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_4(values, shift, allowzeropivot, &zeropivotdetected)); 37198a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 37208a9c020eSBarry Smith break; 37219371c9d4SSatish Balay case 5: { 37228a9c020eSBarry Smith PetscScalar work[25]; 37238a9c020eSBarry Smith PetscInt ipvt[5]; 37248a9c020eSBarry Smith 37258a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_5(values, ipvt, work, shift, allowzeropivot, &zeropivotdetected)); 37268a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 37279371c9d4SSatish Balay } break; 37288a9c020eSBarry Smith case 6: 37298a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_6(values, shift, allowzeropivot, &zeropivotdetected)); 37308a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 37318a9c020eSBarry Smith break; 37328a9c020eSBarry Smith case 7: 37338a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_7(values, shift, allowzeropivot, &zeropivotdetected)); 37348a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 37358a9c020eSBarry Smith break; 37369371c9d4SSatish Balay default: { 37378a9c020eSBarry Smith PetscInt *v_pivots, *IJ, j; 37388a9c020eSBarry Smith PetscScalar *v_work; 37398a9c020eSBarry Smith 37408a9c020eSBarry Smith PetscCall(PetscMalloc3(bs, &v_work, bs, &v_pivots, bs, &IJ)); 3741ad540459SPierre Jolivet for (j = 0; j < bs; j++) IJ[j] = j; 37428a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A(bs, values, v_pivots, v_work, allowzeropivot, &zeropivotdetected)); 37438a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 37448a9c020eSBarry Smith PetscCall(PetscFree3(v_work, v_pivots, IJ)); 37458a9c020eSBarry Smith } 37468a9c020eSBarry Smith } 37478a9c020eSBarry Smith PetscFunctionReturn(0); 37488a9c020eSBarry Smith } 3749