167e560aaSBarry Smith /* 267e560aaSBarry Smith Defines the basic matrix operations for sequential dense. 347d993e7Ssuyashtn Portions of this code are under: 447d993e7Ssuyashtn Copyright (c) 2022 Advanced Micro Devices, Inc. All rights reserved. 567e560aaSBarry Smith */ 6289bc588SBarry Smith 7dec5eb66SMatthew G Knepley #include <../src/mat/impls/dense/seq/dense.h> /*I "petscmat.h" I*/ 8cd3f9d89SJunchao Zhang #include <../src/mat/impls/dense/mpi/mpidense.h> 9c6db04a5SJed Brown #include <petscblaslapack.h> 106a63e612SBarry Smith #include <../src/mat/impls/aij/seq/aij.h> 11b2573a8aSBarry Smith 12d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSymmetrize_Private(Mat A, PetscBool hermitian) 13d71ae5a4SJacob Faibussowitsch { 148c178816SStefano Zampini Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 158c178816SStefano Zampini PetscInt j, k, n = A->rmap->n; 16ca15aa20SStefano Zampini PetscScalar *v; 178c178816SStefano Zampini 188c178816SStefano Zampini PetscFunctionBegin; 1908401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PetscObjectComm((PetscObject)A), PETSC_ERR_SUP, "Cannot symmetrize a rectangular matrix"); 209566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 218c178816SStefano Zampini if (!hermitian) { 228c178816SStefano Zampini for (k = 0; k < n; k++) { 23ad540459SPierre Jolivet for (j = k; j < n; j++) v[j * mat->lda + k] = v[k * mat->lda + j]; 248c178816SStefano Zampini } 258c178816SStefano Zampini } else { 268c178816SStefano Zampini for (k = 0; k < n; k++) { 27ad540459SPierre Jolivet for (j = k; j < n; j++) v[j * mat->lda + k] = PetscConj(v[k * mat->lda + j]); 288c178816SStefano Zampini } 298c178816SStefano Zampini } 309566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 328c178816SStefano Zampini } 338c178816SStefano Zampini 34*ff6a9541SJacob Faibussowitsch PetscErrorCode MatSeqDenseInvertFactors_Private(Mat A) 35d71ae5a4SJacob Faibussowitsch { 368c178816SStefano Zampini Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 378c178816SStefano Zampini PetscBLASInt info, n; 388c178816SStefano Zampini 398c178816SStefano Zampini PetscFunctionBegin; 403ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 419566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 428c178816SStefano Zampini if (A->factortype == MAT_FACTOR_LU) { 4328b400f6SJacob Faibussowitsch PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present"); 448c178816SStefano Zampini if (!mat->fwork) { 458c178816SStefano Zampini mat->lfwork = n; 469566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 478c178816SStefano Zampini } 489566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 49792fecdfSBarry Smith PetscCallBLAS("LAPACKgetri", LAPACKgetri_(&n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info)); 509566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 519566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0)); 528c178816SStefano Zampini } else if (A->factortype == MAT_FACTOR_CHOLESKY) { 53b94d7dedSBarry Smith if (A->spd == PETSC_BOOL3_TRUE) { 549566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 55792fecdfSBarry Smith PetscCallBLAS("LAPACKpotri", LAPACKpotri_("L", &n, mat->v, &mat->lda, &info)); 569566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 579566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_TRUE)); 588c178816SStefano Zampini #if defined(PETSC_USE_COMPLEX) 59b94d7dedSBarry Smith } else if (A->hermitian == PETSC_BOOL3_TRUE) { 6028b400f6SJacob Faibussowitsch PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present"); 6128b400f6SJacob Faibussowitsch PetscCheck(mat->fwork, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Fwork not present"); 629566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 63792fecdfSBarry Smith PetscCallBLAS("LAPACKhetri", LAPACKhetri_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &info)); 649566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 659566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_TRUE)); 668c178816SStefano Zampini #endif 678c178816SStefano Zampini } else { /* symmetric case */ 6828b400f6SJacob Faibussowitsch PetscCheck(mat->pivots, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Pivots not present"); 6928b400f6SJacob Faibussowitsch PetscCheck(mat->fwork, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Fwork not present"); 709566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 71792fecdfSBarry Smith PetscCallBLAS("LAPACKsytri", LAPACKsytri_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &info)); 729566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 739566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSymmetrize_Private(A, PETSC_FALSE)); 748c178816SStefano Zampini } 7528b400f6SJacob Faibussowitsch PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad Inversion: zero pivot in row %" PetscInt_FMT, (PetscInt)info - 1); 769566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0)); 778c178816SStefano Zampini } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Matrix must be factored to solve"); 788c178816SStefano Zampini 798c178816SStefano Zampini A->ops->solve = NULL; 808c178816SStefano Zampini A->ops->matsolve = NULL; 818c178816SStefano Zampini A->ops->solvetranspose = NULL; 828c178816SStefano Zampini A->ops->matsolvetranspose = NULL; 838c178816SStefano Zampini A->ops->solveadd = NULL; 848c178816SStefano Zampini A->ops->solvetransposeadd = NULL; 858c178816SStefano Zampini A->factortype = MAT_FACTOR_NONE; 869566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 888c178816SStefano Zampini } 898c178816SStefano Zampini 90d71ae5a4SJacob Faibussowitsch PetscErrorCode MatZeroRowsColumns_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) 91d71ae5a4SJacob Faibussowitsch { 923f49a652SStefano Zampini Mat_SeqDense *l = (Mat_SeqDense *)A->data; 933f49a652SStefano Zampini PetscInt m = l->lda, n = A->cmap->n, r = A->rmap->n, i, j; 94ca15aa20SStefano Zampini PetscScalar *slot, *bb, *v; 953f49a652SStefano Zampini const PetscScalar *xx; 963f49a652SStefano Zampini 973f49a652SStefano Zampini PetscFunctionBegin; 9876bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 993f49a652SStefano Zampini for (i = 0; i < N; i++) { 10008401ef6SPierre Jolivet PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed"); 10108401ef6SPierre Jolivet PetscCheck(rows[i] < A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Row %" PetscInt_FMT " requested to be zeroed greater than or equal number of rows %" PetscInt_FMT, rows[i], A->rmap->n); 10208401ef6SPierre Jolivet PetscCheck(rows[i] < A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Col %" PetscInt_FMT " requested to be zeroed greater than or equal number of cols %" PetscInt_FMT, rows[i], A->cmap->n); 1033f49a652SStefano Zampini } 10476bd3646SJed Brown } 1053ba16761SJacob Faibussowitsch if (!N) PetscFunctionReturn(PETSC_SUCCESS); 1063f49a652SStefano Zampini 1073f49a652SStefano Zampini /* fix right hand side if needed */ 1083f49a652SStefano Zampini if (x && b) { 1096c4d906cSStefano Zampini Vec xt; 1106c4d906cSStefano Zampini 11108401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices"); 1129566063dSJacob Faibussowitsch PetscCall(VecDuplicate(x, &xt)); 1139566063dSJacob Faibussowitsch PetscCall(VecCopy(x, xt)); 1149566063dSJacob Faibussowitsch PetscCall(VecScale(xt, -1.0)); 1159566063dSJacob Faibussowitsch PetscCall(MatMultAdd(A, xt, b, b)); 1169566063dSJacob Faibussowitsch PetscCall(VecDestroy(&xt)); 1179566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 1189566063dSJacob Faibussowitsch PetscCall(VecGetArray(b, &bb)); 1193f49a652SStefano Zampini for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]]; 1209566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 1219566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(b, &bb)); 1223f49a652SStefano Zampini } 1233f49a652SStefano Zampini 1249566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 1253f49a652SStefano Zampini for (i = 0; i < N; i++) { 126ca15aa20SStefano Zampini slot = v + rows[i] * m; 1279566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(slot, r)); 1283f49a652SStefano Zampini } 1293f49a652SStefano Zampini for (i = 0; i < N; i++) { 130ca15aa20SStefano Zampini slot = v + rows[i]; 1319371c9d4SSatish Balay for (j = 0; j < n; j++) { 1329371c9d4SSatish Balay *slot = 0.0; 1339371c9d4SSatish Balay slot += m; 1349371c9d4SSatish Balay } 1353f49a652SStefano Zampini } 1363f49a652SStefano Zampini if (diag != 0.0) { 13708401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices"); 1383f49a652SStefano Zampini for (i = 0; i < N; i++) { 139ca15aa20SStefano Zampini slot = v + (m + 1) * rows[i]; 1403f49a652SStefano Zampini *slot = diag; 1413f49a652SStefano Zampini } 1423f49a652SStefano Zampini } 1439566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 1443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1453f49a652SStefano Zampini } 1463f49a652SStefano Zampini 147d71ae5a4SJacob Faibussowitsch PetscErrorCode MatPtAPNumeric_SeqDense_SeqDense(Mat A, Mat P, Mat C) 148d71ae5a4SJacob Faibussowitsch { 149abc3b08eSStefano Zampini Mat_SeqDense *c = (Mat_SeqDense *)(C->data); 150abc3b08eSStefano Zampini 151abc3b08eSStefano Zampini PetscFunctionBegin; 152ca15aa20SStefano Zampini if (c->ptapwork) { 1539566063dSJacob Faibussowitsch PetscCall((*C->ops->matmultnumeric)(A, P, c->ptapwork)); 1549566063dSJacob Faibussowitsch PetscCall((*C->ops->transposematmultnumeric)(P, c->ptapwork, C)); 1554222ddf1SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)C), PETSC_ERR_SUP, "Must call MatPtAPSymbolic_SeqDense_SeqDense() first"); 1563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 157abc3b08eSStefano Zampini } 158abc3b08eSStefano Zampini 159d71ae5a4SJacob Faibussowitsch PetscErrorCode MatPtAPSymbolic_SeqDense_SeqDense(Mat A, Mat P, PetscReal fill, Mat C) 160d71ae5a4SJacob Faibussowitsch { 161abc3b08eSStefano Zampini Mat_SeqDense *c; 16247d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 163abc3b08eSStefano Zampini 164abc3b08eSStefano Zampini PetscFunctionBegin; 1659566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, P->cmap->n, P->cmap->n, P->cmap->N, P->cmap->N)); 16647d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 1679566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 16847d993e7Ssuyashtn #elif (PETSC_HAVE_HIP) 16947d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 17047d993e7Ssuyashtn #endif 17147d993e7Ssuyashtn 1727a3c3d58SStefano Zampini if (!cisdense) { 1737a3c3d58SStefano Zampini PetscBool flg; 1747a3c3d58SStefano Zampini 1759566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)P, ((PetscObject)A)->type_name, &flg)); 1769566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 1777a3c3d58SStefano Zampini } 1789566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 1794222ddf1SHong Zhang c = (Mat_SeqDense *)C->data; 1809566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &c->ptapwork)); 1819566063dSJacob Faibussowitsch PetscCall(MatSetSizes(c->ptapwork, A->rmap->n, P->cmap->n, A->rmap->N, P->cmap->N)); 1829566063dSJacob Faibussowitsch PetscCall(MatSetType(c->ptapwork, ((PetscObject)C)->type_name)); 1839566063dSJacob Faibussowitsch PetscCall(MatSetUp(c->ptapwork)); 1843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 185abc3b08eSStefano Zampini } 186abc3b08eSStefano Zampini 187d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) 188d71ae5a4SJacob Faibussowitsch { 189a13144ffSStefano Zampini Mat B = NULL; 190b49cda9fSStefano Zampini Mat_SeqAIJ *a = (Mat_SeqAIJ *)A->data; 191b49cda9fSStefano Zampini Mat_SeqDense *b; 192b49cda9fSStefano Zampini PetscInt *ai = a->i, *aj = a->j, m = A->rmap->N, n = A->cmap->N, i; 1932e5835c6SStefano Zampini const MatScalar *av; 194a13144ffSStefano Zampini PetscBool isseqdense; 195b49cda9fSStefano Zampini 196b49cda9fSStefano Zampini PetscFunctionBegin; 197a13144ffSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 1989566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)*newmat, MATSEQDENSE, &isseqdense)); 19928b400f6SJacob Faibussowitsch PetscCheck(isseqdense, PetscObjectComm((PetscObject)*newmat), PETSC_ERR_USER, "Cannot reuse matrix of type %s", ((PetscObject)(*newmat))->type_name); 200a13144ffSStefano Zampini } 201a13144ffSStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 2029566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B)); 2039566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B, m, n, m, n)); 2049566063dSJacob Faibussowitsch PetscCall(MatSetType(B, MATSEQDENSE)); 2059566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(B, NULL)); 206b49cda9fSStefano Zampini b = (Mat_SeqDense *)(B->data); 207a13144ffSStefano Zampini } else { 208a13144ffSStefano Zampini b = (Mat_SeqDense *)((*newmat)->data); 2099566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(b->v, m * n)); 210a13144ffSStefano Zampini } 2119566063dSJacob Faibussowitsch PetscCall(MatSeqAIJGetArrayRead(A, &av)); 212b49cda9fSStefano Zampini for (i = 0; i < m; i++) { 213b49cda9fSStefano Zampini PetscInt j; 214b49cda9fSStefano Zampini for (j = 0; j < ai[1] - ai[0]; j++) { 215b49cda9fSStefano Zampini b->v[*aj * m + i] = *av; 216b49cda9fSStefano Zampini aj++; 217b49cda9fSStefano Zampini av++; 218b49cda9fSStefano Zampini } 219b49cda9fSStefano Zampini ai++; 220b49cda9fSStefano Zampini } 2219566063dSJacob Faibussowitsch PetscCall(MatSeqAIJRestoreArrayRead(A, &av)); 222b49cda9fSStefano Zampini 223511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 2249566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 2259566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 2269566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A, &B)); 227b49cda9fSStefano Zampini } else { 228a13144ffSStefano Zampini if (B) *newmat = B; 2299566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(*newmat, MAT_FINAL_ASSEMBLY)); 2309566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(*newmat, MAT_FINAL_ASSEMBLY)); 231b49cda9fSStefano Zampini } 2323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 233b49cda9fSStefano Zampini } 234b49cda9fSStefano Zampini 235d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqDense_SeqAIJ(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) 236d71ae5a4SJacob Faibussowitsch { 2376d4ec7b0SPierre Jolivet Mat B = NULL; 2386a63e612SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2399399e1b8SMatthew G. Knepley PetscInt i, j; 2409399e1b8SMatthew G. Knepley PetscInt *rows, *nnz; 2419399e1b8SMatthew G. Knepley MatScalar *aa = a->v, *vals; 2426a63e612SBarry Smith 2436a63e612SBarry Smith PetscFunctionBegin; 2449566063dSJacob Faibussowitsch PetscCall(PetscCalloc3(A->rmap->n, &rows, A->rmap->n, &nnz, A->rmap->n, &vals)); 2456d4ec7b0SPierre Jolivet if (reuse != MAT_REUSE_MATRIX) { 2469566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B)); 2479566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B, A->rmap->n, A->cmap->n, A->rmap->N, A->cmap->N)); 2489566063dSJacob Faibussowitsch PetscCall(MatSetType(B, MATSEQAIJ)); 2499399e1b8SMatthew G. Knepley for (j = 0; j < A->cmap->n; j++) { 2509371c9d4SSatish Balay for (i = 0; i < A->rmap->n; i++) 2519371c9d4SSatish Balay if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) ++nnz[i]; 2526a63e612SBarry Smith aa += a->lda; 2536a63e612SBarry Smith } 2549566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(B, PETSC_DETERMINE, nnz)); 2556d4ec7b0SPierre Jolivet } else B = *newmat; 2569399e1b8SMatthew G. Knepley aa = a->v; 2579399e1b8SMatthew G. Knepley for (j = 0; j < A->cmap->n; j++) { 2589399e1b8SMatthew G. Knepley PetscInt numRows = 0; 2599371c9d4SSatish Balay for (i = 0; i < A->rmap->n; i++) 2609371c9d4SSatish Balay if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) { 2619371c9d4SSatish Balay rows[numRows] = i; 2629371c9d4SSatish Balay vals[numRows++] = aa[i]; 2639371c9d4SSatish Balay } 2649566063dSJacob Faibussowitsch PetscCall(MatSetValues(B, numRows, rows, 1, &j, vals, INSERT_VALUES)); 2659399e1b8SMatthew G. Knepley aa += a->lda; 2669399e1b8SMatthew G. Knepley } 2679566063dSJacob Faibussowitsch PetscCall(PetscFree3(rows, nnz, vals)); 2689566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 2699566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 2706a63e612SBarry Smith 271511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 2729566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A, &B)); 2736d4ec7b0SPierre Jolivet } else if (reuse != MAT_REUSE_MATRIX) *newmat = B; 2743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2756a63e612SBarry Smith } 2766a63e612SBarry Smith 277d71ae5a4SJacob Faibussowitsch PetscErrorCode MatAXPY_SeqDense(Mat Y, PetscScalar alpha, Mat X, MatStructure str) 278d71ae5a4SJacob Faibussowitsch { 2791987afe7SBarry Smith Mat_SeqDense *x = (Mat_SeqDense *)X->data, *y = (Mat_SeqDense *)Y->data; 280ca15aa20SStefano Zampini const PetscScalar *xv; 281ca15aa20SStefano Zampini PetscScalar *yv; 28223fff9afSBarry Smith PetscBLASInt N, m, ldax = 0, lday = 0, one = 1; 2833a40ed3dSBarry Smith 2843a40ed3dSBarry Smith PetscFunctionBegin; 2859566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(X, &xv)); 2869566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(Y, &yv)); 2879566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(X->rmap->n * X->cmap->n, &N)); 2889566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(X->rmap->n, &m)); 2899566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(x->lda, &ldax)); 2909566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(y->lda, &lday)); 291a5ce6ee0Svictorle if (ldax > m || lday > m) { 292ca15aa20SStefano Zampini PetscInt j; 293ca15aa20SStefano Zampini 29448a46eb9SPierre Jolivet for (j = 0; j < X->cmap->n; j++) PetscCallBLAS("BLASaxpy", BLASaxpy_(&m, &alpha, xv + j * ldax, &one, yv + j * lday, &one)); 295a5ce6ee0Svictorle } else { 296792fecdfSBarry Smith PetscCallBLAS("BLASaxpy", BLASaxpy_(&N, &alpha, xv, &one, yv, &one)); 297a5ce6ee0Svictorle } 2989566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(X, &xv)); 2999566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(Y, &yv)); 3009566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(PetscMax(2.0 * N - 1, 0))); 3013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3021987afe7SBarry Smith } 3031987afe7SBarry Smith 304d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetInfo_SeqDense(Mat A, MatInfoType flag, MatInfo *info) 305d71ae5a4SJacob Faibussowitsch { 306ca15aa20SStefano Zampini PetscLogDouble N = A->rmap->n * A->cmap->n; 3073a40ed3dSBarry Smith 3083a40ed3dSBarry Smith PetscFunctionBegin; 3094e220ebcSLois Curfman McInnes info->block_size = 1.0; 310ca15aa20SStefano Zampini info->nz_allocated = N; 311ca15aa20SStefano Zampini info->nz_used = N; 312ca15aa20SStefano Zampini info->nz_unneeded = 0; 313ca15aa20SStefano Zampini info->assemblies = A->num_ass; 3144e220ebcSLois Curfman McInnes info->mallocs = 0; 3154dfa11a4SJacob Faibussowitsch info->memory = 0; /* REVIEW ME */ 3164e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 3174e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 3184e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 3193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 320289bc588SBarry Smith } 321289bc588SBarry Smith 322d71ae5a4SJacob Faibussowitsch PetscErrorCode MatScale_SeqDense(Mat A, PetscScalar alpha) 323d71ae5a4SJacob Faibussowitsch { 324273d9f13SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 325ca15aa20SStefano Zampini PetscScalar *v; 32623fff9afSBarry Smith PetscBLASInt one = 1, j, nz, lda = 0; 32780cd9d93SLois Curfman McInnes 3283a40ed3dSBarry Smith PetscFunctionBegin; 3299566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 3309566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(a->lda, &lda)); 331d0f46423SBarry Smith if (lda > A->rmap->n) { 3329566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &nz)); 33348a46eb9SPierre Jolivet for (j = 0; j < A->cmap->n; j++) PetscCallBLAS("BLASscal", BLASscal_(&nz, &alpha, v + j * lda, &one)); 334a5ce6ee0Svictorle } else { 3359566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n * A->cmap->n, &nz)); 336792fecdfSBarry Smith PetscCallBLAS("BLASscal", BLASscal_(&nz, &alpha, v, &one)); 337a5ce6ee0Svictorle } 33804cbc005SJose E. Roman PetscCall(PetscLogFlops(A->rmap->n * A->cmap->n)); 3399566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 3403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34180cd9d93SLois Curfman McInnes } 34280cd9d93SLois Curfman McInnes 343d71ae5a4SJacob Faibussowitsch PetscErrorCode MatShift_SeqDense(Mat A, PetscScalar alpha) 344d71ae5a4SJacob Faibussowitsch { 3452f605a99SJose E. Roman Mat_SeqDense *a = (Mat_SeqDense *)A->data; 3462f605a99SJose E. Roman PetscScalar *v; 3472f605a99SJose E. Roman PetscInt j, k; 3482f605a99SJose E. Roman 3492f605a99SJose E. Roman PetscFunctionBegin; 3502f605a99SJose E. Roman PetscCall(MatDenseGetArray(A, &v)); 3512f605a99SJose E. Roman k = PetscMin(A->rmap->n, A->cmap->n); 3522f605a99SJose E. Roman for (j = 0; j < k; j++) v[j + j * a->lda] += alpha; 3532f605a99SJose E. Roman PetscCall(PetscLogFlops(k)); 3542f605a99SJose E. Roman PetscCall(MatDenseRestoreArray(A, &v)); 3553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3562f605a99SJose E. Roman } 3572f605a99SJose E. Roman 358d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatIsHermitian_SeqDense(Mat A, PetscReal rtol, PetscBool *fl) 359d71ae5a4SJacob Faibussowitsch { 3601cbb95d3SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 361ca15aa20SStefano Zampini PetscInt i, j, m = A->rmap->n, N = a->lda; 362ca15aa20SStefano Zampini const PetscScalar *v; 3631cbb95d3SBarry Smith 3641cbb95d3SBarry Smith PetscFunctionBegin; 3651cbb95d3SBarry Smith *fl = PETSC_FALSE; 3663ba16761SJacob Faibussowitsch if (A->rmap->n != A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 3679566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 3681cbb95d3SBarry Smith for (i = 0; i < m; i++) { 369ca15aa20SStefano Zampini for (j = i; j < m; j++) { 370ad540459SPierre Jolivet if (PetscAbsScalar(v[i + j * N] - PetscConj(v[j + i * N])) > rtol) goto restore; 3711cbb95d3SBarry Smith } 372637a0070SStefano Zampini } 3731cbb95d3SBarry Smith *fl = PETSC_TRUE; 374637a0070SStefano Zampini restore: 3759566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 3763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 377637a0070SStefano Zampini } 378637a0070SStefano Zampini 379d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatIsSymmetric_SeqDense(Mat A, PetscReal rtol, PetscBool *fl) 380d71ae5a4SJacob Faibussowitsch { 381637a0070SStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 382637a0070SStefano Zampini PetscInt i, j, m = A->rmap->n, N = a->lda; 383637a0070SStefano Zampini const PetscScalar *v; 384637a0070SStefano Zampini 385637a0070SStefano Zampini PetscFunctionBegin; 386637a0070SStefano Zampini *fl = PETSC_FALSE; 3873ba16761SJacob Faibussowitsch if (A->rmap->n != A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 3889566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 389637a0070SStefano Zampini for (i = 0; i < m; i++) { 390637a0070SStefano Zampini for (j = i; j < m; j++) { 391ad540459SPierre Jolivet if (PetscAbsScalar(v[i + j * N] - v[j + i * N]) > rtol) goto restore; 392637a0070SStefano Zampini } 393637a0070SStefano Zampini } 394637a0070SStefano Zampini *fl = PETSC_TRUE; 395637a0070SStefano Zampini restore: 3969566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 3973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3981cbb95d3SBarry Smith } 3991cbb95d3SBarry Smith 400d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi, Mat A, MatDuplicateOption cpvalues) 401d71ae5a4SJacob Faibussowitsch { 402ca15aa20SStefano Zampini Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 40323fc5dcaSStefano Zampini PetscInt lda = (PetscInt)mat->lda, j, m, nlda = lda; 40475f6d85dSStefano Zampini PetscBool isdensecpu; 405b24902e0SBarry Smith 406b24902e0SBarry Smith PetscFunctionBegin; 4079566063dSJacob Faibussowitsch PetscCall(PetscLayoutReference(A->rmap, &newi->rmap)); 4089566063dSJacob Faibussowitsch PetscCall(PetscLayoutReference(A->cmap, &newi->cmap)); 40923fc5dcaSStefano Zampini if (cpvalues == MAT_SHARE_NONZERO_PATTERN) { /* propagate LDA */ 4109566063dSJacob Faibussowitsch PetscCall(MatDenseSetLDA(newi, lda)); 41123fc5dcaSStefano Zampini } 4129566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)newi, MATSEQDENSE, &isdensecpu)); 4139566063dSJacob Faibussowitsch if (isdensecpu) PetscCall(MatSeqDenseSetPreallocation(newi, NULL)); 414b24902e0SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 415ca15aa20SStefano Zampini const PetscScalar *av; 416ca15aa20SStefano Zampini PetscScalar *v; 417ca15aa20SStefano Zampini 4189566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 4199566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(newi, &v)); 4209566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(newi, &nlda)); 421d0f46423SBarry Smith m = A->rmap->n; 42223fc5dcaSStefano Zampini if (lda > m || nlda > m) { 42348a46eb9SPierre Jolivet for (j = 0; j < A->cmap->n; j++) PetscCall(PetscArraycpy(v + j * nlda, av + j * lda, m)); 424b24902e0SBarry Smith } else { 4259566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(v, av, A->rmap->n * A->cmap->n)); 426b24902e0SBarry Smith } 4279566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(newi, &v)); 4289566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 429b24902e0SBarry Smith } 4303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 431b24902e0SBarry Smith } 432b24902e0SBarry Smith 433d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDuplicate_SeqDense(Mat A, MatDuplicateOption cpvalues, Mat *newmat) 434d71ae5a4SJacob Faibussowitsch { 4353a40ed3dSBarry Smith PetscFunctionBegin; 4369566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), newmat)); 4379566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*newmat, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n)); 4389566063dSJacob Faibussowitsch PetscCall(MatSetType(*newmat, ((PetscObject)A)->type_name)); 4399566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(*newmat, A, cpvalues)); 4403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 441b24902e0SBarry Smith } 442b24902e0SBarry Smith 443d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_LU(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T) 444d71ae5a4SJacob Faibussowitsch { 445c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4464396437dSToby Isaac PetscBLASInt info; 44767e560aaSBarry Smith 4483a40ed3dSBarry Smith PetscFunctionBegin; 4499566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 450792fecdfSBarry Smith PetscCallBLAS("LAPACKgetrs", LAPACKgetrs_(T ? "T" : "N", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info)); 4519566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 45205fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "GETRS - Bad solve %d", (int)info); 4539566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m))); 4543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4554396437dSToby Isaac } 4564396437dSToby Isaac 4574396437dSToby Isaac static PetscErrorCode MatConjugate_SeqDense(Mat); 4584396437dSToby Isaac 459d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_Cholesky(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T) 460d71ae5a4SJacob Faibussowitsch { 4614396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4624396437dSToby Isaac PetscBLASInt info; 4634396437dSToby Isaac 4644396437dSToby Isaac PetscFunctionBegin; 465b94d7dedSBarry Smith if (A->spd == PETSC_BOOL3_TRUE) { 4669566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A)); 4679566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 468792fecdfSBarry Smith PetscCallBLAS("LAPACKpotrs", LAPACKpotrs_("L", &m, &nrhs, mat->v, &mat->lda, x, &m, &info)); 4699566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 47005fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "POTRS Bad solve %d", (int)info); 4719566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A)); 472a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX) 473b94d7dedSBarry Smith } else if (A->hermitian == PETSC_BOOL3_TRUE) { 4749566063dSJacob Faibussowitsch if (T) PetscCall(MatConjugate_SeqDense(A)); 4759566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 476792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrs", LAPACKhetrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info)); 4779566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 47805fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "HETRS Bad solve %d", (int)info); 4799566063dSJacob Faibussowitsch if (T) PetscCall(MatConjugate_SeqDense(A)); 480a49dc2a2SStefano Zampini #endif 481a49dc2a2SStefano Zampini } else { /* symmetric case */ 4829566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 483792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrs", LAPACKsytrs_("L", &m, &nrhs, mat->v, &mat->lda, mat->pivots, x, &m, &info)); 4849566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 48505fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "SYTRS Bad solve %d", (int)info); 486a49dc2a2SStefano Zampini } 4879566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (2.0 * m * m - m))); 4883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4894396437dSToby Isaac } 49085e2c93fSHong Zhang 491d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k) 492d71ae5a4SJacob Faibussowitsch { 4934396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 4944396437dSToby Isaac PetscBLASInt info; 4954396437dSToby Isaac char trans; 4964396437dSToby Isaac 4974396437dSToby Isaac PetscFunctionBegin; 4984905a7bcSToby Isaac if (PetscDefined(USE_COMPLEX)) { 4994905a7bcSToby Isaac trans = 'C'; 5004905a7bcSToby Isaac } else { 5014905a7bcSToby Isaac trans = 'T'; 5024905a7bcSToby Isaac } 5039566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 50405fcb23eSStefano Zampini { /* lwork depends on the number of right-hand sides */ 50505fcb23eSStefano Zampini PetscBLASInt nlfwork, lfwork = -1; 50605fcb23eSStefano Zampini PetscScalar fwork; 50705fcb23eSStefano Zampini 508792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info)); 50905fcb23eSStefano Zampini nlfwork = (PetscBLASInt)PetscRealPart(fwork); 51005fcb23eSStefano Zampini if (nlfwork > mat->lfwork) { 51105fcb23eSStefano Zampini mat->lfwork = nlfwork; 51205fcb23eSStefano Zampini PetscCall(PetscFree(mat->fwork)); 51305fcb23eSStefano Zampini PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 51405fcb23eSStefano Zampini } 51505fcb23eSStefano Zampini } 516792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", &trans, &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info)); 5179566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 51805fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %d", (int)info); 5199566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 520792fecdfSBarry Smith PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "N", "N", &mat->rank, &nrhs, mat->v, &mat->lda, x, &ldx, &info)); 5219566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 52205fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %d", (int)info); 5234905a7bcSToby Isaac for (PetscInt j = 0; j < nrhs; j++) { 524ad540459SPierre Jolivet for (PetscInt i = mat->rank; i < k; i++) x[j * ldx + i] = 0.; 5254905a7bcSToby Isaac } 5269566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank)))); 5273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5284905a7bcSToby Isaac } 5294905a7bcSToby Isaac 530d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k) 531d71ae5a4SJacob Faibussowitsch { 5324396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 5334396437dSToby Isaac PetscBLASInt info; 5344396437dSToby Isaac 5354396437dSToby Isaac PetscFunctionBegin; 5364396437dSToby Isaac if (A->rmap->n == A->cmap->n && mat->rank == A->rmap->n) { 5379566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 538792fecdfSBarry Smith PetscCallBLAS("LAPACKtrtrs", LAPACKtrtrs_("U", "T", "N", &m, &nrhs, mat->v, &mat->lda, x, &ldx, &info)); 5399566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 54005fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "TRTRS - Bad triangular solve %d", (int)info); 5419566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A)); 54205fcb23eSStefano Zampini { /* lwork depends on the number of right-hand sides */ 54305fcb23eSStefano Zampini PetscBLASInt nlfwork, lfwork = -1; 54405fcb23eSStefano Zampini PetscScalar fwork; 54505fcb23eSStefano Zampini 546792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, &fwork, &lfwork, &info)); 54705fcb23eSStefano Zampini nlfwork = (PetscBLASInt)PetscRealPart(fwork); 54805fcb23eSStefano Zampini if (nlfwork > mat->lfwork) { 54905fcb23eSStefano Zampini mat->lfwork = nlfwork; 55005fcb23eSStefano Zampini PetscCall(PetscFree(mat->fwork)); 55105fcb23eSStefano Zampini PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 55205fcb23eSStefano Zampini } 55305fcb23eSStefano Zampini } 5549566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 555792fecdfSBarry Smith PetscCallBLAS("LAPACKormqr", LAPACKormqr_("L", "N", &m, &nrhs, &mat->rank, mat->v, &mat->lda, mat->tau, x, &ldx, mat->fwork, &mat->lfwork, &info)); 5569566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 55705fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "ORMQR - Bad orthogonal transform %d", (int)info); 5589566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A)); 5594396437dSToby Isaac } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "QR factored matrix cannot be used for transpose solve"); 5609566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs * (4.0 * m * mat->rank - PetscSqr(mat->rank)))); 5613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5624396437dSToby Isaac } 5634396437dSToby Isaac 564d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_SetUp(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k) 565d71ae5a4SJacob Faibussowitsch { 5664396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 5674905a7bcSToby Isaac PetscScalar *y; 5684905a7bcSToby Isaac PetscBLASInt m = 0, k = 0; 5694905a7bcSToby Isaac 5704905a7bcSToby Isaac PetscFunctionBegin; 5719566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 5729566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 5734905a7bcSToby Isaac if (k < m) { 5749566063dSJacob Faibussowitsch PetscCall(VecCopy(xx, mat->qrrhs)); 5759566063dSJacob Faibussowitsch PetscCall(VecGetArray(mat->qrrhs, &y)); 5764905a7bcSToby Isaac } else { 5779566063dSJacob Faibussowitsch PetscCall(VecCopy(xx, yy)); 5789566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &y)); 5794905a7bcSToby Isaac } 5804396437dSToby Isaac *_y = y; 5814396437dSToby Isaac *_k = k; 5824396437dSToby Isaac *_m = m; 5833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5844396437dSToby Isaac } 5854396437dSToby Isaac 586d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_TearDown(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k) 587d71ae5a4SJacob Faibussowitsch { 5884396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 58942e9364cSSatish Balay PetscScalar *y = NULL; 5904396437dSToby Isaac PetscBLASInt m, k; 5914396437dSToby Isaac 5924396437dSToby Isaac PetscFunctionBegin; 5934396437dSToby Isaac y = *_y; 5944396437dSToby Isaac *_y = NULL; 5954396437dSToby Isaac k = *_k; 5964396437dSToby Isaac m = *_m; 5974905a7bcSToby Isaac if (k < m) { 5984905a7bcSToby Isaac PetscScalar *yv; 5999566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &yv)); 6009566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(yv, y, k)); 6019566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &yv)); 6029566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(mat->qrrhs, &y)); 6034905a7bcSToby Isaac } else { 6049566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &y)); 6054905a7bcSToby Isaac } 6063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6074905a7bcSToby Isaac } 6084905a7bcSToby Isaac 609d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_LU(Mat A, Vec xx, Vec yy) 610d71ae5a4SJacob Faibussowitsch { 61142e9364cSSatish Balay PetscScalar *y = NULL; 61242e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 6134396437dSToby Isaac 6144396437dSToby Isaac PetscFunctionBegin; 6159566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6169566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_FALSE)); 6179566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6194396437dSToby Isaac } 6204396437dSToby Isaac 621d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_LU(Mat A, Vec xx, Vec yy) 622d71ae5a4SJacob Faibussowitsch { 62342e9364cSSatish Balay PetscScalar *y = NULL; 62442e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 6254396437dSToby Isaac 6264396437dSToby Isaac PetscFunctionBegin; 6279566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6289566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_TRUE)); 6299566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6314396437dSToby Isaac } 6324396437dSToby Isaac 633d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_Cholesky(Mat A, Vec xx, Vec yy) 634d71ae5a4SJacob Faibussowitsch { 635e54beecaSStefano Zampini PetscScalar *y = NULL; 636e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 6374396437dSToby Isaac 6384396437dSToby Isaac PetscFunctionBegin; 6399566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6409566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_FALSE)); 6419566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6434396437dSToby Isaac } 6444396437dSToby Isaac 645d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_Cholesky(Mat A, Vec xx, Vec yy) 646d71ae5a4SJacob Faibussowitsch { 647e54beecaSStefano Zampini PetscScalar *y = NULL; 648e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 6494396437dSToby Isaac 6504396437dSToby Isaac PetscFunctionBegin; 6519566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6529566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_TRUE)); 6539566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6554396437dSToby Isaac } 6564396437dSToby Isaac 657d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolve_SeqDense_QR(Mat A, Vec xx, Vec yy) 658d71ae5a4SJacob Faibussowitsch { 659e54beecaSStefano Zampini PetscScalar *y = NULL; 660e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 6614396437dSToby Isaac 6624396437dSToby Isaac PetscFunctionBegin; 6639566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6649566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k)); 6659566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6674396437dSToby Isaac } 6684396437dSToby Isaac 669d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSolveTranspose_SeqDense_QR(Mat A, Vec xx, Vec yy) 670d71ae5a4SJacob Faibussowitsch { 67142e9364cSSatish Balay PetscScalar *y = NULL; 67242e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 6734396437dSToby Isaac 6744396437dSToby Isaac PetscFunctionBegin; 6759566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6769566063dSJacob Faibussowitsch PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, PetscMax(m, k), m, 1, k)); 6779566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 6794396437dSToby Isaac } 6804396437dSToby Isaac 681d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_SetUp(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k) 682d71ae5a4SJacob Faibussowitsch { 6834905a7bcSToby Isaac const PetscScalar *b; 6844396437dSToby Isaac PetscScalar *y; 685bf5a80bcSToby Isaac PetscInt n, _ldb, _ldx; 686bf5a80bcSToby Isaac PetscBLASInt nrhs = 0, m = 0, k = 0, ldb = 0, ldx = 0, ldy = 0; 6874905a7bcSToby Isaac 6884905a7bcSToby Isaac PetscFunctionBegin; 6899371c9d4SSatish Balay *_ldy = 0; 6909371c9d4SSatish Balay *_m = 0; 6919371c9d4SSatish Balay *_nrhs = 0; 6929371c9d4SSatish Balay *_k = 0; 6939371c9d4SSatish Balay *_y = NULL; 6949566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 6959566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 6969566063dSJacob Faibussowitsch PetscCall(MatGetSize(B, NULL, &n)); 6979566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(n, &nrhs)); 6989566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(B, &_ldb)); 6999566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldb, &ldb)); 7009566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(X, &_ldx)); 7019566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldx, &ldx)); 702bf5a80bcSToby Isaac if (ldx < m) { 7039566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &b)); 7049566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nrhs * m, &y)); 705bf5a80bcSToby Isaac if (ldb == m) { 7069566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(y, b, ldb * nrhs)); 7074905a7bcSToby Isaac } else { 70848a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * m], &b[j * ldb], m)); 7094905a7bcSToby Isaac } 710bf5a80bcSToby Isaac ldy = m; 7119566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &b)); 7124905a7bcSToby Isaac } else { 713bf5a80bcSToby Isaac if (ldb == ldx) { 7149566063dSJacob Faibussowitsch PetscCall(MatCopy(B, X, SAME_NONZERO_PATTERN)); 7159566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &y)); 7164905a7bcSToby Isaac } else { 7179566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &y)); 7189566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &b)); 71948a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&y[j * ldx], &b[j * ldb], m)); 7209566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &b)); 7214905a7bcSToby Isaac } 722bf5a80bcSToby Isaac ldy = ldx; 7234905a7bcSToby Isaac } 7244396437dSToby Isaac *_y = y; 725bf5a80bcSToby Isaac *_ldy = ldy; 7264396437dSToby Isaac *_k = k; 7274396437dSToby Isaac *_m = m; 7284396437dSToby Isaac *_nrhs = nrhs; 7293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7304396437dSToby Isaac } 7314396437dSToby Isaac 732d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_TearDown(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k) 733d71ae5a4SJacob Faibussowitsch { 7344396437dSToby Isaac PetscScalar *y; 735bf5a80bcSToby Isaac PetscInt _ldx; 736bf5a80bcSToby Isaac PetscBLASInt k, ldy, nrhs, ldx = 0; 7374396437dSToby Isaac 7384396437dSToby Isaac PetscFunctionBegin; 7394396437dSToby Isaac y = *_y; 7404396437dSToby Isaac *_y = NULL; 7414396437dSToby Isaac k = *_k; 742bf5a80bcSToby Isaac ldy = *_ldy; 7434396437dSToby Isaac nrhs = *_nrhs; 7449566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(X, &_ldx)); 7459566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldx, &ldx)); 746bf5a80bcSToby Isaac if (ldx != ldy) { 7474905a7bcSToby Isaac PetscScalar *xv; 7489566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X, &xv)); 74948a46eb9SPierre Jolivet for (PetscInt j = 0; j < nrhs; j++) PetscCall(PetscArraycpy(&xv[j * ldx], &y[j * ldy], k)); 7509566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(X, &xv)); 7519566063dSJacob Faibussowitsch PetscCall(PetscFree(y)); 7524905a7bcSToby Isaac } else { 7539566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(X, &y)); 7544905a7bcSToby Isaac } 7553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 75685e2c93fSHong Zhang } 75785e2c93fSHong Zhang 758d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_LU(Mat A, Mat B, Mat X) 759d71ae5a4SJacob Faibussowitsch { 7604396437dSToby Isaac PetscScalar *y; 761bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7624396437dSToby Isaac 7634396437dSToby Isaac PetscFunctionBegin; 7649566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7659566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_FALSE)); 7669566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7684396437dSToby Isaac } 7694396437dSToby Isaac 770d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_LU(Mat A, Mat B, Mat X) 771d71ae5a4SJacob Faibussowitsch { 7724396437dSToby Isaac PetscScalar *y; 773bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7744396437dSToby Isaac 7754396437dSToby Isaac PetscFunctionBegin; 7769566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7779566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_TRUE)); 7789566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7804396437dSToby Isaac } 7814396437dSToby Isaac 782d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_Cholesky(Mat A, Mat B, Mat X) 783d71ae5a4SJacob Faibussowitsch { 7844396437dSToby Isaac PetscScalar *y; 785bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7864396437dSToby Isaac 7874396437dSToby Isaac PetscFunctionBegin; 7889566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7899566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_FALSE)); 7909566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7924396437dSToby Isaac } 7934396437dSToby Isaac 794d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_Cholesky(Mat A, Mat B, Mat X) 795d71ae5a4SJacob Faibussowitsch { 7964396437dSToby Isaac PetscScalar *y; 797bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7984396437dSToby Isaac 7994396437dSToby Isaac PetscFunctionBegin; 8009566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 8019566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_TRUE)); 8029566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 8033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8044396437dSToby Isaac } 8054396437dSToby Isaac 806d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolve_SeqDense_QR(Mat A, Mat B, Mat X) 807d71ae5a4SJacob Faibussowitsch { 8084396437dSToby Isaac PetscScalar *y; 809bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 8104396437dSToby Isaac 8114396437dSToby Isaac PetscFunctionBegin; 8129566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 8139566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k)); 8149566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 8153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8164396437dSToby Isaac } 8174396437dSToby Isaac 818d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMatSolveTranspose_SeqDense_QR(Mat A, Mat B, Mat X) 819d71ae5a4SJacob Faibussowitsch { 8204396437dSToby Isaac PetscScalar *y; 821bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 8224396437dSToby Isaac 8234396437dSToby Isaac PetscFunctionBegin; 8249566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 8259566063dSJacob Faibussowitsch PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k)); 8269566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 8273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8284396437dSToby Isaac } 8294396437dSToby Isaac 830db4efbfdSBarry Smith /* ---------------------------------------------------------------*/ 831db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots, 832db4efbfdSBarry Smith rather than put it in the Mat->row slot.*/ 833d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLUFactor_SeqDense(Mat A, IS row, IS col, const MatFactorInfo *minfo) 834d71ae5a4SJacob Faibussowitsch { 835db4efbfdSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 836db4efbfdSBarry Smith PetscBLASInt n, m, info; 837db4efbfdSBarry Smith 838db4efbfdSBarry Smith PetscFunctionBegin; 8399566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 8409566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 8414dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); } 8423ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 8439566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 844792fecdfSBarry Smith PetscCallBLAS("LAPACKgetrf", LAPACKgetrf_(&m, &n, mat->v, &mat->lda, mat->pivots, &info)); 8459566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 8468e57ea43SSatish Balay 84705fcb23eSStefano Zampini PetscCheck(info >= 0, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to LU factorization %d", (int)info); 84805fcb23eSStefano Zampini PetscCheck(info <= 0, PETSC_COMM_SELF, PETSC_ERR_MAT_LU_ZRPVT, "Bad LU factorization %d", (int)info); 8498208b9aeSStefano Zampini 8504396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_LU; 8514396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_LU; 8524396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_LU; 8534396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_LU; 854d5f3da31SBarry Smith A->factortype = MAT_FACTOR_LU; 855db4efbfdSBarry Smith 8569566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 8579566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 858f6224b95SHong Zhang 8599566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((2.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3)); 8603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 861db4efbfdSBarry Smith } 862db4efbfdSBarry Smith 863d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) 864d71ae5a4SJacob Faibussowitsch { 8654396437dSToby Isaac MatFactorInfo info; 8664396437dSToby Isaac 8674396437dSToby Isaac PetscFunctionBegin; 8689566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 869dbbe0bcdSBarry Smith PetscUseTypeMethod(fact, lufactor, NULL, NULL, &info); 8703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8714396437dSToby Isaac } 8724396437dSToby Isaac 873d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, IS col, const MatFactorInfo *info) 874d71ae5a4SJacob Faibussowitsch { 8754396437dSToby Isaac PetscFunctionBegin; 8764396437dSToby Isaac fact->preallocated = PETSC_TRUE; 8774396437dSToby Isaac fact->assembled = PETSC_TRUE; 8784396437dSToby Isaac fact->ops->lufactornumeric = MatLUFactorNumeric_SeqDense; 8793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8804396437dSToby Isaac } 8814396437dSToby Isaac 882a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */ 883d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCholeskyFactor_SeqDense(Mat A, IS perm, const MatFactorInfo *factinfo) 884d71ae5a4SJacob Faibussowitsch { 885db4efbfdSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 886c5df96a5SBarry Smith PetscBLASInt info, n; 887db4efbfdSBarry Smith 888db4efbfdSBarry Smith PetscFunctionBegin; 8899566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 8903ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 891b94d7dedSBarry Smith if (A->spd == PETSC_BOOL3_TRUE) { 8929566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 893792fecdfSBarry Smith PetscCallBLAS("LAPACKpotrf", LAPACKpotrf_("L", &n, mat->v, &mat->lda, &info)); 8949566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 895a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX) 896b94d7dedSBarry Smith } else if (A->hermitian == PETSC_BOOL3_TRUE) { 8974dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); } 898a49dc2a2SStefano Zampini if (!mat->fwork) { 899a49dc2a2SStefano Zampini PetscScalar dummy; 900a49dc2a2SStefano Zampini 901a49dc2a2SStefano Zampini mat->lfwork = -1; 9029566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 903792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info)); 9049566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 905a49dc2a2SStefano Zampini mat->lfwork = (PetscInt)PetscRealPart(dummy); 9069566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 907a49dc2a2SStefano Zampini } 9089566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 909792fecdfSBarry Smith PetscCallBLAS("LAPACKhetrf", LAPACKhetrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info)); 9109566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 911a49dc2a2SStefano Zampini #endif 912a49dc2a2SStefano Zampini } else { /* symmetric case */ 9134dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(A->rmap->n, &mat->pivots)); } 914a49dc2a2SStefano Zampini if (!mat->fwork) { 915a49dc2a2SStefano Zampini PetscScalar dummy; 916a49dc2a2SStefano Zampini 917a49dc2a2SStefano Zampini mat->lfwork = -1; 9189566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 919792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, &dummy, &mat->lfwork, &info)); 9209566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 921a49dc2a2SStefano Zampini mat->lfwork = (PetscInt)PetscRealPart(dummy); 9229566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 923a49dc2a2SStefano Zampini } 9249566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 925792fecdfSBarry Smith PetscCallBLAS("LAPACKsytrf", LAPACKsytrf_("L", &n, mat->v, &mat->lda, mat->pivots, mat->fwork, &mat->lfwork, &info)); 9269566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 927a49dc2a2SStefano Zampini } 92828b400f6SJacob Faibussowitsch PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_MAT_CH_ZRPVT, "Bad factorization: zero pivot in row %" PetscInt_FMT, (PetscInt)info - 1); 9298208b9aeSStefano Zampini 9304396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_Cholesky; 9314396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_Cholesky; 9324396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_Cholesky; 9334396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_Cholesky; 934d5f3da31SBarry Smith A->factortype = MAT_FACTOR_CHOLESKY; 9352205254eSKarl Rupp 9369566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 9379566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 938f6224b95SHong Zhang 9399566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((1.0 * A->cmap->n * A->cmap->n * A->cmap->n) / 3.0)); 9403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 941db4efbfdSBarry Smith } 942db4efbfdSBarry Smith 943d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) 944d71ae5a4SJacob Faibussowitsch { 945db4efbfdSBarry Smith MatFactorInfo info; 946db4efbfdSBarry Smith 947db4efbfdSBarry Smith PetscFunctionBegin; 948db4efbfdSBarry Smith info.fill = 1.0; 9492205254eSKarl Rupp 9509566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 951dbbe0bcdSBarry Smith PetscUseTypeMethod(fact, choleskyfactor, NULL, &info); 9523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 953db4efbfdSBarry Smith } 954db4efbfdSBarry Smith 955d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info) 956d71ae5a4SJacob Faibussowitsch { 957db4efbfdSBarry Smith PetscFunctionBegin; 958c3ef05f6SHong Zhang fact->assembled = PETSC_TRUE; 9591bbcc794SSatish Balay fact->preallocated = PETSC_TRUE; 960719d5645SBarry Smith fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense; 9613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 962db4efbfdSBarry Smith } 963db4efbfdSBarry Smith 964d71ae5a4SJacob Faibussowitsch PetscErrorCode MatQRFactor_SeqDense(Mat A, IS col, const MatFactorInfo *minfo) 965d71ae5a4SJacob Faibussowitsch { 9664905a7bcSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 9674905a7bcSToby Isaac PetscBLASInt n, m, info, min, max; 9684905a7bcSToby Isaac 9694905a7bcSToby Isaac PetscFunctionBegin; 9709566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 9719566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 9724396437dSToby Isaac max = PetscMax(m, n); 9734396437dSToby Isaac min = PetscMin(m, n); 9744dfa11a4SJacob Faibussowitsch if (!mat->tau) { PetscCall(PetscMalloc1(min, &mat->tau)); } 9754dfa11a4SJacob Faibussowitsch if (!mat->pivots) { PetscCall(PetscMalloc1(n, &mat->pivots)); } 97648a46eb9SPierre Jolivet if (!mat->qrrhs) PetscCall(MatCreateVecs(A, NULL, &(mat->qrrhs))); 9773ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 9784905a7bcSToby Isaac if (!mat->fwork) { 9794905a7bcSToby Isaac PetscScalar dummy; 9804905a7bcSToby Isaac 9814905a7bcSToby Isaac mat->lfwork = -1; 9829566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 983792fecdfSBarry Smith PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, &dummy, &mat->lfwork, &info)); 9849566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 9854905a7bcSToby Isaac mat->lfwork = (PetscInt)PetscRealPart(dummy); 9869566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork, &mat->fwork)); 9874905a7bcSToby Isaac } 9889566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 989792fecdfSBarry Smith PetscCallBLAS("LAPACKgeqrf", LAPACKgeqrf_(&m, &n, mat->v, &mat->lda, mat->tau, mat->fwork, &mat->lfwork, &info)); 9909566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 99105fcb23eSStefano Zampini PetscCheck(!info, PETSC_COMM_SELF, PETSC_ERR_LIB, "Bad argument to QR factorization %d", (int)info); 9924905a7bcSToby 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 9934905a7bcSToby Isaac mat->rank = min; 9944905a7bcSToby Isaac 9954396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_QR; 9964396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_QR; 9974905a7bcSToby Isaac A->factortype = MAT_FACTOR_QR; 9984905a7bcSToby Isaac if (m == n) { 9994396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_QR; 10004396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_QR; 10014905a7bcSToby Isaac } 10024905a7bcSToby Isaac 10039566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 10049566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &A->solvertype)); 10054905a7bcSToby Isaac 10069566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * min * min * (max - min / 3.0))); 10073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 10084905a7bcSToby Isaac } 10094905a7bcSToby Isaac 1010d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatQRFactorNumeric_SeqDense(Mat fact, Mat A, const MatFactorInfo *info_dummy) 1011d71ae5a4SJacob Faibussowitsch { 10124905a7bcSToby Isaac MatFactorInfo info; 10134905a7bcSToby Isaac 10144905a7bcSToby Isaac PetscFunctionBegin; 10154905a7bcSToby Isaac info.fill = 1.0; 10164905a7bcSToby Isaac 10179566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact, A, MAT_COPY_VALUES)); 1018cac4c232SBarry Smith PetscUseMethod(fact, "MatQRFactor_C", (Mat, IS, const MatFactorInfo *), (fact, NULL, &info)); 10193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 10204905a7bcSToby Isaac } 10214905a7bcSToby Isaac 1022d71ae5a4SJacob Faibussowitsch PetscErrorCode MatQRFactorSymbolic_SeqDense(Mat fact, Mat A, IS row, const MatFactorInfo *info) 1023d71ae5a4SJacob Faibussowitsch { 10244905a7bcSToby Isaac PetscFunctionBegin; 10254905a7bcSToby Isaac fact->assembled = PETSC_TRUE; 10264905a7bcSToby Isaac fact->preallocated = PETSC_TRUE; 10279566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)fact, "MatQRFactorNumeric_C", MatQRFactorNumeric_SeqDense)); 10283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 10294905a7bcSToby Isaac } 10304905a7bcSToby Isaac 1031ca15aa20SStefano Zampini /* uses LAPACK */ 1032d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A, MatFactorType ftype, Mat *fact) 1033d71ae5a4SJacob Faibussowitsch { 1034db4efbfdSBarry Smith PetscFunctionBegin; 10359566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), fact)); 10369566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*fact, A->rmap->n, A->cmap->n, A->rmap->n, A->cmap->n)); 10379566063dSJacob Faibussowitsch PetscCall(MatSetType(*fact, MATDENSE)); 103866e17bc3SBarry Smith (*fact)->trivialsymbolic = PETSC_TRUE; 10392a350339SBarry Smith if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU) { 1040db4efbfdSBarry Smith (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense; 10412a350339SBarry Smith (*fact)->ops->ilufactorsymbolic = MatLUFactorSymbolic_SeqDense; 1042bf5a80bcSToby Isaac } else if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) { 1043db4efbfdSBarry Smith (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense; 1044bf5a80bcSToby Isaac } else if (ftype == MAT_FACTOR_QR) { 10459566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)(*fact), "MatQRFactorSymbolic_C", MatQRFactorSymbolic_SeqDense)); 1046db4efbfdSBarry Smith } 1047d5f3da31SBarry Smith (*fact)->factortype = ftype; 104800c67f3bSHong Zhang 10499566063dSJacob Faibussowitsch PetscCall(PetscFree((*fact)->solvertype)); 10509566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC, &(*fact)->solvertype)); 10519566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_LU])); 10529566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ILU])); 10539566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_CHOLESKY])); 10549566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL, (char **)&(*fact)->preferredordering[MAT_FACTOR_ICC])); 10553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1056db4efbfdSBarry Smith } 1057db4efbfdSBarry Smith 1058289bc588SBarry Smith /* ------------------------------------------------------------------*/ 1059d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSOR_SeqDense(Mat A, Vec bb, PetscReal omega, MatSORType flag, PetscReal shift, PetscInt its, PetscInt lits, Vec xx) 1060d71ae5a4SJacob Faibussowitsch { 1061c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1062d9ca1df4SBarry Smith PetscScalar *x, *v = mat->v, zero = 0.0, xt; 1063d9ca1df4SBarry Smith const PetscScalar *b; 1064d0f46423SBarry Smith PetscInt m = A->rmap->n, i; 106523fff9afSBarry Smith PetscBLASInt o = 1, bm = 0; 1066289bc588SBarry Smith 10673a40ed3dSBarry Smith PetscFunctionBegin; 106847d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 106908401ef6SPierre Jolivet PetscCheck(A->offloadmask != PETSC_OFFLOAD_GPU, PETSC_COMM_SELF, PETSC_ERR_SUP, "Not implemented"); 1070ca15aa20SStefano Zampini #endif 1071422a814eSBarry Smith if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */ 10729566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(m, &bm)); 1073289bc588SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 10743bffc371SBarry Smith /* this is a hack fix, should have another version without the second BLASdotu */ 10759566063dSJacob Faibussowitsch PetscCall(VecSet(xx, zero)); 1076289bc588SBarry Smith } 10779566063dSJacob Faibussowitsch PetscCall(VecGetArray(xx, &x)); 10789566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(bb, &b)); 1079b965ef7fSBarry Smith its = its * lits; 108008401ef6SPierre 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); 1081289bc588SBarry Smith while (its--) { 1082fccaa45eSBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 1083289bc588SBarry Smith for (i = 0; i < m; i++) { 1084792fecdfSBarry Smith PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o)); 108555a1b374SBarry Smith x[i] = (1. - omega) * x[i] + omega * (xt + v[i + i * m] * x[i]) / (v[i + i * m] + shift); 1086289bc588SBarry Smith } 1087289bc588SBarry Smith } 1088fccaa45eSBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 1089289bc588SBarry Smith for (i = m - 1; i >= 0; i--) { 1090792fecdfSBarry Smith PetscCallBLAS("BLASdotu", xt = b[i] - BLASdotu_(&bm, v + i, &bm, x, &o)); 109155a1b374SBarry Smith x[i] = (1. - omega) * x[i] + omega * (xt + v[i + i * m] * x[i]) / (v[i + i * m] + shift); 1092289bc588SBarry Smith } 1093289bc588SBarry Smith } 1094289bc588SBarry Smith } 10959566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(bb, &b)); 10969566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(xx, &x)); 10973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1098289bc588SBarry Smith } 1099289bc588SBarry Smith 1100289bc588SBarry Smith /* -----------------------------------------------------------------*/ 1101d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultTranspose_SeqDense(Mat A, Vec xx, Vec yy) 1102d71ae5a4SJacob Faibussowitsch { 1103c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1104d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 1105d9ca1df4SBarry Smith PetscScalar *y; 11060805154bSBarry Smith PetscBLASInt m, n, _One = 1; 1107ea709b57SSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 11083a40ed3dSBarry Smith 11093a40ed3dSBarry Smith PetscFunctionBegin; 11109566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 11119566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 11129566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 11139566063dSJacob Faibussowitsch PetscCall(VecGetArrayWrite(yy, &y)); 11145ac36cfcSBarry Smith if (!A->rmap->n || !A->cmap->n) { 11155ac36cfcSBarry Smith PetscBLASInt i; 11165ac36cfcSBarry Smith for (i = 0; i < n; i++) y[i] = 0.0; 11175ac36cfcSBarry Smith } else { 1118792fecdfSBarry Smith PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v, &mat->lda, x, &_One, &_DZero, y, &_One)); 11199566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n - A->cmap->n)); 11205ac36cfcSBarry Smith } 11219566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 11229566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayWrite(yy, &y)); 11233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1124289bc588SBarry Smith } 1125800995b7SMatthew Knepley 1126d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMult_SeqDense(Mat A, Vec xx, Vec yy) 1127d71ae5a4SJacob Faibussowitsch { 1128c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1129d9ca1df4SBarry Smith PetscScalar *y, _DOne = 1.0, _DZero = 0.0; 11300805154bSBarry Smith PetscBLASInt m, n, _One = 1; 1131d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 11323a40ed3dSBarry Smith 11333a40ed3dSBarry Smith PetscFunctionBegin; 11349566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 11359566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 11369566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 11379566063dSJacob Faibussowitsch PetscCall(VecGetArrayWrite(yy, &y)); 11385ac36cfcSBarry Smith if (!A->rmap->n || !A->cmap->n) { 11395ac36cfcSBarry Smith PetscBLASInt i; 11405ac36cfcSBarry Smith for (i = 0; i < m; i++) y[i] = 0.0; 11415ac36cfcSBarry Smith } else { 1142792fecdfSBarry Smith PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DZero, y, &_One)); 11439566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n - A->rmap->n)); 11445ac36cfcSBarry Smith } 11459566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 11469566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayWrite(yy, &y)); 11473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1148289bc588SBarry Smith } 11496ee01492SSatish Balay 1150d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) 1151d71ae5a4SJacob Faibussowitsch { 1152c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1153d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 1154d9ca1df4SBarry Smith PetscScalar *y, _DOne = 1.0; 11550805154bSBarry Smith PetscBLASInt m, n, _One = 1; 11563a40ed3dSBarry Smith 11573a40ed3dSBarry Smith PetscFunctionBegin; 11589566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 11599566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 11609566063dSJacob Faibussowitsch PetscCall(VecCopy(zz, yy)); 11613ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 11629566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 11639566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &y)); 1164792fecdfSBarry Smith PetscCallBLAS("BLASgemv", BLASgemv_("N", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DOne, y, &_One)); 11659566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 11669566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &y)); 11679566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n)); 11683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1169289bc588SBarry Smith } 11706ee01492SSatish Balay 1171d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A, Vec xx, Vec zz, Vec yy) 1172d71ae5a4SJacob Faibussowitsch { 1173c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1174d9ca1df4SBarry Smith const PetscScalar *v = mat->v, *x; 1175d9ca1df4SBarry Smith PetscScalar *y; 11760805154bSBarry Smith PetscBLASInt m, n, _One = 1; 117787828ca2SBarry Smith PetscScalar _DOne = 1.0; 11783a40ed3dSBarry Smith 11793a40ed3dSBarry Smith PetscFunctionBegin; 11809566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &m)); 11819566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &n)); 11829566063dSJacob Faibussowitsch PetscCall(VecCopy(zz, yy)); 11833ba16761SJacob Faibussowitsch if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(PETSC_SUCCESS); 11849566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx, &x)); 11859566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy, &y)); 1186792fecdfSBarry Smith PetscCallBLAS("BLASgemv", BLASgemv_("T", &m, &n, &_DOne, v, &(mat->lda), x, &_One, &_DOne, y, &_One)); 11879566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx, &x)); 11889566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy, &y)); 11899566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->rmap->n * A->cmap->n)); 11903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1191289bc588SBarry Smith } 1192289bc588SBarry Smith 1193289bc588SBarry Smith /* -----------------------------------------------------------------*/ 1194d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals) 1195d71ae5a4SJacob Faibussowitsch { 1196c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 119713f74950SBarry Smith PetscInt i; 119867e560aaSBarry Smith 11993a40ed3dSBarry Smith PetscFunctionBegin; 1200d0f46423SBarry Smith *ncols = A->cmap->n; 1201289bc588SBarry Smith if (cols) { 12029566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->cmap->n, cols)); 1203d0f46423SBarry Smith for (i = 0; i < A->cmap->n; i++) (*cols)[i] = i; 1204289bc588SBarry Smith } 1205289bc588SBarry Smith if (vals) { 1206ca15aa20SStefano Zampini const PetscScalar *v; 1207ca15aa20SStefano Zampini 12089566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 12099566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->cmap->n, vals)); 1210ca15aa20SStefano Zampini v += row; 12119371c9d4SSatish Balay for (i = 0; i < A->cmap->n; i++) { 12129371c9d4SSatish Balay (*vals)[i] = *v; 12139371c9d4SSatish Balay v += mat->lda; 12149371c9d4SSatish Balay } 12159566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 1216289bc588SBarry Smith } 12173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1218289bc588SBarry Smith } 12196ee01492SSatish Balay 1220d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRestoreRow_SeqDense(Mat A, PetscInt row, PetscInt *ncols, PetscInt **cols, PetscScalar **vals) 1221d71ae5a4SJacob Faibussowitsch { 1222606d414cSSatish Balay PetscFunctionBegin; 1223cb4a9cd9SHong Zhang if (ncols) *ncols = 0; 12249566063dSJacob Faibussowitsch if (cols) PetscCall(PetscFree(*cols)); 12259566063dSJacob Faibussowitsch if (vals) PetscCall(PetscFree(*vals)); 12263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1227289bc588SBarry Smith } 1228289bc588SBarry Smith /* ----------------------------------------------------------------*/ 1229d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], const PetscScalar v[], InsertMode addv) 1230d71ae5a4SJacob Faibussowitsch { 1231c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1232ca15aa20SStefano Zampini PetscScalar *av; 123313f74950SBarry Smith PetscInt i, j, idx = 0; 123447d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1235c70f7ee4SJunchao Zhang PetscOffloadMask oldf; 1236ca15aa20SStefano Zampini #endif 1237d6dfbf8fSBarry Smith 12383a40ed3dSBarry Smith PetscFunctionBegin; 12399566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &av)); 1240289bc588SBarry Smith if (!mat->roworiented) { 1241dbb450caSBarry Smith if (addv == INSERT_VALUES) { 1242289bc588SBarry Smith for (j = 0; j < n; j++) { 12439371c9d4SSatish Balay if (indexn[j] < 0) { 12449371c9d4SSatish Balay idx += m; 12459371c9d4SSatish Balay continue; 12469371c9d4SSatish Balay } 12476bdcaf15SBarry Smith PetscCheck(indexn[j] < A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Column too large: col %" PetscInt_FMT " max %" PetscInt_FMT, indexn[j], A->cmap->n - 1); 1248289bc588SBarry Smith for (i = 0; i < m; i++) { 12499371c9d4SSatish Balay if (indexm[i] < 0) { 12509371c9d4SSatish Balay idx++; 12519371c9d4SSatish Balay continue; 12529371c9d4SSatish Balay } 12536bdcaf15SBarry Smith PetscCheck(indexm[i] < A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Row too large: row %" PetscInt_FMT " max %" PetscInt_FMT, indexm[i], A->rmap->n - 1); 1254ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] = v[idx++]; 1255289bc588SBarry Smith } 1256289bc588SBarry Smith } 12573a40ed3dSBarry Smith } else { 1258289bc588SBarry Smith for (j = 0; j < n; j++) { 12599371c9d4SSatish Balay if (indexn[j] < 0) { 12609371c9d4SSatish Balay idx += m; 12619371c9d4SSatish Balay continue; 12629371c9d4SSatish Balay } 12636bdcaf15SBarry 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); 1264289bc588SBarry Smith for (i = 0; i < m; i++) { 12659371c9d4SSatish Balay if (indexm[i] < 0) { 12669371c9d4SSatish Balay idx++; 12679371c9d4SSatish Balay continue; 12689371c9d4SSatish Balay } 12696bdcaf15SBarry 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); 1270ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] += v[idx++]; 1271289bc588SBarry Smith } 1272289bc588SBarry Smith } 1273289bc588SBarry Smith } 12743a40ed3dSBarry Smith } else { 1275dbb450caSBarry Smith if (addv == INSERT_VALUES) { 1276e8d4e0b9SBarry Smith for (i = 0; i < m; i++) { 12779371c9d4SSatish Balay if (indexm[i] < 0) { 12789371c9d4SSatish Balay idx += n; 12799371c9d4SSatish Balay continue; 12809371c9d4SSatish Balay } 12816bdcaf15SBarry Smith PetscCheck(indexm[i] < A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Row too large: row %" PetscInt_FMT " max %" PetscInt_FMT, indexm[i], A->rmap->n - 1); 1282e8d4e0b9SBarry Smith for (j = 0; j < n; j++) { 12839371c9d4SSatish Balay if (indexn[j] < 0) { 12849371c9d4SSatish Balay idx++; 12859371c9d4SSatish Balay continue; 12869371c9d4SSatish Balay } 12876bdcaf15SBarry Smith PetscCheck(indexn[j] < A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Column too large: col %" PetscInt_FMT " max %" PetscInt_FMT, indexn[j], A->cmap->n - 1); 1288ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] = v[idx++]; 1289e8d4e0b9SBarry Smith } 1290e8d4e0b9SBarry Smith } 12913a40ed3dSBarry Smith } else { 1292289bc588SBarry Smith for (i = 0; i < m; i++) { 12939371c9d4SSatish Balay if (indexm[i] < 0) { 12949371c9d4SSatish Balay idx += n; 12959371c9d4SSatish Balay continue; 12969371c9d4SSatish Balay } 12976bdcaf15SBarry 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); 1298289bc588SBarry Smith for (j = 0; j < n; j++) { 12999371c9d4SSatish Balay if (indexn[j] < 0) { 13009371c9d4SSatish Balay idx++; 13019371c9d4SSatish Balay continue; 13029371c9d4SSatish Balay } 13036bdcaf15SBarry 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); 1304ca15aa20SStefano Zampini av[indexn[j] * mat->lda + indexm[i]] += v[idx++]; 1305289bc588SBarry Smith } 1306289bc588SBarry Smith } 1307289bc588SBarry Smith } 1308e8d4e0b9SBarry Smith } 1309ca15aa20SStefano Zampini /* hack to prevent unneeded copy to the GPU while returning the array */ 131047d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1311c70f7ee4SJunchao Zhang oldf = A->offloadmask; 1312c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_GPU; 1313ca15aa20SStefano Zampini #endif 13149566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &av)); 131547d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1316c70f7ee4SJunchao Zhang A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU); 1317ca15aa20SStefano Zampini #endif 13183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1319289bc588SBarry Smith } 1320e8d4e0b9SBarry Smith 1321d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetValues_SeqDense(Mat A, PetscInt m, const PetscInt indexm[], PetscInt n, const PetscInt indexn[], PetscScalar v[]) 1322d71ae5a4SJacob Faibussowitsch { 1323ae80bb75SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1324ca15aa20SStefano Zampini const PetscScalar *vv; 132513f74950SBarry Smith PetscInt i, j; 1326ae80bb75SLois Curfman McInnes 13273a40ed3dSBarry Smith PetscFunctionBegin; 13289566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &vv)); 1329ae80bb75SLois Curfman McInnes /* row-oriented output */ 1330ae80bb75SLois Curfman McInnes for (i = 0; i < m; i++) { 13319371c9d4SSatish Balay if (indexm[i] < 0) { 13329371c9d4SSatish Balay v += n; 13339371c9d4SSatish Balay continue; 13349371c9d4SSatish Balay } 133508401ef6SPierre 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); 1336ae80bb75SLois Curfman McInnes for (j = 0; j < n; j++) { 13379371c9d4SSatish Balay if (indexn[j] < 0) { 13389371c9d4SSatish Balay v++; 13399371c9d4SSatish Balay continue; 13409371c9d4SSatish Balay } 134108401ef6SPierre 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); 1342ca15aa20SStefano Zampini *v++ = vv[indexn[j] * mat->lda + indexm[i]]; 1343ae80bb75SLois Curfman McInnes } 1344ae80bb75SLois Curfman McInnes } 13459566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &vv)); 13463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1347ae80bb75SLois Curfman McInnes } 1348ae80bb75SLois Curfman McInnes 1349289bc588SBarry Smith /* -----------------------------------------------------------------*/ 1350289bc588SBarry Smith 1351d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_Dense_Binary(Mat mat, PetscViewer viewer) 1352d71ae5a4SJacob Faibussowitsch { 13538491ab44SLisandro Dalcin PetscBool skipHeader; 13548491ab44SLisandro Dalcin PetscViewerFormat format; 13558491ab44SLisandro Dalcin PetscInt header[4], M, N, m, lda, i, j, k; 13568491ab44SLisandro Dalcin const PetscScalar *v; 13578491ab44SLisandro Dalcin PetscScalar *vwork; 1358aabbc4fbSShri Abhyankar 1359aabbc4fbSShri Abhyankar PetscFunctionBegin; 13609566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 13619566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader)); 13629566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 13638491ab44SLisandro Dalcin if (skipHeader) format = PETSC_VIEWER_NATIVE; 1364aabbc4fbSShri Abhyankar 13659566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &M, &N)); 13668491ab44SLisandro Dalcin 13678491ab44SLisandro Dalcin /* write matrix header */ 13689371c9d4SSatish Balay header[0] = MAT_FILE_CLASSID; 13699371c9d4SSatish Balay header[1] = M; 13709371c9d4SSatish Balay header[2] = N; 13718491ab44SLisandro Dalcin header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M * N; 13729566063dSJacob Faibussowitsch if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer, header, 4, PETSC_INT)); 13738491ab44SLisandro Dalcin 13749566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mat, &m, NULL)); 13758491ab44SLisandro Dalcin if (format != PETSC_VIEWER_NATIVE) { 13768491ab44SLisandro Dalcin PetscInt nnz = m * N, *iwork; 13778491ab44SLisandro Dalcin /* store row lengths for each row */ 13789566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz, &iwork)); 13798491ab44SLisandro Dalcin for (i = 0; i < m; i++) iwork[i] = N; 13809566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 13818491ab44SLisandro Dalcin /* store column indices (zero start index) */ 13828491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 13839371c9d4SSatish Balay for (j = 0; j < N; j++, k++) iwork[k] = j; 13849566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, iwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 13859566063dSJacob Faibussowitsch PetscCall(PetscFree(iwork)); 13868491ab44SLisandro Dalcin } 13878491ab44SLisandro Dalcin /* store matrix values as a dense matrix in row major order */ 13889566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m * N, &vwork)); 13899566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(mat, &v)); 13909566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(mat, &lda)); 13918491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 13929371c9d4SSatish Balay for (j = 0; j < N; j++, k++) vwork[k] = v[i + lda * j]; 13939566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(mat, &v)); 13949566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer, vwork, m * N, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 13959566063dSJacob Faibussowitsch PetscCall(PetscFree(vwork)); 13963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13978491ab44SLisandro Dalcin } 13988491ab44SLisandro Dalcin 1399d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLoad_Dense_Binary(Mat mat, PetscViewer viewer) 1400d71ae5a4SJacob Faibussowitsch { 14018491ab44SLisandro Dalcin PetscBool skipHeader; 14028491ab44SLisandro Dalcin PetscInt header[4], M, N, m, nz, lda, i, j, k; 14038491ab44SLisandro Dalcin PetscInt rows, cols; 14048491ab44SLisandro Dalcin PetscScalar *v, *vwork; 14058491ab44SLisandro Dalcin 14068491ab44SLisandro Dalcin PetscFunctionBegin; 14079566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 14089566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetSkipHeader(viewer, &skipHeader)); 14098491ab44SLisandro Dalcin 14108491ab44SLisandro Dalcin if (!skipHeader) { 14119566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, header, 4, NULL, PETSC_INT)); 141208401ef6SPierre Jolivet PetscCheck(header[0] == MAT_FILE_CLASSID, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Not a matrix object in file"); 14139371c9d4SSatish Balay M = header[1]; 14149371c9d4SSatish Balay N = header[2]; 141508401ef6SPierre Jolivet PetscCheck(M >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix row size (%" PetscInt_FMT ") in file is negative", M); 141608401ef6SPierre Jolivet PetscCheck(N >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Matrix column size (%" PetscInt_FMT ") in file is negative", N); 14178491ab44SLisandro Dalcin nz = header[3]; 1418aed4548fSBarry Smith PetscCheck(nz == MATRIX_BINARY_FORMAT_DENSE || nz >= 0, PetscObjectComm((PetscObject)viewer), PETSC_ERR_FILE_UNEXPECTED, "Unknown matrix format %" PetscInt_FMT " in file", nz); 1419aabbc4fbSShri Abhyankar } else { 14209566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &M, &N)); 1421aed4548fSBarry 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"); 14228491ab44SLisandro Dalcin nz = MATRIX_BINARY_FORMAT_DENSE; 1423e6324fbbSBarry Smith } 1424aabbc4fbSShri Abhyankar 14258491ab44SLisandro Dalcin /* setup global sizes if not set */ 14268491ab44SLisandro Dalcin if (mat->rmap->N < 0) mat->rmap->N = M; 14278491ab44SLisandro Dalcin if (mat->cmap->N < 0) mat->cmap->N = N; 14289566063dSJacob Faibussowitsch PetscCall(MatSetUp(mat)); 14298491ab44SLisandro Dalcin /* check if global sizes are correct */ 14309566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, &rows, &cols)); 1431aed4548fSBarry 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); 1432aabbc4fbSShri Abhyankar 14339566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat, NULL, &N)); 14349566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mat, &m, NULL)); 14359566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(mat, &v)); 14369566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(mat, &lda)); 14378491ab44SLisandro Dalcin if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense format */ 14388491ab44SLisandro Dalcin PetscInt nnz = m * N; 14398491ab44SLisandro Dalcin /* read in matrix values */ 14409566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz, &vwork)); 14419566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 14428491ab44SLisandro Dalcin /* store values in column major order */ 14438491ab44SLisandro Dalcin for (j = 0; j < N; j++) 14449371c9d4SSatish Balay for (i = 0; i < m; i++) v[i + lda * j] = vwork[i * N + j]; 14459566063dSJacob Faibussowitsch PetscCall(PetscFree(vwork)); 14468491ab44SLisandro Dalcin } else { /* matrix in file is sparse format */ 14478491ab44SLisandro Dalcin PetscInt nnz = 0, *rlens, *icols; 14488491ab44SLisandro Dalcin /* read in row lengths */ 14499566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m, &rlens)); 14509566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, rlens, m, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 14518491ab44SLisandro Dalcin for (i = 0; i < m; i++) nnz += rlens[i]; 14528491ab44SLisandro Dalcin /* read in column indices and values */ 14539566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(nnz, &icols, nnz, &vwork)); 14549566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, icols, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_INT)); 14559566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer, vwork, nnz, PETSC_DETERMINE, PETSC_DETERMINE, PETSC_SCALAR)); 14568491ab44SLisandro Dalcin /* store values in column major order */ 14578491ab44SLisandro Dalcin for (k = 0, i = 0; i < m; i++) 14589371c9d4SSatish Balay for (j = 0; j < rlens[i]; j++, k++) v[i + lda * icols[k]] = vwork[k]; 14599566063dSJacob Faibussowitsch PetscCall(PetscFree(rlens)); 14609566063dSJacob Faibussowitsch PetscCall(PetscFree2(icols, vwork)); 1461aabbc4fbSShri Abhyankar } 14629566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(mat, &v)); 14639566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mat, MAT_FINAL_ASSEMBLY)); 14649566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mat, MAT_FINAL_ASSEMBLY)); 14653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1466aabbc4fbSShri Abhyankar } 1467aabbc4fbSShri Abhyankar 1468d71ae5a4SJacob Faibussowitsch PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer) 1469d71ae5a4SJacob Faibussowitsch { 1470eb91f321SVaclav Hapla PetscBool isbinary, ishdf5; 1471eb91f321SVaclav Hapla 1472eb91f321SVaclav Hapla PetscFunctionBegin; 1473eb91f321SVaclav Hapla PetscValidHeaderSpecific(newMat, MAT_CLASSID, 1); 1474eb91f321SVaclav Hapla PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 1475eb91f321SVaclav Hapla /* force binary viewer to load .info file if it has not yet done so */ 14769566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 14779566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 14789566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERHDF5, &ishdf5)); 1479eb91f321SVaclav Hapla if (isbinary) { 14809566063dSJacob Faibussowitsch PetscCall(MatLoad_Dense_Binary(newMat, viewer)); 1481eb91f321SVaclav Hapla } else if (ishdf5) { 1482eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5) 14839566063dSJacob Faibussowitsch PetscCall(MatLoad_Dense_HDF5(newMat, viewer)); 1484eb91f321SVaclav Hapla #else 1485eb91f321SVaclav Hapla SETERRQ(PetscObjectComm((PetscObject)newMat), PETSC_ERR_SUP, "HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1486eb91f321SVaclav Hapla #endif 1487eb91f321SVaclav Hapla } else { 148898921bdaSJacob 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); 1489eb91f321SVaclav Hapla } 14903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1491eb91f321SVaclav Hapla } 1492eb91f321SVaclav Hapla 1493d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_ASCII(Mat A, PetscViewer viewer) 1494d71ae5a4SJacob Faibussowitsch { 1495932b0c3eSLois Curfman McInnes Mat_SeqDense *a = (Mat_SeqDense *)A->data; 149613f74950SBarry Smith PetscInt i, j; 14972dcb1b2aSMatthew Knepley const char *name; 1498ca15aa20SStefano Zampini PetscScalar *v, *av; 1499f3ef73ceSBarry Smith PetscViewerFormat format; 15005f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX) 1501ace3abfcSBarry Smith PetscBool allreal = PETSC_TRUE; 15025f481a85SSatish Balay #endif 1503932b0c3eSLois Curfman McInnes 15043a40ed3dSBarry Smith PetscFunctionBegin; 15059566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&av)); 15069566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 1507456192e2SBarry Smith if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 15083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); /* do nothing for now */ 1509fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 15109566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE)); 1511d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 1512ca15aa20SStefano Zampini v = av + i; 15139566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "row %" PetscInt_FMT ":", i)); 1514d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1515aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 1516329f5518SBarry Smith if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) { 15179566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g + %g i) ", j, (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v))); 1518329f5518SBarry Smith } else if (PetscRealPart(*v)) { 15199566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)PetscRealPart(*v))); 15206831982aSBarry Smith } 152180cd9d93SLois Curfman McInnes #else 152248a46eb9SPierre Jolivet if (*v) PetscCall(PetscViewerASCIIPrintf(viewer, " (%" PetscInt_FMT ", %g) ", j, (double)*v)); 152380cd9d93SLois Curfman McInnes #endif 15241b807ce4Svictorle v += a->lda; 152580cd9d93SLois Curfman McInnes } 15269566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 152780cd9d93SLois Curfman McInnes } 15289566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE)); 15293a40ed3dSBarry Smith } else { 15309566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_FALSE)); 1531aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 153247989497SBarry Smith /* determine if matrix has all real values */ 1533bcd8d3a4SJose E. Roman for (j = 0; j < A->cmap->n; j++) { 1534bcd8d3a4SJose E. Roman v = av + j * a->lda; 1535bcd8d3a4SJose E. Roman for (i = 0; i < A->rmap->n; i++) { 15369371c9d4SSatish Balay if (PetscImaginaryPart(v[i])) { 15379371c9d4SSatish Balay allreal = PETSC_FALSE; 15389371c9d4SSatish Balay break; 15399371c9d4SSatish Balay } 154047989497SBarry Smith } 1541bcd8d3a4SJose E. Roman } 154247989497SBarry Smith #endif 1543fb9695e5SSatish Balay if (format == PETSC_VIEWER_ASCII_MATLAB) { 15449566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)A, &name)); 15459566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%% Size = %" PetscInt_FMT " %" PetscInt_FMT " \n", A->rmap->n, A->cmap->n)); 15469566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%s = zeros(%" PetscInt_FMT ",%" PetscInt_FMT ");\n", name, A->rmap->n, A->cmap->n)); 15479566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%s = [\n", name)); 1548ffac6cdbSBarry Smith } 1549ffac6cdbSBarry Smith 1550d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 1551ca15aa20SStefano Zampini v = av + i; 1552d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1553aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 155447989497SBarry Smith if (allreal) { 15559566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)PetscRealPart(*v))); 155647989497SBarry Smith } else { 15579566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e + %18.16ei ", (double)PetscRealPart(*v), (double)PetscImaginaryPart(*v))); 155847989497SBarry Smith } 1559289bc588SBarry Smith #else 15609566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "%18.16e ", (double)*v)); 1561289bc588SBarry Smith #endif 15621b807ce4Svictorle v += a->lda; 1563289bc588SBarry Smith } 15649566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "\n")); 1565289bc588SBarry Smith } 156648a46eb9SPierre Jolivet if (format == PETSC_VIEWER_ASCII_MATLAB) PetscCall(PetscViewerASCIIPrintf(viewer, "];\n")); 15679566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer, PETSC_TRUE)); 1568da3a660dSBarry Smith } 15699566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&av)); 15709566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer)); 15713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1572289bc588SBarry Smith } 1573289bc588SBarry Smith 15749804daf3SBarry Smith #include <petscdraw.h> 1575d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw, void *Aa) 1576d71ae5a4SJacob Faibussowitsch { 1577f1af5d2fSBarry Smith Mat A = (Mat)Aa; 1578383922c3SLisandro Dalcin PetscInt m = A->rmap->n, n = A->cmap->n, i, j; 1579383922c3SLisandro Dalcin int color = PETSC_DRAW_WHITE; 1580ca15aa20SStefano Zampini const PetscScalar *v; 1581b0a32e0cSBarry Smith PetscViewer viewer; 1582b05fc000SLisandro Dalcin PetscReal xl, yl, xr, yr, x_l, x_r, y_l, y_r; 1583f3ef73ceSBarry Smith PetscViewerFormat format; 1584f1af5d2fSBarry Smith 1585f1af5d2fSBarry Smith PetscFunctionBegin; 15869566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)A, "Zoomviewer", (PetscObject *)&viewer)); 15879566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 15889566063dSJacob Faibussowitsch PetscCall(PetscDrawGetCoordinates(draw, &xl, &yl, &xr, &yr)); 1589f1af5d2fSBarry Smith 1590f1af5d2fSBarry Smith /* Loop over matrix elements drawing boxes */ 15919566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &v)); 1592fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 1593d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 1594f1af5d2fSBarry Smith /* Blue for negative and Red for positive */ 1595f1af5d2fSBarry Smith for (j = 0; j < n; j++) { 15969371c9d4SSatish Balay x_l = j; 15979371c9d4SSatish Balay x_r = x_l + 1.0; 1598f1af5d2fSBarry Smith for (i = 0; i < m; i++) { 1599f1af5d2fSBarry Smith y_l = m - i - 1.0; 1600f1af5d2fSBarry Smith y_r = y_l + 1.0; 1601ca15aa20SStefano Zampini if (PetscRealPart(v[j * m + i]) > 0.) color = PETSC_DRAW_RED; 1602ca15aa20SStefano Zampini else if (PetscRealPart(v[j * m + i]) < 0.) color = PETSC_DRAW_BLUE; 1603ca15aa20SStefano Zampini else continue; 16049566063dSJacob Faibussowitsch PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color)); 1605f1af5d2fSBarry Smith } 1606f1af5d2fSBarry Smith } 1607d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 1608f1af5d2fSBarry Smith } else { 1609f1af5d2fSBarry Smith /* use contour shading to indicate magnitude of values */ 1610f1af5d2fSBarry Smith /* first determine max of all nonzero values */ 1611b05fc000SLisandro Dalcin PetscReal minv = 0.0, maxv = 0.0; 1612b05fc000SLisandro Dalcin PetscDraw popup; 1613b05fc000SLisandro Dalcin 1614f1af5d2fSBarry Smith for (i = 0; i < m * n; i++) { 1615f1af5d2fSBarry Smith if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]); 1616f1af5d2fSBarry Smith } 1617383922c3SLisandro Dalcin if (minv >= maxv) maxv = minv + PETSC_SMALL; 16189566063dSJacob Faibussowitsch PetscCall(PetscDrawGetPopup(draw, &popup)); 16199566063dSJacob Faibussowitsch PetscCall(PetscDrawScalePopup(popup, minv, maxv)); 1620383922c3SLisandro Dalcin 1621d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 1622f1af5d2fSBarry Smith for (j = 0; j < n; j++) { 1623f1af5d2fSBarry Smith x_l = j; 1624f1af5d2fSBarry Smith x_r = x_l + 1.0; 1625f1af5d2fSBarry Smith for (i = 0; i < m; i++) { 1626f1af5d2fSBarry Smith y_l = m - i - 1.0; 1627f1af5d2fSBarry Smith y_r = y_l + 1.0; 1628b05fc000SLisandro Dalcin color = PetscDrawRealToColor(PetscAbsScalar(v[j * m + i]), minv, maxv); 16299566063dSJacob Faibussowitsch PetscCall(PetscDrawRectangle(draw, x_l, y_l, x_r, y_r, color, color, color, color)); 1630f1af5d2fSBarry Smith } 1631f1af5d2fSBarry Smith } 1632d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 1633f1af5d2fSBarry Smith } 16349566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &v)); 16353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1636f1af5d2fSBarry Smith } 1637f1af5d2fSBarry Smith 1638d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatView_SeqDense_Draw(Mat A, PetscViewer viewer) 1639d71ae5a4SJacob Faibussowitsch { 1640b0a32e0cSBarry Smith PetscDraw draw; 1641ace3abfcSBarry Smith PetscBool isnull; 1642329f5518SBarry Smith PetscReal xr, yr, xl, yl, h, w; 1643f1af5d2fSBarry Smith 1644f1af5d2fSBarry Smith PetscFunctionBegin; 16459566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 16469566063dSJacob Faibussowitsch PetscCall(PetscDrawIsNull(draw, &isnull)); 16473ba16761SJacob Faibussowitsch if (isnull) PetscFunctionReturn(PETSC_SUCCESS); 1648f1af5d2fSBarry Smith 16499371c9d4SSatish Balay xr = A->cmap->n; 16509371c9d4SSatish Balay yr = A->rmap->n; 16519371c9d4SSatish Balay h = yr / 10.0; 16529371c9d4SSatish Balay w = xr / 10.0; 16539371c9d4SSatish Balay xr += w; 16549371c9d4SSatish Balay yr += h; 16559371c9d4SSatish Balay xl = -w; 16569371c9d4SSatish Balay yl = -h; 16579566063dSJacob Faibussowitsch PetscCall(PetscDrawSetCoordinates(draw, xl, yl, xr, yr)); 16589566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", (PetscObject)viewer)); 16599566063dSJacob Faibussowitsch PetscCall(PetscDrawZoom(draw, MatView_SeqDense_Draw_Zoom, A)); 16609566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A, "Zoomviewer", NULL)); 16619566063dSJacob Faibussowitsch PetscCall(PetscDrawSave(draw)); 16623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1663f1af5d2fSBarry Smith } 1664f1af5d2fSBarry Smith 1665d71ae5a4SJacob Faibussowitsch PetscErrorCode MatView_SeqDense(Mat A, PetscViewer viewer) 1666d71ae5a4SJacob Faibussowitsch { 1667ace3abfcSBarry Smith PetscBool iascii, isbinary, isdraw; 1668932b0c3eSLois Curfman McInnes 16693a40ed3dSBarry Smith PetscFunctionBegin; 16709566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 16719566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 16729566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 16731baa6e33SBarry Smith if (iascii) PetscCall(MatView_SeqDense_ASCII(A, viewer)); 16741baa6e33SBarry Smith else if (isbinary) PetscCall(MatView_Dense_Binary(A, viewer)); 16751baa6e33SBarry Smith else if (isdraw) PetscCall(MatView_SeqDense_Draw(A, viewer)); 16763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1677932b0c3eSLois Curfman McInnes } 1678289bc588SBarry Smith 1679d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A, const PetscScalar *array) 1680d71ae5a4SJacob Faibussowitsch { 1681d3042a70SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1682d3042a70SBarry Smith 1683d3042a70SBarry Smith PetscFunctionBegin; 168428b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 168528b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 168628b400f6SJacob Faibussowitsch PetscCheck(!a->unplacedarray, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreArray() first"); 1687d3042a70SBarry Smith a->unplacedarray = a->v; 1688d3042a70SBarry Smith a->unplaced_user_alloc = a->user_alloc; 1689d3042a70SBarry Smith a->v = (PetscScalar *)array; 1690637a0070SStefano Zampini a->user_alloc = PETSC_TRUE; 169147d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1692c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_CPU; 1693ca15aa20SStefano Zampini #endif 16943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1695d3042a70SBarry Smith } 1696d3042a70SBarry Smith 1697d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseResetArray_SeqDense(Mat A) 1698d71ae5a4SJacob Faibussowitsch { 1699d3042a70SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1700d3042a70SBarry Smith 1701d3042a70SBarry Smith PetscFunctionBegin; 170228b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 170328b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 1704d3042a70SBarry Smith a->v = a->unplacedarray; 1705d3042a70SBarry Smith a->user_alloc = a->unplaced_user_alloc; 1706d3042a70SBarry Smith a->unplacedarray = NULL; 170747d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1708c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_CPU; 1709ca15aa20SStefano Zampini #endif 17103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1711d3042a70SBarry Smith } 1712d3042a70SBarry Smith 1713d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A, const PetscScalar *array) 1714d71ae5a4SJacob Faibussowitsch { 1715d5ea218eSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 1716d5ea218eSStefano Zampini 1717d5ea218eSStefano Zampini PetscFunctionBegin; 171828b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 171928b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 17209566063dSJacob Faibussowitsch if (!a->user_alloc) PetscCall(PetscFree(a->v)); 1721d5ea218eSStefano Zampini a->v = (PetscScalar *)array; 1722d5ea218eSStefano Zampini a->user_alloc = PETSC_FALSE; 172347d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 1724d5ea218eSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 1725d5ea218eSStefano Zampini #endif 17263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1727d5ea218eSStefano Zampini } 1728d5ea218eSStefano Zampini 1729d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDestroy_SeqDense(Mat mat) 1730d71ae5a4SJacob Faibussowitsch { 1731ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)mat->data; 173290f02eecSBarry Smith 17333a40ed3dSBarry Smith PetscFunctionBegin; 1734aa482453SBarry Smith #if defined(PETSC_USE_LOG) 17353ba16761SJacob Faibussowitsch PetscCall(PetscLogObjectState((PetscObject)mat, "Rows %" PetscInt_FMT " Cols %" PetscInt_FMT, mat->rmap->n, mat->cmap->n)); 1736a5a9c739SBarry Smith #endif 17379566063dSJacob Faibussowitsch PetscCall(VecDestroy(&(l->qrrhs))); 17389566063dSJacob Faibussowitsch PetscCall(PetscFree(l->tau)); 17399566063dSJacob Faibussowitsch PetscCall(PetscFree(l->pivots)); 17409566063dSJacob Faibussowitsch PetscCall(PetscFree(l->fwork)); 17419566063dSJacob Faibussowitsch PetscCall(MatDestroy(&l->ptapwork)); 17429566063dSJacob Faibussowitsch if (!l->user_alloc) PetscCall(PetscFree(l->v)); 17439566063dSJacob Faibussowitsch if (!l->unplaced_user_alloc) PetscCall(PetscFree(l->unplacedarray)); 174428b400f6SJacob Faibussowitsch PetscCheck(!l->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 174528b400f6SJacob Faibussowitsch PetscCheck(!l->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 17469566063dSJacob Faibussowitsch PetscCall(VecDestroy(&l->cvec)); 17479566063dSJacob Faibussowitsch PetscCall(MatDestroy(&l->cmat)); 17489566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->data)); 1749dbd8c25aSHong Zhang 17509566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)mat, NULL)); 17519566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactor_C", NULL)); 17522e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorSymbolic_C", NULL)); 17532e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatQRFactorNumeric_C", NULL)); 17549566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetLDA_C", NULL)); 17559566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseSetLDA_C", NULL)); 17569566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArray_C", NULL)); 17579566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArray_C", NULL)); 17589566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDensePlaceArray_C", NULL)); 17599566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseResetArray_C", NULL)); 17609566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseReplaceArray_C", NULL)); 17619566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayRead_C", NULL)); 17629566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayRead_C", NULL)); 17639566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetArrayWrite_C", NULL)); 17649566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreArrayWrite_C", NULL)); 17659566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqaij_C", NULL)); 17668baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 17679566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_elemental_C", NULL)); 17688baccfbdSHong Zhang #endif 1769d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 17709566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_scalapack_C", NULL)); 1771d24d4204SJose E. Roman #endif 17722bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA) 17739566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensecuda_C", NULL)); 17749566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", NULL)); 17759566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensecuda_seqdense_C", NULL)); 17762e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensecuda_C", NULL)); 17772bf066beSStefano Zampini #endif 177847d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 177947d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatConvert_seqdense_seqdensehip_C", NULL)); 178047d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensehip_seqdensehip_C", NULL)); 178147d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdensehip_seqdense_C", NULL)); 178247d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdensehip_C", NULL)); 178347d993e7Ssuyashtn #endif 17849566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatSeqDenseSetPreallocation_C", NULL)); 17859566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqaij_seqdense_C", NULL)); 17869566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqdense_seqdense_C", NULL)); 17879566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqbaij_seqdense_C", NULL)); 17889566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatProductSetFromOptions_seqsbaij_seqdense_C", NULL)); 178952c5f739Sprj- 17909566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumn_C", NULL)); 17919566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumn_C", NULL)); 17929566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVec_C", NULL)); 17939566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVec_C", NULL)); 17949566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecRead_C", NULL)); 17959566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecRead_C", NULL)); 17969566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetColumnVecWrite_C", NULL)); 17979566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreColumnVecWrite_C", NULL)); 17989566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseGetSubMatrix_C", NULL)); 17999566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat, "MatDenseRestoreSubMatrix_C", NULL)); 18003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1801289bc588SBarry Smith } 1802289bc588SBarry Smith 1803d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatTranspose_SeqDense(Mat A, MatReuse reuse, Mat *matout) 1804d71ae5a4SJacob Faibussowitsch { 1805c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 18066536e3caSStefano Zampini PetscInt k, j, m = A->rmap->n, M = mat->lda, n = A->cmap->n; 180787828ca2SBarry Smith PetscScalar *v, tmp; 180848b35521SBarry Smith 18093a40ed3dSBarry Smith PetscFunctionBegin; 18107fb60732SBarry Smith if (reuse == MAT_REUSE_MATRIX) PetscCall(MatTransposeCheckNonzeroState_Private(A, *matout)); 18116536e3caSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 18126536e3caSStefano Zampini if (m == n) { /* in place transpose */ 18139566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 1814d3e5ee88SLois Curfman McInnes for (j = 0; j < m; j++) { 1815289bc588SBarry Smith for (k = 0; k < j; k++) { 18161b807ce4Svictorle tmp = v[j + k * M]; 18171b807ce4Svictorle v[j + k * M] = v[k + j * M]; 18181b807ce4Svictorle v[k + j * M] = tmp; 1819289bc588SBarry Smith } 1820289bc588SBarry Smith } 18219566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 18226536e3caSStefano Zampini } else { /* reuse memory, temporary allocates new memory */ 18236536e3caSStefano Zampini PetscScalar *v2; 18246536e3caSStefano Zampini PetscLayout tmplayout; 18256536e3caSStefano Zampini 18269566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((size_t)m * n, &v2)); 18279566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 18286536e3caSStefano Zampini for (j = 0; j < n; j++) { 18296536e3caSStefano Zampini for (k = 0; k < m; k++) v2[j + (size_t)k * n] = v[k + (size_t)j * M]; 18306536e3caSStefano Zampini } 18319566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(v, v2, (size_t)m * n)); 18329566063dSJacob Faibussowitsch PetscCall(PetscFree(v2)); 18339566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 18346536e3caSStefano Zampini /* cleanup size dependent quantities */ 18359566063dSJacob Faibussowitsch PetscCall(VecDestroy(&mat->cvec)); 18369566063dSJacob Faibussowitsch PetscCall(MatDestroy(&mat->cmat)); 18379566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->pivots)); 18389566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->fwork)); 18399566063dSJacob Faibussowitsch PetscCall(MatDestroy(&mat->ptapwork)); 18406536e3caSStefano Zampini /* swap row/col layouts */ 18416536e3caSStefano Zampini mat->lda = n; 18426536e3caSStefano Zampini tmplayout = A->rmap; 18436536e3caSStefano Zampini A->rmap = A->cmap; 18446536e3caSStefano Zampini A->cmap = tmplayout; 18456536e3caSStefano Zampini } 18463a40ed3dSBarry Smith } else { /* out-of-place transpose */ 1847d3e5ee88SLois Curfman McInnes Mat tmat; 1848ec8511deSBarry Smith Mat_SeqDense *tmatd; 184987828ca2SBarry Smith PetscScalar *v2; 1850af36a384SStefano Zampini PetscInt M2; 1851ea709b57SSatish Balay 18526536e3caSStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 18539566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &tmat)); 18549566063dSJacob Faibussowitsch PetscCall(MatSetSizes(tmat, A->cmap->n, A->rmap->n, A->cmap->n, A->rmap->n)); 18559566063dSJacob Faibussowitsch PetscCall(MatSetType(tmat, ((PetscObject)A)->type_name)); 18569566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(tmat, NULL)); 1857ca15aa20SStefano Zampini } else tmat = *matout; 1858ca15aa20SStefano Zampini 18599566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&v)); 18609566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(tmat, &v2)); 1861ec8511deSBarry Smith tmatd = (Mat_SeqDense *)tmat->data; 1862ca15aa20SStefano Zampini M2 = tmatd->lda; 1863d3e5ee88SLois Curfman McInnes for (j = 0; j < n; j++) { 1864af36a384SStefano Zampini for (k = 0; k < m; k++) v2[j + k * M2] = v[k + j * M]; 1865d3e5ee88SLois Curfman McInnes } 18669566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(tmat, &v2)); 18679566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&v)); 18689566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(tmat, MAT_FINAL_ASSEMBLY)); 18699566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(tmat, MAT_FINAL_ASSEMBLY)); 18706536e3caSStefano Zampini *matout = tmat; 187148b35521SBarry Smith } 18723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1873289bc588SBarry Smith } 1874289bc588SBarry Smith 1875d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatEqual_SeqDense(Mat A1, Mat A2, PetscBool *flg) 1876d71ae5a4SJacob Faibussowitsch { 1877c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat1 = (Mat_SeqDense *)A1->data; 1878c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat2 = (Mat_SeqDense *)A2->data; 1879ca15aa20SStefano Zampini PetscInt i; 1880ca15aa20SStefano Zampini const PetscScalar *v1, *v2; 18819ea5d5aeSSatish Balay 18823a40ed3dSBarry Smith PetscFunctionBegin; 18839371c9d4SSatish Balay if (A1->rmap->n != A2->rmap->n) { 18849371c9d4SSatish Balay *flg = PETSC_FALSE; 18853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18869371c9d4SSatish Balay } 18879371c9d4SSatish Balay if (A1->cmap->n != A2->cmap->n) { 18889371c9d4SSatish Balay *flg = PETSC_FALSE; 18893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18909371c9d4SSatish Balay } 18919566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A1, &v1)); 18929566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A2, &v2)); 1893ca15aa20SStefano Zampini for (i = 0; i < A1->cmap->n; i++) { 18949566063dSJacob Faibussowitsch PetscCall(PetscArraycmp(v1, v2, A1->rmap->n, flg)); 18953ba16761SJacob Faibussowitsch if (*flg == PETSC_FALSE) PetscFunctionReturn(PETSC_SUCCESS); 1896ca15aa20SStefano Zampini v1 += mat1->lda; 1897ca15aa20SStefano Zampini v2 += mat2->lda; 18981b807ce4Svictorle } 18999566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A1, &v1)); 19009566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A2, &v2)); 190177c4ece6SBarry Smith *flg = PETSC_TRUE; 19023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1903289bc588SBarry Smith } 1904289bc588SBarry Smith 1905d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetDiagonal_SeqDense(Mat A, Vec v) 1906d71ae5a4SJacob Faibussowitsch { 1907c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 190813f74950SBarry Smith PetscInt i, n, len; 1909ca15aa20SStefano Zampini PetscScalar *x; 1910ca15aa20SStefano Zampini const PetscScalar *vv; 191144cd7ae7SLois Curfman McInnes 19123a40ed3dSBarry Smith PetscFunctionBegin; 19139566063dSJacob Faibussowitsch PetscCall(VecGetSize(v, &n)); 19149566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 1915d0f46423SBarry Smith len = PetscMin(A->rmap->n, A->cmap->n); 19169566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &vv)); 191708401ef6SPierre Jolivet PetscCheck(n == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming mat and vec"); 1918ad540459SPierre Jolivet for (i = 0; i < len; i++) x[i] = vv[i * mat->lda + i]; 19199566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &vv)); 19209566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 19213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1922289bc588SBarry Smith } 1923289bc588SBarry Smith 1924d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDiagonalScale_SeqDense(Mat A, Vec ll, Vec rr) 1925d71ae5a4SJacob Faibussowitsch { 1926c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1927f1ceaac6SMatthew G. Knepley const PetscScalar *l, *r; 1928ca15aa20SStefano Zampini PetscScalar x, *v, *vv; 1929d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n; 193055659b69SBarry Smith 19313a40ed3dSBarry Smith PetscFunctionBegin; 19329566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &vv)); 193328988994SBarry Smith if (ll) { 19349566063dSJacob Faibussowitsch PetscCall(VecGetSize(ll, &m)); 19359566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(ll, &l)); 193608401ef6SPierre Jolivet PetscCheck(m == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Left scaling vec wrong size"); 1937da3a660dSBarry Smith for (i = 0; i < m; i++) { 1938da3a660dSBarry Smith x = l[i]; 1939ca15aa20SStefano Zampini v = vv + i; 19409371c9d4SSatish Balay for (j = 0; j < n; j++) { 19419371c9d4SSatish Balay (*v) *= x; 19429371c9d4SSatish Balay v += mat->lda; 19439371c9d4SSatish Balay } 1944da3a660dSBarry Smith } 19459566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(ll, &l)); 19469566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * n * m)); 1947da3a660dSBarry Smith } 194828988994SBarry Smith if (rr) { 19499566063dSJacob Faibussowitsch PetscCall(VecGetSize(rr, &n)); 19509566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(rr, &r)); 195108401ef6SPierre Jolivet PetscCheck(n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Right scaling vec wrong size"); 1952da3a660dSBarry Smith for (i = 0; i < n; i++) { 1953da3a660dSBarry Smith x = r[i]; 1954ca15aa20SStefano Zampini v = vv + i * mat->lda; 19552205254eSKarl Rupp for (j = 0; j < m; j++) (*v++) *= x; 1956da3a660dSBarry Smith } 19579566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(rr, &r)); 19589566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * n * m)); 1959da3a660dSBarry Smith } 19609566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &vv)); 19613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1962289bc588SBarry Smith } 1963289bc588SBarry Smith 1964d71ae5a4SJacob Faibussowitsch PetscErrorCode MatNorm_SeqDense(Mat A, NormType type, PetscReal *nrm) 1965d71ae5a4SJacob Faibussowitsch { 1966c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 1967ca15aa20SStefano Zampini PetscScalar *v, *vv; 1968329f5518SBarry Smith PetscReal sum = 0.0; 196975f6d85dSStefano Zampini PetscInt lda, m = A->rmap->n, i, j; 197055659b69SBarry Smith 19713a40ed3dSBarry Smith PetscFunctionBegin; 19729566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, (const PetscScalar **)&vv)); 19739566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(A, &lda)); 1974ca15aa20SStefano Zampini v = vv; 1975289bc588SBarry Smith if (type == NORM_FROBENIUS) { 1976a5ce6ee0Svictorle if (lda > m) { 1977d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 1978ca15aa20SStefano Zampini v = vv + j * lda; 1979a5ce6ee0Svictorle for (i = 0; i < m; i++) { 19809371c9d4SSatish Balay sum += PetscRealPart(PetscConj(*v) * (*v)); 19819371c9d4SSatish Balay v++; 1982a5ce6ee0Svictorle } 1983a5ce6ee0Svictorle } 1984a5ce6ee0Svictorle } else { 1985570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16) 1986570b7f6dSBarry Smith PetscBLASInt one = 1, cnt = A->cmap->n * A->rmap->n; 1987792fecdfSBarry Smith PetscCallBLAS("BLASnrm2", *nrm = BLASnrm2_(&cnt, v, &one)); 1988570b7f6dSBarry Smith } 1989570b7f6dSBarry Smith #else 1990d0f46423SBarry Smith for (i = 0; i < A->cmap->n * A->rmap->n; i++) { 19919371c9d4SSatish Balay sum += PetscRealPart(PetscConj(*v) * (*v)); 19929371c9d4SSatish Balay v++; 1993289bc588SBarry Smith } 1994a5ce6ee0Svictorle } 19958f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 1996570b7f6dSBarry Smith #endif 19979566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0 * A->cmap->n * A->rmap->n)); 19983a40ed3dSBarry Smith } else if (type == NORM_1) { 1999064f8208SBarry Smith *nrm = 0.0; 2000d0f46423SBarry Smith for (j = 0; j < A->cmap->n; j++) { 2001ca15aa20SStefano Zampini v = vv + j * mat->lda; 2002289bc588SBarry Smith sum = 0.0; 2003d0f46423SBarry Smith for (i = 0; i < A->rmap->n; i++) { 20049371c9d4SSatish Balay sum += PetscAbsScalar(*v); 20059371c9d4SSatish Balay v++; 2006289bc588SBarry Smith } 2007064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 2008289bc588SBarry Smith } 20099566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n)); 20103a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 2011064f8208SBarry Smith *nrm = 0.0; 2012d0f46423SBarry Smith for (j = 0; j < A->rmap->n; j++) { 2013ca15aa20SStefano Zampini v = vv + j; 2014289bc588SBarry Smith sum = 0.0; 2015d0f46423SBarry Smith for (i = 0; i < A->cmap->n; i++) { 20169371c9d4SSatish Balay sum += PetscAbsScalar(*v); 20179371c9d4SSatish Balay v += mat->lda; 2018289bc588SBarry Smith } 2019064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 2020289bc588SBarry Smith } 20219566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * A->cmap->n * A->rmap->n)); 2022e7e72b3dSBarry Smith } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "No two norm"); 20239566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, (const PetscScalar **)&vv)); 20243ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2025289bc588SBarry Smith } 2026289bc588SBarry Smith 2027d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatSetOption_SeqDense(Mat A, MatOption op, PetscBool flg) 2028d71ae5a4SJacob Faibussowitsch { 2029c0bbcb79SLois Curfman McInnes Mat_SeqDense *aij = (Mat_SeqDense *)A->data; 203067e560aaSBarry Smith 20313a40ed3dSBarry Smith PetscFunctionBegin; 2032b5a2b587SKris Buschelman switch (op) { 2033d71ae5a4SJacob Faibussowitsch case MAT_ROW_ORIENTED: 2034d71ae5a4SJacob Faibussowitsch aij->roworiented = flg; 2035d71ae5a4SJacob Faibussowitsch break; 2036512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 2037b5a2b587SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 20383971808eSMatthew Knepley case MAT_NEW_NONZERO_ALLOCATION_ERR: 20398c78258cSHong Zhang case MAT_FORCE_DIAGONAL_ENTRIES: 204013fa8e87SLisandro Dalcin case MAT_KEEP_NONZERO_PATTERN: 2041b5a2b587SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 2042b5a2b587SKris Buschelman case MAT_USE_HASH_TABLE: 20430f8fb01aSBarry Smith case MAT_IGNORE_ZERO_ENTRIES: 20445021d80fSJed Brown case MAT_IGNORE_LOWER_TRIANGULAR: 2045d71ae5a4SJacob Faibussowitsch case MAT_SORTED_FULL: 2046d71ae5a4SJacob Faibussowitsch PetscCall(PetscInfo(A, "Option %s ignored\n", MatOptions[op])); 2047d71ae5a4SJacob Faibussowitsch break; 20485021d80fSJed Brown case MAT_SPD: 204977e54ba9SKris Buschelman case MAT_SYMMETRIC: 205077e54ba9SKris Buschelman case MAT_STRUCTURALLY_SYMMETRIC: 20519a4540c5SBarry Smith case MAT_HERMITIAN: 20529a4540c5SBarry Smith case MAT_SYMMETRY_ETERNAL: 2053b94d7dedSBarry Smith case MAT_STRUCTURAL_SYMMETRY_ETERNAL: 2054d71ae5a4SJacob Faibussowitsch case MAT_SPD_ETERNAL: 2055d71ae5a4SJacob Faibussowitsch break; 2056d71ae5a4SJacob Faibussowitsch default: 2057d71ae5a4SJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "unknown option %s", MatOptions[op]); 20583a40ed3dSBarry Smith } 20593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2060289bc588SBarry Smith } 2061289bc588SBarry Smith 2062d71ae5a4SJacob Faibussowitsch PetscErrorCode MatZeroEntries_SeqDense(Mat A) 2063d71ae5a4SJacob Faibussowitsch { 2064ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)A->data; 20653d8925e7SStefano Zampini PetscInt lda = l->lda, m = A->rmap->n, n = A->cmap->n, j; 2066ca15aa20SStefano Zampini PetscScalar *v; 20673a40ed3dSBarry Smith 20683a40ed3dSBarry Smith PetscFunctionBegin; 20699566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(A, &v)); 2070a5ce6ee0Svictorle if (lda > m) { 207148a46eb9SPierre Jolivet for (j = 0; j < n; j++) PetscCall(PetscArrayzero(v + j * lda, m)); 2072a5ce6ee0Svictorle } else { 20739566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(v, PetscInt64Mult(m, n))); 2074a5ce6ee0Svictorle } 20759566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(A, &v)); 20763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 20776f0a148fSBarry Smith } 20786f0a148fSBarry Smith 2079d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatZeroRows_SeqDense(Mat A, PetscInt N, const PetscInt rows[], PetscScalar diag, Vec x, Vec b) 2080d71ae5a4SJacob Faibussowitsch { 2081ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense *)A->data; 2082b9679d65SBarry Smith PetscInt m = l->lda, n = A->cmap->n, i, j; 2083ca15aa20SStefano Zampini PetscScalar *slot, *bb, *v; 208497b48c8fSBarry Smith const PetscScalar *xx; 208555659b69SBarry Smith 20863a40ed3dSBarry Smith PetscFunctionBegin; 208776bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 2088b9679d65SBarry Smith for (i = 0; i < N; i++) { 208908401ef6SPierre Jolivet PetscCheck(rows[i] >= 0, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Negative row requested to be zeroed"); 209008401ef6SPierre 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); 2091b9679d65SBarry Smith } 209276bd3646SJed Brown } 20933ba16761SJacob Faibussowitsch if (!N) PetscFunctionReturn(PETSC_SUCCESS); 2094b9679d65SBarry Smith 209597b48c8fSBarry Smith /* fix right hand side if needed */ 209697b48c8fSBarry Smith if (x && b) { 20979566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xx)); 20989566063dSJacob Faibussowitsch PetscCall(VecGetArray(b, &bb)); 20992205254eSKarl Rupp for (i = 0; i < N; i++) bb[rows[i]] = diag * xx[rows[i]]; 21009566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xx)); 21019566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(b, &bb)); 210297b48c8fSBarry Smith } 210397b48c8fSBarry Smith 21049566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 21056f0a148fSBarry Smith for (i = 0; i < N; i++) { 2106ca15aa20SStefano Zampini slot = v + rows[i]; 21079371c9d4SSatish Balay for (j = 0; j < n; j++) { 21089371c9d4SSatish Balay *slot = 0.0; 21099371c9d4SSatish Balay slot += m; 21109371c9d4SSatish Balay } 21116f0a148fSBarry Smith } 2112f4df32b1SMatthew Knepley if (diag != 0.0) { 211308401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n, PETSC_COMM_SELF, PETSC_ERR_SUP, "Only coded for square matrices"); 21146f0a148fSBarry Smith for (i = 0; i < N; i++) { 2115ca15aa20SStefano Zampini slot = v + (m + 1) * rows[i]; 2116f4df32b1SMatthew Knepley *slot = diag; 21176f0a148fSBarry Smith } 21186f0a148fSBarry Smith } 21199566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 21203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 21216f0a148fSBarry Smith } 2122557bce09SLois Curfman McInnes 2123d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A, PetscInt *lda) 2124d71ae5a4SJacob Faibussowitsch { 212549a6ff4bSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 212649a6ff4bSBarry Smith 212749a6ff4bSBarry Smith PetscFunctionBegin; 212849a6ff4bSBarry Smith *lda = mat->lda; 21293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 213049a6ff4bSBarry Smith } 213149a6ff4bSBarry Smith 2132d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArray_SeqDense(Mat A, PetscScalar **array) 2133d71ae5a4SJacob Faibussowitsch { 2134c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 21353a40ed3dSBarry Smith 21363a40ed3dSBarry Smith PetscFunctionBegin; 213728b400f6SJacob Faibussowitsch PetscCheck(!mat->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 213864e87e97SBarry Smith *array = mat->v; 21393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 214064e87e97SBarry Smith } 21410754003eSLois Curfman McInnes 2142d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A, PetscScalar **array) 2143d71ae5a4SJacob Faibussowitsch { 21443a40ed3dSBarry Smith PetscFunctionBegin; 214575f6d85dSStefano Zampini if (array) *array = NULL; 21463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2147ff14e315SSatish Balay } 21480754003eSLois Curfman McInnes 21490f74d2c1SSatish Balay /*@ 215011a5261eSBarry Smith MatDenseGetLDA - gets the leading dimension of the array returned from `MatDenseGetArray()` 215149a6ff4bSBarry Smith 2152ad16ce7aSStefano Zampini Not collective 215349a6ff4bSBarry Smith 215449a6ff4bSBarry Smith Input Parameter: 215511a5261eSBarry Smith . mat - a `MATDENSE` or `MATDENSECUDA` matrix 215649a6ff4bSBarry Smith 215749a6ff4bSBarry Smith Output Parameter: 215849a6ff4bSBarry Smith . lda - the leading dimension 215949a6ff4bSBarry Smith 216049a6ff4bSBarry Smith Level: intermediate 216149a6ff4bSBarry Smith 216211a5261eSBarry Smith .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseSetLDA()` 216349a6ff4bSBarry Smith @*/ 2164d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetLDA(Mat A, PetscInt *lda) 2165d71ae5a4SJacob Faibussowitsch { 216649a6ff4bSBarry Smith PetscFunctionBegin; 2167d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2168dadcf809SJacob Faibussowitsch PetscValidIntPointer(lda, 2); 216975f6d85dSStefano Zampini MatCheckPreallocated(A, 1); 2170cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetLDA_C", (Mat, PetscInt *), (A, lda)); 21713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 217249a6ff4bSBarry Smith } 217349a6ff4bSBarry Smith 21740f74d2c1SSatish Balay /*@ 217511a5261eSBarry Smith MatDenseSetLDA - Sets the leading dimension of the array used by the `MATDENSE` matrix 2176ad16ce7aSStefano Zampini 2177ad16ce7aSStefano Zampini Not collective 2178ad16ce7aSStefano Zampini 2179d8d19677SJose E. Roman Input Parameters: 218011a5261eSBarry Smith + mat - a `MATDENSE` or `MATDENSECUDA` matrix 2181ad16ce7aSStefano Zampini - lda - the leading dimension 2182ad16ce7aSStefano Zampini 2183ad16ce7aSStefano Zampini Level: intermediate 2184ad16ce7aSStefano Zampini 218511a5261eSBarry Smith .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetLDA()` 2186ad16ce7aSStefano Zampini @*/ 2187d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA(Mat A, PetscInt lda) 2188d71ae5a4SJacob Faibussowitsch { 2189ad16ce7aSStefano Zampini PetscFunctionBegin; 2190ad16ce7aSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2191cac4c232SBarry Smith PetscTryMethod(A, "MatDenseSetLDA_C", (Mat, PetscInt), (A, lda)); 21923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2193ad16ce7aSStefano Zampini } 2194ad16ce7aSStefano Zampini 2195ad16ce7aSStefano Zampini /*@C 219611a5261eSBarry Smith MatDenseGetArray - gives read-write access to the array where the data for a `MATDENSE` matrix is stored 219773a71a0fSBarry Smith 2198c3339decSBarry Smith Logically Collective 219973a71a0fSBarry Smith 220073a71a0fSBarry Smith Input Parameter: 22016947451fSStefano Zampini . mat - a dense matrix 220273a71a0fSBarry Smith 220373a71a0fSBarry Smith Output Parameter: 220473a71a0fSBarry Smith . array - pointer to the data 220573a71a0fSBarry Smith 220673a71a0fSBarry Smith Level: intermediate 220773a71a0fSBarry Smith 22080ab4885dSBarry Smith Fortran Note: 22090ab4885dSBarry Smith `MatDenseGetArray()` Fortran binding is deprecated (since PETSc 3.19), use `MatDenseGetArrayF90()` 22100ab4885dSBarry Smith 221111a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 221273a71a0fSBarry Smith @*/ 2213d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArray(Mat A, PetscScalar **array) 2214d71ae5a4SJacob Faibussowitsch { 221573a71a0fSBarry Smith PetscFunctionBegin; 2216d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2217d5ea218eSStefano Zampini PetscValidPointer(array, 2); 2218cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array)); 22193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 222073a71a0fSBarry Smith } 222173a71a0fSBarry Smith 2222dec5eb66SMatthew G Knepley /*@C 222311a5261eSBarry Smith MatDenseRestoreArray - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArray()` 222473a71a0fSBarry Smith 2225c3339decSBarry Smith Logically Collective 22268572280aSBarry Smith 22278572280aSBarry Smith Input Parameters: 22286947451fSStefano Zampini + mat - a dense matrix 2229742765d3SMatthew Knepley - array - pointer to the data (may be NULL) 22308572280aSBarry Smith 22318572280aSBarry Smith Level: intermediate 22328572280aSBarry Smith 22330ab4885dSBarry Smith Fortran Note: 22340ab4885dSBarry Smith `MatDenseRestoreArray()` Fortran binding is deprecated (since PETSc 3.19), use `MatDenseRestoreArrayF90()` 22350ab4885dSBarry Smith 223611a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 22378572280aSBarry Smith @*/ 2238d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArray(Mat A, PetscScalar **array) 2239d71ae5a4SJacob Faibussowitsch { 22408572280aSBarry Smith PetscFunctionBegin; 2241d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2242d5ea218eSStefano Zampini PetscValidPointer(array, 2); 2243cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array)); 22449566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)A)); 224547d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 2246637a0070SStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 2247637a0070SStefano Zampini #endif 22483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22498572280aSBarry Smith } 22508572280aSBarry Smith 22518572280aSBarry Smith /*@C 225211a5261eSBarry Smith MatDenseGetArrayRead - gives read-only access to the array where the data for a `MATDENSE` matrix is stored 22538572280aSBarry Smith 22540ab4885dSBarry Smith Not Collective; No Fortran Support 22558572280aSBarry Smith 22568572280aSBarry Smith Input Parameter: 22576947451fSStefano Zampini . mat - a dense matrix 22588572280aSBarry Smith 22598572280aSBarry Smith Output Parameter: 22608572280aSBarry Smith . array - pointer to the data 22618572280aSBarry Smith 22628572280aSBarry Smith Level: intermediate 22638572280aSBarry Smith 226411a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 22658572280aSBarry Smith @*/ 2266d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArrayRead(Mat A, const PetscScalar **array) 2267d71ae5a4SJacob Faibussowitsch { 22688572280aSBarry Smith PetscFunctionBegin; 2269d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2270d5ea218eSStefano Zampini PetscValidPointer(array, 2); 2271cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, const PetscScalar **), (A, array)); 22723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22738572280aSBarry Smith } 22748572280aSBarry Smith 22758572280aSBarry Smith /*@C 227611a5261eSBarry Smith MatDenseRestoreArrayRead - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayRead()` 22778572280aSBarry Smith 22780ab4885dSBarry Smith Not Collective; No Fortran Support 227973a71a0fSBarry Smith 228073a71a0fSBarry Smith Input Parameters: 22816947451fSStefano Zampini + mat - a dense matrix 2282742765d3SMatthew Knepley - array - pointer to the data (may be NULL) 228373a71a0fSBarry Smith 228473a71a0fSBarry Smith Level: intermediate 228573a71a0fSBarry Smith 228611a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 228773a71a0fSBarry Smith @*/ 2288d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArrayRead(Mat A, const PetscScalar **array) 2289d71ae5a4SJacob Faibussowitsch { 229073a71a0fSBarry Smith PetscFunctionBegin; 2291d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2292d5ea218eSStefano Zampini PetscValidPointer(array, 2); 2293cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, const PetscScalar **), (A, array)); 22943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 229573a71a0fSBarry Smith } 229673a71a0fSBarry Smith 22976947451fSStefano Zampini /*@C 229811a5261eSBarry Smith MatDenseGetArrayWrite - gives write-only access to the array where the data for a `MATDENSE` matrix is stored 22996947451fSStefano Zampini 23000ab4885dSBarry Smith Not Collective; No Fortran Support 23016947451fSStefano Zampini 23026947451fSStefano Zampini Input Parameter: 23036947451fSStefano Zampini . mat - a dense matrix 23046947451fSStefano Zampini 23056947451fSStefano Zampini Output Parameter: 23066947451fSStefano Zampini . array - pointer to the data 23076947451fSStefano Zampini 23086947451fSStefano Zampini Level: intermediate 23096947451fSStefano Zampini 231011a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()` 23116947451fSStefano Zampini @*/ 2312d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetArrayWrite(Mat A, PetscScalar **array) 2313d71ae5a4SJacob Faibussowitsch { 23146947451fSStefano Zampini PetscFunctionBegin; 2315d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2316d5ea218eSStefano Zampini PetscValidPointer(array, 2); 2317cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array)); 23183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23196947451fSStefano Zampini } 23206947451fSStefano Zampini 23216947451fSStefano Zampini /*@C 232211a5261eSBarry Smith MatDenseRestoreArrayWrite - returns access to the array where the data for a `MATDENSE` matrix is stored obtained by `MatDenseGetArrayWrite()` 23236947451fSStefano Zampini 23240ab4885dSBarry Smith Not Collective; No Fortran Support 23256947451fSStefano Zampini 23266947451fSStefano Zampini Input Parameters: 23276947451fSStefano Zampini + mat - a dense matrix 2328742765d3SMatthew Knepley - array - pointer to the data (may be NULL) 23296947451fSStefano Zampini 23306947451fSStefano Zampini Level: intermediate 23316947451fSStefano Zampini 233211a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()` 23336947451fSStefano Zampini @*/ 2334d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreArrayWrite(Mat A, PetscScalar **array) 2335d71ae5a4SJacob Faibussowitsch { 23366947451fSStefano Zampini PetscFunctionBegin; 2337d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2338d5ea218eSStefano Zampini PetscValidPointer(array, 2); 2339cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array)); 23409566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)A)); 234147d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 23426947451fSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 23436947451fSStefano Zampini #endif 23443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23456947451fSStefano Zampini } 23466947451fSStefano Zampini 2347cd3f9d89SJunchao Zhang /*@C 2348cd3f9d89SJunchao Zhang MatDenseGetArrayAndMemType - gives read-write access to the array where the data for a `MATDENSE` matrix is stored 2349cd3f9d89SJunchao Zhang 2350cd3f9d89SJunchao Zhang Logically Collective 2351cd3f9d89SJunchao Zhang 2352cd3f9d89SJunchao Zhang Input Parameter: 2353cd3f9d89SJunchao Zhang . mat - a dense matrix 2354cd3f9d89SJunchao Zhang 2355cd3f9d89SJunchao Zhang Output Parameters: 2356cd3f9d89SJunchao Zhang + array - pointer to the data 2357cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer 2358cd3f9d89SJunchao Zhang 2359cd3f9d89SJunchao Zhang Notes: 2360e865de01SJunchao Zhang If the matrix is of a device type such as MATDENSECUDA, MATDENSEHIP, etc., 2361cd3f9d89SJunchao Zhang an array on device is always returned and is guaranteed to contain the matrix's latest data. 2362cd3f9d89SJunchao Zhang 2363cd3f9d89SJunchao Zhang Level: intermediate 2364cd3f9d89SJunchao Zhang 2365cd3f9d89SJunchao Zhang .seealso: `MATDENSE`, `MatDenseRestoreArrayAndMemType()`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArrayWriteAndMemType()`, `MatDenseGetArrayRead()`, 2366cd3f9d89SJunchao Zhang `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()` 2367cd3f9d89SJunchao Zhang @*/ 2368cd3f9d89SJunchao Zhang PetscErrorCode MatDenseGetArrayAndMemType(Mat A, PetscScalar **array, PetscMemType *mtype) 2369cd3f9d89SJunchao Zhang { 2370cd3f9d89SJunchao Zhang PetscBool isMPI; 2371cd3f9d89SJunchao Zhang 2372cd3f9d89SJunchao Zhang PetscFunctionBegin; 2373cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2374cd3f9d89SJunchao Zhang PetscValidPointer(array, 2); 2375e865de01SJunchao Zhang PetscCall(MatBindToCPU(A, PETSC_FALSE)); /* We want device matrices to always return device arrays, so we unbind the matrix if it is bound to CPU */ 2376cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2377cd3f9d89SJunchao Zhang if (isMPI) { 2378cd3f9d89SJunchao Zhang /* Dispatch here so that the code can be reused for all subclasses of MATDENSE */ 2379cd3f9d89SJunchao Zhang PetscCall(MatDenseGetArrayAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype)); 2380cd3f9d89SJunchao Zhang } else { 2381cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **, PetscMemType *); 23823ba16761SJacob Faibussowitsch 23833ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayAndMemType_C", &fptr)); 2384cd3f9d89SJunchao Zhang if (fptr) { 2385cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array, mtype)); 2386cd3f9d89SJunchao Zhang } else { 2387cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseGetArray_C", (Mat, PetscScalar **), (A, array)); 2388cd3f9d89SJunchao Zhang if (mtype) *mtype = PETSC_MEMTYPE_HOST; 2389cd3f9d89SJunchao Zhang } 2390cd3f9d89SJunchao Zhang } 23913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2392cd3f9d89SJunchao Zhang } 2393cd3f9d89SJunchao Zhang 2394cd3f9d89SJunchao Zhang /*@C 2395cd3f9d89SJunchao Zhang MatDenseRestoreArrayAndMemType - returns access to the array that is obtained by `MatDenseGetArrayAndMemType()` 2396cd3f9d89SJunchao Zhang 2397cd3f9d89SJunchao Zhang Logically Collective 2398cd3f9d89SJunchao Zhang 2399cd3f9d89SJunchao Zhang Input Parameters: 2400cd3f9d89SJunchao Zhang + mat - a dense matrix 2401cd3f9d89SJunchao Zhang - array - pointer to the data 2402cd3f9d89SJunchao Zhang 2403cd3f9d89SJunchao Zhang Level: intermediate 2404cd3f9d89SJunchao Zhang 2405cd3f9d89SJunchao Zhang .seealso: `MATDENSE`, `MatDenseGetArrayAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 2406cd3f9d89SJunchao Zhang @*/ 2407cd3f9d89SJunchao Zhang PetscErrorCode MatDenseRestoreArrayAndMemType(Mat A, PetscScalar **array) 2408cd3f9d89SJunchao Zhang { 2409cd3f9d89SJunchao Zhang PetscBool isMPI; 2410cd3f9d89SJunchao Zhang 2411cd3f9d89SJunchao Zhang PetscFunctionBegin; 2412cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2413cd3f9d89SJunchao Zhang PetscValidPointer(array, 2); 2414cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2415cd3f9d89SJunchao Zhang if (isMPI) { 2416cd3f9d89SJunchao Zhang PetscCall(MatDenseRestoreArrayAndMemType(((Mat_MPIDense *)A->data)->A, array)); 2417cd3f9d89SJunchao Zhang } else { 2418cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **); 24193ba16761SJacob Faibussowitsch 24203ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayAndMemType_C", &fptr)); 2421cd3f9d89SJunchao Zhang if (fptr) { 2422cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array)); 2423cd3f9d89SJunchao Zhang } else { 2424cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseRestoreArray_C", (Mat, PetscScalar **), (A, array)); 2425cd3f9d89SJunchao Zhang } 2426cd3f9d89SJunchao Zhang *array = NULL; 2427cd3f9d89SJunchao Zhang } 2428cd3f9d89SJunchao Zhang PetscCall(PetscObjectStateIncrease((PetscObject)A)); 24293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2430cd3f9d89SJunchao Zhang } 2431cd3f9d89SJunchao Zhang 2432cd3f9d89SJunchao Zhang /*@C 2433cd3f9d89SJunchao Zhang MatDenseGetArrayReadAndMemType - gives read-only access to the array where the data for a `MATDENSE` matrix is stored 2434cd3f9d89SJunchao Zhang 2435cd3f9d89SJunchao Zhang Logically Collective 2436cd3f9d89SJunchao Zhang 2437cd3f9d89SJunchao Zhang Input Parameter: 2438cd3f9d89SJunchao Zhang . mat - a dense matrix 2439cd3f9d89SJunchao Zhang 2440cd3f9d89SJunchao Zhang Output Parameters: 2441cd3f9d89SJunchao Zhang + array - pointer to the data 2442cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer 2443cd3f9d89SJunchao Zhang 2444cd3f9d89SJunchao Zhang Notes: 2445e865de01SJunchao Zhang If the matrix is of a device type such as MATDENSECUDA, MATDENSEHIP, etc., 2446cd3f9d89SJunchao Zhang an array on device is always returned and is guaranteed to contain the matrix's latest data. 2447cd3f9d89SJunchao Zhang 2448cd3f9d89SJunchao Zhang Level: intermediate 2449cd3f9d89SJunchao Zhang 2450cd3f9d89SJunchao Zhang .seealso: `MATDENSE`, `MatDenseRestoreArrayReadAndMemType()`, `MatDenseGetArrayWriteAndMemType()`, 2451cd3f9d89SJunchao Zhang `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()` 2452cd3f9d89SJunchao Zhang @*/ 2453cd3f9d89SJunchao Zhang PetscErrorCode MatDenseGetArrayReadAndMemType(Mat A, const PetscScalar **array, PetscMemType *mtype) 2454cd3f9d89SJunchao Zhang { 2455cd3f9d89SJunchao Zhang PetscBool isMPI; 2456cd3f9d89SJunchao Zhang 2457cd3f9d89SJunchao Zhang PetscFunctionBegin; 2458cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2459cd3f9d89SJunchao Zhang PetscValidPointer(array, 2); 2460e865de01SJunchao Zhang PetscCall(MatBindToCPU(A, PETSC_FALSE)); /* We want device matrices to always return device arrays, so we unbind the matrix if it is bound to CPU */ 2461cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2462cd3f9d89SJunchao Zhang if (isMPI) { /* Dispatch here so that the code can be reused for all subclasses of MATDENSE */ 2463cd3f9d89SJunchao Zhang PetscCall(MatDenseGetArrayReadAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype)); 2464cd3f9d89SJunchao Zhang } else { 2465cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, const PetscScalar **, PetscMemType *); 24663ba16761SJacob Faibussowitsch 24673ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayReadAndMemType_C", &fptr)); 2468cd3f9d89SJunchao Zhang if (fptr) { 2469cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array, mtype)); 2470cd3f9d89SJunchao Zhang } else { 2471cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseGetArrayRead_C", (Mat, const PetscScalar **), (A, array)); 2472cd3f9d89SJunchao Zhang if (mtype) *mtype = PETSC_MEMTYPE_HOST; 2473cd3f9d89SJunchao Zhang } 2474cd3f9d89SJunchao Zhang } 24753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2476cd3f9d89SJunchao Zhang } 2477cd3f9d89SJunchao Zhang 2478cd3f9d89SJunchao Zhang /*@C 2479cd3f9d89SJunchao Zhang MatDenseRestoreArrayReadAndMemType - returns access to the array that is obtained by `MatDenseGetArrayReadAndMemType()` 2480cd3f9d89SJunchao Zhang 2481cd3f9d89SJunchao Zhang Logically Collective 2482cd3f9d89SJunchao Zhang 2483cd3f9d89SJunchao Zhang Input Parameters: 2484cd3f9d89SJunchao Zhang + mat - a dense matrix 2485cd3f9d89SJunchao Zhang - array - pointer to the data 2486cd3f9d89SJunchao Zhang 2487cd3f9d89SJunchao Zhang Level: intermediate 2488cd3f9d89SJunchao Zhang 2489cd3f9d89SJunchao Zhang .seealso: `MATDENSE`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 2490cd3f9d89SJunchao Zhang @*/ 2491cd3f9d89SJunchao Zhang PetscErrorCode MatDenseRestoreArrayReadAndMemType(Mat A, const PetscScalar **array) 2492cd3f9d89SJunchao Zhang { 2493cd3f9d89SJunchao Zhang PetscBool isMPI; 2494cd3f9d89SJunchao Zhang 2495cd3f9d89SJunchao Zhang PetscFunctionBegin; 2496cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2497cd3f9d89SJunchao Zhang PetscValidPointer(array, 2); 2498cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2499cd3f9d89SJunchao Zhang if (isMPI) { 2500cd3f9d89SJunchao Zhang PetscCall(MatDenseRestoreArrayReadAndMemType(((Mat_MPIDense *)A->data)->A, array)); 2501cd3f9d89SJunchao Zhang } else { 2502cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, const PetscScalar **); 25033ba16761SJacob Faibussowitsch 25043ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayReadAndMemType_C", &fptr)); 2505cd3f9d89SJunchao Zhang if (fptr) { 2506cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array)); 2507cd3f9d89SJunchao Zhang } else { 2508cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseRestoreArrayRead_C", (Mat, const PetscScalar **), (A, array)); 2509cd3f9d89SJunchao Zhang } 2510cd3f9d89SJunchao Zhang *array = NULL; 2511cd3f9d89SJunchao Zhang } 25123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2513cd3f9d89SJunchao Zhang } 2514cd3f9d89SJunchao Zhang 2515cd3f9d89SJunchao Zhang /*@C 2516cd3f9d89SJunchao Zhang MatDenseGetArrayWriteAndMemType - gives write-only access to the array where the data for a `MATDENSE` matrix is stored 2517cd3f9d89SJunchao Zhang 2518cd3f9d89SJunchao Zhang Logically Collective 2519cd3f9d89SJunchao Zhang 2520cd3f9d89SJunchao Zhang Input Parameter: 2521cd3f9d89SJunchao Zhang . mat - a dense matrix 2522cd3f9d89SJunchao Zhang 2523cd3f9d89SJunchao Zhang Output Parameters: 2524cd3f9d89SJunchao Zhang + array - pointer to the data 2525cd3f9d89SJunchao Zhang - mtype - memory type of the returned pointer 2526cd3f9d89SJunchao Zhang 2527cd3f9d89SJunchao Zhang Notes: 2528e865de01SJunchao Zhang If the matrix is of a device type such as MATDENSECUDA, MATDENSEHIP, etc., 2529cd3f9d89SJunchao Zhang an array on device is always returned and is guaranteed to contain the matrix's latest data. 2530cd3f9d89SJunchao Zhang 2531cd3f9d89SJunchao Zhang Level: intermediate 2532cd3f9d89SJunchao Zhang 2533cd3f9d89SJunchao Zhang .seealso: `MATDENSE`, `MatDenseRestoreArrayWriteAndMemType()`, `MatDenseGetArrayReadAndMemType()`, `MatDenseGetArrayRead()`, 2534cd3f9d89SJunchao Zhang `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`, `MatSeqAIJGetCSRAndMemType()` 2535cd3f9d89SJunchao Zhang @*/ 2536cd3f9d89SJunchao Zhang PetscErrorCode MatDenseGetArrayWriteAndMemType(Mat A, PetscScalar **array, PetscMemType *mtype) 2537cd3f9d89SJunchao Zhang { 2538cd3f9d89SJunchao Zhang PetscBool isMPI; 2539cd3f9d89SJunchao Zhang 2540cd3f9d89SJunchao Zhang PetscFunctionBegin; 2541cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2542cd3f9d89SJunchao Zhang PetscValidPointer(array, 2); 2543e865de01SJunchao Zhang PetscCall(MatBindToCPU(A, PETSC_FALSE)); /* We want device matrices to always return device arrays, so we unbind the matrix if it is bound to CPU */ 2544cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2545cd3f9d89SJunchao Zhang if (isMPI) { 2546cd3f9d89SJunchao Zhang PetscCall(MatDenseGetArrayWriteAndMemType(((Mat_MPIDense *)A->data)->A, array, mtype)); 2547cd3f9d89SJunchao Zhang } else { 2548cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **, PetscMemType *); 25493ba16761SJacob Faibussowitsch 25503ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseGetArrayWriteAndMemType_C", &fptr)); 2551cd3f9d89SJunchao Zhang if (fptr) { 2552cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array, mtype)); 2553cd3f9d89SJunchao Zhang } else { 2554cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseGetArrayWrite_C", (Mat, PetscScalar **), (A, array)); 2555cd3f9d89SJunchao Zhang if (mtype) *mtype = PETSC_MEMTYPE_HOST; 2556cd3f9d89SJunchao Zhang } 2557cd3f9d89SJunchao Zhang } 25583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2559cd3f9d89SJunchao Zhang } 2560cd3f9d89SJunchao Zhang 2561cd3f9d89SJunchao Zhang /*@C 2562cd3f9d89SJunchao Zhang MatDenseRestoreArrayWriteAndMemType - returns access to the array that is obtained by `MatDenseGetArrayReadAndMemType()` 2563cd3f9d89SJunchao Zhang 2564cd3f9d89SJunchao Zhang Logically Collective 2565cd3f9d89SJunchao Zhang 2566cd3f9d89SJunchao Zhang Input Parameters: 2567cd3f9d89SJunchao Zhang + mat - a dense matrix 2568cd3f9d89SJunchao Zhang - array - pointer to the data 2569cd3f9d89SJunchao Zhang 2570cd3f9d89SJunchao Zhang Level: intermediate 2571cd3f9d89SJunchao Zhang 2572cd3f9d89SJunchao Zhang .seealso: `MATDENSE`, `MatDenseGetArrayWriteAndMemType()`, `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 2573cd3f9d89SJunchao Zhang @*/ 2574cd3f9d89SJunchao Zhang PetscErrorCode MatDenseRestoreArrayWriteAndMemType(Mat A, PetscScalar **array) 2575cd3f9d89SJunchao Zhang { 2576cd3f9d89SJunchao Zhang PetscBool isMPI; 2577cd3f9d89SJunchao Zhang 2578cd3f9d89SJunchao Zhang PetscFunctionBegin; 2579cd3f9d89SJunchao Zhang PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 2580cd3f9d89SJunchao Zhang PetscValidPointer(array, 2); 2581cd3f9d89SJunchao Zhang PetscCall(PetscObjectBaseTypeCompare((PetscObject)A, MATMPIDENSE, &isMPI)); 2582cd3f9d89SJunchao Zhang if (isMPI) { 2583cd3f9d89SJunchao Zhang PetscCall(MatDenseRestoreArrayWriteAndMemType(((Mat_MPIDense *)A->data)->A, array)); 2584cd3f9d89SJunchao Zhang } else { 2585cd3f9d89SJunchao Zhang PetscErrorCode (*fptr)(Mat, PetscScalar **); 25863ba16761SJacob Faibussowitsch 25873ba16761SJacob Faibussowitsch PetscCall(PetscObjectQueryFunction((PetscObject)A, "MatDenseRestoreArrayWriteAndMemType_C", &fptr)); 2588cd3f9d89SJunchao Zhang if (fptr) { 2589cd3f9d89SJunchao Zhang PetscCall((*fptr)(A, array)); 2590cd3f9d89SJunchao Zhang } else { 2591cd3f9d89SJunchao Zhang PetscUseMethod(A, "MatDenseRestoreArrayWrite_C", (Mat, PetscScalar **), (A, array)); 2592cd3f9d89SJunchao Zhang } 2593cd3f9d89SJunchao Zhang *array = NULL; 2594cd3f9d89SJunchao Zhang } 2595cd3f9d89SJunchao Zhang PetscCall(PetscObjectStateIncrease((PetscObject)A)); 25963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2597cd3f9d89SJunchao Zhang } 2598cd3f9d89SJunchao Zhang 2599d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A, IS isrow, IS iscol, MatReuse scall, Mat *B) 2600d71ae5a4SJacob Faibussowitsch { 2601c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 2602bf5a80bcSToby Isaac PetscInt i, j, nrows, ncols, ldb; 26035d0c19d7SBarry Smith const PetscInt *irow, *icol; 260487828ca2SBarry Smith PetscScalar *av, *bv, *v = mat->v; 26050754003eSLois Curfman McInnes Mat newmat; 26060754003eSLois Curfman McInnes 26073a40ed3dSBarry Smith PetscFunctionBegin; 26089566063dSJacob Faibussowitsch PetscCall(ISGetIndices(isrow, &irow)); 26099566063dSJacob Faibussowitsch PetscCall(ISGetIndices(iscol, &icol)); 26109566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(isrow, &nrows)); 26119566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(iscol, &ncols)); 26120754003eSLois Curfman McInnes 2613182d2002SSatish Balay /* Check submatrixcall */ 2614182d2002SSatish Balay if (scall == MAT_REUSE_MATRIX) { 261513f74950SBarry Smith PetscInt n_cols, n_rows; 26169566063dSJacob Faibussowitsch PetscCall(MatGetSize(*B, &n_rows, &n_cols)); 261721a2c019SBarry Smith if (n_rows != nrows || n_cols != ncols) { 2618f746d493SDmitry Karpeev /* resize the result matrix to match number of requested rows/columns */ 26199566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*B, nrows, ncols, nrows, ncols)); 262021a2c019SBarry Smith } 2621182d2002SSatish Balay newmat = *B; 2622182d2002SSatish Balay } else { 26230754003eSLois Curfman McInnes /* Create and fill new matrix */ 26249566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &newmat)); 26259566063dSJacob Faibussowitsch PetscCall(MatSetSizes(newmat, nrows, ncols, nrows, ncols)); 26269566063dSJacob Faibussowitsch PetscCall(MatSetType(newmat, ((PetscObject)A)->type_name)); 26279566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(newmat, NULL)); 2628182d2002SSatish Balay } 2629182d2002SSatish Balay 2630182d2002SSatish Balay /* Now extract the data pointers and do the copy,column at a time */ 26319566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(newmat, &bv)); 26329566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(newmat, &ldb)); 2633182d2002SSatish Balay for (i = 0; i < ncols; i++) { 26346de62eeeSBarry Smith av = v + mat->lda * icol[i]; 2635ca15aa20SStefano Zampini for (j = 0; j < nrows; j++) bv[j] = av[irow[j]]; 2636bf5a80bcSToby Isaac bv += ldb; 26370754003eSLois Curfman McInnes } 26389566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(newmat, &bv)); 2639182d2002SSatish Balay 2640182d2002SSatish Balay /* Assemble the matrices so that the correct flags are set */ 26419566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(newmat, MAT_FINAL_ASSEMBLY)); 26429566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(newmat, MAT_FINAL_ASSEMBLY)); 26430754003eSLois Curfman McInnes 26440754003eSLois Curfman McInnes /* Free work space */ 26459566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(isrow, &irow)); 26469566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(iscol, &icol)); 2647182d2002SSatish Balay *B = newmat; 26483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26490754003eSLois Curfman McInnes } 26500754003eSLois Curfman McInnes 2651d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A, PetscInt n, const IS irow[], const IS icol[], MatReuse scall, Mat *B[]) 2652d71ae5a4SJacob Faibussowitsch { 265313f74950SBarry Smith PetscInt i; 2654905e6a2fSBarry Smith 26553a40ed3dSBarry Smith PetscFunctionBegin; 265648a46eb9SPierre Jolivet if (scall == MAT_INITIAL_MATRIX) PetscCall(PetscCalloc1(n, B)); 2657905e6a2fSBarry Smith 265848a46eb9SPierre Jolivet for (i = 0; i < n; i++) PetscCall(MatCreateSubMatrix_SeqDense(A, irow[i], icol[i], scall, &(*B)[i])); 26593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2660905e6a2fSBarry Smith } 2661905e6a2fSBarry Smith 2662d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat, MatAssemblyType mode) 2663d71ae5a4SJacob Faibussowitsch { 2664c0aa2d19SHong Zhang PetscFunctionBegin; 26653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2666c0aa2d19SHong Zhang } 2667c0aa2d19SHong Zhang 2668d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat, MatAssemblyType mode) 2669d71ae5a4SJacob Faibussowitsch { 2670c0aa2d19SHong Zhang PetscFunctionBegin; 26713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2672c0aa2d19SHong Zhang } 2673c0aa2d19SHong Zhang 2674d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCopy_SeqDense(Mat A, Mat B, MatStructure str) 2675d71ae5a4SJacob Faibussowitsch { 26764b0e389bSBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data; 2677ca15aa20SStefano Zampini const PetscScalar *va; 2678ca15aa20SStefano Zampini PetscScalar *vb; 2679d0f46423SBarry Smith PetscInt lda1 = a->lda, lda2 = b->lda, m = A->rmap->n, n = A->cmap->n, j; 26803a40ed3dSBarry Smith 26813a40ed3dSBarry Smith PetscFunctionBegin; 268233f4a19fSKris Buschelman /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */ 268333f4a19fSKris Buschelman if (A->ops->copy != B->ops->copy) { 26849566063dSJacob Faibussowitsch PetscCall(MatCopy_Basic(A, B, str)); 26853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26863a40ed3dSBarry Smith } 2687aed4548fSBarry Smith PetscCheck(m == B->rmap->n && n == B->cmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "size(B) != size(A)"); 26889566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &va)); 26899566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(B, &vb)); 2690a5ce6ee0Svictorle if (lda1 > m || lda2 > m) { 269148a46eb9SPierre Jolivet for (j = 0; j < n; j++) PetscCall(PetscArraycpy(vb + j * lda2, va + j * lda1, m)); 2692a5ce6ee0Svictorle } else { 26939566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(vb, va, A->rmap->n * A->cmap->n)); 2694a5ce6ee0Svictorle } 26959566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(B, &vb)); 26969566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &va)); 26979566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B, MAT_FINAL_ASSEMBLY)); 26989566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B, MAT_FINAL_ASSEMBLY)); 26993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2700273d9f13SBarry Smith } 2701273d9f13SBarry Smith 2702d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetUp_SeqDense(Mat A) 2703d71ae5a4SJacob Faibussowitsch { 2704273d9f13SBarry Smith PetscFunctionBegin; 27059566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 27069566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 270748a46eb9SPierre Jolivet if (!A->preallocated) PetscCall(MatSeqDenseSetPreallocation(A, NULL)); 27083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 27094b0e389bSBarry Smith } 27104b0e389bSBarry Smith 2711d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatConjugate_SeqDense(Mat A) 2712d71ae5a4SJacob Faibussowitsch { 27134396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 271406c5243aSJose E. Roman PetscInt i, j; 27154396437dSToby Isaac PetscInt min = PetscMin(A->rmap->n, A->cmap->n); 2716ca15aa20SStefano Zampini PetscScalar *aa; 2717ba337c44SJed Brown 2718ba337c44SJed Brown PetscFunctionBegin; 27199566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 272006c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 272106c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscConj(aa[i + j * mat->lda]); 272206c5243aSJose E. Roman } 27239566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 27249371c9d4SSatish Balay if (mat->tau) 27259371c9d4SSatish Balay for (i = 0; i < min; i++) mat->tau[i] = PetscConj(mat->tau[i]); 27263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2727ba337c44SJed Brown } 2728ba337c44SJed Brown 2729d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatRealPart_SeqDense(Mat A) 2730d71ae5a4SJacob Faibussowitsch { 273106c5243aSJose E. Roman Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 273206c5243aSJose E. Roman PetscInt i, j; 2733ca15aa20SStefano Zampini PetscScalar *aa; 2734ba337c44SJed Brown 2735ba337c44SJed Brown PetscFunctionBegin; 27369566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 273706c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 273806c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscRealPart(aa[i + j * mat->lda]); 273906c5243aSJose E. Roman } 27409566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 27413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2742ba337c44SJed Brown } 2743ba337c44SJed Brown 2744d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatImaginaryPart_SeqDense(Mat A) 2745d71ae5a4SJacob Faibussowitsch { 274606c5243aSJose E. Roman Mat_SeqDense *mat = (Mat_SeqDense *)A->data; 274706c5243aSJose E. Roman PetscInt i, j; 2748ca15aa20SStefano Zampini PetscScalar *aa; 2749ba337c44SJed Brown 2750ba337c44SJed Brown PetscFunctionBegin; 27519566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &aa)); 275206c5243aSJose E. Roman for (j = 0; j < A->cmap->n; j++) { 275306c5243aSJose E. Roman for (i = 0; i < A->rmap->n; i++) aa[i + j * mat->lda] = PetscImaginaryPart(aa[i + j * mat->lda]); 275406c5243aSJose E. Roman } 27559566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &aa)); 27563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2757ba337c44SJed Brown } 2758284134d9SBarry Smith 2759a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/ 2760d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2761d71ae5a4SJacob Faibussowitsch { 2762d0f46423SBarry Smith PetscInt m = A->rmap->n, n = B->cmap->n; 276347d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 2764a9fe9ddaSSatish Balay 2765ee16a9a1SHong Zhang PetscFunctionBegin; 27669566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 276747d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 27689566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 276947d993e7Ssuyashtn #endif 277047d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 277147d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 277247d993e7Ssuyashtn #endif 27737a3c3d58SStefano Zampini if (!cisdense) { 27747a3c3d58SStefano Zampini PetscBool flg; 27757a3c3d58SStefano Zampini 27769566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 27779566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 27787a3c3d58SStefano Zampini } 27799566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 27803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2781ee16a9a1SHong Zhang } 2782a9fe9ddaSSatish Balay 2783d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2784d71ae5a4SJacob Faibussowitsch { 27856718818eSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data, *b = (Mat_SeqDense *)B->data, *c = (Mat_SeqDense *)C->data; 27860805154bSBarry Smith PetscBLASInt m, n, k; 2787ca15aa20SStefano Zampini const PetscScalar *av, *bv; 2788ca15aa20SStefano Zampini PetscScalar *cv; 2789a9fe9ddaSSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 2790a9fe9ddaSSatish Balay 2791a9fe9ddaSSatish Balay PetscFunctionBegin; 27929566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 27939566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 27949566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 27953ba16761SJacob Faibussowitsch if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS); 27969566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 27979566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 27989566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2799792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("N", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 28009566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 28019566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 28029566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 28039566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 28043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2805a9fe9ddaSSatish Balay } 2806a9fe9ddaSSatish Balay 2807d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2808d71ae5a4SJacob Faibussowitsch { 280969f65d41SStefano Zampini PetscInt m = A->rmap->n, n = B->rmap->n; 281047d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 281169f65d41SStefano Zampini 281269f65d41SStefano Zampini PetscFunctionBegin; 28139566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 281447d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 28159566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 281647d993e7Ssuyashtn #endif 281747d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 281847d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 281947d993e7Ssuyashtn #endif 28207a3c3d58SStefano Zampini if (!cisdense) { 28217a3c3d58SStefano Zampini PetscBool flg; 28227a3c3d58SStefano Zampini 28239566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 28249566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 28257a3c3d58SStefano Zampini } 28269566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 28273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 282869f65d41SStefano Zampini } 282969f65d41SStefano Zampini 2830d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2831d71ae5a4SJacob Faibussowitsch { 283269f65d41SStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 283369f65d41SStefano Zampini Mat_SeqDense *b = (Mat_SeqDense *)B->data; 283469f65d41SStefano Zampini Mat_SeqDense *c = (Mat_SeqDense *)C->data; 28356718818eSStefano Zampini const PetscScalar *av, *bv; 28366718818eSStefano Zampini PetscScalar *cv; 283769f65d41SStefano Zampini PetscBLASInt m, n, k; 283869f65d41SStefano Zampini PetscScalar _DOne = 1.0, _DZero = 0.0; 283969f65d41SStefano Zampini 284069f65d41SStefano Zampini PetscFunctionBegin; 28419566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 28429566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 28439566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n, &k)); 28443ba16761SJacob Faibussowitsch if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS); 28459566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 28469566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 28479566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2848792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("N", "T", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 28499566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 28509566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 28519566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 28529566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 28533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 285469f65d41SStefano Zampini } 285569f65d41SStefano Zampini 2856d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A, Mat B, PetscReal fill, Mat C) 2857d71ae5a4SJacob Faibussowitsch { 2858d0f46423SBarry Smith PetscInt m = A->cmap->n, n = B->cmap->n; 285947d993e7Ssuyashtn PetscBool cisdense = PETSC_FALSE; 2860a9fe9ddaSSatish Balay 2861ee16a9a1SHong Zhang PetscFunctionBegin; 28629566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, m, n)); 286347d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) 28649566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSECUDA, "")); 286547d993e7Ssuyashtn #endif 286647d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 286747d993e7Ssuyashtn PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATSEQDENSE, MATSEQDENSEHIP, "")); 286847d993e7Ssuyashtn #endif 28697a3c3d58SStefano Zampini if (!cisdense) { 28707a3c3d58SStefano Zampini PetscBool flg; 28717a3c3d58SStefano Zampini 28729566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B, ((PetscObject)A)->type_name, &flg)); 28739566063dSJacob Faibussowitsch PetscCall(MatSetType(C, flg ? ((PetscObject)A)->type_name : MATDENSE)); 28747a3c3d58SStefano Zampini } 28759566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 28763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2877ee16a9a1SHong Zhang } 2878a9fe9ddaSSatish Balay 2879d71ae5a4SJacob Faibussowitsch PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A, Mat B, Mat C) 2880d71ae5a4SJacob Faibussowitsch { 2881a9fe9ddaSSatish Balay Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2882a9fe9ddaSSatish Balay Mat_SeqDense *b = (Mat_SeqDense *)B->data; 2883a9fe9ddaSSatish Balay Mat_SeqDense *c = (Mat_SeqDense *)C->data; 28846718818eSStefano Zampini const PetscScalar *av, *bv; 28856718818eSStefano Zampini PetscScalar *cv; 28860805154bSBarry Smith PetscBLASInt m, n, k; 2887a9fe9ddaSSatish Balay PetscScalar _DOne = 1.0, _DZero = 0.0; 2888a9fe9ddaSSatish Balay 2889a9fe9ddaSSatish Balay PetscFunctionBegin; 28909566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n, &m)); 28919566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n, &n)); 28929566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n, &k)); 28933ba16761SJacob Faibussowitsch if (!m || !n || !k) PetscFunctionReturn(PETSC_SUCCESS); 28949566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &av)); 28959566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &bv)); 28969566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C, &cv)); 2897792fecdfSBarry Smith PetscCallBLAS("BLASgemm", BLASgemm_("T", "N", &m, &n, &k, &_DOne, av, &a->lda, bv, &b->lda, &_DZero, cv, &c->lda)); 28989566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &av)); 28999566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &bv)); 29009566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C, &cv)); 29019566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0 * m * n * k + 1.0 * m * n * (k - 1))); 29023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2903a9fe9ddaSSatish Balay } 2904985db425SBarry Smith 29054222ddf1SHong Zhang /* ----------------------------------------------- */ 2906d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C) 2907d71ae5a4SJacob Faibussowitsch { 29084222ddf1SHong Zhang PetscFunctionBegin; 29094222ddf1SHong Zhang C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense; 29104222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AB; 29113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29124222ddf1SHong Zhang } 29134222ddf1SHong Zhang 2914d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C) 2915d71ae5a4SJacob Faibussowitsch { 29164222ddf1SHong Zhang PetscFunctionBegin; 29174222ddf1SHong Zhang C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense; 29184222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AtB; 29193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29204222ddf1SHong Zhang } 29214222ddf1SHong Zhang 2922d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C) 2923d71ae5a4SJacob Faibussowitsch { 29244222ddf1SHong Zhang PetscFunctionBegin; 29254222ddf1SHong Zhang C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense; 29264222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_ABt; 29273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29284222ddf1SHong Zhang } 29294222ddf1SHong Zhang 2930d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C) 2931d71ae5a4SJacob Faibussowitsch { 29324222ddf1SHong Zhang Mat_Product *product = C->product; 29334222ddf1SHong Zhang 29344222ddf1SHong Zhang PetscFunctionBegin; 29354222ddf1SHong Zhang switch (product->type) { 2936d71ae5a4SJacob Faibussowitsch case MATPRODUCT_AB: 2937d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_AB(C)); 2938d71ae5a4SJacob Faibussowitsch break; 2939d71ae5a4SJacob Faibussowitsch case MATPRODUCT_AtB: 2940d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_AtB(C)); 2941d71ae5a4SJacob Faibussowitsch break; 2942d71ae5a4SJacob Faibussowitsch case MATPRODUCT_ABt: 2943d71ae5a4SJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_ABt(C)); 2944d71ae5a4SJacob Faibussowitsch break; 2945d71ae5a4SJacob Faibussowitsch default: 2946d71ae5a4SJacob Faibussowitsch break; 29474222ddf1SHong Zhang } 29483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29494222ddf1SHong Zhang } 29504222ddf1SHong Zhang /* ----------------------------------------------- */ 29514222ddf1SHong Zhang 2952d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMax_SeqDense(Mat A, Vec v, PetscInt idx[]) 2953d71ae5a4SJacob Faibussowitsch { 2954985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2955d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2956985db425SBarry Smith PetscScalar *x; 2957ca15aa20SStefano Zampini const PetscScalar *aa; 2958985db425SBarry Smith 2959985db425SBarry Smith PetscFunctionBegin; 296028b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29619566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29629566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 29639566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 296408401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2965985db425SBarry Smith for (i = 0; i < m; i++) { 29669371c9d4SSatish Balay x[i] = aa[i]; 29679371c9d4SSatish Balay if (idx) idx[i] = 0; 2968985db425SBarry Smith for (j = 1; j < n; j++) { 29699371c9d4SSatish Balay if (PetscRealPart(x[i]) < PetscRealPart(aa[i + a->lda * j])) { 29709371c9d4SSatish Balay x[i] = aa[i + a->lda * j]; 29719371c9d4SSatish Balay if (idx) idx[i] = j; 29729371c9d4SSatish Balay } 2973985db425SBarry Smith } 2974985db425SBarry Smith } 29759566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 29769566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 29773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2978985db425SBarry Smith } 2979985db425SBarry Smith 2980d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A, Vec v, PetscInt idx[]) 2981d71ae5a4SJacob Faibussowitsch { 2982985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 2983d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 2984985db425SBarry Smith PetscScalar *x; 2985985db425SBarry Smith PetscReal atmp; 2986ca15aa20SStefano Zampini const PetscScalar *aa; 2987985db425SBarry Smith 2988985db425SBarry Smith PetscFunctionBegin; 298928b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 29909566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 29919566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 29929566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 299308401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 2994985db425SBarry Smith for (i = 0; i < m; i++) { 29959189402eSHong Zhang x[i] = PetscAbsScalar(aa[i]); 2996985db425SBarry Smith for (j = 1; j < n; j++) { 2997ca15aa20SStefano Zampini atmp = PetscAbsScalar(aa[i + a->lda * j]); 29989371c9d4SSatish Balay if (PetscAbsScalar(x[i]) < atmp) { 29999371c9d4SSatish Balay x[i] = atmp; 30009371c9d4SSatish Balay if (idx) idx[i] = j; 30019371c9d4SSatish Balay } 3002985db425SBarry Smith } 3003985db425SBarry Smith } 30049566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 30059566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 30063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3007985db425SBarry Smith } 3008985db425SBarry Smith 3009d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatGetRowMin_SeqDense(Mat A, Vec v, PetscInt idx[]) 3010d71ae5a4SJacob Faibussowitsch { 3011985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 3012d0f46423SBarry Smith PetscInt i, j, m = A->rmap->n, n = A->cmap->n, p; 3013985db425SBarry Smith PetscScalar *x; 3014ca15aa20SStefano Zampini const PetscScalar *aa; 3015985db425SBarry Smith 3016985db425SBarry Smith PetscFunctionBegin; 301728b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 30189566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 30199566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 30209566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v, &p)); 302108401ef6SPierre Jolivet PetscCheck(p == A->rmap->n, PETSC_COMM_SELF, PETSC_ERR_ARG_SIZ, "Nonconforming matrix and vector"); 3022985db425SBarry Smith for (i = 0; i < m; i++) { 30239371c9d4SSatish Balay x[i] = aa[i]; 30249371c9d4SSatish Balay if (idx) idx[i] = 0; 3025985db425SBarry Smith for (j = 1; j < n; j++) { 30269371c9d4SSatish Balay if (PetscRealPart(x[i]) > PetscRealPart(aa[i + a->lda * j])) { 30279371c9d4SSatish Balay x[i] = aa[i + a->lda * j]; 30289371c9d4SSatish Balay if (idx) idx[i] = j; 30299371c9d4SSatish Balay } 3030985db425SBarry Smith } 3031985db425SBarry Smith } 30329566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 30339566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 30343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3035985db425SBarry Smith } 3036985db425SBarry Smith 3037d71ae5a4SJacob Faibussowitsch PetscErrorCode MatGetColumnVector_SeqDense(Mat A, Vec v, PetscInt col) 3038d71ae5a4SJacob Faibussowitsch { 30398d0534beSBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 30408d0534beSBarry Smith PetscScalar *x; 3041ca15aa20SStefano Zampini const PetscScalar *aa; 30428d0534beSBarry Smith 30438d0534beSBarry Smith PetscFunctionBegin; 304428b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 30459566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &aa)); 30469566063dSJacob Faibussowitsch PetscCall(VecGetArray(v, &x)); 30479566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(x, aa + col * a->lda, A->rmap->n)); 30489566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v, &x)); 30499566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &aa)); 30503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30518d0534beSBarry Smith } 30528d0534beSBarry Smith 3053d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatGetColumnReductions_SeqDense(Mat A, PetscInt type, PetscReal *reductions) 3054d71ae5a4SJacob Faibussowitsch { 30550716a85fSBarry Smith PetscInt i, j, m, n; 30561683a169SBarry Smith const PetscScalar *a; 30570716a85fSBarry Smith 30580716a85fSBarry Smith PetscFunctionBegin; 30599566063dSJacob Faibussowitsch PetscCall(MatGetSize(A, &m, &n)); 30609566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(reductions, n)); 30619566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &a)); 3062857cbf51SRichard Tran Mills if (type == NORM_2) { 30630716a85fSBarry Smith for (i = 0; i < n; i++) { 3064ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j] * a[j]); 30650716a85fSBarry Smith a += m; 30660716a85fSBarry Smith } 3067857cbf51SRichard Tran Mills } else if (type == NORM_1) { 30680716a85fSBarry Smith for (i = 0; i < n; i++) { 3069ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscAbsScalar(a[j]); 30700716a85fSBarry Smith a += m; 30710716a85fSBarry Smith } 3072857cbf51SRichard Tran Mills } else if (type == NORM_INFINITY) { 30730716a85fSBarry Smith for (i = 0; i < n; i++) { 3074ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] = PetscMax(PetscAbsScalar(a[j]), reductions[i]); 30750716a85fSBarry Smith a += m; 30760716a85fSBarry Smith } 3077857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_REALPART || type == REDUCTION_MEAN_REALPART) { 3078a873a8cdSSam Reynolds for (i = 0; i < n; i++) { 3079ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscRealPart(a[j]); 3080a873a8cdSSam Reynolds a += m; 3081a873a8cdSSam Reynolds } 3082857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_IMAGINARYPART || type == REDUCTION_MEAN_IMAGINARYPART) { 3083857cbf51SRichard Tran Mills for (i = 0; i < n; i++) { 3084ad540459SPierre Jolivet for (j = 0; j < m; j++) reductions[i] += PetscImaginaryPart(a[j]); 3085857cbf51SRichard Tran Mills a += m; 3086857cbf51SRichard Tran Mills } 3087857cbf51SRichard Tran Mills } else SETERRQ(PetscObjectComm((PetscObject)A), PETSC_ERR_ARG_WRONG, "Unknown reduction type"); 30889566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &a)); 3089857cbf51SRichard Tran Mills if (type == NORM_2) { 3090a873a8cdSSam Reynolds for (i = 0; i < n; i++) reductions[i] = PetscSqrtReal(reductions[i]); 3091857cbf51SRichard Tran Mills } else if (type == REDUCTION_MEAN_REALPART || type == REDUCTION_MEAN_IMAGINARYPART) { 3092a873a8cdSSam Reynolds for (i = 0; i < n; i++) reductions[i] /= m; 30930716a85fSBarry Smith } 30943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30950716a85fSBarry Smith } 30960716a85fSBarry Smith 3097d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSetRandom_SeqDense(Mat x, PetscRandom rctx) 3098d71ae5a4SJacob Faibussowitsch { 309973a71a0fSBarry Smith PetscScalar *a; 3100637a0070SStefano Zampini PetscInt lda, m, n, i, j; 310173a71a0fSBarry Smith 310273a71a0fSBarry Smith PetscFunctionBegin; 31039566063dSJacob Faibussowitsch PetscCall(MatGetSize(x, &m, &n)); 31049566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(x, &lda)); 31053faff063SStefano Zampini PetscCall(MatDenseGetArrayWrite(x, &a)); 3106637a0070SStefano Zampini for (j = 0; j < n; j++) { 310748a46eb9SPierre Jolivet for (i = 0; i < m; i++) PetscCall(PetscRandomGetValue(rctx, a + j * lda + i)); 310873a71a0fSBarry Smith } 31093faff063SStefano Zampini PetscCall(MatDenseRestoreArrayWrite(x, &a)); 31103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 311173a71a0fSBarry Smith } 311273a71a0fSBarry Smith 3113d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A, PetscBool *missing, PetscInt *d) 3114d71ae5a4SJacob Faibussowitsch { 31153b49f96aSBarry Smith PetscFunctionBegin; 31163b49f96aSBarry Smith *missing = PETSC_FALSE; 31173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 31183b49f96aSBarry Smith } 311973a71a0fSBarry Smith 3120ca15aa20SStefano Zampini /* vals is not const */ 3121d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A, PetscInt col, PetscScalar **vals) 3122d71ae5a4SJacob Faibussowitsch { 312386aefd0dSHong Zhang Mat_SeqDense *a = (Mat_SeqDense *)A->data; 3124ca15aa20SStefano Zampini PetscScalar *v; 312586aefd0dSHong Zhang 312686aefd0dSHong Zhang PetscFunctionBegin; 312728b400f6SJacob Faibussowitsch PetscCheck(!A->factortype, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Not for factored matrix"); 31289566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, &v)); 3129ca15aa20SStefano Zampini *vals = v + col * a->lda; 31309566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, &v)); 31313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 313286aefd0dSHong Zhang } 313386aefd0dSHong Zhang 3134d71ae5a4SJacob Faibussowitsch static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A, PetscScalar **vals) 3135d71ae5a4SJacob Faibussowitsch { 313686aefd0dSHong Zhang PetscFunctionBegin; 3137742765d3SMatthew Knepley if (vals) *vals = NULL; /* user cannot accidentally use the array later */ 31383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 313986aefd0dSHong Zhang } 3140abc3b08eSStefano Zampini 3141289bc588SBarry Smith /* -------------------------------------------------------------------*/ 3142a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = {MatSetValues_SeqDense, 3143905e6a2fSBarry Smith MatGetRow_SeqDense, 3144905e6a2fSBarry Smith MatRestoreRow_SeqDense, 3145905e6a2fSBarry Smith MatMult_SeqDense, 314697304618SKris Buschelman /* 4*/ MatMultAdd_SeqDense, 31477c922b88SBarry Smith MatMultTranspose_SeqDense, 31487c922b88SBarry Smith MatMultTransposeAdd_SeqDense, 3149f4259b30SLisandro Dalcin NULL, 3150f4259b30SLisandro Dalcin NULL, 3151f4259b30SLisandro Dalcin NULL, 3152f4259b30SLisandro Dalcin /* 10*/ NULL, 3153905e6a2fSBarry Smith MatLUFactor_SeqDense, 3154905e6a2fSBarry Smith MatCholeskyFactor_SeqDense, 315541f059aeSBarry Smith MatSOR_SeqDense, 3156ec8511deSBarry Smith MatTranspose_SeqDense, 315797304618SKris Buschelman /* 15*/ MatGetInfo_SeqDense, 3158905e6a2fSBarry Smith MatEqual_SeqDense, 3159905e6a2fSBarry Smith MatGetDiagonal_SeqDense, 3160905e6a2fSBarry Smith MatDiagonalScale_SeqDense, 3161905e6a2fSBarry Smith MatNorm_SeqDense, 3162c0aa2d19SHong Zhang /* 20*/ MatAssemblyBegin_SeqDense, 3163c0aa2d19SHong Zhang MatAssemblyEnd_SeqDense, 3164905e6a2fSBarry Smith MatSetOption_SeqDense, 3165905e6a2fSBarry Smith MatZeroEntries_SeqDense, 3166d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqDense, 3167f4259b30SLisandro Dalcin NULL, 3168f4259b30SLisandro Dalcin NULL, 3169f4259b30SLisandro Dalcin NULL, 3170f4259b30SLisandro Dalcin NULL, 31714994cf47SJed Brown /* 29*/ MatSetUp_SeqDense, 3172f4259b30SLisandro Dalcin NULL, 3173f4259b30SLisandro Dalcin NULL, 3174f4259b30SLisandro Dalcin NULL, 3175f4259b30SLisandro Dalcin NULL, 3176d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqDense, 3177f4259b30SLisandro Dalcin NULL, 3178f4259b30SLisandro Dalcin NULL, 3179f4259b30SLisandro Dalcin NULL, 3180f4259b30SLisandro Dalcin NULL, 3181d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqDense, 31827dae84e0SHong Zhang MatCreateSubMatrices_SeqDense, 3183f4259b30SLisandro Dalcin NULL, 31844b0e389bSBarry Smith MatGetValues_SeqDense, 3185a5ae1ecdSBarry Smith MatCopy_SeqDense, 3186d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqDense, 3187a5ae1ecdSBarry Smith MatScale_SeqDense, 31882f605a99SJose E. Roman MatShift_SeqDense, 3189f4259b30SLisandro Dalcin NULL, 31903f49a652SStefano Zampini MatZeroRowsColumns_SeqDense, 319173a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqDense, 3192f4259b30SLisandro Dalcin NULL, 3193f4259b30SLisandro Dalcin NULL, 3194f4259b30SLisandro Dalcin NULL, 3195f4259b30SLisandro Dalcin NULL, 3196f4259b30SLisandro Dalcin /* 54*/ NULL, 3197f4259b30SLisandro Dalcin NULL, 3198f4259b30SLisandro Dalcin NULL, 3199f4259b30SLisandro Dalcin NULL, 3200f4259b30SLisandro Dalcin NULL, 3201023c16fcSToby Isaac /* 59*/ MatCreateSubMatrix_SeqDense, 3202e03a110bSBarry Smith MatDestroy_SeqDense, 3203e03a110bSBarry Smith MatView_SeqDense, 3204f4259b30SLisandro Dalcin NULL, 3205f4259b30SLisandro Dalcin NULL, 3206f4259b30SLisandro Dalcin /* 64*/ NULL, 3207f4259b30SLisandro Dalcin NULL, 3208f4259b30SLisandro Dalcin NULL, 3209f4259b30SLisandro Dalcin NULL, 3210f4259b30SLisandro Dalcin NULL, 3211d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqDense, 3212f4259b30SLisandro Dalcin NULL, 3213f4259b30SLisandro Dalcin NULL, 3214f4259b30SLisandro Dalcin NULL, 3215f4259b30SLisandro Dalcin NULL, 3216f4259b30SLisandro Dalcin /* 74*/ NULL, 3217f4259b30SLisandro Dalcin NULL, 3218f4259b30SLisandro Dalcin NULL, 3219f4259b30SLisandro Dalcin NULL, 3220f4259b30SLisandro Dalcin NULL, 3221f4259b30SLisandro Dalcin /* 79*/ NULL, 3222f4259b30SLisandro Dalcin NULL, 3223f4259b30SLisandro Dalcin NULL, 3224f4259b30SLisandro Dalcin NULL, 32255bba2384SShri Abhyankar /* 83*/ MatLoad_SeqDense, 3226637a0070SStefano Zampini MatIsSymmetric_SeqDense, 32271cbb95d3SBarry Smith MatIsHermitian_SeqDense, 3228f4259b30SLisandro Dalcin NULL, 3229f4259b30SLisandro Dalcin NULL, 3230f4259b30SLisandro Dalcin NULL, 3231f4259b30SLisandro Dalcin /* 89*/ NULL, 3232f4259b30SLisandro Dalcin NULL, 3233a9fe9ddaSSatish Balay MatMatMultNumeric_SeqDense_SeqDense, 3234f4259b30SLisandro Dalcin NULL, 3235f4259b30SLisandro Dalcin NULL, 3236f4259b30SLisandro Dalcin /* 94*/ NULL, 3237f4259b30SLisandro Dalcin NULL, 3238f4259b30SLisandro Dalcin NULL, 323969f65d41SStefano Zampini MatMatTransposeMultNumeric_SeqDense_SeqDense, 3240f4259b30SLisandro Dalcin NULL, 32414222ddf1SHong Zhang /* 99*/ MatProductSetFromOptions_SeqDense, 3242f4259b30SLisandro Dalcin NULL, 3243f4259b30SLisandro Dalcin NULL, 3244ba337c44SJed Brown MatConjugate_SeqDense, 3245f4259b30SLisandro Dalcin NULL, 3246f4259b30SLisandro Dalcin /*104*/ NULL, 3247ba337c44SJed Brown MatRealPart_SeqDense, 3248ba337c44SJed Brown MatImaginaryPart_SeqDense, 3249f4259b30SLisandro Dalcin NULL, 3250f4259b30SLisandro Dalcin NULL, 3251f4259b30SLisandro Dalcin /*109*/ NULL, 3252f4259b30SLisandro Dalcin NULL, 32538d0534beSBarry Smith MatGetRowMin_SeqDense, 3254aabbc4fbSShri Abhyankar MatGetColumnVector_SeqDense, 32553b49f96aSBarry Smith MatMissingDiagonal_SeqDense, 3256f4259b30SLisandro Dalcin /*114*/ NULL, 3257f4259b30SLisandro Dalcin NULL, 3258f4259b30SLisandro Dalcin NULL, 3259f4259b30SLisandro Dalcin NULL, 3260f4259b30SLisandro Dalcin NULL, 3261f4259b30SLisandro Dalcin /*119*/ NULL, 3262f4259b30SLisandro Dalcin NULL, 3263f4259b30SLisandro Dalcin NULL, 3264f4259b30SLisandro Dalcin NULL, 3265f4259b30SLisandro Dalcin NULL, 3266f4259b30SLisandro Dalcin /*124*/ NULL, 3267a873a8cdSSam Reynolds MatGetColumnReductions_SeqDense, 3268f4259b30SLisandro Dalcin NULL, 3269f4259b30SLisandro Dalcin NULL, 3270f4259b30SLisandro Dalcin NULL, 3271f4259b30SLisandro Dalcin /*129*/ NULL, 3272f4259b30SLisandro Dalcin NULL, 3273f4259b30SLisandro Dalcin NULL, 327475648e8dSHong Zhang MatTransposeMatMultNumeric_SeqDense_SeqDense, 3275f4259b30SLisandro Dalcin NULL, 3276f4259b30SLisandro Dalcin /*134*/ NULL, 3277f4259b30SLisandro Dalcin NULL, 3278f4259b30SLisandro Dalcin NULL, 3279f4259b30SLisandro Dalcin NULL, 3280f4259b30SLisandro Dalcin NULL, 3281f4259b30SLisandro Dalcin /*139*/ NULL, 3282f4259b30SLisandro Dalcin NULL, 3283f4259b30SLisandro Dalcin NULL, 3284f4259b30SLisandro Dalcin NULL, 3285f4259b30SLisandro Dalcin NULL, 32864222ddf1SHong Zhang MatCreateMPIMatConcatenateSeqMat_SeqDense, 3287f4259b30SLisandro Dalcin /*145*/ NULL, 3288f4259b30SLisandro Dalcin NULL, 328999a7f59eSMark Adams NULL, 329099a7f59eSMark Adams NULL, 32917fb60732SBarry Smith NULL, 3292dec0b466SHong Zhang /*150*/ NULL, 3293dec0b466SHong Zhang NULL}; 329490ace30eSBarry Smith 32954b828684SBarry Smith /*@C 329611a5261eSBarry Smith MatCreateSeqDense - Creates a `MATSEQDENSE` that 3297d65003e9SLois Curfman McInnes is stored in column major order (the usual Fortran 77 manner). Many 3298d65003e9SLois Curfman McInnes of the matrix operations use the BLAS and LAPACK routines. 3299289bc588SBarry Smith 3300d083f849SBarry Smith Collective 3301db81eaa0SLois Curfman McInnes 330220563c6bSBarry Smith Input Parameters: 330311a5261eSBarry Smith + comm - MPI communicator, set to `PETSC_COMM_SELF` 33040c775827SLois Curfman McInnes . m - number of rows 330518f449edSLois Curfman McInnes . n - number of columns 33060298fd71SBarry Smith - data - optional location of matrix data in column major order. Set data=NULL for PETSc 3307dfc5480cSLois Curfman McInnes to control all matrix memory allocation. 330820563c6bSBarry Smith 330920563c6bSBarry Smith Output Parameter: 331044cd7ae7SLois Curfman McInnes . A - the matrix 331120563c6bSBarry Smith 331211a5261eSBarry Smith Note: 331318f449edSLois Curfman McInnes The data input variable is intended primarily for Fortran programmers 331418f449edSLois Curfman McInnes who wish to allocate their own matrix memory space. Most users should 33150298fd71SBarry Smith set data=NULL. 331618f449edSLois Curfman McInnes 3317027ccd11SLois Curfman McInnes Level: intermediate 3318027ccd11SLois Curfman McInnes 331911a5261eSBarry Smith .seealso: `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()` 332020563c6bSBarry Smith @*/ 3321d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateSeqDense(MPI_Comm comm, PetscInt m, PetscInt n, PetscScalar *data, Mat *A) 3322d71ae5a4SJacob Faibussowitsch { 33233a40ed3dSBarry Smith PetscFunctionBegin; 33249566063dSJacob Faibussowitsch PetscCall(MatCreate(comm, A)); 33259566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*A, m, n, m, n)); 33269566063dSJacob Faibussowitsch PetscCall(MatSetType(*A, MATSEQDENSE)); 33279566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(*A, data)); 33283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3329273d9f13SBarry Smith } 3330273d9f13SBarry Smith 3331273d9f13SBarry Smith /*@C 333211a5261eSBarry Smith MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements of a `MATSEQDENSE` matrix 3333273d9f13SBarry Smith 3334d083f849SBarry Smith Collective 3335273d9f13SBarry Smith 3336273d9f13SBarry Smith Input Parameters: 33371c4f3114SJed Brown + B - the matrix 33380298fd71SBarry Smith - data - the array (or NULL) 3339273d9f13SBarry Smith 334011a5261eSBarry Smith Note: 3341273d9f13SBarry Smith The data input variable is intended primarily for Fortran programmers 3342273d9f13SBarry Smith who wish to allocate their own matrix memory space. Most users should 3343284134d9SBarry Smith need not call this routine. 3344273d9f13SBarry Smith 3345273d9f13SBarry Smith Level: intermediate 3346273d9f13SBarry Smith 334711a5261eSBarry Smith .seealso: `MATSEQDENSE`, `MatCreate()`, `MatCreateDense()`, `MatSetValues()`, `MatDenseSetLDA()` 3348273d9f13SBarry Smith @*/ 3349d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation(Mat B, PetscScalar data[]) 3350d71ae5a4SJacob Faibussowitsch { 3351a23d5eceSKris Buschelman PetscFunctionBegin; 3352d5ea218eSStefano Zampini PetscValidHeaderSpecific(B, MAT_CLASSID, 1); 3353cac4c232SBarry Smith PetscTryMethod(B, "MatSeqDenseSetPreallocation_C", (Mat, PetscScalar[]), (B, data)); 33543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3355a23d5eceSKris Buschelman } 3356a23d5eceSKris Buschelman 3357d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseSetPreallocation_SeqDense(Mat B, PetscScalar *data) 3358d71ae5a4SJacob Faibussowitsch { 3359ad16ce7aSStefano Zampini Mat_SeqDense *b = (Mat_SeqDense *)B->data; 3360273d9f13SBarry Smith 3361273d9f13SBarry Smith PetscFunctionBegin; 336228b400f6SJacob Faibussowitsch PetscCheck(!b->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3363273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 3364a868139aSShri Abhyankar 33659566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(B->rmap)); 33669566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(B->cmap)); 336734ef9618SShri Abhyankar 3368ad16ce7aSStefano Zampini if (b->lda <= 0) b->lda = B->rmap->n; 336986d161a7SShri Abhyankar 33709e8f95c4SLisandro Dalcin if (!data) { /* petsc-allocated storage */ 33719566063dSJacob Faibussowitsch if (!b->user_alloc) PetscCall(PetscFree(b->v)); 33729566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((size_t)b->lda * B->cmap->n, &b->v)); 33732205254eSKarl Rupp 33749e8f95c4SLisandro Dalcin b->user_alloc = PETSC_FALSE; 3375273d9f13SBarry Smith } else { /* user-allocated storage */ 33769566063dSJacob Faibussowitsch if (!b->user_alloc) PetscCall(PetscFree(b->v)); 3377273d9f13SBarry Smith b->v = data; 3378273d9f13SBarry Smith b->user_alloc = PETSC_TRUE; 3379273d9f13SBarry Smith } 33800450473dSBarry Smith B->assembled = PETSC_TRUE; 33813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3382273d9f13SBarry Smith } 3383273d9f13SBarry Smith 338465b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 3385d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype, MatReuse reuse, Mat *newmat) 3386d71ae5a4SJacob Faibussowitsch { 3387d77f618aSHong Zhang Mat mat_elemental; 33881683a169SBarry Smith const PetscScalar *array; 33891683a169SBarry Smith PetscScalar *v_colwise; 3390d77f618aSHong Zhang PetscInt M = A->rmap->N, N = A->cmap->N, i, j, k, *rows, *cols; 3391d77f618aSHong Zhang 33928baccfbdSHong Zhang PetscFunctionBegin; 33939566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(M * N, &v_colwise, M, &rows, N, &cols)); 33949566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &array)); 3395d77f618aSHong Zhang /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */ 3396d77f618aSHong Zhang k = 0; 3397d77f618aSHong Zhang for (j = 0; j < N; j++) { 3398d77f618aSHong Zhang cols[j] = j; 3399ad540459SPierre Jolivet for (i = 0; i < M; i++) v_colwise[j * M + i] = array[k++]; 3400d77f618aSHong Zhang } 3401ad540459SPierre Jolivet for (i = 0; i < M; i++) rows[i] = i; 34029566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &array)); 3403d77f618aSHong Zhang 34049566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental)); 34059566063dSJacob Faibussowitsch PetscCall(MatSetSizes(mat_elemental, PETSC_DECIDE, PETSC_DECIDE, M, N)); 34069566063dSJacob Faibussowitsch PetscCall(MatSetType(mat_elemental, MATELEMENTAL)); 34079566063dSJacob Faibussowitsch PetscCall(MatSetUp(mat_elemental)); 3408d77f618aSHong Zhang 3409d77f618aSHong Zhang /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */ 34109566063dSJacob Faibussowitsch PetscCall(MatSetValues(mat_elemental, M, rows, N, cols, v_colwise, ADD_VALUES)); 34119566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY)); 34129566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY)); 34139566063dSJacob Faibussowitsch PetscCall(PetscFree3(v_colwise, rows, cols)); 3414d77f618aSHong Zhang 3415511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 34169566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A, &mat_elemental)); 3417d77f618aSHong Zhang } else { 3418d77f618aSHong Zhang *newmat = mat_elemental; 3419d77f618aSHong Zhang } 34203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34218baccfbdSHong Zhang } 342265b80a83SHong Zhang #endif 34238baccfbdSHong Zhang 3424d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseSetLDA_SeqDense(Mat B, PetscInt lda) 3425d71ae5a4SJacob Faibussowitsch { 34261b807ce4Svictorle Mat_SeqDense *b = (Mat_SeqDense *)B->data; 34277422da62SJose E. Roman PetscBool data; 342821a2c019SBarry Smith 34291b807ce4Svictorle PetscFunctionBegin; 34307422da62SJose E. Roman data = (PetscBool)((B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE); 3431aed4548fSBarry Smith PetscCheck(b->user_alloc || !data || b->lda == lda, PETSC_COMM_SELF, PETSC_ERR_ORDER, "LDA cannot be changed after allocation of internal storage"); 343208401ef6SPierre 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); 34331b807ce4Svictorle b->lda = lda; 34343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34351b807ce4Svictorle } 34361b807ce4Svictorle 3437d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm, Mat inmat, PetscInt n, MatReuse scall, Mat *outmat) 3438d71ae5a4SJacob Faibussowitsch { 3439d528f656SJakub Kruzik PetscFunctionBegin; 34409566063dSJacob Faibussowitsch PetscCall(MatCreateMPIMatConcatenateSeqMat_MPIDense(comm, inmat, n, scall, outmat)); 34413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3442d528f656SJakub Kruzik } 3443d528f656SJakub Kruzik 3444d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A, PetscInt col, Vec *v) 3445d71ae5a4SJacob Faibussowitsch { 34466947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34476947451fSStefano Zampini 34486947451fSStefano Zampini PetscFunctionBegin; 344928b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 345028b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 34514dfa11a4SJacob Faibussowitsch if (!a->cvec) { PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec)); } 34526947451fSStefano Zampini a->vecinuse = col + 1; 34539566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A, (PetscScalar **)&a->ptrinuse)); 34549566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda)); 34556947451fSStefano Zampini *v = a->cvec; 34563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34576947451fSStefano Zampini } 34586947451fSStefano Zampini 3459d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A, PetscInt col, Vec *v) 3460d71ae5a4SJacob Faibussowitsch { 34616947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34626947451fSStefano Zampini 34636947451fSStefano Zampini PetscFunctionBegin; 346428b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 346528b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 34666947451fSStefano Zampini a->vecinuse = 0; 34679566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A, (PetscScalar **)&a->ptrinuse)); 34689566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 346975f6d85dSStefano Zampini if (v) *v = NULL; 34703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34716947451fSStefano Zampini } 34726947451fSStefano Zampini 3473d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v) 3474d71ae5a4SJacob Faibussowitsch { 34756947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34766947451fSStefano Zampini 34776947451fSStefano Zampini PetscFunctionBegin; 347828b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 347928b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 34804dfa11a4SJacob Faibussowitsch if (!a->cvec) { PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec)); } 34816947451fSStefano Zampini a->vecinuse = col + 1; 34829566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A, &a->ptrinuse)); 34839566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda)); 34849566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(a->cvec)); 34856947451fSStefano Zampini *v = a->cvec; 34863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 34876947451fSStefano Zampini } 34886947451fSStefano Zampini 3489d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A, PetscInt col, Vec *v) 3490d71ae5a4SJacob Faibussowitsch { 34916947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 34926947451fSStefano Zampini 34936947451fSStefano Zampini PetscFunctionBegin; 349428b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 349528b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 34966947451fSStefano Zampini a->vecinuse = 0; 34979566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A, &a->ptrinuse)); 34989566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(a->cvec)); 34999566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 350075f6d85dSStefano Zampini if (v) *v = NULL; 35013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35026947451fSStefano Zampini } 35036947451fSStefano Zampini 3504d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v) 3505d71ae5a4SJacob Faibussowitsch { 35066947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35076947451fSStefano Zampini 35086947451fSStefano Zampini PetscFunctionBegin; 350928b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 351028b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 35114dfa11a4SJacob Faibussowitsch if (!a->cvec) { PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A), A->rmap->bs, A->rmap->n, NULL, &a->cvec)); } 35126947451fSStefano Zampini a->vecinuse = col + 1; 35139566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(A, (PetscScalar **)&a->ptrinuse)); 35149566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(a->cvec, a->ptrinuse + (size_t)col * (size_t)a->lda)); 35156947451fSStefano Zampini *v = a->cvec; 35163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35176947451fSStefano Zampini } 35186947451fSStefano Zampini 3519d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A, PetscInt col, Vec *v) 3520d71ae5a4SJacob Faibussowitsch { 35216947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35226947451fSStefano Zampini 35236947451fSStefano Zampini PetscFunctionBegin; 352428b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetColumnVec() first"); 352528b400f6SJacob Faibussowitsch PetscCheck(a->cvec, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column vector"); 35266947451fSStefano Zampini a->vecinuse = 0; 35279566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(A, (PetscScalar **)&a->ptrinuse)); 35289566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 352975f6d85dSStefano Zampini if (v) *v = NULL; 35303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35316947451fSStefano Zampini } 35326947451fSStefano Zampini 3533d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) 3534d71ae5a4SJacob Faibussowitsch { 35355ea7661aSPierre Jolivet Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35365ea7661aSPierre Jolivet 35375ea7661aSPierre Jolivet PetscFunctionBegin; 353828b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreColumnVec() first"); 353928b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseRestoreSubMatrix() first"); 3540a2748737SPierre Jolivet if (a->cmat && (cend - cbegin != a->cmat->cmap->N || rend - rbegin != a->cmat->rmap->N)) PetscCall(MatDestroy(&a->cmat)); 35415ea7661aSPierre Jolivet if (!a->cmat) { 3542a2748737SPierre Jolivet PetscCall(MatCreateDense(PetscObjectComm((PetscObject)A), rend - rbegin, PETSC_DECIDE, rend - rbegin, cend - cbegin, a->v + rbegin + (size_t)cbegin * a->lda, &a->cmat)); 35435ea7661aSPierre Jolivet } else { 3544a2748737SPierre Jolivet PetscCall(MatDensePlaceArray(a->cmat, a->v + rbegin + (size_t)cbegin * a->lda)); 35455ea7661aSPierre Jolivet } 35469566063dSJacob Faibussowitsch PetscCall(MatDenseSetLDA(a->cmat, a->lda)); 35475ea7661aSPierre Jolivet a->matinuse = cbegin + 1; 35485ea7661aSPierre Jolivet *v = a->cmat; 354947d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 355075f6d85dSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 355175f6d85dSStefano Zampini #endif 35523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35535ea7661aSPierre Jolivet } 35545ea7661aSPierre Jolivet 3555d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A, Mat *v) 3556d71ae5a4SJacob Faibussowitsch { 35575ea7661aSPierre Jolivet Mat_SeqDense *a = (Mat_SeqDense *)A->data; 35585ea7661aSPierre Jolivet 35595ea7661aSPierre Jolivet PetscFunctionBegin; 356028b400f6SJacob Faibussowitsch PetscCheck(a->matinuse, PETSC_COMM_SELF, PETSC_ERR_ORDER, "Need to call MatDenseGetSubMatrix() first"); 356128b400f6SJacob Faibussowitsch PetscCheck(a->cmat, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing internal column matrix"); 356208401ef6SPierre Jolivet PetscCheck(*v == a->cmat, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Not the matrix obtained from MatDenseGetSubMatrix()"); 35635ea7661aSPierre Jolivet a->matinuse = 0; 35649566063dSJacob Faibussowitsch PetscCall(MatDenseResetArray(a->cmat)); 3565742765d3SMatthew Knepley if (v) *v = NULL; 356647d993e7Ssuyashtn #if defined(PETSC_HAVE_CUDA) || defined(PETSC_HAVE_HIP) 35673faff063SStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 35683faff063SStefano Zampini #endif 35693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 35705ea7661aSPierre Jolivet } 35715ea7661aSPierre Jolivet 35720bad9183SKris Buschelman /*MC 3573fafad747SKris Buschelman MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices. 35740bad9183SKris Buschelman 35750bad9183SKris Buschelman Options Database Keys: 357611a5261eSBarry Smith . -mat_type seqdense - sets the matrix type to `MATSEQDENSE` during a call to `MatSetFromOptions()` 35770bad9183SKris Buschelman 35780bad9183SKris Buschelman Level: beginner 35790bad9183SKris Buschelman 358011a5261eSBarry Smith .seealso: `MATSEQDENSE`, `MatCreateSeqDense()` 35810bad9183SKris Buschelman M*/ 3582d71ae5a4SJacob Faibussowitsch PetscErrorCode MatCreate_SeqDense(Mat B) 3583d71ae5a4SJacob Faibussowitsch { 3584273d9f13SBarry Smith Mat_SeqDense *b; 35857c334f02SBarry Smith PetscMPIInt size; 3586273d9f13SBarry Smith 3587273d9f13SBarry Smith PetscFunctionBegin; 35889566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)B), &size)); 358908401ef6SPierre Jolivet PetscCheck(size <= 1, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Comm must be of size 1"); 359055659b69SBarry Smith 35914dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&b)); 35929566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(B->ops, &MatOps_Values, sizeof(struct _MatOps))); 359344cd7ae7SLois Curfman McInnes B->data = (void *)b; 359418f449edSLois Curfman McInnes 3595273d9f13SBarry Smith b->roworiented = PETSC_TRUE; 35964e220ebcSLois Curfman McInnes 35979566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatQRFactor_C", MatQRFactor_SeqDense)); 35989566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetLDA_C", MatDenseGetLDA_SeqDense)); 35999566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseSetLDA_C", MatDenseSetLDA_SeqDense)); 36009566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArray_C", MatDenseGetArray_SeqDense)); 36019566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArray_C", MatDenseRestoreArray_SeqDense)); 36029566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDensePlaceArray_C", MatDensePlaceArray_SeqDense)); 36039566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseResetArray_C", MatDenseResetArray_SeqDense)); 36049566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseReplaceArray_C", MatDenseReplaceArray_SeqDense)); 36059566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayRead_C", MatDenseGetArray_SeqDense)); 36069566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayRead_C", MatDenseRestoreArray_SeqDense)); 36079566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetArrayWrite_C", MatDenseGetArray_SeqDense)); 36089566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreArrayWrite_C", MatDenseRestoreArray_SeqDense)); 36099566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqaij_C", MatConvert_SeqDense_SeqAIJ)); 36108baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 36119566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_elemental_C", MatConvert_SeqDense_Elemental)); 36128baccfbdSHong Zhang #endif 3613d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 36149566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_scalapack_C", MatConvert_Dense_ScaLAPACK)); 3615d24d4204SJose E. Roman #endif 36162bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA) 36179566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensecuda_C", MatConvert_SeqDense_SeqDenseCUDA)); 36189566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdensecuda_C", MatProductSetFromOptions_SeqDense)); 36199566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensecuda_seqdense_C", MatProductSetFromOptions_SeqDense)); 36209566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensecuda_C", MatProductSetFromOptions_SeqDense)); 36212bf066beSStefano Zampini #endif 362247d993e7Ssuyashtn #if defined(PETSC_HAVE_HIP) 362347d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatConvert_seqdense_seqdensehip_C", MatConvert_SeqDense_SeqDenseHIP)); 362447d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensehip_seqdensehip_C", MatProductSetFromOptions_SeqDense)); 362547d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdensehip_seqdense_C", MatProductSetFromOptions_SeqDense)); 362647d993e7Ssuyashtn PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdensehip_C", MatProductSetFromOptions_SeqDense)); 362747d993e7Ssuyashtn #endif 36289566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatSeqDenseSetPreallocation_C", MatSeqDenseSetPreallocation_SeqDense)); 36299566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqaij_seqdense_C", MatProductSetFromOptions_SeqAIJ_SeqDense)); 36309566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqdense_seqdense_C", MatProductSetFromOptions_SeqDense)); 36319566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense)); 36329566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatProductSetFromOptions_seqsbaij_seqdense_C", MatProductSetFromOptions_SeqXBAIJ_SeqDense)); 363396e6d5c4SRichard Tran Mills 36349566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumn_C", MatDenseGetColumn_SeqDense)); 36359566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumn_C", MatDenseRestoreColumn_SeqDense)); 36369566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVec_C", MatDenseGetColumnVec_SeqDense)); 36379566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVec_C", MatDenseRestoreColumnVec_SeqDense)); 36389566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecRead_C", MatDenseGetColumnVecRead_SeqDense)); 36399566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecRead_C", MatDenseRestoreColumnVecRead_SeqDense)); 36409566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetColumnVecWrite_C", MatDenseGetColumnVecWrite_SeqDense)); 36419566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreColumnVecWrite_C", MatDenseRestoreColumnVecWrite_SeqDense)); 36429566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseGetSubMatrix_C", MatDenseGetSubMatrix_SeqDense)); 36439566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B, "MatDenseRestoreSubMatrix_C", MatDenseRestoreSubMatrix_SeqDense)); 36449566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)B, MATSEQDENSE)); 36453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3646289bc588SBarry Smith } 364786aefd0dSHong Zhang 364886aefd0dSHong Zhang /*@C 364911a5261eSBarry 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. 365086aefd0dSHong Zhang 365186aefd0dSHong Zhang Not Collective 365286aefd0dSHong Zhang 36535ea7661aSPierre Jolivet Input Parameters: 365411a5261eSBarry Smith + mat - a `MATSEQDENSE` or `MATMPIDENSE` matrix 365586aefd0dSHong Zhang - col - column index 365686aefd0dSHong Zhang 365786aefd0dSHong Zhang Output Parameter: 365886aefd0dSHong Zhang . vals - pointer to the data 365986aefd0dSHong Zhang 366086aefd0dSHong Zhang Level: intermediate 366186aefd0dSHong Zhang 366211a5261eSBarry Smith Note: 366311a5261eSBarry Smith Use `MatDenseGetColumnVec()` to get access to a column of a `MATDENSE` treated as a `Vec` 366411a5261eSBarry Smith 366511a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseRestoreColumn()`, `MatDenseGetColumnVec()` 366686aefd0dSHong Zhang @*/ 3667d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumn(Mat A, PetscInt col, PetscScalar **vals) 3668d71ae5a4SJacob Faibussowitsch { 366986aefd0dSHong Zhang PetscFunctionBegin; 3670d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3671d5ea218eSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 3672d5ea218eSStefano Zampini PetscValidPointer(vals, 3); 3673cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumn_C", (Mat, PetscInt, PetscScalar **), (A, col, vals)); 36743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 367586aefd0dSHong Zhang } 367686aefd0dSHong Zhang 367786aefd0dSHong Zhang /*@C 367811a5261eSBarry Smith MatDenseRestoreColumn - returns access to a column of a `MATDENSE` matrix which is returned by `MatDenseGetColumn()`. 367986aefd0dSHong Zhang 368086aefd0dSHong Zhang Not Collective 368186aefd0dSHong Zhang 3682742765d3SMatthew Knepley Input Parameters: 368311a5261eSBarry Smith + mat - a `MATSEQDENSE` or `MATMPIDENSE` matrix 3684742765d3SMatthew Knepley - vals - pointer to the data (may be NULL) 368586aefd0dSHong Zhang 368686aefd0dSHong Zhang Level: intermediate 368786aefd0dSHong Zhang 368811a5261eSBarry Smith .seealso: `MATDENSE`, `MatDenseGetColumn()` 368986aefd0dSHong Zhang @*/ 3690d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumn(Mat A, PetscScalar **vals) 3691d71ae5a4SJacob Faibussowitsch { 369286aefd0dSHong Zhang PetscFunctionBegin; 3693d5ea218eSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 3694d5ea218eSStefano Zampini PetscValidPointer(vals, 2); 3695cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumn_C", (Mat, PetscScalar **), (A, vals)); 36963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 369786aefd0dSHong Zhang } 36986947451fSStefano Zampini 36990f74d2c1SSatish Balay /*@ 370011a5261eSBarry Smith MatDenseGetColumnVec - Gives read-write access to a column of a `MATDENSE` matrix, represented as a `Vec`. 37016947451fSStefano Zampini 37026947451fSStefano Zampini Collective 37036947451fSStefano Zampini 37045ea7661aSPierre Jolivet Input Parameters: 370511a5261eSBarry Smith + mat - the `Mat` object 37066947451fSStefano Zampini - col - the column index 37076947451fSStefano Zampini 37086947451fSStefano Zampini Output Parameter: 37096947451fSStefano Zampini . v - the vector 37106947451fSStefano Zampini 37116947451fSStefano Zampini Notes: 371211a5261eSBarry Smith The vector is owned by PETSc. Users need to call `MatDenseRestoreColumnVec()` when the vector is no longer needed. 371311a5261eSBarry Smith 371411a5261eSBarry Smith Use `MatDenseGetColumnVecRead()` to obtain read-only access or `MatDenseGetColumnVecWrite()` for write-only access. 37156947451fSStefano Zampini 37166947451fSStefano Zampini Level: intermediate 37176947451fSStefano Zampini 371847d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`, `MatDenseGetColumn()` 37196947451fSStefano Zampini @*/ 3720d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVec(Mat A, PetscInt col, Vec *v) 3721d71ae5a4SJacob Faibussowitsch { 37226947451fSStefano Zampini PetscFunctionBegin; 37236947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 37246947451fSStefano Zampini PetscValidType(A, 1); 37256947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 37266947451fSStefano Zampini PetscValidPointer(v, 3); 372728b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 37282cf15c64SPierre 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); 3729cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v)); 37303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37316947451fSStefano Zampini } 37326947451fSStefano Zampini 37330f74d2c1SSatish Balay /*@ 37346947451fSStefano Zampini MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVec(). 37356947451fSStefano Zampini 37366947451fSStefano Zampini Collective 37376947451fSStefano Zampini 37385ea7661aSPierre Jolivet Input Parameters: 37396947451fSStefano Zampini + mat - the Mat object 37406947451fSStefano Zampini . col - the column index 3741742765d3SMatthew Knepley - v - the Vec object (may be NULL) 37426947451fSStefano Zampini 37436947451fSStefano Zampini Level: intermediate 37446947451fSStefano Zampini 374547d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 37466947451fSStefano Zampini @*/ 3747d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVec(Mat A, PetscInt col, Vec *v) 3748d71ae5a4SJacob Faibussowitsch { 37496947451fSStefano Zampini PetscFunctionBegin; 37506947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 37516947451fSStefano Zampini PetscValidType(A, 1); 37526947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 375308401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 37542cf15c64SPierre 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); 3755cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVec_C", (Mat, PetscInt, Vec *), (A, col, v)); 37563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37576947451fSStefano Zampini } 37586947451fSStefano Zampini 37590f74d2c1SSatish Balay /*@ 37606947451fSStefano Zampini MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a Vec. 37616947451fSStefano Zampini 37626947451fSStefano Zampini Collective 37636947451fSStefano Zampini 37645ea7661aSPierre Jolivet Input Parameters: 37656947451fSStefano Zampini + mat - the Mat object 37666947451fSStefano Zampini - col - the column index 37676947451fSStefano Zampini 37686947451fSStefano Zampini Output Parameter: 37696947451fSStefano Zampini . v - the vector 37706947451fSStefano Zampini 37716947451fSStefano Zampini Notes: 37726947451fSStefano Zampini The vector is owned by PETSc and users cannot modify it. 377311a5261eSBarry Smith 37746947451fSStefano Zampini Users need to call MatDenseRestoreColumnVecRead() when the vector is no longer needed. 377511a5261eSBarry Smith 37766947451fSStefano Zampini Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecWrite() for write-only access. 37776947451fSStefano Zampini 37786947451fSStefano Zampini Level: intermediate 37796947451fSStefano Zampini 378047d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 37816947451fSStefano Zampini @*/ 3782d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecRead(Mat A, PetscInt col, Vec *v) 3783d71ae5a4SJacob Faibussowitsch { 37846947451fSStefano Zampini PetscFunctionBegin; 37856947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 37866947451fSStefano Zampini PetscValidType(A, 1); 37876947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 37886947451fSStefano Zampini PetscValidPointer(v, 3); 378928b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 37902cf15c64SPierre 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); 3791cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v)); 37923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37936947451fSStefano Zampini } 37946947451fSStefano Zampini 37950f74d2c1SSatish Balay /*@ 37966947451fSStefano Zampini MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecRead(). 37976947451fSStefano Zampini 37986947451fSStefano Zampini Collective 37996947451fSStefano Zampini 38005ea7661aSPierre Jolivet Input Parameters: 38016947451fSStefano Zampini + mat - the Mat object 38026947451fSStefano Zampini . col - the column index 3803742765d3SMatthew Knepley - v - the Vec object (may be NULL) 38046947451fSStefano Zampini 38056947451fSStefano Zampini Level: intermediate 38066947451fSStefano Zampini 380747d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecWrite()` 38086947451fSStefano Zampini @*/ 3809d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecRead(Mat A, PetscInt col, Vec *v) 3810d71ae5a4SJacob Faibussowitsch { 38116947451fSStefano Zampini PetscFunctionBegin; 38126947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38136947451fSStefano Zampini PetscValidType(A, 1); 38146947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 381508401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 38162cf15c64SPierre 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); 3817cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVecRead_C", (Mat, PetscInt, Vec *), (A, col, v)); 38183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38196947451fSStefano Zampini } 38206947451fSStefano Zampini 38210f74d2c1SSatish Balay /*@ 38226947451fSStefano Zampini MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a Vec. 38236947451fSStefano Zampini 38246947451fSStefano Zampini Collective 38256947451fSStefano Zampini 38265ea7661aSPierre Jolivet Input Parameters: 38276947451fSStefano Zampini + mat - the Mat object 38286947451fSStefano Zampini - col - the column index 38296947451fSStefano Zampini 38306947451fSStefano Zampini Output Parameter: 38316947451fSStefano Zampini . v - the vector 38326947451fSStefano Zampini 38336947451fSStefano Zampini Notes: 38346947451fSStefano Zampini The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVecWrite() when the vector is no longer needed. 383511a5261eSBarry Smith 38366947451fSStefano Zampini Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecRead() for read-only access. 38376947451fSStefano Zampini 38386947451fSStefano Zampini Level: intermediate 38396947451fSStefano Zampini 384047d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 38416947451fSStefano Zampini @*/ 3842d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetColumnVecWrite(Mat A, PetscInt col, Vec *v) 3843d71ae5a4SJacob Faibussowitsch { 38446947451fSStefano Zampini PetscFunctionBegin; 38456947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38466947451fSStefano Zampini PetscValidType(A, 1); 38476947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 38486947451fSStefano Zampini PetscValidPointer(v, 3); 384928b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3850aed4548fSBarry 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); 3851cac4c232SBarry Smith PetscUseMethod(A, "MatDenseGetColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v)); 38523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38536947451fSStefano Zampini } 38546947451fSStefano Zampini 38550f74d2c1SSatish Balay /*@ 38566947451fSStefano Zampini MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecWrite(). 38576947451fSStefano Zampini 38586947451fSStefano Zampini Collective 38596947451fSStefano Zampini 38605ea7661aSPierre Jolivet Input Parameters: 38616947451fSStefano Zampini + mat - the Mat object 38626947451fSStefano Zampini . col - the column index 3863742765d3SMatthew Knepley - v - the Vec object (may be NULL) 38646947451fSStefano Zampini 38656947451fSStefano Zampini Level: intermediate 38666947451fSStefano Zampini 386747d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()` 38686947451fSStefano Zampini @*/ 3869d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A, PetscInt col, Vec *v) 3870d71ae5a4SJacob Faibussowitsch { 38716947451fSStefano Zampini PetscFunctionBegin; 38726947451fSStefano Zampini PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 38736947451fSStefano Zampini PetscValidType(A, 1); 38746947451fSStefano Zampini PetscValidLogicalCollectiveInt(A, col, 2); 387508401ef6SPierre Jolivet PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3876aed4548fSBarry 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); 3877cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreColumnVecWrite_C", (Mat, PetscInt, Vec *), (A, col, v)); 38783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38796947451fSStefano Zampini } 38805ea7661aSPierre Jolivet 38810f74d2c1SSatish Balay /*@ 3882a2748737SPierre Jolivet MatDenseGetSubMatrix - Gives access to a block of rows and columns of a dense matrix, represented as a Mat. 38835ea7661aSPierre Jolivet 38845ea7661aSPierre Jolivet Collective 38855ea7661aSPierre Jolivet 38865ea7661aSPierre Jolivet Input Parameters: 38875ea7661aSPierre Jolivet + mat - the Mat object 3888a2748737SPierre Jolivet . rbegin - the first global row index in the block (if PETSC_DECIDE, is 0) 3889a2748737SPierre Jolivet . rend - the global row index past the last one in the block (if PETSC_DECIDE, is M) 3890a2748737SPierre Jolivet . cbegin - the first global column index in the block (if PETSC_DECIDE, is 0) 3891a2748737SPierre Jolivet - cend - the global column index past the last one in the block (if PETSC_DECIDE, is N) 38925ea7661aSPierre Jolivet 38935ea7661aSPierre Jolivet Output Parameter: 38945ea7661aSPierre Jolivet . v - the matrix 38955ea7661aSPierre Jolivet 38965ea7661aSPierre Jolivet Notes: 38975ea7661aSPierre Jolivet The matrix is owned by PETSc. Users need to call MatDenseRestoreSubMatrix() when the matrix is no longer needed. 389811a5261eSBarry Smith 3899a2748737SPierre 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. 39005ea7661aSPierre Jolivet 39015ea7661aSPierre Jolivet Level: intermediate 39025ea7661aSPierre Jolivet 390347d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreSubMatrix()` 39045ea7661aSPierre Jolivet @*/ 3905d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseGetSubMatrix(Mat A, PetscInt rbegin, PetscInt rend, PetscInt cbegin, PetscInt cend, Mat *v) 3906d71ae5a4SJacob Faibussowitsch { 39075ea7661aSPierre Jolivet PetscFunctionBegin; 39085ea7661aSPierre Jolivet PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 39095ea7661aSPierre Jolivet PetscValidType(A, 1); 3910a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, rbegin, 2); 3911a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, rend, 3); 3912a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, cbegin, 4); 3913a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A, cend, 5); 3914a2748737SPierre Jolivet PetscValidPointer(v, 6); 3915a2748737SPierre Jolivet if (rbegin == PETSC_DECIDE) rbegin = 0; 3916a2748737SPierre Jolivet if (rend == PETSC_DECIDE) rend = A->rmap->N; 3917a2748737SPierre Jolivet if (cbegin == PETSC_DECIDE) cbegin = 0; 3918a2748737SPierre Jolivet if (cend == PETSC_DECIDE) cend = A->cmap->N; 391928b400f6SJacob Faibussowitsch PetscCheck(A->preallocated, PetscObjectComm((PetscObject)A), PETSC_ERR_ORDER, "Matrix not preallocated"); 3920a2748737SPierre 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); 3921a2748737SPierre 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); 3922a2748737SPierre 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); 3923a2748737SPierre 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); 3924a2748737SPierre Jolivet PetscUseMethod(A, "MatDenseGetSubMatrix_C", (Mat, PetscInt, PetscInt, PetscInt, PetscInt, Mat *), (A, rbegin, rend, cbegin, cend, v)); 39253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 39265ea7661aSPierre Jolivet } 39275ea7661aSPierre Jolivet 39280f74d2c1SSatish Balay /*@ 39295ea7661aSPierre Jolivet MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from MatDenseGetSubMatrix(). 39305ea7661aSPierre Jolivet 39315ea7661aSPierre Jolivet Collective 39325ea7661aSPierre Jolivet 39335ea7661aSPierre Jolivet Input Parameters: 39345ea7661aSPierre Jolivet + mat - the Mat object 3935742765d3SMatthew Knepley - v - the Mat object (may be NULL) 39365ea7661aSPierre Jolivet 39375ea7661aSPierre Jolivet Level: intermediate 39385ea7661aSPierre Jolivet 393947d993e7Ssuyashtn .seealso: `MATDENSE`, `MATDENSECUDA`, `MATDENSEHIP`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseGetSubMatrix()` 39405ea7661aSPierre Jolivet @*/ 3941d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDenseRestoreSubMatrix(Mat A, Mat *v) 3942d71ae5a4SJacob Faibussowitsch { 39435ea7661aSPierre Jolivet PetscFunctionBegin; 39445ea7661aSPierre Jolivet PetscValidHeaderSpecific(A, MAT_CLASSID, 1); 39455ea7661aSPierre Jolivet PetscValidType(A, 1); 39465ea7661aSPierre Jolivet PetscValidPointer(v, 2); 3947cac4c232SBarry Smith PetscUseMethod(A, "MatDenseRestoreSubMatrix_C", (Mat, Mat *), (A, v)); 39483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 39495ea7661aSPierre Jolivet } 39508a9c020eSBarry Smith 39518a9c020eSBarry Smith #include <petscblaslapack.h> 39528a9c020eSBarry Smith #include <petsc/private/kernels/blockinvert.h> 39538a9c020eSBarry Smith 3954d71ae5a4SJacob Faibussowitsch PetscErrorCode MatSeqDenseInvert(Mat A) 3955d71ae5a4SJacob Faibussowitsch { 39568a9c020eSBarry Smith Mat_SeqDense *a = (Mat_SeqDense *)A->data; 39578a9c020eSBarry Smith PetscInt bs = A->rmap->n; 39588a9c020eSBarry Smith MatScalar *values = a->v; 39598a9c020eSBarry Smith const PetscReal shift = 0.0; 39608a9c020eSBarry Smith PetscBool allowzeropivot = PetscNot(A->erroriffailure), zeropivotdetected = PETSC_FALSE; 39618a9c020eSBarry Smith 39628a9c020eSBarry Smith PetscFunctionBegin; 39638a9c020eSBarry Smith /* factor and invert each block */ 39648a9c020eSBarry Smith switch (bs) { 3965d71ae5a4SJacob Faibussowitsch case 1: 3966d71ae5a4SJacob Faibussowitsch values[0] = (PetscScalar)1.0 / (values[0] + shift); 3967d71ae5a4SJacob Faibussowitsch break; 39688a9c020eSBarry Smith case 2: 39698a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_2(values, shift, allowzeropivot, &zeropivotdetected)); 39708a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39718a9c020eSBarry Smith break; 39728a9c020eSBarry Smith case 3: 39738a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_3(values, shift, allowzeropivot, &zeropivotdetected)); 39748a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39758a9c020eSBarry Smith break; 39768a9c020eSBarry Smith case 4: 39778a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_4(values, shift, allowzeropivot, &zeropivotdetected)); 39788a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39798a9c020eSBarry Smith break; 39809371c9d4SSatish Balay case 5: { 39818a9c020eSBarry Smith PetscScalar work[25]; 39828a9c020eSBarry Smith PetscInt ipvt[5]; 39838a9c020eSBarry Smith 39848a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_5(values, ipvt, work, shift, allowzeropivot, &zeropivotdetected)); 39858a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39869371c9d4SSatish Balay } break; 39878a9c020eSBarry Smith case 6: 39888a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_6(values, shift, allowzeropivot, &zeropivotdetected)); 39898a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39908a9c020eSBarry Smith break; 39918a9c020eSBarry Smith case 7: 39928a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_7(values, shift, allowzeropivot, &zeropivotdetected)); 39938a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 39948a9c020eSBarry Smith break; 39959371c9d4SSatish Balay default: { 39968a9c020eSBarry Smith PetscInt *v_pivots, *IJ, j; 39978a9c020eSBarry Smith PetscScalar *v_work; 39988a9c020eSBarry Smith 39998a9c020eSBarry Smith PetscCall(PetscMalloc3(bs, &v_work, bs, &v_pivots, bs, &IJ)); 4000ad540459SPierre Jolivet for (j = 0; j < bs; j++) IJ[j] = j; 40018a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A(bs, values, v_pivots, v_work, allowzeropivot, &zeropivotdetected)); 40028a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 40038a9c020eSBarry Smith PetscCall(PetscFree3(v_work, v_pivots, IJ)); 40048a9c020eSBarry Smith } 40058a9c020eSBarry Smith } 40063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 40078a9c020eSBarry Smith } 4008