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 99371c9d4SSatish Balay PetscErrorCode MatSeqDenseSymmetrize_Private(Mat A, PetscBool hermitian) { 108c178816SStefano Zampini Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 118c178816SStefano Zampini PetscInt j, k, n = A->rmap->n; 12ca15aa20SStefano Zampini PetscScalar *v; 138c178816SStefano Zampini 148c178816SStefano Zampini PetscFunctionBegin; 1508401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Cannot symmetrize a rectangular matrix"); 169566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 178c178816SStefano Zampini if (!hermitian) { 188c178816SStefano Zampini for (k = 0; k < n; k++) { 19ad540459SPierre Jolivet for (j = k; j < n; j++) v[j * mat->lda + k] = v[k * mat->lda + j]; 208c178816SStefano Zampini } 218c178816SStefano Zampini } else { 228c178816SStefano Zampini for (k = 0; k < n; k++) { 23ad540459SPierre Jolivet for (j = k; j < n; j++) v[j * mat->lda + k] = PetscConj(v[k * mat->lda + j]); 248c178816SStefano Zampini } 258c178816SStefano Zampini } 269566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 278c178816SStefano Zampini PetscFunctionReturn(0); 288c178816SStefano Zampini } 298c178816SStefano Zampini 309371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode MatSeqDenseInvertFactors_Private(Mat A) { 318c178816SStefano Zampini Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 328c178816SStefano Zampini PetscBLASInt info, n; 338c178816SStefano Zampini 348c178816SStefano Zampini PetscFunctionBegin; 358c178816SStefano Zampini if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 369566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 378c178816SStefano Zampini if (A->factortype == MAT_FACTOR_LU) { 3828b400f6SJacob Faibussowitsch PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present"); 398c178816SStefano Zampini if (!mat->fwork) { 408c178816SStefano Zampini mat->lfwork = n; 419566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 429566063dSJacob Faibussowitsch PetscCall(PetscLogObjectMemory((PetscObject)A, mat->lfwork * sizeof(PetscBLASInt))); 438c178816SStefano Zampini } 449566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 45792fecdfSBarry Smith PetscCallBLAS("LAPACKgetri", LAPACKgetri_(&n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info)); 469566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 479566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0)); 488c178816SStefano Zampini } else if (A->factortype == MAT_FACTOR_CHOLESKY) { 49b94d7dedSBarry Smith if (A->spd == PETSC_BOOL3_TRUE) { 509566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 51792fecdfSBarry Smith PetscCallBLAS("LAPACKpotri", LAPACKpotri_("L", &n, mat->v, &mat->lda, &info)); 529566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 539566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_TRUE)); 548c178816SStefano Zampini #if defined(PETSC_USE_COMPLEX) 55b94d7dedSBarry Smith } else if (A->hermitian == PETSC_BOOL3_TRUE) { 5628b400f6SJacob Faibussowitsch PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present"); 5728b400f6SJacob Faibussowitsch PetscCheck(mat->fwork, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Fwork not present"); 589566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 59792fecdfSBarry Smith PetscCallBLAS("LAPACKhetri", LAPACKhetri_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &info)); 609566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 619566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_TRUE)); 628c178816SStefano Zampini #endif 638c178816SStefano Zampini } else { /* symmetric case */ 6428b400f6SJacob Faibussowitsch PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present"); 6528b400f6SJacob Faibussowitsch PetscCheck(mat->fwork, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Fwork not present"); 669566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 67792fecdfSBarry Smith PetscCallBLAS("LAPACKsytri", LAPACKsytri_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &info)); 689566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 699566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_FALSE)); 708c178816SStefano Zampini } 7128b400f6SJacob Faibussowitsch PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad Inversion: zero pivot in row %" PetscInt_FMT, (PetscInt)info - 1); 729566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0)); 738c178816SStefano Zampini } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Matrix must be factored to solve"); 748c178816SStefano Zampini 758c178816SStefano Zampini A->ops->solve = NULL; 768c178816SStefano Zampini A->ops->matsolve = NULL; 778c178816SStefano Zampini A->ops->solvetranspose = NULL; 788c178816SStefano Zampini A->ops->matsolvetranspose = NULL; 798c178816SStefano Zampini A->ops->solveadd = NULL; 808c178816SStefano Zampini A->ops->solvetransposeadd = NULL; 818c178816SStefano Zampini A->factortype = MAT_FACTOR_NONE; 829566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 838c178816SStefano Zampini PetscFunctionReturn(0); 848c178816SStefano Zampini } 858c178816SStefano Zampini 869371c9d4SSatish Balay PetscErrorCode MatZeroRowsColumns_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) { 873f49a652SStefano Zampini Mat_SeqDense *l = (Mat_SeqDense *)A->data; 883f49a652SStefano Zampini PetscInt m = l->lda, n = A->cmap->n, r = A->rmap->n, i, j; 89ca15aa20SStefano Zampini PetscScalar *slot, *bb, *v; 903f49a652SStefano Zampini const PetscScalar *xx; 913f49a652SStefano Zampini 923f49a652SStefano Zampini PetscFunctionBegin; 9376bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 943f49a652SStefano Zampini for (i = 0; i < N; i++) { 9508401ef6SPierre Jolivet PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed"); 9608401ef6SPierre 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); 9708401ef6SPierre 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); 983f49a652SStefano Zampini } 9976bd3646SJed Brown } 100ca15aa20SStefano Zampini if (!N) PetscFunctionReturn(0); 1013f49a652SStefano Zampini 1023f49a652SStefano Zampini /* fix right hand side if needed */ 1033f49a652SStefano Zampini if (x && b) { 1046c4d906cSStefano Zampini Vec xt; 1056c4d906cSStefano Zampini 10608401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices"); 1079566063dSJacob Faibussowitsch PetscCall(VecDuplicate(x, &xt)); 1089566063dSJacob Faibussowitsch PetscCall(VecCopy(x, xt)); 1099566063dSJacob Faibussowitsch PetscCall(VecScale(xt, -1.0)); 1109566063dSJacob Faibussowitsch PetscCall(MatMultAdd(A, xt, b, b)); 1119566063dSJacob Faibussowitsch PetscCall(VecDestroy(&xt)); 1129566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 1139566063dSJacob Faibussowitsch PetscCall(VecGetArray(b, &bb)); 1143f49a652SStefano Zampini for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]]; 1159566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 1169566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(b, &bb)); 1173f49a652SStefano Zampini } 1183f49a652SStefano Zampini 1199566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 1203f49a652SStefano Zampini for (i = 0; i < N; i++) { 121ca15aa20SStefano Zampini slot = v + rows[i] * m; 1229566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(slot, r)); 1233f49a652SStefano Zampini } 1243f49a652SStefano Zampini for (i = 0; i < N; i++) { 125ca15aa20SStefano Zampini slot = v + rows[i]; 1269371c9d4SSatish Balay for (j = 0; j < n; j++) { 1279371c9d4SSatish Balay *slot = 0.0; 1289371c9d4SSatish Balay slot += m; 1299371c9d4SSatish Balay } 1303f49a652SStefano Zampini } 1313f49a652SStefano Zampini if (diag != 0.0) { 13208401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices"); 1333f49a652SStefano Zampini for (i = 0; i < N; i++) { 134ca15aa20SStefano Zampini slot = v + (m + 1) * rows[i]; 1353f49a652SStefano Zampini *slot = diag; 1363f49a652SStefano Zampini } 1373f49a652SStefano Zampini } 1389566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 1393f49a652SStefano Zampini PetscFunctionReturn(0); 1403f49a652SStefano Zampini } 1413f49a652SStefano Zampini 1429371c9d4SSatish Balay PetscErrorCode MatPtAPNumeric_SeqDense_SeqDense(Mat A, Mat P, Mat C) { 143abc3b08eSStefano Zampini Mat_SeqDense *c = (Mat_SeqDense *)(C->data); 144abc3b08eSStefano Zampini 145abc3b08eSStefano Zampini PetscFunctionBegin; 146ca15aa20SStefano Zampini if (c->ptapwork) { 1479566063dSJacob Faibussowitsch PetscCall((*C->ops->matmultnumeric)(A, P, c->ptapwork)); 1489566063dSJacob Faibussowitsch PetscCall((*C->ops->transposematmultnumeric)(P, c->ptapwork, C)); 1494222ddf1SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)C), PETSC_ERR_SUP, "Must call MatPtAPSymbolic_SeqDense_SeqDense() first"); 150abc3b08eSStefano Zampini PetscFunctionReturn(0); 151abc3b08eSStefano Zampini } 152abc3b08eSStefano Zampini 1539371c9d4SSatish Balay PetscErrorCode MatPtAPSymbolic_SeqDense_SeqDense(Mat A, Mat P, PetscReal fill, Mat C) { 154abc3b08eSStefano Zampini Mat_SeqDense *c; 1557a3c3d58SStefano Zampini PetscBool cisdense; 156abc3b08eSStefano Zampini 157abc3b08eSStefano Zampini PetscFunctionBegin; 1589566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, P->cmap->n, P->cmap->n, P->cmap->N, P->cmap->N)); 1599566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 1607a3c3d58SStefano Zampini if (!cisdense) { 1617a3c3d58SStefano Zampini PetscBool flg; 1627a3c3d58SStefano Zampini 1639566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)P, ((PetscObject)A)->type_name, &flg)); 1649566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 1657a3c3d58SStefano Zampini } 1669566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 1674222ddf1SHong Zhang c = (Mat_SeqDense *)C->data; 1689566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &c->ptapwork)); 1699566063dSJacob Faibussowitsch PetscCall(MatSetSizes(c->ptapwork, A->rmap->n, P->cmap->n, A->rmap->N, P->cmap->N)); 1709566063dSJacob Faibussowitsch PetscCall(MatSetType(c->ptapwork, ((PetscObject)C)->type_name)); 1719566063dSJacob Faibussowitsch PetscCall(MatSetUp(c->ptapwork)); 172abc3b08eSStefano Zampini PetscFunctionReturn(0); 173abc3b08eSStefano Zampini } 174abc3b08eSStefano Zampini 1759371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) { 176a13144ffSStefano Zampini Mat B = NULL; 177b49cda9fSStefano Zampini Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data; 178b49cda9fSStefano Zampini Mat_SeqDense *b; 179b49cda9fSStefano Zampini PetscInt *ai = a->i, *aj = a->j, m = A->rmap->N, n = A->cmap->N, i; 1802e5835c6SStefano Zampini const MatScalar *av; 181a13144ffSStefano Zampini PetscBool isseqdense; 182b49cda9fSStefano Zampini 183b49cda9fSStefano Zampini PetscFunctionBegin; 184a13144ffSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 1859566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)*newmat, MATSEQDENSE, &isseqdense)); 18628b400f6SJacob Faibussowitsch PetscCheck(isseqdense, PetscObjectComm((PetscObject)*newmat), PETSC_ERR_USER, "Cannot reuse matrix of type %s", ((PetscObject)(*newmat))->type_name); 187a13144ffSStefano Zampini } 188a13144ffSStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 1899566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B)); 1909566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B, m, n, m, n)); 1919566063dSJacob Faibussowitsch PetscCall(MatSetType(B, MATSEQDENSE)); 1929566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(B, NULL)); 193b49cda9fSStefano Zampini b = (Mat_SeqDense *)(B->data); 194a13144ffSStefano Zampini } else { 195a13144ffSStefano Zampini b = (Mat_SeqDense *)((*newmat)->data); 1969566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(b->v, m * n)); 197a13144ffSStefano Zampini } 1989566063dSJacob Faibussowitsch PetscCall(MatSeqAIJGetArrayRead(A, &av)); 199b49cda9fSStefano Zampini for (i = 0; i < m; i++) { 200b49cda9fSStefano Zampini PetscInt j; 201b49cda9fSStefano Zampini for (j = 0; j < ai[1] - ai[0]; j++) { 202b49cda9fSStefano Zampini b->v[*aj * m + i] = *av; 203b49cda9fSStefano Zampini aj++; 204b49cda9fSStefano Zampini av++; 205b49cda9fSStefano Zampini } 206b49cda9fSStefano Zampini ai++; 207b49cda9fSStefano Zampini } 2089566063dSJacob Faibussowitsch PetscCall(MatSeqAIJRestoreArrayRead(A, &av)); 209b49cda9fSStefano Zampini 210511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 2119566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 2129566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 2139566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A, &B)); 214b49cda9fSStefano Zampini } else { 215a13144ffSStefano Zampini if (B) *newmat = B; 2169566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(*newmat, MAT_FINAL_ASSEMBLY)); 2179566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(*newmat, MAT_FINAL_ASSEMBLY)); 218b49cda9fSStefano Zampini } 219b49cda9fSStefano Zampini PetscFunctionReturn(0); 220b49cda9fSStefano Zampini } 221b49cda9fSStefano Zampini 2229371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatConvert_SeqDense_SeqAIJ(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) { 2236d4ec7b0SPierre Jolivet Mat B = NULL; 2246a63e612SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2259399e1b8SMatthew G. Knepley PetscInt i, j; 2269399e1b8SMatthew G. Knepley PetscInt *rows, *nnz; 2279399e1b8SMatthew G. Knepley MatScalar *aa = a->v, *vals; 2286a63e612SBarry Smith 2296a63e612SBarry Smith PetscFunctionBegin; 2309566063dSJacob Faibussowitsch PetscCall(PetscCalloc3(A->rmap->n, &rows, A->rmap->n, &nnz, A->rmap->n, &vals)); 2316d4ec7b0SPierre Jolivet if (reuse != MAT_REUSE_MATRIX) { 2329566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B)); 2339566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B, A->rmap->n, A->cmap->n, A->rmap->N, A->cmap->N)); 2349566063dSJacob Faibussowitsch PetscCall(MatSetType(B, MATSEQAIJ)); 2359399e1b8SMatthew G. Knepley for (j = 0; j < A->cmap->n; j++) { 2369371c9d4SSatish Balay for (i = 0; i < A->rmap->n; i++) 2379371c9d4SSatish Balay if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) ++nnz[i]; 2386a63e612SBarry Smith aa += a->lda; 2396a63e612SBarry Smith } 2409566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(B, PETSC_DETERMINE, nnz)); 2416d4ec7b0SPierre Jolivet } else B = *newmat; 2429399e1b8SMatthew G. Knepley aa = a->v; 2439399e1b8SMatthew G. Knepley for (j = 0; j < A->cmap->n; j++) { 2449399e1b8SMatthew G. Knepley PetscInt numRows = 0; 2459371c9d4SSatish Balay for (i = 0; i < A->rmap->n; i++) 2469371c9d4SSatish Balay if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) { 2479371c9d4SSatish Balay rows[numRows] = i; 2489371c9d4SSatish Balay vals[numRows++] = aa[i]; 2499371c9d4SSatish Balay } 2509566063dSJacob Faibussowitsch PetscCall(MatSetValues(B, numRows, rows, 1, &j, vals, INSERT_VALUES)); 2519399e1b8SMatthew G. Knepley aa += a->lda; 2529399e1b8SMatthew G. Knepley } 2539566063dSJacob Faibussowitsch PetscCall(PetscFree3(rows, nnz, vals)); 2549566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 2559566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 2566a63e612SBarry Smith 257511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 2589566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A, &B)); 2596d4ec7b0SPierre Jolivet } else if (reuse != MAT_REUSE_MATRIX) *newmat = B; 2606a63e612SBarry Smith PetscFunctionReturn(0); 2616a63e612SBarry Smith } 2626a63e612SBarry Smith 2639371c9d4SSatish Balay PetscErrorCode MatAXPY_SeqDense(Mat Y, PetscScalar alpha, Mat X, MatStructure str) { 2641987afe7SBarry Smith Mat_SeqDense *x = (Mat_SeqDense *)X->data, *y = (Mat_SeqDense *)Y->data; 265ca15aa20SStefano Zampini const PetscScalar *xv; 266ca15aa20SStefano Zampini PetscScalar *yv; 26723fff9afSBarry Smith PetscBLASInt N, m, ldax = 0, lday = 0, one = 1; 2683a40ed3dSBarry Smith 2693a40ed3dSBarry Smith PetscFunctionBegin; 2709566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(X, &xv)); 2719566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(Y, &yv)); 2729566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(X->rmap->n * X->cmap->n, &N)); 2739566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(X->rmap->n, &m)); 2749566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(x->lda, &ldax)); 2759566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(y->lda, &lday)); 276a5ce6ee0Svictorle if (ldax > m || lday > m) { 277ca15aa20SStefano Zampini PetscInt j; 278ca15aa20SStefano Zampini 27948a46eb9SPierre Jolivet for (j = 0; j < X->cmap->n; j++) PetscCallBLAS("BLASaxpy", BLASaxpy_(&m, &alpha, xv + j * ldax, &one, yv + j * lday, &one)); 280a5ce6ee0Svictorle } else { 281792fecdfSBarry Smith PetscCallBLAS("BLASaxpy", BLASaxpy_(&N, &alpha, xv, &one, yv, &one)); 282a5ce6ee0Svictorle } 2839566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(X, &xv)); 2849566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(Y, &yv)); 2859566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(PetscMax(2.0 * N - 1, 0))); 2863a40ed3dSBarry Smith PetscFunctionReturn(0); 2871987afe7SBarry Smith } 2881987afe7SBarry Smith 2899371c9d4SSatish Balay static PetscErrorCode MatGetInfo_SeqDense(Mat A, MatInfoType flag, MatInfo *info) { 290ca15aa20SStefano Zampini PetscLogDouble N = A->rmap->n * A->cmap->n; 2913a40ed3dSBarry Smith 2923a40ed3dSBarry Smith PetscFunctionBegin; 2934e220ebcSLois Curfman McInnes info->block_size = 1.0; 294ca15aa20SStefano Zampini info->nz_allocated = N; 295ca15aa20SStefano Zampini info->nz_used = N; 296ca15aa20SStefano Zampini info->nz_unneeded = 0; 297ca15aa20SStefano Zampini info->assemblies = A->num_ass; 2984e220ebcSLois Curfman McInnes info->mallocs = 0; 2997adad957SLisandro Dalcin info->memory = ((PetscObject)A)->mem; 3004e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 3014e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 3024e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 3033a40ed3dSBarry Smith PetscFunctionReturn(0); 304289bc588SBarry Smith } 305289bc588SBarry Smith 3069371c9d4SSatish Balay PetscErrorCode MatScale_SeqDense(Mat A, PetscScalar alpha) { 307273d9f13SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 308ca15aa20SStefano Zampini PetscScalar *v; 30923fff9afSBarry Smith PetscBLASInt one = 1, j, nz, lda = 0; 31080cd9d93SLois Curfman McInnes 3113a40ed3dSBarry Smith PetscFunctionBegin; 3129566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 3139566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(a->lda, &lda)); 314d0f46423SBarry Smith if (lda > A->rmap->n) { 3159566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &nz)); 31648a46eb9SPierre Jolivet for (j = 0; j < A->cmap->n; j++) PetscCallBLAS("BLASscal", BLASscal_(&nz, &alpha, v + j * lda, &one)); 317a5ce6ee0Svictorle } else { 3189566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n * A->cmap->n, &nz)); 319792fecdfSBarry Smith PetscCallBLAS("BLASscal", BLASscal_(&nz, &alpha, v, &one)); 320a5ce6ee0Svictorle } 32104cbc005SJose E. Roman PetscCall(PetscLogFlops(A->rmap->n * A->cmap->n)); 3229566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 3233a40ed3dSBarry Smith PetscFunctionReturn(0); 32480cd9d93SLois Curfman McInnes } 32580cd9d93SLois Curfman McInnes 3269371c9d4SSatish Balay PetscErrorCode MatShift_SeqDense(Mat A, PetscScalar alpha) { 3272f605a99SJose E. Roman Mat_SeqDense *a = (Mat_SeqDense *)A->data; 3282f605a99SJose E. Roman PetscScalar *v; 3292f605a99SJose E. Roman PetscInt j, k; 3302f605a99SJose E. Roman 3312f605a99SJose E. Roman PetscFunctionBegin; 3322f605a99SJose E. Roman PetscCall(MatDenseGetArray(A, &v)); 3332f605a99SJose E. Roman k = PetscMin(A->rmap->n, A->cmap->n); 3342f605a99SJose E. Roman for (j = 0; j < k; j++) v[j + j * a->lda] += alpha; 3352f605a99SJose E. Roman PetscCall(PetscLogFlops(k)); 3362f605a99SJose E. Roman PetscCall(MatDenseRestoreArray(A, &v)); 3372f605a99SJose E. Roman PetscFunctionReturn(0); 3382f605a99SJose E. Roman } 3392f605a99SJose E. Roman 3409371c9d4SSatish Balay static PetscErrorCode MatIsHermitian_SeqDense(Mat A, PetscReal rtol, PetscBool *fl) { 3411cbb95d3SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 342ca15aa20SStefano Zampini PetscInt i, j, m = A->rmap->n, N = a->lda; 343ca15aa20SStefano Zampini const PetscScalar *v; 3441cbb95d3SBarry Smith 3451cbb95d3SBarry Smith PetscFunctionBegin; 3461cbb95d3SBarry Smith *fl = PETSC_FALSE; 347d0f46423SBarry Smith if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0); 3489566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 3491cbb95d3SBarry Smith for (i = 0; i < m; i++) { 350ca15aa20SStefano Zampini for (j = i; j < m; j++) { 351ad540459SPierre Jolivet if (PetscAbsScalar(v[i + j * N] - PetscConj(v[j + i * N])) > rtol) goto restore; 3521cbb95d3SBarry Smith } 353637a0070SStefano Zampini } 3541cbb95d3SBarry Smith *fl = PETSC_TRUE; 355637a0070SStefano Zampini restore: 3569566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 357637a0070SStefano Zampini PetscFunctionReturn(0); 358637a0070SStefano Zampini } 359637a0070SStefano Zampini 3609371c9d4SSatish Balay static PetscErrorCode MatIsSymmetric_SeqDense(Mat A, PetscReal rtol, PetscBool *fl) { 361637a0070SStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 362637a0070SStefano Zampini PetscInt i, j, m = A->rmap->n, N = a->lda; 363637a0070SStefano Zampini const PetscScalar *v; 364637a0070SStefano Zampini 365637a0070SStefano Zampini PetscFunctionBegin; 366637a0070SStefano Zampini *fl = PETSC_FALSE; 367637a0070SStefano Zampini if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0); 3689566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 369637a0070SStefano Zampini for (i = 0; i < m; i++) { 370637a0070SStefano Zampini for (j = i; j < m; j++) { 371ad540459SPierre Jolivet if (PetscAbsScalar(v[i + j * N] - v[j + i * N]) > rtol) goto restore; 372637a0070SStefano Zampini } 373637a0070SStefano Zampini } 374637a0070SStefano Zampini *fl = PETSC_TRUE; 375637a0070SStefano Zampini restore: 3769566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 3771cbb95d3SBarry Smith PetscFunctionReturn(0); 3781cbb95d3SBarry Smith } 3791cbb95d3SBarry Smith 3809371c9d4SSatish Balay PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi, Mat A, MatDuplicateOption cpvalues) { 381ca15aa20SStefano Zampini Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 38223fc5dcaSStefano Zampini PetscInt lda = (PetscInt)mat->lda, j, m, nlda = lda; 38375f6d85dSStefano Zampini PetscBool isdensecpu; 384b24902e0SBarry Smith 385b24902e0SBarry Smith PetscFunctionBegin; 3869566063dSJacob Faibussowitsch PetscCall(PetscLayoutReference(A->rmap, &newi->rmap)); 3879566063dSJacob Faibussowitsch PetscCall(PetscLayoutReference(A->cmap, &newi->cmap)); 38823fc5dcaSStefano Zampini if (cpvalues == MAT_SHARE_NONZERO_PATTERN) { /* propagate LDA */ 3899566063dSJacob Faibussowitsch PetscCall(MatDenseSetLDA(newi, lda)); 39023fc5dcaSStefano Zampini } 3919566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)newi, MATSEQDENSE, &isdensecpu)); 3929566063dSJacob Faibussowitsch if (isdensecpu) PetscCall(MatSeqDenseSetPreallocation(newi, NULL)); 393b24902e0SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 394ca15aa20SStefano Zampini const PetscScalar *av; 395ca15aa20SStefano Zampini PetscScalar *v; 396ca15aa20SStefano Zampini 3979566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 3989566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(newi, &v)); 3999566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(newi, &nlda)); 400d0f46423SBarry Smith m = A->rmap->n; 40123fc5dcaSStefano Zampini if (lda > m || nlda > m) { 40248a46eb9SPierre Jolivet for (j = 0; j < A->cmap->n; j++) PetscCall(PetscArraycpy(v + j * nlda, av + j * lda, m)); 403b24902e0SBarry Smith } else { 4049566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(v, av, A->rmap->n * A->cmap->n)); 405b24902e0SBarry Smith } 4069566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(newi, &v)); 4079566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 408b24902e0SBarry Smith } 409b24902e0SBarry Smith PetscFunctionReturn(0); 410b24902e0SBarry Smith } 411b24902e0SBarry Smith 4129371c9d4SSatish Balay PetscErrorCode MatDuplicate_SeqDense(Mat A, MatDuplicateOption cpvalues, Mat *newmat) { 4133a40ed3dSBarry Smith PetscFunctionBegin; 4149566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), newmat)); 4159566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*newmat, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n)); 4169566063dSJacob Faibussowitsch PetscCall(MatSetType(*newmat, ((PetscObject)A)->type_name)); 4179566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(*newmat, A, cpvalues)); 418b24902e0SBarry Smith PetscFunctionReturn(0); 419b24902e0SBarry Smith } 420b24902e0SBarry Smith 4219371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_Internal_LU(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T) { 422c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4234396437dSToby Isaac PetscBLASInt info; 42467e560aaSBarry Smith 4253a40ed3dSBarry Smith PetscFunctionBegin; 4269566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 427792fecdfSBarry Smith PetscCallBLAS("LAPACKgetrs", LAPACKgetrs_(T ? "T" : "N", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info)); 4289566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 42905fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "GETRS - Bad solve %d", (int)info); 4309566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m))); 4314396437dSToby Isaac PetscFunctionReturn(0); 4324396437dSToby Isaac } 4334396437dSToby Isaac 4344396437dSToby Isaac static PetscErrorCode MatConjugate_SeqDense(Mat); 4354396437dSToby Isaac 4369371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_Internal_Cholesky(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T) { 4374396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4384396437dSToby Isaac PetscBLASInt info; 4394396437dSToby Isaac 4404396437dSToby Isaac PetscFunctionBegin; 441b94d7dedSBarry Smith if (A->spd == PETSC_BOOL3_TRUE) { 4429566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A)); 4439566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 444792fecdfSBarry Smith PetscCallBLAS("LAPACKpotrs", LAPACKpotrs_("L", &m, &nrhs, mat->v, &mat->lda, x, &m, &info)); 4459566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 44605fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "POTRS Bad solve %d", (int)info); 4479566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A)); 448a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX) 449b94d7dedSBarry Smith } else if (A->hermitian == PETSC_BOOL3_TRUE) { 4509566063dSJacob Faibussowitsch if (T) PetscCall(MatConjugate_SeqDense(A)); 4519566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 452792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrs", LAPACKhetrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info)); 4539566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 45405fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "HETRS Bad solve %d", (int)info); 4559566063dSJacob Faibussowitsch if (T) PetscCall(MatConjugate_SeqDense(A)); 456a49dc2a2SStefano Zampini #endif 457a49dc2a2SStefano Zampini } else { /* symmetric case */ 4589566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 459792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrs", LAPACKsytrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info)); 4609566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 46105fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "SYTRS Bad solve %d", (int)info); 462a49dc2a2SStefano Zampini } 4639566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m))); 4644396437dSToby Isaac PetscFunctionReturn(0); 4654396437dSToby Isaac } 46685e2c93fSHong Zhang 4679371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k) { 4684396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4694396437dSToby Isaac PetscBLASInt info; 4704396437dSToby Isaac char trans; 4714396437dSToby Isaac 4724396437dSToby Isaac PetscFunctionBegin; 4734905a7bcSToby Isaac if (PetscDefined(USE_COMPLEX)) { 4744905a7bcSToby Isaac trans = 'C'; 4754905a7bcSToby Isaac } else { 4764905a7bcSToby Isaac trans = 'T'; 4774905a7bcSToby Isaac } 4789566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 47905fcb23eSStefano Zampini { /* lwork depends on the number of right-hand sides */ 48005fcb23eSStefano Zampini PetscBLASInt nlfwork, lfwork = -1; 48105fcb23eSStefano Zampini PetscScalar fwork; 48205fcb23eSStefano Zampini 483792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info)); 48405fcb23eSStefano Zampini nlfwork = (PetscBLASInt)PetscRealPart(fwork); 48505fcb23eSStefano Zampini if (nlfwork > mat->lfwork) { 48605fcb23eSStefano Zampini mat->lfwork = nlfwork; 48705fcb23eSStefano Zampini PetscCall(PetscFree(mat->fwork)); 48805fcb23eSStefano Zampini PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 48905fcb23eSStefano Zampini } 49005fcb23eSStefano Zampini } 491792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info)); 4929566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 49305fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %d", (int)info); 4949566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 495792fecdfSBarry Smith PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "N", "N", &mat->rank, &nrhs, mat->v, &mat->lda, x, &ldx, &info)); 4969566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 49705fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %d", (int)info); 4984905a7bcSToby Isaac for (PetscInt j = 0; j < nrhs; j++) { 499ad540459SPierre Jolivet for (PetscInt i = mat->rank; i < k; i++) x[j * ldx + i] = 0.; 5004905a7bcSToby Isaac } 5019566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank)))); 5024905a7bcSToby Isaac PetscFunctionReturn(0); 5034905a7bcSToby Isaac } 5044905a7bcSToby Isaac 5059371c9d4SSatish Balay static PetscErrorCode MatSolveTranspose_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k) { 5064396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 5074396437dSToby Isaac PetscBLASInt info; 5084396437dSToby Isaac 5094396437dSToby Isaac PetscFunctionBegin; 5104396437dSToby Isaac if (A->rmap->n == A->cmap->n && mat->rank == A->rmap->n) { 5119566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 512792fecdfSBarry Smith PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "T", "N", &m, &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); 5159566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A)); 51605fcb23eSStefano Zampini { /* lwork depends on the number of right-hand sides */ 51705fcb23eSStefano Zampini PetscBLASInt nlfwork, lfwork = -1; 51805fcb23eSStefano Zampini PetscScalar fwork; 51905fcb23eSStefano Zampini 520792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info)); 52105fcb23eSStefano Zampini nlfwork = (PetscBLASInt)PetscRealPart(fwork); 52205fcb23eSStefano Zampini if (nlfwork > mat->lfwork) { 52305fcb23eSStefano Zampini mat->lfwork = nlfwork; 52405fcb23eSStefano Zampini PetscCall(PetscFree(mat->fwork)); 52505fcb23eSStefano Zampini PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 52605fcb23eSStefano Zampini } 52705fcb23eSStefano Zampini } 5289566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 529792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info)); 5309566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 53105fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %d", (int)info); 5329566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A)); 5334396437dSToby Isaac } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "QR factored matrix cannot be used for transpose solve"); 5349566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank)))); 5354396437dSToby Isaac PetscFunctionReturn(0); 5364396437dSToby Isaac } 5374396437dSToby Isaac 5389371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_SetUp(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k) { 5394396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 5404905a7bcSToby Isaac PetscScalar *y; 5414905a7bcSToby Isaac PetscBLASInt m = 0, k = 0; 5424905a7bcSToby Isaac 5434905a7bcSToby Isaac PetscFunctionBegin; 5449566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 5459566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 5464905a7bcSToby Isaac if (k < m) { 5479566063dSJacob Faibussowitsch PetscCall(VecCopy(xx, mat->qrrhs)); 5489566063dSJacob Faibussowitsch PetscCall(VecGetArray(mat->qrrhs, &y)); 5494905a7bcSToby Isaac } else { 5509566063dSJacob Faibussowitsch PetscCall(VecCopy(xx, yy)); 5519566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &y)); 5524905a7bcSToby Isaac } 5534396437dSToby Isaac *_y = y; 5544396437dSToby Isaac *_k = k; 5554396437dSToby Isaac *_m = m; 5564396437dSToby Isaac PetscFunctionReturn(0); 5574396437dSToby Isaac } 5584396437dSToby Isaac 5599371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_TearDown(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k) { 5604396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 56142e9364cSSatish Balay PetscScalar *y = NULL; 5624396437dSToby Isaac PetscBLASInt m, k; 5634396437dSToby Isaac 5644396437dSToby Isaac PetscFunctionBegin; 5654396437dSToby Isaac y = *_y; 5664396437dSToby Isaac *_y = NULL; 5674396437dSToby Isaac k = *_k; 5684396437dSToby Isaac m = *_m; 5694905a7bcSToby Isaac if (k < m) { 5704905a7bcSToby Isaac PetscScalar *yv; 5719566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &yv)); 5729566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(yv, y, k)); 5739566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &yv)); 5749566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(mat->qrrhs, &y)); 5754905a7bcSToby Isaac } else { 5769566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &y)); 5774905a7bcSToby Isaac } 5784905a7bcSToby Isaac PetscFunctionReturn(0); 5794905a7bcSToby Isaac } 5804905a7bcSToby Isaac 5819371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_LU(Mat A, Vec xx, Vec yy) { 58242e9364cSSatish Balay PetscScalar *y = NULL; 58342e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 5844396437dSToby Isaac 5854396437dSToby Isaac PetscFunctionBegin; 5869566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 5879566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_FALSE)); 5889566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 5894396437dSToby Isaac PetscFunctionReturn(0); 5904396437dSToby Isaac } 5914396437dSToby Isaac 5929371c9d4SSatish Balay static PetscErrorCode MatSolveTranspose_SeqDense_LU(Mat A, Vec xx, Vec yy) { 59342e9364cSSatish Balay PetscScalar *y = NULL; 59442e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 5954396437dSToby Isaac 5964396437dSToby Isaac PetscFunctionBegin; 5979566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 5989566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_TRUE)); 5999566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6004396437dSToby Isaac PetscFunctionReturn(0); 6014396437dSToby Isaac } 6024396437dSToby Isaac 6039371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_Cholesky(Mat A, Vec xx, Vec yy) { 604e54beecaSStefano Zampini PetscScalar *y = NULL; 605e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 6064396437dSToby Isaac 6074396437dSToby Isaac PetscFunctionBegin; 6089566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6099566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_FALSE)); 6109566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6114396437dSToby Isaac PetscFunctionReturn(0); 6124396437dSToby Isaac } 6134396437dSToby Isaac 6149371c9d4SSatish Balay static PetscErrorCode MatSolveTranspose_SeqDense_Cholesky(Mat A, Vec xx, Vec yy) { 615e54beecaSStefano Zampini PetscScalar *y = NULL; 616e54beecaSStefano Zampini 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_Cholesky(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 6259371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_QR(Mat A, Vec xx, Vec yy) { 626e54beecaSStefano Zampini PetscScalar *y = NULL; 627e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 6284396437dSToby Isaac 6294396437dSToby Isaac PetscFunctionBegin; 6309566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6319566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k)); 6329566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6334396437dSToby Isaac PetscFunctionReturn(0); 6344396437dSToby Isaac } 6354396437dSToby Isaac 6369371c9d4SSatish Balay static PetscErrorCode MatSolveTranspose_SeqDense_QR(Mat A, Vec xx, Vec yy) { 63742e9364cSSatish Balay PetscScalar *y = NULL; 63842e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 6394396437dSToby Isaac 6404396437dSToby Isaac PetscFunctionBegin; 6419566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6429566063dSJacob Faibussowitsch PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k)); 6439566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6444396437dSToby Isaac PetscFunctionReturn(0); 6454396437dSToby Isaac } 6464396437dSToby Isaac 6479371c9d4SSatish Balay static PetscErrorCode MatMatSolve_SeqDense_SetUp(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k) { 6484905a7bcSToby Isaac const PetscScalar *b; 6494396437dSToby Isaac PetscScalar *y; 650bf5a80bcSToby Isaac PetscInt n, _ldb, _ldx; 651bf5a80bcSToby Isaac PetscBLASInt nrhs = 0, m = 0, k = 0, ldb = 0, ldx = 0, ldy = 0; 6524905a7bcSToby Isaac 6534905a7bcSToby Isaac PetscFunctionBegin; 6549371c9d4SSatish Balay *_ldy = 0; 6559371c9d4SSatish Balay *_m = 0; 6569371c9d4SSatish Balay *_nrhs = 0; 6579371c9d4SSatish Balay *_k = 0; 6589371c9d4SSatish Balay *_y = NULL; 6599566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 6609566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 6619566063dSJacob Faibussowitsch PetscCall(MatGetSize(B, NULL, &n)); 6629566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(n, &nrhs)); 6639566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(B, &_ldb)); 6649566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldb, &ldb)); 6659566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(X, &_ldx)); 6669566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldx, &ldx)); 667bf5a80bcSToby Isaac if (ldx < m) { 6689566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &b)); 6699566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nrhs * m, &y)); 670bf5a80bcSToby Isaac if (ldb == m) { 6719566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(y, b, ldb * nrhs)); 6724905a7bcSToby Isaac } else { 67348a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * m], &b[j * ldb], m)); 6744905a7bcSToby Isaac } 675bf5a80bcSToby Isaac ldy = m; 6769566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &b)); 6774905a7bcSToby Isaac } else { 678bf5a80bcSToby Isaac if (ldb == ldx) { 6799566063dSJacob Faibussowitsch PetscCall(MatCopy(B, X, SAME_NONZERO_PATTERN)); 6809566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &y)); 6814905a7bcSToby Isaac } else { 6829566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &y)); 6839566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &b)); 68448a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * ldx], &b[j * ldb], m)); 6859566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &b)); 6864905a7bcSToby Isaac } 687bf5a80bcSToby Isaac ldy = ldx; 6884905a7bcSToby Isaac } 6894396437dSToby Isaac *_y = y; 690bf5a80bcSToby Isaac *_ldy = ldy; 6914396437dSToby Isaac *_k = k; 6924396437dSToby Isaac *_m = m; 6934396437dSToby Isaac *_nrhs = nrhs; 6944396437dSToby Isaac PetscFunctionReturn(0); 6954396437dSToby Isaac } 6964396437dSToby Isaac 6979371c9d4SSatish Balay static PetscErrorCode MatMatSolve_SeqDense_TearDown(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k) { 6984396437dSToby Isaac PetscScalar *y; 699bf5a80bcSToby Isaac PetscInt _ldx; 700bf5a80bcSToby Isaac PetscBLASInt k, ldy, nrhs, ldx = 0; 7014396437dSToby Isaac 7024396437dSToby Isaac PetscFunctionBegin; 7034396437dSToby Isaac y = *_y; 7044396437dSToby Isaac *_y = NULL; 7054396437dSToby Isaac k = *_k; 706bf5a80bcSToby Isaac ldy = *_ldy; 7074396437dSToby Isaac nrhs = *_nrhs; 7089566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(X, &_ldx)); 7099566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldx, &ldx)); 710bf5a80bcSToby Isaac if (ldx != ldy) { 7114905a7bcSToby Isaac PetscScalar *xv; 7129566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &xv)); 71348a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&xv[j * ldx], &y[j * ldy], k)); 7149566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(X, &xv)); 7159566063dSJacob Faibussowitsch PetscCall(PetscFree(y)); 7164905a7bcSToby Isaac } else { 7179566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(X, &y)); 7184905a7bcSToby Isaac } 71985e2c93fSHong Zhang PetscFunctionReturn(0); 72085e2c93fSHong Zhang } 72185e2c93fSHong Zhang 7229371c9d4SSatish Balay static PetscErrorCode MatMatSolve_SeqDense_LU(Mat A, Mat B, Mat X) { 7234396437dSToby Isaac PetscScalar *y; 724bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7254396437dSToby Isaac 7264396437dSToby Isaac PetscFunctionBegin; 7279566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7289566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_FALSE)); 7299566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7304396437dSToby Isaac PetscFunctionReturn(0); 7314396437dSToby Isaac } 7324396437dSToby Isaac 7339371c9d4SSatish Balay static PetscErrorCode MatMatSolveTranspose_SeqDense_LU(Mat A, Mat B, Mat X) { 7344396437dSToby Isaac PetscScalar *y; 735bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7364396437dSToby Isaac 7374396437dSToby Isaac PetscFunctionBegin; 7389566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7399566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_TRUE)); 7409566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7414396437dSToby Isaac PetscFunctionReturn(0); 7424396437dSToby Isaac } 7434396437dSToby Isaac 7449371c9d4SSatish Balay static PetscErrorCode MatMatSolve_SeqDense_Cholesky(Mat A, Mat B, Mat X) { 7454396437dSToby Isaac PetscScalar *y; 746bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7474396437dSToby Isaac 7484396437dSToby Isaac PetscFunctionBegin; 7499566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7509566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_FALSE)); 7519566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7524396437dSToby Isaac PetscFunctionReturn(0); 7534396437dSToby Isaac } 7544396437dSToby Isaac 7559371c9d4SSatish Balay static PetscErrorCode MatMatSolveTranspose_SeqDense_Cholesky(Mat A, Mat B, Mat X) { 7564396437dSToby Isaac PetscScalar *y; 757bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7584396437dSToby Isaac 7594396437dSToby Isaac PetscFunctionBegin; 7609566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7619566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_TRUE)); 7629566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7634396437dSToby Isaac PetscFunctionReturn(0); 7644396437dSToby Isaac } 7654396437dSToby Isaac 7669371c9d4SSatish Balay static PetscErrorCode MatMatSolve_SeqDense_QR(Mat A, Mat B, Mat X) { 7674396437dSToby Isaac PetscScalar *y; 768bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7694396437dSToby Isaac 7704396437dSToby Isaac PetscFunctionBegin; 7719566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7729566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k)); 7739566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7744396437dSToby Isaac PetscFunctionReturn(0); 7754396437dSToby Isaac } 7764396437dSToby Isaac 7779371c9d4SSatish Balay static PetscErrorCode MatMatSolveTranspose_SeqDense_QR(Mat A, Mat B, Mat X) { 7784396437dSToby Isaac PetscScalar *y; 779bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7804396437dSToby Isaac 7814396437dSToby Isaac PetscFunctionBegin; 7829566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7839566063dSJacob Faibussowitsch PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k)); 7849566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7854396437dSToby Isaac PetscFunctionReturn(0); 7864396437dSToby Isaac } 7874396437dSToby Isaac 788db4efbfdSBarry Smith /* ---------------------------------------------------------------*/ 789db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots, 790db4efbfdSBarry Smith rather than put it in the Mat->row slot.*/ 7919371c9d4SSatish Balay PetscErrorCode MatLUFactor_SeqDense(Mat A, IS row, IS col, const MatFactorInfo *minfo) { 792db4efbfdSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 793db4efbfdSBarry Smith PetscBLASInt n, m, info; 794db4efbfdSBarry Smith 795db4efbfdSBarry Smith PetscFunctionBegin; 7969566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 7979566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 798db4efbfdSBarry Smith if (!mat->pivots) { 7999566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); 8009566063dSJacob Faibussowitsch PetscCall(PetscLogObjectMemory((PetscObject)A, A->rmap->n * sizeof(PetscBLASInt))); 801db4efbfdSBarry Smith } 802db4efbfdSBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 8039566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 804792fecdfSBarry Smith PetscCallBLAS("LAPACKgetrf", LAPACKgetrf_(&m, &n, mat->v, &mat->lda, mat->pivots, &info)); 8059566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 8068e57ea43SSatish Balay 80705fcb23eSStefano Zampini PetscCheck(info >= 0, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to LU factorization %d", (int)info); 80805fcb23eSStefano Zampini PetscCheck(info <= 0, PETSC_COMM_SELF, PETSC_ERR_MAT_LU_ZRPVT, "Bad LU factorization %d", (int)info); 8098208b9aeSStefano Zampini 8104396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_LU; 8114396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_LU; 8124396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_LU; 8134396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_LU; 814d5f3da31SBarry Smith A->factortype = MAT_FACTOR_LU; 815db4efbfdSBarry Smith 8169566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 8179566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 818f6224b95SHong Zhang 8199566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((2.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3)); 820db4efbfdSBarry Smith PetscFunctionReturn(0); 821db4efbfdSBarry Smith } 822db4efbfdSBarry Smith 8239371c9d4SSatish Balay static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) { 8244396437dSToby Isaac MatFactorInfo info; 8254396437dSToby Isaac 8264396437dSToby Isaac PetscFunctionBegin; 8279566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 828dbbe0bcdSBarry Smith PetscUseTypeMethod(fact, lufactor, NULL, NULL, &info); 8294396437dSToby Isaac PetscFunctionReturn(0); 8304396437dSToby Isaac } 8314396437dSToby Isaac 8329371c9d4SSatish Balay PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, IS col, const MatFactorInfo *info) { 8334396437dSToby Isaac PetscFunctionBegin; 8344396437dSToby Isaac fact->preallocated = PETSC_TRUE; 8354396437dSToby Isaac fact->assembled = PETSC_TRUE; 8364396437dSToby Isaac fact->ops->lufactornumeric = MatLUFactorNumeric_SeqDense; 8374396437dSToby Isaac PetscFunctionReturn(0); 8384396437dSToby Isaac } 8394396437dSToby Isaac 840a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */ 8419371c9d4SSatish Balay PetscErrorCode MatCholeskyFactor_SeqDense(Mat A, IS perm, const MatFactorInfo *factinfo) { 842db4efbfdSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 843c5df96a5SBarry Smith PetscBLASInt info, n; 844db4efbfdSBarry Smith 845db4efbfdSBarry Smith PetscFunctionBegin; 8469566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 847db4efbfdSBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 848b94d7dedSBarry Smith if (A->spd == PETSC_BOOL3_TRUE) { 8499566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 850792fecdfSBarry Smith PetscCallBLAS("LAPACKpotrf", LAPACKpotrf_("L", &n, mat->v, &mat->lda, &info)); 8519566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 852a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX) 853b94d7dedSBarry Smith } else if (A->hermitian == PETSC_BOOL3_TRUE) { 854a49dc2a2SStefano Zampini if (!mat->pivots) { 8559566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); 8569566063dSJacob Faibussowitsch PetscCall(PetscLogObjectMemory((PetscObject)A, A->rmap->n * sizeof(PetscBLASInt))); 857a49dc2a2SStefano Zampini } 858a49dc2a2SStefano Zampini if (!mat->fwork) { 859a49dc2a2SStefano Zampini PetscScalar dummy; 860a49dc2a2SStefano Zampini 861a49dc2a2SStefano Zampini mat->lfwork = -1; 8629566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 863792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info)); 8649566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 865a49dc2a2SStefano Zampini mat->lfwork = (PetscInt)PetscRealPart(dummy); 8669566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 8679566063dSJacob Faibussowitsch PetscCall(PetscLogObjectMemory((PetscObject)A, mat->lfwork * sizeof(PetscBLASInt))); 868a49dc2a2SStefano Zampini } 8699566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 870792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info)); 8719566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 872a49dc2a2SStefano Zampini #endif 873a49dc2a2SStefano Zampini } else { /* symmetric case */ 874a49dc2a2SStefano Zampini if (!mat->pivots) { 8759566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); 8769566063dSJacob Faibussowitsch PetscCall(PetscLogObjectMemory((PetscObject)A, A->rmap->n * sizeof(PetscBLASInt))); 877a49dc2a2SStefano Zampini } 878a49dc2a2SStefano Zampini if (!mat->fwork) { 879a49dc2a2SStefano Zampini PetscScalar dummy; 880a49dc2a2SStefano Zampini 881a49dc2a2SStefano Zampini mat->lfwork = -1; 8829566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 883792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info)); 8849566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 885a49dc2a2SStefano Zampini mat->lfwork = (PetscInt)PetscRealPart(dummy); 8869566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 8879566063dSJacob Faibussowitsch PetscCall(PetscLogObjectMemory((PetscObject)A, mat->lfwork * sizeof(PetscBLASInt))); 888a49dc2a2SStefano Zampini } 8899566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 890792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info)); 8919566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 892a49dc2a2SStefano Zampini } 89328b400f6SJacob Faibussowitsch PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad factorization: zero pivot in row %" PetscInt_FMT, (PetscInt)info - 1); 8948208b9aeSStefano Zampini 8954396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_Cholesky; 8964396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_Cholesky; 8974396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_Cholesky; 8984396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_Cholesky; 899d5f3da31SBarry Smith A->factortype = MAT_FACTOR_CHOLESKY; 9002205254eSKarl Rupp 9019566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 9029566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 903f6224b95SHong Zhang 9049566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0)); 905db4efbfdSBarry Smith PetscFunctionReturn(0); 906db4efbfdSBarry Smith } 907db4efbfdSBarry Smith 9089371c9d4SSatish Balay static PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) { 909db4efbfdSBarry Smith MatFactorInfo info; 910db4efbfdSBarry Smith 911db4efbfdSBarry Smith PetscFunctionBegin; 912db4efbfdSBarry Smith info.fill = 1.0; 9132205254eSKarl Rupp 9149566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 915dbbe0bcdSBarry Smith PetscUseTypeMethod(fact, choleskyfactor, NULL, &info); 916db4efbfdSBarry Smith PetscFunctionReturn(0); 917db4efbfdSBarry Smith } 918db4efbfdSBarry Smith 9199371c9d4SSatish Balay PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info) { 920db4efbfdSBarry Smith PetscFunctionBegin; 921c3ef05f6SHong Zhang fact->assembled = PETSC_TRUE; 9221bbcc794SSatish Balay fact->preallocated = PETSC_TRUE; 923719d5645SBarry Smith fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense; 924db4efbfdSBarry Smith PetscFunctionReturn(0); 925db4efbfdSBarry Smith } 926db4efbfdSBarry Smith 9279371c9d4SSatish Balay PetscErrorCode MatQRFactor_SeqDense(Mat A, IS col, const MatFactorInfo *minfo) { 9284905a7bcSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 9294905a7bcSToby Isaac PetscBLASInt n, m, info, min, max; 9304905a7bcSToby Isaac 9314905a7bcSToby Isaac PetscFunctionBegin; 9329566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 9339566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 9344396437dSToby Isaac max = PetscMax(m, n); 9354396437dSToby Isaac min = PetscMin(m, n); 9364905a7bcSToby Isaac if (!mat->tau) { 9379566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(min, &mat->tau)); 9389566063dSJacob Faibussowitsch PetscCall(PetscLogObjectMemory((PetscObject)A, min * sizeof(PetscScalar))); 9394396437dSToby Isaac } 9404396437dSToby Isaac if (!mat->pivots) { 9419566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n, &mat->pivots)); 9429566063dSJacob Faibussowitsch PetscCall(PetscLogObjectMemory((PetscObject)A, n * sizeof(PetscScalar))); 9434396437dSToby Isaac } 94448a46eb9SPierre Jolivet if (!mat->qrrhs) PetscCall(MatCreateVecs(A, NULL, &(mat->qrrhs))); 9454905a7bcSToby Isaac if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 9464905a7bcSToby Isaac if (!mat->fwork) { 9474905a7bcSToby Isaac PetscScalar dummy; 9484905a7bcSToby Isaac 9494905a7bcSToby Isaac mat->lfwork = -1; 9509566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 951792fecdfSBarry Smith PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, &dummy, &mat->lfwork, &info)); 9529566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 9534905a7bcSToby Isaac mat->lfwork = (PetscInt)PetscRealPart(dummy); 9549566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 9559566063dSJacob Faibussowitsch PetscCall(PetscLogObjectMemory((PetscObject)A, mat->lfwork * sizeof(PetscBLASInt))); 9564905a7bcSToby Isaac } 9579566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 958792fecdfSBarry Smith PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, mat->fwork, &mat->lfwork, &info)); 9599566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 96005fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to QR factorization %d", (int)info); 9614905a7bcSToby 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 9624905a7bcSToby Isaac mat->rank = min; 9634905a7bcSToby Isaac 9644396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_QR; 9654396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_QR; 9664905a7bcSToby Isaac A->factortype = MAT_FACTOR_QR; 9674905a7bcSToby Isaac if (m == n) { 9684396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_QR; 9694396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_QR; 9704905a7bcSToby Isaac } 9714905a7bcSToby Isaac 9729566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 9739566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 9744905a7bcSToby Isaac 9759566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * min * min * (max - min / 3.0))); 9764905a7bcSToby Isaac PetscFunctionReturn(0); 9774905a7bcSToby Isaac } 9784905a7bcSToby Isaac 9799371c9d4SSatish Balay static PetscErrorCode MatQRFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) { 9804905a7bcSToby Isaac MatFactorInfo info; 9814905a7bcSToby Isaac 9824905a7bcSToby Isaac PetscFunctionBegin; 9834905a7bcSToby Isaac info.fill = 1.0; 9844905a7bcSToby Isaac 9859566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 986cac4c232SBarry Smith PetscUseMethod(fact, "MatQRFactor_C", (Mat, IS, const MatFactorInfo *), (fact, NULL, &info)); 9874905a7bcSToby Isaac PetscFunctionReturn(0); 9884905a7bcSToby Isaac } 9894905a7bcSToby Isaac 9909371c9d4SSatish Balay PetscErrorCode MatQRFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info) { 9914905a7bcSToby Isaac PetscFunctionBegin; 9924905a7bcSToby Isaac fact->assembled = PETSC_TRUE; 9934905a7bcSToby Isaac fact->preallocated = PETSC_TRUE; 9949566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)fact, "MatQRFactorNumeric_C", MatQRFactorNumeric_SeqDense)); 9954905a7bcSToby Isaac PetscFunctionReturn(0); 9964905a7bcSToby Isaac } 9974905a7bcSToby Isaac 998ca15aa20SStefano Zampini /* uses LAPACK */ 9999371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A, MatFactorType ftype, Mat *fact) { 1000db4efbfdSBarry Smith PetscFunctionBegin; 10019566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), fact)); 10029566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*fact, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n)); 10039566063dSJacob Faibussowitsch PetscCall(MatSetType(*fact, MATDENSE)); 100466e17bc3SBarry Smith (*fact)->trivialsymbolic = PETSC_TRUE; 10052a350339SBarry Smith if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU) { 1006db4efbfdSBarry Smith (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense; 10072a350339SBarry Smith (*fact)->ops->ilufactorsymbolic = MatLUFactorSymbolic_SeqDense; 1008bf5a80bcSToby Isaac } else if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) { 1009db4efbfdSBarry Smith (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense; 1010bf5a80bcSToby Isaac } else if (ftype == MAT_FACTOR_QR) { 10119566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)(*fact), "MatQRFactorSymbolic_C", MatQRFactorSymbolic_SeqDense)); 1012db4efbfdSBarry Smith } 1013d5f3da31SBarry Smith (*fact)->factortype = ftype; 101400c67f3bSHong Zhang 10159566063dSJacob Faibussowitsch PetscCall(PetscFree((*fact)->solvertype)); 10169566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &(*fact)->solvertype)); 10179566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_LU])); 10189566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ILU])); 10199566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_CHOLESKY])); 10209566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ICC])); 1021db4efbfdSBarry Smith PetscFunctionReturn(0); 1022db4efbfdSBarry Smith } 1023db4efbfdSBarry Smith 1024289bc588SBarry Smith /* ------------------------------------------------------------------*/ 10259371c9d4SSatish Balay static PetscErrorCode MatSOR_SeqDense(Mat A, Vec bb, PetscReal omega, MatSORType flag, PetscReal shift, PetscInt its, PetscInt lits, Vec xx) { 1026c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1027d9ca1df4SBarry Smith PetscScalar *x, *v = mat->v, zero = 0.0, xt; 1028d9ca1df4SBarry Smith const PetscScalar *b; 1029d0f46423SBarry Smith PetscInt m = A->rmap->n, i; 103023fff9afSBarry Smith PetscBLASInt o = 1, bm = 0; 1031289bc588SBarry Smith 10323a40ed3dSBarry Smith PetscFunctionBegin; 1033ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA) 103408401ef6SPierre Jolivet PetscCheck(A->offloadmask != PETSC_OFFLOAD_GPU, PETSC_COMM_SELF, PETSC_ERR_SUP, "Not implemented"); 1035ca15aa20SStefano Zampini #endif 1036422a814eSBarry Smith if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */ 10379566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(m, &bm)); 1038289bc588SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 10393bffc371SBarry Smith /* this is a hack fix, should have another version without the second BLASdotu */ 10409566063dSJacob Faibussowitsch PetscCall(VecSet(xx, zero)); 1041289bc588SBarry Smith } 10429566063dSJacob Faibussowitsch PetscCall(VecGetArray(xx, &x)); 10439566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(bb, &b)); 1044b965ef7fSBarry Smith its = its * lits; 104508401ef6SPierre 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); 1046289bc588SBarry Smith while (its--) { 1047fccaa45eSBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 1048289bc588SBarry Smith for (i = 0; i < m; i++) { 1049792fecdfSBarry Smith PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o)); 105055a1b374SBarry Smith x[i] = (1. - omega) * x[i] + omega * (xt + v[i + i * m] * x[i]) / (v[i + i * m] + shift); 1051289bc588SBarry Smith } 1052289bc588SBarry Smith } 1053fccaa45eSBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 1054289bc588SBarry Smith for (i = m - 1; i >= 0; i--) { 1055792fecdfSBarry Smith PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o)); 105655a1b374SBarry Smith x[i] = (1. - omega) * x[i] + omega * (xt + v[i + i * m] * x[i]) / (v[i + i * m] + shift); 1057289bc588SBarry Smith } 1058289bc588SBarry Smith } 1059289bc588SBarry Smith } 10609566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(bb, &b)); 10619566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(xx, &x)); 10623a40ed3dSBarry Smith PetscFunctionReturn(0); 1063289bc588SBarry Smith } 1064289bc588SBarry Smith 1065289bc588SBarry Smith /* -----------------------------------------------------------------*/ 10669371c9d4SSatish Balay PetscErrorCode MatMultTranspose_SeqDense(Mat A, Vec xx, Vec yy) { 1067c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1068d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 1069d9ca1df4SBarry Smith PetscScalar *y; 10700805154bSBarry Smith PetscBLASInt m, n, _One = 1; 1071ea709b57SSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 10723a40ed3dSBarry Smith 10733a40ed3dSBarry Smith PetscFunctionBegin; 10749566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 10759566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 10769566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 10779566063dSJacob Faibussowitsch PetscCall(VecGetArrayWrite(yy, &y)); 10785ac36cfcSBarry Smith if (!A->rmap->n || !A->cmap->n) { 10795ac36cfcSBarry Smith PetscBLASInt i; 10805ac36cfcSBarry Smith for (i = 0; i < n; i++) y[i] = 0.0; 10815ac36cfcSBarry Smith } else { 1082792fecdfSBarry Smith PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v, &mat->lda, x, &_One, &_DZero, y, &_One)); 10839566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n - A->cmap->n)); 10845ac36cfcSBarry Smith } 10859566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 10869566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayWrite(yy, &y)); 10873a40ed3dSBarry Smith PetscFunctionReturn(0); 1088289bc588SBarry Smith } 1089800995b7SMatthew Knepley 10909371c9d4SSatish Balay PetscErrorCode MatMult_SeqDense(Mat A, Vec xx, Vec yy) { 1091c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1092d9ca1df4SBarry Smith PetscScalar *y, _DOne = 1.0, _DZero = 0.0; 10930805154bSBarry Smith PetscBLASInt m, n, _One = 1; 1094d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 10953a40ed3dSBarry Smith 10963a40ed3dSBarry Smith PetscFunctionBegin; 10979566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 10989566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 10999566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 11009566063dSJacob Faibussowitsch PetscCall(VecGetArrayWrite(yy, &y)); 11015ac36cfcSBarry Smith if (!A->rmap->n || !A->cmap->n) { 11025ac36cfcSBarry Smith PetscBLASInt i; 11035ac36cfcSBarry Smith for (i = 0; i < m; i++) y[i] = 0.0; 11045ac36cfcSBarry Smith } else { 1105792fecdfSBarry Smith PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DZero, y, &_One)); 11069566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n - A->rmap->n)); 11075ac36cfcSBarry Smith } 11089566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 11099566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayWrite(yy, &y)); 11103a40ed3dSBarry Smith PetscFunctionReturn(0); 1111289bc588SBarry Smith } 11126ee01492SSatish Balay 11139371c9d4SSatish Balay PetscErrorCode MatMultAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) { 1114c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1115d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 1116d9ca1df4SBarry Smith PetscScalar *y, _DOne = 1.0; 11170805154bSBarry Smith PetscBLASInt m, n, _One = 1; 11183a40ed3dSBarry Smith 11193a40ed3dSBarry Smith PetscFunctionBegin; 11209566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 11219566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 11229566063dSJacob Faibussowitsch PetscCall(VecCopy(zz, yy)); 1123d0f46423SBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 11249566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 11259566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &y)); 1126792fecdfSBarry Smith PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DOne, y, &_One)); 11279566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 11289566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &y)); 11299566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n)); 11303a40ed3dSBarry Smith PetscFunctionReturn(0); 1131289bc588SBarry Smith } 11326ee01492SSatish Balay 11339371c9d4SSatish Balay PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) { 1134c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1135d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 1136d9ca1df4SBarry Smith PetscScalar *y; 11370805154bSBarry Smith PetscBLASInt m, n, _One = 1; 113887828ca2SBarry Smith PetscScalar _DOne = 1.0; 11393a40ed3dSBarry Smith 11403a40ed3dSBarry Smith PetscFunctionBegin; 11419566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 11429566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 11439566063dSJacob Faibussowitsch PetscCall(VecCopy(zz, yy)); 1144d0f46423SBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 11459566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 11469566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &y)); 1147792fecdfSBarry Smith PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DOne, y, &_One)); 11489566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 11499566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &y)); 11509566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n)); 11513a40ed3dSBarry Smith PetscFunctionReturn(0); 1152289bc588SBarry Smith } 1153289bc588SBarry Smith 1154289bc588SBarry Smith /* -----------------------------------------------------------------*/ 11559371c9d4SSatish Balay static PetscErrorCode MatGetRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals) { 1156c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 115713f74950SBarry Smith PetscInt i; 115867e560aaSBarry Smith 11593a40ed3dSBarry Smith PetscFunctionBegin; 1160d0f46423SBarry Smith *ncols = A->cmap->n; 1161289bc588SBarry Smith if (cols) { 11629566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->cmap->n, cols)); 1163d0f46423SBarry Smith for (i = 0; i < A->cmap->n; i++) (*cols)[i] = i; 1164289bc588SBarry Smith } 1165289bc588SBarry Smith if (vals) { 1166ca15aa20SStefano Zampini const PetscScalar *v; 1167ca15aa20SStefano Zampini 11689566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 11699566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->cmap->n, vals)); 1170ca15aa20SStefano Zampini v += row; 11719371c9d4SSatish Balay for (i = 0; i < A->cmap->n; i++) { 11729371c9d4SSatish Balay (*vals)[i] = *v; 11739371c9d4SSatish Balay v += mat->lda; 11749371c9d4SSatish Balay } 11759566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 1176289bc588SBarry Smith } 11773a40ed3dSBarry Smith PetscFunctionReturn(0); 1178289bc588SBarry Smith } 11796ee01492SSatish Balay 11809371c9d4SSatish Balay static PetscErrorCode MatRestoreRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals) { 1181606d414cSSatish Balay PetscFunctionBegin; 1182cb4a9cd9SHong Zhang if (ncols) *ncols = 0; 11839566063dSJacob Faibussowitsch if (cols) PetscCall(PetscFree(*cols)); 11849566063dSJacob Faibussowitsch if (vals) PetscCall(PetscFree(*vals)); 11853a40ed3dSBarry Smith PetscFunctionReturn(0); 1186289bc588SBarry Smith } 1187289bc588SBarry Smith /* ----------------------------------------------------------------*/ 11889371c9d4SSatish Balay static PetscErrorCode MatSetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], const PetscScalar v[], InsertMode addv) { 1189c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1190ca15aa20SStefano Zampini PetscScalar *av; 119113f74950SBarry Smith PetscInt i, j, idx = 0; 1192ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA) 1193c70f7ee4SJunchao Zhang PetscOffloadMask oldf; 1194ca15aa20SStefano Zampini #endif 1195d6dfbf8fSBarry Smith 11963a40ed3dSBarry Smith PetscFunctionBegin; 11979566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &av)); 1198289bc588SBarry Smith if (!mat->roworiented) { 1199dbb450caSBarry Smith if (addv == INSERT_VALUES) { 1200289bc588SBarry Smith for (j = 0; j < n; j++) { 12019371c9d4SSatish Balay if (indexn[j] < 0) { 12029371c9d4SSatish Balay idx += m; 12039371c9d4SSatish Balay continue; 12049371c9d4SSatish Balay } 12056bdcaf15SBarry 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); 1206289bc588SBarry Smith for (i = 0; i < m; i++) { 12079371c9d4SSatish Balay if (indexm[i] < 0) { 12089371c9d4SSatish Balay idx++; 12099371c9d4SSatish Balay continue; 12109371c9d4SSatish Balay } 12116bdcaf15SBarry 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); 1212ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] = v[idx++]; 1213289bc588SBarry Smith } 1214289bc588SBarry Smith } 12153a40ed3dSBarry Smith } else { 1216289bc588SBarry Smith for (j = 0; j < n; j++) { 12179371c9d4SSatish Balay if (indexn[j] < 0) { 12189371c9d4SSatish Balay idx += m; 12199371c9d4SSatish Balay continue; 12209371c9d4SSatish Balay } 12216bdcaf15SBarry 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); 1222289bc588SBarry Smith for (i = 0; i < m; i++) { 12239371c9d4SSatish Balay if (indexm[i] < 0) { 12249371c9d4SSatish Balay idx++; 12259371c9d4SSatish Balay continue; 12269371c9d4SSatish Balay } 12276bdcaf15SBarry 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); 1228ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] += v[idx++]; 1229289bc588SBarry Smith } 1230289bc588SBarry Smith } 1231289bc588SBarry Smith } 12323a40ed3dSBarry Smith } else { 1233dbb450caSBarry Smith if (addv == INSERT_VALUES) { 1234e8d4e0b9SBarry Smith for (i = 0; i < m; i++) { 12359371c9d4SSatish Balay if (indexm[i] < 0) { 12369371c9d4SSatish Balay idx += n; 12379371c9d4SSatish Balay continue; 12389371c9d4SSatish Balay } 12396bdcaf15SBarry 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); 1240e8d4e0b9SBarry Smith for (j = 0; j < n; j++) { 12419371c9d4SSatish Balay if (indexn[j] < 0) { 12429371c9d4SSatish Balay idx++; 12439371c9d4SSatish Balay continue; 12449371c9d4SSatish Balay } 12456bdcaf15SBarry 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); 1246ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] = v[idx++]; 1247e8d4e0b9SBarry Smith } 1248e8d4e0b9SBarry Smith } 12493a40ed3dSBarry Smith } else { 1250289bc588SBarry Smith for (i = 0; i < m; i++) { 12519371c9d4SSatish Balay if (indexm[i] < 0) { 12529371c9d4SSatish Balay idx += n; 12539371c9d4SSatish Balay continue; 12549371c9d4SSatish Balay } 12556bdcaf15SBarry 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); 1256289bc588SBarry Smith for (j = 0; j < n; j++) { 12579371c9d4SSatish Balay if (indexn[j] < 0) { 12589371c9d4SSatish Balay idx++; 12599371c9d4SSatish Balay continue; 12609371c9d4SSatish Balay } 12616bdcaf15SBarry 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); 1262ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] += v[idx++]; 1263289bc588SBarry Smith } 1264289bc588SBarry Smith } 1265289bc588SBarry Smith } 1266e8d4e0b9SBarry Smith } 1267ca15aa20SStefano Zampini /* hack to prevent unneeded copy to the GPU while returning the array */ 1268ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA) 1269c70f7ee4SJunchao Zhang oldf = A->offloadmask; 1270c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_GPU; 1271ca15aa20SStefano Zampini #endif 12729566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &av)); 1273ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA) 1274c70f7ee4SJunchao Zhang A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU); 1275ca15aa20SStefano Zampini #endif 12763a40ed3dSBarry Smith PetscFunctionReturn(0); 1277289bc588SBarry Smith } 1278e8d4e0b9SBarry Smith 12799371c9d4SSatish Balay static PetscErrorCode MatGetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], PetscScalar v[]) { 1280ae80bb75SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1281ca15aa20SStefano Zampini const PetscScalar *vv; 128213f74950SBarry Smith PetscInt i, j; 1283ae80bb75SLois Curfman McInnes 12843a40ed3dSBarry Smith PetscFunctionBegin; 12859566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &vv)); 1286ae80bb75SLois Curfman McInnes /* row-oriented output */ 1287ae80bb75SLois Curfman McInnes for (i = 0; i < m; i++) { 12889371c9d4SSatish Balay if (indexm[i] < 0) { 12899371c9d4SSatish Balay v += n; 12909371c9d4SSatish Balay continue; 12919371c9d4SSatish Balay } 129208401ef6SPierre 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); 1293ae80bb75SLois Curfman McInnes for (j = 0; j < n; j++) { 12949371c9d4SSatish Balay if (indexn[j] < 0) { 12959371c9d4SSatish Balay v++; 12969371c9d4SSatish Balay continue; 12979371c9d4SSatish Balay } 129808401ef6SPierre 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); 1299ca15aa20SStefano Zampini *v++ = vv[indexn[j] * mat->lda + indexm[i]]; 1300ae80bb75SLois Curfman McInnes } 1301ae80bb75SLois Curfman McInnes } 13029566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &vv)); 13033a40ed3dSBarry Smith PetscFunctionReturn(0); 1304ae80bb75SLois Curfman McInnes } 1305ae80bb75SLois Curfman McInnes 1306289bc588SBarry Smith /* -----------------------------------------------------------------*/ 1307289bc588SBarry Smith 13089371c9d4SSatish Balay PetscErrorCode MatView_Dense_Binary(Mat mat, PetscViewer viewer) { 13098491ab44SLisandro Dalcin PetscBool skipHeader; 13108491ab44SLisandro Dalcin PetscViewerFormat format; 13118491ab44SLisandro Dalcin PetscInt header[4], M, N, m, lda, i, j, k; 13128491ab44SLisandro Dalcin const PetscScalar *v; 13138491ab44SLisandro Dalcin PetscScalar *vwork; 1314aabbc4fbSShri Abhyankar 1315aabbc4fbSShri Abhyankar PetscFunctionBegin; 13169566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 13179566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader)); 13189566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 13198491ab44SLisandro Dalcin if (skipHeader) format = PETSC_VIEWER_NATIVE; 1320aabbc4fbSShri Abhyankar 13219566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &M, &N)); 13228491ab44SLisandro Dalcin 13238491ab44SLisandro Dalcin /* write matrix header */ 13249371c9d4SSatish Balay header[0] = MAT_FILE_CLASSID; 13259371c9d4SSatish Balay header[1] = M; 13269371c9d4SSatish Balay header[2] = N; 13278491ab44SLisandro Dalcin header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M * N; 13289566063dSJacob Faibussowitsch if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer, header, 4, PETSC_INT)); 13298491ab44SLisandro Dalcin 13309566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mat, &m, NULL)); 13318491ab44SLisandro Dalcin if (format != PETSC_VIEWER_NATIVE) { 13328491ab44SLisandro Dalcin PetscInt nnz = m * N, *iwork; 13338491ab44SLisandro Dalcin /* store row lengths for each row */ 13349566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz, &iwork)); 13358491ab44SLisandro Dalcin for (i = 0; i < m; i++) iwork[i] = N; 13369566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 13378491ab44SLisandro Dalcin /* store column indices (zero start index) */ 13388491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 13399371c9d4SSatish Balay for (j = 0; j < N; j++, k++) iwork[k] = j; 13409566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 13419566063dSJacob Faibussowitsch PetscCall(PetscFree(iwork)); 13428491ab44SLisandro Dalcin } 13438491ab44SLisandro Dalcin /* store matrix values as a dense matrix in row major order */ 13449566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m * N, &vwork)); 13459566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(mat, &v)); 13469566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(mat, &lda)); 13478491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 13489371c9d4SSatish Balay for (j = 0; j < N; j++, k++) vwork[k] = v[i + lda * j]; 13499566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(mat, &v)); 13509566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, vwork, m * N, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 13519566063dSJacob Faibussowitsch PetscCall(PetscFree(vwork)); 13528491ab44SLisandro Dalcin PetscFunctionReturn(0); 13538491ab44SLisandro Dalcin } 13548491ab44SLisandro Dalcin 13559371c9d4SSatish Balay PetscErrorCode MatLoad_Dense_Binary(Mat mat, PetscViewer viewer) { 13568491ab44SLisandro Dalcin PetscBool skipHeader; 13578491ab44SLisandro Dalcin PetscInt header[4], M, N, m, nz, lda, i, j, k; 13588491ab44SLisandro Dalcin PetscInt rows, cols; 13598491ab44SLisandro Dalcin PetscScalar *v, *vwork; 13608491ab44SLisandro Dalcin 13618491ab44SLisandro Dalcin PetscFunctionBegin; 13629566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 13639566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader)); 13648491ab44SLisandro Dalcin 13658491ab44SLisandro Dalcin if (!skipHeader) { 13669566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, header, 4, NULL, PETSC_INT)); 136708401ef6SPierre Jolivet PetscCheck(header[0] == MAT_FILE_CLASSID, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Not a matrix object in file"); 13689371c9d4SSatish Balay M = header[1]; 13699371c9d4SSatish Balay N = header[2]; 137008401ef6SPierre Jolivet PetscCheck(M >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix row size (%" PetscInt_FMT ") in file is negative", M); 137108401ef6SPierre Jolivet PetscCheck(N >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix column size (%" PetscInt_FMT ") in file is negative", N); 13728491ab44SLisandro Dalcin nz = header[3]; 1373aed4548fSBarry Smith PetscCheck(nz == MATRIX_BINARY_FORMAT_DENSE || nz >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Unknown matrix format %" PetscInt_FMT " in file", nz); 1374aabbc4fbSShri Abhyankar } else { 13759566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &M, &N)); 1376aed4548fSBarry 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"); 13778491ab44SLisandro Dalcin nz = MATRIX_BINARY_FORMAT_DENSE; 1378e6324fbbSBarry Smith } 1379aabbc4fbSShri Abhyankar 13808491ab44SLisandro Dalcin /* setup global sizes if not set */ 13818491ab44SLisandro Dalcin if (mat->rmap->N < 0) mat->rmap->N = M; 13828491ab44SLisandro Dalcin if (mat->cmap->N < 0) mat->cmap->N = N; 13839566063dSJacob Faibussowitsch PetscCall(MatSetUp(mat)); 13848491ab44SLisandro Dalcin /* check if global sizes are correct */ 13859566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &rows, &cols)); 1386aed4548fSBarry 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); 1387aabbc4fbSShri Abhyankar 13889566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, NULL, &N)); 13899566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mat, &m, NULL)); 13909566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(mat, &v)); 13919566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(mat, &lda)); 13928491ab44SLisandro Dalcin if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense format */ 13938491ab44SLisandro Dalcin PetscInt nnz = m * N; 13948491ab44SLisandro Dalcin /* read in matrix values */ 13959566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz, &vwork)); 13969566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 13978491ab44SLisandro Dalcin /* store values in column major order */ 13988491ab44SLisandro Dalcin for (j = 0; j < N; j++) 13999371c9d4SSatish Balay for (i = 0; i < m; i++) v[i + lda * j] = vwork[i * N + j]; 14009566063dSJacob Faibussowitsch PetscCall(PetscFree(vwork)); 14018491ab44SLisandro Dalcin } else { /* matrix in file is sparse format */ 14028491ab44SLisandro Dalcin PetscInt nnz = 0, *rlens, *icols; 14038491ab44SLisandro Dalcin /* read in row lengths */ 14049566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m, &rlens)); 14059566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, rlens, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 14068491ab44SLisandro Dalcin for (i = 0; i < m; i++) nnz += rlens[i]; 14078491ab44SLisandro Dalcin /* read in column indices and values */ 14089566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(nnz, &icols, nnz, &vwork)); 14099566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, icols, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 14109566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 14118491ab44SLisandro Dalcin /* store values in column major order */ 14128491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 14139371c9d4SSatish Balay for (j = 0; j < rlens[i]; j++, k++) v[i + lda * icols[k]] = vwork[k]; 14149566063dSJacob Faibussowitsch PetscCall(PetscFree(rlens)); 14159566063dSJacob Faibussowitsch PetscCall(PetscFree2(icols, vwork)); 1416aabbc4fbSShri Abhyankar } 14179566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(mat, &v)); 14189566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY)); 14199566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY)); 1420aabbc4fbSShri Abhyankar PetscFunctionReturn(0); 1421aabbc4fbSShri Abhyankar } 1422aabbc4fbSShri Abhyankar 14239371c9d4SSatish Balay PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer) { 1424eb91f321SVaclav Hapla PetscBool isbinary, ishdf5; 1425eb91f321SVaclav Hapla 1426eb91f321SVaclav Hapla PetscFunctionBegin; 1427eb91f321SVaclav Hapla PetscValidHeaderSpecific(newMat, MAT_CLASSID, 1); 1428eb91f321SVaclav Hapla PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1429eb91f321SVaclav Hapla /* force binary viewer to load .info file if it has not yet done so */ 14309566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 14319566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 14329566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5)); 1433eb91f321SVaclav Hapla if (isbinary) { 14349566063dSJacob Faibussowitsch PetscCall(MatLoad_Dense_Binary(newMat, viewer)); 1435eb91f321SVaclav Hapla } else if (ishdf5) { 1436eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5) 14379566063dSJacob Faibussowitsch PetscCall(MatLoad_Dense_HDF5(newMat, viewer)); 1438eb91f321SVaclav Hapla #else 1439eb91f321SVaclav Hapla SETERRQ(PetscObjectComm((PetscObject)newMat), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1440eb91f321SVaclav Hapla #endif 1441eb91f321SVaclav Hapla } else { 144298921bdaSJacob 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); 1443eb91f321SVaclav Hapla } 1444eb91f321SVaclav Hapla PetscFunctionReturn(0); 1445eb91f321SVaclav Hapla } 1446eb91f321SVaclav Hapla 14479371c9d4SSatish Balay static PetscErrorCode MatView_SeqDense_ASCII(Mat A, PetscViewer viewer) { 1448932b0c3eSLois Curfman McInnes Mat_SeqDense *a = (Mat_SeqDense *)A->data; 144913f74950SBarry Smith PetscInt i, j; 14502dcb1b2aSMatthew Knepley const char *name; 1451ca15aa20SStefano Zampini PetscScalar *v, *av; 1452f3ef73ceSBarry Smith PetscViewerFormat format; 14535f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX) 1454ace3abfcSBarry Smith PetscBool allreal = PETSC_TRUE; 14555f481a85SSatish Balay #endif 1456932b0c3eSLois Curfman McInnes 14573a40ed3dSBarry Smith PetscFunctionBegin; 14589566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&av)); 14599566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 1460456192e2SBarry Smith if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 14613a40ed3dSBarry Smith PetscFunctionReturn(0); /* do nothing for now */ 1462fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 14639566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE)); 1464d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 1465ca15aa20SStefano Zampini v = av + i; 14669566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "row %" PetscInt_FMT ":", i)); 1467d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1468aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 1469329f5518SBarry Smith if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) { 14709566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g + %g i) ", j, (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v))); 1471329f5518SBarry Smith } else if (PetscRealPart(*v)) { 14729566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)PetscRealPart(*v))); 14736831982aSBarry Smith } 147480cd9d93SLois Curfman McInnes #else 147548a46eb9SPierre Jolivet if (*v) PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)*v)); 147680cd9d93SLois Curfman McInnes #endif 14771b807ce4Svictorle v += a->lda; 147880cd9d93SLois Curfman McInnes } 14799566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 148080cd9d93SLois Curfman McInnes } 14819566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE)); 14823a40ed3dSBarry Smith } else { 14839566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE)); 1484aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 148547989497SBarry Smith /* determine if matrix has all real values */ 1486bcd8d3a4SJose E. Roman for (j = 0; j < A->cmap->n; j++) { 1487bcd8d3a4SJose E. Roman v = av + j * a->lda; 1488bcd8d3a4SJose E. Roman for (i = 0; i < A->rmap->n; i++) { 14899371c9d4SSatish Balay if (PetscImaginaryPart(v[i])) { 14909371c9d4SSatish Balay allreal = PETSC_FALSE; 14919371c9d4SSatish Balay break; 14929371c9d4SSatish Balay } 149347989497SBarry Smith } 1494bcd8d3a4SJose E. Roman } 149547989497SBarry Smith #endif 1496fb9695e5SSatish Balay if (format == PETSC_VIEWER_ASCII_MATLAB) { 14979566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)A, &name)); 14989566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%% Size = %" PetscInt_FMT " %" PetscInt_FMT " \n", A->rmap->n, A->cmap->n)); 14999566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%s = zeros(%" PetscInt_FMT ",%" PetscInt_FMT ");\n", name, A->rmap->n, A->cmap->n)); 15009566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%s = [\n", name)); 1501ffac6cdbSBarry Smith } 1502ffac6cdbSBarry Smith 1503d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 1504ca15aa20SStefano Zampini v = av + i; 1505d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1506aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 150747989497SBarry Smith if (allreal) { 15089566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)PetscRealPart(*v))); 150947989497SBarry Smith } else { 15109566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e + %18.16ei ", (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v))); 151147989497SBarry Smith } 1512289bc588SBarry Smith #else 15139566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)*v)); 1514289bc588SBarry Smith #endif 15151b807ce4Svictorle v += a->lda; 1516289bc588SBarry Smith } 15179566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 1518289bc588SBarry Smith } 151948a46eb9SPierre Jolivet if (format == PETSC_VIEWER_ASCII_MATLAB) PetscCall(PetscViewerASCIIPrintf(viewer, "];\n")); 15209566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE)); 1521da3a660dSBarry Smith } 15229566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&av)); 15239566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer)); 15243a40ed3dSBarry Smith PetscFunctionReturn(0); 1525289bc588SBarry Smith } 1526289bc588SBarry Smith 15279804daf3SBarry Smith #include <petscdraw.h> 15289371c9d4SSatish Balay static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw, void *Aa) { 1529f1af5d2fSBarry Smith Mat A = (Mat)Aa; 1530383922c3SLisandro Dalcin PetscInt m = A->rmap->n, n = A->cmap->n, i, j; 1531383922c3SLisandro Dalcin int color = PETSC_DRAW_WHITE; 1532ca15aa20SStefano Zampini const PetscScalar *v; 1533b0a32e0cSBarry Smith PetscViewer viewer; 1534b05fc000SLisandro Dalcin PetscReal xl, yl, xr, yr, x_l, x_r, y_l, y_r; 1535f3ef73ceSBarry Smith PetscViewerFormat format; 1536f1af5d2fSBarry Smith 1537f1af5d2fSBarry Smith PetscFunctionBegin; 15389566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)A, "Zoomviewer", (PetscObject *)&viewer)); 15399566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 15409566063dSJacob Faibussowitsch PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr)); 1541f1af5d2fSBarry Smith 1542f1af5d2fSBarry Smith /* Loop over matrix elements drawing boxes */ 15439566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 1544fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 1545d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 1546f1af5d2fSBarry Smith /* Blue for negative and Red for positive */ 1547f1af5d2fSBarry Smith for (j = 0; j < n; j++) { 15489371c9d4SSatish Balay x_l = j; 15499371c9d4SSatish Balay x_r = x_l + 1.0; 1550f1af5d2fSBarry Smith for (i = 0; i < m; i++) { 1551f1af5d2fSBarry Smith y_l = m - i - 1.0; 1552f1af5d2fSBarry Smith y_r = y_l + 1.0; 1553ca15aa20SStefano Zampini if (PetscRealPart(v[j * m + i]) > 0.) color = PETSC_DRAW_RED; 1554ca15aa20SStefano Zampini else if (PetscRealPart(v[j * m + i]) < 0.) color = PETSC_DRAW_BLUE; 1555ca15aa20SStefano Zampini else continue; 15569566063dSJacob Faibussowitsch PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color)); 1557f1af5d2fSBarry Smith } 1558f1af5d2fSBarry Smith } 1559d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 1560f1af5d2fSBarry Smith } else { 1561f1af5d2fSBarry Smith /* use contour shading to indicate magnitude of values */ 1562f1af5d2fSBarry Smith /* first determine max of all nonzero values */ 1563b05fc000SLisandro Dalcin PetscReal minv = 0.0, maxv = 0.0; 1564b05fc000SLisandro Dalcin PetscDraw popup; 1565b05fc000SLisandro Dalcin 1566f1af5d2fSBarry Smith for (i = 0; i < m * n; i++) { 1567f1af5d2fSBarry Smith if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]); 1568f1af5d2fSBarry Smith } 1569383922c3SLisandro Dalcin if (minv >= maxv) maxv = minv + PETSC_SMALL; 15709566063dSJacob Faibussowitsch PetscCall(PetscDrawGetPopup(draw, &popup)); 15719566063dSJacob Faibussowitsch PetscCall(PetscDrawScalePopup(popup, minv, maxv)); 1572383922c3SLisandro Dalcin 1573d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 1574f1af5d2fSBarry Smith for (j = 0; j < n; j++) { 1575f1af5d2fSBarry Smith x_l = j; 1576f1af5d2fSBarry Smith x_r = x_l + 1.0; 1577f1af5d2fSBarry Smith for (i = 0; i < m; i++) { 1578f1af5d2fSBarry Smith y_l = m - i - 1.0; 1579f1af5d2fSBarry Smith y_r = y_l + 1.0; 1580b05fc000SLisandro Dalcin color = PetscDrawRealToColor(PetscAbsScalar(v[j * m + i]), minv, maxv); 15819566063dSJacob Faibussowitsch PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color)); 1582f1af5d2fSBarry Smith } 1583f1af5d2fSBarry Smith } 1584d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 1585f1af5d2fSBarry Smith } 15869566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 1587f1af5d2fSBarry Smith PetscFunctionReturn(0); 1588f1af5d2fSBarry Smith } 1589f1af5d2fSBarry Smith 15909371c9d4SSatish Balay static PetscErrorCode MatView_SeqDense_Draw(Mat A, PetscViewer viewer) { 1591b0a32e0cSBarry Smith PetscDraw draw; 1592ace3abfcSBarry Smith PetscBool isnull; 1593329f5518SBarry Smith PetscReal xr, yr, xl, yl, h, w; 1594f1af5d2fSBarry Smith 1595f1af5d2fSBarry Smith PetscFunctionBegin; 15969566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 15979566063dSJacob Faibussowitsch PetscCall(PetscDrawIsNull(draw, &isnull)); 1598abc0a331SBarry Smith if (isnull) PetscFunctionReturn(0); 1599f1af5d2fSBarry Smith 16009371c9d4SSatish Balay xr = A->cmap->n; 16019371c9d4SSatish Balay yr = A->rmap->n; 16029371c9d4SSatish Balay h = yr / 10.0; 16039371c9d4SSatish Balay w = xr / 10.0; 16049371c9d4SSatish Balay xr += w; 16059371c9d4SSatish Balay yr += h; 16069371c9d4SSatish Balay xl = -w; 16079371c9d4SSatish Balay yl = -h; 16089566063dSJacob Faibussowitsch PetscCall(PetscDrawSetCoordinates(draw, xl, yl, xr, yr)); 16099566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", (PetscObject)viewer)); 16109566063dSJacob Faibussowitsch PetscCall(PetscDrawZoom(draw, MatView_SeqDense_Draw_Zoom, A)); 16119566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", NULL)); 16129566063dSJacob Faibussowitsch PetscCall(PetscDrawSave(draw)); 1613f1af5d2fSBarry Smith PetscFunctionReturn(0); 1614f1af5d2fSBarry Smith } 1615f1af5d2fSBarry Smith 16169371c9d4SSatish Balay PetscErrorCode MatView_SeqDense(Mat A, PetscViewer viewer) { 1617ace3abfcSBarry Smith PetscBool iascii, isbinary, isdraw; 1618932b0c3eSLois Curfman McInnes 16193a40ed3dSBarry Smith PetscFunctionBegin; 16209566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 16219566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 16229566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 16231baa6e33SBarry Smith if (iascii) PetscCall(MatView_SeqDense_ASCII(A, viewer)); 16241baa6e33SBarry Smith else if (isbinary) PetscCall(MatView_Dense_Binary(A, viewer)); 16251baa6e33SBarry Smith else if (isdraw) PetscCall(MatView_SeqDense_Draw(A, viewer)); 16263a40ed3dSBarry Smith PetscFunctionReturn(0); 1627932b0c3eSLois Curfman McInnes } 1628289bc588SBarry Smith 16299371c9d4SSatish Balay static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A, const PetscScalar *array) { 1630d3042a70SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1631d3042a70SBarry Smith 1632d3042a70SBarry Smith PetscFunctionBegin; 163328b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 163428b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 163528b400f6SJacob Faibussowitsch PetscCheck(!a->unplacedarray, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreArray() first"); 1636d3042a70SBarry Smith a->unplacedarray = a->v; 1637d3042a70SBarry Smith a->unplaced_user_alloc = a->user_alloc; 1638d3042a70SBarry Smith a->v = (PetscScalar *)array; 1639637a0070SStefano Zampini a->user_alloc = PETSC_TRUE; 1640ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA) 1641c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_CPU; 1642ca15aa20SStefano Zampini #endif 1643d3042a70SBarry Smith PetscFunctionReturn(0); 1644d3042a70SBarry Smith } 1645d3042a70SBarry Smith 16469371c9d4SSatish Balay static PetscErrorCode MatDenseResetArray_SeqDense(Mat A) { 1647d3042a70SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1648d3042a70SBarry Smith 1649d3042a70SBarry Smith PetscFunctionBegin; 165028b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 165128b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 1652d3042a70SBarry Smith a->v = a->unplacedarray; 1653d3042a70SBarry Smith a->user_alloc = a->unplaced_user_alloc; 1654d3042a70SBarry Smith a->unplacedarray = NULL; 1655ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA) 1656c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_CPU; 1657ca15aa20SStefano Zampini #endif 1658d3042a70SBarry Smith PetscFunctionReturn(0); 1659d3042a70SBarry Smith } 1660d3042a70SBarry Smith 16619371c9d4SSatish Balay static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A, const PetscScalar *array) { 1662d5ea218eSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1663d5ea218eSStefano Zampini 1664d5ea218eSStefano Zampini PetscFunctionBegin; 166528b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 166628b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 16679566063dSJacob Faibussowitsch if (!a->user_alloc) PetscCall(PetscFree(a->v)); 1668d5ea218eSStefano Zampini a->v = (PetscScalar *)array; 1669d5ea218eSStefano Zampini a->user_alloc = PETSC_FALSE; 1670d5ea218eSStefano Zampini #if defined(PETSC_HAVE_CUDA) 1671d5ea218eSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 1672d5ea218eSStefano Zampini #endif 1673d5ea218eSStefano Zampini PetscFunctionReturn(0); 1674d5ea218eSStefano Zampini } 1675d5ea218eSStefano Zampini 16769371c9d4SSatish Balay PetscErrorCode MatDestroy_SeqDense(Mat mat) { 1677ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)mat->data; 167890f02eecSBarry Smith 16793a40ed3dSBarry Smith PetscFunctionBegin; 1680aa482453SBarry Smith #if defined(PETSC_USE_LOG) 1681c0aa6a63SJacob Faibussowitsch PetscLogObjectState((PetscObject)mat, "Rows %" PetscInt_FMT " Cols %" PetscInt_FMT, mat->rmap->n, mat->cmap->n); 1682a5a9c739SBarry Smith #endif 16839566063dSJacob Faibussowitsch PetscCall(VecDestroy(&(l->qrrhs))); 16849566063dSJacob Faibussowitsch PetscCall(PetscFree(l->tau)); 16859566063dSJacob Faibussowitsch PetscCall(PetscFree(l->pivots)); 16869566063dSJacob Faibussowitsch PetscCall(PetscFree(l->fwork)); 16879566063dSJacob Faibussowitsch PetscCall(MatDestroy(&l->ptapwork)); 16889566063dSJacob Faibussowitsch if (!l->user_alloc) PetscCall(PetscFree(l->v)); 16899566063dSJacob Faibussowitsch if (!l->unplaced_user_alloc) PetscCall(PetscFree(l->unplacedarray)); 169028b400f6SJacob Faibussowitsch PetscCheck(!l->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 169128b400f6SJacob Faibussowitsch PetscCheck(!l->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 16929566063dSJacob Faibussowitsch PetscCall(VecDestroy(&l->cvec)); 16939566063dSJacob Faibussowitsch PetscCall(MatDestroy(&l->cmat)); 16949566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->data)); 1695dbd8c25aSHong Zhang 16969566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)mat, NULL)); 16979566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactor_C", NULL)); 16982e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorSymbolic_C", NULL)); 16992e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorNumeric_C", NULL)); 17009566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetLDA_C", NULL)); 17019566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseSetLDA_C", NULL)); 17029566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArray_C", NULL)); 17039566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArray_C", NULL)); 17049566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDensePlaceArray_C", NULL)); 17059566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseResetArray_C", NULL)); 17069566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseReplaceArray_C", NULL)); 17079566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayRead_C", NULL)); 17089566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayRead_C", NULL)); 17099566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayWrite_C", NULL)); 17109566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayWrite_C", NULL)); 17119566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqaij_C", NULL)); 17128baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 17139566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_elemental_C", NULL)); 17148baccfbdSHong Zhang #endif 1715d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 17169566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_scalapack_C", NULL)); 1717d24d4204SJose E. Roman #endif 17182bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA) 17199566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensecuda_C", NULL)); 17209566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", NULL)); 17219566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdense_C", NULL)); 17222e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensecuda_C", NULL)); 17232bf066beSStefano Zampini #endif 17249566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatSeqDenseSetPreallocation_C", NULL)); 17259566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqaij_seqdense_C", NULL)); 17269566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdense_C", NULL)); 17279566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqbaij_seqdense_C", NULL)); 17289566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqsbaij_seqdense_C", NULL)); 172952c5f739Sprj- 17309566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumn_C", NULL)); 17319566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumn_C", NULL)); 17329566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVec_C", NULL)); 17339566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVec_C", NULL)); 17349566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecRead_C", NULL)); 17359566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecRead_C", NULL)); 17369566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecWrite_C", NULL)); 17379566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecWrite_C", NULL)); 17389566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetSubMatrix_C", NULL)); 17399566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreSubMatrix_C", NULL)); 17403a40ed3dSBarry Smith PetscFunctionReturn(0); 1741289bc588SBarry Smith } 1742289bc588SBarry Smith 17439371c9d4SSatish Balay static PetscErrorCode MatTranspose_SeqDense(Mat A, MatReuse reuse, Mat *matout) { 1744c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 17456536e3caSStefano Zampini PetscInt k, j, m = A->rmap->n, M = mat->lda, n = A->cmap->n; 174687828ca2SBarry Smith PetscScalar *v, tmp; 174748b35521SBarry Smith 17483a40ed3dSBarry Smith PetscFunctionBegin; 17497fb60732SBarry Smith if (reuse == MAT_REUSE_MATRIX) PetscCall(MatTransposeCheckNonzeroState_Private(A, *matout)); 17506536e3caSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 17516536e3caSStefano Zampini if (m == n) { /* in place transpose */ 17529566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 1753d3e5ee88SLois Curfman McInnes for (j = 0; j < m; j++) { 1754289bc588SBarry Smith for (k = 0; k < j; k++) { 17551b807ce4Svictorle tmp = v[j + k * M]; 17561b807ce4Svictorle v[j + k * M] = v[k + j * M]; 17571b807ce4Svictorle v[k + j * M] = tmp; 1758289bc588SBarry Smith } 1759289bc588SBarry Smith } 17609566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 17616536e3caSStefano Zampini } else { /* reuse memory, temporary allocates new memory */ 17626536e3caSStefano Zampini PetscScalar *v2; 17636536e3caSStefano Zampini PetscLayout tmplayout; 17646536e3caSStefano Zampini 17659566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((size_t)m * n, &v2)); 17669566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 17676536e3caSStefano Zampini for (j = 0; j < n; j++) { 17686536e3caSStefano Zampini for (k = 0; k < m; k++) v2[j + (size_t)k * n] = v[k + (size_t)j * M]; 17696536e3caSStefano Zampini } 17709566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(v, v2, (size_t)m * n)); 17719566063dSJacob Faibussowitsch PetscCall(PetscFree(v2)); 17729566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 17736536e3caSStefano Zampini /* cleanup size dependent quantities */ 17749566063dSJacob Faibussowitsch PetscCall(VecDestroy(&mat->cvec)); 17759566063dSJacob Faibussowitsch PetscCall(MatDestroy(&mat->cmat)); 17769566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->pivots)); 17779566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->fwork)); 17789566063dSJacob Faibussowitsch PetscCall(MatDestroy(&mat->ptapwork)); 17796536e3caSStefano Zampini /* swap row/col layouts */ 17806536e3caSStefano Zampini mat->lda = n; 17816536e3caSStefano Zampini tmplayout = A->rmap; 17826536e3caSStefano Zampini A->rmap = A->cmap; 17836536e3caSStefano Zampini A->cmap = tmplayout; 17846536e3caSStefano Zampini } 17853a40ed3dSBarry Smith } else { /* out-of-place transpose */ 1786d3e5ee88SLois Curfman McInnes Mat tmat; 1787ec8511deSBarry Smith Mat_SeqDense *tmatd; 178887828ca2SBarry Smith PetscScalar *v2; 1789af36a384SStefano Zampini PetscInt M2; 1790ea709b57SSatish Balay 17916536e3caSStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 17929566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &tmat)); 17939566063dSJacob Faibussowitsch PetscCall(MatSetSizes(tmat, A->cmap->n, A->rmap->n, A->cmap->n, A->rmap->n)); 17949566063dSJacob Faibussowitsch PetscCall(MatSetType(tmat, ((PetscObject)A)->type_name)); 17959566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(tmat, NULL)); 1796ca15aa20SStefano Zampini } else tmat = *matout; 1797ca15aa20SStefano Zampini 17989566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&v)); 17999566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(tmat, &v2)); 1800ec8511deSBarry Smith tmatd = (Mat_SeqDense *)tmat->data; 1801ca15aa20SStefano Zampini M2 = tmatd->lda; 1802d3e5ee88SLois Curfman McInnes for (j = 0; j < n; j++) { 1803af36a384SStefano Zampini for (k = 0; k < m; k++) v2[j + k * M2] = v[k + j * M]; 1804d3e5ee88SLois Curfman McInnes } 18059566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(tmat, &v2)); 18069566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&v)); 18079566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(tmat, MAT_FINAL_ASSEMBLY)); 18089566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(tmat, MAT_FINAL_ASSEMBLY)); 18096536e3caSStefano Zampini *matout = tmat; 181048b35521SBarry Smith } 18113a40ed3dSBarry Smith PetscFunctionReturn(0); 1812289bc588SBarry Smith } 1813289bc588SBarry Smith 18149371c9d4SSatish Balay static PetscErrorCode MatEqual_SeqDense(Mat A1, Mat A2, PetscBool *flg) { 1815c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat1 = (Mat_SeqDense *)A1->data; 1816c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat2 = (Mat_SeqDense *)A2->data; 1817ca15aa20SStefano Zampini PetscInt i; 1818ca15aa20SStefano Zampini const PetscScalar *v1, *v2; 18199ea5d5aeSSatish Balay 18203a40ed3dSBarry Smith PetscFunctionBegin; 18219371c9d4SSatish Balay if (A1->rmap->n != A2->rmap->n) { 18229371c9d4SSatish Balay *flg = PETSC_FALSE; 18239371c9d4SSatish Balay PetscFunctionReturn(0); 18249371c9d4SSatish Balay } 18259371c9d4SSatish Balay if (A1->cmap->n != A2->cmap->n) { 18269371c9d4SSatish Balay *flg = PETSC_FALSE; 18279371c9d4SSatish Balay PetscFunctionReturn(0); 18289371c9d4SSatish Balay } 18299566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A1, &v1)); 18309566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A2, &v2)); 1831ca15aa20SStefano Zampini for (i = 0; i < A1->cmap->n; i++) { 18329566063dSJacob Faibussowitsch PetscCall(PetscArraycmp(v1, v2, A1->rmap->n, flg)); 1833ca15aa20SStefano Zampini if (*flg == PETSC_FALSE) PetscFunctionReturn(0); 1834ca15aa20SStefano Zampini v1 += mat1->lda; 1835ca15aa20SStefano Zampini v2 += mat2->lda; 18361b807ce4Svictorle } 18379566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A1, &v1)); 18389566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A2, &v2)); 183977c4ece6SBarry Smith *flg = PETSC_TRUE; 18403a40ed3dSBarry Smith PetscFunctionReturn(0); 1841289bc588SBarry Smith } 1842289bc588SBarry Smith 18439371c9d4SSatish Balay static PetscErrorCode MatGetDiagonal_SeqDense(Mat A, Vec v) { 1844c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 184513f74950SBarry Smith PetscInt i, n, len; 1846ca15aa20SStefano Zampini PetscScalar *x; 1847ca15aa20SStefano Zampini const PetscScalar *vv; 184844cd7ae7SLois Curfman McInnes 18493a40ed3dSBarry Smith PetscFunctionBegin; 18509566063dSJacob Faibussowitsch PetscCall(VecGetSize(v, &n)); 18519566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 1852d0f46423SBarry Smith len = PetscMin(A->rmap->n, A->cmap->n); 18539566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &vv)); 185408401ef6SPierre Jolivet PetscCheck(n == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming mat and vec"); 1855ad540459SPierre Jolivet for (i = 0; i < len; i++) x[i] = vv[i * mat->lda + i]; 18569566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &vv)); 18579566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 18583a40ed3dSBarry Smith PetscFunctionReturn(0); 1859289bc588SBarry Smith } 1860289bc588SBarry Smith 18619371c9d4SSatish Balay static PetscErrorCode MatDiagonalScale_SeqDense(Mat A, Vec ll, Vec rr) { 1862c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1863f1ceaac6SMatthew G. Knepley const PetscScalar *l, *r; 1864ca15aa20SStefano Zampini PetscScalar x, *v, *vv; 1865d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n; 186655659b69SBarry Smith 18673a40ed3dSBarry Smith PetscFunctionBegin; 18689566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &vv)); 186928988994SBarry Smith if (ll) { 18709566063dSJacob Faibussowitsch PetscCall(VecGetSize(ll, &m)); 18719566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(ll, &l)); 187208401ef6SPierre Jolivet PetscCheck(m == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Left scaling vec wrong size"); 1873da3a660dSBarry Smith for (i = 0; i < m; i++) { 1874da3a660dSBarry Smith x = l[i]; 1875ca15aa20SStefano Zampini v = vv + i; 18769371c9d4SSatish Balay for (j = 0; j < n; j++) { 18779371c9d4SSatish Balay (*v) *= x; 18789371c9d4SSatish Balay v += mat->lda; 18799371c9d4SSatish Balay } 1880da3a660dSBarry Smith } 18819566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(ll, &l)); 18829566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * n * m)); 1883da3a660dSBarry Smith } 188428988994SBarry Smith if (rr) { 18859566063dSJacob Faibussowitsch PetscCall(VecGetSize(rr, &n)); 18869566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(rr, &r)); 188708401ef6SPierre Jolivet PetscCheck(n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Right scaling vec wrong size"); 1888da3a660dSBarry Smith for (i = 0; i < n; i++) { 1889da3a660dSBarry Smith x = r[i]; 1890ca15aa20SStefano Zampini v = vv + i * mat->lda; 18912205254eSKarl Rupp for (j = 0; j < m; j++) (*v++) *= x; 1892da3a660dSBarry Smith } 18939566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(rr, &r)); 18949566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * n * m)); 1895da3a660dSBarry Smith } 18969566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &vv)); 18973a40ed3dSBarry Smith PetscFunctionReturn(0); 1898289bc588SBarry Smith } 1899289bc588SBarry Smith 19009371c9d4SSatish Balay PetscErrorCode MatNorm_SeqDense(Mat A, NormType type, PetscReal *nrm) { 1901c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1902ca15aa20SStefano Zampini PetscScalar *v, *vv; 1903329f5518SBarry Smith PetscReal sum = 0.0; 190475f6d85dSStefano Zampini PetscInt lda, m = A->rmap->n, i, j; 190555659b69SBarry Smith 19063a40ed3dSBarry Smith PetscFunctionBegin; 19079566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&vv)); 19089566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(A, &lda)); 1909ca15aa20SStefano Zampini v = vv; 1910289bc588SBarry Smith if (type == NORM_FROBENIUS) { 1911a5ce6ee0Svictorle if (lda > m) { 1912d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1913ca15aa20SStefano Zampini v = vv + j * lda; 1914a5ce6ee0Svictorle for (i = 0; i < m; i++) { 19159371c9d4SSatish Balay sum += PetscRealPart(PetscConj(*v) * (*v)); 19169371c9d4SSatish Balay v++; 1917a5ce6ee0Svictorle } 1918a5ce6ee0Svictorle } 1919a5ce6ee0Svictorle } else { 1920570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16) 1921570b7f6dSBarry Smith PetscBLASInt one = 1, cnt = A->cmap->n * A->rmap->n; 1922792fecdfSBarry Smith PetscCallBLAS("BLASnrm2", *nrm = BLASnrm2_(&cnt, v, &one)); 1923570b7f6dSBarry Smith } 1924570b7f6dSBarry Smith #else 1925d0f46423SBarry Smith for (i = 0; i < A->cmap->n * A->rmap->n; i++) { 19269371c9d4SSatish Balay sum += PetscRealPart(PetscConj(*v) * (*v)); 19279371c9d4SSatish Balay v++; 1928289bc588SBarry Smith } 1929a5ce6ee0Svictorle } 19308f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 1931570b7f6dSBarry Smith #endif 19329566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->cmap->n * A->rmap->n)); 19333a40ed3dSBarry Smith } else if (type == NORM_1) { 1934064f8208SBarry Smith *nrm = 0.0; 1935d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1936ca15aa20SStefano Zampini v = vv + j * mat->lda; 1937289bc588SBarry Smith sum = 0.0; 1938d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 19399371c9d4SSatish Balay sum += PetscAbsScalar(*v); 19409371c9d4SSatish Balay v++; 1941289bc588SBarry Smith } 1942064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 1943289bc588SBarry Smith } 19449566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n)); 19453a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 1946064f8208SBarry Smith *nrm = 0.0; 1947d0f46423SBarry Smith for (j = 0; j < A->rmap->n; j++) { 1948ca15aa20SStefano Zampini v = vv + j; 1949289bc588SBarry Smith sum = 0.0; 1950d0f46423SBarry Smith for (i = 0; i < A->cmap->n; i++) { 19519371c9d4SSatish Balay sum += PetscAbsScalar(*v); 19529371c9d4SSatish Balay v += mat->lda; 1953289bc588SBarry Smith } 1954064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 1955289bc588SBarry Smith } 19569566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n)); 1957e7e72b3dSBarry Smith } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "No two norm"); 19589566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&vv)); 19593a40ed3dSBarry Smith PetscFunctionReturn(0); 1960289bc588SBarry Smith } 1961289bc588SBarry Smith 19629371c9d4SSatish Balay static PetscErrorCode MatSetOption_SeqDense(Mat A, MatOption op, PetscBool flg) { 1963c0bbcb79SLois Curfman McInnes Mat_SeqDense *aij = (Mat_SeqDense *)A->data; 196467e560aaSBarry Smith 19653a40ed3dSBarry Smith PetscFunctionBegin; 1966b5a2b587SKris Buschelman switch (op) { 19679371c9d4SSatish Balay case MAT_ROW_ORIENTED: aij->roworiented = flg; break; 1968512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 1969b5a2b587SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 19703971808eSMatthew Knepley case MAT_NEW_NONZERO_ALLOCATION_ERR: 19718c78258cSHong Zhang case MAT_FORCE_DIAGONAL_ENTRIES: 197213fa8e87SLisandro Dalcin case MAT_KEEP_NONZERO_PATTERN: 1973b5a2b587SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 1974b5a2b587SKris Buschelman case MAT_USE_HASH_TABLE: 19750f8fb01aSBarry Smith case MAT_IGNORE_ZERO_ENTRIES: 19765021d80fSJed Brown case MAT_IGNORE_LOWER_TRIANGULAR: 19779371c9d4SSatish Balay case MAT_SORTED_FULL: PetscCall(PetscInfo(A, "Option %s ignored\n", MatOptions[op])); break; 19785021d80fSJed Brown case MAT_SPD: 197977e54ba9SKris Buschelman case MAT_SYMMETRIC: 198077e54ba9SKris Buschelman case MAT_STRUCTURALLY_SYMMETRIC: 19819a4540c5SBarry Smith case MAT_HERMITIAN: 19829a4540c5SBarry Smith case MAT_SYMMETRY_ETERNAL: 1983b94d7dedSBarry Smith case MAT_STRUCTURAL_SYMMETRY_ETERNAL: 19849371c9d4SSatish Balay case MAT_SPD_ETERNAL: break; 19859371c9d4SSatish Balay default: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "unknown option %s", MatOptions[op]); 19863a40ed3dSBarry Smith } 19873a40ed3dSBarry Smith PetscFunctionReturn(0); 1988289bc588SBarry Smith } 1989289bc588SBarry Smith 19909371c9d4SSatish Balay PetscErrorCode MatZeroEntries_SeqDense(Mat A) { 1991ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)A->data; 19923d8925e7SStefano Zampini PetscInt lda = l->lda, m = A->rmap->n, n = A->cmap->n, j; 1993ca15aa20SStefano Zampini PetscScalar *v; 19943a40ed3dSBarry Smith 19953a40ed3dSBarry Smith PetscFunctionBegin; 19969566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(A, &v)); 1997a5ce6ee0Svictorle if (lda > m) { 199848a46eb9SPierre Jolivet for (j = 0; j < n; j++) PetscCall(PetscArrayzero(v + j * lda, m)); 1999a5ce6ee0Svictorle } else { 20009566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(v, PetscInt64Mult(m, n))); 2001a5ce6ee0Svictorle } 20029566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(A, &v)); 20033a40ed3dSBarry Smith PetscFunctionReturn(0); 20046f0a148fSBarry Smith } 20056f0a148fSBarry Smith 20069371c9d4SSatish Balay static PetscErrorCode MatZeroRows_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) { 2007ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)A->data; 2008b9679d65SBarry Smith PetscInt m = l->lda, n = A->cmap->n, i, j; 2009ca15aa20SStefano Zampini PetscScalar *slot, *bb, *v; 201097b48c8fSBarry Smith const PetscScalar *xx; 201155659b69SBarry Smith 20123a40ed3dSBarry Smith PetscFunctionBegin; 201376bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 2014b9679d65SBarry Smith for (i = 0; i < N; i++) { 201508401ef6SPierre Jolivet PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed"); 201608401ef6SPierre 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); 2017b9679d65SBarry Smith } 201876bd3646SJed Brown } 2019ca15aa20SStefano Zampini if (!N) PetscFunctionReturn(0); 2020b9679d65SBarry Smith 202197b48c8fSBarry Smith /* fix right hand side if needed */ 202297b48c8fSBarry Smith if (x && b) { 20239566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 20249566063dSJacob Faibussowitsch PetscCall(VecGetArray(b, &bb)); 20252205254eSKarl Rupp for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]]; 20269566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 20279566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(b, &bb)); 202897b48c8fSBarry Smith } 202997b48c8fSBarry Smith 20309566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 20316f0a148fSBarry Smith for (i = 0; i < N; i++) { 2032ca15aa20SStefano Zampini slot = v + rows[i]; 20339371c9d4SSatish Balay for (j = 0; j < n; j++) { 20349371c9d4SSatish Balay *slot = 0.0; 20359371c9d4SSatish Balay slot += m; 20369371c9d4SSatish Balay } 20376f0a148fSBarry Smith } 2038f4df32b1SMatthew Knepley if (diag != 0.0) { 203908401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices"); 20406f0a148fSBarry Smith for (i = 0; i < N; i++) { 2041ca15aa20SStefano Zampini slot = v + (m + 1) * rows[i]; 2042f4df32b1SMatthew Knepley *slot = diag; 20436f0a148fSBarry Smith } 20446f0a148fSBarry Smith } 20459566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 20463a40ed3dSBarry Smith PetscFunctionReturn(0); 20476f0a148fSBarry Smith } 2048557bce09SLois Curfman McInnes 20499371c9d4SSatish Balay static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A, PetscInt *lda) { 205049a6ff4bSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 205149a6ff4bSBarry Smith 205249a6ff4bSBarry Smith PetscFunctionBegin; 205349a6ff4bSBarry Smith *lda = mat->lda; 205449a6ff4bSBarry Smith PetscFunctionReturn(0); 205549a6ff4bSBarry Smith } 205649a6ff4bSBarry Smith 20579371c9d4SSatish Balay PetscErrorCode MatDenseGetArray_SeqDense(Mat A, PetscScalar **array) { 2058c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 20593a40ed3dSBarry Smith 20603a40ed3dSBarry Smith PetscFunctionBegin; 206128b400f6SJacob Faibussowitsch PetscCheck(!mat->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 206264e87e97SBarry Smith *array = mat->v; 20633a40ed3dSBarry Smith PetscFunctionReturn(0); 206464e87e97SBarry Smith } 20650754003eSLois Curfman McInnes 20669371c9d4SSatish Balay PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A, PetscScalar **array) { 20673a40ed3dSBarry Smith PetscFunctionBegin; 206875f6d85dSStefano Zampini if (array) *array = NULL; 20693a40ed3dSBarry Smith PetscFunctionReturn(0); 2070ff14e315SSatish Balay } 20710754003eSLois Curfman McInnes 20720f74d2c1SSatish Balay /*@ 207311a5261eSBarry Smith MatDenseGetLDA - gets the leading dimension of the array returned from `MatDenseGetArray()` 207449a6ff4bSBarry Smith 2075ad16ce7aSStefano Zampini Not collective 207649a6ff4bSBarry Smith 207749a6ff4bSBarry Smith Input Parameter: 207811a5261eSBarry Smith . mat - a `MATDENSE` or `MATDENSECUDA` matrix 207949a6ff4bSBarry Smith 208049a6ff4bSBarry Smith Output Parameter: 208149a6ff4bSBarry Smith . lda - the leading dimension 208249a6ff4bSBarry Smith 208349a6ff4bSBarry Smith Level: intermediate 208449a6ff4bSBarry Smith 208511a5261eSBarry Smith .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseSetLDA()` 208649a6ff4bSBarry Smith @*/ 20879371c9d4SSatish Balay PetscErrorCode MatDenseGetLDA(Mat A, PetscInt *lda) { 208849a6ff4bSBarry Smith PetscFunctionBegin; 2089d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2090dadcf809SJacob Faibussowitsch PetscValidIntPointer(lda, 2); 209175f6d85dSStefano Zampini MatCheckPreallocated(A, 1); 2092cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetLDA_C", (Mat, PetscInt *), (A, lda)); 209349a6ff4bSBarry Smith PetscFunctionReturn(0); 209449a6ff4bSBarry Smith } 209549a6ff4bSBarry Smith 20960f74d2c1SSatish Balay /*@ 209711a5261eSBarry Smith MatDenseSetLDA - Sets the leading dimension of the array used by the `MATDENSE` matrix 2098ad16ce7aSStefano Zampini 2099ad16ce7aSStefano Zampini Not collective 2100ad16ce7aSStefano Zampini 2101d8d19677SJose E. Roman Input Parameters: 210211a5261eSBarry Smith + mat - a `MATDENSE` or `MATDENSECUDA` matrix 2103ad16ce7aSStefano Zampini - lda - the leading dimension 2104ad16ce7aSStefano Zampini 2105ad16ce7aSStefano Zampini Level: intermediate 2106ad16ce7aSStefano Zampini 210711a5261eSBarry Smith .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetLDA()` 2108ad16ce7aSStefano Zampini @*/ 21099371c9d4SSatish Balay PetscErrorCode MatDenseSetLDA(Mat A, PetscInt lda) { 2110ad16ce7aSStefano Zampini PetscFunctionBegin; 2111ad16ce7aSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2112cac4c232SBarry Smith PetscTryMethod(A, "MatDenseSetLDA_C", (Mat, PetscInt), (A, lda)); 2113ad16ce7aSStefano Zampini PetscFunctionReturn(0); 2114ad16ce7aSStefano Zampini } 2115ad16ce7aSStefano Zampini 2116ad16ce7aSStefano Zampini /*@C 211711a5261eSBarry Smith MatDenseGetArray - gives read-write access to the array where the data for a `MATDENSE` matrix is stored 211873a71a0fSBarry Smith 211911a5261eSBarry Smith Logically Collective on A 212073a71a0fSBarry Smith 212173a71a0fSBarry Smith Input Parameter: 21226947451fSStefano Zampini . mat - a dense matrix 212373a71a0fSBarry Smith 212473a71a0fSBarry Smith Output Parameter: 212573a71a0fSBarry Smith . array - pointer to the data 212673a71a0fSBarry Smith 212773a71a0fSBarry Smith Level: intermediate 212873a71a0fSBarry Smith 212911a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 213073a71a0fSBarry Smith @*/ 21319371c9d4SSatish Balay PetscErrorCode MatDenseGetArray(Mat A, PetscScalar **array) { 213273a71a0fSBarry Smith PetscFunctionBegin; 2133d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2134d5ea218eSStefano Zampini PetscValidPointer(array, 2); 2135cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array)); 213673a71a0fSBarry Smith PetscFunctionReturn(0); 213773a71a0fSBarry Smith } 213873a71a0fSBarry Smith 2139dec5eb66SMatthew G Knepley /*@C 214011a5261eSBarry Smith MatDenseRestoreArray - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArray()` 214173a71a0fSBarry Smith 214211a5261eSBarry Smith Logically Collective on A 21438572280aSBarry Smith 21448572280aSBarry Smith Input Parameters: 21456947451fSStefano Zampini + mat - a dense matrix 2146742765d3SMatthew Knepley - array - pointer to the data (may be NULL) 21478572280aSBarry Smith 21488572280aSBarry Smith Level: intermediate 21498572280aSBarry Smith 215011a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 21518572280aSBarry Smith @*/ 21529371c9d4SSatish Balay PetscErrorCode MatDenseRestoreArray(Mat A, PetscScalar **array) { 21538572280aSBarry Smith PetscFunctionBegin; 2154d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2155d5ea218eSStefano Zampini PetscValidPointer(array, 2); 2156cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array)); 21579566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)A)); 2158637a0070SStefano Zampini #if defined(PETSC_HAVE_CUDA) 2159637a0070SStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 2160637a0070SStefano Zampini #endif 21618572280aSBarry Smith PetscFunctionReturn(0); 21628572280aSBarry Smith } 21638572280aSBarry Smith 21648572280aSBarry Smith /*@C 216511a5261eSBarry Smith MatDenseGetArrayRead - gives read-only access to the array where the data for a `MATDENSE` matrix is stored 21668572280aSBarry Smith 21678572280aSBarry Smith Not Collective 21688572280aSBarry Smith 21698572280aSBarry Smith Input Parameter: 21706947451fSStefano Zampini . mat - a dense matrix 21718572280aSBarry Smith 21728572280aSBarry Smith Output Parameter: 21738572280aSBarry Smith . array - pointer to the data 21748572280aSBarry Smith 21758572280aSBarry Smith Level: intermediate 21768572280aSBarry Smith 217711a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 21788572280aSBarry Smith @*/ 21799371c9d4SSatish Balay PetscErrorCode MatDenseGetArrayRead(Mat A, const PetscScalar **array) { 21808572280aSBarry Smith PetscFunctionBegin; 2181d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2182d5ea218eSStefano Zampini PetscValidPointer(array, 2); 2183cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, const PetscScalar **), (A, array)); 21848572280aSBarry Smith PetscFunctionReturn(0); 21858572280aSBarry Smith } 21868572280aSBarry Smith 21878572280aSBarry Smith /*@C 218811a5261eSBarry Smith MatDenseRestoreArrayRead - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayRead()` 21898572280aSBarry Smith 219073a71a0fSBarry Smith Not Collective 219173a71a0fSBarry Smith 219273a71a0fSBarry Smith Input Parameters: 21936947451fSStefano Zampini + mat - a dense matrix 2194742765d3SMatthew Knepley - array - pointer to the data (may be NULL) 219573a71a0fSBarry Smith 219673a71a0fSBarry Smith Level: intermediate 219773a71a0fSBarry Smith 219811a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 219973a71a0fSBarry Smith @*/ 22009371c9d4SSatish Balay PetscErrorCode MatDenseRestoreArrayRead(Mat A, const PetscScalar **array) { 220173a71a0fSBarry Smith PetscFunctionBegin; 2202d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2203d5ea218eSStefano Zampini PetscValidPointer(array, 2); 2204cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, const PetscScalar **), (A, array)); 220573a71a0fSBarry Smith PetscFunctionReturn(0); 220673a71a0fSBarry Smith } 220773a71a0fSBarry Smith 22086947451fSStefano Zampini /*@C 220911a5261eSBarry Smith MatDenseGetArrayWrite - gives write-only access to the array where the data for a `MATDENSE` matrix is stored 22106947451fSStefano Zampini 22116947451fSStefano Zampini Not Collective 22126947451fSStefano Zampini 22136947451fSStefano Zampini Input Parameter: 22146947451fSStefano Zampini . mat - a dense matrix 22156947451fSStefano Zampini 22166947451fSStefano Zampini Output Parameter: 22176947451fSStefano Zampini . array - pointer to the data 22186947451fSStefano Zampini 22196947451fSStefano Zampini Level: intermediate 22206947451fSStefano Zampini 222111a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()` 22226947451fSStefano Zampini @*/ 22239371c9d4SSatish Balay PetscErrorCode MatDenseGetArrayWrite(Mat A, PetscScalar **array) { 22246947451fSStefano Zampini PetscFunctionBegin; 2225d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2226d5ea218eSStefano Zampini PetscValidPointer(array, 2); 2227cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array)); 22286947451fSStefano Zampini PetscFunctionReturn(0); 22296947451fSStefano Zampini } 22306947451fSStefano Zampini 22316947451fSStefano Zampini /*@C 223211a5261eSBarry Smith MatDenseRestoreArrayWrite - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayWrite()` 22336947451fSStefano Zampini 22346947451fSStefano Zampini Not Collective 22356947451fSStefano Zampini 22366947451fSStefano Zampini Input Parameters: 22376947451fSStefano Zampini + mat - a dense matrix 2238742765d3SMatthew Knepley - array - pointer to the data (may be NULL) 22396947451fSStefano Zampini 22406947451fSStefano Zampini Level: intermediate 22416947451fSStefano Zampini 224211a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()` 22436947451fSStefano Zampini @*/ 22449371c9d4SSatish Balay PetscErrorCode MatDenseRestoreArrayWrite(Mat A, PetscScalar **array) { 22456947451fSStefano Zampini PetscFunctionBegin; 2246d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2247d5ea218eSStefano Zampini PetscValidPointer(array, 2); 2248cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array)); 22499566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)A)); 22506947451fSStefano Zampini #if defined(PETSC_HAVE_CUDA) 22516947451fSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 22526947451fSStefano Zampini #endif 22536947451fSStefano Zampini PetscFunctionReturn(0); 22546947451fSStefano Zampini } 22556947451fSStefano Zampini 22569371c9d4SSatish Balay static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A, IS isrow, IS iscol, MatReuse scall, Mat *B) { 2257c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 2258bf5a80bcSToby Isaac PetscInt i, j, nrows, ncols, ldb; 22595d0c19d7SBarry Smith const PetscInt *irow, *icol; 226087828ca2SBarry Smith PetscScalar *av, *bv, *v = mat->v; 22610754003eSLois Curfman McInnes Mat newmat; 22620754003eSLois Curfman McInnes 22633a40ed3dSBarry Smith PetscFunctionBegin; 22649566063dSJacob Faibussowitsch PetscCall(ISGetIndices(isrow, &irow)); 22659566063dSJacob Faibussowitsch PetscCall(ISGetIndices(iscol, &icol)); 22669566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(isrow, &nrows)); 22679566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(iscol, &ncols)); 22680754003eSLois Curfman McInnes 2269182d2002SSatish Balay /* Check submatrixcall */ 2270182d2002SSatish Balay if (scall == MAT_REUSE_MATRIX) { 227113f74950SBarry Smith PetscInt n_cols, n_rows; 22729566063dSJacob Faibussowitsch PetscCall(MatGetSize(*B, &n_rows, &n_cols)); 227321a2c019SBarry Smith if (n_rows != nrows || n_cols != ncols) { 2274f746d493SDmitry Karpeev /* resize the result matrix to match number of requested rows/columns */ 22759566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*B, nrows, ncols, nrows, ncols)); 227621a2c019SBarry Smith } 2277182d2002SSatish Balay newmat = *B; 2278182d2002SSatish Balay } else { 22790754003eSLois Curfman McInnes /* Create and fill new matrix */ 22809566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &newmat)); 22819566063dSJacob Faibussowitsch PetscCall(MatSetSizes(newmat, nrows, ncols, nrows, ncols)); 22829566063dSJacob Faibussowitsch PetscCall(MatSetType(newmat, ((PetscObject)A)->type_name)); 22839566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(newmat, NULL)); 2284182d2002SSatish Balay } 2285182d2002SSatish Balay 2286182d2002SSatish Balay /* Now extract the data pointers and do the copy,column at a time */ 22879566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(newmat, &bv)); 22889566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(newmat, &ldb)); 2289182d2002SSatish Balay for (i = 0; i < ncols; i++) { 22906de62eeeSBarry Smith av = v + mat->lda * icol[i]; 2291ca15aa20SStefano Zampini for (j = 0; j < nrows; j++) bv[j] = av[irow[j]]; 2292bf5a80bcSToby Isaac bv += ldb; 22930754003eSLois Curfman McInnes } 22949566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(newmat, &bv)); 2295182d2002SSatish Balay 2296182d2002SSatish Balay /* Assemble the matrices so that the correct flags are set */ 22979566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(newmat, MAT_FINAL_ASSEMBLY)); 22989566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(newmat, MAT_FINAL_ASSEMBLY)); 22990754003eSLois Curfman McInnes 23000754003eSLois Curfman McInnes /* Free work space */ 23019566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(isrow, &irow)); 23029566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(iscol, &icol)); 2303182d2002SSatish Balay *B = newmat; 23043a40ed3dSBarry Smith PetscFunctionReturn(0); 23050754003eSLois Curfman McInnes } 23060754003eSLois Curfman McInnes 23079371c9d4SSatish Balay static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A, PetscInt n, const IS irow[], const IS icol[], MatReuse scall, Mat *B[]) { 230813f74950SBarry Smith PetscInt i; 2309905e6a2fSBarry Smith 23103a40ed3dSBarry Smith PetscFunctionBegin; 231148a46eb9SPierre Jolivet if (scall == MAT_INITIAL_MATRIX) PetscCall(PetscCalloc1(n, B)); 2312905e6a2fSBarry Smith 231348a46eb9SPierre Jolivet for (i = 0; i < n; i++) PetscCall(MatCreateSubMatrix_SeqDense(A, irow[i], icol[i], scall, &(*B)[i])); 23143a40ed3dSBarry Smith PetscFunctionReturn(0); 2315905e6a2fSBarry Smith } 2316905e6a2fSBarry Smith 23179371c9d4SSatish Balay static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat, MatAssemblyType mode) { 2318c0aa2d19SHong Zhang PetscFunctionBegin; 2319c0aa2d19SHong Zhang PetscFunctionReturn(0); 2320c0aa2d19SHong Zhang } 2321c0aa2d19SHong Zhang 23229371c9d4SSatish Balay static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat, MatAssemblyType mode) { 2323c0aa2d19SHong Zhang PetscFunctionBegin; 2324c0aa2d19SHong Zhang PetscFunctionReturn(0); 2325c0aa2d19SHong Zhang } 2326c0aa2d19SHong Zhang 23279371c9d4SSatish Balay PetscErrorCode MatCopy_SeqDense(Mat A, Mat B, MatStructure str) { 23284b0e389bSBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data; 2329ca15aa20SStefano Zampini const PetscScalar *va; 2330ca15aa20SStefano Zampini PetscScalar *vb; 2331d0f46423SBarry Smith PetscInt lda1 = a->lda, lda2 = b->lda, m = A->rmap->n, n = A->cmap->n, j; 23323a40ed3dSBarry Smith 23333a40ed3dSBarry Smith PetscFunctionBegin; 233433f4a19fSKris Buschelman /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */ 233533f4a19fSKris Buschelman if (A->ops->copy != B->ops->copy) { 23369566063dSJacob Faibussowitsch PetscCall(MatCopy_Basic(A, B, str)); 23373a40ed3dSBarry Smith PetscFunctionReturn(0); 23383a40ed3dSBarry Smith } 2339aed4548fSBarry Smith PetscCheck(m == B->rmap->n && n == B->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "size(B) != size(A)"); 23409566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &va)); 23419566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(B, &vb)); 2342a5ce6ee0Svictorle if (lda1 > m || lda2 > m) { 234348a46eb9SPierre Jolivet for (j = 0; j < n; j++) PetscCall(PetscArraycpy(vb + j * lda2, va + j * lda1, m)); 2344a5ce6ee0Svictorle } else { 23459566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(vb, va, A->rmap->n * A->cmap->n)); 2346a5ce6ee0Svictorle } 23479566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(B, &vb)); 23489566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &va)); 23499566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 23509566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 2351273d9f13SBarry Smith PetscFunctionReturn(0); 2352273d9f13SBarry Smith } 2353273d9f13SBarry Smith 23549371c9d4SSatish Balay PetscErrorCode MatSetUp_SeqDense(Mat A) { 2355273d9f13SBarry Smith PetscFunctionBegin; 23569566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 23579566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 235848a46eb9SPierre Jolivet if (!A->preallocated) PetscCall(MatSeqDenseSetPreallocation(A, NULL)); 23593a40ed3dSBarry Smith PetscFunctionReturn(0); 23604b0e389bSBarry Smith } 23614b0e389bSBarry Smith 23629371c9d4SSatish Balay static PetscErrorCode MatConjugate_SeqDense(Mat A) { 23634396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 236406c5243aSJose E. Roman PetscInt i, j; 23654396437dSToby Isaac PetscInt min = PetscMin(A->rmap->n, A->cmap->n); 2366ca15aa20SStefano Zampini PetscScalar *aa; 2367ba337c44SJed Brown 2368ba337c44SJed Brown PetscFunctionBegin; 23699566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 237006c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 237106c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscConj(aa[i + j * mat->lda]); 237206c5243aSJose E. Roman } 23739566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 23749371c9d4SSatish Balay if (mat->tau) 23759371c9d4SSatish Balay for (i = 0; i < min; i++) mat->tau[i] = PetscConj(mat->tau[i]); 2376ba337c44SJed Brown PetscFunctionReturn(0); 2377ba337c44SJed Brown } 2378ba337c44SJed Brown 23799371c9d4SSatish Balay static PetscErrorCode MatRealPart_SeqDense(Mat A) { 238006c5243aSJose E. Roman Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 238106c5243aSJose E. Roman PetscInt i, j; 2382ca15aa20SStefano Zampini PetscScalar *aa; 2383ba337c44SJed Brown 2384ba337c44SJed Brown PetscFunctionBegin; 23859566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 238606c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 238706c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscRealPart(aa[i + j * mat->lda]); 238806c5243aSJose E. Roman } 23899566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 2390ba337c44SJed Brown PetscFunctionReturn(0); 2391ba337c44SJed Brown } 2392ba337c44SJed Brown 23939371c9d4SSatish Balay static PetscErrorCode MatImaginaryPart_SeqDense(Mat A) { 239406c5243aSJose E. Roman Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 239506c5243aSJose E. Roman PetscInt i, j; 2396ca15aa20SStefano Zampini PetscScalar *aa; 2397ba337c44SJed Brown 2398ba337c44SJed Brown PetscFunctionBegin; 23999566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 240006c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 240106c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscImaginaryPart(aa[i + j * mat->lda]); 240206c5243aSJose E. Roman } 24039566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 2404ba337c44SJed Brown PetscFunctionReturn(0); 2405ba337c44SJed Brown } 2406284134d9SBarry Smith 2407a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/ 24089371c9d4SSatish Balay PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) { 2409d0f46423SBarry Smith PetscInt m = A->rmap->n, n = B->cmap->n; 24107a3c3d58SStefano Zampini PetscBool cisdense; 2411a9fe9ddaSSatish Balay 2412ee16a9a1SHong Zhang PetscFunctionBegin; 24139566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 24149566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 24157a3c3d58SStefano Zampini if (!cisdense) { 24167a3c3d58SStefano Zampini PetscBool flg; 24177a3c3d58SStefano Zampini 24189566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 24199566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 24207a3c3d58SStefano Zampini } 24219566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 2422ee16a9a1SHong Zhang PetscFunctionReturn(0); 2423ee16a9a1SHong Zhang } 2424a9fe9ddaSSatish Balay 24259371c9d4SSatish Balay PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) { 24266718818eSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data, *c = (Mat_SeqDense *)C->data; 24270805154bSBarry Smith PetscBLASInt m, n, k; 2428ca15aa20SStefano Zampini const PetscScalar *av, *bv; 2429ca15aa20SStefano Zampini PetscScalar *cv; 2430a9fe9ddaSSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 2431a9fe9ddaSSatish Balay 2432a9fe9ddaSSatish Balay PetscFunctionBegin; 24339566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 24349566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 24359566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 243649d0e964SStefano Zampini if (!m || !n || !k) PetscFunctionReturn(0); 24379566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 24389566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 24399566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2440792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("N", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 24419566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 24429566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 24439566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 24449566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 2445a9fe9ddaSSatish Balay PetscFunctionReturn(0); 2446a9fe9ddaSSatish Balay } 2447a9fe9ddaSSatish Balay 24489371c9d4SSatish Balay PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) { 244969f65d41SStefano Zampini PetscInt m = A->rmap->n, n = B->rmap->n; 24507a3c3d58SStefano Zampini PetscBool cisdense; 245169f65d41SStefano Zampini 245269f65d41SStefano Zampini PetscFunctionBegin; 24539566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 24549566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 24557a3c3d58SStefano Zampini if (!cisdense) { 24567a3c3d58SStefano Zampini PetscBool flg; 24577a3c3d58SStefano Zampini 24589566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 24599566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 24607a3c3d58SStefano Zampini } 24619566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 246269f65d41SStefano Zampini PetscFunctionReturn(0); 246369f65d41SStefano Zampini } 246469f65d41SStefano Zampini 24659371c9d4SSatish Balay PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) { 246669f65d41SStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 246769f65d41SStefano Zampini Mat_SeqDense *b = (Mat_SeqDense *)B->data; 246869f65d41SStefano Zampini Mat_SeqDense *c = (Mat_SeqDense *)C->data; 24696718818eSStefano Zampini const PetscScalar *av, *bv; 24706718818eSStefano Zampini PetscScalar *cv; 247169f65d41SStefano Zampini PetscBLASInt m, n, k; 247269f65d41SStefano Zampini PetscScalar _DOne = 1.0, _DZero = 0.0; 247369f65d41SStefano Zampini 247469f65d41SStefano Zampini PetscFunctionBegin; 24759566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 24769566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 24779566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 247849d0e964SStefano Zampini if (!m || !n || !k) PetscFunctionReturn(0); 24799566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 24809566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 24819566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2482792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("N", "T", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 24839566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 24849566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 24859566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 24869566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 248769f65d41SStefano Zampini PetscFunctionReturn(0); 248869f65d41SStefano Zampini } 248969f65d41SStefano Zampini 24909371c9d4SSatish Balay PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) { 2491d0f46423SBarry Smith PetscInt m = A->cmap->n, n = B->cmap->n; 24927a3c3d58SStefano Zampini PetscBool cisdense; 2493a9fe9ddaSSatish Balay 2494ee16a9a1SHong Zhang PetscFunctionBegin; 24959566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 24969566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 24977a3c3d58SStefano Zampini if (!cisdense) { 24987a3c3d58SStefano Zampini PetscBool flg; 24997a3c3d58SStefano Zampini 25009566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 25019566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 25027a3c3d58SStefano Zampini } 25039566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 2504ee16a9a1SHong Zhang PetscFunctionReturn(0); 2505ee16a9a1SHong Zhang } 2506a9fe9ddaSSatish Balay 25079371c9d4SSatish Balay PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) { 2508a9fe9ddaSSatish Balay Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2509a9fe9ddaSSatish Balay Mat_SeqDense *b = (Mat_SeqDense *)B->data; 2510a9fe9ddaSSatish Balay Mat_SeqDense *c = (Mat_SeqDense *)C->data; 25116718818eSStefano Zampini const PetscScalar *av, *bv; 25126718818eSStefano Zampini PetscScalar *cv; 25130805154bSBarry Smith PetscBLASInt m, n, k; 2514a9fe9ddaSSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 2515a9fe9ddaSSatish Balay 2516a9fe9ddaSSatish Balay PetscFunctionBegin; 25179566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 25189566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 25199566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &k)); 252049d0e964SStefano Zampini if (!m || !n || !k) PetscFunctionReturn(0); 25219566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 25229566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 25239566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2524792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("T", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 25259566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 25269566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 25279566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 25289566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 2529a9fe9ddaSSatish Balay PetscFunctionReturn(0); 2530a9fe9ddaSSatish Balay } 2531985db425SBarry Smith 25324222ddf1SHong Zhang /* ----------------------------------------------- */ 25339371c9d4SSatish Balay static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C) { 25344222ddf1SHong Zhang PetscFunctionBegin; 25354222ddf1SHong Zhang C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense; 25364222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AB; 25374222ddf1SHong Zhang PetscFunctionReturn(0); 25384222ddf1SHong Zhang } 25394222ddf1SHong Zhang 25409371c9d4SSatish Balay static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C) { 25414222ddf1SHong Zhang PetscFunctionBegin; 25424222ddf1SHong Zhang C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense; 25434222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AtB; 25444222ddf1SHong Zhang PetscFunctionReturn(0); 25454222ddf1SHong Zhang } 25464222ddf1SHong Zhang 25479371c9d4SSatish Balay static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C) { 25484222ddf1SHong Zhang PetscFunctionBegin; 25494222ddf1SHong Zhang C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense; 25504222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_ABt; 25514222ddf1SHong Zhang PetscFunctionReturn(0); 25524222ddf1SHong Zhang } 25534222ddf1SHong Zhang 25549371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C) { 25554222ddf1SHong Zhang Mat_Product *product = C->product; 25564222ddf1SHong Zhang 25574222ddf1SHong Zhang PetscFunctionBegin; 25584222ddf1SHong Zhang switch (product->type) { 25599371c9d4SSatish Balay case MATPRODUCT_AB: PetscCall(MatProductSetFromOptions_SeqDense_AB(C)); break; 25609371c9d4SSatish Balay case MATPRODUCT_AtB: PetscCall(MatProductSetFromOptions_SeqDense_AtB(C)); break; 25619371c9d4SSatish Balay case MATPRODUCT_ABt: PetscCall(MatProductSetFromOptions_SeqDense_ABt(C)); break; 25629371c9d4SSatish Balay default: break; 25634222ddf1SHong Zhang } 25644222ddf1SHong Zhang PetscFunctionReturn(0); 25654222ddf1SHong Zhang } 25664222ddf1SHong Zhang /* ----------------------------------------------- */ 25674222ddf1SHong Zhang 25689371c9d4SSatish Balay static PetscErrorCode MatGetRowMax_SeqDense(Mat A, Vec v, PetscInt idx[]) { 2569985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2570d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2571985db425SBarry Smith PetscScalar *x; 2572ca15aa20SStefano Zampini const PetscScalar *aa; 2573985db425SBarry Smith 2574985db425SBarry Smith PetscFunctionBegin; 257528b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 25769566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 25779566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 25789566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 257908401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2580985db425SBarry Smith for (i = 0; i < m; i++) { 25819371c9d4SSatish Balay x[i] = aa[i]; 25829371c9d4SSatish Balay if (idx) idx[i] = 0; 2583985db425SBarry Smith for (j = 1; j < n; j++) { 25849371c9d4SSatish Balay if (PetscRealPart(x[i]) < PetscRealPart(aa[i + a->lda * j])) { 25859371c9d4SSatish Balay x[i] = aa[i + a->lda * j]; 25869371c9d4SSatish Balay if (idx) idx[i] = j; 25879371c9d4SSatish Balay } 2588985db425SBarry Smith } 2589985db425SBarry Smith } 25909566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 25919566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 2592985db425SBarry Smith PetscFunctionReturn(0); 2593985db425SBarry Smith } 2594985db425SBarry Smith 25959371c9d4SSatish Balay static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A, Vec v, PetscInt idx[]) { 2596985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2597d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2598985db425SBarry Smith PetscScalar *x; 2599985db425SBarry Smith PetscReal atmp; 2600ca15aa20SStefano Zampini const PetscScalar *aa; 2601985db425SBarry Smith 2602985db425SBarry Smith PetscFunctionBegin; 260328b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 26049566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 26059566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 26069566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 260708401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2608985db425SBarry Smith for (i = 0; i < m; i++) { 26099189402eSHong Zhang x[i] = PetscAbsScalar(aa[i]); 2610985db425SBarry Smith for (j = 1; j < n; j++) { 2611ca15aa20SStefano Zampini atmp = PetscAbsScalar(aa[i + a->lda * j]); 26129371c9d4SSatish Balay if (PetscAbsScalar(x[i]) < atmp) { 26139371c9d4SSatish Balay x[i] = atmp; 26149371c9d4SSatish Balay if (idx) idx[i] = j; 26159371c9d4SSatish Balay } 2616985db425SBarry Smith } 2617985db425SBarry Smith } 26189566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 26199566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 2620985db425SBarry Smith PetscFunctionReturn(0); 2621985db425SBarry Smith } 2622985db425SBarry Smith 26239371c9d4SSatish Balay static PetscErrorCode MatGetRowMin_SeqDense(Mat A, Vec v, PetscInt idx[]) { 2624985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2625d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2626985db425SBarry Smith PetscScalar *x; 2627ca15aa20SStefano Zampini const PetscScalar *aa; 2628985db425SBarry Smith 2629985db425SBarry Smith PetscFunctionBegin; 263028b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 26319566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 26329566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 26339566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 263408401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2635985db425SBarry Smith for (i = 0; i < m; i++) { 26369371c9d4SSatish Balay x[i] = aa[i]; 26379371c9d4SSatish Balay if (idx) idx[i] = 0; 2638985db425SBarry Smith for (j = 1; j < n; j++) { 26399371c9d4SSatish Balay if (PetscRealPart(x[i]) > PetscRealPart(aa[i + a->lda * j])) { 26409371c9d4SSatish Balay x[i] = aa[i + a->lda * j]; 26419371c9d4SSatish Balay if (idx) idx[i] = j; 26429371c9d4SSatish Balay } 2643985db425SBarry Smith } 2644985db425SBarry Smith } 26459566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 26469566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 2647985db425SBarry Smith PetscFunctionReturn(0); 2648985db425SBarry Smith } 2649985db425SBarry Smith 26509371c9d4SSatish Balay PetscErrorCode MatGetColumnVector_SeqDense(Mat A, Vec v, PetscInt col) { 26518d0534beSBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 26528d0534beSBarry Smith PetscScalar *x; 2653ca15aa20SStefano Zampini const PetscScalar *aa; 26548d0534beSBarry Smith 26558d0534beSBarry Smith PetscFunctionBegin; 265628b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 26579566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 26589566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 26599566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(x, aa + col * a->lda, A->rmap->n)); 26609566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 26619566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 26628d0534beSBarry Smith PetscFunctionReturn(0); 26638d0534beSBarry Smith } 26648d0534beSBarry Smith 26659371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatGetColumnReductions_SeqDense(Mat A, PetscInt type, PetscReal *reductions) { 26660716a85fSBarry Smith PetscInt i, j, m, n; 26671683a169SBarry Smith const PetscScalar *a; 26680716a85fSBarry Smith 26690716a85fSBarry Smith PetscFunctionBegin; 26709566063dSJacob Faibussowitsch PetscCall(MatGetSize(A, &m, &n)); 26719566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(reductions, n)); 26729566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &a)); 2673857cbf51SRichard Tran Mills if (type == NORM_2) { 26740716a85fSBarry Smith for (i = 0; i < n; i++) { 2675ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j] * a[j]); 26760716a85fSBarry Smith a += m; 26770716a85fSBarry Smith } 2678857cbf51SRichard Tran Mills } else if (type == NORM_1) { 26790716a85fSBarry Smith for (i = 0; i < n; i++) { 2680ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j]); 26810716a85fSBarry Smith a += m; 26820716a85fSBarry Smith } 2683857cbf51SRichard Tran Mills } else if (type == NORM_INFINITY) { 26840716a85fSBarry Smith for (i = 0; i < n; i++) { 2685ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] = PetscMax(PetscAbsScalar(a[j]), reductions[i]); 26860716a85fSBarry Smith a += m; 26870716a85fSBarry Smith } 2688857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_REALPART || type == REDUCTION_MEAN_REALPART) { 2689a873a8cdSSam Reynolds for (i = 0; i < n; i++) { 2690ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscRealPart(a[j]); 2691a873a8cdSSam Reynolds a += m; 2692a873a8cdSSam Reynolds } 2693857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_IMAGINARYPART || type == REDUCTION_MEAN_IMAGINARYPART) { 2694857cbf51SRichard Tran Mills for (i = 0; i < n; i++) { 2695ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscImaginaryPart(a[j]); 2696857cbf51SRichard Tran Mills a += m; 2697857cbf51SRichard Tran Mills } 2698857cbf51SRichard Tran Mills } else SETERRQ(PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Unknown reduction type"); 26999566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &a)); 2700857cbf51SRichard Tran Mills if (type == NORM_2) { 2701a873a8cdSSam Reynolds for (i = 0; i < n; i++) reductions[i] = PetscSqrtReal(reductions[i]); 2702857cbf51SRichard Tran Mills } else if (type == REDUCTION_MEAN_REALPART || type == REDUCTION_MEAN_IMAGINARYPART) { 2703a873a8cdSSam Reynolds for (i = 0; i < n; i++) reductions[i] /= m; 27040716a85fSBarry Smith } 27050716a85fSBarry Smith PetscFunctionReturn(0); 27060716a85fSBarry Smith } 27070716a85fSBarry Smith 2708*3faff063SStefano Zampini PetscErrorCode MatSetRandom_SeqDense(Mat x, PetscRandom rctx) { 270973a71a0fSBarry Smith PetscScalar *a; 2710637a0070SStefano Zampini PetscInt lda, m, n, i, j; 271173a71a0fSBarry Smith 271273a71a0fSBarry Smith PetscFunctionBegin; 27139566063dSJacob Faibussowitsch PetscCall(MatGetSize(x, &m, &n)); 27149566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(x, &lda)); 2715*3faff063SStefano Zampini PetscCall(MatDenseGetArrayWrite(x, &a)); 2716637a0070SStefano Zampini for (j = 0; j < n; j++) { 271748a46eb9SPierre Jolivet for (i = 0; i < m; i++) PetscCall(PetscRandomGetValue(rctx, a + j * lda + i)); 271873a71a0fSBarry Smith } 2719*3faff063SStefano Zampini PetscCall(MatDenseRestoreArrayWrite(x, &a)); 272073a71a0fSBarry Smith PetscFunctionReturn(0); 272173a71a0fSBarry Smith } 272273a71a0fSBarry Smith 27239371c9d4SSatish Balay static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A, PetscBool *missing, PetscInt *d) { 27243b49f96aSBarry Smith PetscFunctionBegin; 27253b49f96aSBarry Smith *missing = PETSC_FALSE; 27263b49f96aSBarry Smith PetscFunctionReturn(0); 27273b49f96aSBarry Smith } 272873a71a0fSBarry Smith 2729ca15aa20SStefano Zampini /* vals is not const */ 27309371c9d4SSatish Balay static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A, PetscInt col, PetscScalar **vals) { 273186aefd0dSHong Zhang Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2732ca15aa20SStefano Zampini PetscScalar *v; 273386aefd0dSHong Zhang 273486aefd0dSHong Zhang PetscFunctionBegin; 273528b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 27369566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 2737ca15aa20SStefano Zampini *vals = v + col * a->lda; 27389566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 273986aefd0dSHong Zhang PetscFunctionReturn(0); 274086aefd0dSHong Zhang } 274186aefd0dSHong Zhang 27429371c9d4SSatish Balay static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A, PetscScalar **vals) { 274386aefd0dSHong Zhang PetscFunctionBegin; 2744742765d3SMatthew Knepley if (vals) *vals = NULL; /* user cannot accidentally use the array later */ 274586aefd0dSHong Zhang PetscFunctionReturn(0); 274686aefd0dSHong Zhang } 2747abc3b08eSStefano Zampini 2748289bc588SBarry Smith /* -------------------------------------------------------------------*/ 2749a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqDense, 2750905e6a2fSBarry Smith MatGetRow_SeqDense, 2751905e6a2fSBarry Smith MatRestoreRow_SeqDense, 2752905e6a2fSBarry Smith MatMult_SeqDense, 275397304618SKris Buschelman /* 4*/ MatMultAdd_SeqDense, 27547c922b88SBarry Smith MatMultTranspose_SeqDense, 27557c922b88SBarry Smith MatMultTransposeAdd_SeqDense, 2756f4259b30SLisandro Dalcin NULL, 2757f4259b30SLisandro Dalcin NULL, 2758f4259b30SLisandro Dalcin NULL, 2759f4259b30SLisandro Dalcin /* 10*/ NULL, 2760905e6a2fSBarry Smith MatLUFactor_SeqDense, 2761905e6a2fSBarry Smith MatCholeskyFactor_SeqDense, 276241f059aeSBarry Smith MatSOR_SeqDense, 2763ec8511deSBarry Smith MatTranspose_SeqDense, 276497304618SKris Buschelman /* 15*/ MatGetInfo_SeqDense, 2765905e6a2fSBarry Smith MatEqual_SeqDense, 2766905e6a2fSBarry Smith MatGetDiagonal_SeqDense, 2767905e6a2fSBarry Smith MatDiagonalScale_SeqDense, 2768905e6a2fSBarry Smith MatNorm_SeqDense, 2769c0aa2d19SHong Zhang /* 20*/ MatAssemblyBegin_SeqDense, 2770c0aa2d19SHong Zhang MatAssemblyEnd_SeqDense, 2771905e6a2fSBarry Smith MatSetOption_SeqDense, 2772905e6a2fSBarry Smith MatZeroEntries_SeqDense, 2773d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqDense, 2774f4259b30SLisandro Dalcin NULL, 2775f4259b30SLisandro Dalcin NULL, 2776f4259b30SLisandro Dalcin NULL, 2777f4259b30SLisandro Dalcin NULL, 27784994cf47SJed Brown /* 29*/ MatSetUp_SeqDense, 2779f4259b30SLisandro Dalcin NULL, 2780f4259b30SLisandro Dalcin NULL, 2781f4259b30SLisandro Dalcin NULL, 2782f4259b30SLisandro Dalcin NULL, 2783d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqDense, 2784f4259b30SLisandro Dalcin NULL, 2785f4259b30SLisandro Dalcin NULL, 2786f4259b30SLisandro Dalcin NULL, 2787f4259b30SLisandro Dalcin NULL, 2788d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqDense, 27897dae84e0SHong Zhang MatCreateSubMatrices_SeqDense, 2790f4259b30SLisandro Dalcin NULL, 27914b0e389bSBarry Smith MatGetValues_SeqDense, 2792a5ae1ecdSBarry Smith MatCopy_SeqDense, 2793d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqDense, 2794a5ae1ecdSBarry Smith MatScale_SeqDense, 27952f605a99SJose E. Roman MatShift_SeqDense, 2796f4259b30SLisandro Dalcin NULL, 27973f49a652SStefano Zampini MatZeroRowsColumns_SeqDense, 279873a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqDense, 2799f4259b30SLisandro Dalcin NULL, 2800f4259b30SLisandro Dalcin NULL, 2801f4259b30SLisandro Dalcin NULL, 2802f4259b30SLisandro Dalcin NULL, 2803f4259b30SLisandro Dalcin /* 54*/ NULL, 2804f4259b30SLisandro Dalcin NULL, 2805f4259b30SLisandro Dalcin NULL, 2806f4259b30SLisandro Dalcin NULL, 2807f4259b30SLisandro Dalcin NULL, 2808023c16fcSToby Isaac /* 59*/ MatCreateSubMatrix_SeqDense, 2809e03a110bSBarry Smith MatDestroy_SeqDense, 2810e03a110bSBarry Smith MatView_SeqDense, 2811f4259b30SLisandro Dalcin NULL, 2812f4259b30SLisandro Dalcin NULL, 2813f4259b30SLisandro Dalcin /* 64*/ NULL, 2814f4259b30SLisandro Dalcin NULL, 2815f4259b30SLisandro Dalcin NULL, 2816f4259b30SLisandro Dalcin NULL, 2817f4259b30SLisandro Dalcin NULL, 2818d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqDense, 2819f4259b30SLisandro Dalcin NULL, 2820f4259b30SLisandro Dalcin NULL, 2821f4259b30SLisandro Dalcin NULL, 2822f4259b30SLisandro Dalcin NULL, 2823f4259b30SLisandro Dalcin /* 74*/ NULL, 2824f4259b30SLisandro Dalcin NULL, 2825f4259b30SLisandro Dalcin NULL, 2826f4259b30SLisandro Dalcin NULL, 2827f4259b30SLisandro Dalcin NULL, 2828f4259b30SLisandro Dalcin /* 79*/ NULL, 2829f4259b30SLisandro Dalcin NULL, 2830f4259b30SLisandro Dalcin NULL, 2831f4259b30SLisandro Dalcin NULL, 28325bba2384SShri Abhyankar /* 83*/ MatLoad_SeqDense, 2833637a0070SStefano Zampini MatIsSymmetric_SeqDense, 28341cbb95d3SBarry Smith MatIsHermitian_SeqDense, 2835f4259b30SLisandro Dalcin NULL, 2836f4259b30SLisandro Dalcin NULL, 2837f4259b30SLisandro Dalcin NULL, 2838f4259b30SLisandro Dalcin /* 89*/ NULL, 2839f4259b30SLisandro Dalcin NULL, 2840a9fe9ddaSSatish Balay MatMatMultNumeric_SeqDense_SeqDense, 2841f4259b30SLisandro Dalcin NULL, 2842f4259b30SLisandro Dalcin NULL, 2843f4259b30SLisandro Dalcin /* 94*/ NULL, 2844f4259b30SLisandro Dalcin NULL, 2845f4259b30SLisandro Dalcin NULL, 284669f65d41SStefano Zampini MatMatTransposeMultNumeric_SeqDense_SeqDense, 2847f4259b30SLisandro Dalcin NULL, 28484222ddf1SHong Zhang /* 99*/ MatProductSetFromOptions_SeqDense, 2849f4259b30SLisandro Dalcin NULL, 2850f4259b30SLisandro Dalcin NULL, 2851ba337c44SJed Brown MatConjugate_SeqDense, 2852f4259b30SLisandro Dalcin NULL, 2853f4259b30SLisandro Dalcin /*104*/ NULL, 2854ba337c44SJed Brown MatRealPart_SeqDense, 2855ba337c44SJed Brown MatImaginaryPart_SeqDense, 2856f4259b30SLisandro Dalcin NULL, 2857f4259b30SLisandro Dalcin NULL, 2858f4259b30SLisandro Dalcin /*109*/ NULL, 2859f4259b30SLisandro Dalcin NULL, 28608d0534beSBarry Smith MatGetRowMin_SeqDense, 2861aabbc4fbSShri Abhyankar MatGetColumnVector_SeqDense, 28623b49f96aSBarry Smith MatMissingDiagonal_SeqDense, 2863f4259b30SLisandro Dalcin /*114*/ NULL, 2864f4259b30SLisandro Dalcin NULL, 2865f4259b30SLisandro Dalcin NULL, 2866f4259b30SLisandro Dalcin NULL, 2867f4259b30SLisandro Dalcin NULL, 2868f4259b30SLisandro Dalcin /*119*/ NULL, 2869f4259b30SLisandro Dalcin NULL, 2870f4259b30SLisandro Dalcin NULL, 2871f4259b30SLisandro Dalcin NULL, 2872f4259b30SLisandro Dalcin NULL, 2873f4259b30SLisandro Dalcin /*124*/ NULL, 2874a873a8cdSSam Reynolds MatGetColumnReductions_SeqDense, 2875f4259b30SLisandro Dalcin NULL, 2876f4259b30SLisandro Dalcin NULL, 2877f4259b30SLisandro Dalcin NULL, 2878f4259b30SLisandro Dalcin /*129*/ NULL, 2879f4259b30SLisandro Dalcin NULL, 2880f4259b30SLisandro Dalcin NULL, 288175648e8dSHong Zhang MatTransposeMatMultNumeric_SeqDense_SeqDense, 2882f4259b30SLisandro Dalcin NULL, 2883f4259b30SLisandro Dalcin /*134*/ NULL, 2884f4259b30SLisandro Dalcin NULL, 2885f4259b30SLisandro Dalcin NULL, 2886f4259b30SLisandro Dalcin NULL, 2887f4259b30SLisandro Dalcin NULL, 2888f4259b30SLisandro Dalcin /*139*/ NULL, 2889f4259b30SLisandro Dalcin NULL, 2890f4259b30SLisandro Dalcin NULL, 2891f4259b30SLisandro Dalcin NULL, 2892f4259b30SLisandro Dalcin NULL, 28934222ddf1SHong Zhang MatCreateMPIMatConcatenateSeqMat_SeqDense, 2894f4259b30SLisandro Dalcin /*145*/ NULL, 2895f4259b30SLisandro Dalcin NULL, 289699a7f59eSMark Adams NULL, 289799a7f59eSMark Adams NULL, 28987fb60732SBarry Smith NULL, 28999371c9d4SSatish Balay /*150*/ NULL}; 290090ace30eSBarry Smith 29014b828684SBarry Smith /*@C 290211a5261eSBarry Smith MatCreateSeqDense - Creates a `MATSEQDENSE` that 2903d65003e9SLois Curfman McInnes is stored in column major order (the usual Fortran 77 manner). Many 2904d65003e9SLois Curfman McInnes of the matrix operations use the BLAS and LAPACK routines. 2905289bc588SBarry Smith 2906d083f849SBarry Smith Collective 2907db81eaa0SLois Curfman McInnes 290820563c6bSBarry Smith Input Parameters: 290911a5261eSBarry Smith + comm - MPI communicator, set to `PETSC_COMM_SELF` 29100c775827SLois Curfman McInnes . m - number of rows 291118f449edSLois Curfman McInnes . n - number of columns 29120298fd71SBarry Smith - data - optional location of matrix data in column major order. Set data=NULL for PETSc 2913dfc5480cSLois Curfman McInnes to control all matrix memory allocation. 291420563c6bSBarry Smith 291520563c6bSBarry Smith Output Parameter: 291644cd7ae7SLois Curfman McInnes . A - the matrix 291720563c6bSBarry Smith 291811a5261eSBarry Smith Note: 291918f449edSLois Curfman McInnes The data input variable is intended primarily for Fortran programmers 292018f449edSLois Curfman McInnes who wish to allocate their own matrix memory space. Most users should 29210298fd71SBarry Smith set data=NULL. 292218f449edSLois Curfman McInnes 2923027ccd11SLois Curfman McInnes Level: intermediate 2924027ccd11SLois Curfman McInnes 292511a5261eSBarry Smith .seealso: `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()` 292620563c6bSBarry Smith @*/ 29279371c9d4SSatish Balay PetscErrorCode MatCreateSeqDense(MPI_Comm comm, PetscInt m, PetscInt n, PetscScalar *data, Mat *A) { 29283a40ed3dSBarry Smith PetscFunctionBegin; 29299566063dSJacob Faibussowitsch PetscCall(MatCreate(comm, A)); 29309566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*A, m, n, m, n)); 29319566063dSJacob Faibussowitsch PetscCall(MatSetType(*A, MATSEQDENSE)); 29329566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(*A, data)); 2933273d9f13SBarry Smith PetscFunctionReturn(0); 2934273d9f13SBarry Smith } 2935273d9f13SBarry Smith 2936273d9f13SBarry Smith /*@C 293711a5261eSBarry Smith MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements of a `MATSEQDENSE` matrix 2938273d9f13SBarry Smith 2939d083f849SBarry Smith Collective 2940273d9f13SBarry Smith 2941273d9f13SBarry Smith Input Parameters: 29421c4f3114SJed Brown + B - the matrix 29430298fd71SBarry Smith - data - the array (or NULL) 2944273d9f13SBarry Smith 294511a5261eSBarry Smith Note: 2946273d9f13SBarry Smith The data input variable is intended primarily for Fortran programmers 2947273d9f13SBarry Smith who wish to allocate their own matrix memory space. Most users should 2948284134d9SBarry Smith need not call this routine. 2949273d9f13SBarry Smith 2950273d9f13SBarry Smith Level: intermediate 2951273d9f13SBarry Smith 295211a5261eSBarry Smith .seealso: `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()`, `MatDenseSetLDA()` 2953273d9f13SBarry Smith @*/ 29549371c9d4SSatish Balay PetscErrorCode MatSeqDenseSetPreallocation(Mat B, PetscScalar data[]) { 2955a23d5eceSKris Buschelman PetscFunctionBegin; 2956d5ea218eSStefano Zampini PetscValidHeaderSpecific(B, MAT_CLASSID, 1); 2957cac4c232SBarry Smith PetscTryMethod(B, "MatSeqDenseSetPreallocation_C", (Mat, PetscScalar[]), (B, data)); 2958a23d5eceSKris Buschelman PetscFunctionReturn(0); 2959a23d5eceSKris Buschelman } 2960a23d5eceSKris Buschelman 29619371c9d4SSatish Balay PetscErrorCode MatSeqDenseSetPreallocation_SeqDense(Mat B, PetscScalar *data) { 2962ad16ce7aSStefano Zampini Mat_SeqDense *b = (Mat_SeqDense *)B->data; 2963273d9f13SBarry Smith 2964273d9f13SBarry Smith PetscFunctionBegin; 296528b400f6SJacob Faibussowitsch PetscCheck(!b->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 2966273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 2967a868139aSShri Abhyankar 29689566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(B->rmap)); 29699566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(B->cmap)); 297034ef9618SShri Abhyankar 2971ad16ce7aSStefano Zampini if (b->lda <= 0) b->lda = B->rmap->n; 297286d161a7SShri Abhyankar 29739e8f95c4SLisandro Dalcin if (!data) { /* petsc-allocated storage */ 29749566063dSJacob Faibussowitsch if (!b->user_alloc) PetscCall(PetscFree(b->v)); 29759566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((size_t)b->lda * B->cmap->n, &b->v)); 29769566063dSJacob Faibussowitsch PetscCall(PetscLogObjectMemory((PetscObject)B, b->lda * B->cmap->n * sizeof(PetscScalar))); 29772205254eSKarl Rupp 29789e8f95c4SLisandro Dalcin b->user_alloc = PETSC_FALSE; 2979273d9f13SBarry Smith } else { /* user-allocated storage */ 29809566063dSJacob Faibussowitsch if (!b->user_alloc) PetscCall(PetscFree(b->v)); 2981273d9f13SBarry Smith b->v = data; 2982273d9f13SBarry Smith b->user_alloc = PETSC_TRUE; 2983273d9f13SBarry Smith } 29840450473dSBarry Smith B->assembled = PETSC_TRUE; 2985273d9f13SBarry Smith PetscFunctionReturn(0); 2986273d9f13SBarry Smith } 2987273d9f13SBarry Smith 298865b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 29899371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) { 2990d77f618aSHong Zhang Mat mat_elemental; 29911683a169SBarry Smith const PetscScalar *array; 29921683a169SBarry Smith PetscScalar *v_colwise; 2993d77f618aSHong Zhang PetscInt M = A->rmap->N, N = A->cmap->N, i, j, k, *rows, *cols; 2994d77f618aSHong Zhang 29958baccfbdSHong Zhang PetscFunctionBegin; 29969566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(M * N, &v_colwise, M, &rows, N, &cols)); 29979566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &array)); 2998d77f618aSHong Zhang /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */ 2999d77f618aSHong Zhang k = 0; 3000d77f618aSHong Zhang for (j = 0; j < N; j++) { 3001d77f618aSHong Zhang cols[j] = j; 3002ad540459SPierre Jolivet for (i = 0; i < M; i++) v_colwise[j * M + i] = array[k++]; 3003d77f618aSHong Zhang } 3004ad540459SPierre Jolivet for (i = 0; i < M; i++) rows[i] = i; 30059566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &array)); 3006d77f618aSHong Zhang 30079566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental)); 30089566063dSJacob Faibussowitsch PetscCall(MatSetSizes(mat_elemental, PETSC_DECIDE, PETSC_DECIDE, M, N)); 30099566063dSJacob Faibussowitsch PetscCall(MatSetType(mat_elemental, MATELEMENTAL)); 30109566063dSJacob Faibussowitsch PetscCall(MatSetUp(mat_elemental)); 3011d77f618aSHong Zhang 3012d77f618aSHong Zhang /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */ 30139566063dSJacob Faibussowitsch PetscCall(MatSetValues(mat_elemental, M, rows, N, cols, v_colwise, ADD_VALUES)); 30149566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY)); 30159566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY)); 30169566063dSJacob Faibussowitsch PetscCall(PetscFree3(v_colwise, rows, cols)); 3017d77f618aSHong Zhang 3018511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 30199566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A, &mat_elemental)); 3020d77f618aSHong Zhang } else { 3021d77f618aSHong Zhang *newmat = mat_elemental; 3022d77f618aSHong Zhang } 30238baccfbdSHong Zhang PetscFunctionReturn(0); 30248baccfbdSHong Zhang } 302565b80a83SHong Zhang #endif 30268baccfbdSHong Zhang 30279371c9d4SSatish Balay PetscErrorCode MatDenseSetLDA_SeqDense(Mat B, PetscInt lda) { 30281b807ce4Svictorle Mat_SeqDense *b = (Mat_SeqDense *)B->data; 30297422da62SJose E. Roman PetscBool data; 303021a2c019SBarry Smith 30311b807ce4Svictorle PetscFunctionBegin; 30327422da62SJose E. Roman data = (PetscBool)((B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE); 3033aed4548fSBarry Smith PetscCheck(b->user_alloc || !data || b->lda == lda, PETSC_COMM_SELF, PETSC_ERR_ORDER, "LDA cannot be changed after allocation of internal storage"); 303408401ef6SPierre 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); 30351b807ce4Svictorle b->lda = lda; 30361b807ce4Svictorle PetscFunctionReturn(0); 30371b807ce4Svictorle } 30381b807ce4Svictorle 30399371c9d4SSatish Balay PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm, Mat inmat, PetscInt n, MatReuse scall, Mat *outmat) { 3040d528f656SJakub Kruzik PetscFunctionBegin; 30419566063dSJacob Faibussowitsch PetscCall(MatCreateMPIMatConcatenateSeqMat_MPIDense(comm, inmat, n, scall, outmat)); 3042d528f656SJakub Kruzik PetscFunctionReturn(0); 3043d528f656SJakub Kruzik } 3044d528f656SJakub Kruzik 30459371c9d4SSatish Balay PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A, PetscInt col, Vec *v) { 30466947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 30476947451fSStefano Zampini 30486947451fSStefano Zampini PetscFunctionBegin; 304928b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 305028b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 30516947451fSStefano Zampini if (!a->cvec) { 30529566063dSJacob Faibussowitsch PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec)); 30539566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)A, (PetscObject)a->cvec)); 30546947451fSStefano Zampini } 30556947451fSStefano Zampini a->vecinuse = col + 1; 30569566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, (PetscScalar **)&a->ptrinuse)); 30579566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda)); 30586947451fSStefano Zampini *v = a->cvec; 30596947451fSStefano Zampini PetscFunctionReturn(0); 30606947451fSStefano Zampini } 30616947451fSStefano Zampini 30629371c9d4SSatish Balay PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A, PetscInt col, Vec *v) { 30636947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 30646947451fSStefano Zampini 30656947451fSStefano Zampini PetscFunctionBegin; 306628b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 306728b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 30686947451fSStefano Zampini a->vecinuse = 0; 30699566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, (PetscScalar **)&a->ptrinuse)); 30709566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 307175f6d85dSStefano Zampini if (v) *v = NULL; 30726947451fSStefano Zampini PetscFunctionReturn(0); 30736947451fSStefano Zampini } 30746947451fSStefano Zampini 30759371c9d4SSatish Balay PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v) { 30766947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 30776947451fSStefano Zampini 30786947451fSStefano Zampini PetscFunctionBegin; 307928b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 308028b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 30816947451fSStefano Zampini if (!a->cvec) { 30829566063dSJacob Faibussowitsch PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec)); 30839566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)A, (PetscObject)a->cvec)); 30846947451fSStefano Zampini } 30856947451fSStefano Zampini a->vecinuse = col + 1; 30869566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &a->ptrinuse)); 30879566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda)); 30889566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(a->cvec)); 30896947451fSStefano Zampini *v = a->cvec; 30906947451fSStefano Zampini PetscFunctionReturn(0); 30916947451fSStefano Zampini } 30926947451fSStefano Zampini 30939371c9d4SSatish Balay PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v) { 30946947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 30956947451fSStefano Zampini 30966947451fSStefano Zampini PetscFunctionBegin; 309728b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 309828b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 30996947451fSStefano Zampini a->vecinuse = 0; 31009566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &a->ptrinuse)); 31019566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(a->cvec)); 31029566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 310375f6d85dSStefano Zampini if (v) *v = NULL; 31046947451fSStefano Zampini PetscFunctionReturn(0); 31056947451fSStefano Zampini } 31066947451fSStefano Zampini 31079371c9d4SSatish Balay PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v) { 31086947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 31096947451fSStefano Zampini 31106947451fSStefano Zampini PetscFunctionBegin; 311128b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 311228b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 31136947451fSStefano Zampini if (!a->cvec) { 31149566063dSJacob Faibussowitsch PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec)); 31159566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)A, (PetscObject)a->cvec)); 31166947451fSStefano Zampini } 31176947451fSStefano Zampini a->vecinuse = col + 1; 31189566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(A, (PetscScalar **)&a->ptrinuse)); 31199566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda)); 31206947451fSStefano Zampini *v = a->cvec; 31216947451fSStefano Zampini PetscFunctionReturn(0); 31226947451fSStefano Zampini } 31236947451fSStefano Zampini 31249371c9d4SSatish Balay PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v) { 31256947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 31266947451fSStefano Zampini 31276947451fSStefano Zampini PetscFunctionBegin; 312828b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 312928b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 31306947451fSStefano Zampini a->vecinuse = 0; 31319566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(A, (PetscScalar **)&a->ptrinuse)); 31329566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 313375f6d85dSStefano Zampini if (v) *v = NULL; 31346947451fSStefano Zampini PetscFunctionReturn(0); 31356947451fSStefano Zampini } 31366947451fSStefano Zampini 31379371c9d4SSatish Balay PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) { 31385ea7661aSPierre Jolivet Mat_SeqDense *a = (Mat_SeqDense *)A->data; 31395ea7661aSPierre Jolivet 31405ea7661aSPierre Jolivet PetscFunctionBegin; 314128b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 314228b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3143a2748737SPierre Jolivet if (a->cmat && (cend - cbegin != a->cmat->cmap->N || rend - rbegin != a->cmat->rmap->N)) PetscCall(MatDestroy(&a->cmat)); 31445ea7661aSPierre Jolivet if (!a->cmat) { 3145a2748737SPierre Jolivet PetscCall(MatCreateDense(PetscObjectComm((PetscObject)A), rend - rbegin, PETSC_DECIDE, rend - rbegin, cend - cbegin, a->v + rbegin + (size_t)cbegin * a->lda, &a->cmat)); 31469566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)A, (PetscObject)a->cmat)); 31475ea7661aSPierre Jolivet } else { 3148a2748737SPierre Jolivet PetscCall(MatDensePlaceArray(a->cmat, a->v + rbegin + (size_t)cbegin * a->lda)); 31495ea7661aSPierre Jolivet } 31509566063dSJacob Faibussowitsch PetscCall(MatDenseSetLDA(a->cmat, a->lda)); 31515ea7661aSPierre Jolivet a->matinuse = cbegin + 1; 31525ea7661aSPierre Jolivet *v = a->cmat; 315375f6d85dSStefano Zampini #if defined(PETSC_HAVE_CUDA) 315475f6d85dSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 315575f6d85dSStefano Zampini #endif 31565ea7661aSPierre Jolivet PetscFunctionReturn(0); 31575ea7661aSPierre Jolivet } 31585ea7661aSPierre Jolivet 31599371c9d4SSatish Balay PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A, Mat *v) { 31605ea7661aSPierre Jolivet Mat_SeqDense *a = (Mat_SeqDense *)A->data; 31615ea7661aSPierre Jolivet 31625ea7661aSPierre Jolivet PetscFunctionBegin; 316328b400f6SJacob Faibussowitsch PetscCheck(a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetSubMatrix() first"); 316428b400f6SJacob Faibussowitsch PetscCheck(a->cmat, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column matrix"); 316508401ef6SPierre Jolivet PetscCheck(*v == a->cmat, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not the matrix obtained from MatDenseGetSubMatrix()"); 31665ea7661aSPierre Jolivet a->matinuse = 0; 31679566063dSJacob Faibussowitsch PetscCall(MatDenseResetArray(a->cmat)); 3168742765d3SMatthew Knepley if (v) *v = NULL; 3169*3faff063SStefano Zampini #if defined(PETSC_HAVE_CUDA) 3170*3faff063SStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 3171*3faff063SStefano Zampini #endif 31725ea7661aSPierre Jolivet PetscFunctionReturn(0); 31735ea7661aSPierre Jolivet } 31745ea7661aSPierre Jolivet 31750bad9183SKris Buschelman /*MC 3176fafad747SKris Buschelman MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices. 31770bad9183SKris Buschelman 31780bad9183SKris Buschelman Options Database Keys: 317911a5261eSBarry Smith . -mat_type seqdense - sets the matrix type to `MATSEQDENSE` during a call to `MatSetFromOptions()` 31800bad9183SKris Buschelman 31810bad9183SKris Buschelman Level: beginner 31820bad9183SKris Buschelman 318311a5261eSBarry Smith .seealso: `MATSEQDENSE`, `MatCreateSeqDense()` 31840bad9183SKris Buschelman M*/ 31859371c9d4SSatish Balay PetscErrorCode MatCreate_SeqDense(Mat B) { 3186273d9f13SBarry Smith Mat_SeqDense *b; 31877c334f02SBarry Smith PetscMPIInt size; 3188273d9f13SBarry Smith 3189273d9f13SBarry Smith PetscFunctionBegin; 31909566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)B), &size)); 319108401ef6SPierre Jolivet PetscCheck(size <= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Comm must be of size 1"); 319255659b69SBarry Smith 31939566063dSJacob Faibussowitsch PetscCall(PetscNewLog(B, &b)); 31949566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(B->ops, &MatOps_Values, sizeof(struct _MatOps))); 319544cd7ae7SLois Curfman McInnes B->data = (void *)b; 319618f449edSLois Curfman McInnes 3197273d9f13SBarry Smith b->roworiented = PETSC_TRUE; 31984e220ebcSLois Curfman McInnes 31999566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatQRFactor_C", MatQRFactor_SeqDense)); 32009566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetLDA_C", MatDenseGetLDA_SeqDense)); 32019566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseSetLDA_C", MatDenseSetLDA_SeqDense)); 32029566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArray_C", MatDenseGetArray_SeqDense)); 32039566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArray_C", MatDenseRestoreArray_SeqDense)); 32049566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDensePlaceArray_C", MatDensePlaceArray_SeqDense)); 32059566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseResetArray_C", MatDenseResetArray_SeqDense)); 32069566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseReplaceArray_C", MatDenseReplaceArray_SeqDense)); 32079566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayRead_C", MatDenseGetArray_SeqDense)); 32089566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayRead_C", MatDenseRestoreArray_SeqDense)); 32099566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayWrite_C", MatDenseGetArray_SeqDense)); 32109566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayWrite_C", MatDenseRestoreArray_SeqDense)); 32119566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqaij_C", MatConvert_SeqDense_SeqAIJ)); 32128baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 32139566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_elemental_C", MatConvert_SeqDense_Elemental)); 32148baccfbdSHong Zhang #endif 3215d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 32169566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_scalapack_C", MatConvert_Dense_ScaLAPACK)); 3217d24d4204SJose E. Roman #endif 32182bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA) 32199566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensecuda_C", MatConvert_SeqDense_SeqDenseCUDA)); 32209566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", MatProductSetFromOptions_SeqDense)); 32219566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdense_C", MatProductSetFromOptions_SeqDense)); 32229566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensecuda_C", MatProductSetFromOptions_SeqDense)); 32232bf066beSStefano Zampini #endif 32249566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSeqDenseSetPreallocation_C", MatSeqDenseSetPreallocation_SeqDense)); 32259566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqaij_seqdense_C", MatProductSetFromOptions_SeqAIJ_SeqDense)); 32269566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdense_C", MatProductSetFromOptions_SeqDense)); 32279566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense)); 32289566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqsbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense)); 322996e6d5c4SRichard Tran Mills 32309566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumn_C", MatDenseGetColumn_SeqDense)); 32319566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumn_C", MatDenseRestoreColumn_SeqDense)); 32329566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVec_C", MatDenseGetColumnVec_SeqDense)); 32339566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVec_C", MatDenseRestoreColumnVec_SeqDense)); 32349566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecRead_C", MatDenseGetColumnVecRead_SeqDense)); 32359566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecRead_C", MatDenseRestoreColumnVecRead_SeqDense)); 32369566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecWrite_C", MatDenseGetColumnVecWrite_SeqDense)); 32379566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecWrite_C", MatDenseRestoreColumnVecWrite_SeqDense)); 32389566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetSubMatrix_C", MatDenseGetSubMatrix_SeqDense)); 32399566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreSubMatrix_C", MatDenseRestoreSubMatrix_SeqDense)); 32409566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)B, MATSEQDENSE)); 32413a40ed3dSBarry Smith PetscFunctionReturn(0); 3242289bc588SBarry Smith } 324386aefd0dSHong Zhang 324486aefd0dSHong Zhang /*@C 324511a5261eSBarry 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. 324686aefd0dSHong Zhang 324786aefd0dSHong Zhang Not Collective 324886aefd0dSHong Zhang 32495ea7661aSPierre Jolivet Input Parameters: 325011a5261eSBarry Smith + mat - a `MATSEQDENSE` or `MATMPIDENSE` matrix 325186aefd0dSHong Zhang - col - column index 325286aefd0dSHong Zhang 325386aefd0dSHong Zhang Output Parameter: 325486aefd0dSHong Zhang . vals - pointer to the data 325586aefd0dSHong Zhang 325686aefd0dSHong Zhang Level: intermediate 325786aefd0dSHong Zhang 325811a5261eSBarry Smith Note: 325911a5261eSBarry Smith Use `MatDenseGetColumnVec()` to get access to a column of a `MATDENSE` treated as a `Vec` 326011a5261eSBarry Smith 326111a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreColumn()`, `MatDenseGetColumnVec()` 326286aefd0dSHong Zhang @*/ 32639371c9d4SSatish Balay PetscErrorCode MatDenseGetColumn(Mat A, PetscInt col, PetscScalar **vals) { 326486aefd0dSHong Zhang PetscFunctionBegin; 3265d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3266d5ea218eSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 3267d5ea218eSStefano Zampini PetscValidPointer(vals, 3); 3268cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumn_C", (Mat, PetscInt, PetscScalar **), (A, col, vals)); 326986aefd0dSHong Zhang PetscFunctionReturn(0); 327086aefd0dSHong Zhang } 327186aefd0dSHong Zhang 327286aefd0dSHong Zhang /*@C 327311a5261eSBarry Smith MatDenseRestoreColumn - returns access to a column of a `MATDENSE` matrix which is returned by `MatDenseGetColumn()`. 327486aefd0dSHong Zhang 327586aefd0dSHong Zhang Not Collective 327686aefd0dSHong Zhang 3277742765d3SMatthew Knepley Input Parameters: 327811a5261eSBarry Smith + mat - a `MATSEQDENSE` or `MATMPIDENSE` matrix 3279742765d3SMatthew Knepley - vals - pointer to the data (may be NULL) 328086aefd0dSHong Zhang 328186aefd0dSHong Zhang Level: intermediate 328286aefd0dSHong Zhang 328311a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetColumn()` 328486aefd0dSHong Zhang @*/ 32859371c9d4SSatish Balay PetscErrorCode MatDenseRestoreColumn(Mat A, PetscScalar **vals) { 328686aefd0dSHong Zhang PetscFunctionBegin; 3287d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3288d5ea218eSStefano Zampini PetscValidPointer(vals, 2); 3289cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumn_C", (Mat, PetscScalar **), (A, vals)); 329086aefd0dSHong Zhang PetscFunctionReturn(0); 329186aefd0dSHong Zhang } 32926947451fSStefano Zampini 32930f74d2c1SSatish Balay /*@ 329411a5261eSBarry Smith MatDenseGetColumnVec - Gives read-write access to a column of a `MATDENSE` matrix, represented as a `Vec`. 32956947451fSStefano Zampini 32966947451fSStefano Zampini Collective 32976947451fSStefano Zampini 32985ea7661aSPierre Jolivet Input Parameters: 329911a5261eSBarry Smith + mat - the `Mat` object 33006947451fSStefano Zampini - col - the column index 33016947451fSStefano Zampini 33026947451fSStefano Zampini Output Parameter: 33036947451fSStefano Zampini . v - the vector 33046947451fSStefano Zampini 33056947451fSStefano Zampini Notes: 330611a5261eSBarry Smith The vector is owned by PETSc. Users need to call `MatDenseRestoreColumnVec()` when the vector is no longer needed. 330711a5261eSBarry Smith 330811a5261eSBarry Smith Use `MatDenseGetColumnVecRead()` to obtain read-only access or `MatDenseGetColumnVecWrite()` for write-only access. 33096947451fSStefano Zampini 33106947451fSStefano Zampini Level: intermediate 33116947451fSStefano Zampini 331211a5261eSBarry Smith .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`, `MatDenseGetColumn()` 33136947451fSStefano Zampini @*/ 33149371c9d4SSatish Balay PetscErrorCode MatDenseGetColumnVec(Mat A, PetscInt col, Vec *v) { 33156947451fSStefano Zampini PetscFunctionBegin; 33166947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 33176947451fSStefano Zampini PetscValidType(A, 1); 33186947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 33196947451fSStefano Zampini PetscValidPointer(v, 3); 332028b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 33212cf15c64SPierre 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); 3322cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v)); 33236947451fSStefano Zampini PetscFunctionReturn(0); 33246947451fSStefano Zampini } 33256947451fSStefano Zampini 33260f74d2c1SSatish Balay /*@ 33276947451fSStefano Zampini MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVec(). 33286947451fSStefano Zampini 33296947451fSStefano Zampini Collective 33306947451fSStefano Zampini 33315ea7661aSPierre Jolivet Input Parameters: 33326947451fSStefano Zampini + mat - the Mat object 33336947451fSStefano Zampini . col - the column index 3334742765d3SMatthew Knepley - v - the Vec object (may be NULL) 33356947451fSStefano Zampini 33366947451fSStefano Zampini Level: intermediate 33376947451fSStefano Zampini 3338db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 33396947451fSStefano Zampini @*/ 33409371c9d4SSatish Balay PetscErrorCode MatDenseRestoreColumnVec(Mat A, PetscInt col, Vec *v) { 33416947451fSStefano Zampini PetscFunctionBegin; 33426947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 33436947451fSStefano Zampini PetscValidType(A, 1); 33446947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 334508401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 33462cf15c64SPierre 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); 3347cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v)); 33486947451fSStefano Zampini PetscFunctionReturn(0); 33496947451fSStefano Zampini } 33506947451fSStefano Zampini 33510f74d2c1SSatish Balay /*@ 33526947451fSStefano Zampini MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a Vec. 33536947451fSStefano Zampini 33546947451fSStefano Zampini Collective 33556947451fSStefano Zampini 33565ea7661aSPierre Jolivet Input Parameters: 33576947451fSStefano Zampini + mat - the Mat object 33586947451fSStefano Zampini - col - the column index 33596947451fSStefano Zampini 33606947451fSStefano Zampini Output Parameter: 33616947451fSStefano Zampini . v - the vector 33626947451fSStefano Zampini 33636947451fSStefano Zampini Notes: 33646947451fSStefano Zampini The vector is owned by PETSc and users cannot modify it. 336511a5261eSBarry Smith 33666947451fSStefano Zampini Users need to call MatDenseRestoreColumnVecRead() when the vector is no longer needed. 336711a5261eSBarry Smith 33686947451fSStefano Zampini Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecWrite() for write-only access. 33696947451fSStefano Zampini 33706947451fSStefano Zampini Level: intermediate 33716947451fSStefano Zampini 3372db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 33736947451fSStefano Zampini @*/ 33749371c9d4SSatish Balay PetscErrorCode MatDenseGetColumnVecRead(Mat A, PetscInt col, Vec *v) { 33756947451fSStefano Zampini PetscFunctionBegin; 33766947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 33776947451fSStefano Zampini PetscValidType(A, 1); 33786947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 33796947451fSStefano Zampini PetscValidPointer(v, 3); 338028b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 33812cf15c64SPierre 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); 3382cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v)); 33836947451fSStefano Zampini PetscFunctionReturn(0); 33846947451fSStefano Zampini } 33856947451fSStefano Zampini 33860f74d2c1SSatish Balay /*@ 33876947451fSStefano Zampini MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecRead(). 33886947451fSStefano Zampini 33896947451fSStefano Zampini Collective 33906947451fSStefano Zampini 33915ea7661aSPierre Jolivet Input Parameters: 33926947451fSStefano Zampini + mat - the Mat object 33936947451fSStefano Zampini . col - the column index 3394742765d3SMatthew Knepley - v - the Vec object (may be NULL) 33956947451fSStefano Zampini 33966947451fSStefano Zampini Level: intermediate 33976947451fSStefano Zampini 3398db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecWrite()` 33996947451fSStefano Zampini @*/ 34009371c9d4SSatish Balay PetscErrorCode MatDenseRestoreColumnVecRead(Mat A, PetscInt col, Vec *v) { 34016947451fSStefano Zampini PetscFunctionBegin; 34026947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 34036947451fSStefano Zampini PetscValidType(A, 1); 34046947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 340508401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 34062cf15c64SPierre 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); 3407cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v)); 34086947451fSStefano Zampini PetscFunctionReturn(0); 34096947451fSStefano Zampini } 34106947451fSStefano Zampini 34110f74d2c1SSatish Balay /*@ 34126947451fSStefano Zampini MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a Vec. 34136947451fSStefano Zampini 34146947451fSStefano Zampini Collective 34156947451fSStefano Zampini 34165ea7661aSPierre Jolivet Input Parameters: 34176947451fSStefano Zampini + mat - the Mat object 34186947451fSStefano Zampini - col - the column index 34196947451fSStefano Zampini 34206947451fSStefano Zampini Output Parameter: 34216947451fSStefano Zampini . v - the vector 34226947451fSStefano Zampini 34236947451fSStefano Zampini Notes: 34246947451fSStefano Zampini The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVecWrite() when the vector is no longer needed. 342511a5261eSBarry Smith 34266947451fSStefano Zampini Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecRead() for read-only access. 34276947451fSStefano Zampini 34286947451fSStefano Zampini Level: intermediate 34296947451fSStefano Zampini 3430db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 34316947451fSStefano Zampini @*/ 34329371c9d4SSatish Balay PetscErrorCode MatDenseGetColumnVecWrite(Mat A, PetscInt col, Vec *v) { 34336947451fSStefano Zampini PetscFunctionBegin; 34346947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 34356947451fSStefano Zampini PetscValidType(A, 1); 34366947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 34376947451fSStefano Zampini PetscValidPointer(v, 3); 343828b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3439aed4548fSBarry 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); 3440cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v)); 34416947451fSStefano Zampini PetscFunctionReturn(0); 34426947451fSStefano Zampini } 34436947451fSStefano Zampini 34440f74d2c1SSatish Balay /*@ 34456947451fSStefano Zampini MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecWrite(). 34466947451fSStefano Zampini 34476947451fSStefano Zampini Collective 34486947451fSStefano Zampini 34495ea7661aSPierre Jolivet Input Parameters: 34506947451fSStefano Zampini + mat - the Mat object 34516947451fSStefano Zampini . col - the column index 3452742765d3SMatthew Knepley - v - the Vec object (may be NULL) 34536947451fSStefano Zampini 34546947451fSStefano Zampini Level: intermediate 34556947451fSStefano Zampini 3456db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()` 34576947451fSStefano Zampini @*/ 34589371c9d4SSatish Balay PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A, PetscInt col, Vec *v) { 34596947451fSStefano Zampini PetscFunctionBegin; 34606947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 34616947451fSStefano Zampini PetscValidType(A, 1); 34626947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 346308401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3464aed4548fSBarry 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); 3465cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v)); 34666947451fSStefano Zampini PetscFunctionReturn(0); 34676947451fSStefano Zampini } 34685ea7661aSPierre Jolivet 34690f74d2c1SSatish Balay /*@ 3470a2748737SPierre Jolivet MatDenseGetSubMatrix - Gives access to a block of rows and columns of a dense matrix, represented as a Mat. 34715ea7661aSPierre Jolivet 34725ea7661aSPierre Jolivet Collective 34735ea7661aSPierre Jolivet 34745ea7661aSPierre Jolivet Input Parameters: 34755ea7661aSPierre Jolivet + mat - the Mat object 3476a2748737SPierre Jolivet . rbegin - the first global row index in the block (if PETSC_DECIDE, is 0) 3477a2748737SPierre Jolivet . rend - the global row index past the last one in the block (if PETSC_DECIDE, is M) 3478a2748737SPierre Jolivet . cbegin - the first global column index in the block (if PETSC_DECIDE, is 0) 3479a2748737SPierre Jolivet - cend - the global column index past the last one in the block (if PETSC_DECIDE, is N) 34805ea7661aSPierre Jolivet 34815ea7661aSPierre Jolivet Output Parameter: 34825ea7661aSPierre Jolivet . v - the matrix 34835ea7661aSPierre Jolivet 34845ea7661aSPierre Jolivet Notes: 34855ea7661aSPierre Jolivet The matrix is owned by PETSc. Users need to call MatDenseRestoreSubMatrix() when the matrix is no longer needed. 348611a5261eSBarry Smith 3487a2748737SPierre 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. 34885ea7661aSPierre Jolivet 34895ea7661aSPierre Jolivet Level: intermediate 34905ea7661aSPierre Jolivet 3491db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreSubMatrix()` 34925ea7661aSPierre Jolivet @*/ 34939371c9d4SSatish Balay PetscErrorCode MatDenseGetSubMatrix(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) { 34945ea7661aSPierre Jolivet PetscFunctionBegin; 34955ea7661aSPierre Jolivet PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 34965ea7661aSPierre Jolivet PetscValidType(A, 1); 3497a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, rbegin, 2); 3498a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, rend, 3); 3499a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, cbegin, 4); 3500a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, cend, 5); 3501a2748737SPierre Jolivet PetscValidPointer(v, 6); 3502a2748737SPierre Jolivet if (rbegin == PETSC_DECIDE) rbegin = 0; 3503a2748737SPierre Jolivet if (rend == PETSC_DECIDE) rend = A->rmap->N; 3504a2748737SPierre Jolivet if (cbegin == PETSC_DECIDE) cbegin = 0; 3505a2748737SPierre Jolivet if (cend == PETSC_DECIDE) cend = A->cmap->N; 350628b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3507a2748737SPierre 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); 3508a2748737SPierre 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); 3509a2748737SPierre 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); 3510a2748737SPierre 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); 3511a2748737SPierre Jolivet PetscUseMethod(A, "MatDenseGetSubMatrix_C", (Mat, PetscInt, PetscInt, PetscInt, PetscInt, Mat *), (A, rbegin, rend, cbegin, cend, v)); 35125ea7661aSPierre Jolivet PetscFunctionReturn(0); 35135ea7661aSPierre Jolivet } 35145ea7661aSPierre Jolivet 35150f74d2c1SSatish Balay /*@ 35165ea7661aSPierre Jolivet MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from MatDenseGetSubMatrix(). 35175ea7661aSPierre Jolivet 35185ea7661aSPierre Jolivet Collective 35195ea7661aSPierre Jolivet 35205ea7661aSPierre Jolivet Input Parameters: 35215ea7661aSPierre Jolivet + mat - the Mat object 3522742765d3SMatthew Knepley - v - the Mat object (may be NULL) 35235ea7661aSPierre Jolivet 35245ea7661aSPierre Jolivet Level: intermediate 35255ea7661aSPierre Jolivet 3526db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseGetSubMatrix()` 35275ea7661aSPierre Jolivet @*/ 35289371c9d4SSatish Balay PetscErrorCode MatDenseRestoreSubMatrix(Mat A, Mat *v) { 35295ea7661aSPierre Jolivet PetscFunctionBegin; 35305ea7661aSPierre Jolivet PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 35315ea7661aSPierre Jolivet PetscValidType(A, 1); 35325ea7661aSPierre Jolivet PetscValidPointer(v, 2); 3533cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreSubMatrix_C", (Mat, Mat *), (A, v)); 35345ea7661aSPierre Jolivet PetscFunctionReturn(0); 35355ea7661aSPierre Jolivet } 35368a9c020eSBarry Smith 35378a9c020eSBarry Smith #include <petscblaslapack.h> 35388a9c020eSBarry Smith #include <petsc/private/kernels/blockinvert.h> 35398a9c020eSBarry Smith 35409371c9d4SSatish Balay PetscErrorCode MatSeqDenseInvert(Mat A) { 35418a9c020eSBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35428a9c020eSBarry Smith PetscInt bs = A->rmap->n; 35438a9c020eSBarry Smith MatScalar *values = a->v; 35448a9c020eSBarry Smith const PetscReal shift = 0.0; 35458a9c020eSBarry Smith PetscBool allowzeropivot = PetscNot(A->erroriffailure), zeropivotdetected = PETSC_FALSE; 35468a9c020eSBarry Smith 35478a9c020eSBarry Smith PetscFunctionBegin; 35488a9c020eSBarry Smith /* factor and invert each block */ 35498a9c020eSBarry Smith switch (bs) { 35509371c9d4SSatish Balay case 1: values[0] = (PetscScalar)1.0 / (values[0] + shift); break; 35518a9c020eSBarry Smith case 2: 35528a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_2(values, shift, allowzeropivot, &zeropivotdetected)); 35538a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 35548a9c020eSBarry Smith break; 35558a9c020eSBarry Smith case 3: 35568a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_3(values, shift, allowzeropivot, &zeropivotdetected)); 35578a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 35588a9c020eSBarry Smith break; 35598a9c020eSBarry Smith case 4: 35608a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_4(values, shift, allowzeropivot, &zeropivotdetected)); 35618a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 35628a9c020eSBarry Smith break; 35639371c9d4SSatish Balay case 5: { 35648a9c020eSBarry Smith PetscScalar work[25]; 35658a9c020eSBarry Smith PetscInt ipvt[5]; 35668a9c020eSBarry Smith 35678a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_5(values, ipvt, work, shift, allowzeropivot, &zeropivotdetected)); 35688a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 35699371c9d4SSatish Balay } break; 35708a9c020eSBarry Smith case 6: 35718a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_6(values, shift, allowzeropivot, &zeropivotdetected)); 35728a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 35738a9c020eSBarry Smith break; 35748a9c020eSBarry Smith case 7: 35758a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_7(values, shift, allowzeropivot, &zeropivotdetected)); 35768a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 35778a9c020eSBarry Smith break; 35789371c9d4SSatish Balay default: { 35798a9c020eSBarry Smith PetscInt *v_pivots, *IJ, j; 35808a9c020eSBarry Smith PetscScalar *v_work; 35818a9c020eSBarry Smith 35828a9c020eSBarry Smith PetscCall(PetscMalloc3(bs, &v_work, bs, &v_pivots, bs, &IJ)); 3583ad540459SPierre Jolivet for (j = 0; j < bs; j++) IJ[j] = j; 35848a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A(bs, values, v_pivots, v_work, allowzeropivot, &zeropivotdetected)); 35858a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 35868a9c020eSBarry Smith PetscCall(PetscFree3(v_work, v_pivots, IJ)); 35878a9c020eSBarry Smith } 35888a9c020eSBarry Smith } 35898a9c020eSBarry Smith PetscFunctionReturn(0); 35908a9c020eSBarry Smith } 3591