167e560aaSBarry Smith /* 267e560aaSBarry Smith Defines the basic matrix operations for sequential dense. 367e560aaSBarry Smith */ 4289bc588SBarry Smith 5dec5eb66SMatthew G Knepley #include <../src/mat/impls/dense/seq/dense.h> /*I "petscmat.h" I*/ 6c6db04a5SJed Brown #include <petscblaslapack.h> 76a63e612SBarry Smith #include <../src/mat/impls/aij/seq/aij.h> 8b2573a8aSBarry Smith 9*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSymmetrize_Private(Mat A, PetscBool hermitian) 10*d71ae5a4SJacob Faibussowitsch { 118c178816SStefano Zampini Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 128c178816SStefano Zampini PetscInt j, k, n = A->rmap->n; 13ca15aa20SStefano Zampini PetscScalar *v; 148c178816SStefano Zampini 158c178816SStefano Zampini PetscFunctionBegin; 1608401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Cannot symmetrize a rectangular matrix"); 179566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 188c178816SStefano Zampini if (!hermitian) { 198c178816SStefano Zampini for (k = 0; k < n; k++) { 20ad540459SPierre Jolivet for (j = k; j < n; j++) v[j * mat->lda + k] = v[k * mat->lda + j]; 218c178816SStefano Zampini } 228c178816SStefano Zampini } else { 238c178816SStefano Zampini for (k = 0; k < n; k++) { 24ad540459SPierre Jolivet for (j = k; j < n; j++) v[j * mat->lda + k] = PetscConj(v[k * mat->lda + j]); 258c178816SStefano Zampini } 268c178816SStefano Zampini } 279566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 288c178816SStefano Zampini PetscFunctionReturn(0); 298c178816SStefano Zampini } 308c178816SStefano Zampini 31*d71ae5a4SJacob Faibussowitsch PETSC_EXTERN PetscErrorCode MatSeqDenseInvertFactors_Private(Mat A) 32*d71ae5a4SJacob Faibussowitsch { 338c178816SStefano Zampini Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 348c178816SStefano Zampini PetscBLASInt info, n; 358c178816SStefano Zampini 368c178816SStefano Zampini PetscFunctionBegin; 378c178816SStefano Zampini if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 389566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 398c178816SStefano Zampini if (A->factortype == MAT_FACTOR_LU) { 4028b400f6SJacob Faibussowitsch PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present"); 418c178816SStefano Zampini if (!mat->fwork) { 428c178816SStefano Zampini mat->lfwork = n; 439566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 448c178816SStefano Zampini } 459566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 46792fecdfSBarry Smith PetscCallBLAS("LAPACKgetri", LAPACKgetri_(&n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info)); 479566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 489566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0)); 498c178816SStefano Zampini } else if (A->factortype == MAT_FACTOR_CHOLESKY) { 50b94d7dedSBarry Smith if (A->spd == PETSC_BOOL3_TRUE) { 519566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 52792fecdfSBarry Smith PetscCallBLAS("LAPACKpotri", LAPACKpotri_("L", &n, mat->v, &mat->lda, &info)); 539566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 549566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_TRUE)); 558c178816SStefano Zampini #if defined(PETSC_USE_COMPLEX) 56b94d7dedSBarry Smith } else if (A->hermitian == PETSC_BOOL3_TRUE) { 5728b400f6SJacob Faibussowitsch PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present"); 5828b400f6SJacob Faibussowitsch PetscCheck(mat->fwork, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Fwork not present"); 599566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 60792fecdfSBarry Smith PetscCallBLAS("LAPACKhetri", LAPACKhetri_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &info)); 619566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 629566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_TRUE)); 638c178816SStefano Zampini #endif 648c178816SStefano Zampini } else { /* symmetric case */ 6528b400f6SJacob Faibussowitsch PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present"); 6628b400f6SJacob Faibussowitsch PetscCheck(mat->fwork, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Fwork not present"); 679566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 68792fecdfSBarry Smith PetscCallBLAS("LAPACKsytri", LAPACKsytri_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &info)); 699566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 709566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_FALSE)); 718c178816SStefano Zampini } 7228b400f6SJacob Faibussowitsch PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad Inversion: zero pivot in row %" PetscInt_FMT, (PetscInt)info - 1); 739566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0)); 748c178816SStefano Zampini } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Matrix must be factored to solve"); 758c178816SStefano Zampini 768c178816SStefano Zampini A->ops->solve = NULL; 778c178816SStefano Zampini A->ops->matsolve = NULL; 788c178816SStefano Zampini A->ops->solvetranspose = NULL; 798c178816SStefano Zampini A->ops->matsolvetranspose = NULL; 808c178816SStefano Zampini A->ops->solveadd = NULL; 818c178816SStefano Zampini A->ops->solvetransposeadd = NULL; 828c178816SStefano Zampini A->factortype = MAT_FACTOR_NONE; 839566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 848c178816SStefano Zampini PetscFunctionReturn(0); 858c178816SStefano Zampini } 868c178816SStefano Zampini 87*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatZeroRowsColumns_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) 88*d71ae5a4SJacob Faibussowitsch { 893f49a652SStefano Zampini Mat_SeqDense *l = (Mat_SeqDense *)A->data; 903f49a652SStefano Zampini PetscInt m = l->lda, n = A->cmap->n, r = A->rmap->n, i, j; 91ca15aa20SStefano Zampini PetscScalar *slot, *bb, *v; 923f49a652SStefano Zampini const PetscScalar *xx; 933f49a652SStefano Zampini 943f49a652SStefano Zampini PetscFunctionBegin; 9576bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 963f49a652SStefano Zampini for (i = 0; i < N; i++) { 9708401ef6SPierre Jolivet PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed"); 9808401ef6SPierre 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); 9908401ef6SPierre 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); 1003f49a652SStefano Zampini } 10176bd3646SJed Brown } 102ca15aa20SStefano Zampini if (!N) PetscFunctionReturn(0); 1033f49a652SStefano Zampini 1043f49a652SStefano Zampini /* fix right hand side if needed */ 1053f49a652SStefano Zampini if (x && b) { 1066c4d906cSStefano Zampini Vec xt; 1076c4d906cSStefano Zampini 10808401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices"); 1099566063dSJacob Faibussowitsch PetscCall(VecDuplicate(x, &xt)); 1109566063dSJacob Faibussowitsch PetscCall(VecCopy(x, xt)); 1119566063dSJacob Faibussowitsch PetscCall(VecScale(xt, -1.0)); 1129566063dSJacob Faibussowitsch PetscCall(MatMultAdd(A, xt, b, b)); 1139566063dSJacob Faibussowitsch PetscCall(VecDestroy(&xt)); 1149566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 1159566063dSJacob Faibussowitsch PetscCall(VecGetArray(b, &bb)); 1163f49a652SStefano Zampini for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]]; 1179566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 1189566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(b, &bb)); 1193f49a652SStefano Zampini } 1203f49a652SStefano Zampini 1219566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 1223f49a652SStefano Zampini for (i = 0; i < N; i++) { 123ca15aa20SStefano Zampini slot = v + rows[i] * m; 1249566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(slot, r)); 1253f49a652SStefano Zampini } 1263f49a652SStefano Zampini for (i = 0; i < N; i++) { 127ca15aa20SStefano Zampini slot = v + rows[i]; 1289371c9d4SSatish Balay for (j = 0; j < n; j++) { 1299371c9d4SSatish Balay *slot = 0.0; 1309371c9d4SSatish Balay slot += m; 1319371c9d4SSatish Balay } 1323f49a652SStefano Zampini } 1333f49a652SStefano Zampini if (diag != 0.0) { 13408401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices"); 1353f49a652SStefano Zampini for (i = 0; i < N; i++) { 136ca15aa20SStefano Zampini slot = v + (m + 1) * rows[i]; 1373f49a652SStefano Zampini *slot = diag; 1383f49a652SStefano Zampini } 1393f49a652SStefano Zampini } 1409566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 1413f49a652SStefano Zampini PetscFunctionReturn(0); 1423f49a652SStefano Zampini } 1433f49a652SStefano Zampini 144*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatPtAPNumeric_SeqDense_SeqDense(Mat A, Mat P, Mat C) 145*d71ae5a4SJacob Faibussowitsch { 146abc3b08eSStefano Zampini Mat_SeqDense *c = (Mat_SeqDense *)(C->data); 147abc3b08eSStefano Zampini 148abc3b08eSStefano Zampini PetscFunctionBegin; 149ca15aa20SStefano Zampini if (c->ptapwork) { 1509566063dSJacob Faibussowitsch PetscCall((*C->ops->matmultnumeric)(A, P, c->ptapwork)); 1519566063dSJacob Faibussowitsch PetscCall((*C->ops->transposematmultnumeric)(P, c->ptapwork, C)); 1524222ddf1SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)C), PETSC_ERR_SUP, "Must call MatPtAPSymbolic_SeqDense_SeqDense() first"); 153abc3b08eSStefano Zampini PetscFunctionReturn(0); 154abc3b08eSStefano Zampini } 155abc3b08eSStefano Zampini 156*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatPtAPSymbolic_SeqDense_SeqDense(Mat A, Mat P, PetscReal fill, Mat C) 157*d71ae5a4SJacob Faibussowitsch { 158abc3b08eSStefano Zampini Mat_SeqDense *c; 1597a3c3d58SStefano Zampini PetscBool cisdense; 160abc3b08eSStefano Zampini 161abc3b08eSStefano Zampini PetscFunctionBegin; 1629566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, P->cmap->n, P->cmap->n, P->cmap->N, P->cmap->N)); 1639566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 1647a3c3d58SStefano Zampini if (!cisdense) { 1657a3c3d58SStefano Zampini PetscBool flg; 1667a3c3d58SStefano Zampini 1679566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)P, ((PetscObject)A)->type_name, &flg)); 1689566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 1697a3c3d58SStefano Zampini } 1709566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 1714222ddf1SHong Zhang c = (Mat_SeqDense *)C->data; 1729566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &c->ptapwork)); 1739566063dSJacob Faibussowitsch PetscCall(MatSetSizes(c->ptapwork, A->rmap->n, P->cmap->n, A->rmap->N, P->cmap->N)); 1749566063dSJacob Faibussowitsch PetscCall(MatSetType(c->ptapwork, ((PetscObject)C)->type_name)); 1759566063dSJacob Faibussowitsch PetscCall(MatSetUp(c->ptapwork)); 176abc3b08eSStefano Zampini PetscFunctionReturn(0); 177abc3b08eSStefano Zampini } 178abc3b08eSStefano Zampini 179*d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) 180*d71ae5a4SJacob Faibussowitsch { 181a13144ffSStefano Zampini Mat B = NULL; 182b49cda9fSStefano Zampini Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data; 183b49cda9fSStefano Zampini Mat_SeqDense *b; 184b49cda9fSStefano Zampini PetscInt *ai = a->i, *aj = a->j, m = A->rmap->N, n = A->cmap->N, i; 1852e5835c6SStefano Zampini const MatScalar *av; 186a13144ffSStefano Zampini PetscBool isseqdense; 187b49cda9fSStefano Zampini 188b49cda9fSStefano Zampini PetscFunctionBegin; 189a13144ffSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 1909566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)*newmat, MATSEQDENSE, &isseqdense)); 19128b400f6SJacob Faibussowitsch PetscCheck(isseqdense, PetscObjectComm((PetscObject)*newmat), PETSC_ERR_USER, "Cannot reuse matrix of type %s", ((PetscObject)(*newmat))->type_name); 192a13144ffSStefano Zampini } 193a13144ffSStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 1949566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B)); 1959566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B, m, n, m, n)); 1969566063dSJacob Faibussowitsch PetscCall(MatSetType(B, MATSEQDENSE)); 1979566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(B, NULL)); 198b49cda9fSStefano Zampini b = (Mat_SeqDense *)(B->data); 199a13144ffSStefano Zampini } else { 200a13144ffSStefano Zampini b = (Mat_SeqDense *)((*newmat)->data); 2019566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(b->v, m * n)); 202a13144ffSStefano Zampini } 2039566063dSJacob Faibussowitsch PetscCall(MatSeqAIJGetArrayRead(A, &av)); 204b49cda9fSStefano Zampini for (i = 0; i < m; i++) { 205b49cda9fSStefano Zampini PetscInt j; 206b49cda9fSStefano Zampini for (j = 0; j < ai[1] - ai[0]; j++) { 207b49cda9fSStefano Zampini b->v[*aj * m + i] = *av; 208b49cda9fSStefano Zampini aj++; 209b49cda9fSStefano Zampini av++; 210b49cda9fSStefano Zampini } 211b49cda9fSStefano Zampini ai++; 212b49cda9fSStefano Zampini } 2139566063dSJacob Faibussowitsch PetscCall(MatSeqAIJRestoreArrayRead(A, &av)); 214b49cda9fSStefano Zampini 215511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 2169566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 2179566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 2189566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A, &B)); 219b49cda9fSStefano Zampini } else { 220a13144ffSStefano Zampini if (B) *newmat = B; 2219566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(*newmat, MAT_FINAL_ASSEMBLY)); 2229566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(*newmat, MAT_FINAL_ASSEMBLY)); 223b49cda9fSStefano Zampini } 224b49cda9fSStefano Zampini PetscFunctionReturn(0); 225b49cda9fSStefano Zampini } 226b49cda9fSStefano Zampini 227*d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqDense_SeqAIJ(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) 228*d71ae5a4SJacob Faibussowitsch { 2296d4ec7b0SPierre Jolivet Mat B = NULL; 2306a63e612SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2319399e1b8SMatthew G. Knepley PetscInt i, j; 2329399e1b8SMatthew G. Knepley PetscInt *rows, *nnz; 2339399e1b8SMatthew G. Knepley MatScalar *aa = a->v, *vals; 2346a63e612SBarry Smith 2356a63e612SBarry Smith PetscFunctionBegin; 2369566063dSJacob Faibussowitsch PetscCall(PetscCalloc3(A->rmap->n, &rows, A->rmap->n, &nnz, A->rmap->n, &vals)); 2376d4ec7b0SPierre Jolivet if (reuse != MAT_REUSE_MATRIX) { 2389566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B)); 2399566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B, A->rmap->n, A->cmap->n, A->rmap->N, A->cmap->N)); 2409566063dSJacob Faibussowitsch PetscCall(MatSetType(B, MATSEQAIJ)); 2419399e1b8SMatthew G. Knepley for (j = 0; j < A->cmap->n; j++) { 2429371c9d4SSatish Balay for (i = 0; i < A->rmap->n; i++) 2439371c9d4SSatish Balay if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) ++nnz[i]; 2446a63e612SBarry Smith aa += a->lda; 2456a63e612SBarry Smith } 2469566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(B, PETSC_DETERMINE, nnz)); 2476d4ec7b0SPierre Jolivet } else B = *newmat; 2489399e1b8SMatthew G. Knepley aa = a->v; 2499399e1b8SMatthew G. Knepley for (j = 0; j < A->cmap->n; j++) { 2509399e1b8SMatthew G. Knepley PetscInt numRows = 0; 2519371c9d4SSatish Balay for (i = 0; i < A->rmap->n; i++) 2529371c9d4SSatish Balay if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) { 2539371c9d4SSatish Balay rows[numRows] = i; 2549371c9d4SSatish Balay vals[numRows++] = aa[i]; 2559371c9d4SSatish Balay } 2569566063dSJacob Faibussowitsch PetscCall(MatSetValues(B, numRows, rows, 1, &j, vals, INSERT_VALUES)); 2579399e1b8SMatthew G. Knepley aa += a->lda; 2589399e1b8SMatthew G. Knepley } 2599566063dSJacob Faibussowitsch PetscCall(PetscFree3(rows, nnz, vals)); 2609566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 2619566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 2626a63e612SBarry Smith 263511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 2649566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A, &B)); 2656d4ec7b0SPierre Jolivet } else if (reuse != MAT_REUSE_MATRIX) *newmat = B; 2666a63e612SBarry Smith PetscFunctionReturn(0); 2676a63e612SBarry Smith } 2686a63e612SBarry Smith 269*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatAXPY_SeqDense(Mat Y, PetscScalar alpha, Mat X, MatStructure str) 270*d71ae5a4SJacob Faibussowitsch { 2711987afe7SBarry Smith Mat_SeqDense *x = (Mat_SeqDense *)X->data, *y = (Mat_SeqDense *)Y->data; 272ca15aa20SStefano Zampini const PetscScalar *xv; 273ca15aa20SStefano Zampini PetscScalar *yv; 27423fff9afSBarry Smith PetscBLASInt N, m, ldax = 0, lday = 0, one = 1; 2753a40ed3dSBarry Smith 2763a40ed3dSBarry Smith PetscFunctionBegin; 2779566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(X, &xv)); 2789566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(Y, &yv)); 2799566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(X->rmap->n * X->cmap->n, &N)); 2809566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(X->rmap->n, &m)); 2819566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(x->lda, &ldax)); 2829566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(y->lda, &lday)); 283a5ce6ee0Svictorle if (ldax > m || lday > m) { 284ca15aa20SStefano Zampini PetscInt j; 285ca15aa20SStefano Zampini 28648a46eb9SPierre Jolivet for (j = 0; j < X->cmap->n; j++) PetscCallBLAS("BLASaxpy", BLASaxpy_(&m, &alpha, xv + j * ldax, &one, yv + j * lday, &one)); 287a5ce6ee0Svictorle } else { 288792fecdfSBarry Smith PetscCallBLAS("BLASaxpy", BLASaxpy_(&N, &alpha, xv, &one, yv, &one)); 289a5ce6ee0Svictorle } 2909566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(X, &xv)); 2919566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(Y, &yv)); 2929566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(PetscMax(2.0 * N - 1, 0))); 2933a40ed3dSBarry Smith PetscFunctionReturn(0); 2941987afe7SBarry Smith } 2951987afe7SBarry Smith 296*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetInfo_SeqDense(Mat A, MatInfoType flag, MatInfo *info) 297*d71ae5a4SJacob Faibussowitsch { 298ca15aa20SStefano Zampini PetscLogDouble N = A->rmap->n * A->cmap->n; 2993a40ed3dSBarry Smith 3003a40ed3dSBarry Smith PetscFunctionBegin; 3014e220ebcSLois Curfman McInnes info->block_size = 1.0; 302ca15aa20SStefano Zampini info->nz_allocated = N; 303ca15aa20SStefano Zampini info->nz_used = N; 304ca15aa20SStefano Zampini info->nz_unneeded = 0; 305ca15aa20SStefano Zampini info->assemblies = A->num_ass; 3064e220ebcSLois Curfman McInnes info->mallocs = 0; 3074dfa11a4SJacob Faibussowitsch info->memory = 0; /* REVIEW ME */ 3084e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 3094e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 3104e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 3113a40ed3dSBarry Smith PetscFunctionReturn(0); 312289bc588SBarry Smith } 313289bc588SBarry Smith 314*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatScale_SeqDense(Mat A, PetscScalar alpha) 315*d71ae5a4SJacob Faibussowitsch { 316273d9f13SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 317ca15aa20SStefano Zampini PetscScalar *v; 31823fff9afSBarry Smith PetscBLASInt one = 1, j, nz, lda = 0; 31980cd9d93SLois Curfman McInnes 3203a40ed3dSBarry Smith PetscFunctionBegin; 3219566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 3229566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(a->lda, &lda)); 323d0f46423SBarry Smith if (lda > A->rmap->n) { 3249566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &nz)); 32548a46eb9SPierre Jolivet for (j = 0; j < A->cmap->n; j++) PetscCallBLAS("BLASscal", BLASscal_(&nz, &alpha, v + j * lda, &one)); 326a5ce6ee0Svictorle } else { 3279566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n * A->cmap->n, &nz)); 328792fecdfSBarry Smith PetscCallBLAS("BLASscal", BLASscal_(&nz, &alpha, v, &one)); 329a5ce6ee0Svictorle } 33004cbc005SJose E. Roman PetscCall(PetscLogFlops(A->rmap->n * A->cmap->n)); 3319566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 3323a40ed3dSBarry Smith PetscFunctionReturn(0); 33380cd9d93SLois Curfman McInnes } 33480cd9d93SLois Curfman McInnes 335*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatShift_SeqDense(Mat A, PetscScalar alpha) 336*d71ae5a4SJacob Faibussowitsch { 3372f605a99SJose E. Roman Mat_SeqDense *a = (Mat_SeqDense *)A->data; 3382f605a99SJose E. Roman PetscScalar *v; 3392f605a99SJose E. Roman PetscInt j, k; 3402f605a99SJose E. Roman 3412f605a99SJose E. Roman PetscFunctionBegin; 3422f605a99SJose E. Roman PetscCall(MatDenseGetArray(A, &v)); 3432f605a99SJose E. Roman k = PetscMin(A->rmap->n, A->cmap->n); 3442f605a99SJose E. Roman for (j = 0; j < k; j++) v[j + j * a->lda] += alpha; 3452f605a99SJose E. Roman PetscCall(PetscLogFlops(k)); 3462f605a99SJose E. Roman PetscCall(MatDenseRestoreArray(A, &v)); 3472f605a99SJose E. Roman PetscFunctionReturn(0); 3482f605a99SJose E. Roman } 3492f605a99SJose E. Roman 350*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatIsHermitian_SeqDense(Mat A, PetscReal rtol, PetscBool *fl) 351*d71ae5a4SJacob Faibussowitsch { 3521cbb95d3SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 353ca15aa20SStefano Zampini PetscInt i, j, m = A->rmap->n, N = a->lda; 354ca15aa20SStefano Zampini const PetscScalar *v; 3551cbb95d3SBarry Smith 3561cbb95d3SBarry Smith PetscFunctionBegin; 3571cbb95d3SBarry Smith *fl = PETSC_FALSE; 358d0f46423SBarry Smith if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0); 3599566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 3601cbb95d3SBarry Smith for (i = 0; i < m; i++) { 361ca15aa20SStefano Zampini for (j = i; j < m; j++) { 362ad540459SPierre Jolivet if (PetscAbsScalar(v[i + j * N] - PetscConj(v[j + i * N])) > rtol) goto restore; 3631cbb95d3SBarry Smith } 364637a0070SStefano Zampini } 3651cbb95d3SBarry Smith *fl = PETSC_TRUE; 366637a0070SStefano Zampini restore: 3679566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 368637a0070SStefano Zampini PetscFunctionReturn(0); 369637a0070SStefano Zampini } 370637a0070SStefano Zampini 371*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatIsSymmetric_SeqDense(Mat A, PetscReal rtol, PetscBool *fl) 372*d71ae5a4SJacob Faibussowitsch { 373637a0070SStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 374637a0070SStefano Zampini PetscInt i, j, m = A->rmap->n, N = a->lda; 375637a0070SStefano Zampini const PetscScalar *v; 376637a0070SStefano Zampini 377637a0070SStefano Zampini PetscFunctionBegin; 378637a0070SStefano Zampini *fl = PETSC_FALSE; 379637a0070SStefano Zampini if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0); 3809566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 381637a0070SStefano Zampini for (i = 0; i < m; i++) { 382637a0070SStefano Zampini for (j = i; j < m; j++) { 383ad540459SPierre Jolivet if (PetscAbsScalar(v[i + j * N] - v[j + i * N]) > rtol) goto restore; 384637a0070SStefano Zampini } 385637a0070SStefano Zampini } 386637a0070SStefano Zampini *fl = PETSC_TRUE; 387637a0070SStefano Zampini restore: 3889566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 3891cbb95d3SBarry Smith PetscFunctionReturn(0); 3901cbb95d3SBarry Smith } 3911cbb95d3SBarry Smith 392*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi, Mat A, MatDuplicateOption cpvalues) 393*d71ae5a4SJacob Faibussowitsch { 394ca15aa20SStefano Zampini Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 39523fc5dcaSStefano Zampini PetscInt lda = (PetscInt)mat->lda, j, m, nlda = lda; 39675f6d85dSStefano Zampini PetscBool isdensecpu; 397b24902e0SBarry Smith 398b24902e0SBarry Smith PetscFunctionBegin; 3999566063dSJacob Faibussowitsch PetscCall(PetscLayoutReference(A->rmap, &newi->rmap)); 4009566063dSJacob Faibussowitsch PetscCall(PetscLayoutReference(A->cmap, &newi->cmap)); 40123fc5dcaSStefano Zampini if (cpvalues == MAT_SHARE_NONZERO_PATTERN) { /* propagate LDA */ 4029566063dSJacob Faibussowitsch PetscCall(MatDenseSetLDA(newi, lda)); 40323fc5dcaSStefano Zampini } 4049566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)newi, MATSEQDENSE, &isdensecpu)); 4059566063dSJacob Faibussowitsch if (isdensecpu) PetscCall(MatSeqDenseSetPreallocation(newi, NULL)); 406b24902e0SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 407ca15aa20SStefano Zampini const PetscScalar *av; 408ca15aa20SStefano Zampini PetscScalar *v; 409ca15aa20SStefano Zampini 4109566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 4119566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(newi, &v)); 4129566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(newi, &nlda)); 413d0f46423SBarry Smith m = A->rmap->n; 41423fc5dcaSStefano Zampini if (lda > m || nlda > m) { 41548a46eb9SPierre Jolivet for (j = 0; j < A->cmap->n; j++) PetscCall(PetscArraycpy(v + j * nlda, av + j * lda, m)); 416b24902e0SBarry Smith } else { 4179566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(v, av, A->rmap->n * A->cmap->n)); 418b24902e0SBarry Smith } 4199566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(newi, &v)); 4209566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 421b24902e0SBarry Smith } 422b24902e0SBarry Smith PetscFunctionReturn(0); 423b24902e0SBarry Smith } 424b24902e0SBarry Smith 425*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDuplicate_SeqDense(Mat A, MatDuplicateOption cpvalues, Mat *newmat) 426*d71ae5a4SJacob Faibussowitsch { 4273a40ed3dSBarry Smith PetscFunctionBegin; 4289566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), newmat)); 4299566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*newmat, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n)); 4309566063dSJacob Faibussowitsch PetscCall(MatSetType(*newmat, ((PetscObject)A)->type_name)); 4319566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(*newmat, A, cpvalues)); 432b24902e0SBarry Smith PetscFunctionReturn(0); 433b24902e0SBarry Smith } 434b24902e0SBarry Smith 435*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_LU(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T) 436*d71ae5a4SJacob Faibussowitsch { 437c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4384396437dSToby Isaac PetscBLASInt info; 43967e560aaSBarry Smith 4403a40ed3dSBarry Smith PetscFunctionBegin; 4419566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 442792fecdfSBarry Smith PetscCallBLAS("LAPACKgetrs", LAPACKgetrs_(T ? "T" : "N", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info)); 4439566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 44405fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "GETRS - Bad solve %d", (int)info); 4459566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m))); 4464396437dSToby Isaac PetscFunctionReturn(0); 4474396437dSToby Isaac } 4484396437dSToby Isaac 4494396437dSToby Isaac static PetscErrorCode MatConjugate_SeqDense(Mat); 4504396437dSToby Isaac 451*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_Cholesky(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T) 452*d71ae5a4SJacob Faibussowitsch { 4534396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4544396437dSToby Isaac PetscBLASInt info; 4554396437dSToby Isaac 4564396437dSToby Isaac PetscFunctionBegin; 457b94d7dedSBarry Smith if (A->spd == PETSC_BOOL3_TRUE) { 4589566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A)); 4599566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 460792fecdfSBarry Smith PetscCallBLAS("LAPACKpotrs", LAPACKpotrs_("L", &m, &nrhs, mat->v, &mat->lda, x, &m, &info)); 4619566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 46205fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "POTRS Bad solve %d", (int)info); 4639566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A)); 464a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX) 465b94d7dedSBarry Smith } else if (A->hermitian == PETSC_BOOL3_TRUE) { 4669566063dSJacob Faibussowitsch if (T) PetscCall(MatConjugate_SeqDense(A)); 4679566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 468792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrs", LAPACKhetrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info)); 4699566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 47005fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "HETRS Bad solve %d", (int)info); 4719566063dSJacob Faibussowitsch if (T) PetscCall(MatConjugate_SeqDense(A)); 472a49dc2a2SStefano Zampini #endif 473a49dc2a2SStefano Zampini } else { /* symmetric case */ 4749566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 475792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrs", LAPACKsytrs_("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, "SYTRS Bad solve %d", (int)info); 478a49dc2a2SStefano Zampini } 4799566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m))); 4804396437dSToby Isaac PetscFunctionReturn(0); 4814396437dSToby Isaac } 48285e2c93fSHong Zhang 483*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k) 484*d71ae5a4SJacob Faibussowitsch { 4854396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4864396437dSToby Isaac PetscBLASInt info; 4874396437dSToby Isaac char trans; 4884396437dSToby Isaac 4894396437dSToby Isaac PetscFunctionBegin; 4904905a7bcSToby Isaac if (PetscDefined(USE_COMPLEX)) { 4914905a7bcSToby Isaac trans = 'C'; 4924905a7bcSToby Isaac } else { 4934905a7bcSToby Isaac trans = 'T'; 4944905a7bcSToby Isaac } 4959566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 49605fcb23eSStefano Zampini { /* lwork depends on the number of right-hand sides */ 49705fcb23eSStefano Zampini PetscBLASInt nlfwork, lfwork = -1; 49805fcb23eSStefano Zampini PetscScalar fwork; 49905fcb23eSStefano Zampini 500792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info)); 50105fcb23eSStefano Zampini nlfwork = (PetscBLASInt)PetscRealPart(fwork); 50205fcb23eSStefano Zampini if (nlfwork > mat->lfwork) { 50305fcb23eSStefano Zampini mat->lfwork = nlfwork; 50405fcb23eSStefano Zampini PetscCall(PetscFree(mat->fwork)); 50505fcb23eSStefano Zampini PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 50605fcb23eSStefano Zampini } 50705fcb23eSStefano Zampini } 508792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info)); 5099566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 51005fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %d", (int)info); 5119566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 512792fecdfSBarry Smith PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "N", "N", &mat->rank, &nrhs, mat->v, &mat->lda, x, &ldx, &info)); 5139566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 51405fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %d", (int)info); 5154905a7bcSToby Isaac for (PetscInt j = 0; j < nrhs; j++) { 516ad540459SPierre Jolivet for (PetscInt i = mat->rank; i < k; i++) x[j * ldx + i] = 0.; 5174905a7bcSToby Isaac } 5189566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank)))); 5194905a7bcSToby Isaac PetscFunctionReturn(0); 5204905a7bcSToby Isaac } 5214905a7bcSToby Isaac 522*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k) 523*d71ae5a4SJacob Faibussowitsch { 5244396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 5254396437dSToby Isaac PetscBLASInt info; 5264396437dSToby Isaac 5274396437dSToby Isaac PetscFunctionBegin; 5284396437dSToby Isaac if (A->rmap->n == A->cmap->n && mat->rank == A->rmap->n) { 5299566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 530792fecdfSBarry Smith PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "T", "N", &m, &nrhs, mat->v, &mat->lda, x, &ldx, &info)); 5319566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 53205fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %d", (int)info); 5339566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A)); 53405fcb23eSStefano Zampini { /* lwork depends on the number of right-hand sides */ 53505fcb23eSStefano Zampini PetscBLASInt nlfwork, lfwork = -1; 53605fcb23eSStefano Zampini PetscScalar fwork; 53705fcb23eSStefano Zampini 538792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info)); 53905fcb23eSStefano Zampini nlfwork = (PetscBLASInt)PetscRealPart(fwork); 54005fcb23eSStefano Zampini if (nlfwork > mat->lfwork) { 54105fcb23eSStefano Zampini mat->lfwork = nlfwork; 54205fcb23eSStefano Zampini PetscCall(PetscFree(mat->fwork)); 54305fcb23eSStefano Zampini PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 54405fcb23eSStefano Zampini } 54505fcb23eSStefano Zampini } 5469566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 547792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info)); 5489566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 54905fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %d", (int)info); 5509566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A)); 5514396437dSToby Isaac } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "QR factored matrix cannot be used for transpose solve"); 5529566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank)))); 5534396437dSToby Isaac PetscFunctionReturn(0); 5544396437dSToby Isaac } 5554396437dSToby Isaac 556*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_SetUp(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k) 557*d71ae5a4SJacob Faibussowitsch { 5584396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 5594905a7bcSToby Isaac PetscScalar *y; 5604905a7bcSToby Isaac PetscBLASInt m = 0, k = 0; 5614905a7bcSToby Isaac 5624905a7bcSToby Isaac PetscFunctionBegin; 5639566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 5649566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 5654905a7bcSToby Isaac if (k < m) { 5669566063dSJacob Faibussowitsch PetscCall(VecCopy(xx, mat->qrrhs)); 5679566063dSJacob Faibussowitsch PetscCall(VecGetArray(mat->qrrhs, &y)); 5684905a7bcSToby Isaac } else { 5699566063dSJacob Faibussowitsch PetscCall(VecCopy(xx, yy)); 5709566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &y)); 5714905a7bcSToby Isaac } 5724396437dSToby Isaac *_y = y; 5734396437dSToby Isaac *_k = k; 5744396437dSToby Isaac *_m = m; 5754396437dSToby Isaac PetscFunctionReturn(0); 5764396437dSToby Isaac } 5774396437dSToby Isaac 578*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_TearDown(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k) 579*d71ae5a4SJacob Faibussowitsch { 5804396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 58142e9364cSSatish Balay PetscScalar *y = NULL; 5824396437dSToby Isaac PetscBLASInt m, k; 5834396437dSToby Isaac 5844396437dSToby Isaac PetscFunctionBegin; 5854396437dSToby Isaac y = *_y; 5864396437dSToby Isaac *_y = NULL; 5874396437dSToby Isaac k = *_k; 5884396437dSToby Isaac m = *_m; 5894905a7bcSToby Isaac if (k < m) { 5904905a7bcSToby Isaac PetscScalar *yv; 5919566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &yv)); 5929566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(yv, y, k)); 5939566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &yv)); 5949566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(mat->qrrhs, &y)); 5954905a7bcSToby Isaac } else { 5969566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &y)); 5974905a7bcSToby Isaac } 5984905a7bcSToby Isaac PetscFunctionReturn(0); 5994905a7bcSToby Isaac } 6004905a7bcSToby Isaac 601*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_LU(Mat A, Vec xx, Vec yy) 602*d71ae5a4SJacob Faibussowitsch { 60342e9364cSSatish Balay PetscScalar *y = NULL; 60442e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 6054396437dSToby Isaac 6064396437dSToby Isaac PetscFunctionBegin; 6079566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6089566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_FALSE)); 6099566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6104396437dSToby Isaac PetscFunctionReturn(0); 6114396437dSToby Isaac } 6124396437dSToby Isaac 613*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_LU(Mat A, Vec xx, Vec yy) 614*d71ae5a4SJacob Faibussowitsch { 61542e9364cSSatish Balay PetscScalar *y = NULL; 61642e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 6174396437dSToby Isaac 6184396437dSToby Isaac PetscFunctionBegin; 6199566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6209566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_TRUE)); 6219566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6224396437dSToby Isaac PetscFunctionReturn(0); 6234396437dSToby Isaac } 6244396437dSToby Isaac 625*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Cholesky(Mat A, Vec xx, Vec yy) 626*d71ae5a4SJacob Faibussowitsch { 627e54beecaSStefano Zampini PetscScalar *y = NULL; 628e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 6294396437dSToby Isaac 6304396437dSToby Isaac PetscFunctionBegin; 6319566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6329566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_FALSE)); 6339566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6344396437dSToby Isaac PetscFunctionReturn(0); 6354396437dSToby Isaac } 6364396437dSToby Isaac 637*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_Cholesky(Mat A, Vec xx, Vec yy) 638*d71ae5a4SJacob Faibussowitsch { 639e54beecaSStefano Zampini PetscScalar *y = NULL; 640e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 6414396437dSToby Isaac 6424396437dSToby Isaac PetscFunctionBegin; 6439566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6449566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_TRUE)); 6459566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6464396437dSToby Isaac PetscFunctionReturn(0); 6474396437dSToby Isaac } 6484396437dSToby Isaac 649*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_QR(Mat A, Vec xx, Vec yy) 650*d71ae5a4SJacob Faibussowitsch { 651e54beecaSStefano Zampini PetscScalar *y = NULL; 652e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 6534396437dSToby Isaac 6544396437dSToby Isaac PetscFunctionBegin; 6559566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6569566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k)); 6579566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6584396437dSToby Isaac PetscFunctionReturn(0); 6594396437dSToby Isaac } 6604396437dSToby Isaac 661*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_QR(Mat A, Vec xx, Vec yy) 662*d71ae5a4SJacob Faibussowitsch { 66342e9364cSSatish Balay PetscScalar *y = NULL; 66442e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 6654396437dSToby Isaac 6664396437dSToby Isaac PetscFunctionBegin; 6679566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6689566063dSJacob Faibussowitsch PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k)); 6699566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6704396437dSToby Isaac PetscFunctionReturn(0); 6714396437dSToby Isaac } 6724396437dSToby Isaac 673*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_SetUp(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k) 674*d71ae5a4SJacob Faibussowitsch { 6754905a7bcSToby Isaac const PetscScalar *b; 6764396437dSToby Isaac PetscScalar *y; 677bf5a80bcSToby Isaac PetscInt n, _ldb, _ldx; 678bf5a80bcSToby Isaac PetscBLASInt nrhs = 0, m = 0, k = 0, ldb = 0, ldx = 0, ldy = 0; 6794905a7bcSToby Isaac 6804905a7bcSToby Isaac PetscFunctionBegin; 6819371c9d4SSatish Balay *_ldy = 0; 6829371c9d4SSatish Balay *_m = 0; 6839371c9d4SSatish Balay *_nrhs = 0; 6849371c9d4SSatish Balay *_k = 0; 6859371c9d4SSatish Balay *_y = NULL; 6869566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 6879566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 6889566063dSJacob Faibussowitsch PetscCall(MatGetSize(B, NULL, &n)); 6899566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(n, &nrhs)); 6909566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(B, &_ldb)); 6919566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldb, &ldb)); 6929566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(X, &_ldx)); 6939566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldx, &ldx)); 694bf5a80bcSToby Isaac if (ldx < m) { 6959566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &b)); 6969566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nrhs * m, &y)); 697bf5a80bcSToby Isaac if (ldb == m) { 6989566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(y, b, ldb * nrhs)); 6994905a7bcSToby Isaac } else { 70048a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * m], &b[j * ldb], m)); 7014905a7bcSToby Isaac } 702bf5a80bcSToby Isaac ldy = m; 7039566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &b)); 7044905a7bcSToby Isaac } else { 705bf5a80bcSToby Isaac if (ldb == ldx) { 7069566063dSJacob Faibussowitsch PetscCall(MatCopy(B, X, SAME_NONZERO_PATTERN)); 7079566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &y)); 7084905a7bcSToby Isaac } else { 7099566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &y)); 7109566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &b)); 71148a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * ldx], &b[j * ldb], m)); 7129566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &b)); 7134905a7bcSToby Isaac } 714bf5a80bcSToby Isaac ldy = ldx; 7154905a7bcSToby Isaac } 7164396437dSToby Isaac *_y = y; 717bf5a80bcSToby Isaac *_ldy = ldy; 7184396437dSToby Isaac *_k = k; 7194396437dSToby Isaac *_m = m; 7204396437dSToby Isaac *_nrhs = nrhs; 7214396437dSToby Isaac PetscFunctionReturn(0); 7224396437dSToby Isaac } 7234396437dSToby Isaac 724*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_TearDown(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k) 725*d71ae5a4SJacob Faibussowitsch { 7264396437dSToby Isaac PetscScalar *y; 727bf5a80bcSToby Isaac PetscInt _ldx; 728bf5a80bcSToby Isaac PetscBLASInt k, ldy, nrhs, ldx = 0; 7294396437dSToby Isaac 7304396437dSToby Isaac PetscFunctionBegin; 7314396437dSToby Isaac y = *_y; 7324396437dSToby Isaac *_y = NULL; 7334396437dSToby Isaac k = *_k; 734bf5a80bcSToby Isaac ldy = *_ldy; 7354396437dSToby Isaac nrhs = *_nrhs; 7369566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(X, &_ldx)); 7379566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldx, &ldx)); 738bf5a80bcSToby Isaac if (ldx != ldy) { 7394905a7bcSToby Isaac PetscScalar *xv; 7409566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &xv)); 74148a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&xv[j * ldx], &y[j * ldy], k)); 7429566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(X, &xv)); 7439566063dSJacob Faibussowitsch PetscCall(PetscFree(y)); 7444905a7bcSToby Isaac } else { 7459566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(X, &y)); 7464905a7bcSToby Isaac } 74785e2c93fSHong Zhang PetscFunctionReturn(0); 74885e2c93fSHong Zhang } 74985e2c93fSHong Zhang 750*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_LU(Mat A, Mat B, Mat X) 751*d71ae5a4SJacob Faibussowitsch { 7524396437dSToby Isaac PetscScalar *y; 753bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7544396437dSToby Isaac 7554396437dSToby Isaac PetscFunctionBegin; 7569566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7579566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_FALSE)); 7589566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7594396437dSToby Isaac PetscFunctionReturn(0); 7604396437dSToby Isaac } 7614396437dSToby Isaac 762*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_LU(Mat A, Mat B, Mat X) 763*d71ae5a4SJacob Faibussowitsch { 7644396437dSToby Isaac PetscScalar *y; 765bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7664396437dSToby Isaac 7674396437dSToby Isaac PetscFunctionBegin; 7689566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7699566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_TRUE)); 7709566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7714396437dSToby Isaac PetscFunctionReturn(0); 7724396437dSToby Isaac } 7734396437dSToby Isaac 774*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_Cholesky(Mat A, Mat B, Mat X) 775*d71ae5a4SJacob Faibussowitsch { 7764396437dSToby Isaac PetscScalar *y; 777bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7784396437dSToby Isaac 7794396437dSToby Isaac PetscFunctionBegin; 7809566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7819566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_FALSE)); 7829566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7834396437dSToby Isaac PetscFunctionReturn(0); 7844396437dSToby Isaac } 7854396437dSToby Isaac 786*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_Cholesky(Mat A, Mat B, Mat X) 787*d71ae5a4SJacob Faibussowitsch { 7884396437dSToby Isaac PetscScalar *y; 789bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7904396437dSToby Isaac 7914396437dSToby Isaac PetscFunctionBegin; 7929566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7939566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_TRUE)); 7949566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7954396437dSToby Isaac PetscFunctionReturn(0); 7964396437dSToby Isaac } 7974396437dSToby Isaac 798*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_QR(Mat A, Mat B, Mat X) 799*d71ae5a4SJacob Faibussowitsch { 8004396437dSToby Isaac PetscScalar *y; 801bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 8024396437dSToby Isaac 8034396437dSToby Isaac PetscFunctionBegin; 8049566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 8059566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k)); 8069566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 8074396437dSToby Isaac PetscFunctionReturn(0); 8084396437dSToby Isaac } 8094396437dSToby Isaac 810*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_QR(Mat A, Mat B, Mat X) 811*d71ae5a4SJacob Faibussowitsch { 8124396437dSToby Isaac PetscScalar *y; 813bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 8144396437dSToby Isaac 8154396437dSToby Isaac PetscFunctionBegin; 8169566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 8179566063dSJacob Faibussowitsch PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k)); 8189566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 8194396437dSToby Isaac PetscFunctionReturn(0); 8204396437dSToby Isaac } 8214396437dSToby Isaac 822db4efbfdSBarry Smith /* ---------------------------------------------------------------*/ 823db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots, 824db4efbfdSBarry Smith rather than put it in the Mat->row slot.*/ 825*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLUFactor_SeqDense(Mat A, IS row, IS col, const MatFactorInfo *minfo) 826*d71ae5a4SJacob Faibussowitsch { 827db4efbfdSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 828db4efbfdSBarry Smith PetscBLASInt n, m, info; 829db4efbfdSBarry Smith 830db4efbfdSBarry Smith PetscFunctionBegin; 8319566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 8329566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 8334dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); } 834db4efbfdSBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 8359566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 836792fecdfSBarry Smith PetscCallBLAS("LAPACKgetrf", LAPACKgetrf_(&m, &n, mat->v, &mat->lda, mat->pivots, &info)); 8379566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 8388e57ea43SSatish Balay 83905fcb23eSStefano Zampini PetscCheck(info >= 0, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to LU factorization %d", (int)info); 84005fcb23eSStefano Zampini PetscCheck(info <= 0, PETSC_COMM_SELF, PETSC_ERR_MAT_LU_ZRPVT, "Bad LU factorization %d", (int)info); 8418208b9aeSStefano Zampini 8424396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_LU; 8434396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_LU; 8444396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_LU; 8454396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_LU; 846d5f3da31SBarry Smith A->factortype = MAT_FACTOR_LU; 847db4efbfdSBarry Smith 8489566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 8499566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 850f6224b95SHong Zhang 8519566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((2.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3)); 852db4efbfdSBarry Smith PetscFunctionReturn(0); 853db4efbfdSBarry Smith } 854db4efbfdSBarry Smith 855*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) 856*d71ae5a4SJacob Faibussowitsch { 8574396437dSToby Isaac MatFactorInfo info; 8584396437dSToby Isaac 8594396437dSToby Isaac PetscFunctionBegin; 8609566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 861dbbe0bcdSBarry Smith PetscUseTypeMethod(fact, lufactor, NULL, NULL, &info); 8624396437dSToby Isaac PetscFunctionReturn(0); 8634396437dSToby Isaac } 8644396437dSToby Isaac 865*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, IS col, const MatFactorInfo *info) 866*d71ae5a4SJacob Faibussowitsch { 8674396437dSToby Isaac PetscFunctionBegin; 8684396437dSToby Isaac fact->preallocated = PETSC_TRUE; 8694396437dSToby Isaac fact->assembled = PETSC_TRUE; 8704396437dSToby Isaac fact->ops->lufactornumeric = MatLUFactorNumeric_SeqDense; 8714396437dSToby Isaac PetscFunctionReturn(0); 8724396437dSToby Isaac } 8734396437dSToby Isaac 874a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */ 875*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCholeskyFactor_SeqDense(Mat A, IS perm, const MatFactorInfo *factinfo) 876*d71ae5a4SJacob Faibussowitsch { 877db4efbfdSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 878c5df96a5SBarry Smith PetscBLASInt info, n; 879db4efbfdSBarry Smith 880db4efbfdSBarry Smith PetscFunctionBegin; 8819566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 882db4efbfdSBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 883b94d7dedSBarry Smith if (A->spd == PETSC_BOOL3_TRUE) { 8849566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 885792fecdfSBarry Smith PetscCallBLAS("LAPACKpotrf", LAPACKpotrf_("L", &n, mat->v, &mat->lda, &info)); 8869566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 887a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX) 888b94d7dedSBarry Smith } else if (A->hermitian == PETSC_BOOL3_TRUE) { 8894dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); } 890a49dc2a2SStefano Zampini if (!mat->fwork) { 891a49dc2a2SStefano Zampini PetscScalar dummy; 892a49dc2a2SStefano Zampini 893a49dc2a2SStefano Zampini mat->lfwork = -1; 8949566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 895792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info)); 8969566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 897a49dc2a2SStefano Zampini mat->lfwork = (PetscInt)PetscRealPart(dummy); 8989566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 899a49dc2a2SStefano Zampini } 9009566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 901792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info)); 9029566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 903a49dc2a2SStefano Zampini #endif 904a49dc2a2SStefano Zampini } else { /* symmetric case */ 9054dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); } 906a49dc2a2SStefano Zampini if (!mat->fwork) { 907a49dc2a2SStefano Zampini PetscScalar dummy; 908a49dc2a2SStefano Zampini 909a49dc2a2SStefano Zampini mat->lfwork = -1; 9109566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 911792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info)); 9129566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 913a49dc2a2SStefano Zampini mat->lfwork = (PetscInt)PetscRealPart(dummy); 9149566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 915a49dc2a2SStefano Zampini } 9169566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 917792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info)); 9189566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 919a49dc2a2SStefano Zampini } 92028b400f6SJacob Faibussowitsch PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad factorization: zero pivot in row %" PetscInt_FMT, (PetscInt)info - 1); 9218208b9aeSStefano Zampini 9224396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_Cholesky; 9234396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_Cholesky; 9244396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_Cholesky; 9254396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_Cholesky; 926d5f3da31SBarry Smith A->factortype = MAT_FACTOR_CHOLESKY; 9272205254eSKarl Rupp 9289566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 9299566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 930f6224b95SHong Zhang 9319566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0)); 932db4efbfdSBarry Smith PetscFunctionReturn(0); 933db4efbfdSBarry Smith } 934db4efbfdSBarry Smith 935*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) 936*d71ae5a4SJacob Faibussowitsch { 937db4efbfdSBarry Smith MatFactorInfo info; 938db4efbfdSBarry Smith 939db4efbfdSBarry Smith PetscFunctionBegin; 940db4efbfdSBarry Smith info.fill = 1.0; 9412205254eSKarl Rupp 9429566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 943dbbe0bcdSBarry Smith PetscUseTypeMethod(fact, choleskyfactor, NULL, &info); 944db4efbfdSBarry Smith PetscFunctionReturn(0); 945db4efbfdSBarry Smith } 946db4efbfdSBarry Smith 947*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info) 948*d71ae5a4SJacob Faibussowitsch { 949db4efbfdSBarry Smith PetscFunctionBegin; 950c3ef05f6SHong Zhang fact->assembled = PETSC_TRUE; 9511bbcc794SSatish Balay fact->preallocated = PETSC_TRUE; 952719d5645SBarry Smith fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense; 953db4efbfdSBarry Smith PetscFunctionReturn(0); 954db4efbfdSBarry Smith } 955db4efbfdSBarry Smith 956*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatQRFactor_SeqDense(Mat A, IS col, const MatFactorInfo *minfo) 957*d71ae5a4SJacob Faibussowitsch { 9584905a7bcSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 9594905a7bcSToby Isaac PetscBLASInt n, m, info, min, max; 9604905a7bcSToby Isaac 9614905a7bcSToby Isaac PetscFunctionBegin; 9629566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 9639566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 9644396437dSToby Isaac max = PetscMax(m, n); 9654396437dSToby Isaac min = PetscMin(m, n); 9664dfa11a4SJacob Faibussowitsch if (!mat->tau) { PetscCall(PetscMalloc1(min, &mat->tau)); } 9674dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(n, &mat->pivots)); } 96848a46eb9SPierre Jolivet if (!mat->qrrhs) PetscCall(MatCreateVecs(A, NULL, &(mat->qrrhs))); 9694905a7bcSToby Isaac if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 9704905a7bcSToby Isaac if (!mat->fwork) { 9714905a7bcSToby Isaac PetscScalar dummy; 9724905a7bcSToby Isaac 9734905a7bcSToby Isaac mat->lfwork = -1; 9749566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 975792fecdfSBarry Smith PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, &dummy, &mat->lfwork, &info)); 9769566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 9774905a7bcSToby Isaac mat->lfwork = (PetscInt)PetscRealPart(dummy); 9789566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 9794905a7bcSToby Isaac } 9809566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 981792fecdfSBarry Smith PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, mat->fwork, &mat->lfwork, &info)); 9829566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 98305fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to QR factorization %d", (int)info); 9844905a7bcSToby 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 9854905a7bcSToby Isaac mat->rank = min; 9864905a7bcSToby Isaac 9874396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_QR; 9884396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_QR; 9894905a7bcSToby Isaac A->factortype = MAT_FACTOR_QR; 9904905a7bcSToby Isaac if (m == n) { 9914396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_QR; 9924396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_QR; 9934905a7bcSToby Isaac } 9944905a7bcSToby Isaac 9959566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 9969566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 9974905a7bcSToby Isaac 9989566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * min * min * (max - min / 3.0))); 9994905a7bcSToby Isaac PetscFunctionReturn(0); 10004905a7bcSToby Isaac } 10014905a7bcSToby Isaac 1002*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatQRFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) 1003*d71ae5a4SJacob Faibussowitsch { 10044905a7bcSToby Isaac MatFactorInfo info; 10054905a7bcSToby Isaac 10064905a7bcSToby Isaac PetscFunctionBegin; 10074905a7bcSToby Isaac info.fill = 1.0; 10084905a7bcSToby Isaac 10099566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 1010cac4c232SBarry Smith PetscUseMethod(fact, "MatQRFactor_C", (Mat, IS, const MatFactorInfo *), (fact, NULL, &info)); 10114905a7bcSToby Isaac PetscFunctionReturn(0); 10124905a7bcSToby Isaac } 10134905a7bcSToby Isaac 1014*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatQRFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info) 1015*d71ae5a4SJacob Faibussowitsch { 10164905a7bcSToby Isaac PetscFunctionBegin; 10174905a7bcSToby Isaac fact->assembled = PETSC_TRUE; 10184905a7bcSToby Isaac fact->preallocated = PETSC_TRUE; 10199566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)fact, "MatQRFactorNumeric_C", MatQRFactorNumeric_SeqDense)); 10204905a7bcSToby Isaac PetscFunctionReturn(0); 10214905a7bcSToby Isaac } 10224905a7bcSToby Isaac 1023ca15aa20SStefano Zampini /* uses LAPACK */ 1024*d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A, MatFactorType ftype, Mat *fact) 1025*d71ae5a4SJacob Faibussowitsch { 1026db4efbfdSBarry Smith PetscFunctionBegin; 10279566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), fact)); 10289566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*fact, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n)); 10299566063dSJacob Faibussowitsch PetscCall(MatSetType(*fact, MATDENSE)); 103066e17bc3SBarry Smith (*fact)->trivialsymbolic = PETSC_TRUE; 10312a350339SBarry Smith if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU) { 1032db4efbfdSBarry Smith (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense; 10332a350339SBarry Smith (*fact)->ops->ilufactorsymbolic = MatLUFactorSymbolic_SeqDense; 1034bf5a80bcSToby Isaac } else if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) { 1035db4efbfdSBarry Smith (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense; 1036bf5a80bcSToby Isaac } else if (ftype == MAT_FACTOR_QR) { 10379566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)(*fact), "MatQRFactorSymbolic_C", MatQRFactorSymbolic_SeqDense)); 1038db4efbfdSBarry Smith } 1039d5f3da31SBarry Smith (*fact)->factortype = ftype; 104000c67f3bSHong Zhang 10419566063dSJacob Faibussowitsch PetscCall(PetscFree((*fact)->solvertype)); 10429566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &(*fact)->solvertype)); 10439566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_LU])); 10449566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ILU])); 10459566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_CHOLESKY])); 10469566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ICC])); 1047db4efbfdSBarry Smith PetscFunctionReturn(0); 1048db4efbfdSBarry Smith } 1049db4efbfdSBarry Smith 1050289bc588SBarry Smith /* ------------------------------------------------------------------*/ 1051*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSOR_SeqDense(Mat A, Vec bb, PetscReal omega, MatSORType flag, PetscReal shift, PetscInt its, PetscInt lits, Vec xx) 1052*d71ae5a4SJacob Faibussowitsch { 1053c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1054d9ca1df4SBarry Smith PetscScalar *x, *v = mat->v, zero = 0.0, xt; 1055d9ca1df4SBarry Smith const PetscScalar *b; 1056d0f46423SBarry Smith PetscInt m = A->rmap->n, i; 105723fff9afSBarry Smith PetscBLASInt o = 1, bm = 0; 1058289bc588SBarry Smith 10593a40ed3dSBarry Smith PetscFunctionBegin; 1060ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA) 106108401ef6SPierre Jolivet PetscCheck(A->offloadmask != PETSC_OFFLOAD_GPU, PETSC_COMM_SELF, PETSC_ERR_SUP, "Not implemented"); 1062ca15aa20SStefano Zampini #endif 1063422a814eSBarry Smith if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */ 10649566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(m, &bm)); 1065289bc588SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 10663bffc371SBarry Smith /* this is a hack fix, should have another version without the second BLASdotu */ 10679566063dSJacob Faibussowitsch PetscCall(VecSet(xx, zero)); 1068289bc588SBarry Smith } 10699566063dSJacob Faibussowitsch PetscCall(VecGetArray(xx, &x)); 10709566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(bb, &b)); 1071b965ef7fSBarry Smith its = its * lits; 107208401ef6SPierre 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); 1073289bc588SBarry Smith while (its--) { 1074fccaa45eSBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 1075289bc588SBarry Smith for (i = 0; i < m; i++) { 1076792fecdfSBarry Smith PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o)); 107755a1b374SBarry Smith x[i] = (1. - omega) * x[i] + omega * (xt + v[i + i * m] * x[i]) / (v[i + i * m] + shift); 1078289bc588SBarry Smith } 1079289bc588SBarry Smith } 1080fccaa45eSBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 1081289bc588SBarry Smith for (i = m - 1; i >= 0; i--) { 1082792fecdfSBarry Smith PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o)); 108355a1b374SBarry Smith x[i] = (1. - omega) * x[i] + omega * (xt + v[i + i * m] * x[i]) / (v[i + i * m] + shift); 1084289bc588SBarry Smith } 1085289bc588SBarry Smith } 1086289bc588SBarry Smith } 10879566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(bb, &b)); 10889566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(xx, &x)); 10893a40ed3dSBarry Smith PetscFunctionReturn(0); 1090289bc588SBarry Smith } 1091289bc588SBarry Smith 1092289bc588SBarry Smith /* -----------------------------------------------------------------*/ 1093*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultTranspose_SeqDense(Mat A, Vec xx, Vec yy) 1094*d71ae5a4SJacob Faibussowitsch { 1095c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1096d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 1097d9ca1df4SBarry Smith PetscScalar *y; 10980805154bSBarry Smith PetscBLASInt m, n, _One = 1; 1099ea709b57SSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 11003a40ed3dSBarry Smith 11013a40ed3dSBarry Smith PetscFunctionBegin; 11029566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 11039566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 11049566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 11059566063dSJacob Faibussowitsch PetscCall(VecGetArrayWrite(yy, &y)); 11065ac36cfcSBarry Smith if (!A->rmap->n || !A->cmap->n) { 11075ac36cfcSBarry Smith PetscBLASInt i; 11085ac36cfcSBarry Smith for (i = 0; i < n; i++) y[i] = 0.0; 11095ac36cfcSBarry Smith } else { 1110792fecdfSBarry Smith PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v, &mat->lda, x, &_One, &_DZero, y, &_One)); 11119566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n - A->cmap->n)); 11125ac36cfcSBarry Smith } 11139566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 11149566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayWrite(yy, &y)); 11153a40ed3dSBarry Smith PetscFunctionReturn(0); 1116289bc588SBarry Smith } 1117800995b7SMatthew Knepley 1118*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMult_SeqDense(Mat A, Vec xx, Vec yy) 1119*d71ae5a4SJacob Faibussowitsch { 1120c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1121d9ca1df4SBarry Smith PetscScalar *y, _DOne = 1.0, _DZero = 0.0; 11220805154bSBarry Smith PetscBLASInt m, n, _One = 1; 1123d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 11243a40ed3dSBarry Smith 11253a40ed3dSBarry Smith PetscFunctionBegin; 11269566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 11279566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 11289566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 11299566063dSJacob Faibussowitsch PetscCall(VecGetArrayWrite(yy, &y)); 11305ac36cfcSBarry Smith if (!A->rmap->n || !A->cmap->n) { 11315ac36cfcSBarry Smith PetscBLASInt i; 11325ac36cfcSBarry Smith for (i = 0; i < m; i++) y[i] = 0.0; 11335ac36cfcSBarry Smith } else { 1134792fecdfSBarry Smith PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DZero, y, &_One)); 11359566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n - A->rmap->n)); 11365ac36cfcSBarry Smith } 11379566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 11389566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayWrite(yy, &y)); 11393a40ed3dSBarry Smith PetscFunctionReturn(0); 1140289bc588SBarry Smith } 11416ee01492SSatish Balay 1142*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) 1143*d71ae5a4SJacob Faibussowitsch { 1144c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1145d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 1146d9ca1df4SBarry Smith PetscScalar *y, _DOne = 1.0; 11470805154bSBarry Smith PetscBLASInt m, n, _One = 1; 11483a40ed3dSBarry Smith 11493a40ed3dSBarry Smith PetscFunctionBegin; 11509566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 11519566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 11529566063dSJacob Faibussowitsch PetscCall(VecCopy(zz, yy)); 1153d0f46423SBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 11549566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 11559566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &y)); 1156792fecdfSBarry Smith PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DOne, y, &_One)); 11579566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 11589566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &y)); 11599566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n)); 11603a40ed3dSBarry Smith PetscFunctionReturn(0); 1161289bc588SBarry Smith } 11626ee01492SSatish Balay 1163*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) 1164*d71ae5a4SJacob Faibussowitsch { 1165c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1166d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 1167d9ca1df4SBarry Smith PetscScalar *y; 11680805154bSBarry Smith PetscBLASInt m, n, _One = 1; 116987828ca2SBarry Smith PetscScalar _DOne = 1.0; 11703a40ed3dSBarry Smith 11713a40ed3dSBarry Smith PetscFunctionBegin; 11729566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 11739566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 11749566063dSJacob Faibussowitsch PetscCall(VecCopy(zz, yy)); 1175d0f46423SBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 11769566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 11779566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &y)); 1178792fecdfSBarry Smith PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DOne, y, &_One)); 11799566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 11809566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &y)); 11819566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n)); 11823a40ed3dSBarry Smith PetscFunctionReturn(0); 1183289bc588SBarry Smith } 1184289bc588SBarry Smith 1185289bc588SBarry Smith /* -----------------------------------------------------------------*/ 1186*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals) 1187*d71ae5a4SJacob Faibussowitsch { 1188c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 118913f74950SBarry Smith PetscInt i; 119067e560aaSBarry Smith 11913a40ed3dSBarry Smith PetscFunctionBegin; 1192d0f46423SBarry Smith *ncols = A->cmap->n; 1193289bc588SBarry Smith if (cols) { 11949566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->cmap->n, cols)); 1195d0f46423SBarry Smith for (i = 0; i < A->cmap->n; i++) (*cols)[i] = i; 1196289bc588SBarry Smith } 1197289bc588SBarry Smith if (vals) { 1198ca15aa20SStefano Zampini const PetscScalar *v; 1199ca15aa20SStefano Zampini 12009566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 12019566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->cmap->n, vals)); 1202ca15aa20SStefano Zampini v += row; 12039371c9d4SSatish Balay for (i = 0; i < A->cmap->n; i++) { 12049371c9d4SSatish Balay (*vals)[i] = *v; 12059371c9d4SSatish Balay v += mat->lda; 12069371c9d4SSatish Balay } 12079566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 1208289bc588SBarry Smith } 12093a40ed3dSBarry Smith PetscFunctionReturn(0); 1210289bc588SBarry Smith } 12116ee01492SSatish Balay 1212*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRestoreRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals) 1213*d71ae5a4SJacob Faibussowitsch { 1214606d414cSSatish Balay PetscFunctionBegin; 1215cb4a9cd9SHong Zhang if (ncols) *ncols = 0; 12169566063dSJacob Faibussowitsch if (cols) PetscCall(PetscFree(*cols)); 12179566063dSJacob Faibussowitsch if (vals) PetscCall(PetscFree(*vals)); 12183a40ed3dSBarry Smith PetscFunctionReturn(0); 1219289bc588SBarry Smith } 1220289bc588SBarry Smith /* ----------------------------------------------------------------*/ 1221*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], const PetscScalar v[], InsertMode addv) 1222*d71ae5a4SJacob Faibussowitsch { 1223c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1224ca15aa20SStefano Zampini PetscScalar *av; 122513f74950SBarry Smith PetscInt i, j, idx = 0; 1226ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA) 1227c70f7ee4SJunchao Zhang PetscOffloadMask oldf; 1228ca15aa20SStefano Zampini #endif 1229d6dfbf8fSBarry Smith 12303a40ed3dSBarry Smith PetscFunctionBegin; 12319566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &av)); 1232289bc588SBarry Smith if (!mat->roworiented) { 1233dbb450caSBarry Smith if (addv == INSERT_VALUES) { 1234289bc588SBarry Smith for (j = 0; j < n; j++) { 12359371c9d4SSatish Balay if (indexn[j] < 0) { 12369371c9d4SSatish Balay idx += m; 12379371c9d4SSatish Balay continue; 12389371c9d4SSatish Balay } 12396bdcaf15SBarry 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); 1240289bc588SBarry Smith for (i = 0; i < m; i++) { 12419371c9d4SSatish Balay if (indexm[i] < 0) { 12429371c9d4SSatish Balay idx++; 12439371c9d4SSatish Balay continue; 12449371c9d4SSatish Balay } 12456bdcaf15SBarry 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); 1246ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] = v[idx++]; 1247289bc588SBarry Smith } 1248289bc588SBarry Smith } 12493a40ed3dSBarry Smith } else { 1250289bc588SBarry Smith for (j = 0; j < n; j++) { 12519371c9d4SSatish Balay if (indexn[j] < 0) { 12529371c9d4SSatish Balay idx += m; 12539371c9d4SSatish Balay continue; 12549371c9d4SSatish Balay } 12556bdcaf15SBarry 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); 1256289bc588SBarry Smith for (i = 0; i < m; i++) { 12579371c9d4SSatish Balay if (indexm[i] < 0) { 12589371c9d4SSatish Balay idx++; 12599371c9d4SSatish Balay continue; 12609371c9d4SSatish Balay } 12616bdcaf15SBarry 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); 1262ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] += v[idx++]; 1263289bc588SBarry Smith } 1264289bc588SBarry Smith } 1265289bc588SBarry Smith } 12663a40ed3dSBarry Smith } else { 1267dbb450caSBarry Smith if (addv == INSERT_VALUES) { 1268e8d4e0b9SBarry Smith for (i = 0; i < m; i++) { 12699371c9d4SSatish Balay if (indexm[i] < 0) { 12709371c9d4SSatish Balay idx += n; 12719371c9d4SSatish Balay continue; 12729371c9d4SSatish Balay } 12736bdcaf15SBarry 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); 1274e8d4e0b9SBarry Smith for (j = 0; j < n; j++) { 12759371c9d4SSatish Balay if (indexn[j] < 0) { 12769371c9d4SSatish Balay idx++; 12779371c9d4SSatish Balay continue; 12789371c9d4SSatish Balay } 12796bdcaf15SBarry 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); 1280ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] = v[idx++]; 1281e8d4e0b9SBarry Smith } 1282e8d4e0b9SBarry Smith } 12833a40ed3dSBarry Smith } else { 1284289bc588SBarry Smith for (i = 0; i < m; i++) { 12859371c9d4SSatish Balay if (indexm[i] < 0) { 12869371c9d4SSatish Balay idx += n; 12879371c9d4SSatish Balay continue; 12889371c9d4SSatish Balay } 12896bdcaf15SBarry 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); 1290289bc588SBarry Smith for (j = 0; j < n; j++) { 12919371c9d4SSatish Balay if (indexn[j] < 0) { 12929371c9d4SSatish Balay idx++; 12939371c9d4SSatish Balay continue; 12949371c9d4SSatish Balay } 12956bdcaf15SBarry 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); 1296ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] += v[idx++]; 1297289bc588SBarry Smith } 1298289bc588SBarry Smith } 1299289bc588SBarry Smith } 1300e8d4e0b9SBarry Smith } 1301ca15aa20SStefano Zampini /* hack to prevent unneeded copy to the GPU while returning the array */ 1302ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA) 1303c70f7ee4SJunchao Zhang oldf = A->offloadmask; 1304c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_GPU; 1305ca15aa20SStefano Zampini #endif 13069566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &av)); 1307ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA) 1308c70f7ee4SJunchao Zhang A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU); 1309ca15aa20SStefano Zampini #endif 13103a40ed3dSBarry Smith PetscFunctionReturn(0); 1311289bc588SBarry Smith } 1312e8d4e0b9SBarry Smith 1313*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], PetscScalar v[]) 1314*d71ae5a4SJacob Faibussowitsch { 1315ae80bb75SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1316ca15aa20SStefano Zampini const PetscScalar *vv; 131713f74950SBarry Smith PetscInt i, j; 1318ae80bb75SLois Curfman McInnes 13193a40ed3dSBarry Smith PetscFunctionBegin; 13209566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &vv)); 1321ae80bb75SLois Curfman McInnes /* row-oriented output */ 1322ae80bb75SLois Curfman McInnes for (i = 0; i < m; i++) { 13239371c9d4SSatish Balay if (indexm[i] < 0) { 13249371c9d4SSatish Balay v += n; 13259371c9d4SSatish Balay continue; 13269371c9d4SSatish Balay } 132708401ef6SPierre 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); 1328ae80bb75SLois Curfman McInnes for (j = 0; j < n; j++) { 13299371c9d4SSatish Balay if (indexn[j] < 0) { 13309371c9d4SSatish Balay v++; 13319371c9d4SSatish Balay continue; 13329371c9d4SSatish Balay } 133308401ef6SPierre 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); 1334ca15aa20SStefano Zampini *v++ = vv[indexn[j] * mat->lda + indexm[i]]; 1335ae80bb75SLois Curfman McInnes } 1336ae80bb75SLois Curfman McInnes } 13379566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &vv)); 13383a40ed3dSBarry Smith PetscFunctionReturn(0); 1339ae80bb75SLois Curfman McInnes } 1340ae80bb75SLois Curfman McInnes 1341289bc588SBarry Smith /* -----------------------------------------------------------------*/ 1342289bc588SBarry Smith 1343*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_Dense_Binary(Mat mat, PetscViewer viewer) 1344*d71ae5a4SJacob Faibussowitsch { 13458491ab44SLisandro Dalcin PetscBool skipHeader; 13468491ab44SLisandro Dalcin PetscViewerFormat format; 13478491ab44SLisandro Dalcin PetscInt header[4], M, N, m, lda, i, j, k; 13488491ab44SLisandro Dalcin const PetscScalar *v; 13498491ab44SLisandro Dalcin PetscScalar *vwork; 1350aabbc4fbSShri Abhyankar 1351aabbc4fbSShri Abhyankar PetscFunctionBegin; 13529566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 13539566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader)); 13549566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 13558491ab44SLisandro Dalcin if (skipHeader) format = PETSC_VIEWER_NATIVE; 1356aabbc4fbSShri Abhyankar 13579566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &M, &N)); 13588491ab44SLisandro Dalcin 13598491ab44SLisandro Dalcin /* write matrix header */ 13609371c9d4SSatish Balay header[0] = MAT_FILE_CLASSID; 13619371c9d4SSatish Balay header[1] = M; 13629371c9d4SSatish Balay header[2] = N; 13638491ab44SLisandro Dalcin header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M * N; 13649566063dSJacob Faibussowitsch if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer, header, 4, PETSC_INT)); 13658491ab44SLisandro Dalcin 13669566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mat, &m, NULL)); 13678491ab44SLisandro Dalcin if (format != PETSC_VIEWER_NATIVE) { 13688491ab44SLisandro Dalcin PetscInt nnz = m * N, *iwork; 13698491ab44SLisandro Dalcin /* store row lengths for each row */ 13709566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz, &iwork)); 13718491ab44SLisandro Dalcin for (i = 0; i < m; i++) iwork[i] = N; 13729566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 13738491ab44SLisandro Dalcin /* store column indices (zero start index) */ 13748491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 13759371c9d4SSatish Balay for (j = 0; j < N; j++, k++) iwork[k] = j; 13769566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 13779566063dSJacob Faibussowitsch PetscCall(PetscFree(iwork)); 13788491ab44SLisandro Dalcin } 13798491ab44SLisandro Dalcin /* store matrix values as a dense matrix in row major order */ 13809566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m * N, &vwork)); 13819566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(mat, &v)); 13829566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(mat, &lda)); 13838491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 13849371c9d4SSatish Balay for (j = 0; j < N; j++, k++) vwork[k] = v[i + lda * j]; 13859566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(mat, &v)); 13869566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, vwork, m * N, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 13879566063dSJacob Faibussowitsch PetscCall(PetscFree(vwork)); 13888491ab44SLisandro Dalcin PetscFunctionReturn(0); 13898491ab44SLisandro Dalcin } 13908491ab44SLisandro Dalcin 1391*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLoad_Dense_Binary(Mat mat, PetscViewer viewer) 1392*d71ae5a4SJacob Faibussowitsch { 13938491ab44SLisandro Dalcin PetscBool skipHeader; 13948491ab44SLisandro Dalcin PetscInt header[4], M, N, m, nz, lda, i, j, k; 13958491ab44SLisandro Dalcin PetscInt rows, cols; 13968491ab44SLisandro Dalcin PetscScalar *v, *vwork; 13978491ab44SLisandro Dalcin 13988491ab44SLisandro Dalcin PetscFunctionBegin; 13999566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 14009566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader)); 14018491ab44SLisandro Dalcin 14028491ab44SLisandro Dalcin if (!skipHeader) { 14039566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, header, 4, NULL, PETSC_INT)); 140408401ef6SPierre Jolivet PetscCheck(header[0] == MAT_FILE_CLASSID, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Not a matrix object in file"); 14059371c9d4SSatish Balay M = header[1]; 14069371c9d4SSatish Balay N = header[2]; 140708401ef6SPierre Jolivet PetscCheck(M >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix row size (%" PetscInt_FMT ") in file is negative", M); 140808401ef6SPierre Jolivet PetscCheck(N >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix column size (%" PetscInt_FMT ") in file is negative", N); 14098491ab44SLisandro Dalcin nz = header[3]; 1410aed4548fSBarry Smith PetscCheck(nz == MATRIX_BINARY_FORMAT_DENSE || nz >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Unknown matrix format %" PetscInt_FMT " in file", nz); 1411aabbc4fbSShri Abhyankar } else { 14129566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &M, &N)); 1413aed4548fSBarry 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"); 14148491ab44SLisandro Dalcin nz = MATRIX_BINARY_FORMAT_DENSE; 1415e6324fbbSBarry Smith } 1416aabbc4fbSShri Abhyankar 14178491ab44SLisandro Dalcin /* setup global sizes if not set */ 14188491ab44SLisandro Dalcin if (mat->rmap->N < 0) mat->rmap->N = M; 14198491ab44SLisandro Dalcin if (mat->cmap->N < 0) mat->cmap->N = N; 14209566063dSJacob Faibussowitsch PetscCall(MatSetUp(mat)); 14218491ab44SLisandro Dalcin /* check if global sizes are correct */ 14229566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &rows, &cols)); 1423aed4548fSBarry 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); 1424aabbc4fbSShri Abhyankar 14259566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, NULL, &N)); 14269566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mat, &m, NULL)); 14279566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(mat, &v)); 14289566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(mat, &lda)); 14298491ab44SLisandro Dalcin if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense format */ 14308491ab44SLisandro Dalcin PetscInt nnz = m * N; 14318491ab44SLisandro Dalcin /* read in matrix values */ 14329566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz, &vwork)); 14339566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 14348491ab44SLisandro Dalcin /* store values in column major order */ 14358491ab44SLisandro Dalcin for (j = 0; j < N; j++) 14369371c9d4SSatish Balay for (i = 0; i < m; i++) v[i + lda * j] = vwork[i * N + j]; 14379566063dSJacob Faibussowitsch PetscCall(PetscFree(vwork)); 14388491ab44SLisandro Dalcin } else { /* matrix in file is sparse format */ 14398491ab44SLisandro Dalcin PetscInt nnz = 0, *rlens, *icols; 14408491ab44SLisandro Dalcin /* read in row lengths */ 14419566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m, &rlens)); 14429566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, rlens, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 14438491ab44SLisandro Dalcin for (i = 0; i < m; i++) nnz += rlens[i]; 14448491ab44SLisandro Dalcin /* read in column indices and values */ 14459566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(nnz, &icols, nnz, &vwork)); 14469566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, icols, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 14479566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 14488491ab44SLisandro Dalcin /* store values in column major order */ 14498491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 14509371c9d4SSatish Balay for (j = 0; j < rlens[i]; j++, k++) v[i + lda * icols[k]] = vwork[k]; 14519566063dSJacob Faibussowitsch PetscCall(PetscFree(rlens)); 14529566063dSJacob Faibussowitsch PetscCall(PetscFree2(icols, vwork)); 1453aabbc4fbSShri Abhyankar } 14549566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(mat, &v)); 14559566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY)); 14569566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY)); 1457aabbc4fbSShri Abhyankar PetscFunctionReturn(0); 1458aabbc4fbSShri Abhyankar } 1459aabbc4fbSShri Abhyankar 1460*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer) 1461*d71ae5a4SJacob Faibussowitsch { 1462eb91f321SVaclav Hapla PetscBool isbinary, ishdf5; 1463eb91f321SVaclav Hapla 1464eb91f321SVaclav Hapla PetscFunctionBegin; 1465eb91f321SVaclav Hapla PetscValidHeaderSpecific(newMat, MAT_CLASSID, 1); 1466eb91f321SVaclav Hapla PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1467eb91f321SVaclav Hapla /* force binary viewer to load .info file if it has not yet done so */ 14689566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 14699566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 14709566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5)); 1471eb91f321SVaclav Hapla if (isbinary) { 14729566063dSJacob Faibussowitsch PetscCall(MatLoad_Dense_Binary(newMat, viewer)); 1473eb91f321SVaclav Hapla } else if (ishdf5) { 1474eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5) 14759566063dSJacob Faibussowitsch PetscCall(MatLoad_Dense_HDF5(newMat, viewer)); 1476eb91f321SVaclav Hapla #else 1477eb91f321SVaclav Hapla SETERRQ(PetscObjectComm((PetscObject)newMat), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1478eb91f321SVaclav Hapla #endif 1479eb91f321SVaclav Hapla } else { 148098921bdaSJacob 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); 1481eb91f321SVaclav Hapla } 1482eb91f321SVaclav Hapla PetscFunctionReturn(0); 1483eb91f321SVaclav Hapla } 1484eb91f321SVaclav Hapla 1485*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_ASCII(Mat A, PetscViewer viewer) 1486*d71ae5a4SJacob Faibussowitsch { 1487932b0c3eSLois Curfman McInnes Mat_SeqDense *a = (Mat_SeqDense *)A->data; 148813f74950SBarry Smith PetscInt i, j; 14892dcb1b2aSMatthew Knepley const char *name; 1490ca15aa20SStefano Zampini PetscScalar *v, *av; 1491f3ef73ceSBarry Smith PetscViewerFormat format; 14925f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX) 1493ace3abfcSBarry Smith PetscBool allreal = PETSC_TRUE; 14945f481a85SSatish Balay #endif 1495932b0c3eSLois Curfman McInnes 14963a40ed3dSBarry Smith PetscFunctionBegin; 14979566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&av)); 14989566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 1499456192e2SBarry Smith if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 15003a40ed3dSBarry Smith PetscFunctionReturn(0); /* do nothing for now */ 1501fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 15029566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE)); 1503d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 1504ca15aa20SStefano Zampini v = av + i; 15059566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "row %" PetscInt_FMT ":", i)); 1506d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1507aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 1508329f5518SBarry Smith if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) { 15099566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g + %g i) ", j, (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v))); 1510329f5518SBarry Smith } else if (PetscRealPart(*v)) { 15119566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)PetscRealPart(*v))); 15126831982aSBarry Smith } 151380cd9d93SLois Curfman McInnes #else 151448a46eb9SPierre Jolivet if (*v) PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)*v)); 151580cd9d93SLois Curfman McInnes #endif 15161b807ce4Svictorle v += a->lda; 151780cd9d93SLois Curfman McInnes } 15189566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 151980cd9d93SLois Curfman McInnes } 15209566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE)); 15213a40ed3dSBarry Smith } else { 15229566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE)); 1523aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 152447989497SBarry Smith /* determine if matrix has all real values */ 1525bcd8d3a4SJose E. Roman for (j = 0; j < A->cmap->n; j++) { 1526bcd8d3a4SJose E. Roman v = av + j * a->lda; 1527bcd8d3a4SJose E. Roman for (i = 0; i < A->rmap->n; i++) { 15289371c9d4SSatish Balay if (PetscImaginaryPart(v[i])) { 15299371c9d4SSatish Balay allreal = PETSC_FALSE; 15309371c9d4SSatish Balay break; 15319371c9d4SSatish Balay } 153247989497SBarry Smith } 1533bcd8d3a4SJose E. Roman } 153447989497SBarry Smith #endif 1535fb9695e5SSatish Balay if (format == PETSC_VIEWER_ASCII_MATLAB) { 15369566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)A, &name)); 15379566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%% Size = %" PetscInt_FMT " %" PetscInt_FMT " \n", A->rmap->n, A->cmap->n)); 15389566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%s = zeros(%" PetscInt_FMT ",%" PetscInt_FMT ");\n", name, A->rmap->n, A->cmap->n)); 15399566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%s = [\n", name)); 1540ffac6cdbSBarry Smith } 1541ffac6cdbSBarry Smith 1542d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 1543ca15aa20SStefano Zampini v = av + i; 1544d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1545aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 154647989497SBarry Smith if (allreal) { 15479566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)PetscRealPart(*v))); 154847989497SBarry Smith } else { 15499566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e + %18.16ei ", (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v))); 155047989497SBarry Smith } 1551289bc588SBarry Smith #else 15529566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)*v)); 1553289bc588SBarry Smith #endif 15541b807ce4Svictorle v += a->lda; 1555289bc588SBarry Smith } 15569566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 1557289bc588SBarry Smith } 155848a46eb9SPierre Jolivet if (format == PETSC_VIEWER_ASCII_MATLAB) PetscCall(PetscViewerASCIIPrintf(viewer, "];\n")); 15599566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE)); 1560da3a660dSBarry Smith } 15619566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&av)); 15629566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer)); 15633a40ed3dSBarry Smith PetscFunctionReturn(0); 1564289bc588SBarry Smith } 1565289bc588SBarry Smith 15669804daf3SBarry Smith #include <petscdraw.h> 1567*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw, void *Aa) 1568*d71ae5a4SJacob Faibussowitsch { 1569f1af5d2fSBarry Smith Mat A = (Mat)Aa; 1570383922c3SLisandro Dalcin PetscInt m = A->rmap->n, n = A->cmap->n, i, j; 1571383922c3SLisandro Dalcin int color = PETSC_DRAW_WHITE; 1572ca15aa20SStefano Zampini const PetscScalar *v; 1573b0a32e0cSBarry Smith PetscViewer viewer; 1574b05fc000SLisandro Dalcin PetscReal xl, yl, xr, yr, x_l, x_r, y_l, y_r; 1575f3ef73ceSBarry Smith PetscViewerFormat format; 1576f1af5d2fSBarry Smith 1577f1af5d2fSBarry Smith PetscFunctionBegin; 15789566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)A, "Zoomviewer", (PetscObject *)&viewer)); 15799566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 15809566063dSJacob Faibussowitsch PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr)); 1581f1af5d2fSBarry Smith 1582f1af5d2fSBarry Smith /* Loop over matrix elements drawing boxes */ 15839566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 1584fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 1585d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 1586f1af5d2fSBarry Smith /* Blue for negative and Red for positive */ 1587f1af5d2fSBarry Smith for (j = 0; j < n; j++) { 15889371c9d4SSatish Balay x_l = j; 15899371c9d4SSatish Balay x_r = x_l + 1.0; 1590f1af5d2fSBarry Smith for (i = 0; i < m; i++) { 1591f1af5d2fSBarry Smith y_l = m - i - 1.0; 1592f1af5d2fSBarry Smith y_r = y_l + 1.0; 1593ca15aa20SStefano Zampini if (PetscRealPart(v[j * m + i]) > 0.) color = PETSC_DRAW_RED; 1594ca15aa20SStefano Zampini else if (PetscRealPart(v[j * m + i]) < 0.) color = PETSC_DRAW_BLUE; 1595ca15aa20SStefano Zampini else continue; 15969566063dSJacob Faibussowitsch PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color)); 1597f1af5d2fSBarry Smith } 1598f1af5d2fSBarry Smith } 1599d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 1600f1af5d2fSBarry Smith } else { 1601f1af5d2fSBarry Smith /* use contour shading to indicate magnitude of values */ 1602f1af5d2fSBarry Smith /* first determine max of all nonzero values */ 1603b05fc000SLisandro Dalcin PetscReal minv = 0.0, maxv = 0.0; 1604b05fc000SLisandro Dalcin PetscDraw popup; 1605b05fc000SLisandro Dalcin 1606f1af5d2fSBarry Smith for (i = 0; i < m * n; i++) { 1607f1af5d2fSBarry Smith if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]); 1608f1af5d2fSBarry Smith } 1609383922c3SLisandro Dalcin if (minv >= maxv) maxv = minv + PETSC_SMALL; 16109566063dSJacob Faibussowitsch PetscCall(PetscDrawGetPopup(draw, &popup)); 16119566063dSJacob Faibussowitsch PetscCall(PetscDrawScalePopup(popup, minv, maxv)); 1612383922c3SLisandro Dalcin 1613d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 1614f1af5d2fSBarry Smith for (j = 0; j < n; j++) { 1615f1af5d2fSBarry Smith x_l = j; 1616f1af5d2fSBarry Smith x_r = x_l + 1.0; 1617f1af5d2fSBarry Smith for (i = 0; i < m; i++) { 1618f1af5d2fSBarry Smith y_l = m - i - 1.0; 1619f1af5d2fSBarry Smith y_r = y_l + 1.0; 1620b05fc000SLisandro Dalcin color = PetscDrawRealToColor(PetscAbsScalar(v[j * m + i]), minv, maxv); 16219566063dSJacob Faibussowitsch PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color)); 1622f1af5d2fSBarry Smith } 1623f1af5d2fSBarry Smith } 1624d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 1625f1af5d2fSBarry Smith } 16269566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 1627f1af5d2fSBarry Smith PetscFunctionReturn(0); 1628f1af5d2fSBarry Smith } 1629f1af5d2fSBarry Smith 1630*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw(Mat A, PetscViewer viewer) 1631*d71ae5a4SJacob Faibussowitsch { 1632b0a32e0cSBarry Smith PetscDraw draw; 1633ace3abfcSBarry Smith PetscBool isnull; 1634329f5518SBarry Smith PetscReal xr, yr, xl, yl, h, w; 1635f1af5d2fSBarry Smith 1636f1af5d2fSBarry Smith PetscFunctionBegin; 16379566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 16389566063dSJacob Faibussowitsch PetscCall(PetscDrawIsNull(draw, &isnull)); 1639abc0a331SBarry Smith if (isnull) PetscFunctionReturn(0); 1640f1af5d2fSBarry Smith 16419371c9d4SSatish Balay xr = A->cmap->n; 16429371c9d4SSatish Balay yr = A->rmap->n; 16439371c9d4SSatish Balay h = yr / 10.0; 16449371c9d4SSatish Balay w = xr / 10.0; 16459371c9d4SSatish Balay xr += w; 16469371c9d4SSatish Balay yr += h; 16479371c9d4SSatish Balay xl = -w; 16489371c9d4SSatish Balay yl = -h; 16499566063dSJacob Faibussowitsch PetscCall(PetscDrawSetCoordinates(draw, xl, yl, xr, yr)); 16509566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", (PetscObject)viewer)); 16519566063dSJacob Faibussowitsch PetscCall(PetscDrawZoom(draw, MatView_SeqDense_Draw_Zoom, A)); 16529566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", NULL)); 16539566063dSJacob Faibussowitsch PetscCall(PetscDrawSave(draw)); 1654f1af5d2fSBarry Smith PetscFunctionReturn(0); 1655f1af5d2fSBarry Smith } 1656f1af5d2fSBarry Smith 1657*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_SeqDense(Mat A, PetscViewer viewer) 1658*d71ae5a4SJacob Faibussowitsch { 1659ace3abfcSBarry Smith PetscBool iascii, isbinary, isdraw; 1660932b0c3eSLois Curfman McInnes 16613a40ed3dSBarry Smith PetscFunctionBegin; 16629566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 16639566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 16649566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 16651baa6e33SBarry Smith if (iascii) PetscCall(MatView_SeqDense_ASCII(A, viewer)); 16661baa6e33SBarry Smith else if (isbinary) PetscCall(MatView_Dense_Binary(A, viewer)); 16671baa6e33SBarry Smith else if (isdraw) PetscCall(MatView_SeqDense_Draw(A, viewer)); 16683a40ed3dSBarry Smith PetscFunctionReturn(0); 1669932b0c3eSLois Curfman McInnes } 1670289bc588SBarry Smith 1671*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A, const PetscScalar *array) 1672*d71ae5a4SJacob Faibussowitsch { 1673d3042a70SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1674d3042a70SBarry Smith 1675d3042a70SBarry Smith PetscFunctionBegin; 167628b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 167728b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 167828b400f6SJacob Faibussowitsch PetscCheck(!a->unplacedarray, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreArray() first"); 1679d3042a70SBarry Smith a->unplacedarray = a->v; 1680d3042a70SBarry Smith a->unplaced_user_alloc = a->user_alloc; 1681d3042a70SBarry Smith a->v = (PetscScalar *)array; 1682637a0070SStefano Zampini a->user_alloc = PETSC_TRUE; 1683ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA) 1684c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_CPU; 1685ca15aa20SStefano Zampini #endif 1686d3042a70SBarry Smith PetscFunctionReturn(0); 1687d3042a70SBarry Smith } 1688d3042a70SBarry Smith 1689*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseResetArray_SeqDense(Mat A) 1690*d71ae5a4SJacob Faibussowitsch { 1691d3042a70SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1692d3042a70SBarry Smith 1693d3042a70SBarry Smith PetscFunctionBegin; 169428b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 169528b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 1696d3042a70SBarry Smith a->v = a->unplacedarray; 1697d3042a70SBarry Smith a->user_alloc = a->unplaced_user_alloc; 1698d3042a70SBarry Smith a->unplacedarray = NULL; 1699ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA) 1700c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_CPU; 1701ca15aa20SStefano Zampini #endif 1702d3042a70SBarry Smith PetscFunctionReturn(0); 1703d3042a70SBarry Smith } 1704d3042a70SBarry Smith 1705*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A, const PetscScalar *array) 1706*d71ae5a4SJacob Faibussowitsch { 1707d5ea218eSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1708d5ea218eSStefano Zampini 1709d5ea218eSStefano Zampini PetscFunctionBegin; 171028b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 171128b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 17129566063dSJacob Faibussowitsch if (!a->user_alloc) PetscCall(PetscFree(a->v)); 1713d5ea218eSStefano Zampini a->v = (PetscScalar *)array; 1714d5ea218eSStefano Zampini a->user_alloc = PETSC_FALSE; 1715d5ea218eSStefano Zampini #if defined(PETSC_HAVE_CUDA) 1716d5ea218eSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 1717d5ea218eSStefano Zampini #endif 1718d5ea218eSStefano Zampini PetscFunctionReturn(0); 1719d5ea218eSStefano Zampini } 1720d5ea218eSStefano Zampini 1721*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDestroy_SeqDense(Mat mat) 1722*d71ae5a4SJacob Faibussowitsch { 1723ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)mat->data; 172490f02eecSBarry Smith 17253a40ed3dSBarry Smith PetscFunctionBegin; 1726aa482453SBarry Smith #if defined(PETSC_USE_LOG) 1727c0aa6a63SJacob Faibussowitsch PetscLogObjectState((PetscObject)mat, "Rows %" PetscInt_FMT " Cols %" PetscInt_FMT, mat->rmap->n, mat->cmap->n); 1728a5a9c739SBarry Smith #endif 17299566063dSJacob Faibussowitsch PetscCall(VecDestroy(&(l->qrrhs))); 17309566063dSJacob Faibussowitsch PetscCall(PetscFree(l->tau)); 17319566063dSJacob Faibussowitsch PetscCall(PetscFree(l->pivots)); 17329566063dSJacob Faibussowitsch PetscCall(PetscFree(l->fwork)); 17339566063dSJacob Faibussowitsch PetscCall(MatDestroy(&l->ptapwork)); 17349566063dSJacob Faibussowitsch if (!l->user_alloc) PetscCall(PetscFree(l->v)); 17359566063dSJacob Faibussowitsch if (!l->unplaced_user_alloc) PetscCall(PetscFree(l->unplacedarray)); 173628b400f6SJacob Faibussowitsch PetscCheck(!l->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 173728b400f6SJacob Faibussowitsch PetscCheck(!l->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 17389566063dSJacob Faibussowitsch PetscCall(VecDestroy(&l->cvec)); 17399566063dSJacob Faibussowitsch PetscCall(MatDestroy(&l->cmat)); 17409566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->data)); 1741dbd8c25aSHong Zhang 17429566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)mat, NULL)); 17439566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactor_C", NULL)); 17442e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorSymbolic_C", NULL)); 17452e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorNumeric_C", NULL)); 17469566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetLDA_C", NULL)); 17479566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseSetLDA_C", NULL)); 17489566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArray_C", NULL)); 17499566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArray_C", NULL)); 17509566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDensePlaceArray_C", NULL)); 17519566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseResetArray_C", NULL)); 17529566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseReplaceArray_C", NULL)); 17539566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayRead_C", NULL)); 17549566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayRead_C", NULL)); 17559566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayWrite_C", NULL)); 17569566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayWrite_C", NULL)); 17579566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqaij_C", NULL)); 17588baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 17599566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_elemental_C", NULL)); 17608baccfbdSHong Zhang #endif 1761d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 17629566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_scalapack_C", NULL)); 1763d24d4204SJose E. Roman #endif 17642bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA) 17659566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensecuda_C", NULL)); 17669566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", NULL)); 17679566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdense_C", NULL)); 17682e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensecuda_C", NULL)); 17692bf066beSStefano Zampini #endif 17709566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatSeqDenseSetPreallocation_C", NULL)); 17719566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqaij_seqdense_C", NULL)); 17729566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdense_C", NULL)); 17739566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqbaij_seqdense_C", NULL)); 17749566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqsbaij_seqdense_C", NULL)); 177552c5f739Sprj- 17769566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumn_C", NULL)); 17779566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumn_C", NULL)); 17789566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVec_C", NULL)); 17799566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVec_C", NULL)); 17809566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecRead_C", NULL)); 17819566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecRead_C", NULL)); 17829566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecWrite_C", NULL)); 17839566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecWrite_C", NULL)); 17849566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetSubMatrix_C", NULL)); 17859566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreSubMatrix_C", NULL)); 17863a40ed3dSBarry Smith PetscFunctionReturn(0); 1787289bc588SBarry Smith } 1788289bc588SBarry Smith 1789*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatTranspose_SeqDense(Mat A, MatReuse reuse, Mat *matout) 1790*d71ae5a4SJacob Faibussowitsch { 1791c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 17926536e3caSStefano Zampini PetscInt k, j, m = A->rmap->n, M = mat->lda, n = A->cmap->n; 179387828ca2SBarry Smith PetscScalar *v, tmp; 179448b35521SBarry Smith 17953a40ed3dSBarry Smith PetscFunctionBegin; 17967fb60732SBarry Smith if (reuse == MAT_REUSE_MATRIX) PetscCall(MatTransposeCheckNonzeroState_Private(A, *matout)); 17976536e3caSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 17986536e3caSStefano Zampini if (m == n) { /* in place transpose */ 17999566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 1800d3e5ee88SLois Curfman McInnes for (j = 0; j < m; j++) { 1801289bc588SBarry Smith for (k = 0; k < j; k++) { 18021b807ce4Svictorle tmp = v[j + k * M]; 18031b807ce4Svictorle v[j + k * M] = v[k + j * M]; 18041b807ce4Svictorle v[k + j * M] = tmp; 1805289bc588SBarry Smith } 1806289bc588SBarry Smith } 18079566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 18086536e3caSStefano Zampini } else { /* reuse memory, temporary allocates new memory */ 18096536e3caSStefano Zampini PetscScalar *v2; 18106536e3caSStefano Zampini PetscLayout tmplayout; 18116536e3caSStefano Zampini 18129566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((size_t)m * n, &v2)); 18139566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 18146536e3caSStefano Zampini for (j = 0; j < n; j++) { 18156536e3caSStefano Zampini for (k = 0; k < m; k++) v2[j + (size_t)k * n] = v[k + (size_t)j * M]; 18166536e3caSStefano Zampini } 18179566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(v, v2, (size_t)m * n)); 18189566063dSJacob Faibussowitsch PetscCall(PetscFree(v2)); 18199566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 18206536e3caSStefano Zampini /* cleanup size dependent quantities */ 18219566063dSJacob Faibussowitsch PetscCall(VecDestroy(&mat->cvec)); 18229566063dSJacob Faibussowitsch PetscCall(MatDestroy(&mat->cmat)); 18239566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->pivots)); 18249566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->fwork)); 18259566063dSJacob Faibussowitsch PetscCall(MatDestroy(&mat->ptapwork)); 18266536e3caSStefano Zampini /* swap row/col layouts */ 18276536e3caSStefano Zampini mat->lda = n; 18286536e3caSStefano Zampini tmplayout = A->rmap; 18296536e3caSStefano Zampini A->rmap = A->cmap; 18306536e3caSStefano Zampini A->cmap = tmplayout; 18316536e3caSStefano Zampini } 18323a40ed3dSBarry Smith } else { /* out-of-place transpose */ 1833d3e5ee88SLois Curfman McInnes Mat tmat; 1834ec8511deSBarry Smith Mat_SeqDense *tmatd; 183587828ca2SBarry Smith PetscScalar *v2; 1836af36a384SStefano Zampini PetscInt M2; 1837ea709b57SSatish Balay 18386536e3caSStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 18399566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &tmat)); 18409566063dSJacob Faibussowitsch PetscCall(MatSetSizes(tmat, A->cmap->n, A->rmap->n, A->cmap->n, A->rmap->n)); 18419566063dSJacob Faibussowitsch PetscCall(MatSetType(tmat, ((PetscObject)A)->type_name)); 18429566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(tmat, NULL)); 1843ca15aa20SStefano Zampini } else tmat = *matout; 1844ca15aa20SStefano Zampini 18459566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&v)); 18469566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(tmat, &v2)); 1847ec8511deSBarry Smith tmatd = (Mat_SeqDense *)tmat->data; 1848ca15aa20SStefano Zampini M2 = tmatd->lda; 1849d3e5ee88SLois Curfman McInnes for (j = 0; j < n; j++) { 1850af36a384SStefano Zampini for (k = 0; k < m; k++) v2[j + k * M2] = v[k + j * M]; 1851d3e5ee88SLois Curfman McInnes } 18529566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(tmat, &v2)); 18539566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&v)); 18549566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(tmat, MAT_FINAL_ASSEMBLY)); 18559566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(tmat, MAT_FINAL_ASSEMBLY)); 18566536e3caSStefano Zampini *matout = tmat; 185748b35521SBarry Smith } 18583a40ed3dSBarry Smith PetscFunctionReturn(0); 1859289bc588SBarry Smith } 1860289bc588SBarry Smith 1861*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatEqual_SeqDense(Mat A1, Mat A2, PetscBool *flg) 1862*d71ae5a4SJacob Faibussowitsch { 1863c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat1 = (Mat_SeqDense *)A1->data; 1864c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat2 = (Mat_SeqDense *)A2->data; 1865ca15aa20SStefano Zampini PetscInt i; 1866ca15aa20SStefano Zampini const PetscScalar *v1, *v2; 18679ea5d5aeSSatish Balay 18683a40ed3dSBarry Smith PetscFunctionBegin; 18699371c9d4SSatish Balay if (A1->rmap->n != A2->rmap->n) { 18709371c9d4SSatish Balay *flg = PETSC_FALSE; 18719371c9d4SSatish Balay PetscFunctionReturn(0); 18729371c9d4SSatish Balay } 18739371c9d4SSatish Balay if (A1->cmap->n != A2->cmap->n) { 18749371c9d4SSatish Balay *flg = PETSC_FALSE; 18759371c9d4SSatish Balay PetscFunctionReturn(0); 18769371c9d4SSatish Balay } 18779566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A1, &v1)); 18789566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A2, &v2)); 1879ca15aa20SStefano Zampini for (i = 0; i < A1->cmap->n; i++) { 18809566063dSJacob Faibussowitsch PetscCall(PetscArraycmp(v1, v2, A1->rmap->n, flg)); 1881ca15aa20SStefano Zampini if (*flg == PETSC_FALSE) PetscFunctionReturn(0); 1882ca15aa20SStefano Zampini v1 += mat1->lda; 1883ca15aa20SStefano Zampini v2 += mat2->lda; 18841b807ce4Svictorle } 18859566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A1, &v1)); 18869566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A2, &v2)); 188777c4ece6SBarry Smith *flg = PETSC_TRUE; 18883a40ed3dSBarry Smith PetscFunctionReturn(0); 1889289bc588SBarry Smith } 1890289bc588SBarry Smith 1891*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetDiagonal_SeqDense(Mat A, Vec v) 1892*d71ae5a4SJacob Faibussowitsch { 1893c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 189413f74950SBarry Smith PetscInt i, n, len; 1895ca15aa20SStefano Zampini PetscScalar *x; 1896ca15aa20SStefano Zampini const PetscScalar *vv; 189744cd7ae7SLois Curfman McInnes 18983a40ed3dSBarry Smith PetscFunctionBegin; 18999566063dSJacob Faibussowitsch PetscCall(VecGetSize(v, &n)); 19009566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 1901d0f46423SBarry Smith len = PetscMin(A->rmap->n, A->cmap->n); 19029566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &vv)); 190308401ef6SPierre Jolivet PetscCheck(n == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming mat and vec"); 1904ad540459SPierre Jolivet for (i = 0; i < len; i++) x[i] = vv[i * mat->lda + i]; 19059566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &vv)); 19069566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 19073a40ed3dSBarry Smith PetscFunctionReturn(0); 1908289bc588SBarry Smith } 1909289bc588SBarry Smith 1910*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDiagonalScale_SeqDense(Mat A, Vec ll, Vec rr) 1911*d71ae5a4SJacob Faibussowitsch { 1912c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1913f1ceaac6SMatthew G. Knepley const PetscScalar *l, *r; 1914ca15aa20SStefano Zampini PetscScalar x, *v, *vv; 1915d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n; 191655659b69SBarry Smith 19173a40ed3dSBarry Smith PetscFunctionBegin; 19189566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &vv)); 191928988994SBarry Smith if (ll) { 19209566063dSJacob Faibussowitsch PetscCall(VecGetSize(ll, &m)); 19219566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(ll, &l)); 192208401ef6SPierre Jolivet PetscCheck(m == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Left scaling vec wrong size"); 1923da3a660dSBarry Smith for (i = 0; i < m; i++) { 1924da3a660dSBarry Smith x = l[i]; 1925ca15aa20SStefano Zampini v = vv + i; 19269371c9d4SSatish Balay for (j = 0; j < n; j++) { 19279371c9d4SSatish Balay (*v) *= x; 19289371c9d4SSatish Balay v += mat->lda; 19299371c9d4SSatish Balay } 1930da3a660dSBarry Smith } 19319566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(ll, &l)); 19329566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * n * m)); 1933da3a660dSBarry Smith } 193428988994SBarry Smith if (rr) { 19359566063dSJacob Faibussowitsch PetscCall(VecGetSize(rr, &n)); 19369566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(rr, &r)); 193708401ef6SPierre Jolivet PetscCheck(n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Right scaling vec wrong size"); 1938da3a660dSBarry Smith for (i = 0; i < n; i++) { 1939da3a660dSBarry Smith x = r[i]; 1940ca15aa20SStefano Zampini v = vv + i * mat->lda; 19412205254eSKarl Rupp for (j = 0; j < m; j++) (*v++) *= x; 1942da3a660dSBarry Smith } 19439566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(rr, &r)); 19449566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * n * m)); 1945da3a660dSBarry Smith } 19469566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &vv)); 19473a40ed3dSBarry Smith PetscFunctionReturn(0); 1948289bc588SBarry Smith } 1949289bc588SBarry Smith 1950*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatNorm_SeqDense(Mat A, NormType type, PetscReal *nrm) 1951*d71ae5a4SJacob Faibussowitsch { 1952c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1953ca15aa20SStefano Zampini PetscScalar *v, *vv; 1954329f5518SBarry Smith PetscReal sum = 0.0; 195575f6d85dSStefano Zampini PetscInt lda, m = A->rmap->n, i, j; 195655659b69SBarry Smith 19573a40ed3dSBarry Smith PetscFunctionBegin; 19589566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&vv)); 19599566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(A, &lda)); 1960ca15aa20SStefano Zampini v = vv; 1961289bc588SBarry Smith if (type == NORM_FROBENIUS) { 1962a5ce6ee0Svictorle if (lda > m) { 1963d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1964ca15aa20SStefano Zampini v = vv + j * lda; 1965a5ce6ee0Svictorle for (i = 0; i < m; i++) { 19669371c9d4SSatish Balay sum += PetscRealPart(PetscConj(*v) * (*v)); 19679371c9d4SSatish Balay v++; 1968a5ce6ee0Svictorle } 1969a5ce6ee0Svictorle } 1970a5ce6ee0Svictorle } else { 1971570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16) 1972570b7f6dSBarry Smith PetscBLASInt one = 1, cnt = A->cmap->n * A->rmap->n; 1973792fecdfSBarry Smith PetscCallBLAS("BLASnrm2", *nrm = BLASnrm2_(&cnt, v, &one)); 1974570b7f6dSBarry Smith } 1975570b7f6dSBarry Smith #else 1976d0f46423SBarry Smith for (i = 0; i < A->cmap->n * A->rmap->n; i++) { 19779371c9d4SSatish Balay sum += PetscRealPart(PetscConj(*v) * (*v)); 19789371c9d4SSatish Balay v++; 1979289bc588SBarry Smith } 1980a5ce6ee0Svictorle } 19818f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 1982570b7f6dSBarry Smith #endif 19839566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->cmap->n * A->rmap->n)); 19843a40ed3dSBarry Smith } else if (type == NORM_1) { 1985064f8208SBarry Smith *nrm = 0.0; 1986d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1987ca15aa20SStefano Zampini v = vv + j * mat->lda; 1988289bc588SBarry Smith sum = 0.0; 1989d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 19909371c9d4SSatish Balay sum += PetscAbsScalar(*v); 19919371c9d4SSatish Balay v++; 1992289bc588SBarry Smith } 1993064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 1994289bc588SBarry Smith } 19959566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n)); 19963a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 1997064f8208SBarry Smith *nrm = 0.0; 1998d0f46423SBarry Smith for (j = 0; j < A->rmap->n; j++) { 1999ca15aa20SStefano Zampini v = vv + j; 2000289bc588SBarry Smith sum = 0.0; 2001d0f46423SBarry Smith for (i = 0; i < A->cmap->n; i++) { 20029371c9d4SSatish Balay sum += PetscAbsScalar(*v); 20039371c9d4SSatish Balay v += mat->lda; 2004289bc588SBarry Smith } 2005064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 2006289bc588SBarry Smith } 20079566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n)); 2008e7e72b3dSBarry Smith } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "No two norm"); 20099566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&vv)); 20103a40ed3dSBarry Smith PetscFunctionReturn(0); 2011289bc588SBarry Smith } 2012289bc588SBarry Smith 2013*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetOption_SeqDense(Mat A, MatOption op, PetscBool flg) 2014*d71ae5a4SJacob Faibussowitsch { 2015c0bbcb79SLois Curfman McInnes Mat_SeqDense *aij = (Mat_SeqDense *)A->data; 201667e560aaSBarry Smith 20173a40ed3dSBarry Smith PetscFunctionBegin; 2018b5a2b587SKris Buschelman switch (op) { 2019*d71ae5a4SJacob Faibussowitsch case MAT_ROW_ORIENTED: 2020*d71ae5a4SJacob Faibussowitsch aij->roworiented = flg; 2021*d71ae5a4SJacob Faibussowitsch break; 2022512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 2023b5a2b587SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 20243971808eSMatthew Knepley case MAT_NEW_NONZERO_ALLOCATION_ERR: 20258c78258cSHong Zhang case MAT_FORCE_DIAGONAL_ENTRIES: 202613fa8e87SLisandro Dalcin case MAT_KEEP_NONZERO_PATTERN: 2027b5a2b587SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 2028b5a2b587SKris Buschelman case MAT_USE_HASH_TABLE: 20290f8fb01aSBarry Smith case MAT_IGNORE_ZERO_ENTRIES: 20305021d80fSJed Brown case MAT_IGNORE_LOWER_TRIANGULAR: 2031*d71ae5a4SJacob Faibussowitsch case MAT_SORTED_FULL: 2032*d71ae5a4SJacob Faibussowitsch PetscCall(PetscInfo(A, "Option %s ignored\n", MatOptions[op])); 2033*d71ae5a4SJacob Faibussowitsch break; 20345021d80fSJed Brown case MAT_SPD: 203577e54ba9SKris Buschelman case MAT_SYMMETRIC: 203677e54ba9SKris Buschelman case MAT_STRUCTURALLY_SYMMETRIC: 20379a4540c5SBarry Smith case MAT_HERMITIAN: 20389a4540c5SBarry Smith case MAT_SYMMETRY_ETERNAL: 2039b94d7dedSBarry Smith case MAT_STRUCTURAL_SYMMETRY_ETERNAL: 2040*d71ae5a4SJacob Faibussowitsch case MAT_SPD_ETERNAL: 2041*d71ae5a4SJacob Faibussowitsch break; 2042*d71ae5a4SJacob Faibussowitsch default: 2043*d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "unknown option %s", MatOptions[op]); 20443a40ed3dSBarry Smith } 20453a40ed3dSBarry Smith PetscFunctionReturn(0); 2046289bc588SBarry Smith } 2047289bc588SBarry Smith 2048*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatZeroEntries_SeqDense(Mat A) 2049*d71ae5a4SJacob Faibussowitsch { 2050ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)A->data; 20513d8925e7SStefano Zampini PetscInt lda = l->lda, m = A->rmap->n, n = A->cmap->n, j; 2052ca15aa20SStefano Zampini PetscScalar *v; 20533a40ed3dSBarry Smith 20543a40ed3dSBarry Smith PetscFunctionBegin; 20559566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(A, &v)); 2056a5ce6ee0Svictorle if (lda > m) { 205748a46eb9SPierre Jolivet for (j = 0; j < n; j++) PetscCall(PetscArrayzero(v + j * lda, m)); 2058a5ce6ee0Svictorle } else { 20599566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(v, PetscInt64Mult(m, n))); 2060a5ce6ee0Svictorle } 20619566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(A, &v)); 20623a40ed3dSBarry Smith PetscFunctionReturn(0); 20636f0a148fSBarry Smith } 20646f0a148fSBarry Smith 2065*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatZeroRows_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) 2066*d71ae5a4SJacob Faibussowitsch { 2067ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)A->data; 2068b9679d65SBarry Smith PetscInt m = l->lda, n = A->cmap->n, i, j; 2069ca15aa20SStefano Zampini PetscScalar *slot, *bb, *v; 207097b48c8fSBarry Smith const PetscScalar *xx; 207155659b69SBarry Smith 20723a40ed3dSBarry Smith PetscFunctionBegin; 207376bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 2074b9679d65SBarry Smith for (i = 0; i < N; i++) { 207508401ef6SPierre Jolivet PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed"); 207608401ef6SPierre 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); 2077b9679d65SBarry Smith } 207876bd3646SJed Brown } 2079ca15aa20SStefano Zampini if (!N) PetscFunctionReturn(0); 2080b9679d65SBarry Smith 208197b48c8fSBarry Smith /* fix right hand side if needed */ 208297b48c8fSBarry Smith if (x && b) { 20839566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 20849566063dSJacob Faibussowitsch PetscCall(VecGetArray(b, &bb)); 20852205254eSKarl Rupp for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]]; 20869566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 20879566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(b, &bb)); 208897b48c8fSBarry Smith } 208997b48c8fSBarry Smith 20909566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 20916f0a148fSBarry Smith for (i = 0; i < N; i++) { 2092ca15aa20SStefano Zampini slot = v + rows[i]; 20939371c9d4SSatish Balay for (j = 0; j < n; j++) { 20949371c9d4SSatish Balay *slot = 0.0; 20959371c9d4SSatish Balay slot += m; 20969371c9d4SSatish Balay } 20976f0a148fSBarry Smith } 2098f4df32b1SMatthew Knepley if (diag != 0.0) { 209908401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices"); 21006f0a148fSBarry Smith for (i = 0; i < N; i++) { 2101ca15aa20SStefano Zampini slot = v + (m + 1) * rows[i]; 2102f4df32b1SMatthew Knepley *slot = diag; 21036f0a148fSBarry Smith } 21046f0a148fSBarry Smith } 21059566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 21063a40ed3dSBarry Smith PetscFunctionReturn(0); 21076f0a148fSBarry Smith } 2108557bce09SLois Curfman McInnes 2109*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A, PetscInt *lda) 2110*d71ae5a4SJacob Faibussowitsch { 211149a6ff4bSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 211249a6ff4bSBarry Smith 211349a6ff4bSBarry Smith PetscFunctionBegin; 211449a6ff4bSBarry Smith *lda = mat->lda; 211549a6ff4bSBarry Smith PetscFunctionReturn(0); 211649a6ff4bSBarry Smith } 211749a6ff4bSBarry Smith 2118*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArray_SeqDense(Mat A, PetscScalar **array) 2119*d71ae5a4SJacob Faibussowitsch { 2120c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 21213a40ed3dSBarry Smith 21223a40ed3dSBarry Smith PetscFunctionBegin; 212328b400f6SJacob Faibussowitsch PetscCheck(!mat->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 212464e87e97SBarry Smith *array = mat->v; 21253a40ed3dSBarry Smith PetscFunctionReturn(0); 212664e87e97SBarry Smith } 21270754003eSLois Curfman McInnes 2128*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A, PetscScalar **array) 2129*d71ae5a4SJacob Faibussowitsch { 21303a40ed3dSBarry Smith PetscFunctionBegin; 213175f6d85dSStefano Zampini if (array) *array = NULL; 21323a40ed3dSBarry Smith PetscFunctionReturn(0); 2133ff14e315SSatish Balay } 21340754003eSLois Curfman McInnes 21350f74d2c1SSatish Balay /*@ 213611a5261eSBarry Smith MatDenseGetLDA - gets the leading dimension of the array returned from `MatDenseGetArray()` 213749a6ff4bSBarry Smith 2138ad16ce7aSStefano Zampini Not collective 213949a6ff4bSBarry Smith 214049a6ff4bSBarry Smith Input Parameter: 214111a5261eSBarry Smith . mat - a `MATDENSE` or `MATDENSECUDA` matrix 214249a6ff4bSBarry Smith 214349a6ff4bSBarry Smith Output Parameter: 214449a6ff4bSBarry Smith . lda - the leading dimension 214549a6ff4bSBarry Smith 214649a6ff4bSBarry Smith Level: intermediate 214749a6ff4bSBarry Smith 214811a5261eSBarry Smith .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseSetLDA()` 214949a6ff4bSBarry Smith @*/ 2150*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetLDA(Mat A, PetscInt *lda) 2151*d71ae5a4SJacob Faibussowitsch { 215249a6ff4bSBarry Smith PetscFunctionBegin; 2153d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2154dadcf809SJacob Faibussowitsch PetscValidIntPointer(lda, 2); 215575f6d85dSStefano Zampini MatCheckPreallocated(A, 1); 2156cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetLDA_C", (Mat, PetscInt *), (A, lda)); 215749a6ff4bSBarry Smith PetscFunctionReturn(0); 215849a6ff4bSBarry Smith } 215949a6ff4bSBarry Smith 21600f74d2c1SSatish Balay /*@ 216111a5261eSBarry Smith MatDenseSetLDA - Sets the leading dimension of the array used by the `MATDENSE` matrix 2162ad16ce7aSStefano Zampini 2163ad16ce7aSStefano Zampini Not collective 2164ad16ce7aSStefano Zampini 2165d8d19677SJose E. Roman Input Parameters: 216611a5261eSBarry Smith + mat - a `MATDENSE` or `MATDENSECUDA` matrix 2167ad16ce7aSStefano Zampini - lda - the leading dimension 2168ad16ce7aSStefano Zampini 2169ad16ce7aSStefano Zampini Level: intermediate 2170ad16ce7aSStefano Zampini 217111a5261eSBarry Smith .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetLDA()` 2172ad16ce7aSStefano Zampini @*/ 2173*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA(Mat A, PetscInt lda) 2174*d71ae5a4SJacob Faibussowitsch { 2175ad16ce7aSStefano Zampini PetscFunctionBegin; 2176ad16ce7aSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2177cac4c232SBarry Smith PetscTryMethod(A, "MatDenseSetLDA_C", (Mat, PetscInt), (A, lda)); 2178ad16ce7aSStefano Zampini PetscFunctionReturn(0); 2179ad16ce7aSStefano Zampini } 2180ad16ce7aSStefano Zampini 2181ad16ce7aSStefano Zampini /*@C 218211a5261eSBarry Smith MatDenseGetArray - gives read-write access to the array where the data for a `MATDENSE` matrix is stored 218373a71a0fSBarry Smith 218411a5261eSBarry Smith Logically Collective on A 218573a71a0fSBarry Smith 218673a71a0fSBarry Smith Input Parameter: 21876947451fSStefano Zampini . mat - a dense matrix 218873a71a0fSBarry Smith 218973a71a0fSBarry Smith Output Parameter: 219073a71a0fSBarry Smith . array - pointer to the data 219173a71a0fSBarry Smith 219273a71a0fSBarry Smith Level: intermediate 219373a71a0fSBarry Smith 219411a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 219573a71a0fSBarry Smith @*/ 2196*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArray(Mat A, PetscScalar **array) 2197*d71ae5a4SJacob Faibussowitsch { 219873a71a0fSBarry Smith PetscFunctionBegin; 2199d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2200d5ea218eSStefano Zampini PetscValidPointer(array, 2); 2201cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array)); 220273a71a0fSBarry Smith PetscFunctionReturn(0); 220373a71a0fSBarry Smith } 220473a71a0fSBarry Smith 2205dec5eb66SMatthew G Knepley /*@C 220611a5261eSBarry Smith MatDenseRestoreArray - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArray()` 220773a71a0fSBarry Smith 220811a5261eSBarry Smith Logically Collective on A 22098572280aSBarry Smith 22108572280aSBarry Smith Input Parameters: 22116947451fSStefano Zampini + mat - a dense matrix 2212742765d3SMatthew Knepley - array - pointer to the data (may be NULL) 22138572280aSBarry Smith 22148572280aSBarry Smith Level: intermediate 22158572280aSBarry Smith 221611a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 22178572280aSBarry Smith @*/ 2218*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArray(Mat A, PetscScalar **array) 2219*d71ae5a4SJacob Faibussowitsch { 22208572280aSBarry Smith PetscFunctionBegin; 2221d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2222d5ea218eSStefano Zampini PetscValidPointer(array, 2); 2223cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array)); 22249566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)A)); 2225637a0070SStefano Zampini #if defined(PETSC_HAVE_CUDA) 2226637a0070SStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 2227637a0070SStefano Zampini #endif 22288572280aSBarry Smith PetscFunctionReturn(0); 22298572280aSBarry Smith } 22308572280aSBarry Smith 22318572280aSBarry Smith /*@C 223211a5261eSBarry Smith MatDenseGetArrayRead - gives read-only access to the array where the data for a `MATDENSE` matrix is stored 22338572280aSBarry Smith 22348572280aSBarry Smith Not Collective 22358572280aSBarry Smith 22368572280aSBarry Smith Input Parameter: 22376947451fSStefano Zampini . mat - a dense matrix 22388572280aSBarry Smith 22398572280aSBarry Smith Output Parameter: 22408572280aSBarry Smith . array - pointer to the data 22418572280aSBarry Smith 22428572280aSBarry Smith Level: intermediate 22438572280aSBarry Smith 224411a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 22458572280aSBarry Smith @*/ 2246*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArrayRead(Mat A, const PetscScalar **array) 2247*d71ae5a4SJacob Faibussowitsch { 22488572280aSBarry Smith PetscFunctionBegin; 2249d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2250d5ea218eSStefano Zampini PetscValidPointer(array, 2); 2251cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, const PetscScalar **), (A, array)); 22528572280aSBarry Smith PetscFunctionReturn(0); 22538572280aSBarry Smith } 22548572280aSBarry Smith 22558572280aSBarry Smith /*@C 225611a5261eSBarry Smith MatDenseRestoreArrayRead - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayRead()` 22578572280aSBarry Smith 225873a71a0fSBarry Smith Not Collective 225973a71a0fSBarry Smith 226073a71a0fSBarry Smith Input Parameters: 22616947451fSStefano Zampini + mat - a dense matrix 2262742765d3SMatthew Knepley - array - pointer to the data (may be NULL) 226373a71a0fSBarry Smith 226473a71a0fSBarry Smith Level: intermediate 226573a71a0fSBarry Smith 226611a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 226773a71a0fSBarry Smith @*/ 2268*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArrayRead(Mat A, const PetscScalar **array) 2269*d71ae5a4SJacob Faibussowitsch { 227073a71a0fSBarry Smith PetscFunctionBegin; 2271d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2272d5ea218eSStefano Zampini PetscValidPointer(array, 2); 2273cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, const PetscScalar **), (A, array)); 227473a71a0fSBarry Smith PetscFunctionReturn(0); 227573a71a0fSBarry Smith } 227673a71a0fSBarry Smith 22776947451fSStefano Zampini /*@C 227811a5261eSBarry Smith MatDenseGetArrayWrite - gives write-only access to the array where the data for a `MATDENSE` matrix is stored 22796947451fSStefano Zampini 22806947451fSStefano Zampini Not Collective 22816947451fSStefano Zampini 22826947451fSStefano Zampini Input Parameter: 22836947451fSStefano Zampini . mat - a dense matrix 22846947451fSStefano Zampini 22856947451fSStefano Zampini Output Parameter: 22866947451fSStefano Zampini . array - pointer to the data 22876947451fSStefano Zampini 22886947451fSStefano Zampini Level: intermediate 22896947451fSStefano Zampini 229011a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()` 22916947451fSStefano Zampini @*/ 2292*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArrayWrite(Mat A, PetscScalar **array) 2293*d71ae5a4SJacob Faibussowitsch { 22946947451fSStefano Zampini PetscFunctionBegin; 2295d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2296d5ea218eSStefano Zampini PetscValidPointer(array, 2); 2297cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array)); 22986947451fSStefano Zampini PetscFunctionReturn(0); 22996947451fSStefano Zampini } 23006947451fSStefano Zampini 23016947451fSStefano Zampini /*@C 230211a5261eSBarry Smith MatDenseRestoreArrayWrite - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayWrite()` 23036947451fSStefano Zampini 23046947451fSStefano Zampini Not Collective 23056947451fSStefano Zampini 23066947451fSStefano Zampini Input Parameters: 23076947451fSStefano Zampini + mat - a dense matrix 2308742765d3SMatthew Knepley - array - pointer to the data (may be NULL) 23096947451fSStefano Zampini 23106947451fSStefano Zampini Level: intermediate 23116947451fSStefano Zampini 231211a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()` 23136947451fSStefano Zampini @*/ 2314*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArrayWrite(Mat A, PetscScalar **array) 2315*d71ae5a4SJacob Faibussowitsch { 23166947451fSStefano Zampini PetscFunctionBegin; 2317d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2318d5ea218eSStefano Zampini PetscValidPointer(array, 2); 2319cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array)); 23209566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)A)); 23216947451fSStefano Zampini #if defined(PETSC_HAVE_CUDA) 23226947451fSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 23236947451fSStefano Zampini #endif 23246947451fSStefano Zampini PetscFunctionReturn(0); 23256947451fSStefano Zampini } 23266947451fSStefano Zampini 2327*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A, IS isrow, IS iscol, MatReuse scall, Mat *B) 2328*d71ae5a4SJacob Faibussowitsch { 2329c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 2330bf5a80bcSToby Isaac PetscInt i, j, nrows, ncols, ldb; 23315d0c19d7SBarry Smith const PetscInt *irow, *icol; 233287828ca2SBarry Smith PetscScalar *av, *bv, *v = mat->v; 23330754003eSLois Curfman McInnes Mat newmat; 23340754003eSLois Curfman McInnes 23353a40ed3dSBarry Smith PetscFunctionBegin; 23369566063dSJacob Faibussowitsch PetscCall(ISGetIndices(isrow, &irow)); 23379566063dSJacob Faibussowitsch PetscCall(ISGetIndices(iscol, &icol)); 23389566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(isrow, &nrows)); 23399566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(iscol, &ncols)); 23400754003eSLois Curfman McInnes 2341182d2002SSatish Balay /* Check submatrixcall */ 2342182d2002SSatish Balay if (scall == MAT_REUSE_MATRIX) { 234313f74950SBarry Smith PetscInt n_cols, n_rows; 23449566063dSJacob Faibussowitsch PetscCall(MatGetSize(*B, &n_rows, &n_cols)); 234521a2c019SBarry Smith if (n_rows != nrows || n_cols != ncols) { 2346f746d493SDmitry Karpeev /* resize the result matrix to match number of requested rows/columns */ 23479566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*B, nrows, ncols, nrows, ncols)); 234821a2c019SBarry Smith } 2349182d2002SSatish Balay newmat = *B; 2350182d2002SSatish Balay } else { 23510754003eSLois Curfman McInnes /* Create and fill new matrix */ 23529566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &newmat)); 23539566063dSJacob Faibussowitsch PetscCall(MatSetSizes(newmat, nrows, ncols, nrows, ncols)); 23549566063dSJacob Faibussowitsch PetscCall(MatSetType(newmat, ((PetscObject)A)->type_name)); 23559566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(newmat, NULL)); 2356182d2002SSatish Balay } 2357182d2002SSatish Balay 2358182d2002SSatish Balay /* Now extract the data pointers and do the copy,column at a time */ 23599566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(newmat, &bv)); 23609566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(newmat, &ldb)); 2361182d2002SSatish Balay for (i = 0; i < ncols; i++) { 23626de62eeeSBarry Smith av = v + mat->lda * icol[i]; 2363ca15aa20SStefano Zampini for (j = 0; j < nrows; j++) bv[j] = av[irow[j]]; 2364bf5a80bcSToby Isaac bv += ldb; 23650754003eSLois Curfman McInnes } 23669566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(newmat, &bv)); 2367182d2002SSatish Balay 2368182d2002SSatish Balay /* Assemble the matrices so that the correct flags are set */ 23699566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(newmat, MAT_FINAL_ASSEMBLY)); 23709566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(newmat, MAT_FINAL_ASSEMBLY)); 23710754003eSLois Curfman McInnes 23720754003eSLois Curfman McInnes /* Free work space */ 23739566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(isrow, &irow)); 23749566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(iscol, &icol)); 2375182d2002SSatish Balay *B = newmat; 23763a40ed3dSBarry Smith PetscFunctionReturn(0); 23770754003eSLois Curfman McInnes } 23780754003eSLois Curfman McInnes 2379*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A, PetscInt n, const IS irow[], const IS icol[], MatReuse scall, Mat *B[]) 2380*d71ae5a4SJacob Faibussowitsch { 238113f74950SBarry Smith PetscInt i; 2382905e6a2fSBarry Smith 23833a40ed3dSBarry Smith PetscFunctionBegin; 238448a46eb9SPierre Jolivet if (scall == MAT_INITIAL_MATRIX) PetscCall(PetscCalloc1(n, B)); 2385905e6a2fSBarry Smith 238648a46eb9SPierre Jolivet for (i = 0; i < n; i++) PetscCall(MatCreateSubMatrix_SeqDense(A, irow[i], icol[i], scall, &(*B)[i])); 23873a40ed3dSBarry Smith PetscFunctionReturn(0); 2388905e6a2fSBarry Smith } 2389905e6a2fSBarry Smith 2390*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat, MatAssemblyType mode) 2391*d71ae5a4SJacob Faibussowitsch { 2392c0aa2d19SHong Zhang PetscFunctionBegin; 2393c0aa2d19SHong Zhang PetscFunctionReturn(0); 2394c0aa2d19SHong Zhang } 2395c0aa2d19SHong Zhang 2396*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat, MatAssemblyType mode) 2397*d71ae5a4SJacob Faibussowitsch { 2398c0aa2d19SHong Zhang PetscFunctionBegin; 2399c0aa2d19SHong Zhang PetscFunctionReturn(0); 2400c0aa2d19SHong Zhang } 2401c0aa2d19SHong Zhang 2402*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCopy_SeqDense(Mat A, Mat B, MatStructure str) 2403*d71ae5a4SJacob Faibussowitsch { 24044b0e389bSBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data; 2405ca15aa20SStefano Zampini const PetscScalar *va; 2406ca15aa20SStefano Zampini PetscScalar *vb; 2407d0f46423SBarry Smith PetscInt lda1 = a->lda, lda2 = b->lda, m = A->rmap->n, n = A->cmap->n, j; 24083a40ed3dSBarry Smith 24093a40ed3dSBarry Smith PetscFunctionBegin; 241033f4a19fSKris Buschelman /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */ 241133f4a19fSKris Buschelman if (A->ops->copy != B->ops->copy) { 24129566063dSJacob Faibussowitsch PetscCall(MatCopy_Basic(A, B, str)); 24133a40ed3dSBarry Smith PetscFunctionReturn(0); 24143a40ed3dSBarry Smith } 2415aed4548fSBarry Smith PetscCheck(m == B->rmap->n && n == B->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "size(B) != size(A)"); 24169566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &va)); 24179566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(B, &vb)); 2418a5ce6ee0Svictorle if (lda1 > m || lda2 > m) { 241948a46eb9SPierre Jolivet for (j = 0; j < n; j++) PetscCall(PetscArraycpy(vb + j * lda2, va + j * lda1, m)); 2420a5ce6ee0Svictorle } else { 24219566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(vb, va, A->rmap->n * A->cmap->n)); 2422a5ce6ee0Svictorle } 24239566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(B, &vb)); 24249566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &va)); 24259566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 24269566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 2427273d9f13SBarry Smith PetscFunctionReturn(0); 2428273d9f13SBarry Smith } 2429273d9f13SBarry Smith 2430*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetUp_SeqDense(Mat A) 2431*d71ae5a4SJacob Faibussowitsch { 2432273d9f13SBarry Smith PetscFunctionBegin; 24339566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 24349566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 243548a46eb9SPierre Jolivet if (!A->preallocated) PetscCall(MatSeqDenseSetPreallocation(A, NULL)); 24363a40ed3dSBarry Smith PetscFunctionReturn(0); 24374b0e389bSBarry Smith } 24384b0e389bSBarry Smith 2439*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatConjugate_SeqDense(Mat A) 2440*d71ae5a4SJacob Faibussowitsch { 24414396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 244206c5243aSJose E. Roman PetscInt i, j; 24434396437dSToby Isaac PetscInt min = PetscMin(A->rmap->n, A->cmap->n); 2444ca15aa20SStefano Zampini PetscScalar *aa; 2445ba337c44SJed Brown 2446ba337c44SJed Brown PetscFunctionBegin; 24479566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 244806c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 244906c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscConj(aa[i + j * mat->lda]); 245006c5243aSJose E. Roman } 24519566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 24529371c9d4SSatish Balay if (mat->tau) 24539371c9d4SSatish Balay for (i = 0; i < min; i++) mat->tau[i] = PetscConj(mat->tau[i]); 2454ba337c44SJed Brown PetscFunctionReturn(0); 2455ba337c44SJed Brown } 2456ba337c44SJed Brown 2457*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRealPart_SeqDense(Mat A) 2458*d71ae5a4SJacob Faibussowitsch { 245906c5243aSJose E. Roman Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 246006c5243aSJose E. Roman PetscInt i, j; 2461ca15aa20SStefano Zampini PetscScalar *aa; 2462ba337c44SJed Brown 2463ba337c44SJed Brown PetscFunctionBegin; 24649566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 246506c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 246606c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscRealPart(aa[i + j * mat->lda]); 246706c5243aSJose E. Roman } 24689566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 2469ba337c44SJed Brown PetscFunctionReturn(0); 2470ba337c44SJed Brown } 2471ba337c44SJed Brown 2472*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatImaginaryPart_SeqDense(Mat A) 2473*d71ae5a4SJacob Faibussowitsch { 247406c5243aSJose E. Roman Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 247506c5243aSJose E. Roman PetscInt i, j; 2476ca15aa20SStefano Zampini PetscScalar *aa; 2477ba337c44SJed Brown 2478ba337c44SJed Brown PetscFunctionBegin; 24799566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 248006c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 248106c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscImaginaryPart(aa[i + j * mat->lda]); 248206c5243aSJose E. Roman } 24839566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 2484ba337c44SJed Brown PetscFunctionReturn(0); 2485ba337c44SJed Brown } 2486284134d9SBarry Smith 2487a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/ 2488*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2489*d71ae5a4SJacob Faibussowitsch { 2490d0f46423SBarry Smith PetscInt m = A->rmap->n, n = B->cmap->n; 24917a3c3d58SStefano Zampini PetscBool cisdense; 2492a9fe9ddaSSatish Balay 2493ee16a9a1SHong Zhang PetscFunctionBegin; 24949566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 24959566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 24967a3c3d58SStefano Zampini if (!cisdense) { 24977a3c3d58SStefano Zampini PetscBool flg; 24987a3c3d58SStefano Zampini 24999566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 25009566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 25017a3c3d58SStefano Zampini } 25029566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 2503ee16a9a1SHong Zhang PetscFunctionReturn(0); 2504ee16a9a1SHong Zhang } 2505a9fe9ddaSSatish Balay 2506*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2507*d71ae5a4SJacob Faibussowitsch { 25086718818eSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data, *c = (Mat_SeqDense *)C->data; 25090805154bSBarry Smith PetscBLASInt m, n, k; 2510ca15aa20SStefano Zampini const PetscScalar *av, *bv; 2511ca15aa20SStefano Zampini PetscScalar *cv; 2512a9fe9ddaSSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 2513a9fe9ddaSSatish Balay 2514a9fe9ddaSSatish Balay PetscFunctionBegin; 25159566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 25169566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 25179566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 251849d0e964SStefano Zampini if (!m || !n || !k) PetscFunctionReturn(0); 25199566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 25209566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 25219566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2522792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("N", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 25239566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 25249566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 25259566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 25269566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 2527a9fe9ddaSSatish Balay PetscFunctionReturn(0); 2528a9fe9ddaSSatish Balay } 2529a9fe9ddaSSatish Balay 2530*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2531*d71ae5a4SJacob Faibussowitsch { 253269f65d41SStefano Zampini PetscInt m = A->rmap->n, n = B->rmap->n; 25337a3c3d58SStefano Zampini PetscBool cisdense; 253469f65d41SStefano Zampini 253569f65d41SStefano Zampini PetscFunctionBegin; 25369566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 25379566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 25387a3c3d58SStefano Zampini if (!cisdense) { 25397a3c3d58SStefano Zampini PetscBool flg; 25407a3c3d58SStefano Zampini 25419566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 25429566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 25437a3c3d58SStefano Zampini } 25449566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 254569f65d41SStefano Zampini PetscFunctionReturn(0); 254669f65d41SStefano Zampini } 254769f65d41SStefano Zampini 2548*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2549*d71ae5a4SJacob Faibussowitsch { 255069f65d41SStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 255169f65d41SStefano Zampini Mat_SeqDense *b = (Mat_SeqDense *)B->data; 255269f65d41SStefano Zampini Mat_SeqDense *c = (Mat_SeqDense *)C->data; 25536718818eSStefano Zampini const PetscScalar *av, *bv; 25546718818eSStefano Zampini PetscScalar *cv; 255569f65d41SStefano Zampini PetscBLASInt m, n, k; 255669f65d41SStefano Zampini PetscScalar _DOne = 1.0, _DZero = 0.0; 255769f65d41SStefano Zampini 255869f65d41SStefano Zampini PetscFunctionBegin; 25599566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 25609566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 25619566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 256249d0e964SStefano Zampini if (!m || !n || !k) PetscFunctionReturn(0); 25639566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 25649566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 25659566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2566792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("N", "T", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 25679566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 25689566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 25699566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 25709566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 257169f65d41SStefano Zampini PetscFunctionReturn(0); 257269f65d41SStefano Zampini } 257369f65d41SStefano Zampini 2574*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2575*d71ae5a4SJacob Faibussowitsch { 2576d0f46423SBarry Smith PetscInt m = A->cmap->n, n = B->cmap->n; 25777a3c3d58SStefano Zampini PetscBool cisdense; 2578a9fe9ddaSSatish Balay 2579ee16a9a1SHong Zhang PetscFunctionBegin; 25809566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 25819566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 25827a3c3d58SStefano Zampini if (!cisdense) { 25837a3c3d58SStefano Zampini PetscBool flg; 25847a3c3d58SStefano Zampini 25859566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 25869566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 25877a3c3d58SStefano Zampini } 25889566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 2589ee16a9a1SHong Zhang PetscFunctionReturn(0); 2590ee16a9a1SHong Zhang } 2591a9fe9ddaSSatish Balay 2592*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2593*d71ae5a4SJacob Faibussowitsch { 2594a9fe9ddaSSatish Balay Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2595a9fe9ddaSSatish Balay Mat_SeqDense *b = (Mat_SeqDense *)B->data; 2596a9fe9ddaSSatish Balay Mat_SeqDense *c = (Mat_SeqDense *)C->data; 25976718818eSStefano Zampini const PetscScalar *av, *bv; 25986718818eSStefano Zampini PetscScalar *cv; 25990805154bSBarry Smith PetscBLASInt m, n, k; 2600a9fe9ddaSSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 2601a9fe9ddaSSatish Balay 2602a9fe9ddaSSatish Balay PetscFunctionBegin; 26039566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 26049566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 26059566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &k)); 260649d0e964SStefano Zampini if (!m || !n || !k) PetscFunctionReturn(0); 26079566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 26089566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 26099566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2610792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("T", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 26119566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 26129566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 26139566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 26149566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 2615a9fe9ddaSSatish Balay PetscFunctionReturn(0); 2616a9fe9ddaSSatish Balay } 2617985db425SBarry Smith 26184222ddf1SHong Zhang /* ----------------------------------------------- */ 2619*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C) 2620*d71ae5a4SJacob Faibussowitsch { 26214222ddf1SHong Zhang PetscFunctionBegin; 26224222ddf1SHong Zhang C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense; 26234222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AB; 26244222ddf1SHong Zhang PetscFunctionReturn(0); 26254222ddf1SHong Zhang } 26264222ddf1SHong Zhang 2627*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C) 2628*d71ae5a4SJacob Faibussowitsch { 26294222ddf1SHong Zhang PetscFunctionBegin; 26304222ddf1SHong Zhang C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense; 26314222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AtB; 26324222ddf1SHong Zhang PetscFunctionReturn(0); 26334222ddf1SHong Zhang } 26344222ddf1SHong Zhang 2635*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C) 2636*d71ae5a4SJacob Faibussowitsch { 26374222ddf1SHong Zhang PetscFunctionBegin; 26384222ddf1SHong Zhang C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense; 26394222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_ABt; 26404222ddf1SHong Zhang PetscFunctionReturn(0); 26414222ddf1SHong Zhang } 26424222ddf1SHong Zhang 2643*d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C) 2644*d71ae5a4SJacob Faibussowitsch { 26454222ddf1SHong Zhang Mat_Product *product = C->product; 26464222ddf1SHong Zhang 26474222ddf1SHong Zhang PetscFunctionBegin; 26484222ddf1SHong Zhang switch (product->type) { 2649*d71ae5a4SJacob Faibussowitsch case MATPRODUCT_AB: 2650*d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_AB(C)); 2651*d71ae5a4SJacob Faibussowitsch break; 2652*d71ae5a4SJacob Faibussowitsch case MATPRODUCT_AtB: 2653*d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_AtB(C)); 2654*d71ae5a4SJacob Faibussowitsch break; 2655*d71ae5a4SJacob Faibussowitsch case MATPRODUCT_ABt: 2656*d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_ABt(C)); 2657*d71ae5a4SJacob Faibussowitsch break; 2658*d71ae5a4SJacob Faibussowitsch default: 2659*d71ae5a4SJacob Faibussowitsch break; 26604222ddf1SHong Zhang } 26614222ddf1SHong Zhang PetscFunctionReturn(0); 26624222ddf1SHong Zhang } 26634222ddf1SHong Zhang /* ----------------------------------------------- */ 26644222ddf1SHong Zhang 2665*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMax_SeqDense(Mat A, Vec v, PetscInt idx[]) 2666*d71ae5a4SJacob Faibussowitsch { 2667985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2668d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2669985db425SBarry Smith PetscScalar *x; 2670ca15aa20SStefano Zampini const PetscScalar *aa; 2671985db425SBarry Smith 2672985db425SBarry Smith PetscFunctionBegin; 267328b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 26749566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 26759566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 26769566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 267708401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2678985db425SBarry Smith for (i = 0; i < m; i++) { 26799371c9d4SSatish Balay x[i] = aa[i]; 26809371c9d4SSatish Balay if (idx) idx[i] = 0; 2681985db425SBarry Smith for (j = 1; j < n; j++) { 26829371c9d4SSatish Balay if (PetscRealPart(x[i]) < PetscRealPart(aa[i + a->lda * j])) { 26839371c9d4SSatish Balay x[i] = aa[i + a->lda * j]; 26849371c9d4SSatish Balay if (idx) idx[i] = j; 26859371c9d4SSatish Balay } 2686985db425SBarry Smith } 2687985db425SBarry Smith } 26889566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 26899566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 2690985db425SBarry Smith PetscFunctionReturn(0); 2691985db425SBarry Smith } 2692985db425SBarry Smith 2693*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A, Vec v, PetscInt idx[]) 2694*d71ae5a4SJacob 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; 2698985db425SBarry Smith PetscReal atmp; 2699ca15aa20SStefano Zampini const PetscScalar *aa; 2700985db425SBarry Smith 2701985db425SBarry Smith PetscFunctionBegin; 270228b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 27039566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 27049566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 27059566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 270608401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2707985db425SBarry Smith for (i = 0; i < m; i++) { 27089189402eSHong Zhang x[i] = PetscAbsScalar(aa[i]); 2709985db425SBarry Smith for (j = 1; j < n; j++) { 2710ca15aa20SStefano Zampini atmp = PetscAbsScalar(aa[i + a->lda * j]); 27119371c9d4SSatish Balay if (PetscAbsScalar(x[i]) < atmp) { 27129371c9d4SSatish Balay x[i] = atmp; 27139371c9d4SSatish Balay if (idx) idx[i] = j; 27149371c9d4SSatish Balay } 2715985db425SBarry Smith } 2716985db425SBarry Smith } 27179566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 27189566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 2719985db425SBarry Smith PetscFunctionReturn(0); 2720985db425SBarry Smith } 2721985db425SBarry Smith 2722*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMin_SeqDense(Mat A, Vec v, PetscInt idx[]) 2723*d71ae5a4SJacob Faibussowitsch { 2724985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2725d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2726985db425SBarry Smith PetscScalar *x; 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(MatDenseGetArrayRead(A, &aa)); 27329566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 27339566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 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++) { 27369371c9d4SSatish Balay x[i] = aa[i]; 27379371c9d4SSatish Balay if (idx) idx[i] = 0; 2738985db425SBarry Smith for (j = 1; j < n; j++) { 27399371c9d4SSatish Balay if (PetscRealPart(x[i]) > PetscRealPart(aa[i + a->lda * j])) { 27409371c9d4SSatish Balay x[i] = aa[i + a->lda * j]; 27419371c9d4SSatish Balay if (idx) idx[i] = j; 27429371c9d4SSatish Balay } 2743985db425SBarry Smith } 2744985db425SBarry Smith } 27459566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 27469566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 2747985db425SBarry Smith PetscFunctionReturn(0); 2748985db425SBarry Smith } 2749985db425SBarry Smith 2750*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatGetColumnVector_SeqDense(Mat A, Vec v, PetscInt col) 2751*d71ae5a4SJacob Faibussowitsch { 27528d0534beSBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 27538d0534beSBarry Smith PetscScalar *x; 2754ca15aa20SStefano Zampini const PetscScalar *aa; 27558d0534beSBarry Smith 27568d0534beSBarry Smith PetscFunctionBegin; 275728b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 27589566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 27599566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 27609566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(x, aa + col * a->lda, A->rmap->n)); 27619566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 27629566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 27638d0534beSBarry Smith PetscFunctionReturn(0); 27648d0534beSBarry Smith } 27658d0534beSBarry Smith 2766*d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatGetColumnReductions_SeqDense(Mat A, PetscInt type, PetscReal *reductions) 2767*d71ae5a4SJacob Faibussowitsch { 27680716a85fSBarry Smith PetscInt i, j, m, n; 27691683a169SBarry Smith const PetscScalar *a; 27700716a85fSBarry Smith 27710716a85fSBarry Smith PetscFunctionBegin; 27729566063dSJacob Faibussowitsch PetscCall(MatGetSize(A, &m, &n)); 27739566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(reductions, n)); 27749566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &a)); 2775857cbf51SRichard Tran Mills if (type == NORM_2) { 27760716a85fSBarry Smith for (i = 0; i < n; i++) { 2777ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j] * a[j]); 27780716a85fSBarry Smith a += m; 27790716a85fSBarry Smith } 2780857cbf51SRichard Tran Mills } else if (type == NORM_1) { 27810716a85fSBarry Smith for (i = 0; i < n; i++) { 2782ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j]); 27830716a85fSBarry Smith a += m; 27840716a85fSBarry Smith } 2785857cbf51SRichard Tran Mills } else if (type == NORM_INFINITY) { 27860716a85fSBarry Smith for (i = 0; i < n; i++) { 2787ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] = PetscMax(PetscAbsScalar(a[j]), reductions[i]); 27880716a85fSBarry Smith a += m; 27890716a85fSBarry Smith } 2790857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_REALPART || type == REDUCTION_MEAN_REALPART) { 2791a873a8cdSSam Reynolds for (i = 0; i < n; i++) { 2792ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscRealPart(a[j]); 2793a873a8cdSSam Reynolds a += m; 2794a873a8cdSSam Reynolds } 2795857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_IMAGINARYPART || type == REDUCTION_MEAN_IMAGINARYPART) { 2796857cbf51SRichard Tran Mills for (i = 0; i < n; i++) { 2797ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscImaginaryPart(a[j]); 2798857cbf51SRichard Tran Mills a += m; 2799857cbf51SRichard Tran Mills } 2800857cbf51SRichard Tran Mills } else SETERRQ(PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Unknown reduction type"); 28019566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &a)); 2802857cbf51SRichard Tran Mills if (type == NORM_2) { 2803a873a8cdSSam Reynolds for (i = 0; i < n; i++) reductions[i] = PetscSqrtReal(reductions[i]); 2804857cbf51SRichard Tran Mills } else if (type == REDUCTION_MEAN_REALPART || type == REDUCTION_MEAN_IMAGINARYPART) { 2805a873a8cdSSam Reynolds for (i = 0; i < n; i++) reductions[i] /= m; 28060716a85fSBarry Smith } 28070716a85fSBarry Smith PetscFunctionReturn(0); 28080716a85fSBarry Smith } 28090716a85fSBarry Smith 2810*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetRandom_SeqDense(Mat x, PetscRandom rctx) 2811*d71ae5a4SJacob Faibussowitsch { 281273a71a0fSBarry Smith PetscScalar *a; 2813637a0070SStefano Zampini PetscInt lda, m, n, i, j; 281473a71a0fSBarry Smith 281573a71a0fSBarry Smith PetscFunctionBegin; 28169566063dSJacob Faibussowitsch PetscCall(MatGetSize(x, &m, &n)); 28179566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(x, &lda)); 28183faff063SStefano Zampini PetscCall(MatDenseGetArrayWrite(x, &a)); 2819637a0070SStefano Zampini for (j = 0; j < n; j++) { 282048a46eb9SPierre Jolivet for (i = 0; i < m; i++) PetscCall(PetscRandomGetValue(rctx, a + j * lda + i)); 282173a71a0fSBarry Smith } 28223faff063SStefano Zampini PetscCall(MatDenseRestoreArrayWrite(x, &a)); 282373a71a0fSBarry Smith PetscFunctionReturn(0); 282473a71a0fSBarry Smith } 282573a71a0fSBarry Smith 2826*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A, PetscBool *missing, PetscInt *d) 2827*d71ae5a4SJacob Faibussowitsch { 28283b49f96aSBarry Smith PetscFunctionBegin; 28293b49f96aSBarry Smith *missing = PETSC_FALSE; 28303b49f96aSBarry Smith PetscFunctionReturn(0); 28313b49f96aSBarry Smith } 283273a71a0fSBarry Smith 2833ca15aa20SStefano Zampini /* vals is not const */ 2834*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A, PetscInt col, PetscScalar **vals) 2835*d71ae5a4SJacob Faibussowitsch { 283686aefd0dSHong Zhang Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2837ca15aa20SStefano Zampini PetscScalar *v; 283886aefd0dSHong Zhang 283986aefd0dSHong Zhang PetscFunctionBegin; 284028b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 28419566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 2842ca15aa20SStefano Zampini *vals = v + col * a->lda; 28439566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 284486aefd0dSHong Zhang PetscFunctionReturn(0); 284586aefd0dSHong Zhang } 284686aefd0dSHong Zhang 2847*d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A, PetscScalar **vals) 2848*d71ae5a4SJacob Faibussowitsch { 284986aefd0dSHong Zhang PetscFunctionBegin; 2850742765d3SMatthew Knepley if (vals) *vals = NULL; /* user cannot accidentally use the array later */ 285186aefd0dSHong Zhang PetscFunctionReturn(0); 285286aefd0dSHong Zhang } 2853abc3b08eSStefano Zampini 2854289bc588SBarry Smith /* -------------------------------------------------------------------*/ 2855a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqDense, 2856905e6a2fSBarry Smith MatGetRow_SeqDense, 2857905e6a2fSBarry Smith MatRestoreRow_SeqDense, 2858905e6a2fSBarry Smith MatMult_SeqDense, 285997304618SKris Buschelman /* 4*/ MatMultAdd_SeqDense, 28607c922b88SBarry Smith MatMultTranspose_SeqDense, 28617c922b88SBarry Smith MatMultTransposeAdd_SeqDense, 2862f4259b30SLisandro Dalcin NULL, 2863f4259b30SLisandro Dalcin NULL, 2864f4259b30SLisandro Dalcin NULL, 2865f4259b30SLisandro Dalcin /* 10*/ NULL, 2866905e6a2fSBarry Smith MatLUFactor_SeqDense, 2867905e6a2fSBarry Smith MatCholeskyFactor_SeqDense, 286841f059aeSBarry Smith MatSOR_SeqDense, 2869ec8511deSBarry Smith MatTranspose_SeqDense, 287097304618SKris Buschelman /* 15*/ MatGetInfo_SeqDense, 2871905e6a2fSBarry Smith MatEqual_SeqDense, 2872905e6a2fSBarry Smith MatGetDiagonal_SeqDense, 2873905e6a2fSBarry Smith MatDiagonalScale_SeqDense, 2874905e6a2fSBarry Smith MatNorm_SeqDense, 2875c0aa2d19SHong Zhang /* 20*/ MatAssemblyBegin_SeqDense, 2876c0aa2d19SHong Zhang MatAssemblyEnd_SeqDense, 2877905e6a2fSBarry Smith MatSetOption_SeqDense, 2878905e6a2fSBarry Smith MatZeroEntries_SeqDense, 2879d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqDense, 2880f4259b30SLisandro Dalcin NULL, 2881f4259b30SLisandro Dalcin NULL, 2882f4259b30SLisandro Dalcin NULL, 2883f4259b30SLisandro Dalcin NULL, 28844994cf47SJed Brown /* 29*/ MatSetUp_SeqDense, 2885f4259b30SLisandro Dalcin NULL, 2886f4259b30SLisandro Dalcin NULL, 2887f4259b30SLisandro Dalcin NULL, 2888f4259b30SLisandro Dalcin NULL, 2889d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqDense, 2890f4259b30SLisandro Dalcin NULL, 2891f4259b30SLisandro Dalcin NULL, 2892f4259b30SLisandro Dalcin NULL, 2893f4259b30SLisandro Dalcin NULL, 2894d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqDense, 28957dae84e0SHong Zhang MatCreateSubMatrices_SeqDense, 2896f4259b30SLisandro Dalcin NULL, 28974b0e389bSBarry Smith MatGetValues_SeqDense, 2898a5ae1ecdSBarry Smith MatCopy_SeqDense, 2899d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqDense, 2900a5ae1ecdSBarry Smith MatScale_SeqDense, 29012f605a99SJose E. Roman MatShift_SeqDense, 2902f4259b30SLisandro Dalcin NULL, 29033f49a652SStefano Zampini MatZeroRowsColumns_SeqDense, 290473a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqDense, 2905f4259b30SLisandro Dalcin NULL, 2906f4259b30SLisandro Dalcin NULL, 2907f4259b30SLisandro Dalcin NULL, 2908f4259b30SLisandro Dalcin NULL, 2909f4259b30SLisandro Dalcin /* 54*/ NULL, 2910f4259b30SLisandro Dalcin NULL, 2911f4259b30SLisandro Dalcin NULL, 2912f4259b30SLisandro Dalcin NULL, 2913f4259b30SLisandro Dalcin NULL, 2914023c16fcSToby Isaac /* 59*/ MatCreateSubMatrix_SeqDense, 2915e03a110bSBarry Smith MatDestroy_SeqDense, 2916e03a110bSBarry Smith MatView_SeqDense, 2917f4259b30SLisandro Dalcin NULL, 2918f4259b30SLisandro Dalcin NULL, 2919f4259b30SLisandro Dalcin /* 64*/ NULL, 2920f4259b30SLisandro Dalcin NULL, 2921f4259b30SLisandro Dalcin NULL, 2922f4259b30SLisandro Dalcin NULL, 2923f4259b30SLisandro Dalcin NULL, 2924d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqDense, 2925f4259b30SLisandro Dalcin NULL, 2926f4259b30SLisandro Dalcin NULL, 2927f4259b30SLisandro Dalcin NULL, 2928f4259b30SLisandro Dalcin NULL, 2929f4259b30SLisandro Dalcin /* 74*/ NULL, 2930f4259b30SLisandro Dalcin NULL, 2931f4259b30SLisandro Dalcin NULL, 2932f4259b30SLisandro Dalcin NULL, 2933f4259b30SLisandro Dalcin NULL, 2934f4259b30SLisandro Dalcin /* 79*/ NULL, 2935f4259b30SLisandro Dalcin NULL, 2936f4259b30SLisandro Dalcin NULL, 2937f4259b30SLisandro Dalcin NULL, 29385bba2384SShri Abhyankar /* 83*/ MatLoad_SeqDense, 2939637a0070SStefano Zampini MatIsSymmetric_SeqDense, 29401cbb95d3SBarry Smith MatIsHermitian_SeqDense, 2941f4259b30SLisandro Dalcin NULL, 2942f4259b30SLisandro Dalcin NULL, 2943f4259b30SLisandro Dalcin NULL, 2944f4259b30SLisandro Dalcin /* 89*/ NULL, 2945f4259b30SLisandro Dalcin NULL, 2946a9fe9ddaSSatish Balay MatMatMultNumeric_SeqDense_SeqDense, 2947f4259b30SLisandro Dalcin NULL, 2948f4259b30SLisandro Dalcin NULL, 2949f4259b30SLisandro Dalcin /* 94*/ NULL, 2950f4259b30SLisandro Dalcin NULL, 2951f4259b30SLisandro Dalcin NULL, 295269f65d41SStefano Zampini MatMatTransposeMultNumeric_SeqDense_SeqDense, 2953f4259b30SLisandro Dalcin NULL, 29544222ddf1SHong Zhang /* 99*/ MatProductSetFromOptions_SeqDense, 2955f4259b30SLisandro Dalcin NULL, 2956f4259b30SLisandro Dalcin NULL, 2957ba337c44SJed Brown MatConjugate_SeqDense, 2958f4259b30SLisandro Dalcin NULL, 2959f4259b30SLisandro Dalcin /*104*/ NULL, 2960ba337c44SJed Brown MatRealPart_SeqDense, 2961ba337c44SJed Brown MatImaginaryPart_SeqDense, 2962f4259b30SLisandro Dalcin NULL, 2963f4259b30SLisandro Dalcin NULL, 2964f4259b30SLisandro Dalcin /*109*/ NULL, 2965f4259b30SLisandro Dalcin NULL, 29668d0534beSBarry Smith MatGetRowMin_SeqDense, 2967aabbc4fbSShri Abhyankar MatGetColumnVector_SeqDense, 29683b49f96aSBarry Smith MatMissingDiagonal_SeqDense, 2969f4259b30SLisandro Dalcin /*114*/ NULL, 2970f4259b30SLisandro Dalcin NULL, 2971f4259b30SLisandro Dalcin NULL, 2972f4259b30SLisandro Dalcin NULL, 2973f4259b30SLisandro Dalcin NULL, 2974f4259b30SLisandro Dalcin /*119*/ NULL, 2975f4259b30SLisandro Dalcin NULL, 2976f4259b30SLisandro Dalcin NULL, 2977f4259b30SLisandro Dalcin NULL, 2978f4259b30SLisandro Dalcin NULL, 2979f4259b30SLisandro Dalcin /*124*/ NULL, 2980a873a8cdSSam Reynolds MatGetColumnReductions_SeqDense, 2981f4259b30SLisandro Dalcin NULL, 2982f4259b30SLisandro Dalcin NULL, 2983f4259b30SLisandro Dalcin NULL, 2984f4259b30SLisandro Dalcin /*129*/ NULL, 2985f4259b30SLisandro Dalcin NULL, 2986f4259b30SLisandro Dalcin NULL, 298775648e8dSHong Zhang MatTransposeMatMultNumeric_SeqDense_SeqDense, 2988f4259b30SLisandro Dalcin NULL, 2989f4259b30SLisandro Dalcin /*134*/ NULL, 2990f4259b30SLisandro Dalcin NULL, 2991f4259b30SLisandro Dalcin NULL, 2992f4259b30SLisandro Dalcin NULL, 2993f4259b30SLisandro Dalcin NULL, 2994f4259b30SLisandro Dalcin /*139*/ NULL, 2995f4259b30SLisandro Dalcin NULL, 2996f4259b30SLisandro Dalcin NULL, 2997f4259b30SLisandro Dalcin NULL, 2998f4259b30SLisandro Dalcin NULL, 29994222ddf1SHong Zhang MatCreateMPIMatConcatenateSeqMat_SeqDense, 3000f4259b30SLisandro Dalcin /*145*/ NULL, 3001f4259b30SLisandro Dalcin NULL, 300299a7f59eSMark Adams NULL, 300399a7f59eSMark Adams NULL, 30047fb60732SBarry Smith NULL, 30059371c9d4SSatish Balay /*150*/ NULL}; 300690ace30eSBarry Smith 30074b828684SBarry Smith /*@C 300811a5261eSBarry Smith MatCreateSeqDense - Creates a `MATSEQDENSE` that 3009d65003e9SLois Curfman McInnes is stored in column major order (the usual Fortran 77 manner). Many 3010d65003e9SLois Curfman McInnes of the matrix operations use the BLAS and LAPACK routines. 3011289bc588SBarry Smith 3012d083f849SBarry Smith Collective 3013db81eaa0SLois Curfman McInnes 301420563c6bSBarry Smith Input Parameters: 301511a5261eSBarry Smith + comm - MPI communicator, set to `PETSC_COMM_SELF` 30160c775827SLois Curfman McInnes . m - number of rows 301718f449edSLois Curfman McInnes . n - number of columns 30180298fd71SBarry Smith - data - optional location of matrix data in column major order. Set data=NULL for PETSc 3019dfc5480cSLois Curfman McInnes to control all matrix memory allocation. 302020563c6bSBarry Smith 302120563c6bSBarry Smith Output Parameter: 302244cd7ae7SLois Curfman McInnes . A - the matrix 302320563c6bSBarry Smith 302411a5261eSBarry Smith Note: 302518f449edSLois Curfman McInnes The data input variable is intended primarily for Fortran programmers 302618f449edSLois Curfman McInnes who wish to allocate their own matrix memory space. Most users should 30270298fd71SBarry Smith set data=NULL. 302818f449edSLois Curfman McInnes 3029027ccd11SLois Curfman McInnes Level: intermediate 3030027ccd11SLois Curfman McInnes 303111a5261eSBarry Smith .seealso: `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()` 303220563c6bSBarry Smith @*/ 3033*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateSeqDense(MPI_Comm comm, PetscInt m, PetscInt n, PetscScalar *data, Mat *A) 3034*d71ae5a4SJacob Faibussowitsch { 30353a40ed3dSBarry Smith PetscFunctionBegin; 30369566063dSJacob Faibussowitsch PetscCall(MatCreate(comm, A)); 30379566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*A, m, n, m, n)); 30389566063dSJacob Faibussowitsch PetscCall(MatSetType(*A, MATSEQDENSE)); 30399566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(*A, data)); 3040273d9f13SBarry Smith PetscFunctionReturn(0); 3041273d9f13SBarry Smith } 3042273d9f13SBarry Smith 3043273d9f13SBarry Smith /*@C 304411a5261eSBarry Smith MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements of a `MATSEQDENSE` matrix 3045273d9f13SBarry Smith 3046d083f849SBarry Smith Collective 3047273d9f13SBarry Smith 3048273d9f13SBarry Smith Input Parameters: 30491c4f3114SJed Brown + B - the matrix 30500298fd71SBarry Smith - data - the array (or NULL) 3051273d9f13SBarry Smith 305211a5261eSBarry Smith Note: 3053273d9f13SBarry Smith The data input variable is intended primarily for Fortran programmers 3054273d9f13SBarry Smith who wish to allocate their own matrix memory space. Most users should 3055284134d9SBarry Smith need not call this routine. 3056273d9f13SBarry Smith 3057273d9f13SBarry Smith Level: intermediate 3058273d9f13SBarry Smith 305911a5261eSBarry Smith .seealso: `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()`, `MatDenseSetLDA()` 3060273d9f13SBarry Smith @*/ 3061*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation(Mat B, PetscScalar data[]) 3062*d71ae5a4SJacob Faibussowitsch { 3063a23d5eceSKris Buschelman PetscFunctionBegin; 3064d5ea218eSStefano Zampini PetscValidHeaderSpecific(B, MAT_CLASSID, 1); 3065cac4c232SBarry Smith PetscTryMethod(B, "MatSeqDenseSetPreallocation_C", (Mat, PetscScalar[]), (B, data)); 3066a23d5eceSKris Buschelman PetscFunctionReturn(0); 3067a23d5eceSKris Buschelman } 3068a23d5eceSKris Buschelman 3069*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation_SeqDense(Mat B, PetscScalar *data) 3070*d71ae5a4SJacob Faibussowitsch { 3071ad16ce7aSStefano Zampini Mat_SeqDense *b = (Mat_SeqDense *)B->data; 3072273d9f13SBarry Smith 3073273d9f13SBarry Smith PetscFunctionBegin; 307428b400f6SJacob Faibussowitsch PetscCheck(!b->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3075273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 3076a868139aSShri Abhyankar 30779566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(B->rmap)); 30789566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(B->cmap)); 307934ef9618SShri Abhyankar 3080ad16ce7aSStefano Zampini if (b->lda <= 0) b->lda = B->rmap->n; 308186d161a7SShri Abhyankar 30829e8f95c4SLisandro Dalcin if (!data) { /* petsc-allocated storage */ 30839566063dSJacob Faibussowitsch if (!b->user_alloc) PetscCall(PetscFree(b->v)); 30849566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((size_t)b->lda * B->cmap->n, &b->v)); 30852205254eSKarl Rupp 30869e8f95c4SLisandro Dalcin b->user_alloc = PETSC_FALSE; 3087273d9f13SBarry Smith } else { /* user-allocated storage */ 30889566063dSJacob Faibussowitsch if (!b->user_alloc) PetscCall(PetscFree(b->v)); 3089273d9f13SBarry Smith b->v = data; 3090273d9f13SBarry Smith b->user_alloc = PETSC_TRUE; 3091273d9f13SBarry Smith } 30920450473dSBarry Smith B->assembled = PETSC_TRUE; 3093273d9f13SBarry Smith PetscFunctionReturn(0); 3094273d9f13SBarry Smith } 3095273d9f13SBarry Smith 309665b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 3097*d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) 3098*d71ae5a4SJacob Faibussowitsch { 3099d77f618aSHong Zhang Mat mat_elemental; 31001683a169SBarry Smith const PetscScalar *array; 31011683a169SBarry Smith PetscScalar *v_colwise; 3102d77f618aSHong Zhang PetscInt M = A->rmap->N, N = A->cmap->N, i, j, k, *rows, *cols; 3103d77f618aSHong Zhang 31048baccfbdSHong Zhang PetscFunctionBegin; 31059566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(M * N, &v_colwise, M, &rows, N, &cols)); 31069566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &array)); 3107d77f618aSHong Zhang /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */ 3108d77f618aSHong Zhang k = 0; 3109d77f618aSHong Zhang for (j = 0; j < N; j++) { 3110d77f618aSHong Zhang cols[j] = j; 3111ad540459SPierre Jolivet for (i = 0; i < M; i++) v_colwise[j * M + i] = array[k++]; 3112d77f618aSHong Zhang } 3113ad540459SPierre Jolivet for (i = 0; i < M; i++) rows[i] = i; 31149566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &array)); 3115d77f618aSHong Zhang 31169566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental)); 31179566063dSJacob Faibussowitsch PetscCall(MatSetSizes(mat_elemental, PETSC_DECIDE, PETSC_DECIDE, M, N)); 31189566063dSJacob Faibussowitsch PetscCall(MatSetType(mat_elemental, MATELEMENTAL)); 31199566063dSJacob Faibussowitsch PetscCall(MatSetUp(mat_elemental)); 3120d77f618aSHong Zhang 3121d77f618aSHong Zhang /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */ 31229566063dSJacob Faibussowitsch PetscCall(MatSetValues(mat_elemental, M, rows, N, cols, v_colwise, ADD_VALUES)); 31239566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY)); 31249566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY)); 31259566063dSJacob Faibussowitsch PetscCall(PetscFree3(v_colwise, rows, cols)); 3126d77f618aSHong Zhang 3127511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 31289566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A, &mat_elemental)); 3129d77f618aSHong Zhang } else { 3130d77f618aSHong Zhang *newmat = mat_elemental; 3131d77f618aSHong Zhang } 31328baccfbdSHong Zhang PetscFunctionReturn(0); 31338baccfbdSHong Zhang } 313465b80a83SHong Zhang #endif 31358baccfbdSHong Zhang 3136*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA_SeqDense(Mat B, PetscInt lda) 3137*d71ae5a4SJacob Faibussowitsch { 31381b807ce4Svictorle Mat_SeqDense *b = (Mat_SeqDense *)B->data; 31397422da62SJose E. Roman PetscBool data; 314021a2c019SBarry Smith 31411b807ce4Svictorle PetscFunctionBegin; 31427422da62SJose E. Roman data = (PetscBool)((B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE); 3143aed4548fSBarry Smith PetscCheck(b->user_alloc || !data || b->lda == lda, PETSC_COMM_SELF, PETSC_ERR_ORDER, "LDA cannot be changed after allocation of internal storage"); 314408401ef6SPierre 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); 31451b807ce4Svictorle b->lda = lda; 31461b807ce4Svictorle PetscFunctionReturn(0); 31471b807ce4Svictorle } 31481b807ce4Svictorle 3149*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm, Mat inmat, PetscInt n, MatReuse scall, Mat *outmat) 3150*d71ae5a4SJacob Faibussowitsch { 3151d528f656SJakub Kruzik PetscFunctionBegin; 31529566063dSJacob Faibussowitsch PetscCall(MatCreateMPIMatConcatenateSeqMat_MPIDense(comm, inmat, n, scall, outmat)); 3153d528f656SJakub Kruzik PetscFunctionReturn(0); 3154d528f656SJakub Kruzik } 3155d528f656SJakub Kruzik 3156*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A, PetscInt col, Vec *v) 3157*d71ae5a4SJacob Faibussowitsch { 31586947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 31596947451fSStefano Zampini 31606947451fSStefano Zampini PetscFunctionBegin; 316128b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 316228b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 31634dfa11a4SJacob Faibussowitsch if (!a->cvec) { PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec)); } 31646947451fSStefano Zampini a->vecinuse = col + 1; 31659566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, (PetscScalar **)&a->ptrinuse)); 31669566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda)); 31676947451fSStefano Zampini *v = a->cvec; 31686947451fSStefano Zampini PetscFunctionReturn(0); 31696947451fSStefano Zampini } 31706947451fSStefano Zampini 3171*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A, PetscInt col, Vec *v) 3172*d71ae5a4SJacob Faibussowitsch { 31736947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 31746947451fSStefano Zampini 31756947451fSStefano Zampini PetscFunctionBegin; 317628b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 317728b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 31786947451fSStefano Zampini a->vecinuse = 0; 31799566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, (PetscScalar **)&a->ptrinuse)); 31809566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 318175f6d85dSStefano Zampini if (v) *v = NULL; 31826947451fSStefano Zampini PetscFunctionReturn(0); 31836947451fSStefano Zampini } 31846947451fSStefano Zampini 3185*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v) 3186*d71ae5a4SJacob 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(MatDenseGetArrayRead(A, &a->ptrinuse)); 31959566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda)); 31969566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(a->cvec)); 31976947451fSStefano Zampini *v = a->cvec; 31986947451fSStefano Zampini PetscFunctionReturn(0); 31996947451fSStefano Zampini } 32006947451fSStefano Zampini 3201*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v) 3202*d71ae5a4SJacob Faibussowitsch { 32036947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 32046947451fSStefano Zampini 32056947451fSStefano Zampini PetscFunctionBegin; 320628b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 320728b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 32086947451fSStefano Zampini a->vecinuse = 0; 32099566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &a->ptrinuse)); 32109566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(a->cvec)); 32119566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 321275f6d85dSStefano Zampini if (v) *v = NULL; 32136947451fSStefano Zampini PetscFunctionReturn(0); 32146947451fSStefano Zampini } 32156947451fSStefano Zampini 3216*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v) 3217*d71ae5a4SJacob Faibussowitsch { 32186947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 32196947451fSStefano Zampini 32206947451fSStefano Zampini PetscFunctionBegin; 322128b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 322228b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 32234dfa11a4SJacob Faibussowitsch if (!a->cvec) { PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec)); } 32246947451fSStefano Zampini a->vecinuse = col + 1; 32259566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(A, (PetscScalar **)&a->ptrinuse)); 32269566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda)); 32276947451fSStefano Zampini *v = a->cvec; 32286947451fSStefano Zampini PetscFunctionReturn(0); 32296947451fSStefano Zampini } 32306947451fSStefano Zampini 3231*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v) 3232*d71ae5a4SJacob Faibussowitsch { 32336947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 32346947451fSStefano Zampini 32356947451fSStefano Zampini PetscFunctionBegin; 323628b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 323728b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 32386947451fSStefano Zampini a->vecinuse = 0; 32399566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(A, (PetscScalar **)&a->ptrinuse)); 32409566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 324175f6d85dSStefano Zampini if (v) *v = NULL; 32426947451fSStefano Zampini PetscFunctionReturn(0); 32436947451fSStefano Zampini } 32446947451fSStefano Zampini 3245*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) 3246*d71ae5a4SJacob Faibussowitsch { 32475ea7661aSPierre Jolivet Mat_SeqDense *a = (Mat_SeqDense *)A->data; 32485ea7661aSPierre Jolivet 32495ea7661aSPierre Jolivet 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"); 3252a2748737SPierre Jolivet if (a->cmat && (cend - cbegin != a->cmat->cmap->N || rend - rbegin != a->cmat->rmap->N)) PetscCall(MatDestroy(&a->cmat)); 32535ea7661aSPierre Jolivet if (!a->cmat) { 3254a2748737SPierre Jolivet PetscCall(MatCreateDense(PetscObjectComm((PetscObject)A), rend - rbegin, PETSC_DECIDE, rend - rbegin, cend - cbegin, a->v + rbegin + (size_t)cbegin * a->lda, &a->cmat)); 32555ea7661aSPierre Jolivet } else { 3256a2748737SPierre Jolivet PetscCall(MatDensePlaceArray(a->cmat, a->v + rbegin + (size_t)cbegin * a->lda)); 32575ea7661aSPierre Jolivet } 32589566063dSJacob Faibussowitsch PetscCall(MatDenseSetLDA(a->cmat, a->lda)); 32595ea7661aSPierre Jolivet a->matinuse = cbegin + 1; 32605ea7661aSPierre Jolivet *v = a->cmat; 326175f6d85dSStefano Zampini #if defined(PETSC_HAVE_CUDA) 326275f6d85dSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 326375f6d85dSStefano Zampini #endif 32645ea7661aSPierre Jolivet PetscFunctionReturn(0); 32655ea7661aSPierre Jolivet } 32665ea7661aSPierre Jolivet 3267*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A, Mat *v) 3268*d71ae5a4SJacob Faibussowitsch { 32695ea7661aSPierre Jolivet Mat_SeqDense *a = (Mat_SeqDense *)A->data; 32705ea7661aSPierre Jolivet 32715ea7661aSPierre Jolivet PetscFunctionBegin; 327228b400f6SJacob Faibussowitsch PetscCheck(a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetSubMatrix() first"); 327328b400f6SJacob Faibussowitsch PetscCheck(a->cmat, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column matrix"); 327408401ef6SPierre Jolivet PetscCheck(*v == a->cmat, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not the matrix obtained from MatDenseGetSubMatrix()"); 32755ea7661aSPierre Jolivet a->matinuse = 0; 32769566063dSJacob Faibussowitsch PetscCall(MatDenseResetArray(a->cmat)); 3277742765d3SMatthew Knepley if (v) *v = NULL; 32783faff063SStefano Zampini #if defined(PETSC_HAVE_CUDA) 32793faff063SStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 32803faff063SStefano Zampini #endif 32815ea7661aSPierre Jolivet PetscFunctionReturn(0); 32825ea7661aSPierre Jolivet } 32835ea7661aSPierre Jolivet 32840bad9183SKris Buschelman /*MC 3285fafad747SKris Buschelman MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices. 32860bad9183SKris Buschelman 32870bad9183SKris Buschelman Options Database Keys: 328811a5261eSBarry Smith . -mat_type seqdense - sets the matrix type to `MATSEQDENSE` during a call to `MatSetFromOptions()` 32890bad9183SKris Buschelman 32900bad9183SKris Buschelman Level: beginner 32910bad9183SKris Buschelman 329211a5261eSBarry Smith .seealso: `MATSEQDENSE`, `MatCreateSeqDense()` 32930bad9183SKris Buschelman M*/ 3294*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreate_SeqDense(Mat B) 3295*d71ae5a4SJacob Faibussowitsch { 3296273d9f13SBarry Smith Mat_SeqDense *b; 32977c334f02SBarry Smith PetscMPIInt size; 3298273d9f13SBarry Smith 3299273d9f13SBarry Smith PetscFunctionBegin; 33009566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)B), &size)); 330108401ef6SPierre Jolivet PetscCheck(size <= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Comm must be of size 1"); 330255659b69SBarry Smith 33034dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&b)); 33049566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(B->ops, &MatOps_Values, sizeof(struct _MatOps))); 330544cd7ae7SLois Curfman McInnes B->data = (void *)b; 330618f449edSLois Curfman McInnes 3307273d9f13SBarry Smith b->roworiented = PETSC_TRUE; 33084e220ebcSLois Curfman McInnes 33099566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatQRFactor_C", MatQRFactor_SeqDense)); 33109566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetLDA_C", MatDenseGetLDA_SeqDense)); 33119566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseSetLDA_C", MatDenseSetLDA_SeqDense)); 33129566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArray_C", MatDenseGetArray_SeqDense)); 33139566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArray_C", MatDenseRestoreArray_SeqDense)); 33149566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDensePlaceArray_C", MatDensePlaceArray_SeqDense)); 33159566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseResetArray_C", MatDenseResetArray_SeqDense)); 33169566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseReplaceArray_C", MatDenseReplaceArray_SeqDense)); 33179566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayRead_C", MatDenseGetArray_SeqDense)); 33189566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayRead_C", MatDenseRestoreArray_SeqDense)); 33199566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayWrite_C", MatDenseGetArray_SeqDense)); 33209566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayWrite_C", MatDenseRestoreArray_SeqDense)); 33219566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqaij_C", MatConvert_SeqDense_SeqAIJ)); 33228baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 33239566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_elemental_C", MatConvert_SeqDense_Elemental)); 33248baccfbdSHong Zhang #endif 3325d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 33269566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_scalapack_C", MatConvert_Dense_ScaLAPACK)); 3327d24d4204SJose E. Roman #endif 33282bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA) 33299566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensecuda_C", MatConvert_SeqDense_SeqDenseCUDA)); 33309566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", MatProductSetFromOptions_SeqDense)); 33319566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdense_C", MatProductSetFromOptions_SeqDense)); 33329566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensecuda_C", MatProductSetFromOptions_SeqDense)); 33332bf066beSStefano Zampini #endif 33349566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSeqDenseSetPreallocation_C", MatSeqDenseSetPreallocation_SeqDense)); 33359566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqaij_seqdense_C", MatProductSetFromOptions_SeqAIJ_SeqDense)); 33369566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdense_C", MatProductSetFromOptions_SeqDense)); 33379566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense)); 33389566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqsbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense)); 333996e6d5c4SRichard Tran Mills 33409566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumn_C", MatDenseGetColumn_SeqDense)); 33419566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumn_C", MatDenseRestoreColumn_SeqDense)); 33429566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVec_C", MatDenseGetColumnVec_SeqDense)); 33439566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVec_C", MatDenseRestoreColumnVec_SeqDense)); 33449566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecRead_C", MatDenseGetColumnVecRead_SeqDense)); 33459566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecRead_C", MatDenseRestoreColumnVecRead_SeqDense)); 33469566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecWrite_C", MatDenseGetColumnVecWrite_SeqDense)); 33479566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecWrite_C", MatDenseRestoreColumnVecWrite_SeqDense)); 33489566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetSubMatrix_C", MatDenseGetSubMatrix_SeqDense)); 33499566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreSubMatrix_C", MatDenseRestoreSubMatrix_SeqDense)); 33509566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)B, MATSEQDENSE)); 33513a40ed3dSBarry Smith PetscFunctionReturn(0); 3352289bc588SBarry Smith } 335386aefd0dSHong Zhang 335486aefd0dSHong Zhang /*@C 335511a5261eSBarry 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. 335686aefd0dSHong Zhang 335786aefd0dSHong Zhang Not Collective 335886aefd0dSHong Zhang 33595ea7661aSPierre Jolivet Input Parameters: 336011a5261eSBarry Smith + mat - a `MATSEQDENSE` or `MATMPIDENSE` matrix 336186aefd0dSHong Zhang - col - column index 336286aefd0dSHong Zhang 336386aefd0dSHong Zhang Output Parameter: 336486aefd0dSHong Zhang . vals - pointer to the data 336586aefd0dSHong Zhang 336686aefd0dSHong Zhang Level: intermediate 336786aefd0dSHong Zhang 336811a5261eSBarry Smith Note: 336911a5261eSBarry Smith Use `MatDenseGetColumnVec()` to get access to a column of a `MATDENSE` treated as a `Vec` 337011a5261eSBarry Smith 337111a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreColumn()`, `MatDenseGetColumnVec()` 337286aefd0dSHong Zhang @*/ 3373*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumn(Mat A, PetscInt col, PetscScalar **vals) 3374*d71ae5a4SJacob Faibussowitsch { 337586aefd0dSHong Zhang PetscFunctionBegin; 3376d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3377d5ea218eSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 3378d5ea218eSStefano Zampini PetscValidPointer(vals, 3); 3379cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumn_C", (Mat, PetscInt, PetscScalar **), (A, col, vals)); 338086aefd0dSHong Zhang PetscFunctionReturn(0); 338186aefd0dSHong Zhang } 338286aefd0dSHong Zhang 338386aefd0dSHong Zhang /*@C 338411a5261eSBarry Smith MatDenseRestoreColumn - returns access to a column of a `MATDENSE` matrix which is returned by `MatDenseGetColumn()`. 338586aefd0dSHong Zhang 338686aefd0dSHong Zhang Not Collective 338786aefd0dSHong Zhang 3388742765d3SMatthew Knepley Input Parameters: 338911a5261eSBarry Smith + mat - a `MATSEQDENSE` or `MATMPIDENSE` matrix 3390742765d3SMatthew Knepley - vals - pointer to the data (may be NULL) 339186aefd0dSHong Zhang 339286aefd0dSHong Zhang Level: intermediate 339386aefd0dSHong Zhang 339411a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetColumn()` 339586aefd0dSHong Zhang @*/ 3396*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumn(Mat A, PetscScalar **vals) 3397*d71ae5a4SJacob Faibussowitsch { 339886aefd0dSHong Zhang PetscFunctionBegin; 3399d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3400d5ea218eSStefano Zampini PetscValidPointer(vals, 2); 3401cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumn_C", (Mat, PetscScalar **), (A, vals)); 340286aefd0dSHong Zhang PetscFunctionReturn(0); 340386aefd0dSHong Zhang } 34046947451fSStefano Zampini 34050f74d2c1SSatish Balay /*@ 340611a5261eSBarry Smith MatDenseGetColumnVec - Gives read-write access to a column of a `MATDENSE` matrix, represented as a `Vec`. 34076947451fSStefano Zampini 34086947451fSStefano Zampini Collective 34096947451fSStefano Zampini 34105ea7661aSPierre Jolivet Input Parameters: 341111a5261eSBarry Smith + mat - the `Mat` object 34126947451fSStefano Zampini - col - the column index 34136947451fSStefano Zampini 34146947451fSStefano Zampini Output Parameter: 34156947451fSStefano Zampini . v - the vector 34166947451fSStefano Zampini 34176947451fSStefano Zampini Notes: 341811a5261eSBarry Smith The vector is owned by PETSc. Users need to call `MatDenseRestoreColumnVec()` when the vector is no longer needed. 341911a5261eSBarry Smith 342011a5261eSBarry Smith Use `MatDenseGetColumnVecRead()` to obtain read-only access or `MatDenseGetColumnVecWrite()` for write-only access. 34216947451fSStefano Zampini 34226947451fSStefano Zampini Level: intermediate 34236947451fSStefano Zampini 342411a5261eSBarry Smith .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`, `MatDenseGetColumn()` 34256947451fSStefano Zampini @*/ 3426*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec(Mat A, PetscInt col, Vec *v) 3427*d71ae5a4SJacob Faibussowitsch { 34286947451fSStefano Zampini PetscFunctionBegin; 34296947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 34306947451fSStefano Zampini PetscValidType(A, 1); 34316947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 34326947451fSStefano Zampini PetscValidPointer(v, 3); 343328b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 34342cf15c64SPierre 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); 3435cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v)); 34366947451fSStefano Zampini PetscFunctionReturn(0); 34376947451fSStefano Zampini } 34386947451fSStefano Zampini 34390f74d2c1SSatish Balay /*@ 34406947451fSStefano Zampini MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVec(). 34416947451fSStefano Zampini 34426947451fSStefano Zampini Collective 34436947451fSStefano Zampini 34445ea7661aSPierre Jolivet Input Parameters: 34456947451fSStefano Zampini + mat - the Mat object 34466947451fSStefano Zampini . col - the column index 3447742765d3SMatthew Knepley - v - the Vec object (may be NULL) 34486947451fSStefano Zampini 34496947451fSStefano Zampini Level: intermediate 34506947451fSStefano Zampini 3451db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 34526947451fSStefano Zampini @*/ 3453*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec(Mat A, PetscInt col, Vec *v) 3454*d71ae5a4SJacob Faibussowitsch { 34556947451fSStefano Zampini PetscFunctionBegin; 34566947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 34576947451fSStefano Zampini PetscValidType(A, 1); 34586947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 345908401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 34602cf15c64SPierre 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); 3461cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v)); 34626947451fSStefano Zampini PetscFunctionReturn(0); 34636947451fSStefano Zampini } 34646947451fSStefano Zampini 34650f74d2c1SSatish Balay /*@ 34666947451fSStefano Zampini MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a Vec. 34676947451fSStefano Zampini 34686947451fSStefano Zampini Collective 34696947451fSStefano Zampini 34705ea7661aSPierre Jolivet Input Parameters: 34716947451fSStefano Zampini + mat - the Mat object 34726947451fSStefano Zampini - col - the column index 34736947451fSStefano Zampini 34746947451fSStefano Zampini Output Parameter: 34756947451fSStefano Zampini . v - the vector 34766947451fSStefano Zampini 34776947451fSStefano Zampini Notes: 34786947451fSStefano Zampini The vector is owned by PETSc and users cannot modify it. 347911a5261eSBarry Smith 34806947451fSStefano Zampini Users need to call MatDenseRestoreColumnVecRead() when the vector is no longer needed. 348111a5261eSBarry Smith 34826947451fSStefano Zampini Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecWrite() for write-only access. 34836947451fSStefano Zampini 34846947451fSStefano Zampini Level: intermediate 34856947451fSStefano Zampini 3486db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 34876947451fSStefano Zampini @*/ 3488*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead(Mat A, PetscInt col, Vec *v) 3489*d71ae5a4SJacob Faibussowitsch { 34906947451fSStefano Zampini PetscFunctionBegin; 34916947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 34926947451fSStefano Zampini PetscValidType(A, 1); 34936947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 34946947451fSStefano Zampini PetscValidPointer(v, 3); 349528b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 34962cf15c64SPierre 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); 3497cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v)); 34986947451fSStefano Zampini PetscFunctionReturn(0); 34996947451fSStefano Zampini } 35006947451fSStefano Zampini 35010f74d2c1SSatish Balay /*@ 35026947451fSStefano Zampini MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecRead(). 35036947451fSStefano Zampini 35046947451fSStefano Zampini Collective 35056947451fSStefano Zampini 35065ea7661aSPierre Jolivet Input Parameters: 35076947451fSStefano Zampini + mat - the Mat object 35086947451fSStefano Zampini . col - the column index 3509742765d3SMatthew Knepley - v - the Vec object (may be NULL) 35106947451fSStefano Zampini 35116947451fSStefano Zampini Level: intermediate 35126947451fSStefano Zampini 3513db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecWrite()` 35146947451fSStefano Zampini @*/ 3515*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead(Mat A, PetscInt col, Vec *v) 3516*d71ae5a4SJacob Faibussowitsch { 35176947451fSStefano Zampini PetscFunctionBegin; 35186947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 35196947451fSStefano Zampini PetscValidType(A, 1); 35206947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 352108401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 35222cf15c64SPierre 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); 3523cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v)); 35246947451fSStefano Zampini PetscFunctionReturn(0); 35256947451fSStefano Zampini } 35266947451fSStefano Zampini 35270f74d2c1SSatish Balay /*@ 35286947451fSStefano Zampini MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a Vec. 35296947451fSStefano Zampini 35306947451fSStefano Zampini Collective 35316947451fSStefano Zampini 35325ea7661aSPierre Jolivet Input Parameters: 35336947451fSStefano Zampini + mat - the Mat object 35346947451fSStefano Zampini - col - the column index 35356947451fSStefano Zampini 35366947451fSStefano Zampini Output Parameter: 35376947451fSStefano Zampini . v - the vector 35386947451fSStefano Zampini 35396947451fSStefano Zampini Notes: 35406947451fSStefano Zampini The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVecWrite() when the vector is no longer needed. 354111a5261eSBarry Smith 35426947451fSStefano Zampini Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecRead() for read-only access. 35436947451fSStefano Zampini 35446947451fSStefano Zampini Level: intermediate 35456947451fSStefano Zampini 3546db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 35476947451fSStefano Zampini @*/ 3548*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite(Mat A, PetscInt col, Vec *v) 3549*d71ae5a4SJacob Faibussowitsch { 35506947451fSStefano Zampini PetscFunctionBegin; 35516947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 35526947451fSStefano Zampini PetscValidType(A, 1); 35536947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 35546947451fSStefano Zampini PetscValidPointer(v, 3); 355528b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3556aed4548fSBarry 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); 3557cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v)); 35586947451fSStefano Zampini PetscFunctionReturn(0); 35596947451fSStefano Zampini } 35606947451fSStefano Zampini 35610f74d2c1SSatish Balay /*@ 35626947451fSStefano Zampini MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecWrite(). 35636947451fSStefano Zampini 35646947451fSStefano Zampini Collective 35656947451fSStefano Zampini 35665ea7661aSPierre Jolivet Input Parameters: 35676947451fSStefano Zampini + mat - the Mat object 35686947451fSStefano Zampini . col - the column index 3569742765d3SMatthew Knepley - v - the Vec object (may be NULL) 35706947451fSStefano Zampini 35716947451fSStefano Zampini Level: intermediate 35726947451fSStefano Zampini 3573db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()` 35746947451fSStefano Zampini @*/ 3575*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A, PetscInt col, Vec *v) 3576*d71ae5a4SJacob Faibussowitsch { 35776947451fSStefano Zampini PetscFunctionBegin; 35786947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 35796947451fSStefano Zampini PetscValidType(A, 1); 35806947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 358108401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3582aed4548fSBarry 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); 3583cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v)); 35846947451fSStefano Zampini PetscFunctionReturn(0); 35856947451fSStefano Zampini } 35865ea7661aSPierre Jolivet 35870f74d2c1SSatish Balay /*@ 3588a2748737SPierre Jolivet MatDenseGetSubMatrix - Gives access to a block of rows and columns of a dense matrix, represented as a Mat. 35895ea7661aSPierre Jolivet 35905ea7661aSPierre Jolivet Collective 35915ea7661aSPierre Jolivet 35925ea7661aSPierre Jolivet Input Parameters: 35935ea7661aSPierre Jolivet + mat - the Mat object 3594a2748737SPierre Jolivet . rbegin - the first global row index in the block (if PETSC_DECIDE, is 0) 3595a2748737SPierre Jolivet . rend - the global row index past the last one in the block (if PETSC_DECIDE, is M) 3596a2748737SPierre Jolivet . cbegin - the first global column index in the block (if PETSC_DECIDE, is 0) 3597a2748737SPierre Jolivet - cend - the global column index past the last one in the block (if PETSC_DECIDE, is N) 35985ea7661aSPierre Jolivet 35995ea7661aSPierre Jolivet Output Parameter: 36005ea7661aSPierre Jolivet . v - the matrix 36015ea7661aSPierre Jolivet 36025ea7661aSPierre Jolivet Notes: 36035ea7661aSPierre Jolivet The matrix is owned by PETSc. Users need to call MatDenseRestoreSubMatrix() when the matrix is no longer needed. 360411a5261eSBarry Smith 3605a2748737SPierre 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. 36065ea7661aSPierre Jolivet 36075ea7661aSPierre Jolivet Level: intermediate 36085ea7661aSPierre Jolivet 3609db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreSubMatrix()` 36105ea7661aSPierre Jolivet @*/ 3611*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) 3612*d71ae5a4SJacob Faibussowitsch { 36135ea7661aSPierre Jolivet PetscFunctionBegin; 36145ea7661aSPierre Jolivet PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 36155ea7661aSPierre Jolivet PetscValidType(A, 1); 3616a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, rbegin, 2); 3617a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, rend, 3); 3618a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, cbegin, 4); 3619a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, cend, 5); 3620a2748737SPierre Jolivet PetscValidPointer(v, 6); 3621a2748737SPierre Jolivet if (rbegin == PETSC_DECIDE) rbegin = 0; 3622a2748737SPierre Jolivet if (rend == PETSC_DECIDE) rend = A->rmap->N; 3623a2748737SPierre Jolivet if (cbegin == PETSC_DECIDE) cbegin = 0; 3624a2748737SPierre Jolivet if (cend == PETSC_DECIDE) cend = A->cmap->N; 362528b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3626a2748737SPierre 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); 3627a2748737SPierre 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); 3628a2748737SPierre 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); 3629a2748737SPierre 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); 3630a2748737SPierre Jolivet PetscUseMethod(A, "MatDenseGetSubMatrix_C", (Mat, PetscInt, PetscInt, PetscInt, PetscInt, Mat *), (A, rbegin, rend, cbegin, cend, v)); 36315ea7661aSPierre Jolivet PetscFunctionReturn(0); 36325ea7661aSPierre Jolivet } 36335ea7661aSPierre Jolivet 36340f74d2c1SSatish Balay /*@ 36355ea7661aSPierre Jolivet MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from MatDenseGetSubMatrix(). 36365ea7661aSPierre Jolivet 36375ea7661aSPierre Jolivet Collective 36385ea7661aSPierre Jolivet 36395ea7661aSPierre Jolivet Input Parameters: 36405ea7661aSPierre Jolivet + mat - the Mat object 3641742765d3SMatthew Knepley - v - the Mat object (may be NULL) 36425ea7661aSPierre Jolivet 36435ea7661aSPierre Jolivet Level: intermediate 36445ea7661aSPierre Jolivet 3645db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseGetSubMatrix()` 36465ea7661aSPierre Jolivet @*/ 3647*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix(Mat A, Mat *v) 3648*d71ae5a4SJacob Faibussowitsch { 36495ea7661aSPierre Jolivet PetscFunctionBegin; 36505ea7661aSPierre Jolivet PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 36515ea7661aSPierre Jolivet PetscValidType(A, 1); 36525ea7661aSPierre Jolivet PetscValidPointer(v, 2); 3653cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreSubMatrix_C", (Mat, Mat *), (A, v)); 36545ea7661aSPierre Jolivet PetscFunctionReturn(0); 36555ea7661aSPierre Jolivet } 36568a9c020eSBarry Smith 36578a9c020eSBarry Smith #include <petscblaslapack.h> 36588a9c020eSBarry Smith #include <petsc/private/kernels/blockinvert.h> 36598a9c020eSBarry Smith 3660*d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseInvert(Mat A) 3661*d71ae5a4SJacob Faibussowitsch { 36628a9c020eSBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 36638a9c020eSBarry Smith PetscInt bs = A->rmap->n; 36648a9c020eSBarry Smith MatScalar *values = a->v; 36658a9c020eSBarry Smith const PetscReal shift = 0.0; 36668a9c020eSBarry Smith PetscBool allowzeropivot = PetscNot(A->erroriffailure), zeropivotdetected = PETSC_FALSE; 36678a9c020eSBarry Smith 36688a9c020eSBarry Smith PetscFunctionBegin; 36698a9c020eSBarry Smith /* factor and invert each block */ 36708a9c020eSBarry Smith switch (bs) { 3671*d71ae5a4SJacob Faibussowitsch case 1: 3672*d71ae5a4SJacob Faibussowitsch values[0] = (PetscScalar)1.0 / (values[0] + shift); 3673*d71ae5a4SJacob Faibussowitsch break; 36748a9c020eSBarry Smith case 2: 36758a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_2(values, shift, allowzeropivot, &zeropivotdetected)); 36768a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 36778a9c020eSBarry Smith break; 36788a9c020eSBarry Smith case 3: 36798a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_3(values, shift, allowzeropivot, &zeropivotdetected)); 36808a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 36818a9c020eSBarry Smith break; 36828a9c020eSBarry Smith case 4: 36838a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_4(values, shift, allowzeropivot, &zeropivotdetected)); 36848a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 36858a9c020eSBarry Smith break; 36869371c9d4SSatish Balay case 5: { 36878a9c020eSBarry Smith PetscScalar work[25]; 36888a9c020eSBarry Smith PetscInt ipvt[5]; 36898a9c020eSBarry Smith 36908a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_5(values, ipvt, work, shift, allowzeropivot, &zeropivotdetected)); 36918a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 36929371c9d4SSatish Balay } break; 36938a9c020eSBarry Smith case 6: 36948a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_6(values, shift, allowzeropivot, &zeropivotdetected)); 36958a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 36968a9c020eSBarry Smith break; 36978a9c020eSBarry Smith case 7: 36988a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_7(values, shift, allowzeropivot, &zeropivotdetected)); 36998a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 37008a9c020eSBarry Smith break; 37019371c9d4SSatish Balay default: { 37028a9c020eSBarry Smith PetscInt *v_pivots, *IJ, j; 37038a9c020eSBarry Smith PetscScalar *v_work; 37048a9c020eSBarry Smith 37058a9c020eSBarry Smith PetscCall(PetscMalloc3(bs, &v_work, bs, &v_pivots, bs, &IJ)); 3706ad540459SPierre Jolivet for (j = 0; j < bs; j++) IJ[j] = j; 37078a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A(bs, values, v_pivots, v_work, allowzeropivot, &zeropivotdetected)); 37088a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 37098a9c020eSBarry Smith PetscCall(PetscFree3(v_work, v_pivots, IJ)); 37108a9c020eSBarry Smith } 37118a9c020eSBarry Smith } 37128a9c020eSBarry Smith PetscFunctionReturn(0); 37138a9c020eSBarry Smith } 3714