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)); 428c178816SStefano Zampini } 439566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 44792fecdfSBarry Smith PetscCallBLAS("LAPACKgetri", LAPACKgetri_(&n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info)); 459566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 469566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0)); 478c178816SStefano Zampini } else if (A->factortype == MAT_FACTOR_CHOLESKY) { 48b94d7dedSBarry Smith if (A->spd == PETSC_BOOL3_TRUE) { 499566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 50792fecdfSBarry Smith PetscCallBLAS("LAPACKpotri", LAPACKpotri_("L", &n, mat->v, &mat->lda, &info)); 519566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 529566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_TRUE)); 538c178816SStefano Zampini #if defined(PETSC_USE_COMPLEX) 54b94d7dedSBarry Smith } else if (A->hermitian == PETSC_BOOL3_TRUE) { 5528b400f6SJacob Faibussowitsch PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present"); 5628b400f6SJacob Faibussowitsch PetscCheck(mat->fwork, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Fwork not present"); 579566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 58792fecdfSBarry Smith PetscCallBLAS("LAPACKhetri", LAPACKhetri_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &info)); 599566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 609566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_TRUE)); 618c178816SStefano Zampini #endif 628c178816SStefano Zampini } else { /* symmetric case */ 6328b400f6SJacob Faibussowitsch PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present"); 6428b400f6SJacob Faibussowitsch PetscCheck(mat->fwork, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Fwork not present"); 659566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 66792fecdfSBarry Smith PetscCallBLAS("LAPACKsytri", LAPACKsytri_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &info)); 679566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 689566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_FALSE)); 698c178816SStefano Zampini } 7028b400f6SJacob Faibussowitsch PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad Inversion: zero pivot in row %" PetscInt_FMT, (PetscInt)info - 1); 719566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0)); 728c178816SStefano Zampini } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Matrix must be factored to solve"); 738c178816SStefano Zampini 748c178816SStefano Zampini A->ops->solve = NULL; 758c178816SStefano Zampini A->ops->matsolve = NULL; 768c178816SStefano Zampini A->ops->solvetranspose = NULL; 778c178816SStefano Zampini A->ops->matsolvetranspose = NULL; 788c178816SStefano Zampini A->ops->solveadd = NULL; 798c178816SStefano Zampini A->ops->solvetransposeadd = NULL; 808c178816SStefano Zampini A->factortype = MAT_FACTOR_NONE; 819566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 828c178816SStefano Zampini PetscFunctionReturn(0); 838c178816SStefano Zampini } 848c178816SStefano Zampini 859371c9d4SSatish Balay PetscErrorCode MatZeroRowsColumns_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) { 863f49a652SStefano Zampini Mat_SeqDense *l = (Mat_SeqDense *)A->data; 873f49a652SStefano Zampini PetscInt m = l->lda, n = A->cmap->n, r = A->rmap->n, i, j; 88ca15aa20SStefano Zampini PetscScalar *slot, *bb, *v; 893f49a652SStefano Zampini const PetscScalar *xx; 903f49a652SStefano Zampini 913f49a652SStefano Zampini PetscFunctionBegin; 9276bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 933f49a652SStefano Zampini for (i = 0; i < N; i++) { 9408401ef6SPierre Jolivet PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed"); 9508401ef6SPierre 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); 9608401ef6SPierre 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); 973f49a652SStefano Zampini } 9876bd3646SJed Brown } 99ca15aa20SStefano Zampini if (!N) PetscFunctionReturn(0); 1003f49a652SStefano Zampini 1013f49a652SStefano Zampini /* fix right hand side if needed */ 1023f49a652SStefano Zampini if (x && b) { 1036c4d906cSStefano Zampini Vec xt; 1046c4d906cSStefano Zampini 10508401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices"); 1069566063dSJacob Faibussowitsch PetscCall(VecDuplicate(x, &xt)); 1079566063dSJacob Faibussowitsch PetscCall(VecCopy(x, xt)); 1089566063dSJacob Faibussowitsch PetscCall(VecScale(xt, -1.0)); 1099566063dSJacob Faibussowitsch PetscCall(MatMultAdd(A, xt, b, b)); 1109566063dSJacob Faibussowitsch PetscCall(VecDestroy(&xt)); 1119566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 1129566063dSJacob Faibussowitsch PetscCall(VecGetArray(b, &bb)); 1133f49a652SStefano Zampini for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]]; 1149566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 1159566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(b, &bb)); 1163f49a652SStefano Zampini } 1173f49a652SStefano Zampini 1189566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 1193f49a652SStefano Zampini for (i = 0; i < N; i++) { 120ca15aa20SStefano Zampini slot = v + rows[i] * m; 1219566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(slot, r)); 1223f49a652SStefano Zampini } 1233f49a652SStefano Zampini for (i = 0; i < N; i++) { 124ca15aa20SStefano Zampini slot = v + rows[i]; 1259371c9d4SSatish Balay for (j = 0; j < n; j++) { 1269371c9d4SSatish Balay *slot = 0.0; 1279371c9d4SSatish Balay slot += m; 1289371c9d4SSatish Balay } 1293f49a652SStefano Zampini } 1303f49a652SStefano Zampini if (diag != 0.0) { 13108401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices"); 1323f49a652SStefano Zampini for (i = 0; i < N; i++) { 133ca15aa20SStefano Zampini slot = v + (m + 1) * rows[i]; 1343f49a652SStefano Zampini *slot = diag; 1353f49a652SStefano Zampini } 1363f49a652SStefano Zampini } 1379566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 1383f49a652SStefano Zampini PetscFunctionReturn(0); 1393f49a652SStefano Zampini } 1403f49a652SStefano Zampini 1419371c9d4SSatish Balay PetscErrorCode MatPtAPNumeric_SeqDense_SeqDense(Mat A, Mat P, Mat C) { 142abc3b08eSStefano Zampini Mat_SeqDense *c = (Mat_SeqDense *)(C->data); 143abc3b08eSStefano Zampini 144abc3b08eSStefano Zampini PetscFunctionBegin; 145ca15aa20SStefano Zampini if (c->ptapwork) { 1469566063dSJacob Faibussowitsch PetscCall((*C->ops->matmultnumeric)(A, P, c->ptapwork)); 1479566063dSJacob Faibussowitsch PetscCall((*C->ops->transposematmultnumeric)(P, c->ptapwork, C)); 1484222ddf1SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)C), PETSC_ERR_SUP, "Must call MatPtAPSymbolic_SeqDense_SeqDense() first"); 149abc3b08eSStefano Zampini PetscFunctionReturn(0); 150abc3b08eSStefano Zampini } 151abc3b08eSStefano Zampini 1529371c9d4SSatish Balay PetscErrorCode MatPtAPSymbolic_SeqDense_SeqDense(Mat A, Mat P, PetscReal fill, Mat C) { 153abc3b08eSStefano Zampini Mat_SeqDense *c; 1547a3c3d58SStefano Zampini PetscBool cisdense; 155abc3b08eSStefano Zampini 156abc3b08eSStefano Zampini PetscFunctionBegin; 1579566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, P->cmap->n, P->cmap->n, P->cmap->N, P->cmap->N)); 1589566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 1597a3c3d58SStefano Zampini if (!cisdense) { 1607a3c3d58SStefano Zampini PetscBool flg; 1617a3c3d58SStefano Zampini 1629566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)P, ((PetscObject)A)->type_name, &flg)); 1639566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 1647a3c3d58SStefano Zampini } 1659566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 1664222ddf1SHong Zhang c = (Mat_SeqDense *)C->data; 1679566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &c->ptapwork)); 1689566063dSJacob Faibussowitsch PetscCall(MatSetSizes(c->ptapwork, A->rmap->n, P->cmap->n, A->rmap->N, P->cmap->N)); 1699566063dSJacob Faibussowitsch PetscCall(MatSetType(c->ptapwork, ((PetscObject)C)->type_name)); 1709566063dSJacob Faibussowitsch PetscCall(MatSetUp(c->ptapwork)); 171abc3b08eSStefano Zampini PetscFunctionReturn(0); 172abc3b08eSStefano Zampini } 173abc3b08eSStefano Zampini 1749371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) { 175a13144ffSStefano Zampini Mat B = NULL; 176b49cda9fSStefano Zampini Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data; 177b49cda9fSStefano Zampini Mat_SeqDense *b; 178b49cda9fSStefano Zampini PetscInt *ai = a->i, *aj = a->j, m = A->rmap->N, n = A->cmap->N, i; 1792e5835c6SStefano Zampini const MatScalar *av; 180a13144ffSStefano Zampini PetscBool isseqdense; 181b49cda9fSStefano Zampini 182b49cda9fSStefano Zampini PetscFunctionBegin; 183a13144ffSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 1849566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)*newmat, MATSEQDENSE, &isseqdense)); 18528b400f6SJacob Faibussowitsch PetscCheck(isseqdense, PetscObjectComm((PetscObject)*newmat), PETSC_ERR_USER, "Cannot reuse matrix of type %s", ((PetscObject)(*newmat))->type_name); 186a13144ffSStefano Zampini } 187a13144ffSStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 1889566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B)); 1899566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B, m, n, m, n)); 1909566063dSJacob Faibussowitsch PetscCall(MatSetType(B, MATSEQDENSE)); 1919566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(B, NULL)); 192b49cda9fSStefano Zampini b = (Mat_SeqDense *)(B->data); 193a13144ffSStefano Zampini } else { 194a13144ffSStefano Zampini b = (Mat_SeqDense *)((*newmat)->data); 1959566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(b->v, m * n)); 196a13144ffSStefano Zampini } 1979566063dSJacob Faibussowitsch PetscCall(MatSeqAIJGetArrayRead(A, &av)); 198b49cda9fSStefano Zampini for (i = 0; i < m; i++) { 199b49cda9fSStefano Zampini PetscInt j; 200b49cda9fSStefano Zampini for (j = 0; j < ai[1] - ai[0]; j++) { 201b49cda9fSStefano Zampini b->v[*aj * m + i] = *av; 202b49cda9fSStefano Zampini aj++; 203b49cda9fSStefano Zampini av++; 204b49cda9fSStefano Zampini } 205b49cda9fSStefano Zampini ai++; 206b49cda9fSStefano Zampini } 2079566063dSJacob Faibussowitsch PetscCall(MatSeqAIJRestoreArrayRead(A, &av)); 208b49cda9fSStefano Zampini 209511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 2109566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 2119566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 2129566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A, &B)); 213b49cda9fSStefano Zampini } else { 214a13144ffSStefano Zampini if (B) *newmat = B; 2159566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(*newmat, MAT_FINAL_ASSEMBLY)); 2169566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(*newmat, MAT_FINAL_ASSEMBLY)); 217b49cda9fSStefano Zampini } 218b49cda9fSStefano Zampini PetscFunctionReturn(0); 219b49cda9fSStefano Zampini } 220b49cda9fSStefano Zampini 2219371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatConvert_SeqDense_SeqAIJ(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) { 2226d4ec7b0SPierre Jolivet Mat B = NULL; 2236a63e612SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2249399e1b8SMatthew G. Knepley PetscInt i, j; 2259399e1b8SMatthew G. Knepley PetscInt *rows, *nnz; 2269399e1b8SMatthew G. Knepley MatScalar *aa = a->v, *vals; 2276a63e612SBarry Smith 2286a63e612SBarry Smith PetscFunctionBegin; 2299566063dSJacob Faibussowitsch PetscCall(PetscCalloc3(A->rmap->n, &rows, A->rmap->n, &nnz, A->rmap->n, &vals)); 2306d4ec7b0SPierre Jolivet if (reuse != MAT_REUSE_MATRIX) { 2319566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B)); 2329566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B, A->rmap->n, A->cmap->n, A->rmap->N, A->cmap->N)); 2339566063dSJacob Faibussowitsch PetscCall(MatSetType(B, MATSEQAIJ)); 2349399e1b8SMatthew G. Knepley for (j = 0; j < A->cmap->n; j++) { 2359371c9d4SSatish Balay for (i = 0; i < A->rmap->n; i++) 2369371c9d4SSatish Balay if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) ++nnz[i]; 2376a63e612SBarry Smith aa += a->lda; 2386a63e612SBarry Smith } 2399566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(B, PETSC_DETERMINE, nnz)); 2406d4ec7b0SPierre Jolivet } else B = *newmat; 2419399e1b8SMatthew G. Knepley aa = a->v; 2429399e1b8SMatthew G. Knepley for (j = 0; j < A->cmap->n; j++) { 2439399e1b8SMatthew G. Knepley PetscInt numRows = 0; 2449371c9d4SSatish Balay for (i = 0; i < A->rmap->n; i++) 2459371c9d4SSatish Balay if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) { 2469371c9d4SSatish Balay rows[numRows] = i; 2479371c9d4SSatish Balay vals[numRows++] = aa[i]; 2489371c9d4SSatish Balay } 2499566063dSJacob Faibussowitsch PetscCall(MatSetValues(B, numRows, rows, 1, &j, vals, INSERT_VALUES)); 2509399e1b8SMatthew G. Knepley aa += a->lda; 2519399e1b8SMatthew G. Knepley } 2529566063dSJacob Faibussowitsch PetscCall(PetscFree3(rows, nnz, vals)); 2539566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 2549566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 2556a63e612SBarry Smith 256511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 2579566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A, &B)); 2586d4ec7b0SPierre Jolivet } else if (reuse != MAT_REUSE_MATRIX) *newmat = B; 2596a63e612SBarry Smith PetscFunctionReturn(0); 2606a63e612SBarry Smith } 2616a63e612SBarry Smith 2629371c9d4SSatish Balay PetscErrorCode MatAXPY_SeqDense(Mat Y, PetscScalar alpha, Mat X, MatStructure str) { 2631987afe7SBarry Smith Mat_SeqDense *x = (Mat_SeqDense *)X->data, *y = (Mat_SeqDense *)Y->data; 264ca15aa20SStefano Zampini const PetscScalar *xv; 265ca15aa20SStefano Zampini PetscScalar *yv; 26623fff9afSBarry Smith PetscBLASInt N, m, ldax = 0, lday = 0, one = 1; 2673a40ed3dSBarry Smith 2683a40ed3dSBarry Smith PetscFunctionBegin; 2699566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(X, &xv)); 2709566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(Y, &yv)); 2719566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(X->rmap->n * X->cmap->n, &N)); 2729566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(X->rmap->n, &m)); 2739566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(x->lda, &ldax)); 2749566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(y->lda, &lday)); 275a5ce6ee0Svictorle if (ldax > m || lday > m) { 276ca15aa20SStefano Zampini PetscInt j; 277ca15aa20SStefano Zampini 27848a46eb9SPierre Jolivet for (j = 0; j < X->cmap->n; j++) PetscCallBLAS("BLASaxpy", BLASaxpy_(&m, &alpha, xv + j * ldax, &one, yv + j * lday, &one)); 279a5ce6ee0Svictorle } else { 280792fecdfSBarry Smith PetscCallBLAS("BLASaxpy", BLASaxpy_(&N, &alpha, xv, &one, yv, &one)); 281a5ce6ee0Svictorle } 2829566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(X, &xv)); 2839566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(Y, &yv)); 2849566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(PetscMax(2.0 * N - 1, 0))); 2853a40ed3dSBarry Smith PetscFunctionReturn(0); 2861987afe7SBarry Smith } 2871987afe7SBarry Smith 2889371c9d4SSatish Balay static PetscErrorCode MatGetInfo_SeqDense(Mat A, MatInfoType flag, MatInfo *info) { 289ca15aa20SStefano Zampini PetscLogDouble N = A->rmap->n * A->cmap->n; 2903a40ed3dSBarry Smith 2913a40ed3dSBarry Smith PetscFunctionBegin; 2924e220ebcSLois Curfman McInnes info->block_size = 1.0; 293ca15aa20SStefano Zampini info->nz_allocated = N; 294ca15aa20SStefano Zampini info->nz_used = N; 295ca15aa20SStefano Zampini info->nz_unneeded = 0; 296ca15aa20SStefano Zampini info->assemblies = A->num_ass; 2974e220ebcSLois Curfman McInnes info->mallocs = 0; 298*4dfa11a4SJacob Faibussowitsch info->memory = 0; /* REVIEW ME */ 2994e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 3004e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 3014e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 3023a40ed3dSBarry Smith PetscFunctionReturn(0); 303289bc588SBarry Smith } 304289bc588SBarry Smith 3059371c9d4SSatish Balay PetscErrorCode MatScale_SeqDense(Mat A, PetscScalar alpha) { 306273d9f13SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 307ca15aa20SStefano Zampini PetscScalar *v; 30823fff9afSBarry Smith PetscBLASInt one = 1, j, nz, lda = 0; 30980cd9d93SLois Curfman McInnes 3103a40ed3dSBarry Smith PetscFunctionBegin; 3119566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 3129566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(a->lda, &lda)); 313d0f46423SBarry Smith if (lda > A->rmap->n) { 3149566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &nz)); 31548a46eb9SPierre Jolivet for (j = 0; j < A->cmap->n; j++) PetscCallBLAS("BLASscal", BLASscal_(&nz, &alpha, v + j * lda, &one)); 316a5ce6ee0Svictorle } else { 3179566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n * A->cmap->n, &nz)); 318792fecdfSBarry Smith PetscCallBLAS("BLASscal", BLASscal_(&nz, &alpha, v, &one)); 319a5ce6ee0Svictorle } 32004cbc005SJose E. Roman PetscCall(PetscLogFlops(A->rmap->n * A->cmap->n)); 3219566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 3223a40ed3dSBarry Smith PetscFunctionReturn(0); 32380cd9d93SLois Curfman McInnes } 32480cd9d93SLois Curfman McInnes 3259371c9d4SSatish Balay PetscErrorCode MatShift_SeqDense(Mat A, PetscScalar alpha) { 3262f605a99SJose E. Roman Mat_SeqDense *a = (Mat_SeqDense *)A->data; 3272f605a99SJose E. Roman PetscScalar *v; 3282f605a99SJose E. Roman PetscInt j, k; 3292f605a99SJose E. Roman 3302f605a99SJose E. Roman PetscFunctionBegin; 3312f605a99SJose E. Roman PetscCall(MatDenseGetArray(A, &v)); 3322f605a99SJose E. Roman k = PetscMin(A->rmap->n, A->cmap->n); 3332f605a99SJose E. Roman for (j = 0; j < k; j++) v[j + j * a->lda] += alpha; 3342f605a99SJose E. Roman PetscCall(PetscLogFlops(k)); 3352f605a99SJose E. Roman PetscCall(MatDenseRestoreArray(A, &v)); 3362f605a99SJose E. Roman PetscFunctionReturn(0); 3372f605a99SJose E. Roman } 3382f605a99SJose E. Roman 3399371c9d4SSatish Balay static PetscErrorCode MatIsHermitian_SeqDense(Mat A, PetscReal rtol, PetscBool *fl) { 3401cbb95d3SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 341ca15aa20SStefano Zampini PetscInt i, j, m = A->rmap->n, N = a->lda; 342ca15aa20SStefano Zampini const PetscScalar *v; 3431cbb95d3SBarry Smith 3441cbb95d3SBarry Smith PetscFunctionBegin; 3451cbb95d3SBarry Smith *fl = PETSC_FALSE; 346d0f46423SBarry Smith if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0); 3479566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 3481cbb95d3SBarry Smith for (i = 0; i < m; i++) { 349ca15aa20SStefano Zampini for (j = i; j < m; j++) { 350ad540459SPierre Jolivet if (PetscAbsScalar(v[i + j * N] - PetscConj(v[j + i * N])) > rtol) goto restore; 3511cbb95d3SBarry Smith } 352637a0070SStefano Zampini } 3531cbb95d3SBarry Smith *fl = PETSC_TRUE; 354637a0070SStefano Zampini restore: 3559566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 356637a0070SStefano Zampini PetscFunctionReturn(0); 357637a0070SStefano Zampini } 358637a0070SStefano Zampini 3599371c9d4SSatish Balay static PetscErrorCode MatIsSymmetric_SeqDense(Mat A, PetscReal rtol, PetscBool *fl) { 360637a0070SStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 361637a0070SStefano Zampini PetscInt i, j, m = A->rmap->n, N = a->lda; 362637a0070SStefano Zampini const PetscScalar *v; 363637a0070SStefano Zampini 364637a0070SStefano Zampini PetscFunctionBegin; 365637a0070SStefano Zampini *fl = PETSC_FALSE; 366637a0070SStefano Zampini if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0); 3679566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 368637a0070SStefano Zampini for (i = 0; i < m; i++) { 369637a0070SStefano Zampini for (j = i; j < m; j++) { 370ad540459SPierre Jolivet if (PetscAbsScalar(v[i + j * N] - v[j + i * N]) > rtol) goto restore; 371637a0070SStefano Zampini } 372637a0070SStefano Zampini } 373637a0070SStefano Zampini *fl = PETSC_TRUE; 374637a0070SStefano Zampini restore: 3759566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 3761cbb95d3SBarry Smith PetscFunctionReturn(0); 3771cbb95d3SBarry Smith } 3781cbb95d3SBarry Smith 3799371c9d4SSatish Balay PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi, Mat A, MatDuplicateOption cpvalues) { 380ca15aa20SStefano Zampini Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 38123fc5dcaSStefano Zampini PetscInt lda = (PetscInt)mat->lda, j, m, nlda = lda; 38275f6d85dSStefano Zampini PetscBool isdensecpu; 383b24902e0SBarry Smith 384b24902e0SBarry Smith PetscFunctionBegin; 3859566063dSJacob Faibussowitsch PetscCall(PetscLayoutReference(A->rmap, &newi->rmap)); 3869566063dSJacob Faibussowitsch PetscCall(PetscLayoutReference(A->cmap, &newi->cmap)); 38723fc5dcaSStefano Zampini if (cpvalues == MAT_SHARE_NONZERO_PATTERN) { /* propagate LDA */ 3889566063dSJacob Faibussowitsch PetscCall(MatDenseSetLDA(newi, lda)); 38923fc5dcaSStefano Zampini } 3909566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)newi, MATSEQDENSE, &isdensecpu)); 3919566063dSJacob Faibussowitsch if (isdensecpu) PetscCall(MatSeqDenseSetPreallocation(newi, NULL)); 392b24902e0SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 393ca15aa20SStefano Zampini const PetscScalar *av; 394ca15aa20SStefano Zampini PetscScalar *v; 395ca15aa20SStefano Zampini 3969566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 3979566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(newi, &v)); 3989566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(newi, &nlda)); 399d0f46423SBarry Smith m = A->rmap->n; 40023fc5dcaSStefano Zampini if (lda > m || nlda > m) { 40148a46eb9SPierre Jolivet for (j = 0; j < A->cmap->n; j++) PetscCall(PetscArraycpy(v + j * nlda, av + j * lda, m)); 402b24902e0SBarry Smith } else { 4039566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(v, av, A->rmap->n * A->cmap->n)); 404b24902e0SBarry Smith } 4059566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(newi, &v)); 4069566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 407b24902e0SBarry Smith } 408b24902e0SBarry Smith PetscFunctionReturn(0); 409b24902e0SBarry Smith } 410b24902e0SBarry Smith 4119371c9d4SSatish Balay PetscErrorCode MatDuplicate_SeqDense(Mat A, MatDuplicateOption cpvalues, Mat *newmat) { 4123a40ed3dSBarry Smith PetscFunctionBegin; 4139566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), newmat)); 4149566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*newmat, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n)); 4159566063dSJacob Faibussowitsch PetscCall(MatSetType(*newmat, ((PetscObject)A)->type_name)); 4169566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(*newmat, A, cpvalues)); 417b24902e0SBarry Smith PetscFunctionReturn(0); 418b24902e0SBarry Smith } 419b24902e0SBarry Smith 4209371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_Internal_LU(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T) { 421c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4224396437dSToby Isaac PetscBLASInt info; 42367e560aaSBarry Smith 4243a40ed3dSBarry Smith PetscFunctionBegin; 4259566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 426792fecdfSBarry Smith PetscCallBLAS("LAPACKgetrs", LAPACKgetrs_(T ? "T" : "N", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info)); 4279566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 42805fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "GETRS - Bad solve %d", (int)info); 4299566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m))); 4304396437dSToby Isaac PetscFunctionReturn(0); 4314396437dSToby Isaac } 4324396437dSToby Isaac 4334396437dSToby Isaac static PetscErrorCode MatConjugate_SeqDense(Mat); 4344396437dSToby Isaac 4359371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_Internal_Cholesky(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T) { 4364396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4374396437dSToby Isaac PetscBLASInt info; 4384396437dSToby Isaac 4394396437dSToby Isaac PetscFunctionBegin; 440b94d7dedSBarry Smith if (A->spd == PETSC_BOOL3_TRUE) { 4419566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A)); 4429566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 443792fecdfSBarry Smith PetscCallBLAS("LAPACKpotrs", LAPACKpotrs_("L", &m, &nrhs, mat->v, &mat->lda, x, &m, &info)); 4449566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 44505fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "POTRS Bad solve %d", (int)info); 4469566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A)); 447a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX) 448b94d7dedSBarry Smith } else if (A->hermitian == PETSC_BOOL3_TRUE) { 4499566063dSJacob Faibussowitsch if (T) PetscCall(MatConjugate_SeqDense(A)); 4509566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 451792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrs", LAPACKhetrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info)); 4529566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 45305fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "HETRS Bad solve %d", (int)info); 4549566063dSJacob Faibussowitsch if (T) PetscCall(MatConjugate_SeqDense(A)); 455a49dc2a2SStefano Zampini #endif 456a49dc2a2SStefano Zampini } else { /* symmetric case */ 4579566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 458792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrs", LAPACKsytrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info)); 4599566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 46005fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "SYTRS Bad solve %d", (int)info); 461a49dc2a2SStefano Zampini } 4629566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m))); 4634396437dSToby Isaac PetscFunctionReturn(0); 4644396437dSToby Isaac } 46585e2c93fSHong Zhang 4669371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k) { 4674396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4684396437dSToby Isaac PetscBLASInt info; 4694396437dSToby Isaac char trans; 4704396437dSToby Isaac 4714396437dSToby Isaac PetscFunctionBegin; 4724905a7bcSToby Isaac if (PetscDefined(USE_COMPLEX)) { 4734905a7bcSToby Isaac trans = 'C'; 4744905a7bcSToby Isaac } else { 4754905a7bcSToby Isaac trans = 'T'; 4764905a7bcSToby Isaac } 4779566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 47805fcb23eSStefano Zampini { /* lwork depends on the number of right-hand sides */ 47905fcb23eSStefano Zampini PetscBLASInt nlfwork, lfwork = -1; 48005fcb23eSStefano Zampini PetscScalar fwork; 48105fcb23eSStefano Zampini 482792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info)); 48305fcb23eSStefano Zampini nlfwork = (PetscBLASInt)PetscRealPart(fwork); 48405fcb23eSStefano Zampini if (nlfwork > mat->lfwork) { 48505fcb23eSStefano Zampini mat->lfwork = nlfwork; 48605fcb23eSStefano Zampini PetscCall(PetscFree(mat->fwork)); 48705fcb23eSStefano Zampini PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 48805fcb23eSStefano Zampini } 48905fcb23eSStefano Zampini } 490792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info)); 4919566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 49205fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %d", (int)info); 4939566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 494792fecdfSBarry Smith PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "N", "N", &mat->rank, &nrhs, mat->v, &mat->lda, x, &ldx, &info)); 4959566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 49605fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %d", (int)info); 4974905a7bcSToby Isaac for (PetscInt j = 0; j < nrhs; j++) { 498ad540459SPierre Jolivet for (PetscInt i = mat->rank; i < k; i++) x[j * ldx + i] = 0.; 4994905a7bcSToby Isaac } 5009566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank)))); 5014905a7bcSToby Isaac PetscFunctionReturn(0); 5024905a7bcSToby Isaac } 5034905a7bcSToby Isaac 5049371c9d4SSatish Balay static PetscErrorCode MatSolveTranspose_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k) { 5054396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 5064396437dSToby Isaac PetscBLASInt info; 5074396437dSToby Isaac 5084396437dSToby Isaac PetscFunctionBegin; 5094396437dSToby Isaac if (A->rmap->n == A->cmap->n && mat->rank == A->rmap->n) { 5109566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 511792fecdfSBarry Smith PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "T", "N", &m, &nrhs, mat->v, &mat->lda, x, &ldx, &info)); 5129566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 51305fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %d", (int)info); 5149566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A)); 51505fcb23eSStefano Zampini { /* lwork depends on the number of right-hand sides */ 51605fcb23eSStefano Zampini PetscBLASInt nlfwork, lfwork = -1; 51705fcb23eSStefano Zampini PetscScalar fwork; 51805fcb23eSStefano Zampini 519792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info)); 52005fcb23eSStefano Zampini nlfwork = (PetscBLASInt)PetscRealPart(fwork); 52105fcb23eSStefano Zampini if (nlfwork > mat->lfwork) { 52205fcb23eSStefano Zampini mat->lfwork = nlfwork; 52305fcb23eSStefano Zampini PetscCall(PetscFree(mat->fwork)); 52405fcb23eSStefano Zampini PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 52505fcb23eSStefano Zampini } 52605fcb23eSStefano Zampini } 5279566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 528792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info)); 5299566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 53005fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %d", (int)info); 5319566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A)); 5324396437dSToby Isaac } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "QR factored matrix cannot be used for transpose solve"); 5339566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank)))); 5344396437dSToby Isaac PetscFunctionReturn(0); 5354396437dSToby Isaac } 5364396437dSToby Isaac 5379371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_SetUp(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k) { 5384396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 5394905a7bcSToby Isaac PetscScalar *y; 5404905a7bcSToby Isaac PetscBLASInt m = 0, k = 0; 5414905a7bcSToby Isaac 5424905a7bcSToby Isaac PetscFunctionBegin; 5439566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 5449566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 5454905a7bcSToby Isaac if (k < m) { 5469566063dSJacob Faibussowitsch PetscCall(VecCopy(xx, mat->qrrhs)); 5479566063dSJacob Faibussowitsch PetscCall(VecGetArray(mat->qrrhs, &y)); 5484905a7bcSToby Isaac } else { 5499566063dSJacob Faibussowitsch PetscCall(VecCopy(xx, yy)); 5509566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &y)); 5514905a7bcSToby Isaac } 5524396437dSToby Isaac *_y = y; 5534396437dSToby Isaac *_k = k; 5544396437dSToby Isaac *_m = m; 5554396437dSToby Isaac PetscFunctionReturn(0); 5564396437dSToby Isaac } 5574396437dSToby Isaac 5589371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_TearDown(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k) { 5594396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 56042e9364cSSatish Balay PetscScalar *y = NULL; 5614396437dSToby Isaac PetscBLASInt m, k; 5624396437dSToby Isaac 5634396437dSToby Isaac PetscFunctionBegin; 5644396437dSToby Isaac y = *_y; 5654396437dSToby Isaac *_y = NULL; 5664396437dSToby Isaac k = *_k; 5674396437dSToby Isaac m = *_m; 5684905a7bcSToby Isaac if (k < m) { 5694905a7bcSToby Isaac PetscScalar *yv; 5709566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &yv)); 5719566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(yv, y, k)); 5729566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &yv)); 5739566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(mat->qrrhs, &y)); 5744905a7bcSToby Isaac } else { 5759566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &y)); 5764905a7bcSToby Isaac } 5774905a7bcSToby Isaac PetscFunctionReturn(0); 5784905a7bcSToby Isaac } 5794905a7bcSToby Isaac 5809371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_LU(Mat A, Vec xx, Vec yy) { 58142e9364cSSatish Balay PetscScalar *y = NULL; 58242e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 5834396437dSToby Isaac 5844396437dSToby Isaac PetscFunctionBegin; 5859566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 5869566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_FALSE)); 5879566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 5884396437dSToby Isaac PetscFunctionReturn(0); 5894396437dSToby Isaac } 5904396437dSToby Isaac 5919371c9d4SSatish Balay static PetscErrorCode MatSolveTranspose_SeqDense_LU(Mat A, Vec xx, Vec yy) { 59242e9364cSSatish Balay PetscScalar *y = NULL; 59342e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 5944396437dSToby Isaac 5954396437dSToby Isaac PetscFunctionBegin; 5969566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 5979566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_TRUE)); 5989566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 5994396437dSToby Isaac PetscFunctionReturn(0); 6004396437dSToby Isaac } 6014396437dSToby Isaac 6029371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_Cholesky(Mat A, Vec xx, Vec yy) { 603e54beecaSStefano Zampini PetscScalar *y = NULL; 604e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 6054396437dSToby Isaac 6064396437dSToby Isaac PetscFunctionBegin; 6079566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6089566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_FALSE)); 6099566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6104396437dSToby Isaac PetscFunctionReturn(0); 6114396437dSToby Isaac } 6124396437dSToby Isaac 6139371c9d4SSatish Balay static PetscErrorCode MatSolveTranspose_SeqDense_Cholesky(Mat A, Vec xx, Vec yy) { 614e54beecaSStefano Zampini PetscScalar *y = NULL; 615e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 6164396437dSToby Isaac 6174396437dSToby Isaac PetscFunctionBegin; 6189566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6199566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_TRUE)); 6209566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6214396437dSToby Isaac PetscFunctionReturn(0); 6224396437dSToby Isaac } 6234396437dSToby Isaac 6249371c9d4SSatish Balay static PetscErrorCode MatSolve_SeqDense_QR(Mat A, Vec xx, Vec yy) { 625e54beecaSStefano Zampini PetscScalar *y = NULL; 626e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 6274396437dSToby Isaac 6284396437dSToby Isaac PetscFunctionBegin; 6299566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6309566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k)); 6319566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6324396437dSToby Isaac PetscFunctionReturn(0); 6334396437dSToby Isaac } 6344396437dSToby Isaac 6359371c9d4SSatish Balay static PetscErrorCode MatSolveTranspose_SeqDense_QR(Mat A, Vec xx, Vec yy) { 63642e9364cSSatish Balay PetscScalar *y = NULL; 63742e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 6384396437dSToby Isaac 6394396437dSToby Isaac PetscFunctionBegin; 6409566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6419566063dSJacob Faibussowitsch PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k)); 6429566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6434396437dSToby Isaac PetscFunctionReturn(0); 6444396437dSToby Isaac } 6454396437dSToby Isaac 6469371c9d4SSatish Balay static PetscErrorCode MatMatSolve_SeqDense_SetUp(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k) { 6474905a7bcSToby Isaac const PetscScalar *b; 6484396437dSToby Isaac PetscScalar *y; 649bf5a80bcSToby Isaac PetscInt n, _ldb, _ldx; 650bf5a80bcSToby Isaac PetscBLASInt nrhs = 0, m = 0, k = 0, ldb = 0, ldx = 0, ldy = 0; 6514905a7bcSToby Isaac 6524905a7bcSToby Isaac PetscFunctionBegin; 6539371c9d4SSatish Balay *_ldy = 0; 6549371c9d4SSatish Balay *_m = 0; 6559371c9d4SSatish Balay *_nrhs = 0; 6569371c9d4SSatish Balay *_k = 0; 6579371c9d4SSatish Balay *_y = NULL; 6589566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 6599566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 6609566063dSJacob Faibussowitsch PetscCall(MatGetSize(B, NULL, &n)); 6619566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(n, &nrhs)); 6629566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(B, &_ldb)); 6639566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldb, &ldb)); 6649566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(X, &_ldx)); 6659566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldx, &ldx)); 666bf5a80bcSToby Isaac if (ldx < m) { 6679566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &b)); 6689566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nrhs * m, &y)); 669bf5a80bcSToby Isaac if (ldb == m) { 6709566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(y, b, ldb * nrhs)); 6714905a7bcSToby Isaac } else { 67248a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * m], &b[j * ldb], m)); 6734905a7bcSToby Isaac } 674bf5a80bcSToby Isaac ldy = m; 6759566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &b)); 6764905a7bcSToby Isaac } else { 677bf5a80bcSToby Isaac if (ldb == ldx) { 6789566063dSJacob Faibussowitsch PetscCall(MatCopy(B, X, SAME_NONZERO_PATTERN)); 6799566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &y)); 6804905a7bcSToby Isaac } else { 6819566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &y)); 6829566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &b)); 68348a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * ldx], &b[j * ldb], m)); 6849566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &b)); 6854905a7bcSToby Isaac } 686bf5a80bcSToby Isaac ldy = ldx; 6874905a7bcSToby Isaac } 6884396437dSToby Isaac *_y = y; 689bf5a80bcSToby Isaac *_ldy = ldy; 6904396437dSToby Isaac *_k = k; 6914396437dSToby Isaac *_m = m; 6924396437dSToby Isaac *_nrhs = nrhs; 6934396437dSToby Isaac PetscFunctionReturn(0); 6944396437dSToby Isaac } 6954396437dSToby Isaac 6969371c9d4SSatish Balay static PetscErrorCode MatMatSolve_SeqDense_TearDown(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k) { 6974396437dSToby Isaac PetscScalar *y; 698bf5a80bcSToby Isaac PetscInt _ldx; 699bf5a80bcSToby Isaac PetscBLASInt k, ldy, nrhs, ldx = 0; 7004396437dSToby Isaac 7014396437dSToby Isaac PetscFunctionBegin; 7024396437dSToby Isaac y = *_y; 7034396437dSToby Isaac *_y = NULL; 7044396437dSToby Isaac k = *_k; 705bf5a80bcSToby Isaac ldy = *_ldy; 7064396437dSToby Isaac nrhs = *_nrhs; 7079566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(X, &_ldx)); 7089566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldx, &ldx)); 709bf5a80bcSToby Isaac if (ldx != ldy) { 7104905a7bcSToby Isaac PetscScalar *xv; 7119566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &xv)); 71248a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&xv[j * ldx], &y[j * ldy], k)); 7139566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(X, &xv)); 7149566063dSJacob Faibussowitsch PetscCall(PetscFree(y)); 7154905a7bcSToby Isaac } else { 7169566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(X, &y)); 7174905a7bcSToby Isaac } 71885e2c93fSHong Zhang PetscFunctionReturn(0); 71985e2c93fSHong Zhang } 72085e2c93fSHong Zhang 7219371c9d4SSatish Balay static PetscErrorCode MatMatSolve_SeqDense_LU(Mat A, Mat B, Mat X) { 7224396437dSToby Isaac PetscScalar *y; 723bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7244396437dSToby Isaac 7254396437dSToby Isaac PetscFunctionBegin; 7269566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7279566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_FALSE)); 7289566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7294396437dSToby Isaac PetscFunctionReturn(0); 7304396437dSToby Isaac } 7314396437dSToby Isaac 7329371c9d4SSatish Balay static PetscErrorCode MatMatSolveTranspose_SeqDense_LU(Mat A, Mat B, Mat X) { 7334396437dSToby Isaac PetscScalar *y; 734bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7354396437dSToby Isaac 7364396437dSToby Isaac PetscFunctionBegin; 7379566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7389566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_TRUE)); 7399566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7404396437dSToby Isaac PetscFunctionReturn(0); 7414396437dSToby Isaac } 7424396437dSToby Isaac 7439371c9d4SSatish Balay static PetscErrorCode MatMatSolve_SeqDense_Cholesky(Mat A, Mat B, Mat X) { 7444396437dSToby Isaac PetscScalar *y; 745bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7464396437dSToby Isaac 7474396437dSToby Isaac PetscFunctionBegin; 7489566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7499566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_FALSE)); 7509566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7514396437dSToby Isaac PetscFunctionReturn(0); 7524396437dSToby Isaac } 7534396437dSToby Isaac 7549371c9d4SSatish Balay static PetscErrorCode MatMatSolveTranspose_SeqDense_Cholesky(Mat A, Mat B, Mat X) { 7554396437dSToby Isaac PetscScalar *y; 756bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7574396437dSToby Isaac 7584396437dSToby Isaac PetscFunctionBegin; 7599566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7609566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_TRUE)); 7619566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7624396437dSToby Isaac PetscFunctionReturn(0); 7634396437dSToby Isaac } 7644396437dSToby Isaac 7659371c9d4SSatish Balay static PetscErrorCode MatMatSolve_SeqDense_QR(Mat A, Mat B, Mat X) { 7664396437dSToby Isaac PetscScalar *y; 767bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7684396437dSToby Isaac 7694396437dSToby Isaac PetscFunctionBegin; 7709566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7719566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k)); 7729566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7734396437dSToby Isaac PetscFunctionReturn(0); 7744396437dSToby Isaac } 7754396437dSToby Isaac 7769371c9d4SSatish Balay static PetscErrorCode MatMatSolveTranspose_SeqDense_QR(Mat A, Mat B, Mat X) { 7774396437dSToby Isaac PetscScalar *y; 778bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7794396437dSToby Isaac 7804396437dSToby Isaac PetscFunctionBegin; 7819566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7829566063dSJacob Faibussowitsch PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k)); 7839566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7844396437dSToby Isaac PetscFunctionReturn(0); 7854396437dSToby Isaac } 7864396437dSToby Isaac 787db4efbfdSBarry Smith /* ---------------------------------------------------------------*/ 788db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots, 789db4efbfdSBarry Smith rather than put it in the Mat->row slot.*/ 7909371c9d4SSatish Balay PetscErrorCode MatLUFactor_SeqDense(Mat A, IS row, IS col, const MatFactorInfo *minfo) { 791db4efbfdSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 792db4efbfdSBarry Smith PetscBLASInt n, m, info; 793db4efbfdSBarry Smith 794db4efbfdSBarry Smith PetscFunctionBegin; 7959566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 7969566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 797*4dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); } 798db4efbfdSBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 7999566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 800792fecdfSBarry Smith PetscCallBLAS("LAPACKgetrf", LAPACKgetrf_(&m, &n, mat->v, &mat->lda, mat->pivots, &info)); 8019566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 8028e57ea43SSatish Balay 80305fcb23eSStefano Zampini PetscCheck(info >= 0, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to LU factorization %d", (int)info); 80405fcb23eSStefano Zampini PetscCheck(info <= 0, PETSC_COMM_SELF, PETSC_ERR_MAT_LU_ZRPVT, "Bad LU factorization %d", (int)info); 8058208b9aeSStefano Zampini 8064396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_LU; 8074396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_LU; 8084396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_LU; 8094396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_LU; 810d5f3da31SBarry Smith A->factortype = MAT_FACTOR_LU; 811db4efbfdSBarry Smith 8129566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 8139566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 814f6224b95SHong Zhang 8159566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((2.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3)); 816db4efbfdSBarry Smith PetscFunctionReturn(0); 817db4efbfdSBarry Smith } 818db4efbfdSBarry Smith 8199371c9d4SSatish Balay static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) { 8204396437dSToby Isaac MatFactorInfo info; 8214396437dSToby Isaac 8224396437dSToby Isaac PetscFunctionBegin; 8239566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 824dbbe0bcdSBarry Smith PetscUseTypeMethod(fact, lufactor, NULL, NULL, &info); 8254396437dSToby Isaac PetscFunctionReturn(0); 8264396437dSToby Isaac } 8274396437dSToby Isaac 8289371c9d4SSatish Balay PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, IS col, const MatFactorInfo *info) { 8294396437dSToby Isaac PetscFunctionBegin; 8304396437dSToby Isaac fact->preallocated = PETSC_TRUE; 8314396437dSToby Isaac fact->assembled = PETSC_TRUE; 8324396437dSToby Isaac fact->ops->lufactornumeric = MatLUFactorNumeric_SeqDense; 8334396437dSToby Isaac PetscFunctionReturn(0); 8344396437dSToby Isaac } 8354396437dSToby Isaac 836a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */ 8379371c9d4SSatish Balay PetscErrorCode MatCholeskyFactor_SeqDense(Mat A, IS perm, const MatFactorInfo *factinfo) { 838db4efbfdSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 839c5df96a5SBarry Smith PetscBLASInt info, n; 840db4efbfdSBarry Smith 841db4efbfdSBarry Smith PetscFunctionBegin; 8429566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 843db4efbfdSBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 844b94d7dedSBarry Smith if (A->spd == PETSC_BOOL3_TRUE) { 8459566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 846792fecdfSBarry Smith PetscCallBLAS("LAPACKpotrf", LAPACKpotrf_("L", &n, mat->v, &mat->lda, &info)); 8479566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 848a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX) 849b94d7dedSBarry Smith } else if (A->hermitian == PETSC_BOOL3_TRUE) { 850*4dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); } 851a49dc2a2SStefano Zampini if (!mat->fwork) { 852a49dc2a2SStefano Zampini PetscScalar dummy; 853a49dc2a2SStefano Zampini 854a49dc2a2SStefano Zampini mat->lfwork = -1; 8559566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 856792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info)); 8579566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 858a49dc2a2SStefano Zampini mat->lfwork = (PetscInt)PetscRealPart(dummy); 8599566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 860a49dc2a2SStefano Zampini } 8619566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 862792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info)); 8639566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 864a49dc2a2SStefano Zampini #endif 865a49dc2a2SStefano Zampini } else { /* symmetric case */ 866*4dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); } 867a49dc2a2SStefano Zampini if (!mat->fwork) { 868a49dc2a2SStefano Zampini PetscScalar dummy; 869a49dc2a2SStefano Zampini 870a49dc2a2SStefano Zampini mat->lfwork = -1; 8719566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 872792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info)); 8739566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 874a49dc2a2SStefano Zampini mat->lfwork = (PetscInt)PetscRealPart(dummy); 8759566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 876a49dc2a2SStefano Zampini } 8779566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 878792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info)); 8799566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 880a49dc2a2SStefano Zampini } 88128b400f6SJacob Faibussowitsch PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad factorization: zero pivot in row %" PetscInt_FMT, (PetscInt)info - 1); 8828208b9aeSStefano Zampini 8834396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_Cholesky; 8844396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_Cholesky; 8854396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_Cholesky; 8864396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_Cholesky; 887d5f3da31SBarry Smith A->factortype = MAT_FACTOR_CHOLESKY; 8882205254eSKarl Rupp 8899566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 8909566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 891f6224b95SHong Zhang 8929566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0)); 893db4efbfdSBarry Smith PetscFunctionReturn(0); 894db4efbfdSBarry Smith } 895db4efbfdSBarry Smith 8969371c9d4SSatish Balay static PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) { 897db4efbfdSBarry Smith MatFactorInfo info; 898db4efbfdSBarry Smith 899db4efbfdSBarry Smith PetscFunctionBegin; 900db4efbfdSBarry Smith info.fill = 1.0; 9012205254eSKarl Rupp 9029566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 903dbbe0bcdSBarry Smith PetscUseTypeMethod(fact, choleskyfactor, NULL, &info); 904db4efbfdSBarry Smith PetscFunctionReturn(0); 905db4efbfdSBarry Smith } 906db4efbfdSBarry Smith 9079371c9d4SSatish Balay PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info) { 908db4efbfdSBarry Smith PetscFunctionBegin; 909c3ef05f6SHong Zhang fact->assembled = PETSC_TRUE; 9101bbcc794SSatish Balay fact->preallocated = PETSC_TRUE; 911719d5645SBarry Smith fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense; 912db4efbfdSBarry Smith PetscFunctionReturn(0); 913db4efbfdSBarry Smith } 914db4efbfdSBarry Smith 9159371c9d4SSatish Balay PetscErrorCode MatQRFactor_SeqDense(Mat A, IS col, const MatFactorInfo *minfo) { 9164905a7bcSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 9174905a7bcSToby Isaac PetscBLASInt n, m, info, min, max; 9184905a7bcSToby Isaac 9194905a7bcSToby Isaac PetscFunctionBegin; 9209566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 9219566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 9224396437dSToby Isaac max = PetscMax(m, n); 9234396437dSToby Isaac min = PetscMin(m, n); 924*4dfa11a4SJacob Faibussowitsch if (!mat->tau) { PetscCall(PetscMalloc1(min, &mat->tau)); } 925*4dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(n, &mat->pivots)); } 92648a46eb9SPierre Jolivet if (!mat->qrrhs) PetscCall(MatCreateVecs(A, NULL, &(mat->qrrhs))); 9274905a7bcSToby Isaac if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 9284905a7bcSToby Isaac if (!mat->fwork) { 9294905a7bcSToby Isaac PetscScalar dummy; 9304905a7bcSToby Isaac 9314905a7bcSToby Isaac mat->lfwork = -1; 9329566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 933792fecdfSBarry Smith PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, &dummy, &mat->lfwork, &info)); 9349566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 9354905a7bcSToby Isaac mat->lfwork = (PetscInt)PetscRealPart(dummy); 9369566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 9374905a7bcSToby Isaac } 9389566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 939792fecdfSBarry Smith PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, mat->fwork, &mat->lfwork, &info)); 9409566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 94105fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to QR factorization %d", (int)info); 9424905a7bcSToby 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 9434905a7bcSToby Isaac mat->rank = min; 9444905a7bcSToby Isaac 9454396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_QR; 9464396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_QR; 9474905a7bcSToby Isaac A->factortype = MAT_FACTOR_QR; 9484905a7bcSToby Isaac if (m == n) { 9494396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_QR; 9504396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_QR; 9514905a7bcSToby Isaac } 9524905a7bcSToby Isaac 9539566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 9549566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 9554905a7bcSToby Isaac 9569566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * min * min * (max - min / 3.0))); 9574905a7bcSToby Isaac PetscFunctionReturn(0); 9584905a7bcSToby Isaac } 9594905a7bcSToby Isaac 9609371c9d4SSatish Balay static PetscErrorCode MatQRFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) { 9614905a7bcSToby Isaac MatFactorInfo info; 9624905a7bcSToby Isaac 9634905a7bcSToby Isaac PetscFunctionBegin; 9644905a7bcSToby Isaac info.fill = 1.0; 9654905a7bcSToby Isaac 9669566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 967cac4c232SBarry Smith PetscUseMethod(fact, "MatQRFactor_C", (Mat, IS, const MatFactorInfo *), (fact, NULL, &info)); 9684905a7bcSToby Isaac PetscFunctionReturn(0); 9694905a7bcSToby Isaac } 9704905a7bcSToby Isaac 9719371c9d4SSatish Balay PetscErrorCode MatQRFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info) { 9724905a7bcSToby Isaac PetscFunctionBegin; 9734905a7bcSToby Isaac fact->assembled = PETSC_TRUE; 9744905a7bcSToby Isaac fact->preallocated = PETSC_TRUE; 9759566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)fact, "MatQRFactorNumeric_C", MatQRFactorNumeric_SeqDense)); 9764905a7bcSToby Isaac PetscFunctionReturn(0); 9774905a7bcSToby Isaac } 9784905a7bcSToby Isaac 979ca15aa20SStefano Zampini /* uses LAPACK */ 9809371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A, MatFactorType ftype, Mat *fact) { 981db4efbfdSBarry Smith PetscFunctionBegin; 9829566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), fact)); 9839566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*fact, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n)); 9849566063dSJacob Faibussowitsch PetscCall(MatSetType(*fact, MATDENSE)); 98566e17bc3SBarry Smith (*fact)->trivialsymbolic = PETSC_TRUE; 9862a350339SBarry Smith if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU) { 987db4efbfdSBarry Smith (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense; 9882a350339SBarry Smith (*fact)->ops->ilufactorsymbolic = MatLUFactorSymbolic_SeqDense; 989bf5a80bcSToby Isaac } else if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) { 990db4efbfdSBarry Smith (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense; 991bf5a80bcSToby Isaac } else if (ftype == MAT_FACTOR_QR) { 9929566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)(*fact), "MatQRFactorSymbolic_C", MatQRFactorSymbolic_SeqDense)); 993db4efbfdSBarry Smith } 994d5f3da31SBarry Smith (*fact)->factortype = ftype; 99500c67f3bSHong Zhang 9969566063dSJacob Faibussowitsch PetscCall(PetscFree((*fact)->solvertype)); 9979566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &(*fact)->solvertype)); 9989566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_LU])); 9999566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ILU])); 10009566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_CHOLESKY])); 10019566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ICC])); 1002db4efbfdSBarry Smith PetscFunctionReturn(0); 1003db4efbfdSBarry Smith } 1004db4efbfdSBarry Smith 1005289bc588SBarry Smith /* ------------------------------------------------------------------*/ 10069371c9d4SSatish Balay static PetscErrorCode MatSOR_SeqDense(Mat A, Vec bb, PetscReal omega, MatSORType flag, PetscReal shift, PetscInt its, PetscInt lits, Vec xx) { 1007c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1008d9ca1df4SBarry Smith PetscScalar *x, *v = mat->v, zero = 0.0, xt; 1009d9ca1df4SBarry Smith const PetscScalar *b; 1010d0f46423SBarry Smith PetscInt m = A->rmap->n, i; 101123fff9afSBarry Smith PetscBLASInt o = 1, bm = 0; 1012289bc588SBarry Smith 10133a40ed3dSBarry Smith PetscFunctionBegin; 1014ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA) 101508401ef6SPierre Jolivet PetscCheck(A->offloadmask != PETSC_OFFLOAD_GPU, PETSC_COMM_SELF, PETSC_ERR_SUP, "Not implemented"); 1016ca15aa20SStefano Zampini #endif 1017422a814eSBarry Smith if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */ 10189566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(m, &bm)); 1019289bc588SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 10203bffc371SBarry Smith /* this is a hack fix, should have another version without the second BLASdotu */ 10219566063dSJacob Faibussowitsch PetscCall(VecSet(xx, zero)); 1022289bc588SBarry Smith } 10239566063dSJacob Faibussowitsch PetscCall(VecGetArray(xx, &x)); 10249566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(bb, &b)); 1025b965ef7fSBarry Smith its = its * lits; 102608401ef6SPierre 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); 1027289bc588SBarry Smith while (its--) { 1028fccaa45eSBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 1029289bc588SBarry Smith for (i = 0; i < m; i++) { 1030792fecdfSBarry Smith PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o)); 103155a1b374SBarry Smith x[i] = (1. - omega) * x[i] + omega * (xt + v[i + i * m] * x[i]) / (v[i + i * m] + shift); 1032289bc588SBarry Smith } 1033289bc588SBarry Smith } 1034fccaa45eSBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 1035289bc588SBarry Smith for (i = m - 1; i >= 0; i--) { 1036792fecdfSBarry Smith PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o)); 103755a1b374SBarry Smith x[i] = (1. - omega) * x[i] + omega * (xt + v[i + i * m] * x[i]) / (v[i + i * m] + shift); 1038289bc588SBarry Smith } 1039289bc588SBarry Smith } 1040289bc588SBarry Smith } 10419566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(bb, &b)); 10429566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(xx, &x)); 10433a40ed3dSBarry Smith PetscFunctionReturn(0); 1044289bc588SBarry Smith } 1045289bc588SBarry Smith 1046289bc588SBarry Smith /* -----------------------------------------------------------------*/ 10479371c9d4SSatish Balay PetscErrorCode MatMultTranspose_SeqDense(Mat A, Vec xx, Vec yy) { 1048c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1049d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 1050d9ca1df4SBarry Smith PetscScalar *y; 10510805154bSBarry Smith PetscBLASInt m, n, _One = 1; 1052ea709b57SSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 10533a40ed3dSBarry Smith 10543a40ed3dSBarry Smith PetscFunctionBegin; 10559566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 10569566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 10579566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 10589566063dSJacob Faibussowitsch PetscCall(VecGetArrayWrite(yy, &y)); 10595ac36cfcSBarry Smith if (!A->rmap->n || !A->cmap->n) { 10605ac36cfcSBarry Smith PetscBLASInt i; 10615ac36cfcSBarry Smith for (i = 0; i < n; i++) y[i] = 0.0; 10625ac36cfcSBarry Smith } else { 1063792fecdfSBarry Smith PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v, &mat->lda, x, &_One, &_DZero, y, &_One)); 10649566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n - A->cmap->n)); 10655ac36cfcSBarry Smith } 10669566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 10679566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayWrite(yy, &y)); 10683a40ed3dSBarry Smith PetscFunctionReturn(0); 1069289bc588SBarry Smith } 1070800995b7SMatthew Knepley 10719371c9d4SSatish Balay PetscErrorCode MatMult_SeqDense(Mat A, Vec xx, Vec yy) { 1072c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1073d9ca1df4SBarry Smith PetscScalar *y, _DOne = 1.0, _DZero = 0.0; 10740805154bSBarry Smith PetscBLASInt m, n, _One = 1; 1075d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 10763a40ed3dSBarry Smith 10773a40ed3dSBarry Smith PetscFunctionBegin; 10789566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 10799566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 10809566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 10819566063dSJacob Faibussowitsch PetscCall(VecGetArrayWrite(yy, &y)); 10825ac36cfcSBarry Smith if (!A->rmap->n || !A->cmap->n) { 10835ac36cfcSBarry Smith PetscBLASInt i; 10845ac36cfcSBarry Smith for (i = 0; i < m; i++) y[i] = 0.0; 10855ac36cfcSBarry Smith } else { 1086792fecdfSBarry Smith PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DZero, y, &_One)); 10879566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n - A->rmap->n)); 10885ac36cfcSBarry Smith } 10899566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 10909566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayWrite(yy, &y)); 10913a40ed3dSBarry Smith PetscFunctionReturn(0); 1092289bc588SBarry Smith } 10936ee01492SSatish Balay 10949371c9d4SSatish Balay PetscErrorCode MatMultAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) { 1095c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1096d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 1097d9ca1df4SBarry Smith PetscScalar *y, _DOne = 1.0; 10980805154bSBarry Smith PetscBLASInt m, n, _One = 1; 10993a40ed3dSBarry Smith 11003a40ed3dSBarry Smith PetscFunctionBegin; 11019566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 11029566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 11039566063dSJacob Faibussowitsch PetscCall(VecCopy(zz, yy)); 1104d0f46423SBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 11059566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 11069566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &y)); 1107792fecdfSBarry Smith PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DOne, y, &_One)); 11089566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 11099566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &y)); 11109566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n)); 11113a40ed3dSBarry Smith PetscFunctionReturn(0); 1112289bc588SBarry Smith } 11136ee01492SSatish Balay 11149371c9d4SSatish Balay PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) { 1115c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1116d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 1117d9ca1df4SBarry Smith PetscScalar *y; 11180805154bSBarry Smith PetscBLASInt m, n, _One = 1; 111987828ca2SBarry Smith PetscScalar _DOne = 1.0; 11203a40ed3dSBarry Smith 11213a40ed3dSBarry Smith PetscFunctionBegin; 11229566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 11239566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 11249566063dSJacob Faibussowitsch PetscCall(VecCopy(zz, yy)); 1125d0f46423SBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 11269566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 11279566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &y)); 1128792fecdfSBarry Smith PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DOne, y, &_One)); 11299566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 11309566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &y)); 11319566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n)); 11323a40ed3dSBarry Smith PetscFunctionReturn(0); 1133289bc588SBarry Smith } 1134289bc588SBarry Smith 1135289bc588SBarry Smith /* -----------------------------------------------------------------*/ 11369371c9d4SSatish Balay static PetscErrorCode MatGetRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals) { 1137c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 113813f74950SBarry Smith PetscInt i; 113967e560aaSBarry Smith 11403a40ed3dSBarry Smith PetscFunctionBegin; 1141d0f46423SBarry Smith *ncols = A->cmap->n; 1142289bc588SBarry Smith if (cols) { 11439566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->cmap->n, cols)); 1144d0f46423SBarry Smith for (i = 0; i < A->cmap->n; i++) (*cols)[i] = i; 1145289bc588SBarry Smith } 1146289bc588SBarry Smith if (vals) { 1147ca15aa20SStefano Zampini const PetscScalar *v; 1148ca15aa20SStefano Zampini 11499566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 11509566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->cmap->n, vals)); 1151ca15aa20SStefano Zampini v += row; 11529371c9d4SSatish Balay for (i = 0; i < A->cmap->n; i++) { 11539371c9d4SSatish Balay (*vals)[i] = *v; 11549371c9d4SSatish Balay v += mat->lda; 11559371c9d4SSatish Balay } 11569566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 1157289bc588SBarry Smith } 11583a40ed3dSBarry Smith PetscFunctionReturn(0); 1159289bc588SBarry Smith } 11606ee01492SSatish Balay 11619371c9d4SSatish Balay static PetscErrorCode MatRestoreRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals) { 1162606d414cSSatish Balay PetscFunctionBegin; 1163cb4a9cd9SHong Zhang if (ncols) *ncols = 0; 11649566063dSJacob Faibussowitsch if (cols) PetscCall(PetscFree(*cols)); 11659566063dSJacob Faibussowitsch if (vals) PetscCall(PetscFree(*vals)); 11663a40ed3dSBarry Smith PetscFunctionReturn(0); 1167289bc588SBarry Smith } 1168289bc588SBarry Smith /* ----------------------------------------------------------------*/ 11699371c9d4SSatish Balay static PetscErrorCode MatSetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], const PetscScalar v[], InsertMode addv) { 1170c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1171ca15aa20SStefano Zampini PetscScalar *av; 117213f74950SBarry Smith PetscInt i, j, idx = 0; 1173ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA) 1174c70f7ee4SJunchao Zhang PetscOffloadMask oldf; 1175ca15aa20SStefano Zampini #endif 1176d6dfbf8fSBarry Smith 11773a40ed3dSBarry Smith PetscFunctionBegin; 11789566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &av)); 1179289bc588SBarry Smith if (!mat->roworiented) { 1180dbb450caSBarry Smith if (addv == INSERT_VALUES) { 1181289bc588SBarry Smith for (j = 0; j < n; j++) { 11829371c9d4SSatish Balay if (indexn[j] < 0) { 11839371c9d4SSatish Balay idx += m; 11849371c9d4SSatish Balay continue; 11859371c9d4SSatish Balay } 11866bdcaf15SBarry 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); 1187289bc588SBarry Smith for (i = 0; i < m; i++) { 11889371c9d4SSatish Balay if (indexm[i] < 0) { 11899371c9d4SSatish Balay idx++; 11909371c9d4SSatish Balay continue; 11919371c9d4SSatish Balay } 11926bdcaf15SBarry 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); 1193ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] = v[idx++]; 1194289bc588SBarry Smith } 1195289bc588SBarry Smith } 11963a40ed3dSBarry Smith } else { 1197289bc588SBarry Smith for (j = 0; j < n; j++) { 11989371c9d4SSatish Balay if (indexn[j] < 0) { 11999371c9d4SSatish Balay idx += m; 12009371c9d4SSatish Balay continue; 12019371c9d4SSatish Balay } 12026bdcaf15SBarry 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); 1203289bc588SBarry Smith for (i = 0; i < m; i++) { 12049371c9d4SSatish Balay if (indexm[i] < 0) { 12059371c9d4SSatish Balay idx++; 12069371c9d4SSatish Balay continue; 12079371c9d4SSatish Balay } 12086bdcaf15SBarry 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); 1209ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] += v[idx++]; 1210289bc588SBarry Smith } 1211289bc588SBarry Smith } 1212289bc588SBarry Smith } 12133a40ed3dSBarry Smith } else { 1214dbb450caSBarry Smith if (addv == INSERT_VALUES) { 1215e8d4e0b9SBarry Smith for (i = 0; i < m; i++) { 12169371c9d4SSatish Balay if (indexm[i] < 0) { 12179371c9d4SSatish Balay idx += n; 12189371c9d4SSatish Balay continue; 12199371c9d4SSatish Balay } 12206bdcaf15SBarry 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); 1221e8d4e0b9SBarry Smith for (j = 0; j < n; j++) { 12229371c9d4SSatish Balay if (indexn[j] < 0) { 12239371c9d4SSatish Balay idx++; 12249371c9d4SSatish Balay continue; 12259371c9d4SSatish Balay } 12266bdcaf15SBarry 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); 1227ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] = v[idx++]; 1228e8d4e0b9SBarry Smith } 1229e8d4e0b9SBarry Smith } 12303a40ed3dSBarry Smith } else { 1231289bc588SBarry Smith for (i = 0; i < m; i++) { 12329371c9d4SSatish Balay if (indexm[i] < 0) { 12339371c9d4SSatish Balay idx += n; 12349371c9d4SSatish Balay continue; 12359371c9d4SSatish Balay } 12366bdcaf15SBarry 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); 1237289bc588SBarry Smith for (j = 0; j < n; j++) { 12389371c9d4SSatish Balay if (indexn[j] < 0) { 12399371c9d4SSatish Balay idx++; 12409371c9d4SSatish Balay continue; 12419371c9d4SSatish Balay } 12426bdcaf15SBarry 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); 1243ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] += v[idx++]; 1244289bc588SBarry Smith } 1245289bc588SBarry Smith } 1246289bc588SBarry Smith } 1247e8d4e0b9SBarry Smith } 1248ca15aa20SStefano Zampini /* hack to prevent unneeded copy to the GPU while returning the array */ 1249ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA) 1250c70f7ee4SJunchao Zhang oldf = A->offloadmask; 1251c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_GPU; 1252ca15aa20SStefano Zampini #endif 12539566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &av)); 1254ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA) 1255c70f7ee4SJunchao Zhang A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU); 1256ca15aa20SStefano Zampini #endif 12573a40ed3dSBarry Smith PetscFunctionReturn(0); 1258289bc588SBarry Smith } 1259e8d4e0b9SBarry Smith 12609371c9d4SSatish Balay static PetscErrorCode MatGetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], PetscScalar v[]) { 1261ae80bb75SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1262ca15aa20SStefano Zampini const PetscScalar *vv; 126313f74950SBarry Smith PetscInt i, j; 1264ae80bb75SLois Curfman McInnes 12653a40ed3dSBarry Smith PetscFunctionBegin; 12669566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &vv)); 1267ae80bb75SLois Curfman McInnes /* row-oriented output */ 1268ae80bb75SLois Curfman McInnes for (i = 0; i < m; i++) { 12699371c9d4SSatish Balay if (indexm[i] < 0) { 12709371c9d4SSatish Balay v += n; 12719371c9d4SSatish Balay continue; 12729371c9d4SSatish Balay } 127308401ef6SPierre 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); 1274ae80bb75SLois Curfman McInnes for (j = 0; j < n; j++) { 12759371c9d4SSatish Balay if (indexn[j] < 0) { 12769371c9d4SSatish Balay v++; 12779371c9d4SSatish Balay continue; 12789371c9d4SSatish Balay } 127908401ef6SPierre 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); 1280ca15aa20SStefano Zampini *v++ = vv[indexn[j] * mat->lda + indexm[i]]; 1281ae80bb75SLois Curfman McInnes } 1282ae80bb75SLois Curfman McInnes } 12839566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &vv)); 12843a40ed3dSBarry Smith PetscFunctionReturn(0); 1285ae80bb75SLois Curfman McInnes } 1286ae80bb75SLois Curfman McInnes 1287289bc588SBarry Smith /* -----------------------------------------------------------------*/ 1288289bc588SBarry Smith 12899371c9d4SSatish Balay PetscErrorCode MatView_Dense_Binary(Mat mat, PetscViewer viewer) { 12908491ab44SLisandro Dalcin PetscBool skipHeader; 12918491ab44SLisandro Dalcin PetscViewerFormat format; 12928491ab44SLisandro Dalcin PetscInt header[4], M, N, m, lda, i, j, k; 12938491ab44SLisandro Dalcin const PetscScalar *v; 12948491ab44SLisandro Dalcin PetscScalar *vwork; 1295aabbc4fbSShri Abhyankar 1296aabbc4fbSShri Abhyankar PetscFunctionBegin; 12979566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 12989566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader)); 12999566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 13008491ab44SLisandro Dalcin if (skipHeader) format = PETSC_VIEWER_NATIVE; 1301aabbc4fbSShri Abhyankar 13029566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &M, &N)); 13038491ab44SLisandro Dalcin 13048491ab44SLisandro Dalcin /* write matrix header */ 13059371c9d4SSatish Balay header[0] = MAT_FILE_CLASSID; 13069371c9d4SSatish Balay header[1] = M; 13079371c9d4SSatish Balay header[2] = N; 13088491ab44SLisandro Dalcin header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M * N; 13099566063dSJacob Faibussowitsch if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer, header, 4, PETSC_INT)); 13108491ab44SLisandro Dalcin 13119566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mat, &m, NULL)); 13128491ab44SLisandro Dalcin if (format != PETSC_VIEWER_NATIVE) { 13138491ab44SLisandro Dalcin PetscInt nnz = m * N, *iwork; 13148491ab44SLisandro Dalcin /* store row lengths for each row */ 13159566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz, &iwork)); 13168491ab44SLisandro Dalcin for (i = 0; i < m; i++) iwork[i] = N; 13179566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 13188491ab44SLisandro Dalcin /* store column indices (zero start index) */ 13198491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 13209371c9d4SSatish Balay for (j = 0; j < N; j++, k++) iwork[k] = j; 13219566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 13229566063dSJacob Faibussowitsch PetscCall(PetscFree(iwork)); 13238491ab44SLisandro Dalcin } 13248491ab44SLisandro Dalcin /* store matrix values as a dense matrix in row major order */ 13259566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m * N, &vwork)); 13269566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(mat, &v)); 13279566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(mat, &lda)); 13288491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 13299371c9d4SSatish Balay for (j = 0; j < N; j++, k++) vwork[k] = v[i + lda * j]; 13309566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(mat, &v)); 13319566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, vwork, m * N, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 13329566063dSJacob Faibussowitsch PetscCall(PetscFree(vwork)); 13338491ab44SLisandro Dalcin PetscFunctionReturn(0); 13348491ab44SLisandro Dalcin } 13358491ab44SLisandro Dalcin 13369371c9d4SSatish Balay PetscErrorCode MatLoad_Dense_Binary(Mat mat, PetscViewer viewer) { 13378491ab44SLisandro Dalcin PetscBool skipHeader; 13388491ab44SLisandro Dalcin PetscInt header[4], M, N, m, nz, lda, i, j, k; 13398491ab44SLisandro Dalcin PetscInt rows, cols; 13408491ab44SLisandro Dalcin PetscScalar *v, *vwork; 13418491ab44SLisandro Dalcin 13428491ab44SLisandro Dalcin PetscFunctionBegin; 13439566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 13449566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader)); 13458491ab44SLisandro Dalcin 13468491ab44SLisandro Dalcin if (!skipHeader) { 13479566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, header, 4, NULL, PETSC_INT)); 134808401ef6SPierre Jolivet PetscCheck(header[0] == MAT_FILE_CLASSID, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Not a matrix object in file"); 13499371c9d4SSatish Balay M = header[1]; 13509371c9d4SSatish Balay N = header[2]; 135108401ef6SPierre Jolivet PetscCheck(M >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix row size (%" PetscInt_FMT ") in file is negative", M); 135208401ef6SPierre Jolivet PetscCheck(N >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix column size (%" PetscInt_FMT ") in file is negative", N); 13538491ab44SLisandro Dalcin nz = header[3]; 1354aed4548fSBarry Smith PetscCheck(nz == MATRIX_BINARY_FORMAT_DENSE || nz >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Unknown matrix format %" PetscInt_FMT " in file", nz); 1355aabbc4fbSShri Abhyankar } else { 13569566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &M, &N)); 1357aed4548fSBarry 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"); 13588491ab44SLisandro Dalcin nz = MATRIX_BINARY_FORMAT_DENSE; 1359e6324fbbSBarry Smith } 1360aabbc4fbSShri Abhyankar 13618491ab44SLisandro Dalcin /* setup global sizes if not set */ 13628491ab44SLisandro Dalcin if (mat->rmap->N < 0) mat->rmap->N = M; 13638491ab44SLisandro Dalcin if (mat->cmap->N < 0) mat->cmap->N = N; 13649566063dSJacob Faibussowitsch PetscCall(MatSetUp(mat)); 13658491ab44SLisandro Dalcin /* check if global sizes are correct */ 13669566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &rows, &cols)); 1367aed4548fSBarry 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); 1368aabbc4fbSShri Abhyankar 13699566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, NULL, &N)); 13709566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mat, &m, NULL)); 13719566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(mat, &v)); 13729566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(mat, &lda)); 13738491ab44SLisandro Dalcin if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense format */ 13748491ab44SLisandro Dalcin PetscInt nnz = m * N; 13758491ab44SLisandro Dalcin /* read in matrix values */ 13769566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz, &vwork)); 13779566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 13788491ab44SLisandro Dalcin /* store values in column major order */ 13798491ab44SLisandro Dalcin for (j = 0; j < N; j++) 13809371c9d4SSatish Balay for (i = 0; i < m; i++) v[i + lda * j] = vwork[i * N + j]; 13819566063dSJacob Faibussowitsch PetscCall(PetscFree(vwork)); 13828491ab44SLisandro Dalcin } else { /* matrix in file is sparse format */ 13838491ab44SLisandro Dalcin PetscInt nnz = 0, *rlens, *icols; 13848491ab44SLisandro Dalcin /* read in row lengths */ 13859566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m, &rlens)); 13869566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, rlens, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 13878491ab44SLisandro Dalcin for (i = 0; i < m; i++) nnz += rlens[i]; 13888491ab44SLisandro Dalcin /* read in column indices and values */ 13899566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(nnz, &icols, nnz, &vwork)); 13909566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, icols, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 13919566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 13928491ab44SLisandro Dalcin /* store values in column major order */ 13938491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 13949371c9d4SSatish Balay for (j = 0; j < rlens[i]; j++, k++) v[i + lda * icols[k]] = vwork[k]; 13959566063dSJacob Faibussowitsch PetscCall(PetscFree(rlens)); 13969566063dSJacob Faibussowitsch PetscCall(PetscFree2(icols, vwork)); 1397aabbc4fbSShri Abhyankar } 13989566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(mat, &v)); 13999566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY)); 14009566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY)); 1401aabbc4fbSShri Abhyankar PetscFunctionReturn(0); 1402aabbc4fbSShri Abhyankar } 1403aabbc4fbSShri Abhyankar 14049371c9d4SSatish Balay PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer) { 1405eb91f321SVaclav Hapla PetscBool isbinary, ishdf5; 1406eb91f321SVaclav Hapla 1407eb91f321SVaclav Hapla PetscFunctionBegin; 1408eb91f321SVaclav Hapla PetscValidHeaderSpecific(newMat, MAT_CLASSID, 1); 1409eb91f321SVaclav Hapla PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1410eb91f321SVaclav Hapla /* force binary viewer to load .info file if it has not yet done so */ 14119566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 14129566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 14139566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5)); 1414eb91f321SVaclav Hapla if (isbinary) { 14159566063dSJacob Faibussowitsch PetscCall(MatLoad_Dense_Binary(newMat, viewer)); 1416eb91f321SVaclav Hapla } else if (ishdf5) { 1417eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5) 14189566063dSJacob Faibussowitsch PetscCall(MatLoad_Dense_HDF5(newMat, viewer)); 1419eb91f321SVaclav Hapla #else 1420eb91f321SVaclav Hapla SETERRQ(PetscObjectComm((PetscObject)newMat), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1421eb91f321SVaclav Hapla #endif 1422eb91f321SVaclav Hapla } else { 142398921bdaSJacob 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); 1424eb91f321SVaclav Hapla } 1425eb91f321SVaclav Hapla PetscFunctionReturn(0); 1426eb91f321SVaclav Hapla } 1427eb91f321SVaclav Hapla 14289371c9d4SSatish Balay static PetscErrorCode MatView_SeqDense_ASCII(Mat A, PetscViewer viewer) { 1429932b0c3eSLois Curfman McInnes Mat_SeqDense *a = (Mat_SeqDense *)A->data; 143013f74950SBarry Smith PetscInt i, j; 14312dcb1b2aSMatthew Knepley const char *name; 1432ca15aa20SStefano Zampini PetscScalar *v, *av; 1433f3ef73ceSBarry Smith PetscViewerFormat format; 14345f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX) 1435ace3abfcSBarry Smith PetscBool allreal = PETSC_TRUE; 14365f481a85SSatish Balay #endif 1437932b0c3eSLois Curfman McInnes 14383a40ed3dSBarry Smith PetscFunctionBegin; 14399566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&av)); 14409566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 1441456192e2SBarry Smith if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 14423a40ed3dSBarry Smith PetscFunctionReturn(0); /* do nothing for now */ 1443fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 14449566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE)); 1445d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 1446ca15aa20SStefano Zampini v = av + i; 14479566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "row %" PetscInt_FMT ":", i)); 1448d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1449aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 1450329f5518SBarry Smith if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) { 14519566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g + %g i) ", j, (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v))); 1452329f5518SBarry Smith } else if (PetscRealPart(*v)) { 14539566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)PetscRealPart(*v))); 14546831982aSBarry Smith } 145580cd9d93SLois Curfman McInnes #else 145648a46eb9SPierre Jolivet if (*v) PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)*v)); 145780cd9d93SLois Curfman McInnes #endif 14581b807ce4Svictorle v += a->lda; 145980cd9d93SLois Curfman McInnes } 14609566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 146180cd9d93SLois Curfman McInnes } 14629566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE)); 14633a40ed3dSBarry Smith } else { 14649566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE)); 1465aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 146647989497SBarry Smith /* determine if matrix has all real values */ 1467bcd8d3a4SJose E. Roman for (j = 0; j < A->cmap->n; j++) { 1468bcd8d3a4SJose E. Roman v = av + j * a->lda; 1469bcd8d3a4SJose E. Roman for (i = 0; i < A->rmap->n; i++) { 14709371c9d4SSatish Balay if (PetscImaginaryPart(v[i])) { 14719371c9d4SSatish Balay allreal = PETSC_FALSE; 14729371c9d4SSatish Balay break; 14739371c9d4SSatish Balay } 147447989497SBarry Smith } 1475bcd8d3a4SJose E. Roman } 147647989497SBarry Smith #endif 1477fb9695e5SSatish Balay if (format == PETSC_VIEWER_ASCII_MATLAB) { 14789566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)A, &name)); 14799566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%% Size = %" PetscInt_FMT " %" PetscInt_FMT " \n", A->rmap->n, A->cmap->n)); 14809566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%s = zeros(%" PetscInt_FMT ",%" PetscInt_FMT ");\n", name, A->rmap->n, A->cmap->n)); 14819566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%s = [\n", name)); 1482ffac6cdbSBarry Smith } 1483ffac6cdbSBarry Smith 1484d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 1485ca15aa20SStefano Zampini v = av + i; 1486d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1487aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 148847989497SBarry Smith if (allreal) { 14899566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)PetscRealPart(*v))); 149047989497SBarry Smith } else { 14919566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e + %18.16ei ", (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v))); 149247989497SBarry Smith } 1493289bc588SBarry Smith #else 14949566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)*v)); 1495289bc588SBarry Smith #endif 14961b807ce4Svictorle v += a->lda; 1497289bc588SBarry Smith } 14989566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 1499289bc588SBarry Smith } 150048a46eb9SPierre Jolivet if (format == PETSC_VIEWER_ASCII_MATLAB) PetscCall(PetscViewerASCIIPrintf(viewer, "];\n")); 15019566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE)); 1502da3a660dSBarry Smith } 15039566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&av)); 15049566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer)); 15053a40ed3dSBarry Smith PetscFunctionReturn(0); 1506289bc588SBarry Smith } 1507289bc588SBarry Smith 15089804daf3SBarry Smith #include <petscdraw.h> 15099371c9d4SSatish Balay static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw, void *Aa) { 1510f1af5d2fSBarry Smith Mat A = (Mat)Aa; 1511383922c3SLisandro Dalcin PetscInt m = A->rmap->n, n = A->cmap->n, i, j; 1512383922c3SLisandro Dalcin int color = PETSC_DRAW_WHITE; 1513ca15aa20SStefano Zampini const PetscScalar *v; 1514b0a32e0cSBarry Smith PetscViewer viewer; 1515b05fc000SLisandro Dalcin PetscReal xl, yl, xr, yr, x_l, x_r, y_l, y_r; 1516f3ef73ceSBarry Smith PetscViewerFormat format; 1517f1af5d2fSBarry Smith 1518f1af5d2fSBarry Smith PetscFunctionBegin; 15199566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)A, "Zoomviewer", (PetscObject *)&viewer)); 15209566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 15219566063dSJacob Faibussowitsch PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr)); 1522f1af5d2fSBarry Smith 1523f1af5d2fSBarry Smith /* Loop over matrix elements drawing boxes */ 15249566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 1525fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 1526d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 1527f1af5d2fSBarry Smith /* Blue for negative and Red for positive */ 1528f1af5d2fSBarry Smith for (j = 0; j < n; j++) { 15299371c9d4SSatish Balay x_l = j; 15309371c9d4SSatish Balay x_r = x_l + 1.0; 1531f1af5d2fSBarry Smith for (i = 0; i < m; i++) { 1532f1af5d2fSBarry Smith y_l = m - i - 1.0; 1533f1af5d2fSBarry Smith y_r = y_l + 1.0; 1534ca15aa20SStefano Zampini if (PetscRealPart(v[j * m + i]) > 0.) color = PETSC_DRAW_RED; 1535ca15aa20SStefano Zampini else if (PetscRealPart(v[j * m + i]) < 0.) color = PETSC_DRAW_BLUE; 1536ca15aa20SStefano Zampini else continue; 15379566063dSJacob Faibussowitsch PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color)); 1538f1af5d2fSBarry Smith } 1539f1af5d2fSBarry Smith } 1540d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 1541f1af5d2fSBarry Smith } else { 1542f1af5d2fSBarry Smith /* use contour shading to indicate magnitude of values */ 1543f1af5d2fSBarry Smith /* first determine max of all nonzero values */ 1544b05fc000SLisandro Dalcin PetscReal minv = 0.0, maxv = 0.0; 1545b05fc000SLisandro Dalcin PetscDraw popup; 1546b05fc000SLisandro Dalcin 1547f1af5d2fSBarry Smith for (i = 0; i < m * n; i++) { 1548f1af5d2fSBarry Smith if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]); 1549f1af5d2fSBarry Smith } 1550383922c3SLisandro Dalcin if (minv >= maxv) maxv = minv + PETSC_SMALL; 15519566063dSJacob Faibussowitsch PetscCall(PetscDrawGetPopup(draw, &popup)); 15529566063dSJacob Faibussowitsch PetscCall(PetscDrawScalePopup(popup, minv, maxv)); 1553383922c3SLisandro Dalcin 1554d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 1555f1af5d2fSBarry Smith for (j = 0; j < n; j++) { 1556f1af5d2fSBarry Smith x_l = j; 1557f1af5d2fSBarry Smith x_r = x_l + 1.0; 1558f1af5d2fSBarry Smith for (i = 0; i < m; i++) { 1559f1af5d2fSBarry Smith y_l = m - i - 1.0; 1560f1af5d2fSBarry Smith y_r = y_l + 1.0; 1561b05fc000SLisandro Dalcin color = PetscDrawRealToColor(PetscAbsScalar(v[j * m + i]), minv, maxv); 15629566063dSJacob Faibussowitsch PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color)); 1563f1af5d2fSBarry Smith } 1564f1af5d2fSBarry Smith } 1565d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 1566f1af5d2fSBarry Smith } 15679566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 1568f1af5d2fSBarry Smith PetscFunctionReturn(0); 1569f1af5d2fSBarry Smith } 1570f1af5d2fSBarry Smith 15719371c9d4SSatish Balay static PetscErrorCode MatView_SeqDense_Draw(Mat A, PetscViewer viewer) { 1572b0a32e0cSBarry Smith PetscDraw draw; 1573ace3abfcSBarry Smith PetscBool isnull; 1574329f5518SBarry Smith PetscReal xr, yr, xl, yl, h, w; 1575f1af5d2fSBarry Smith 1576f1af5d2fSBarry Smith PetscFunctionBegin; 15779566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 15789566063dSJacob Faibussowitsch PetscCall(PetscDrawIsNull(draw, &isnull)); 1579abc0a331SBarry Smith if (isnull) PetscFunctionReturn(0); 1580f1af5d2fSBarry Smith 15819371c9d4SSatish Balay xr = A->cmap->n; 15829371c9d4SSatish Balay yr = A->rmap->n; 15839371c9d4SSatish Balay h = yr / 10.0; 15849371c9d4SSatish Balay w = xr / 10.0; 15859371c9d4SSatish Balay xr += w; 15869371c9d4SSatish Balay yr += h; 15879371c9d4SSatish Balay xl = -w; 15889371c9d4SSatish Balay yl = -h; 15899566063dSJacob Faibussowitsch PetscCall(PetscDrawSetCoordinates(draw, xl, yl, xr, yr)); 15909566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", (PetscObject)viewer)); 15919566063dSJacob Faibussowitsch PetscCall(PetscDrawZoom(draw, MatView_SeqDense_Draw_Zoom, A)); 15929566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", NULL)); 15939566063dSJacob Faibussowitsch PetscCall(PetscDrawSave(draw)); 1594f1af5d2fSBarry Smith PetscFunctionReturn(0); 1595f1af5d2fSBarry Smith } 1596f1af5d2fSBarry Smith 15979371c9d4SSatish Balay PetscErrorCode MatView_SeqDense(Mat A, PetscViewer viewer) { 1598ace3abfcSBarry Smith PetscBool iascii, isbinary, isdraw; 1599932b0c3eSLois Curfman McInnes 16003a40ed3dSBarry Smith PetscFunctionBegin; 16019566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 16029566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 16039566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 16041baa6e33SBarry Smith if (iascii) PetscCall(MatView_SeqDense_ASCII(A, viewer)); 16051baa6e33SBarry Smith else if (isbinary) PetscCall(MatView_Dense_Binary(A, viewer)); 16061baa6e33SBarry Smith else if (isdraw) PetscCall(MatView_SeqDense_Draw(A, viewer)); 16073a40ed3dSBarry Smith PetscFunctionReturn(0); 1608932b0c3eSLois Curfman McInnes } 1609289bc588SBarry Smith 16109371c9d4SSatish Balay static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A, const PetscScalar *array) { 1611d3042a70SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1612d3042a70SBarry Smith 1613d3042a70SBarry Smith PetscFunctionBegin; 161428b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 161528b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 161628b400f6SJacob Faibussowitsch PetscCheck(!a->unplacedarray, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreArray() first"); 1617d3042a70SBarry Smith a->unplacedarray = a->v; 1618d3042a70SBarry Smith a->unplaced_user_alloc = a->user_alloc; 1619d3042a70SBarry Smith a->v = (PetscScalar *)array; 1620637a0070SStefano Zampini a->user_alloc = PETSC_TRUE; 1621ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA) 1622c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_CPU; 1623ca15aa20SStefano Zampini #endif 1624d3042a70SBarry Smith PetscFunctionReturn(0); 1625d3042a70SBarry Smith } 1626d3042a70SBarry Smith 16279371c9d4SSatish Balay static PetscErrorCode MatDenseResetArray_SeqDense(Mat A) { 1628d3042a70SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1629d3042a70SBarry Smith 1630d3042a70SBarry Smith PetscFunctionBegin; 163128b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 163228b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 1633d3042a70SBarry Smith a->v = a->unplacedarray; 1634d3042a70SBarry Smith a->user_alloc = a->unplaced_user_alloc; 1635d3042a70SBarry Smith a->unplacedarray = NULL; 1636ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA) 1637c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_CPU; 1638ca15aa20SStefano Zampini #endif 1639d3042a70SBarry Smith PetscFunctionReturn(0); 1640d3042a70SBarry Smith } 1641d3042a70SBarry Smith 16429371c9d4SSatish Balay static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A, const PetscScalar *array) { 1643d5ea218eSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1644d5ea218eSStefano Zampini 1645d5ea218eSStefano Zampini PetscFunctionBegin; 164628b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 164728b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 16489566063dSJacob Faibussowitsch if (!a->user_alloc) PetscCall(PetscFree(a->v)); 1649d5ea218eSStefano Zampini a->v = (PetscScalar *)array; 1650d5ea218eSStefano Zampini a->user_alloc = PETSC_FALSE; 1651d5ea218eSStefano Zampini #if defined(PETSC_HAVE_CUDA) 1652d5ea218eSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 1653d5ea218eSStefano Zampini #endif 1654d5ea218eSStefano Zampini PetscFunctionReturn(0); 1655d5ea218eSStefano Zampini } 1656d5ea218eSStefano Zampini 16579371c9d4SSatish Balay PetscErrorCode MatDestroy_SeqDense(Mat mat) { 1658ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)mat->data; 165990f02eecSBarry Smith 16603a40ed3dSBarry Smith PetscFunctionBegin; 1661aa482453SBarry Smith #if defined(PETSC_USE_LOG) 1662c0aa6a63SJacob Faibussowitsch PetscLogObjectState((PetscObject)mat, "Rows %" PetscInt_FMT " Cols %" PetscInt_FMT, mat->rmap->n, mat->cmap->n); 1663a5a9c739SBarry Smith #endif 16649566063dSJacob Faibussowitsch PetscCall(VecDestroy(&(l->qrrhs))); 16659566063dSJacob Faibussowitsch PetscCall(PetscFree(l->tau)); 16669566063dSJacob Faibussowitsch PetscCall(PetscFree(l->pivots)); 16679566063dSJacob Faibussowitsch PetscCall(PetscFree(l->fwork)); 16689566063dSJacob Faibussowitsch PetscCall(MatDestroy(&l->ptapwork)); 16699566063dSJacob Faibussowitsch if (!l->user_alloc) PetscCall(PetscFree(l->v)); 16709566063dSJacob Faibussowitsch if (!l->unplaced_user_alloc) PetscCall(PetscFree(l->unplacedarray)); 167128b400f6SJacob Faibussowitsch PetscCheck(!l->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 167228b400f6SJacob Faibussowitsch PetscCheck(!l->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 16739566063dSJacob Faibussowitsch PetscCall(VecDestroy(&l->cvec)); 16749566063dSJacob Faibussowitsch PetscCall(MatDestroy(&l->cmat)); 16759566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->data)); 1676dbd8c25aSHong Zhang 16779566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)mat, NULL)); 16789566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactor_C", NULL)); 16792e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorSymbolic_C", NULL)); 16802e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorNumeric_C", NULL)); 16819566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetLDA_C", NULL)); 16829566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseSetLDA_C", NULL)); 16839566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArray_C", NULL)); 16849566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArray_C", NULL)); 16859566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDensePlaceArray_C", NULL)); 16869566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseResetArray_C", NULL)); 16879566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseReplaceArray_C", NULL)); 16889566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayRead_C", NULL)); 16899566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayRead_C", NULL)); 16909566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayWrite_C", NULL)); 16919566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayWrite_C", NULL)); 16929566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqaij_C", NULL)); 16938baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 16949566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_elemental_C", NULL)); 16958baccfbdSHong Zhang #endif 1696d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 16979566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_scalapack_C", NULL)); 1698d24d4204SJose E. Roman #endif 16992bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA) 17009566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensecuda_C", NULL)); 17019566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", NULL)); 17029566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdense_C", NULL)); 17032e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensecuda_C", NULL)); 17042bf066beSStefano Zampini #endif 17059566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatSeqDenseSetPreallocation_C", NULL)); 17069566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqaij_seqdense_C", NULL)); 17079566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdense_C", NULL)); 17089566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqbaij_seqdense_C", NULL)); 17099566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqsbaij_seqdense_C", NULL)); 171052c5f739Sprj- 17119566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumn_C", NULL)); 17129566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumn_C", NULL)); 17139566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVec_C", NULL)); 17149566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVec_C", NULL)); 17159566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecRead_C", NULL)); 17169566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecRead_C", NULL)); 17179566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecWrite_C", NULL)); 17189566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecWrite_C", NULL)); 17199566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetSubMatrix_C", NULL)); 17209566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreSubMatrix_C", NULL)); 17213a40ed3dSBarry Smith PetscFunctionReturn(0); 1722289bc588SBarry Smith } 1723289bc588SBarry Smith 17249371c9d4SSatish Balay static PetscErrorCode MatTranspose_SeqDense(Mat A, MatReuse reuse, Mat *matout) { 1725c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 17266536e3caSStefano Zampini PetscInt k, j, m = A->rmap->n, M = mat->lda, n = A->cmap->n; 172787828ca2SBarry Smith PetscScalar *v, tmp; 172848b35521SBarry Smith 17293a40ed3dSBarry Smith PetscFunctionBegin; 17307fb60732SBarry Smith if (reuse == MAT_REUSE_MATRIX) PetscCall(MatTransposeCheckNonzeroState_Private(A, *matout)); 17316536e3caSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 17326536e3caSStefano Zampini if (m == n) { /* in place transpose */ 17339566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 1734d3e5ee88SLois Curfman McInnes for (j = 0; j < m; j++) { 1735289bc588SBarry Smith for (k = 0; k < j; k++) { 17361b807ce4Svictorle tmp = v[j + k * M]; 17371b807ce4Svictorle v[j + k * M] = v[k + j * M]; 17381b807ce4Svictorle v[k + j * M] = tmp; 1739289bc588SBarry Smith } 1740289bc588SBarry Smith } 17419566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 17426536e3caSStefano Zampini } else { /* reuse memory, temporary allocates new memory */ 17436536e3caSStefano Zampini PetscScalar *v2; 17446536e3caSStefano Zampini PetscLayout tmplayout; 17456536e3caSStefano Zampini 17469566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((size_t)m * n, &v2)); 17479566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 17486536e3caSStefano Zampini for (j = 0; j < n; j++) { 17496536e3caSStefano Zampini for (k = 0; k < m; k++) v2[j + (size_t)k * n] = v[k + (size_t)j * M]; 17506536e3caSStefano Zampini } 17519566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(v, v2, (size_t)m * n)); 17529566063dSJacob Faibussowitsch PetscCall(PetscFree(v2)); 17539566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 17546536e3caSStefano Zampini /* cleanup size dependent quantities */ 17559566063dSJacob Faibussowitsch PetscCall(VecDestroy(&mat->cvec)); 17569566063dSJacob Faibussowitsch PetscCall(MatDestroy(&mat->cmat)); 17579566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->pivots)); 17589566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->fwork)); 17599566063dSJacob Faibussowitsch PetscCall(MatDestroy(&mat->ptapwork)); 17606536e3caSStefano Zampini /* swap row/col layouts */ 17616536e3caSStefano Zampini mat->lda = n; 17626536e3caSStefano Zampini tmplayout = A->rmap; 17636536e3caSStefano Zampini A->rmap = A->cmap; 17646536e3caSStefano Zampini A->cmap = tmplayout; 17656536e3caSStefano Zampini } 17663a40ed3dSBarry Smith } else { /* out-of-place transpose */ 1767d3e5ee88SLois Curfman McInnes Mat tmat; 1768ec8511deSBarry Smith Mat_SeqDense *tmatd; 176987828ca2SBarry Smith PetscScalar *v2; 1770af36a384SStefano Zampini PetscInt M2; 1771ea709b57SSatish Balay 17726536e3caSStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 17739566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &tmat)); 17749566063dSJacob Faibussowitsch PetscCall(MatSetSizes(tmat, A->cmap->n, A->rmap->n, A->cmap->n, A->rmap->n)); 17759566063dSJacob Faibussowitsch PetscCall(MatSetType(tmat, ((PetscObject)A)->type_name)); 17769566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(tmat, NULL)); 1777ca15aa20SStefano Zampini } else tmat = *matout; 1778ca15aa20SStefano Zampini 17799566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&v)); 17809566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(tmat, &v2)); 1781ec8511deSBarry Smith tmatd = (Mat_SeqDense *)tmat->data; 1782ca15aa20SStefano Zampini M2 = tmatd->lda; 1783d3e5ee88SLois Curfman McInnes for (j = 0; j < n; j++) { 1784af36a384SStefano Zampini for (k = 0; k < m; k++) v2[j + k * M2] = v[k + j * M]; 1785d3e5ee88SLois Curfman McInnes } 17869566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(tmat, &v2)); 17879566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&v)); 17889566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(tmat, MAT_FINAL_ASSEMBLY)); 17899566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(tmat, MAT_FINAL_ASSEMBLY)); 17906536e3caSStefano Zampini *matout = tmat; 179148b35521SBarry Smith } 17923a40ed3dSBarry Smith PetscFunctionReturn(0); 1793289bc588SBarry Smith } 1794289bc588SBarry Smith 17959371c9d4SSatish Balay static PetscErrorCode MatEqual_SeqDense(Mat A1, Mat A2, PetscBool *flg) { 1796c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat1 = (Mat_SeqDense *)A1->data; 1797c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat2 = (Mat_SeqDense *)A2->data; 1798ca15aa20SStefano Zampini PetscInt i; 1799ca15aa20SStefano Zampini const PetscScalar *v1, *v2; 18009ea5d5aeSSatish Balay 18013a40ed3dSBarry Smith PetscFunctionBegin; 18029371c9d4SSatish Balay if (A1->rmap->n != A2->rmap->n) { 18039371c9d4SSatish Balay *flg = PETSC_FALSE; 18049371c9d4SSatish Balay PetscFunctionReturn(0); 18059371c9d4SSatish Balay } 18069371c9d4SSatish Balay if (A1->cmap->n != A2->cmap->n) { 18079371c9d4SSatish Balay *flg = PETSC_FALSE; 18089371c9d4SSatish Balay PetscFunctionReturn(0); 18099371c9d4SSatish Balay } 18109566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A1, &v1)); 18119566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A2, &v2)); 1812ca15aa20SStefano Zampini for (i = 0; i < A1->cmap->n; i++) { 18139566063dSJacob Faibussowitsch PetscCall(PetscArraycmp(v1, v2, A1->rmap->n, flg)); 1814ca15aa20SStefano Zampini if (*flg == PETSC_FALSE) PetscFunctionReturn(0); 1815ca15aa20SStefano Zampini v1 += mat1->lda; 1816ca15aa20SStefano Zampini v2 += mat2->lda; 18171b807ce4Svictorle } 18189566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A1, &v1)); 18199566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A2, &v2)); 182077c4ece6SBarry Smith *flg = PETSC_TRUE; 18213a40ed3dSBarry Smith PetscFunctionReturn(0); 1822289bc588SBarry Smith } 1823289bc588SBarry Smith 18249371c9d4SSatish Balay static PetscErrorCode MatGetDiagonal_SeqDense(Mat A, Vec v) { 1825c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 182613f74950SBarry Smith PetscInt i, n, len; 1827ca15aa20SStefano Zampini PetscScalar *x; 1828ca15aa20SStefano Zampini const PetscScalar *vv; 182944cd7ae7SLois Curfman McInnes 18303a40ed3dSBarry Smith PetscFunctionBegin; 18319566063dSJacob Faibussowitsch PetscCall(VecGetSize(v, &n)); 18329566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 1833d0f46423SBarry Smith len = PetscMin(A->rmap->n, A->cmap->n); 18349566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &vv)); 183508401ef6SPierre Jolivet PetscCheck(n == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming mat and vec"); 1836ad540459SPierre Jolivet for (i = 0; i < len; i++) x[i] = vv[i * mat->lda + i]; 18379566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &vv)); 18389566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 18393a40ed3dSBarry Smith PetscFunctionReturn(0); 1840289bc588SBarry Smith } 1841289bc588SBarry Smith 18429371c9d4SSatish Balay static PetscErrorCode MatDiagonalScale_SeqDense(Mat A, Vec ll, Vec rr) { 1843c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1844f1ceaac6SMatthew G. Knepley const PetscScalar *l, *r; 1845ca15aa20SStefano Zampini PetscScalar x, *v, *vv; 1846d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n; 184755659b69SBarry Smith 18483a40ed3dSBarry Smith PetscFunctionBegin; 18499566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &vv)); 185028988994SBarry Smith if (ll) { 18519566063dSJacob Faibussowitsch PetscCall(VecGetSize(ll, &m)); 18529566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(ll, &l)); 185308401ef6SPierre Jolivet PetscCheck(m == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Left scaling vec wrong size"); 1854da3a660dSBarry Smith for (i = 0; i < m; i++) { 1855da3a660dSBarry Smith x = l[i]; 1856ca15aa20SStefano Zampini v = vv + i; 18579371c9d4SSatish Balay for (j = 0; j < n; j++) { 18589371c9d4SSatish Balay (*v) *= x; 18599371c9d4SSatish Balay v += mat->lda; 18609371c9d4SSatish Balay } 1861da3a660dSBarry Smith } 18629566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(ll, &l)); 18639566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * n * m)); 1864da3a660dSBarry Smith } 186528988994SBarry Smith if (rr) { 18669566063dSJacob Faibussowitsch PetscCall(VecGetSize(rr, &n)); 18679566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(rr, &r)); 186808401ef6SPierre Jolivet PetscCheck(n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Right scaling vec wrong size"); 1869da3a660dSBarry Smith for (i = 0; i < n; i++) { 1870da3a660dSBarry Smith x = r[i]; 1871ca15aa20SStefano Zampini v = vv + i * mat->lda; 18722205254eSKarl Rupp for (j = 0; j < m; j++) (*v++) *= x; 1873da3a660dSBarry Smith } 18749566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(rr, &r)); 18759566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * n * m)); 1876da3a660dSBarry Smith } 18779566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &vv)); 18783a40ed3dSBarry Smith PetscFunctionReturn(0); 1879289bc588SBarry Smith } 1880289bc588SBarry Smith 18819371c9d4SSatish Balay PetscErrorCode MatNorm_SeqDense(Mat A, NormType type, PetscReal *nrm) { 1882c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1883ca15aa20SStefano Zampini PetscScalar *v, *vv; 1884329f5518SBarry Smith PetscReal sum = 0.0; 188575f6d85dSStefano Zampini PetscInt lda, m = A->rmap->n, i, j; 188655659b69SBarry Smith 18873a40ed3dSBarry Smith PetscFunctionBegin; 18889566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&vv)); 18899566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(A, &lda)); 1890ca15aa20SStefano Zampini v = vv; 1891289bc588SBarry Smith if (type == NORM_FROBENIUS) { 1892a5ce6ee0Svictorle if (lda > m) { 1893d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1894ca15aa20SStefano Zampini v = vv + j * lda; 1895a5ce6ee0Svictorle for (i = 0; i < m; i++) { 18969371c9d4SSatish Balay sum += PetscRealPart(PetscConj(*v) * (*v)); 18979371c9d4SSatish Balay v++; 1898a5ce6ee0Svictorle } 1899a5ce6ee0Svictorle } 1900a5ce6ee0Svictorle } else { 1901570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16) 1902570b7f6dSBarry Smith PetscBLASInt one = 1, cnt = A->cmap->n * A->rmap->n; 1903792fecdfSBarry Smith PetscCallBLAS("BLASnrm2", *nrm = BLASnrm2_(&cnt, v, &one)); 1904570b7f6dSBarry Smith } 1905570b7f6dSBarry Smith #else 1906d0f46423SBarry Smith for (i = 0; i < A->cmap->n * A->rmap->n; i++) { 19079371c9d4SSatish Balay sum += PetscRealPart(PetscConj(*v) * (*v)); 19089371c9d4SSatish Balay v++; 1909289bc588SBarry Smith } 1910a5ce6ee0Svictorle } 19118f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 1912570b7f6dSBarry Smith #endif 19139566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->cmap->n * A->rmap->n)); 19143a40ed3dSBarry Smith } else if (type == NORM_1) { 1915064f8208SBarry Smith *nrm = 0.0; 1916d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1917ca15aa20SStefano Zampini v = vv + j * mat->lda; 1918289bc588SBarry Smith sum = 0.0; 1919d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 19209371c9d4SSatish Balay sum += PetscAbsScalar(*v); 19219371c9d4SSatish Balay v++; 1922289bc588SBarry Smith } 1923064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 1924289bc588SBarry Smith } 19259566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n)); 19263a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 1927064f8208SBarry Smith *nrm = 0.0; 1928d0f46423SBarry Smith for (j = 0; j < A->rmap->n; j++) { 1929ca15aa20SStefano Zampini v = vv + j; 1930289bc588SBarry Smith sum = 0.0; 1931d0f46423SBarry Smith for (i = 0; i < A->cmap->n; i++) { 19329371c9d4SSatish Balay sum += PetscAbsScalar(*v); 19339371c9d4SSatish Balay v += mat->lda; 1934289bc588SBarry Smith } 1935064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 1936289bc588SBarry Smith } 19379566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n)); 1938e7e72b3dSBarry Smith } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "No two norm"); 19399566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&vv)); 19403a40ed3dSBarry Smith PetscFunctionReturn(0); 1941289bc588SBarry Smith } 1942289bc588SBarry Smith 19439371c9d4SSatish Balay static PetscErrorCode MatSetOption_SeqDense(Mat A, MatOption op, PetscBool flg) { 1944c0bbcb79SLois Curfman McInnes Mat_SeqDense *aij = (Mat_SeqDense *)A->data; 194567e560aaSBarry Smith 19463a40ed3dSBarry Smith PetscFunctionBegin; 1947b5a2b587SKris Buschelman switch (op) { 19489371c9d4SSatish Balay case MAT_ROW_ORIENTED: aij->roworiented = flg; break; 1949512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 1950b5a2b587SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 19513971808eSMatthew Knepley case MAT_NEW_NONZERO_ALLOCATION_ERR: 19528c78258cSHong Zhang case MAT_FORCE_DIAGONAL_ENTRIES: 195313fa8e87SLisandro Dalcin case MAT_KEEP_NONZERO_PATTERN: 1954b5a2b587SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 1955b5a2b587SKris Buschelman case MAT_USE_HASH_TABLE: 19560f8fb01aSBarry Smith case MAT_IGNORE_ZERO_ENTRIES: 19575021d80fSJed Brown case MAT_IGNORE_LOWER_TRIANGULAR: 19589371c9d4SSatish Balay case MAT_SORTED_FULL: PetscCall(PetscInfo(A, "Option %s ignored\n", MatOptions[op])); break; 19595021d80fSJed Brown case MAT_SPD: 196077e54ba9SKris Buschelman case MAT_SYMMETRIC: 196177e54ba9SKris Buschelman case MAT_STRUCTURALLY_SYMMETRIC: 19629a4540c5SBarry Smith case MAT_HERMITIAN: 19639a4540c5SBarry Smith case MAT_SYMMETRY_ETERNAL: 1964b94d7dedSBarry Smith case MAT_STRUCTURAL_SYMMETRY_ETERNAL: 19659371c9d4SSatish Balay case MAT_SPD_ETERNAL: break; 19669371c9d4SSatish Balay default: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "unknown option %s", MatOptions[op]); 19673a40ed3dSBarry Smith } 19683a40ed3dSBarry Smith PetscFunctionReturn(0); 1969289bc588SBarry Smith } 1970289bc588SBarry Smith 19719371c9d4SSatish Balay PetscErrorCode MatZeroEntries_SeqDense(Mat A) { 1972ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)A->data; 19733d8925e7SStefano Zampini PetscInt lda = l->lda, m = A->rmap->n, n = A->cmap->n, j; 1974ca15aa20SStefano Zampini PetscScalar *v; 19753a40ed3dSBarry Smith 19763a40ed3dSBarry Smith PetscFunctionBegin; 19779566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(A, &v)); 1978a5ce6ee0Svictorle if (lda > m) { 197948a46eb9SPierre Jolivet for (j = 0; j < n; j++) PetscCall(PetscArrayzero(v + j * lda, m)); 1980a5ce6ee0Svictorle } else { 19819566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(v, PetscInt64Mult(m, n))); 1982a5ce6ee0Svictorle } 19839566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(A, &v)); 19843a40ed3dSBarry Smith PetscFunctionReturn(0); 19856f0a148fSBarry Smith } 19866f0a148fSBarry Smith 19879371c9d4SSatish Balay static PetscErrorCode MatZeroRows_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) { 1988ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)A->data; 1989b9679d65SBarry Smith PetscInt m = l->lda, n = A->cmap->n, i, j; 1990ca15aa20SStefano Zampini PetscScalar *slot, *bb, *v; 199197b48c8fSBarry Smith const PetscScalar *xx; 199255659b69SBarry Smith 19933a40ed3dSBarry Smith PetscFunctionBegin; 199476bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 1995b9679d65SBarry Smith for (i = 0; i < N; i++) { 199608401ef6SPierre Jolivet PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed"); 199708401ef6SPierre 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); 1998b9679d65SBarry Smith } 199976bd3646SJed Brown } 2000ca15aa20SStefano Zampini if (!N) PetscFunctionReturn(0); 2001b9679d65SBarry Smith 200297b48c8fSBarry Smith /* fix right hand side if needed */ 200397b48c8fSBarry Smith if (x && b) { 20049566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 20059566063dSJacob Faibussowitsch PetscCall(VecGetArray(b, &bb)); 20062205254eSKarl Rupp for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]]; 20079566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 20089566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(b, &bb)); 200997b48c8fSBarry Smith } 201097b48c8fSBarry Smith 20119566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 20126f0a148fSBarry Smith for (i = 0; i < N; i++) { 2013ca15aa20SStefano Zampini slot = v + rows[i]; 20149371c9d4SSatish Balay for (j = 0; j < n; j++) { 20159371c9d4SSatish Balay *slot = 0.0; 20169371c9d4SSatish Balay slot += m; 20179371c9d4SSatish Balay } 20186f0a148fSBarry Smith } 2019f4df32b1SMatthew Knepley if (diag != 0.0) { 202008401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices"); 20216f0a148fSBarry Smith for (i = 0; i < N; i++) { 2022ca15aa20SStefano Zampini slot = v + (m + 1) * rows[i]; 2023f4df32b1SMatthew Knepley *slot = diag; 20246f0a148fSBarry Smith } 20256f0a148fSBarry Smith } 20269566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 20273a40ed3dSBarry Smith PetscFunctionReturn(0); 20286f0a148fSBarry Smith } 2029557bce09SLois Curfman McInnes 20309371c9d4SSatish Balay static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A, PetscInt *lda) { 203149a6ff4bSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 203249a6ff4bSBarry Smith 203349a6ff4bSBarry Smith PetscFunctionBegin; 203449a6ff4bSBarry Smith *lda = mat->lda; 203549a6ff4bSBarry Smith PetscFunctionReturn(0); 203649a6ff4bSBarry Smith } 203749a6ff4bSBarry Smith 20389371c9d4SSatish Balay PetscErrorCode MatDenseGetArray_SeqDense(Mat A, PetscScalar **array) { 2039c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 20403a40ed3dSBarry Smith 20413a40ed3dSBarry Smith PetscFunctionBegin; 204228b400f6SJacob Faibussowitsch PetscCheck(!mat->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 204364e87e97SBarry Smith *array = mat->v; 20443a40ed3dSBarry Smith PetscFunctionReturn(0); 204564e87e97SBarry Smith } 20460754003eSLois Curfman McInnes 20479371c9d4SSatish Balay PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A, PetscScalar **array) { 20483a40ed3dSBarry Smith PetscFunctionBegin; 204975f6d85dSStefano Zampini if (array) *array = NULL; 20503a40ed3dSBarry Smith PetscFunctionReturn(0); 2051ff14e315SSatish Balay } 20520754003eSLois Curfman McInnes 20530f74d2c1SSatish Balay /*@ 205411a5261eSBarry Smith MatDenseGetLDA - gets the leading dimension of the array returned from `MatDenseGetArray()` 205549a6ff4bSBarry Smith 2056ad16ce7aSStefano Zampini Not collective 205749a6ff4bSBarry Smith 205849a6ff4bSBarry Smith Input Parameter: 205911a5261eSBarry Smith . mat - a `MATDENSE` or `MATDENSECUDA` matrix 206049a6ff4bSBarry Smith 206149a6ff4bSBarry Smith Output Parameter: 206249a6ff4bSBarry Smith . lda - the leading dimension 206349a6ff4bSBarry Smith 206449a6ff4bSBarry Smith Level: intermediate 206549a6ff4bSBarry Smith 206611a5261eSBarry Smith .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseSetLDA()` 206749a6ff4bSBarry Smith @*/ 20689371c9d4SSatish Balay PetscErrorCode MatDenseGetLDA(Mat A, PetscInt *lda) { 206949a6ff4bSBarry Smith PetscFunctionBegin; 2070d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2071dadcf809SJacob Faibussowitsch PetscValidIntPointer(lda, 2); 207275f6d85dSStefano Zampini MatCheckPreallocated(A, 1); 2073cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetLDA_C", (Mat, PetscInt *), (A, lda)); 207449a6ff4bSBarry Smith PetscFunctionReturn(0); 207549a6ff4bSBarry Smith } 207649a6ff4bSBarry Smith 20770f74d2c1SSatish Balay /*@ 207811a5261eSBarry Smith MatDenseSetLDA - Sets the leading dimension of the array used by the `MATDENSE` matrix 2079ad16ce7aSStefano Zampini 2080ad16ce7aSStefano Zampini Not collective 2081ad16ce7aSStefano Zampini 2082d8d19677SJose E. Roman Input Parameters: 208311a5261eSBarry Smith + mat - a `MATDENSE` or `MATDENSECUDA` matrix 2084ad16ce7aSStefano Zampini - lda - the leading dimension 2085ad16ce7aSStefano Zampini 2086ad16ce7aSStefano Zampini Level: intermediate 2087ad16ce7aSStefano Zampini 208811a5261eSBarry Smith .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetLDA()` 2089ad16ce7aSStefano Zampini @*/ 20909371c9d4SSatish Balay PetscErrorCode MatDenseSetLDA(Mat A, PetscInt lda) { 2091ad16ce7aSStefano Zampini PetscFunctionBegin; 2092ad16ce7aSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2093cac4c232SBarry Smith PetscTryMethod(A, "MatDenseSetLDA_C", (Mat, PetscInt), (A, lda)); 2094ad16ce7aSStefano Zampini PetscFunctionReturn(0); 2095ad16ce7aSStefano Zampini } 2096ad16ce7aSStefano Zampini 2097ad16ce7aSStefano Zampini /*@C 209811a5261eSBarry Smith MatDenseGetArray - gives read-write access to the array where the data for a `MATDENSE` matrix is stored 209973a71a0fSBarry Smith 210011a5261eSBarry Smith Logically Collective on A 210173a71a0fSBarry Smith 210273a71a0fSBarry Smith Input Parameter: 21036947451fSStefano Zampini . mat - a dense matrix 210473a71a0fSBarry Smith 210573a71a0fSBarry Smith Output Parameter: 210673a71a0fSBarry Smith . array - pointer to the data 210773a71a0fSBarry Smith 210873a71a0fSBarry Smith Level: intermediate 210973a71a0fSBarry Smith 211011a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 211173a71a0fSBarry Smith @*/ 21129371c9d4SSatish Balay PetscErrorCode MatDenseGetArray(Mat A, PetscScalar **array) { 211373a71a0fSBarry Smith PetscFunctionBegin; 2114d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2115d5ea218eSStefano Zampini PetscValidPointer(array, 2); 2116cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array)); 211773a71a0fSBarry Smith PetscFunctionReturn(0); 211873a71a0fSBarry Smith } 211973a71a0fSBarry Smith 2120dec5eb66SMatthew G Knepley /*@C 212111a5261eSBarry Smith MatDenseRestoreArray - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArray()` 212273a71a0fSBarry Smith 212311a5261eSBarry Smith Logically Collective on A 21248572280aSBarry Smith 21258572280aSBarry Smith Input Parameters: 21266947451fSStefano Zampini + mat - a dense matrix 2127742765d3SMatthew Knepley - array - pointer to the data (may be NULL) 21288572280aSBarry Smith 21298572280aSBarry Smith Level: intermediate 21308572280aSBarry Smith 213111a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 21328572280aSBarry Smith @*/ 21339371c9d4SSatish Balay PetscErrorCode MatDenseRestoreArray(Mat A, PetscScalar **array) { 21348572280aSBarry Smith PetscFunctionBegin; 2135d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2136d5ea218eSStefano Zampini PetscValidPointer(array, 2); 2137cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array)); 21389566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)A)); 2139637a0070SStefano Zampini #if defined(PETSC_HAVE_CUDA) 2140637a0070SStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 2141637a0070SStefano Zampini #endif 21428572280aSBarry Smith PetscFunctionReturn(0); 21438572280aSBarry Smith } 21448572280aSBarry Smith 21458572280aSBarry Smith /*@C 214611a5261eSBarry Smith MatDenseGetArrayRead - gives read-only access to the array where the data for a `MATDENSE` matrix is stored 21478572280aSBarry Smith 21488572280aSBarry Smith Not Collective 21498572280aSBarry Smith 21508572280aSBarry Smith Input Parameter: 21516947451fSStefano Zampini . mat - a dense matrix 21528572280aSBarry Smith 21538572280aSBarry Smith Output Parameter: 21548572280aSBarry Smith . array - pointer to the data 21558572280aSBarry Smith 21568572280aSBarry Smith Level: intermediate 21578572280aSBarry Smith 215811a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 21598572280aSBarry Smith @*/ 21609371c9d4SSatish Balay PetscErrorCode MatDenseGetArrayRead(Mat A, const PetscScalar **array) { 21618572280aSBarry Smith PetscFunctionBegin; 2162d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2163d5ea218eSStefano Zampini PetscValidPointer(array, 2); 2164cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, const PetscScalar **), (A, array)); 21658572280aSBarry Smith PetscFunctionReturn(0); 21668572280aSBarry Smith } 21678572280aSBarry Smith 21688572280aSBarry Smith /*@C 216911a5261eSBarry Smith MatDenseRestoreArrayRead - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayRead()` 21708572280aSBarry Smith 217173a71a0fSBarry Smith Not Collective 217273a71a0fSBarry Smith 217373a71a0fSBarry Smith Input Parameters: 21746947451fSStefano Zampini + mat - a dense matrix 2175742765d3SMatthew Knepley - array - pointer to the data (may be NULL) 217673a71a0fSBarry Smith 217773a71a0fSBarry Smith Level: intermediate 217873a71a0fSBarry Smith 217911a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 218073a71a0fSBarry Smith @*/ 21819371c9d4SSatish Balay PetscErrorCode MatDenseRestoreArrayRead(Mat A, const PetscScalar **array) { 218273a71a0fSBarry Smith PetscFunctionBegin; 2183d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2184d5ea218eSStefano Zampini PetscValidPointer(array, 2); 2185cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, const PetscScalar **), (A, array)); 218673a71a0fSBarry Smith PetscFunctionReturn(0); 218773a71a0fSBarry Smith } 218873a71a0fSBarry Smith 21896947451fSStefano Zampini /*@C 219011a5261eSBarry Smith MatDenseGetArrayWrite - gives write-only access to the array where the data for a `MATDENSE` matrix is stored 21916947451fSStefano Zampini 21926947451fSStefano Zampini Not Collective 21936947451fSStefano Zampini 21946947451fSStefano Zampini Input Parameter: 21956947451fSStefano Zampini . mat - a dense matrix 21966947451fSStefano Zampini 21976947451fSStefano Zampini Output Parameter: 21986947451fSStefano Zampini . array - pointer to the data 21996947451fSStefano Zampini 22006947451fSStefano Zampini Level: intermediate 22016947451fSStefano Zampini 220211a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()` 22036947451fSStefano Zampini @*/ 22049371c9d4SSatish Balay PetscErrorCode MatDenseGetArrayWrite(Mat A, PetscScalar **array) { 22056947451fSStefano Zampini PetscFunctionBegin; 2206d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2207d5ea218eSStefano Zampini PetscValidPointer(array, 2); 2208cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array)); 22096947451fSStefano Zampini PetscFunctionReturn(0); 22106947451fSStefano Zampini } 22116947451fSStefano Zampini 22126947451fSStefano Zampini /*@C 221311a5261eSBarry Smith MatDenseRestoreArrayWrite - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayWrite()` 22146947451fSStefano Zampini 22156947451fSStefano Zampini Not Collective 22166947451fSStefano Zampini 22176947451fSStefano Zampini Input Parameters: 22186947451fSStefano Zampini + mat - a dense matrix 2219742765d3SMatthew Knepley - array - pointer to the data (may be NULL) 22206947451fSStefano Zampini 22216947451fSStefano Zampini Level: intermediate 22226947451fSStefano Zampini 222311a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()` 22246947451fSStefano Zampini @*/ 22259371c9d4SSatish Balay PetscErrorCode MatDenseRestoreArrayWrite(Mat A, PetscScalar **array) { 22266947451fSStefano Zampini PetscFunctionBegin; 2227d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2228d5ea218eSStefano Zampini PetscValidPointer(array, 2); 2229cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array)); 22309566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)A)); 22316947451fSStefano Zampini #if defined(PETSC_HAVE_CUDA) 22326947451fSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 22336947451fSStefano Zampini #endif 22346947451fSStefano Zampini PetscFunctionReturn(0); 22356947451fSStefano Zampini } 22366947451fSStefano Zampini 22379371c9d4SSatish Balay static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A, IS isrow, IS iscol, MatReuse scall, Mat *B) { 2238c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 2239bf5a80bcSToby Isaac PetscInt i, j, nrows, ncols, ldb; 22405d0c19d7SBarry Smith const PetscInt *irow, *icol; 224187828ca2SBarry Smith PetscScalar *av, *bv, *v = mat->v; 22420754003eSLois Curfman McInnes Mat newmat; 22430754003eSLois Curfman McInnes 22443a40ed3dSBarry Smith PetscFunctionBegin; 22459566063dSJacob Faibussowitsch PetscCall(ISGetIndices(isrow, &irow)); 22469566063dSJacob Faibussowitsch PetscCall(ISGetIndices(iscol, &icol)); 22479566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(isrow, &nrows)); 22489566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(iscol, &ncols)); 22490754003eSLois Curfman McInnes 2250182d2002SSatish Balay /* Check submatrixcall */ 2251182d2002SSatish Balay if (scall == MAT_REUSE_MATRIX) { 225213f74950SBarry Smith PetscInt n_cols, n_rows; 22539566063dSJacob Faibussowitsch PetscCall(MatGetSize(*B, &n_rows, &n_cols)); 225421a2c019SBarry Smith if (n_rows != nrows || n_cols != ncols) { 2255f746d493SDmitry Karpeev /* resize the result matrix to match number of requested rows/columns */ 22569566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*B, nrows, ncols, nrows, ncols)); 225721a2c019SBarry Smith } 2258182d2002SSatish Balay newmat = *B; 2259182d2002SSatish Balay } else { 22600754003eSLois Curfman McInnes /* Create and fill new matrix */ 22619566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &newmat)); 22629566063dSJacob Faibussowitsch PetscCall(MatSetSizes(newmat, nrows, ncols, nrows, ncols)); 22639566063dSJacob Faibussowitsch PetscCall(MatSetType(newmat, ((PetscObject)A)->type_name)); 22649566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(newmat, NULL)); 2265182d2002SSatish Balay } 2266182d2002SSatish Balay 2267182d2002SSatish Balay /* Now extract the data pointers and do the copy,column at a time */ 22689566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(newmat, &bv)); 22699566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(newmat, &ldb)); 2270182d2002SSatish Balay for (i = 0; i < ncols; i++) { 22716de62eeeSBarry Smith av = v + mat->lda * icol[i]; 2272ca15aa20SStefano Zampini for (j = 0; j < nrows; j++) bv[j] = av[irow[j]]; 2273bf5a80bcSToby Isaac bv += ldb; 22740754003eSLois Curfman McInnes } 22759566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(newmat, &bv)); 2276182d2002SSatish Balay 2277182d2002SSatish Balay /* Assemble the matrices so that the correct flags are set */ 22789566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(newmat, MAT_FINAL_ASSEMBLY)); 22799566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(newmat, MAT_FINAL_ASSEMBLY)); 22800754003eSLois Curfman McInnes 22810754003eSLois Curfman McInnes /* Free work space */ 22829566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(isrow, &irow)); 22839566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(iscol, &icol)); 2284182d2002SSatish Balay *B = newmat; 22853a40ed3dSBarry Smith PetscFunctionReturn(0); 22860754003eSLois Curfman McInnes } 22870754003eSLois Curfman McInnes 22889371c9d4SSatish Balay static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A, PetscInt n, const IS irow[], const IS icol[], MatReuse scall, Mat *B[]) { 228913f74950SBarry Smith PetscInt i; 2290905e6a2fSBarry Smith 22913a40ed3dSBarry Smith PetscFunctionBegin; 229248a46eb9SPierre Jolivet if (scall == MAT_INITIAL_MATRIX) PetscCall(PetscCalloc1(n, B)); 2293905e6a2fSBarry Smith 229448a46eb9SPierre Jolivet for (i = 0; i < n; i++) PetscCall(MatCreateSubMatrix_SeqDense(A, irow[i], icol[i], scall, &(*B)[i])); 22953a40ed3dSBarry Smith PetscFunctionReturn(0); 2296905e6a2fSBarry Smith } 2297905e6a2fSBarry Smith 22989371c9d4SSatish Balay static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat, MatAssemblyType mode) { 2299c0aa2d19SHong Zhang PetscFunctionBegin; 2300c0aa2d19SHong Zhang PetscFunctionReturn(0); 2301c0aa2d19SHong Zhang } 2302c0aa2d19SHong Zhang 23039371c9d4SSatish Balay static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat, MatAssemblyType mode) { 2304c0aa2d19SHong Zhang PetscFunctionBegin; 2305c0aa2d19SHong Zhang PetscFunctionReturn(0); 2306c0aa2d19SHong Zhang } 2307c0aa2d19SHong Zhang 23089371c9d4SSatish Balay PetscErrorCode MatCopy_SeqDense(Mat A, Mat B, MatStructure str) { 23094b0e389bSBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data; 2310ca15aa20SStefano Zampini const PetscScalar *va; 2311ca15aa20SStefano Zampini PetscScalar *vb; 2312d0f46423SBarry Smith PetscInt lda1 = a->lda, lda2 = b->lda, m = A->rmap->n, n = A->cmap->n, j; 23133a40ed3dSBarry Smith 23143a40ed3dSBarry Smith PetscFunctionBegin; 231533f4a19fSKris Buschelman /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */ 231633f4a19fSKris Buschelman if (A->ops->copy != B->ops->copy) { 23179566063dSJacob Faibussowitsch PetscCall(MatCopy_Basic(A, B, str)); 23183a40ed3dSBarry Smith PetscFunctionReturn(0); 23193a40ed3dSBarry Smith } 2320aed4548fSBarry Smith PetscCheck(m == B->rmap->n && n == B->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "size(B) != size(A)"); 23219566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &va)); 23229566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(B, &vb)); 2323a5ce6ee0Svictorle if (lda1 > m || lda2 > m) { 232448a46eb9SPierre Jolivet for (j = 0; j < n; j++) PetscCall(PetscArraycpy(vb + j * lda2, va + j * lda1, m)); 2325a5ce6ee0Svictorle } else { 23269566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(vb, va, A->rmap->n * A->cmap->n)); 2327a5ce6ee0Svictorle } 23289566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(B, &vb)); 23299566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &va)); 23309566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 23319566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 2332273d9f13SBarry Smith PetscFunctionReturn(0); 2333273d9f13SBarry Smith } 2334273d9f13SBarry Smith 23359371c9d4SSatish Balay PetscErrorCode MatSetUp_SeqDense(Mat A) { 2336273d9f13SBarry Smith PetscFunctionBegin; 23379566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 23389566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 233948a46eb9SPierre Jolivet if (!A->preallocated) PetscCall(MatSeqDenseSetPreallocation(A, NULL)); 23403a40ed3dSBarry Smith PetscFunctionReturn(0); 23414b0e389bSBarry Smith } 23424b0e389bSBarry Smith 23439371c9d4SSatish Balay static PetscErrorCode MatConjugate_SeqDense(Mat A) { 23444396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 234506c5243aSJose E. Roman PetscInt i, j; 23464396437dSToby Isaac PetscInt min = PetscMin(A->rmap->n, A->cmap->n); 2347ca15aa20SStefano Zampini PetscScalar *aa; 2348ba337c44SJed Brown 2349ba337c44SJed Brown PetscFunctionBegin; 23509566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 235106c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 235206c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscConj(aa[i + j * mat->lda]); 235306c5243aSJose E. Roman } 23549566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 23559371c9d4SSatish Balay if (mat->tau) 23569371c9d4SSatish Balay for (i = 0; i < min; i++) mat->tau[i] = PetscConj(mat->tau[i]); 2357ba337c44SJed Brown PetscFunctionReturn(0); 2358ba337c44SJed Brown } 2359ba337c44SJed Brown 23609371c9d4SSatish Balay static PetscErrorCode MatRealPart_SeqDense(Mat A) { 236106c5243aSJose E. Roman Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 236206c5243aSJose E. Roman PetscInt i, j; 2363ca15aa20SStefano Zampini PetscScalar *aa; 2364ba337c44SJed Brown 2365ba337c44SJed Brown PetscFunctionBegin; 23669566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 236706c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 236806c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscRealPart(aa[i + j * mat->lda]); 236906c5243aSJose E. Roman } 23709566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 2371ba337c44SJed Brown PetscFunctionReturn(0); 2372ba337c44SJed Brown } 2373ba337c44SJed Brown 23749371c9d4SSatish Balay static PetscErrorCode MatImaginaryPart_SeqDense(Mat A) { 237506c5243aSJose E. Roman Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 237606c5243aSJose E. Roman PetscInt i, j; 2377ca15aa20SStefano Zampini PetscScalar *aa; 2378ba337c44SJed Brown 2379ba337c44SJed Brown PetscFunctionBegin; 23809566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 238106c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 238206c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscImaginaryPart(aa[i + j * mat->lda]); 238306c5243aSJose E. Roman } 23849566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 2385ba337c44SJed Brown PetscFunctionReturn(0); 2386ba337c44SJed Brown } 2387284134d9SBarry Smith 2388a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/ 23899371c9d4SSatish Balay PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) { 2390d0f46423SBarry Smith PetscInt m = A->rmap->n, n = B->cmap->n; 23917a3c3d58SStefano Zampini PetscBool cisdense; 2392a9fe9ddaSSatish Balay 2393ee16a9a1SHong Zhang PetscFunctionBegin; 23949566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 23959566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 23967a3c3d58SStefano Zampini if (!cisdense) { 23977a3c3d58SStefano Zampini PetscBool flg; 23987a3c3d58SStefano Zampini 23999566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 24009566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 24017a3c3d58SStefano Zampini } 24029566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 2403ee16a9a1SHong Zhang PetscFunctionReturn(0); 2404ee16a9a1SHong Zhang } 2405a9fe9ddaSSatish Balay 24069371c9d4SSatish Balay PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) { 24076718818eSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data, *c = (Mat_SeqDense *)C->data; 24080805154bSBarry Smith PetscBLASInt m, n, k; 2409ca15aa20SStefano Zampini const PetscScalar *av, *bv; 2410ca15aa20SStefano Zampini PetscScalar *cv; 2411a9fe9ddaSSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 2412a9fe9ddaSSatish Balay 2413a9fe9ddaSSatish Balay PetscFunctionBegin; 24149566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 24159566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 24169566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 241749d0e964SStefano Zampini if (!m || !n || !k) PetscFunctionReturn(0); 24189566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 24199566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 24209566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2421792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("N", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 24229566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 24239566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 24249566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 24259566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 2426a9fe9ddaSSatish Balay PetscFunctionReturn(0); 2427a9fe9ddaSSatish Balay } 2428a9fe9ddaSSatish Balay 24299371c9d4SSatish Balay PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) { 243069f65d41SStefano Zampini PetscInt m = A->rmap->n, n = B->rmap->n; 24317a3c3d58SStefano Zampini PetscBool cisdense; 243269f65d41SStefano Zampini 243369f65d41SStefano Zampini PetscFunctionBegin; 24349566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 24359566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 24367a3c3d58SStefano Zampini if (!cisdense) { 24377a3c3d58SStefano Zampini PetscBool flg; 24387a3c3d58SStefano Zampini 24399566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 24409566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 24417a3c3d58SStefano Zampini } 24429566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 244369f65d41SStefano Zampini PetscFunctionReturn(0); 244469f65d41SStefano Zampini } 244569f65d41SStefano Zampini 24469371c9d4SSatish Balay PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) { 244769f65d41SStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 244869f65d41SStefano Zampini Mat_SeqDense *b = (Mat_SeqDense *)B->data; 244969f65d41SStefano Zampini Mat_SeqDense *c = (Mat_SeqDense *)C->data; 24506718818eSStefano Zampini const PetscScalar *av, *bv; 24516718818eSStefano Zampini PetscScalar *cv; 245269f65d41SStefano Zampini PetscBLASInt m, n, k; 245369f65d41SStefano Zampini PetscScalar _DOne = 1.0, _DZero = 0.0; 245469f65d41SStefano Zampini 245569f65d41SStefano Zampini PetscFunctionBegin; 24569566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 24579566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 24589566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 245949d0e964SStefano Zampini if (!m || !n || !k) PetscFunctionReturn(0); 24609566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 24619566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 24629566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2463792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("N", "T", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 24649566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 24659566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 24669566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 24679566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 246869f65d41SStefano Zampini PetscFunctionReturn(0); 246969f65d41SStefano Zampini } 247069f65d41SStefano Zampini 24719371c9d4SSatish Balay PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) { 2472d0f46423SBarry Smith PetscInt m = A->cmap->n, n = B->cmap->n; 24737a3c3d58SStefano Zampini PetscBool cisdense; 2474a9fe9ddaSSatish Balay 2475ee16a9a1SHong Zhang PetscFunctionBegin; 24769566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 24779566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 24787a3c3d58SStefano Zampini if (!cisdense) { 24797a3c3d58SStefano Zampini PetscBool flg; 24807a3c3d58SStefano Zampini 24819566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 24829566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 24837a3c3d58SStefano Zampini } 24849566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 2485ee16a9a1SHong Zhang PetscFunctionReturn(0); 2486ee16a9a1SHong Zhang } 2487a9fe9ddaSSatish Balay 24889371c9d4SSatish Balay PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) { 2489a9fe9ddaSSatish Balay Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2490a9fe9ddaSSatish Balay Mat_SeqDense *b = (Mat_SeqDense *)B->data; 2491a9fe9ddaSSatish Balay Mat_SeqDense *c = (Mat_SeqDense *)C->data; 24926718818eSStefano Zampini const PetscScalar *av, *bv; 24936718818eSStefano Zampini PetscScalar *cv; 24940805154bSBarry Smith PetscBLASInt m, n, k; 2495a9fe9ddaSSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 2496a9fe9ddaSSatish Balay 2497a9fe9ddaSSatish Balay PetscFunctionBegin; 24989566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 24999566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 25009566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &k)); 250149d0e964SStefano Zampini if (!m || !n || !k) PetscFunctionReturn(0); 25029566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 25039566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 25049566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2505792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("T", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 25069566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 25079566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 25089566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 25099566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 2510a9fe9ddaSSatish Balay PetscFunctionReturn(0); 2511a9fe9ddaSSatish Balay } 2512985db425SBarry Smith 25134222ddf1SHong Zhang /* ----------------------------------------------- */ 25149371c9d4SSatish Balay static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C) { 25154222ddf1SHong Zhang PetscFunctionBegin; 25164222ddf1SHong Zhang C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense; 25174222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AB; 25184222ddf1SHong Zhang PetscFunctionReturn(0); 25194222ddf1SHong Zhang } 25204222ddf1SHong Zhang 25219371c9d4SSatish Balay static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C) { 25224222ddf1SHong Zhang PetscFunctionBegin; 25234222ddf1SHong Zhang C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense; 25244222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AtB; 25254222ddf1SHong Zhang PetscFunctionReturn(0); 25264222ddf1SHong Zhang } 25274222ddf1SHong Zhang 25289371c9d4SSatish Balay static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C) { 25294222ddf1SHong Zhang PetscFunctionBegin; 25304222ddf1SHong Zhang C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense; 25314222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_ABt; 25324222ddf1SHong Zhang PetscFunctionReturn(0); 25334222ddf1SHong Zhang } 25344222ddf1SHong Zhang 25359371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C) { 25364222ddf1SHong Zhang Mat_Product *product = C->product; 25374222ddf1SHong Zhang 25384222ddf1SHong Zhang PetscFunctionBegin; 25394222ddf1SHong Zhang switch (product->type) { 25409371c9d4SSatish Balay case MATPRODUCT_AB: PetscCall(MatProductSetFromOptions_SeqDense_AB(C)); break; 25419371c9d4SSatish Balay case MATPRODUCT_AtB: PetscCall(MatProductSetFromOptions_SeqDense_AtB(C)); break; 25429371c9d4SSatish Balay case MATPRODUCT_ABt: PetscCall(MatProductSetFromOptions_SeqDense_ABt(C)); break; 25439371c9d4SSatish Balay default: break; 25444222ddf1SHong Zhang } 25454222ddf1SHong Zhang PetscFunctionReturn(0); 25464222ddf1SHong Zhang } 25474222ddf1SHong Zhang /* ----------------------------------------------- */ 25484222ddf1SHong Zhang 25499371c9d4SSatish Balay static PetscErrorCode MatGetRowMax_SeqDense(Mat A, Vec v, PetscInt idx[]) { 2550985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2551d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2552985db425SBarry Smith PetscScalar *x; 2553ca15aa20SStefano Zampini const PetscScalar *aa; 2554985db425SBarry Smith 2555985db425SBarry Smith PetscFunctionBegin; 255628b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 25579566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 25589566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 25599566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 256008401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2561985db425SBarry Smith for (i = 0; i < m; i++) { 25629371c9d4SSatish Balay x[i] = aa[i]; 25639371c9d4SSatish Balay if (idx) idx[i] = 0; 2564985db425SBarry Smith for (j = 1; j < n; j++) { 25659371c9d4SSatish Balay if (PetscRealPart(x[i]) < PetscRealPart(aa[i + a->lda * j])) { 25669371c9d4SSatish Balay x[i] = aa[i + a->lda * j]; 25679371c9d4SSatish Balay if (idx) idx[i] = j; 25689371c9d4SSatish Balay } 2569985db425SBarry Smith } 2570985db425SBarry Smith } 25719566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 25729566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 2573985db425SBarry Smith PetscFunctionReturn(0); 2574985db425SBarry Smith } 2575985db425SBarry Smith 25769371c9d4SSatish Balay static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A, Vec v, PetscInt idx[]) { 2577985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2578d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2579985db425SBarry Smith PetscScalar *x; 2580985db425SBarry Smith PetscReal atmp; 2581ca15aa20SStefano Zampini const PetscScalar *aa; 2582985db425SBarry Smith 2583985db425SBarry Smith PetscFunctionBegin; 258428b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 25859566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 25869566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 25879566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 258808401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2589985db425SBarry Smith for (i = 0; i < m; i++) { 25909189402eSHong Zhang x[i] = PetscAbsScalar(aa[i]); 2591985db425SBarry Smith for (j = 1; j < n; j++) { 2592ca15aa20SStefano Zampini atmp = PetscAbsScalar(aa[i + a->lda * j]); 25939371c9d4SSatish Balay if (PetscAbsScalar(x[i]) < atmp) { 25949371c9d4SSatish Balay x[i] = atmp; 25959371c9d4SSatish Balay if (idx) idx[i] = j; 25969371c9d4SSatish Balay } 2597985db425SBarry Smith } 2598985db425SBarry Smith } 25999566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 26009566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 2601985db425SBarry Smith PetscFunctionReturn(0); 2602985db425SBarry Smith } 2603985db425SBarry Smith 26049371c9d4SSatish Balay static PetscErrorCode MatGetRowMin_SeqDense(Mat A, Vec v, PetscInt idx[]) { 2605985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2606d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2607985db425SBarry Smith PetscScalar *x; 2608ca15aa20SStefano Zampini const PetscScalar *aa; 2609985db425SBarry Smith 2610985db425SBarry Smith PetscFunctionBegin; 261128b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 26129566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 26139566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 26149566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 261508401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2616985db425SBarry Smith for (i = 0; i < m; i++) { 26179371c9d4SSatish Balay x[i] = aa[i]; 26189371c9d4SSatish Balay if (idx) idx[i] = 0; 2619985db425SBarry Smith for (j = 1; j < n; j++) { 26209371c9d4SSatish Balay if (PetscRealPart(x[i]) > PetscRealPart(aa[i + a->lda * j])) { 26219371c9d4SSatish Balay x[i] = aa[i + a->lda * j]; 26229371c9d4SSatish Balay if (idx) idx[i] = j; 26239371c9d4SSatish Balay } 2624985db425SBarry Smith } 2625985db425SBarry Smith } 26269566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 26279566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 2628985db425SBarry Smith PetscFunctionReturn(0); 2629985db425SBarry Smith } 2630985db425SBarry Smith 26319371c9d4SSatish Balay PetscErrorCode MatGetColumnVector_SeqDense(Mat A, Vec v, PetscInt col) { 26328d0534beSBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 26338d0534beSBarry Smith PetscScalar *x; 2634ca15aa20SStefano Zampini const PetscScalar *aa; 26358d0534beSBarry Smith 26368d0534beSBarry Smith PetscFunctionBegin; 263728b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 26389566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 26399566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 26409566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(x, aa + col * a->lda, A->rmap->n)); 26419566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 26429566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 26438d0534beSBarry Smith PetscFunctionReturn(0); 26448d0534beSBarry Smith } 26458d0534beSBarry Smith 26469371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatGetColumnReductions_SeqDense(Mat A, PetscInt type, PetscReal *reductions) { 26470716a85fSBarry Smith PetscInt i, j, m, n; 26481683a169SBarry Smith const PetscScalar *a; 26490716a85fSBarry Smith 26500716a85fSBarry Smith PetscFunctionBegin; 26519566063dSJacob Faibussowitsch PetscCall(MatGetSize(A, &m, &n)); 26529566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(reductions, n)); 26539566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &a)); 2654857cbf51SRichard Tran Mills if (type == NORM_2) { 26550716a85fSBarry Smith for (i = 0; i < n; i++) { 2656ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j] * a[j]); 26570716a85fSBarry Smith a += m; 26580716a85fSBarry Smith } 2659857cbf51SRichard Tran Mills } else if (type == NORM_1) { 26600716a85fSBarry Smith for (i = 0; i < n; i++) { 2661ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j]); 26620716a85fSBarry Smith a += m; 26630716a85fSBarry Smith } 2664857cbf51SRichard Tran Mills } else if (type == NORM_INFINITY) { 26650716a85fSBarry Smith for (i = 0; i < n; i++) { 2666ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] = PetscMax(PetscAbsScalar(a[j]), reductions[i]); 26670716a85fSBarry Smith a += m; 26680716a85fSBarry Smith } 2669857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_REALPART || type == REDUCTION_MEAN_REALPART) { 2670a873a8cdSSam Reynolds for (i = 0; i < n; i++) { 2671ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscRealPart(a[j]); 2672a873a8cdSSam Reynolds a += m; 2673a873a8cdSSam Reynolds } 2674857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_IMAGINARYPART || type == REDUCTION_MEAN_IMAGINARYPART) { 2675857cbf51SRichard Tran Mills for (i = 0; i < n; i++) { 2676ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscImaginaryPart(a[j]); 2677857cbf51SRichard Tran Mills a += m; 2678857cbf51SRichard Tran Mills } 2679857cbf51SRichard Tran Mills } else SETERRQ(PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Unknown reduction type"); 26809566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &a)); 2681857cbf51SRichard Tran Mills if (type == NORM_2) { 2682a873a8cdSSam Reynolds for (i = 0; i < n; i++) reductions[i] = PetscSqrtReal(reductions[i]); 2683857cbf51SRichard Tran Mills } else if (type == REDUCTION_MEAN_REALPART || type == REDUCTION_MEAN_IMAGINARYPART) { 2684a873a8cdSSam Reynolds for (i = 0; i < n; i++) reductions[i] /= m; 26850716a85fSBarry Smith } 26860716a85fSBarry Smith PetscFunctionReturn(0); 26870716a85fSBarry Smith } 26880716a85fSBarry Smith 26893faff063SStefano Zampini PetscErrorCode MatSetRandom_SeqDense(Mat x, PetscRandom rctx) { 269073a71a0fSBarry Smith PetscScalar *a; 2691637a0070SStefano Zampini PetscInt lda, m, n, i, j; 269273a71a0fSBarry Smith 269373a71a0fSBarry Smith PetscFunctionBegin; 26949566063dSJacob Faibussowitsch PetscCall(MatGetSize(x, &m, &n)); 26959566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(x, &lda)); 26963faff063SStefano Zampini PetscCall(MatDenseGetArrayWrite(x, &a)); 2697637a0070SStefano Zampini for (j = 0; j < n; j++) { 269848a46eb9SPierre Jolivet for (i = 0; i < m; i++) PetscCall(PetscRandomGetValue(rctx, a + j * lda + i)); 269973a71a0fSBarry Smith } 27003faff063SStefano Zampini PetscCall(MatDenseRestoreArrayWrite(x, &a)); 270173a71a0fSBarry Smith PetscFunctionReturn(0); 270273a71a0fSBarry Smith } 270373a71a0fSBarry Smith 27049371c9d4SSatish Balay static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A, PetscBool *missing, PetscInt *d) { 27053b49f96aSBarry Smith PetscFunctionBegin; 27063b49f96aSBarry Smith *missing = PETSC_FALSE; 27073b49f96aSBarry Smith PetscFunctionReturn(0); 27083b49f96aSBarry Smith } 270973a71a0fSBarry Smith 2710ca15aa20SStefano Zampini /* vals is not const */ 27119371c9d4SSatish Balay static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A, PetscInt col, PetscScalar **vals) { 271286aefd0dSHong Zhang Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2713ca15aa20SStefano Zampini PetscScalar *v; 271486aefd0dSHong Zhang 271586aefd0dSHong Zhang PetscFunctionBegin; 271628b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 27179566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 2718ca15aa20SStefano Zampini *vals = v + col * a->lda; 27199566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 272086aefd0dSHong Zhang PetscFunctionReturn(0); 272186aefd0dSHong Zhang } 272286aefd0dSHong Zhang 27239371c9d4SSatish Balay static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A, PetscScalar **vals) { 272486aefd0dSHong Zhang PetscFunctionBegin; 2725742765d3SMatthew Knepley if (vals) *vals = NULL; /* user cannot accidentally use the array later */ 272686aefd0dSHong Zhang PetscFunctionReturn(0); 272786aefd0dSHong Zhang } 2728abc3b08eSStefano Zampini 2729289bc588SBarry Smith /* -------------------------------------------------------------------*/ 2730a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqDense, 2731905e6a2fSBarry Smith MatGetRow_SeqDense, 2732905e6a2fSBarry Smith MatRestoreRow_SeqDense, 2733905e6a2fSBarry Smith MatMult_SeqDense, 273497304618SKris Buschelman /* 4*/ MatMultAdd_SeqDense, 27357c922b88SBarry Smith MatMultTranspose_SeqDense, 27367c922b88SBarry Smith MatMultTransposeAdd_SeqDense, 2737f4259b30SLisandro Dalcin NULL, 2738f4259b30SLisandro Dalcin NULL, 2739f4259b30SLisandro Dalcin NULL, 2740f4259b30SLisandro Dalcin /* 10*/ NULL, 2741905e6a2fSBarry Smith MatLUFactor_SeqDense, 2742905e6a2fSBarry Smith MatCholeskyFactor_SeqDense, 274341f059aeSBarry Smith MatSOR_SeqDense, 2744ec8511deSBarry Smith MatTranspose_SeqDense, 274597304618SKris Buschelman /* 15*/ MatGetInfo_SeqDense, 2746905e6a2fSBarry Smith MatEqual_SeqDense, 2747905e6a2fSBarry Smith MatGetDiagonal_SeqDense, 2748905e6a2fSBarry Smith MatDiagonalScale_SeqDense, 2749905e6a2fSBarry Smith MatNorm_SeqDense, 2750c0aa2d19SHong Zhang /* 20*/ MatAssemblyBegin_SeqDense, 2751c0aa2d19SHong Zhang MatAssemblyEnd_SeqDense, 2752905e6a2fSBarry Smith MatSetOption_SeqDense, 2753905e6a2fSBarry Smith MatZeroEntries_SeqDense, 2754d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqDense, 2755f4259b30SLisandro Dalcin NULL, 2756f4259b30SLisandro Dalcin NULL, 2757f4259b30SLisandro Dalcin NULL, 2758f4259b30SLisandro Dalcin NULL, 27594994cf47SJed Brown /* 29*/ MatSetUp_SeqDense, 2760f4259b30SLisandro Dalcin NULL, 2761f4259b30SLisandro Dalcin NULL, 2762f4259b30SLisandro Dalcin NULL, 2763f4259b30SLisandro Dalcin NULL, 2764d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqDense, 2765f4259b30SLisandro Dalcin NULL, 2766f4259b30SLisandro Dalcin NULL, 2767f4259b30SLisandro Dalcin NULL, 2768f4259b30SLisandro Dalcin NULL, 2769d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqDense, 27707dae84e0SHong Zhang MatCreateSubMatrices_SeqDense, 2771f4259b30SLisandro Dalcin NULL, 27724b0e389bSBarry Smith MatGetValues_SeqDense, 2773a5ae1ecdSBarry Smith MatCopy_SeqDense, 2774d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqDense, 2775a5ae1ecdSBarry Smith MatScale_SeqDense, 27762f605a99SJose E. Roman MatShift_SeqDense, 2777f4259b30SLisandro Dalcin NULL, 27783f49a652SStefano Zampini MatZeroRowsColumns_SeqDense, 277973a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqDense, 2780f4259b30SLisandro Dalcin NULL, 2781f4259b30SLisandro Dalcin NULL, 2782f4259b30SLisandro Dalcin NULL, 2783f4259b30SLisandro Dalcin NULL, 2784f4259b30SLisandro Dalcin /* 54*/ NULL, 2785f4259b30SLisandro Dalcin NULL, 2786f4259b30SLisandro Dalcin NULL, 2787f4259b30SLisandro Dalcin NULL, 2788f4259b30SLisandro Dalcin NULL, 2789023c16fcSToby Isaac /* 59*/ MatCreateSubMatrix_SeqDense, 2790e03a110bSBarry Smith MatDestroy_SeqDense, 2791e03a110bSBarry Smith MatView_SeqDense, 2792f4259b30SLisandro Dalcin NULL, 2793f4259b30SLisandro Dalcin NULL, 2794f4259b30SLisandro Dalcin /* 64*/ NULL, 2795f4259b30SLisandro Dalcin NULL, 2796f4259b30SLisandro Dalcin NULL, 2797f4259b30SLisandro Dalcin NULL, 2798f4259b30SLisandro Dalcin NULL, 2799d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqDense, 2800f4259b30SLisandro Dalcin NULL, 2801f4259b30SLisandro Dalcin NULL, 2802f4259b30SLisandro Dalcin NULL, 2803f4259b30SLisandro Dalcin NULL, 2804f4259b30SLisandro Dalcin /* 74*/ NULL, 2805f4259b30SLisandro Dalcin NULL, 2806f4259b30SLisandro Dalcin NULL, 2807f4259b30SLisandro Dalcin NULL, 2808f4259b30SLisandro Dalcin NULL, 2809f4259b30SLisandro Dalcin /* 79*/ NULL, 2810f4259b30SLisandro Dalcin NULL, 2811f4259b30SLisandro Dalcin NULL, 2812f4259b30SLisandro Dalcin NULL, 28135bba2384SShri Abhyankar /* 83*/ MatLoad_SeqDense, 2814637a0070SStefano Zampini MatIsSymmetric_SeqDense, 28151cbb95d3SBarry Smith MatIsHermitian_SeqDense, 2816f4259b30SLisandro Dalcin NULL, 2817f4259b30SLisandro Dalcin NULL, 2818f4259b30SLisandro Dalcin NULL, 2819f4259b30SLisandro Dalcin /* 89*/ NULL, 2820f4259b30SLisandro Dalcin NULL, 2821a9fe9ddaSSatish Balay MatMatMultNumeric_SeqDense_SeqDense, 2822f4259b30SLisandro Dalcin NULL, 2823f4259b30SLisandro Dalcin NULL, 2824f4259b30SLisandro Dalcin /* 94*/ NULL, 2825f4259b30SLisandro Dalcin NULL, 2826f4259b30SLisandro Dalcin NULL, 282769f65d41SStefano Zampini MatMatTransposeMultNumeric_SeqDense_SeqDense, 2828f4259b30SLisandro Dalcin NULL, 28294222ddf1SHong Zhang /* 99*/ MatProductSetFromOptions_SeqDense, 2830f4259b30SLisandro Dalcin NULL, 2831f4259b30SLisandro Dalcin NULL, 2832ba337c44SJed Brown MatConjugate_SeqDense, 2833f4259b30SLisandro Dalcin NULL, 2834f4259b30SLisandro Dalcin /*104*/ NULL, 2835ba337c44SJed Brown MatRealPart_SeqDense, 2836ba337c44SJed Brown MatImaginaryPart_SeqDense, 2837f4259b30SLisandro Dalcin NULL, 2838f4259b30SLisandro Dalcin NULL, 2839f4259b30SLisandro Dalcin /*109*/ NULL, 2840f4259b30SLisandro Dalcin NULL, 28418d0534beSBarry Smith MatGetRowMin_SeqDense, 2842aabbc4fbSShri Abhyankar MatGetColumnVector_SeqDense, 28433b49f96aSBarry Smith MatMissingDiagonal_SeqDense, 2844f4259b30SLisandro Dalcin /*114*/ NULL, 2845f4259b30SLisandro Dalcin NULL, 2846f4259b30SLisandro Dalcin NULL, 2847f4259b30SLisandro Dalcin NULL, 2848f4259b30SLisandro Dalcin NULL, 2849f4259b30SLisandro Dalcin /*119*/ NULL, 2850f4259b30SLisandro Dalcin NULL, 2851f4259b30SLisandro Dalcin NULL, 2852f4259b30SLisandro Dalcin NULL, 2853f4259b30SLisandro Dalcin NULL, 2854f4259b30SLisandro Dalcin /*124*/ NULL, 2855a873a8cdSSam Reynolds MatGetColumnReductions_SeqDense, 2856f4259b30SLisandro Dalcin NULL, 2857f4259b30SLisandro Dalcin NULL, 2858f4259b30SLisandro Dalcin NULL, 2859f4259b30SLisandro Dalcin /*129*/ NULL, 2860f4259b30SLisandro Dalcin NULL, 2861f4259b30SLisandro Dalcin NULL, 286275648e8dSHong Zhang MatTransposeMatMultNumeric_SeqDense_SeqDense, 2863f4259b30SLisandro Dalcin NULL, 2864f4259b30SLisandro Dalcin /*134*/ NULL, 2865f4259b30SLisandro Dalcin NULL, 2866f4259b30SLisandro Dalcin NULL, 2867f4259b30SLisandro Dalcin NULL, 2868f4259b30SLisandro Dalcin NULL, 2869f4259b30SLisandro Dalcin /*139*/ NULL, 2870f4259b30SLisandro Dalcin NULL, 2871f4259b30SLisandro Dalcin NULL, 2872f4259b30SLisandro Dalcin NULL, 2873f4259b30SLisandro Dalcin NULL, 28744222ddf1SHong Zhang MatCreateMPIMatConcatenateSeqMat_SeqDense, 2875f4259b30SLisandro Dalcin /*145*/ NULL, 2876f4259b30SLisandro Dalcin NULL, 287799a7f59eSMark Adams NULL, 287899a7f59eSMark Adams NULL, 28797fb60732SBarry Smith NULL, 28809371c9d4SSatish Balay /*150*/ NULL}; 288190ace30eSBarry Smith 28824b828684SBarry Smith /*@C 288311a5261eSBarry Smith MatCreateSeqDense - Creates a `MATSEQDENSE` that 2884d65003e9SLois Curfman McInnes is stored in column major order (the usual Fortran 77 manner). Many 2885d65003e9SLois Curfman McInnes of the matrix operations use the BLAS and LAPACK routines. 2886289bc588SBarry Smith 2887d083f849SBarry Smith Collective 2888db81eaa0SLois Curfman McInnes 288920563c6bSBarry Smith Input Parameters: 289011a5261eSBarry Smith + comm - MPI communicator, set to `PETSC_COMM_SELF` 28910c775827SLois Curfman McInnes . m - number of rows 289218f449edSLois Curfman McInnes . n - number of columns 28930298fd71SBarry Smith - data - optional location of matrix data in column major order. Set data=NULL for PETSc 2894dfc5480cSLois Curfman McInnes to control all matrix memory allocation. 289520563c6bSBarry Smith 289620563c6bSBarry Smith Output Parameter: 289744cd7ae7SLois Curfman McInnes . A - the matrix 289820563c6bSBarry Smith 289911a5261eSBarry Smith Note: 290018f449edSLois Curfman McInnes The data input variable is intended primarily for Fortran programmers 290118f449edSLois Curfman McInnes who wish to allocate their own matrix memory space. Most users should 29020298fd71SBarry Smith set data=NULL. 290318f449edSLois Curfman McInnes 2904027ccd11SLois Curfman McInnes Level: intermediate 2905027ccd11SLois Curfman McInnes 290611a5261eSBarry Smith .seealso: `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()` 290720563c6bSBarry Smith @*/ 29089371c9d4SSatish Balay PetscErrorCode MatCreateSeqDense(MPI_Comm comm, PetscInt m, PetscInt n, PetscScalar *data, Mat *A) { 29093a40ed3dSBarry Smith PetscFunctionBegin; 29109566063dSJacob Faibussowitsch PetscCall(MatCreate(comm, A)); 29119566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*A, m, n, m, n)); 29129566063dSJacob Faibussowitsch PetscCall(MatSetType(*A, MATSEQDENSE)); 29139566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(*A, data)); 2914273d9f13SBarry Smith PetscFunctionReturn(0); 2915273d9f13SBarry Smith } 2916273d9f13SBarry Smith 2917273d9f13SBarry Smith /*@C 291811a5261eSBarry Smith MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements of a `MATSEQDENSE` matrix 2919273d9f13SBarry Smith 2920d083f849SBarry Smith Collective 2921273d9f13SBarry Smith 2922273d9f13SBarry Smith Input Parameters: 29231c4f3114SJed Brown + B - the matrix 29240298fd71SBarry Smith - data - the array (or NULL) 2925273d9f13SBarry Smith 292611a5261eSBarry Smith Note: 2927273d9f13SBarry Smith The data input variable is intended primarily for Fortran programmers 2928273d9f13SBarry Smith who wish to allocate their own matrix memory space. Most users should 2929284134d9SBarry Smith need not call this routine. 2930273d9f13SBarry Smith 2931273d9f13SBarry Smith Level: intermediate 2932273d9f13SBarry Smith 293311a5261eSBarry Smith .seealso: `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()`, `MatDenseSetLDA()` 2934273d9f13SBarry Smith @*/ 29359371c9d4SSatish Balay PetscErrorCode MatSeqDenseSetPreallocation(Mat B, PetscScalar data[]) { 2936a23d5eceSKris Buschelman PetscFunctionBegin; 2937d5ea218eSStefano Zampini PetscValidHeaderSpecific(B, MAT_CLASSID, 1); 2938cac4c232SBarry Smith PetscTryMethod(B, "MatSeqDenseSetPreallocation_C", (Mat, PetscScalar[]), (B, data)); 2939a23d5eceSKris Buschelman PetscFunctionReturn(0); 2940a23d5eceSKris Buschelman } 2941a23d5eceSKris Buschelman 29429371c9d4SSatish Balay PetscErrorCode MatSeqDenseSetPreallocation_SeqDense(Mat B, PetscScalar *data) { 2943ad16ce7aSStefano Zampini Mat_SeqDense *b = (Mat_SeqDense *)B->data; 2944273d9f13SBarry Smith 2945273d9f13SBarry Smith PetscFunctionBegin; 294628b400f6SJacob Faibussowitsch PetscCheck(!b->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 2947273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 2948a868139aSShri Abhyankar 29499566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(B->rmap)); 29509566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(B->cmap)); 295134ef9618SShri Abhyankar 2952ad16ce7aSStefano Zampini if (b->lda <= 0) b->lda = B->rmap->n; 295386d161a7SShri Abhyankar 29549e8f95c4SLisandro Dalcin if (!data) { /* petsc-allocated storage */ 29559566063dSJacob Faibussowitsch if (!b->user_alloc) PetscCall(PetscFree(b->v)); 29569566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((size_t)b->lda * B->cmap->n, &b->v)); 29572205254eSKarl Rupp 29589e8f95c4SLisandro Dalcin b->user_alloc = PETSC_FALSE; 2959273d9f13SBarry Smith } else { /* user-allocated storage */ 29609566063dSJacob Faibussowitsch if (!b->user_alloc) PetscCall(PetscFree(b->v)); 2961273d9f13SBarry Smith b->v = data; 2962273d9f13SBarry Smith b->user_alloc = PETSC_TRUE; 2963273d9f13SBarry Smith } 29640450473dSBarry Smith B->assembled = PETSC_TRUE; 2965273d9f13SBarry Smith PetscFunctionReturn(0); 2966273d9f13SBarry Smith } 2967273d9f13SBarry Smith 296865b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 29699371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) { 2970d77f618aSHong Zhang Mat mat_elemental; 29711683a169SBarry Smith const PetscScalar *array; 29721683a169SBarry Smith PetscScalar *v_colwise; 2973d77f618aSHong Zhang PetscInt M = A->rmap->N, N = A->cmap->N, i, j, k, *rows, *cols; 2974d77f618aSHong Zhang 29758baccfbdSHong Zhang PetscFunctionBegin; 29769566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(M * N, &v_colwise, M, &rows, N, &cols)); 29779566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &array)); 2978d77f618aSHong Zhang /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */ 2979d77f618aSHong Zhang k = 0; 2980d77f618aSHong Zhang for (j = 0; j < N; j++) { 2981d77f618aSHong Zhang cols[j] = j; 2982ad540459SPierre Jolivet for (i = 0; i < M; i++) v_colwise[j * M + i] = array[k++]; 2983d77f618aSHong Zhang } 2984ad540459SPierre Jolivet for (i = 0; i < M; i++) rows[i] = i; 29859566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &array)); 2986d77f618aSHong Zhang 29879566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental)); 29889566063dSJacob Faibussowitsch PetscCall(MatSetSizes(mat_elemental, PETSC_DECIDE, PETSC_DECIDE, M, N)); 29899566063dSJacob Faibussowitsch PetscCall(MatSetType(mat_elemental, MATELEMENTAL)); 29909566063dSJacob Faibussowitsch PetscCall(MatSetUp(mat_elemental)); 2991d77f618aSHong Zhang 2992d77f618aSHong Zhang /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */ 29939566063dSJacob Faibussowitsch PetscCall(MatSetValues(mat_elemental, M, rows, N, cols, v_colwise, ADD_VALUES)); 29949566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY)); 29959566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY)); 29969566063dSJacob Faibussowitsch PetscCall(PetscFree3(v_colwise, rows, cols)); 2997d77f618aSHong Zhang 2998511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 29999566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A, &mat_elemental)); 3000d77f618aSHong Zhang } else { 3001d77f618aSHong Zhang *newmat = mat_elemental; 3002d77f618aSHong Zhang } 30038baccfbdSHong Zhang PetscFunctionReturn(0); 30048baccfbdSHong Zhang } 300565b80a83SHong Zhang #endif 30068baccfbdSHong Zhang 30079371c9d4SSatish Balay PetscErrorCode MatDenseSetLDA_SeqDense(Mat B, PetscInt lda) { 30081b807ce4Svictorle Mat_SeqDense *b = (Mat_SeqDense *)B->data; 30097422da62SJose E. Roman PetscBool data; 301021a2c019SBarry Smith 30111b807ce4Svictorle PetscFunctionBegin; 30127422da62SJose E. Roman data = (PetscBool)((B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE); 3013aed4548fSBarry Smith PetscCheck(b->user_alloc || !data || b->lda == lda, PETSC_COMM_SELF, PETSC_ERR_ORDER, "LDA cannot be changed after allocation of internal storage"); 301408401ef6SPierre 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); 30151b807ce4Svictorle b->lda = lda; 30161b807ce4Svictorle PetscFunctionReturn(0); 30171b807ce4Svictorle } 30181b807ce4Svictorle 30199371c9d4SSatish Balay PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm, Mat inmat, PetscInt n, MatReuse scall, Mat *outmat) { 3020d528f656SJakub Kruzik PetscFunctionBegin; 30219566063dSJacob Faibussowitsch PetscCall(MatCreateMPIMatConcatenateSeqMat_MPIDense(comm, inmat, n, scall, outmat)); 3022d528f656SJakub Kruzik PetscFunctionReturn(0); 3023d528f656SJakub Kruzik } 3024d528f656SJakub Kruzik 30259371c9d4SSatish Balay PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A, PetscInt col, Vec *v) { 30266947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 30276947451fSStefano Zampini 30286947451fSStefano Zampini PetscFunctionBegin; 302928b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 303028b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3031*4dfa11a4SJacob Faibussowitsch if (!a->cvec) { PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec)); } 30326947451fSStefano Zampini a->vecinuse = col + 1; 30339566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, (PetscScalar **)&a->ptrinuse)); 30349566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda)); 30356947451fSStefano Zampini *v = a->cvec; 30366947451fSStefano Zampini PetscFunctionReturn(0); 30376947451fSStefano Zampini } 30386947451fSStefano Zampini 30399371c9d4SSatish Balay PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A, PetscInt col, Vec *v) { 30406947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 30416947451fSStefano Zampini 30426947451fSStefano Zampini PetscFunctionBegin; 304328b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 304428b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 30456947451fSStefano Zampini a->vecinuse = 0; 30469566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, (PetscScalar **)&a->ptrinuse)); 30479566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 304875f6d85dSStefano Zampini if (v) *v = NULL; 30496947451fSStefano Zampini PetscFunctionReturn(0); 30506947451fSStefano Zampini } 30516947451fSStefano Zampini 30529371c9d4SSatish Balay PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v) { 30536947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 30546947451fSStefano Zampini 30556947451fSStefano Zampini PetscFunctionBegin; 305628b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 305728b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3058*4dfa11a4SJacob Faibussowitsch if (!a->cvec) { PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec)); } 30596947451fSStefano Zampini a->vecinuse = col + 1; 30609566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &a->ptrinuse)); 30619566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda)); 30629566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(a->cvec)); 30636947451fSStefano Zampini *v = a->cvec; 30646947451fSStefano Zampini PetscFunctionReturn(0); 30656947451fSStefano Zampini } 30666947451fSStefano Zampini 30679371c9d4SSatish Balay PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v) { 30686947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 30696947451fSStefano Zampini 30706947451fSStefano Zampini PetscFunctionBegin; 307128b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 307228b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 30736947451fSStefano Zampini a->vecinuse = 0; 30749566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &a->ptrinuse)); 30759566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(a->cvec)); 30769566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 307775f6d85dSStefano Zampini if (v) *v = NULL; 30786947451fSStefano Zampini PetscFunctionReturn(0); 30796947451fSStefano Zampini } 30806947451fSStefano Zampini 30819371c9d4SSatish Balay PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v) { 30826947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 30836947451fSStefano Zampini 30846947451fSStefano Zampini PetscFunctionBegin; 308528b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 308628b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3087*4dfa11a4SJacob Faibussowitsch if (!a->cvec) { PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec)); } 30886947451fSStefano Zampini a->vecinuse = col + 1; 30899566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(A, (PetscScalar **)&a->ptrinuse)); 30909566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda)); 30916947451fSStefano Zampini *v = a->cvec; 30926947451fSStefano Zampini PetscFunctionReturn(0); 30936947451fSStefano Zampini } 30946947451fSStefano Zampini 30959371c9d4SSatish Balay PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v) { 30966947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 30976947451fSStefano Zampini 30986947451fSStefano Zampini PetscFunctionBegin; 309928b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 310028b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 31016947451fSStefano Zampini a->vecinuse = 0; 31029566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(A, (PetscScalar **)&a->ptrinuse)); 31039566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 310475f6d85dSStefano Zampini if (v) *v = NULL; 31056947451fSStefano Zampini PetscFunctionReturn(0); 31066947451fSStefano Zampini } 31076947451fSStefano Zampini 31089371c9d4SSatish Balay PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) { 31095ea7661aSPierre Jolivet Mat_SeqDense *a = (Mat_SeqDense *)A->data; 31105ea7661aSPierre Jolivet 31115ea7661aSPierre Jolivet PetscFunctionBegin; 311228b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 311328b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3114a2748737SPierre Jolivet if (a->cmat && (cend - cbegin != a->cmat->cmap->N || rend - rbegin != a->cmat->rmap->N)) PetscCall(MatDestroy(&a->cmat)); 31155ea7661aSPierre Jolivet if (!a->cmat) { 3116a2748737SPierre Jolivet PetscCall(MatCreateDense(PetscObjectComm((PetscObject)A), rend - rbegin, PETSC_DECIDE, rend - rbegin, cend - cbegin, a->v + rbegin + (size_t)cbegin * a->lda, &a->cmat)); 31175ea7661aSPierre Jolivet } else { 3118a2748737SPierre Jolivet PetscCall(MatDensePlaceArray(a->cmat, a->v + rbegin + (size_t)cbegin * a->lda)); 31195ea7661aSPierre Jolivet } 31209566063dSJacob Faibussowitsch PetscCall(MatDenseSetLDA(a->cmat, a->lda)); 31215ea7661aSPierre Jolivet a->matinuse = cbegin + 1; 31225ea7661aSPierre Jolivet *v = a->cmat; 312375f6d85dSStefano Zampini #if defined(PETSC_HAVE_CUDA) 312475f6d85dSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 312575f6d85dSStefano Zampini #endif 31265ea7661aSPierre Jolivet PetscFunctionReturn(0); 31275ea7661aSPierre Jolivet } 31285ea7661aSPierre Jolivet 31299371c9d4SSatish Balay PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A, Mat *v) { 31305ea7661aSPierre Jolivet Mat_SeqDense *a = (Mat_SeqDense *)A->data; 31315ea7661aSPierre Jolivet 31325ea7661aSPierre Jolivet PetscFunctionBegin; 313328b400f6SJacob Faibussowitsch PetscCheck(a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetSubMatrix() first"); 313428b400f6SJacob Faibussowitsch PetscCheck(a->cmat, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column matrix"); 313508401ef6SPierre Jolivet PetscCheck(*v == a->cmat, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not the matrix obtained from MatDenseGetSubMatrix()"); 31365ea7661aSPierre Jolivet a->matinuse = 0; 31379566063dSJacob Faibussowitsch PetscCall(MatDenseResetArray(a->cmat)); 3138742765d3SMatthew Knepley if (v) *v = NULL; 31393faff063SStefano Zampini #if defined(PETSC_HAVE_CUDA) 31403faff063SStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 31413faff063SStefano Zampini #endif 31425ea7661aSPierre Jolivet PetscFunctionReturn(0); 31435ea7661aSPierre Jolivet } 31445ea7661aSPierre Jolivet 31450bad9183SKris Buschelman /*MC 3146fafad747SKris Buschelman MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices. 31470bad9183SKris Buschelman 31480bad9183SKris Buschelman Options Database Keys: 314911a5261eSBarry Smith . -mat_type seqdense - sets the matrix type to `MATSEQDENSE` during a call to `MatSetFromOptions()` 31500bad9183SKris Buschelman 31510bad9183SKris Buschelman Level: beginner 31520bad9183SKris Buschelman 315311a5261eSBarry Smith .seealso: `MATSEQDENSE`, `MatCreateSeqDense()` 31540bad9183SKris Buschelman M*/ 31559371c9d4SSatish Balay PetscErrorCode MatCreate_SeqDense(Mat B) { 3156273d9f13SBarry Smith Mat_SeqDense *b; 31577c334f02SBarry Smith PetscMPIInt size; 3158273d9f13SBarry Smith 3159273d9f13SBarry Smith PetscFunctionBegin; 31609566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)B), &size)); 316108401ef6SPierre Jolivet PetscCheck(size <= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Comm must be of size 1"); 316255659b69SBarry Smith 3163*4dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&b)); 31649566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(B->ops, &MatOps_Values, sizeof(struct _MatOps))); 316544cd7ae7SLois Curfman McInnes B->data = (void *)b; 316618f449edSLois Curfman McInnes 3167273d9f13SBarry Smith b->roworiented = PETSC_TRUE; 31684e220ebcSLois Curfman McInnes 31699566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatQRFactor_C", MatQRFactor_SeqDense)); 31709566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetLDA_C", MatDenseGetLDA_SeqDense)); 31719566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseSetLDA_C", MatDenseSetLDA_SeqDense)); 31729566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArray_C", MatDenseGetArray_SeqDense)); 31739566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArray_C", MatDenseRestoreArray_SeqDense)); 31749566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDensePlaceArray_C", MatDensePlaceArray_SeqDense)); 31759566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseResetArray_C", MatDenseResetArray_SeqDense)); 31769566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseReplaceArray_C", MatDenseReplaceArray_SeqDense)); 31779566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayRead_C", MatDenseGetArray_SeqDense)); 31789566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayRead_C", MatDenseRestoreArray_SeqDense)); 31799566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayWrite_C", MatDenseGetArray_SeqDense)); 31809566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayWrite_C", MatDenseRestoreArray_SeqDense)); 31819566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqaij_C", MatConvert_SeqDense_SeqAIJ)); 31828baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 31839566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_elemental_C", MatConvert_SeqDense_Elemental)); 31848baccfbdSHong Zhang #endif 3185d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 31869566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_scalapack_C", MatConvert_Dense_ScaLAPACK)); 3187d24d4204SJose E. Roman #endif 31882bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA) 31899566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensecuda_C", MatConvert_SeqDense_SeqDenseCUDA)); 31909566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", MatProductSetFromOptions_SeqDense)); 31919566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdense_C", MatProductSetFromOptions_SeqDense)); 31929566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensecuda_C", MatProductSetFromOptions_SeqDense)); 31932bf066beSStefano Zampini #endif 31949566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSeqDenseSetPreallocation_C", MatSeqDenseSetPreallocation_SeqDense)); 31959566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqaij_seqdense_C", MatProductSetFromOptions_SeqAIJ_SeqDense)); 31969566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdense_C", MatProductSetFromOptions_SeqDense)); 31979566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense)); 31989566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqsbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense)); 319996e6d5c4SRichard Tran Mills 32009566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumn_C", MatDenseGetColumn_SeqDense)); 32019566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumn_C", MatDenseRestoreColumn_SeqDense)); 32029566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVec_C", MatDenseGetColumnVec_SeqDense)); 32039566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVec_C", MatDenseRestoreColumnVec_SeqDense)); 32049566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecRead_C", MatDenseGetColumnVecRead_SeqDense)); 32059566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecRead_C", MatDenseRestoreColumnVecRead_SeqDense)); 32069566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecWrite_C", MatDenseGetColumnVecWrite_SeqDense)); 32079566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecWrite_C", MatDenseRestoreColumnVecWrite_SeqDense)); 32089566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetSubMatrix_C", MatDenseGetSubMatrix_SeqDense)); 32099566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreSubMatrix_C", MatDenseRestoreSubMatrix_SeqDense)); 32109566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)B, MATSEQDENSE)); 32113a40ed3dSBarry Smith PetscFunctionReturn(0); 3212289bc588SBarry Smith } 321386aefd0dSHong Zhang 321486aefd0dSHong Zhang /*@C 321511a5261eSBarry 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. 321686aefd0dSHong Zhang 321786aefd0dSHong Zhang Not Collective 321886aefd0dSHong Zhang 32195ea7661aSPierre Jolivet Input Parameters: 322011a5261eSBarry Smith + mat - a `MATSEQDENSE` or `MATMPIDENSE` matrix 322186aefd0dSHong Zhang - col - column index 322286aefd0dSHong Zhang 322386aefd0dSHong Zhang Output Parameter: 322486aefd0dSHong Zhang . vals - pointer to the data 322586aefd0dSHong Zhang 322686aefd0dSHong Zhang Level: intermediate 322786aefd0dSHong Zhang 322811a5261eSBarry Smith Note: 322911a5261eSBarry Smith Use `MatDenseGetColumnVec()` to get access to a column of a `MATDENSE` treated as a `Vec` 323011a5261eSBarry Smith 323111a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreColumn()`, `MatDenseGetColumnVec()` 323286aefd0dSHong Zhang @*/ 32339371c9d4SSatish Balay PetscErrorCode MatDenseGetColumn(Mat A, PetscInt col, PetscScalar **vals) { 323486aefd0dSHong Zhang PetscFunctionBegin; 3235d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3236d5ea218eSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 3237d5ea218eSStefano Zampini PetscValidPointer(vals, 3); 3238cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumn_C", (Mat, PetscInt, PetscScalar **), (A, col, vals)); 323986aefd0dSHong Zhang PetscFunctionReturn(0); 324086aefd0dSHong Zhang } 324186aefd0dSHong Zhang 324286aefd0dSHong Zhang /*@C 324311a5261eSBarry Smith MatDenseRestoreColumn - returns access to a column of a `MATDENSE` matrix which is returned by `MatDenseGetColumn()`. 324486aefd0dSHong Zhang 324586aefd0dSHong Zhang Not Collective 324686aefd0dSHong Zhang 3247742765d3SMatthew Knepley Input Parameters: 324811a5261eSBarry Smith + mat - a `MATSEQDENSE` or `MATMPIDENSE` matrix 3249742765d3SMatthew Knepley - vals - pointer to the data (may be NULL) 325086aefd0dSHong Zhang 325186aefd0dSHong Zhang Level: intermediate 325286aefd0dSHong Zhang 325311a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetColumn()` 325486aefd0dSHong Zhang @*/ 32559371c9d4SSatish Balay PetscErrorCode MatDenseRestoreColumn(Mat A, PetscScalar **vals) { 325686aefd0dSHong Zhang PetscFunctionBegin; 3257d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3258d5ea218eSStefano Zampini PetscValidPointer(vals, 2); 3259cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumn_C", (Mat, PetscScalar **), (A, vals)); 326086aefd0dSHong Zhang PetscFunctionReturn(0); 326186aefd0dSHong Zhang } 32626947451fSStefano Zampini 32630f74d2c1SSatish Balay /*@ 326411a5261eSBarry Smith MatDenseGetColumnVec - Gives read-write access to a column of a `MATDENSE` matrix, represented as a `Vec`. 32656947451fSStefano Zampini 32666947451fSStefano Zampini Collective 32676947451fSStefano Zampini 32685ea7661aSPierre Jolivet Input Parameters: 326911a5261eSBarry Smith + mat - the `Mat` object 32706947451fSStefano Zampini - col - the column index 32716947451fSStefano Zampini 32726947451fSStefano Zampini Output Parameter: 32736947451fSStefano Zampini . v - the vector 32746947451fSStefano Zampini 32756947451fSStefano Zampini Notes: 327611a5261eSBarry Smith The vector is owned by PETSc. Users need to call `MatDenseRestoreColumnVec()` when the vector is no longer needed. 327711a5261eSBarry Smith 327811a5261eSBarry Smith Use `MatDenseGetColumnVecRead()` to obtain read-only access or `MatDenseGetColumnVecWrite()` for write-only access. 32796947451fSStefano Zampini 32806947451fSStefano Zampini Level: intermediate 32816947451fSStefano Zampini 328211a5261eSBarry Smith .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`, `MatDenseGetColumn()` 32836947451fSStefano Zampini @*/ 32849371c9d4SSatish Balay PetscErrorCode MatDenseGetColumnVec(Mat A, PetscInt col, Vec *v) { 32856947451fSStefano Zampini PetscFunctionBegin; 32866947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 32876947451fSStefano Zampini PetscValidType(A, 1); 32886947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 32896947451fSStefano Zampini PetscValidPointer(v, 3); 329028b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 32912cf15c64SPierre 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); 3292cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v)); 32936947451fSStefano Zampini PetscFunctionReturn(0); 32946947451fSStefano Zampini } 32956947451fSStefano Zampini 32960f74d2c1SSatish Balay /*@ 32976947451fSStefano Zampini MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVec(). 32986947451fSStefano Zampini 32996947451fSStefano Zampini Collective 33006947451fSStefano Zampini 33015ea7661aSPierre Jolivet Input Parameters: 33026947451fSStefano Zampini + mat - the Mat object 33036947451fSStefano Zampini . col - the column index 3304742765d3SMatthew Knepley - v - the Vec object (may be NULL) 33056947451fSStefano Zampini 33066947451fSStefano Zampini Level: intermediate 33076947451fSStefano Zampini 3308db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 33096947451fSStefano Zampini @*/ 33109371c9d4SSatish Balay PetscErrorCode MatDenseRestoreColumnVec(Mat A, PetscInt col, Vec *v) { 33116947451fSStefano Zampini PetscFunctionBegin; 33126947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 33136947451fSStefano Zampini PetscValidType(A, 1); 33146947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 331508401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 33162cf15c64SPierre 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); 3317cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v)); 33186947451fSStefano Zampini PetscFunctionReturn(0); 33196947451fSStefano Zampini } 33206947451fSStefano Zampini 33210f74d2c1SSatish Balay /*@ 33226947451fSStefano Zampini MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a Vec. 33236947451fSStefano Zampini 33246947451fSStefano Zampini Collective 33256947451fSStefano Zampini 33265ea7661aSPierre Jolivet Input Parameters: 33276947451fSStefano Zampini + mat - the Mat object 33286947451fSStefano Zampini - col - the column index 33296947451fSStefano Zampini 33306947451fSStefano Zampini Output Parameter: 33316947451fSStefano Zampini . v - the vector 33326947451fSStefano Zampini 33336947451fSStefano Zampini Notes: 33346947451fSStefano Zampini The vector is owned by PETSc and users cannot modify it. 333511a5261eSBarry Smith 33366947451fSStefano Zampini Users need to call MatDenseRestoreColumnVecRead() when the vector is no longer needed. 333711a5261eSBarry Smith 33386947451fSStefano Zampini Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecWrite() for write-only access. 33396947451fSStefano Zampini 33406947451fSStefano Zampini Level: intermediate 33416947451fSStefano Zampini 3342db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 33436947451fSStefano Zampini @*/ 33449371c9d4SSatish Balay PetscErrorCode MatDenseGetColumnVecRead(Mat A, PetscInt col, Vec *v) { 33456947451fSStefano Zampini PetscFunctionBegin; 33466947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 33476947451fSStefano Zampini PetscValidType(A, 1); 33486947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 33496947451fSStefano Zampini PetscValidPointer(v, 3); 335028b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 33512cf15c64SPierre 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); 3352cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v)); 33536947451fSStefano Zampini PetscFunctionReturn(0); 33546947451fSStefano Zampini } 33556947451fSStefano Zampini 33560f74d2c1SSatish Balay /*@ 33576947451fSStefano Zampini MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecRead(). 33586947451fSStefano Zampini 33596947451fSStefano Zampini Collective 33606947451fSStefano Zampini 33615ea7661aSPierre Jolivet Input Parameters: 33626947451fSStefano Zampini + mat - the Mat object 33636947451fSStefano Zampini . col - the column index 3364742765d3SMatthew Knepley - v - the Vec object (may be NULL) 33656947451fSStefano Zampini 33666947451fSStefano Zampini Level: intermediate 33676947451fSStefano Zampini 3368db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecWrite()` 33696947451fSStefano Zampini @*/ 33709371c9d4SSatish Balay PetscErrorCode MatDenseRestoreColumnVecRead(Mat A, PetscInt col, Vec *v) { 33716947451fSStefano Zampini PetscFunctionBegin; 33726947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 33736947451fSStefano Zampini PetscValidType(A, 1); 33746947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 337508401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 33762cf15c64SPierre 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); 3377cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v)); 33786947451fSStefano Zampini PetscFunctionReturn(0); 33796947451fSStefano Zampini } 33806947451fSStefano Zampini 33810f74d2c1SSatish Balay /*@ 33826947451fSStefano Zampini MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a Vec. 33836947451fSStefano Zampini 33846947451fSStefano Zampini Collective 33856947451fSStefano Zampini 33865ea7661aSPierre Jolivet Input Parameters: 33876947451fSStefano Zampini + mat - the Mat object 33886947451fSStefano Zampini - col - the column index 33896947451fSStefano Zampini 33906947451fSStefano Zampini Output Parameter: 33916947451fSStefano Zampini . v - the vector 33926947451fSStefano Zampini 33936947451fSStefano Zampini Notes: 33946947451fSStefano Zampini The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVecWrite() when the vector is no longer needed. 339511a5261eSBarry Smith 33966947451fSStefano Zampini Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecRead() for read-only access. 33976947451fSStefano Zampini 33986947451fSStefano Zampini Level: intermediate 33996947451fSStefano Zampini 3400db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 34016947451fSStefano Zampini @*/ 34029371c9d4SSatish Balay PetscErrorCode MatDenseGetColumnVecWrite(Mat A, PetscInt col, Vec *v) { 34036947451fSStefano Zampini PetscFunctionBegin; 34046947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 34056947451fSStefano Zampini PetscValidType(A, 1); 34066947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 34076947451fSStefano Zampini PetscValidPointer(v, 3); 340828b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3409aed4548fSBarry 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); 3410cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v)); 34116947451fSStefano Zampini PetscFunctionReturn(0); 34126947451fSStefano Zampini } 34136947451fSStefano Zampini 34140f74d2c1SSatish Balay /*@ 34156947451fSStefano Zampini MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecWrite(). 34166947451fSStefano Zampini 34176947451fSStefano Zampini Collective 34186947451fSStefano Zampini 34195ea7661aSPierre Jolivet Input Parameters: 34206947451fSStefano Zampini + mat - the Mat object 34216947451fSStefano Zampini . col - the column index 3422742765d3SMatthew Knepley - v - the Vec object (may be NULL) 34236947451fSStefano Zampini 34246947451fSStefano Zampini Level: intermediate 34256947451fSStefano Zampini 3426db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()` 34276947451fSStefano Zampini @*/ 34289371c9d4SSatish Balay PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A, PetscInt col, Vec *v) { 34296947451fSStefano Zampini PetscFunctionBegin; 34306947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 34316947451fSStefano Zampini PetscValidType(A, 1); 34326947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 343308401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3434aed4548fSBarry 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); 3435cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v)); 34366947451fSStefano Zampini PetscFunctionReturn(0); 34376947451fSStefano Zampini } 34385ea7661aSPierre Jolivet 34390f74d2c1SSatish Balay /*@ 3440a2748737SPierre Jolivet MatDenseGetSubMatrix - Gives access to a block of rows and columns of a dense matrix, represented as a Mat. 34415ea7661aSPierre Jolivet 34425ea7661aSPierre Jolivet Collective 34435ea7661aSPierre Jolivet 34445ea7661aSPierre Jolivet Input Parameters: 34455ea7661aSPierre Jolivet + mat - the Mat object 3446a2748737SPierre Jolivet . rbegin - the first global row index in the block (if PETSC_DECIDE, is 0) 3447a2748737SPierre Jolivet . rend - the global row index past the last one in the block (if PETSC_DECIDE, is M) 3448a2748737SPierre Jolivet . cbegin - the first global column index in the block (if PETSC_DECIDE, is 0) 3449a2748737SPierre Jolivet - cend - the global column index past the last one in the block (if PETSC_DECIDE, is N) 34505ea7661aSPierre Jolivet 34515ea7661aSPierre Jolivet Output Parameter: 34525ea7661aSPierre Jolivet . v - the matrix 34535ea7661aSPierre Jolivet 34545ea7661aSPierre Jolivet Notes: 34555ea7661aSPierre Jolivet The matrix is owned by PETSc. Users need to call MatDenseRestoreSubMatrix() when the matrix is no longer needed. 345611a5261eSBarry Smith 3457a2748737SPierre 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. 34585ea7661aSPierre Jolivet 34595ea7661aSPierre Jolivet Level: intermediate 34605ea7661aSPierre Jolivet 3461db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreSubMatrix()` 34625ea7661aSPierre Jolivet @*/ 34639371c9d4SSatish Balay PetscErrorCode MatDenseGetSubMatrix(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) { 34645ea7661aSPierre Jolivet PetscFunctionBegin; 34655ea7661aSPierre Jolivet PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 34665ea7661aSPierre Jolivet PetscValidType(A, 1); 3467a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, rbegin, 2); 3468a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, rend, 3); 3469a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, cbegin, 4); 3470a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, cend, 5); 3471a2748737SPierre Jolivet PetscValidPointer(v, 6); 3472a2748737SPierre Jolivet if (rbegin == PETSC_DECIDE) rbegin = 0; 3473a2748737SPierre Jolivet if (rend == PETSC_DECIDE) rend = A->rmap->N; 3474a2748737SPierre Jolivet if (cbegin == PETSC_DECIDE) cbegin = 0; 3475a2748737SPierre Jolivet if (cend == PETSC_DECIDE) cend = A->cmap->N; 347628b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3477a2748737SPierre 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); 3478a2748737SPierre 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); 3479a2748737SPierre 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); 3480a2748737SPierre 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); 3481a2748737SPierre Jolivet PetscUseMethod(A, "MatDenseGetSubMatrix_C", (Mat, PetscInt, PetscInt, PetscInt, PetscInt, Mat *), (A, rbegin, rend, cbegin, cend, v)); 34825ea7661aSPierre Jolivet PetscFunctionReturn(0); 34835ea7661aSPierre Jolivet } 34845ea7661aSPierre Jolivet 34850f74d2c1SSatish Balay /*@ 34865ea7661aSPierre Jolivet MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from MatDenseGetSubMatrix(). 34875ea7661aSPierre Jolivet 34885ea7661aSPierre Jolivet Collective 34895ea7661aSPierre Jolivet 34905ea7661aSPierre Jolivet Input Parameters: 34915ea7661aSPierre Jolivet + mat - the Mat object 3492742765d3SMatthew Knepley - v - the Mat object (may be NULL) 34935ea7661aSPierre Jolivet 34945ea7661aSPierre Jolivet Level: intermediate 34955ea7661aSPierre Jolivet 3496db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseGetSubMatrix()` 34975ea7661aSPierre Jolivet @*/ 34989371c9d4SSatish Balay PetscErrorCode MatDenseRestoreSubMatrix(Mat A, Mat *v) { 34995ea7661aSPierre Jolivet PetscFunctionBegin; 35005ea7661aSPierre Jolivet PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 35015ea7661aSPierre Jolivet PetscValidType(A, 1); 35025ea7661aSPierre Jolivet PetscValidPointer(v, 2); 3503cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreSubMatrix_C", (Mat, Mat *), (A, v)); 35045ea7661aSPierre Jolivet PetscFunctionReturn(0); 35055ea7661aSPierre Jolivet } 35068a9c020eSBarry Smith 35078a9c020eSBarry Smith #include <petscblaslapack.h> 35088a9c020eSBarry Smith #include <petsc/private/kernels/blockinvert.h> 35098a9c020eSBarry Smith 35109371c9d4SSatish Balay PetscErrorCode MatSeqDenseInvert(Mat A) { 35118a9c020eSBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35128a9c020eSBarry Smith PetscInt bs = A->rmap->n; 35138a9c020eSBarry Smith MatScalar *values = a->v; 35148a9c020eSBarry Smith const PetscReal shift = 0.0; 35158a9c020eSBarry Smith PetscBool allowzeropivot = PetscNot(A->erroriffailure), zeropivotdetected = PETSC_FALSE; 35168a9c020eSBarry Smith 35178a9c020eSBarry Smith PetscFunctionBegin; 35188a9c020eSBarry Smith /* factor and invert each block */ 35198a9c020eSBarry Smith switch (bs) { 35209371c9d4SSatish Balay case 1: values[0] = (PetscScalar)1.0 / (values[0] + shift); break; 35218a9c020eSBarry Smith case 2: 35228a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_2(values, shift, allowzeropivot, &zeropivotdetected)); 35238a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 35248a9c020eSBarry Smith break; 35258a9c020eSBarry Smith case 3: 35268a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_3(values, shift, allowzeropivot, &zeropivotdetected)); 35278a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 35288a9c020eSBarry Smith break; 35298a9c020eSBarry Smith case 4: 35308a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_4(values, shift, allowzeropivot, &zeropivotdetected)); 35318a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 35328a9c020eSBarry Smith break; 35339371c9d4SSatish Balay case 5: { 35348a9c020eSBarry Smith PetscScalar work[25]; 35358a9c020eSBarry Smith PetscInt ipvt[5]; 35368a9c020eSBarry Smith 35378a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_5(values, ipvt, work, shift, allowzeropivot, &zeropivotdetected)); 35388a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 35399371c9d4SSatish Balay } break; 35408a9c020eSBarry Smith case 6: 35418a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_6(values, shift, allowzeropivot, &zeropivotdetected)); 35428a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 35438a9c020eSBarry Smith break; 35448a9c020eSBarry Smith case 7: 35458a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_7(values, shift, allowzeropivot, &zeropivotdetected)); 35468a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 35478a9c020eSBarry Smith break; 35489371c9d4SSatish Balay default: { 35498a9c020eSBarry Smith PetscInt *v_pivots, *IJ, j; 35508a9c020eSBarry Smith PetscScalar *v_work; 35518a9c020eSBarry Smith 35528a9c020eSBarry Smith PetscCall(PetscMalloc3(bs, &v_work, bs, &v_pivots, bs, &IJ)); 3553ad540459SPierre Jolivet for (j = 0; j < bs; j++) IJ[j] = j; 35548a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A(bs, values, v_pivots, v_work, allowzeropivot, &zeropivotdetected)); 35558a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 35568a9c020eSBarry Smith PetscCall(PetscFree3(v_work, v_pivots, IJ)); 35578a9c020eSBarry Smith } 35588a9c020eSBarry Smith } 35598a9c020eSBarry Smith PetscFunctionReturn(0); 35608a9c020eSBarry Smith } 3561