1be1d678aSKris Buschelman 267e560aaSBarry Smith /* 367e560aaSBarry Smith Defines the basic matrix operations for sequential dense. 467e560aaSBarry Smith */ 5289bc588SBarry Smith 6dec5eb66SMatthew G Knepley #include <../src/mat/impls/dense/seq/dense.h> /*I "petscmat.h" I*/ 7c6db04a5SJed Brown #include <petscblaslapack.h> 8289bc588SBarry Smith 96a63e612SBarry Smith #include <../src/mat/impls/aij/seq/aij.h> 10b2573a8aSBarry Smith 11ca15aa20SStefano Zampini PetscErrorCode MatSeqDenseSymmetrize_Private(Mat A, PetscBool hermitian) 128c178816SStefano Zampini { 138c178816SStefano Zampini Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 148c178816SStefano Zampini PetscInt j, k, n = A->rmap->n; 15ca15aa20SStefano Zampini PetscScalar *v; 168c178816SStefano Zampini 178c178816SStefano Zampini PetscFunctionBegin; 1808401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Cannot symmetrize a rectangular matrix"); 199566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A,&v)); 208c178816SStefano Zampini if (!hermitian) { 218c178816SStefano Zampini for (k=0;k<n;k++) { 228c178816SStefano Zampini for (j=k;j<n;j++) { 23ca15aa20SStefano Zampini v[j*mat->lda + k] = v[k*mat->lda + j]; 248c178816SStefano Zampini } 258c178816SStefano Zampini } 268c178816SStefano Zampini } else { 278c178816SStefano Zampini for (k=0;k<n;k++) { 288c178816SStefano Zampini for (j=k;j<n;j++) { 29ca15aa20SStefano Zampini v[j*mat->lda + k] = PetscConj(v[k*mat->lda + j]); 308c178816SStefano Zampini } 318c178816SStefano Zampini } 328c178816SStefano Zampini } 339566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A,&v)); 348c178816SStefano Zampini PetscFunctionReturn(0); 358c178816SStefano Zampini } 368c178816SStefano Zampini 3705709791SSatish Balay PETSC_EXTERN PetscErrorCode MatSeqDenseInvertFactors_Private(Mat A) 388c178816SStefano Zampini { 398c178816SStefano Zampini Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 408c178816SStefano Zampini PetscBLASInt info,n; 418c178816SStefano Zampini 428c178816SStefano Zampini PetscFunctionBegin; 438c178816SStefano Zampini if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 449566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n,&n)); 458c178816SStefano Zampini if (A->factortype == MAT_FACTOR_LU) { 4628b400f6SJacob Faibussowitsch PetscCheck(mat->pivots,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present"); 478c178816SStefano Zampini if (!mat->fwork) { 488c178816SStefano Zampini mat->lfwork = n; 499566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork,&mat->fwork)); 509566063dSJacob Faibussowitsch PetscCall(PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt))); 518c178816SStefano Zampini } 529566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 538c178816SStefano Zampini PetscStackCallBLAS("LAPACKgetri",LAPACKgetri_(&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info)); 549566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 559566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0)); 568c178816SStefano Zampini } else if (A->factortype == MAT_FACTOR_CHOLESKY) { 578c178816SStefano Zampini if (A->spd) { 589566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 598c178816SStefano Zampini PetscStackCallBLAS("LAPACKpotri",LAPACKpotri_("L",&n,mat->v,&mat->lda,&info)); 609566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 619566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSymmetrize_Private(A,PETSC_TRUE)); 628c178816SStefano Zampini #if defined(PETSC_USE_COMPLEX) 638c178816SStefano Zampini } else if (A->hermitian) { 6428b400f6SJacob Faibussowitsch PetscCheck(mat->pivots,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present"); 6528b400f6SJacob Faibussowitsch PetscCheck(mat->fwork,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Fwork not present"); 669566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 678c178816SStefano Zampini PetscStackCallBLAS("LAPACKhetri",LAPACKhetri_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&info)); 689566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 699566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSymmetrize_Private(A,PETSC_TRUE)); 708c178816SStefano Zampini #endif 718c178816SStefano Zampini } else { /* symmetric case */ 7228b400f6SJacob Faibussowitsch PetscCheck(mat->pivots,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present"); 7328b400f6SJacob Faibussowitsch PetscCheck(mat->fwork,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Fwork not present"); 749566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 758c178816SStefano Zampini PetscStackCallBLAS("LAPACKsytri",LAPACKsytri_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&info)); 769566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 779566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSymmetrize_Private(A,PETSC_FALSE)); 788c178816SStefano Zampini } 7928b400f6SJacob Faibussowitsch PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad Inversion: zero pivot in row %" PetscInt_FMT,(PetscInt)info-1); 809566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0)); 818c178816SStefano Zampini } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve"); 828c178816SStefano Zampini 838c178816SStefano Zampini A->ops->solve = NULL; 848c178816SStefano Zampini A->ops->matsolve = NULL; 858c178816SStefano Zampini A->ops->solvetranspose = NULL; 868c178816SStefano Zampini A->ops->matsolvetranspose = NULL; 878c178816SStefano Zampini A->ops->solveadd = NULL; 888c178816SStefano Zampini A->ops->solvetransposeadd = NULL; 898c178816SStefano Zampini A->factortype = MAT_FACTOR_NONE; 909566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 918c178816SStefano Zampini PetscFunctionReturn(0); 928c178816SStefano Zampini } 938c178816SStefano Zampini 943f49a652SStefano Zampini PetscErrorCode MatZeroRowsColumns_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 953f49a652SStefano Zampini { 963f49a652SStefano Zampini Mat_SeqDense *l = (Mat_SeqDense*)A->data; 973f49a652SStefano Zampini PetscInt m = l->lda, n = A->cmap->n,r = A->rmap->n, i,j; 98ca15aa20SStefano Zampini PetscScalar *slot,*bb,*v; 993f49a652SStefano Zampini const PetscScalar *xx; 1003f49a652SStefano Zampini 1013f49a652SStefano Zampini PetscFunctionBegin; 10276bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 1033f49a652SStefano Zampini for (i=0; i<N; i++) { 10408401ef6SPierre Jolivet PetscCheck(rows[i] >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed"); 10508401ef6SPierre 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); 10608401ef6SPierre 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); 1073f49a652SStefano Zampini } 10876bd3646SJed Brown } 109ca15aa20SStefano Zampini if (!N) PetscFunctionReturn(0); 1103f49a652SStefano Zampini 1113f49a652SStefano Zampini /* fix right hand side if needed */ 1123f49a652SStefano Zampini if (x && b) { 1136c4d906cSStefano Zampini Vec xt; 1146c4d906cSStefano Zampini 11508401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices"); 1169566063dSJacob Faibussowitsch PetscCall(VecDuplicate(x,&xt)); 1179566063dSJacob Faibussowitsch PetscCall(VecCopy(x,xt)); 1189566063dSJacob Faibussowitsch PetscCall(VecScale(xt,-1.0)); 1199566063dSJacob Faibussowitsch PetscCall(MatMultAdd(A,xt,b,b)); 1209566063dSJacob Faibussowitsch PetscCall(VecDestroy(&xt)); 1219566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x,&xx)); 1229566063dSJacob Faibussowitsch PetscCall(VecGetArray(b,&bb)); 1233f49a652SStefano Zampini for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]]; 1249566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x,&xx)); 1259566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(b,&bb)); 1263f49a652SStefano Zampini } 1273f49a652SStefano Zampini 1289566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A,&v)); 1293f49a652SStefano Zampini for (i=0; i<N; i++) { 130ca15aa20SStefano Zampini slot = v + rows[i]*m; 1319566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(slot,r)); 1323f49a652SStefano Zampini } 1333f49a652SStefano Zampini for (i=0; i<N; i++) { 134ca15aa20SStefano Zampini slot = v + rows[i]; 1353f49a652SStefano Zampini for (j=0; j<n; j++) { *slot = 0.0; slot += m;} 1363f49a652SStefano Zampini } 1373f49a652SStefano Zampini if (diag != 0.0) { 13808401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices"); 1393f49a652SStefano Zampini for (i=0; i<N; i++) { 140ca15aa20SStefano Zampini slot = v + (m+1)*rows[i]; 1413f49a652SStefano Zampini *slot = diag; 1423f49a652SStefano Zampini } 1433f49a652SStefano Zampini } 1449566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A,&v)); 1453f49a652SStefano Zampini PetscFunctionReturn(0); 1463f49a652SStefano Zampini } 1473f49a652SStefano Zampini 148abc3b08eSStefano Zampini PetscErrorCode MatPtAPNumeric_SeqDense_SeqDense(Mat A,Mat P,Mat C) 149abc3b08eSStefano Zampini { 150abc3b08eSStefano Zampini Mat_SeqDense *c = (Mat_SeqDense*)(C->data); 151abc3b08eSStefano Zampini 152abc3b08eSStefano Zampini PetscFunctionBegin; 153ca15aa20SStefano Zampini if (c->ptapwork) { 1549566063dSJacob Faibussowitsch PetscCall((*C->ops->matmultnumeric)(A,P,c->ptapwork)); 1559566063dSJacob Faibussowitsch PetscCall((*C->ops->transposematmultnumeric)(P,c->ptapwork,C)); 1564222ddf1SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_SUP,"Must call MatPtAPSymbolic_SeqDense_SeqDense() first"); 157abc3b08eSStefano Zampini PetscFunctionReturn(0); 158abc3b08eSStefano Zampini } 159abc3b08eSStefano Zampini 1604222ddf1SHong Zhang PetscErrorCode MatPtAPSymbolic_SeqDense_SeqDense(Mat A,Mat P,PetscReal fill,Mat C) 161abc3b08eSStefano Zampini { 162abc3b08eSStefano Zampini Mat_SeqDense *c; 1637a3c3d58SStefano Zampini PetscBool cisdense; 164abc3b08eSStefano Zampini 165abc3b08eSStefano Zampini PetscFunctionBegin; 1669566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C,P->cmap->n,P->cmap->n,P->cmap->N,P->cmap->N)); 1679566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"")); 1687a3c3d58SStefano Zampini if (!cisdense) { 1697a3c3d58SStefano Zampini PetscBool flg; 1707a3c3d58SStefano Zampini 1719566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)P,((PetscObject)A)->type_name,&flg)); 1729566063dSJacob Faibussowitsch PetscCall(MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE)); 1737a3c3d58SStefano Zampini } 1749566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 1754222ddf1SHong Zhang c = (Mat_SeqDense*)C->data; 1769566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&c->ptapwork)); 1779566063dSJacob Faibussowitsch PetscCall(MatSetSizes(c->ptapwork,A->rmap->n,P->cmap->n,A->rmap->N,P->cmap->N)); 1789566063dSJacob Faibussowitsch PetscCall(MatSetType(c->ptapwork,((PetscObject)C)->type_name)); 1799566063dSJacob Faibussowitsch PetscCall(MatSetUp(c->ptapwork)); 180abc3b08eSStefano Zampini PetscFunctionReturn(0); 181abc3b08eSStefano Zampini } 182abc3b08eSStefano Zampini 183cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat A,MatType newtype,MatReuse reuse,Mat *newmat) 184b49cda9fSStefano Zampini { 185a13144ffSStefano Zampini Mat B = NULL; 186b49cda9fSStefano Zampini Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 187b49cda9fSStefano Zampini Mat_SeqDense *b; 188b49cda9fSStefano Zampini PetscInt *ai=a->i,*aj=a->j,m=A->rmap->N,n=A->cmap->N,i; 1892e5835c6SStefano Zampini const MatScalar *av; 190a13144ffSStefano Zampini PetscBool isseqdense; 191b49cda9fSStefano Zampini 192b49cda9fSStefano Zampini PetscFunctionBegin; 193a13144ffSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 1949566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)*newmat,MATSEQDENSE,&isseqdense)); 19528b400f6SJacob Faibussowitsch PetscCheck(isseqdense,PetscObjectComm((PetscObject)*newmat),PETSC_ERR_USER,"Cannot reuse matrix of type %s",((PetscObject)(*newmat))->type_name); 196a13144ffSStefano Zampini } 197a13144ffSStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 1989566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&B)); 1999566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B,m,n,m,n)); 2009566063dSJacob Faibussowitsch PetscCall(MatSetType(B,MATSEQDENSE)); 2019566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(B,NULL)); 202b49cda9fSStefano Zampini b = (Mat_SeqDense*)(B->data); 203a13144ffSStefano Zampini } else { 204a13144ffSStefano Zampini b = (Mat_SeqDense*)((*newmat)->data); 2059566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(b->v,m*n)); 206a13144ffSStefano Zampini } 2079566063dSJacob Faibussowitsch PetscCall(MatSeqAIJGetArrayRead(A,&av)); 208b49cda9fSStefano Zampini for (i=0; i<m; i++) { 209b49cda9fSStefano Zampini PetscInt j; 210b49cda9fSStefano Zampini for (j=0;j<ai[1]-ai[0];j++) { 211b49cda9fSStefano Zampini b->v[*aj*m+i] = *av; 212b49cda9fSStefano Zampini aj++; 213b49cda9fSStefano Zampini av++; 214b49cda9fSStefano Zampini } 215b49cda9fSStefano Zampini ai++; 216b49cda9fSStefano Zampini } 2179566063dSJacob Faibussowitsch PetscCall(MatSeqAIJRestoreArrayRead(A,&av)); 218b49cda9fSStefano Zampini 219511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 2209566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY)); 2219566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY)); 2229566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A,&B)); 223b49cda9fSStefano Zampini } else { 224a13144ffSStefano Zampini if (B) *newmat = B; 2259566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY)); 2269566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY)); 227b49cda9fSStefano Zampini } 228b49cda9fSStefano Zampini PetscFunctionReturn(0); 229b49cda9fSStefano Zampini } 230b49cda9fSStefano Zampini 231cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_SeqAIJ(Mat A, MatType newtype,MatReuse reuse,Mat *newmat) 2326a63e612SBarry Smith { 2336d4ec7b0SPierre Jolivet Mat B = NULL; 2346a63e612SBarry Smith Mat_SeqDense *a = (Mat_SeqDense*)A->data; 2359399e1b8SMatthew G. Knepley PetscInt i, j; 2369399e1b8SMatthew G. Knepley PetscInt *rows, *nnz; 2379399e1b8SMatthew G. Knepley MatScalar *aa = a->v, *vals; 2386a63e612SBarry Smith 2396a63e612SBarry Smith PetscFunctionBegin; 2409566063dSJacob Faibussowitsch PetscCall(PetscCalloc3(A->rmap->n,&rows,A->rmap->n,&nnz,A->rmap->n,&vals)); 2416d4ec7b0SPierre Jolivet if (reuse != MAT_REUSE_MATRIX) { 2429566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&B)); 2439566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N)); 2449566063dSJacob Faibussowitsch PetscCall(MatSetType(B,MATSEQAIJ)); 2459399e1b8SMatthew G. Knepley for (j=0; j<A->cmap->n; j++) { 2466d4ec7b0SPierre Jolivet for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) ++nnz[i]; 2476a63e612SBarry Smith aa += a->lda; 2486a63e612SBarry Smith } 2499566063dSJacob Faibussowitsch PetscCall(MatSeqAIJSetPreallocation(B,PETSC_DETERMINE,nnz)); 2506d4ec7b0SPierre Jolivet } else B = *newmat; 2519399e1b8SMatthew G. Knepley aa = a->v; 2529399e1b8SMatthew G. Knepley for (j=0; j<A->cmap->n; j++) { 2539399e1b8SMatthew G. Knepley PetscInt numRows = 0; 2546d4ec7b0SPierre Jolivet for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) {rows[numRows] = i; vals[numRows++] = aa[i];} 2559566063dSJacob Faibussowitsch PetscCall(MatSetValues(B,numRows,rows,1,&j,vals,INSERT_VALUES)); 2569399e1b8SMatthew G. Knepley aa += a->lda; 2579399e1b8SMatthew G. Knepley } 2589566063dSJacob Faibussowitsch PetscCall(PetscFree3(rows,nnz,vals)); 2599566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY)); 2609566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY)); 2616a63e612SBarry Smith 262511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 2639566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A,&B)); 2646d4ec7b0SPierre Jolivet } else if (reuse != MAT_REUSE_MATRIX) *newmat = B; 2656a63e612SBarry Smith PetscFunctionReturn(0); 2666a63e612SBarry Smith } 2676a63e612SBarry Smith 268ca15aa20SStefano Zampini PetscErrorCode MatAXPY_SeqDense(Mat Y,PetscScalar alpha,Mat X,MatStructure str) 2691987afe7SBarry Smith { 2701987afe7SBarry Smith Mat_SeqDense *x = (Mat_SeqDense*)X->data,*y = (Mat_SeqDense*)Y->data; 271ca15aa20SStefano Zampini const PetscScalar *xv; 272ca15aa20SStefano Zampini PetscScalar *yv; 27323fff9afSBarry Smith PetscBLASInt N,m,ldax = 0,lday = 0,one = 1; 2743a40ed3dSBarry Smith 2753a40ed3dSBarry Smith PetscFunctionBegin; 2769566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(X,&xv)); 2779566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(Y,&yv)); 2789566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(X->rmap->n*X->cmap->n,&N)); 2799566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(X->rmap->n,&m)); 2809566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(x->lda,&ldax)); 2819566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(y->lda,&lday)); 282a5ce6ee0Svictorle if (ldax>m || lday>m) { 283ca15aa20SStefano Zampini PetscInt j; 284ca15aa20SStefano Zampini 285d0f46423SBarry Smith for (j=0; j<X->cmap->n; j++) { 286ca15aa20SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&m,&alpha,xv+j*ldax,&one,yv+j*lday,&one)); 287a5ce6ee0Svictorle } 288a5ce6ee0Svictorle } else { 289ca15aa20SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&N,&alpha,xv,&one,yv,&one)); 290a5ce6ee0Svictorle } 2919566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(X,&xv)); 2929566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(Y,&yv)); 2939566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(PetscMax(2.0*N-1,0))); 2943a40ed3dSBarry Smith PetscFunctionReturn(0); 2951987afe7SBarry Smith } 2961987afe7SBarry Smith 297e0877f53SBarry Smith static PetscErrorCode MatGetInfo_SeqDense(Mat A,MatInfoType flag,MatInfo *info) 298289bc588SBarry Smith { 299ca15aa20SStefano Zampini PetscLogDouble N = A->rmap->n*A->cmap->n; 3003a40ed3dSBarry Smith 3013a40ed3dSBarry Smith PetscFunctionBegin; 3024e220ebcSLois Curfman McInnes info->block_size = 1.0; 303ca15aa20SStefano Zampini info->nz_allocated = N; 304ca15aa20SStefano Zampini info->nz_used = N; 305ca15aa20SStefano Zampini info->nz_unneeded = 0; 306ca15aa20SStefano Zampini info->assemblies = A->num_ass; 3074e220ebcSLois Curfman McInnes info->mallocs = 0; 3087adad957SLisandro Dalcin info->memory = ((PetscObject)A)->mem; 3094e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 3104e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 3114e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 3123a40ed3dSBarry Smith PetscFunctionReturn(0); 313289bc588SBarry Smith } 314289bc588SBarry Smith 315637a0070SStefano Zampini PetscErrorCode MatScale_SeqDense(Mat A,PetscScalar alpha) 31680cd9d93SLois Curfman McInnes { 317273d9f13SBarry Smith Mat_SeqDense *a = (Mat_SeqDense*)A->data; 318ca15aa20SStefano Zampini PetscScalar *v; 31923fff9afSBarry Smith PetscBLASInt one = 1,j,nz,lda = 0; 32080cd9d93SLois Curfman McInnes 3213a40ed3dSBarry Smith PetscFunctionBegin; 3229566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A,&v)); 3239566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(a->lda,&lda)); 324d0f46423SBarry Smith if (lda>A->rmap->n) { 3259566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n,&nz)); 326d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 327ca15aa20SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&alpha,v+j*lda,&one)); 328a5ce6ee0Svictorle } 329a5ce6ee0Svictorle } else { 3309566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n*A->cmap->n,&nz)); 331ca15aa20SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&alpha,v,&one)); 332a5ce6ee0Svictorle } 33304cbc005SJose E. Roman PetscCall(PetscLogFlops(A->rmap->n*A->cmap->n)); 3349566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A,&v)); 3353a40ed3dSBarry Smith PetscFunctionReturn(0); 33680cd9d93SLois Curfman McInnes } 33780cd9d93SLois Curfman McInnes 3382f605a99SJose E. Roman PetscErrorCode MatShift_SeqDense(Mat A,PetscScalar alpha) 3392f605a99SJose E. Roman { 3402f605a99SJose E. Roman Mat_SeqDense *a = (Mat_SeqDense*)A->data; 3412f605a99SJose E. Roman PetscScalar *v; 3422f605a99SJose E. Roman PetscInt j,k; 3432f605a99SJose E. Roman 3442f605a99SJose E. Roman PetscFunctionBegin; 3452f605a99SJose E. Roman PetscCall(MatDenseGetArray(A,&v)); 3462f605a99SJose E. Roman k = PetscMin(A->rmap->n,A->cmap->n); 3472f605a99SJose E. Roman for (j=0; j<k; j++) v[j+j*a->lda] += alpha; 3482f605a99SJose E. Roman PetscCall(PetscLogFlops(k)); 3492f605a99SJose E. Roman PetscCall(MatDenseRestoreArray(A,&v)); 3502f605a99SJose E. Roman PetscFunctionReturn(0); 3512f605a99SJose E. Roman } 3522f605a99SJose E. Roman 353e0877f53SBarry Smith static PetscErrorCode MatIsHermitian_SeqDense(Mat A,PetscReal rtol,PetscBool *fl) 3541cbb95d3SBarry Smith { 3551cbb95d3SBarry Smith Mat_SeqDense *a = (Mat_SeqDense*)A->data; 356ca15aa20SStefano Zampini PetscInt i,j,m = A->rmap->n,N = a->lda; 357ca15aa20SStefano Zampini const PetscScalar *v; 3581cbb95d3SBarry Smith 3591cbb95d3SBarry Smith PetscFunctionBegin; 3601cbb95d3SBarry Smith *fl = PETSC_FALSE; 361d0f46423SBarry Smith if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0); 3629566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A,&v)); 3631cbb95d3SBarry Smith for (i=0; i<m; i++) { 364ca15aa20SStefano Zampini for (j=i; j<m; j++) { 365637a0070SStefano Zampini if (PetscAbsScalar(v[i+j*N] - PetscConj(v[j+i*N])) > rtol) { 366637a0070SStefano Zampini goto restore; 3671cbb95d3SBarry Smith } 3681cbb95d3SBarry Smith } 369637a0070SStefano Zampini } 3701cbb95d3SBarry Smith *fl = PETSC_TRUE; 371637a0070SStefano Zampini restore: 3729566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A,&v)); 373637a0070SStefano Zampini PetscFunctionReturn(0); 374637a0070SStefano Zampini } 375637a0070SStefano Zampini 376637a0070SStefano Zampini static PetscErrorCode MatIsSymmetric_SeqDense(Mat A,PetscReal rtol,PetscBool *fl) 377637a0070SStefano Zampini { 378637a0070SStefano Zampini Mat_SeqDense *a = (Mat_SeqDense*)A->data; 379637a0070SStefano Zampini PetscInt i,j,m = A->rmap->n,N = a->lda; 380637a0070SStefano Zampini const PetscScalar *v; 381637a0070SStefano Zampini 382637a0070SStefano Zampini PetscFunctionBegin; 383637a0070SStefano Zampini *fl = PETSC_FALSE; 384637a0070SStefano Zampini if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0); 3859566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A,&v)); 386637a0070SStefano Zampini for (i=0; i<m; i++) { 387637a0070SStefano Zampini for (j=i; j<m; j++) { 388637a0070SStefano Zampini if (PetscAbsScalar(v[i+j*N] - v[j+i*N]) > rtol) { 389637a0070SStefano Zampini goto restore; 390637a0070SStefano Zampini } 391637a0070SStefano Zampini } 392637a0070SStefano Zampini } 393637a0070SStefano Zampini *fl = PETSC_TRUE; 394637a0070SStefano Zampini restore: 3959566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A,&v)); 3961cbb95d3SBarry Smith PetscFunctionReturn(0); 3971cbb95d3SBarry Smith } 3981cbb95d3SBarry Smith 399ca15aa20SStefano Zampini PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi,Mat A,MatDuplicateOption cpvalues) 400b24902e0SBarry Smith { 401ca15aa20SStefano Zampini Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 40223fc5dcaSStefano Zampini PetscInt lda = (PetscInt)mat->lda,j,m,nlda = lda; 40375f6d85dSStefano Zampini PetscBool isdensecpu; 404b24902e0SBarry Smith 405b24902e0SBarry Smith PetscFunctionBegin; 4069566063dSJacob Faibussowitsch PetscCall(PetscLayoutReference(A->rmap,&newi->rmap)); 4079566063dSJacob Faibussowitsch PetscCall(PetscLayoutReference(A->cmap,&newi->cmap)); 40823fc5dcaSStefano Zampini if (cpvalues == MAT_SHARE_NONZERO_PATTERN) { /* propagate LDA */ 4099566063dSJacob Faibussowitsch PetscCall(MatDenseSetLDA(newi,lda)); 41023fc5dcaSStefano Zampini } 4119566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)newi,MATSEQDENSE,&isdensecpu)); 4129566063dSJacob Faibussowitsch if (isdensecpu) PetscCall(MatSeqDenseSetPreallocation(newi,NULL)); 413b24902e0SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 414ca15aa20SStefano Zampini const PetscScalar *av; 415ca15aa20SStefano Zampini PetscScalar *v; 416ca15aa20SStefano Zampini 4179566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A,&av)); 4189566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(newi,&v)); 4199566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(newi,&nlda)); 420d0f46423SBarry Smith m = A->rmap->n; 42123fc5dcaSStefano Zampini if (lda>m || nlda>m) { 422d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 4239566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(v+j*nlda,av+j*lda,m)); 424b24902e0SBarry Smith } 425b24902e0SBarry Smith } else { 4269566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(v,av,A->rmap->n*A->cmap->n)); 427b24902e0SBarry Smith } 4289566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(newi,&v)); 4299566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A,&av)); 430b24902e0SBarry Smith } 431b24902e0SBarry Smith PetscFunctionReturn(0); 432b24902e0SBarry Smith } 433b24902e0SBarry Smith 434ca15aa20SStefano Zampini PetscErrorCode MatDuplicate_SeqDense(Mat A,MatDuplicateOption cpvalues,Mat *newmat) 43502cad45dSBarry Smith { 4363a40ed3dSBarry Smith PetscFunctionBegin; 4379566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A),newmat)); 4389566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*newmat,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n)); 4399566063dSJacob Faibussowitsch PetscCall(MatSetType(*newmat,((PetscObject)A)->type_name)); 4409566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(*newmat,A,cpvalues)); 441b24902e0SBarry Smith PetscFunctionReturn(0); 442b24902e0SBarry Smith } 443b24902e0SBarry Smith 444bf5a80bcSToby Isaac static PetscErrorCode MatSolve_SeqDense_Internal_LU(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T) 445289bc588SBarry Smith { 446c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 4474396437dSToby Isaac PetscBLASInt info; 44867e560aaSBarry Smith 4493a40ed3dSBarry Smith PetscFunctionBegin; 4509566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 4514396437dSToby Isaac PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_(T ? "T" : "N",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info)); 4529566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 45305fcb23eSStefano Zampini PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve %d",(int)info); 4549566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs*(2.0*m*m - m))); 4554396437dSToby Isaac PetscFunctionReturn(0); 4564396437dSToby Isaac } 4574396437dSToby Isaac 4584396437dSToby Isaac static PetscErrorCode MatConjugate_SeqDense(Mat); 4594396437dSToby Isaac 460bf5a80bcSToby Isaac static PetscErrorCode MatSolve_SeqDense_Internal_Cholesky(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T) 4614396437dSToby Isaac { 4624396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 4634396437dSToby Isaac PetscBLASInt info; 4644396437dSToby Isaac 4654396437dSToby Isaac PetscFunctionBegin; 466a49dc2a2SStefano Zampini if (A->spd) { 4679566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A)); 4689566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 4698b83055fSJed Brown PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&nrhs,mat->v,&mat->lda,x,&m,&info)); 4709566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 47105fcb23eSStefano Zampini PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve %d",(int)info); 4729566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A)); 473a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX) 474a49dc2a2SStefano Zampini } else if (A->hermitian) { 4759566063dSJacob Faibussowitsch if (T) PetscCall(MatConjugate_SeqDense(A)); 4769566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 477a49dc2a2SStefano Zampini PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info)); 4789566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 47905fcb23eSStefano Zampini PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve %d",(int)info); 4809566063dSJacob Faibussowitsch if (T) PetscCall(MatConjugate_SeqDense(A)); 481a49dc2a2SStefano Zampini #endif 482a49dc2a2SStefano Zampini } else { /* symmetric case */ 4839566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 484a49dc2a2SStefano Zampini PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info)); 4859566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 48605fcb23eSStefano Zampini PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve %d",(int)info); 487a49dc2a2SStefano Zampini } 4889566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs*(2.0*m*m - m))); 4894396437dSToby Isaac PetscFunctionReturn(0); 4904396437dSToby Isaac } 49185e2c93fSHong Zhang 492bf5a80bcSToby Isaac static PetscErrorCode MatSolve_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k) 4934396437dSToby Isaac { 4944396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 4954396437dSToby Isaac PetscBLASInt info; 4964396437dSToby Isaac char trans; 4974396437dSToby Isaac 4984396437dSToby Isaac PetscFunctionBegin; 4994905a7bcSToby Isaac if (PetscDefined(USE_COMPLEX)) { 5004905a7bcSToby Isaac trans = 'C'; 5014905a7bcSToby Isaac } else { 5024905a7bcSToby Isaac trans = 'T'; 5034905a7bcSToby Isaac } 5049566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 50505fcb23eSStefano Zampini { /* lwork depends on the number of right-hand sides */ 50605fcb23eSStefano Zampini PetscBLASInt nlfwork, lfwork = -1; 50705fcb23eSStefano Zampini PetscScalar fwork; 50805fcb23eSStefano Zampini 50905fcb23eSStefano Zampini PetscStackCallBLAS("LAPACKormqr",LAPACKormqr_("L", &trans, &m,&nrhs,&mat->rank,mat->v,&mat->lda,mat->tau,x,&ldx,&fwork,&lfwork,&info)); 51005fcb23eSStefano Zampini nlfwork = (PetscBLASInt)PetscRealPart(fwork); 51105fcb23eSStefano Zampini if (nlfwork > mat->lfwork) { 51205fcb23eSStefano Zampini mat->lfwork = nlfwork; 51305fcb23eSStefano Zampini PetscCall(PetscFree(mat->fwork)); 51405fcb23eSStefano Zampini PetscCall(PetscMalloc1(mat->lfwork,&mat->fwork)); 51505fcb23eSStefano Zampini } 51605fcb23eSStefano Zampini } 517bf5a80bcSToby Isaac PetscStackCallBLAS("LAPACKormqr",LAPACKormqr_("L", &trans, &m,&nrhs,&mat->rank,mat->v,&mat->lda,mat->tau,x,&ldx,mat->fwork,&mat->lfwork,&info)); 5189566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 51905fcb23eSStefano Zampini PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"ORMQR - Bad orthogonal transform %d",(int)info); 5209566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 521bf5a80bcSToby Isaac PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U", "N", "N", &mat->rank,&nrhs,mat->v,&mat->lda,x,&ldx,&info)); 5229566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 52305fcb23eSStefano Zampini PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"TRTRS - Bad triangular solve %d",(int)info); 5244905a7bcSToby Isaac for (PetscInt j = 0; j < nrhs; j++) { 5254905a7bcSToby Isaac for (PetscInt i = mat->rank; i < k; i++) { 526bf5a80bcSToby Isaac x[j*ldx + i] = 0.; 5274905a7bcSToby Isaac } 5284905a7bcSToby Isaac } 5299566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs*(4.0*m*mat->rank - PetscSqr(mat->rank)))); 5304905a7bcSToby Isaac PetscFunctionReturn(0); 5314905a7bcSToby Isaac } 5324905a7bcSToby Isaac 533bf5a80bcSToby Isaac static PetscErrorCode MatSolveTranspose_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k) 5344905a7bcSToby Isaac { 5354396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 5364396437dSToby Isaac PetscBLASInt info; 5374396437dSToby Isaac 5384396437dSToby Isaac PetscFunctionBegin; 5394396437dSToby Isaac if (A->rmap->n == A->cmap->n && mat->rank == A->rmap->n) { 5409566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 541bf5a80bcSToby Isaac PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U", "T", "N", &m,&nrhs,mat->v,&mat->lda,x,&ldx,&info)); 5429566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 54305fcb23eSStefano Zampini PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"TRTRS - Bad triangular solve %d",(int)info); 5449566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A)); 54505fcb23eSStefano Zampini { /* lwork depends on the number of right-hand sides */ 54605fcb23eSStefano Zampini PetscBLASInt nlfwork, lfwork = -1; 54705fcb23eSStefano Zampini PetscScalar fwork; 54805fcb23eSStefano Zampini 54905fcb23eSStefano Zampini PetscStackCallBLAS("LAPACKormqr",LAPACKormqr_("L", "N", &m,&nrhs,&mat->rank,mat->v,&mat->lda,mat->tau,x,&ldx,&fwork,&lfwork,&info)); 55005fcb23eSStefano Zampini nlfwork = (PetscBLASInt)PetscRealPart(fwork); 55105fcb23eSStefano Zampini if (nlfwork > mat->lfwork) { 55205fcb23eSStefano Zampini mat->lfwork = nlfwork; 55305fcb23eSStefano Zampini PetscCall(PetscFree(mat->fwork)); 55405fcb23eSStefano Zampini PetscCall(PetscMalloc1(mat->lfwork,&mat->fwork)); 55505fcb23eSStefano Zampini } 55605fcb23eSStefano Zampini } 5579566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 558bf5a80bcSToby Isaac PetscStackCallBLAS("LAPACKormqr",LAPACKormqr_("L", "N", &m,&nrhs,&mat->rank,mat->v,&mat->lda,mat->tau,x,&ldx,mat->fwork,&mat->lfwork,&info)); 5599566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 56005fcb23eSStefano Zampini PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"ORMQR - Bad orthogonal transform %d",(int)info); 5619566063dSJacob Faibussowitsch if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A)); 5624396437dSToby Isaac } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"QR factored matrix cannot be used for transpose solve"); 5639566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(nrhs*(4.0*m*mat->rank - PetscSqr(mat->rank)))); 5644396437dSToby Isaac PetscFunctionReturn(0); 5654396437dSToby Isaac } 5664396437dSToby Isaac 5674396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_SetUp(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k) 5684396437dSToby Isaac { 5694396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 5704905a7bcSToby Isaac PetscScalar *y; 5714905a7bcSToby Isaac PetscBLASInt m=0, k=0; 5724905a7bcSToby Isaac 5734905a7bcSToby Isaac PetscFunctionBegin; 5749566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n,&m)); 5759566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n,&k)); 5764905a7bcSToby Isaac if (k < m) { 5779566063dSJacob Faibussowitsch PetscCall(VecCopy(xx, mat->qrrhs)); 5789566063dSJacob Faibussowitsch PetscCall(VecGetArray(mat->qrrhs,&y)); 5794905a7bcSToby Isaac } else { 5809566063dSJacob Faibussowitsch PetscCall(VecCopy(xx, yy)); 5819566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy,&y)); 5824905a7bcSToby Isaac } 5834396437dSToby Isaac *_y = y; 5844396437dSToby Isaac *_k = k; 5854396437dSToby Isaac *_m = m; 5864396437dSToby Isaac PetscFunctionReturn(0); 5874396437dSToby Isaac } 5884396437dSToby Isaac 5894396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_TearDown(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k) 5904396437dSToby Isaac { 5914396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 59242e9364cSSatish Balay PetscScalar *y = NULL; 5934396437dSToby Isaac PetscBLASInt m, k; 5944396437dSToby Isaac 5954396437dSToby Isaac PetscFunctionBegin; 5964396437dSToby Isaac y = *_y; 5974396437dSToby Isaac *_y = NULL; 5984396437dSToby Isaac k = *_k; 5994396437dSToby Isaac m = *_m; 6004905a7bcSToby Isaac if (k < m) { 6014905a7bcSToby Isaac PetscScalar *yv; 6029566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy,&yv)); 6039566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(yv, y, k)); 6049566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy,&yv)); 6059566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(mat->qrrhs, &y)); 6064905a7bcSToby Isaac } else { 6079566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy,&y)); 6084905a7bcSToby Isaac } 6094905a7bcSToby Isaac PetscFunctionReturn(0); 6104905a7bcSToby Isaac } 6114905a7bcSToby Isaac 6124396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_LU(Mat A, Vec xx, Vec yy) 6134396437dSToby Isaac { 61442e9364cSSatish Balay PetscScalar *y = NULL; 61542e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 6164396437dSToby Isaac 6174396437dSToby Isaac PetscFunctionBegin; 6189566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6199566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_FALSE)); 6209566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6214396437dSToby Isaac PetscFunctionReturn(0); 6224396437dSToby Isaac } 6234396437dSToby Isaac 6244396437dSToby Isaac static PetscErrorCode MatSolveTranspose_SeqDense_LU(Mat A, Vec xx, Vec yy) 6254396437dSToby Isaac { 62642e9364cSSatish Balay PetscScalar *y = NULL; 62742e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 6284396437dSToby Isaac 6294396437dSToby Isaac PetscFunctionBegin; 6309566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6319566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_TRUE)); 6329566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6334396437dSToby Isaac PetscFunctionReturn(0); 6344396437dSToby Isaac } 6354396437dSToby Isaac 6364396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_Cholesky(Mat A, Vec xx, Vec yy) 6374396437dSToby Isaac { 638e54beecaSStefano Zampini PetscScalar *y = NULL; 639e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 6404396437dSToby Isaac 6414396437dSToby Isaac PetscFunctionBegin; 6429566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6439566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_FALSE)); 6449566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6454396437dSToby Isaac PetscFunctionReturn(0); 6464396437dSToby Isaac } 6474396437dSToby Isaac 6484396437dSToby Isaac static PetscErrorCode MatSolveTranspose_SeqDense_Cholesky(Mat A, Vec xx, Vec yy) 6494396437dSToby Isaac { 650e54beecaSStefano Zampini PetscScalar *y = NULL; 651e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 6524396437dSToby Isaac 6534396437dSToby Isaac PetscFunctionBegin; 6549566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6559566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_TRUE)); 6569566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6574396437dSToby Isaac PetscFunctionReturn(0); 6584396437dSToby Isaac } 6594396437dSToby Isaac 6604396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_QR(Mat A, Vec xx, Vec yy) 6614396437dSToby Isaac { 662e54beecaSStefano Zampini PetscScalar *y = NULL; 663e54beecaSStefano Zampini PetscBLASInt m = 0, k = 0; 6644396437dSToby Isaac 6654396437dSToby Isaac PetscFunctionBegin; 6669566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6679566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_QR(A, y, PetscMax(m,k), m, 1, k)); 6689566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6694396437dSToby Isaac PetscFunctionReturn(0); 6704396437dSToby Isaac } 6714396437dSToby Isaac 6724396437dSToby Isaac static PetscErrorCode MatSolveTranspose_SeqDense_QR(Mat A, Vec xx, Vec yy) 6734396437dSToby Isaac { 67442e9364cSSatish Balay PetscScalar *y = NULL; 67542e9364cSSatish Balay PetscBLASInt m = 0, k = 0; 6764396437dSToby Isaac 6774396437dSToby Isaac PetscFunctionBegin; 6789566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k)); 6799566063dSJacob Faibussowitsch PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, PetscMax(m,k), m, 1, k)); 6809566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k)); 6814396437dSToby Isaac PetscFunctionReturn(0); 6824396437dSToby Isaac } 6834396437dSToby Isaac 684bf5a80bcSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_SetUp(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k) 6854905a7bcSToby Isaac { 6864905a7bcSToby Isaac const PetscScalar *b; 6874396437dSToby Isaac PetscScalar *y; 688bf5a80bcSToby Isaac PetscInt n, _ldb, _ldx; 689bf5a80bcSToby Isaac PetscBLASInt nrhs=0,m=0,k=0,ldb=0,ldx=0,ldy=0; 6904905a7bcSToby Isaac 6914905a7bcSToby Isaac PetscFunctionBegin; 6926280eecaSJose E. Roman *_ldy=0; *_m=0; *_nrhs=0; *_k=0; *_y = NULL; 6939566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n,&m)); 6949566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n,&k)); 6959566063dSJacob Faibussowitsch PetscCall(MatGetSize(B,NULL,&n)); 6969566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(n,&nrhs)); 6979566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(B,&_ldb)); 6989566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldb, &ldb)); 6999566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(X,&_ldx)); 7009566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldx, &ldx)); 701bf5a80bcSToby Isaac if (ldx < m) { 7029566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B,&b)); 7039566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nrhs * m, &y)); 704bf5a80bcSToby Isaac if (ldb == m) { 7059566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(y,b,ldb*nrhs)); 7064905a7bcSToby Isaac } else { 7074905a7bcSToby Isaac for (PetscInt j = 0; j < nrhs; j++) { 7089566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(&y[j*m],&b[j*ldb],m)); 7094905a7bcSToby Isaac } 7104905a7bcSToby Isaac } 711bf5a80bcSToby Isaac ldy = m; 7129566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B,&b)); 7134905a7bcSToby Isaac } else { 714bf5a80bcSToby Isaac if (ldb == ldx) { 7159566063dSJacob Faibussowitsch PetscCall(MatCopy(B, X, SAME_NONZERO_PATTERN)); 7169566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X,&y)); 7174905a7bcSToby Isaac } else { 7189566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X,&y)); 7199566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B,&b)); 7204905a7bcSToby Isaac for (PetscInt j = 0; j < nrhs; j++) { 7219566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(&y[j*ldx],&b[j*ldb],m)); 7224905a7bcSToby Isaac } 7239566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B,&b)); 7244905a7bcSToby Isaac } 725bf5a80bcSToby Isaac ldy = ldx; 7264905a7bcSToby Isaac } 7274396437dSToby Isaac *_y = y; 728bf5a80bcSToby Isaac *_ldy = ldy; 7294396437dSToby Isaac *_k = k; 7304396437dSToby Isaac *_m = m; 7314396437dSToby Isaac *_nrhs = nrhs; 7324396437dSToby Isaac PetscFunctionReturn(0); 7334396437dSToby Isaac } 7344396437dSToby Isaac 735bf5a80bcSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_TearDown(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k) 7364396437dSToby Isaac { 7374396437dSToby Isaac PetscScalar *y; 738bf5a80bcSToby Isaac PetscInt _ldx; 739bf5a80bcSToby Isaac PetscBLASInt k,ldy,nrhs,ldx=0; 7404396437dSToby Isaac 7414396437dSToby Isaac PetscFunctionBegin; 7424396437dSToby Isaac y = *_y; 7434396437dSToby Isaac *_y = NULL; 7444396437dSToby Isaac k = *_k; 745bf5a80bcSToby Isaac ldy = *_ldy; 7464396437dSToby Isaac nrhs = *_nrhs; 7479566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(X,&_ldx)); 7489566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(_ldx, &ldx)); 749bf5a80bcSToby Isaac if (ldx != ldy) { 7504905a7bcSToby Isaac PetscScalar *xv; 7519566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(X,&xv)); 7524905a7bcSToby Isaac for (PetscInt j = 0; j < nrhs; j++) { 7539566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(&xv[j*ldx],&y[j*ldy],k)); 7544905a7bcSToby Isaac } 7559566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(X,&xv)); 7569566063dSJacob Faibussowitsch PetscCall(PetscFree(y)); 7574905a7bcSToby Isaac } else { 7589566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(X,&y)); 7594905a7bcSToby Isaac } 76085e2c93fSHong Zhang PetscFunctionReturn(0); 76185e2c93fSHong Zhang } 76285e2c93fSHong Zhang 7634396437dSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_LU(Mat A, Mat B, Mat X) 7644396437dSToby Isaac { 7654396437dSToby Isaac PetscScalar *y; 766bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7674396437dSToby Isaac 7684396437dSToby Isaac PetscFunctionBegin; 7699566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7709566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_FALSE)); 7719566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7724396437dSToby Isaac PetscFunctionReturn(0); 7734396437dSToby Isaac } 7744396437dSToby Isaac 7754396437dSToby Isaac static PetscErrorCode MatMatSolveTranspose_SeqDense_LU(Mat A, Mat B, Mat X) 7764396437dSToby Isaac { 7774396437dSToby Isaac PetscScalar *y; 778bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7794396437dSToby Isaac 7804396437dSToby Isaac PetscFunctionBegin; 7819566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7829566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_TRUE)); 7839566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7844396437dSToby Isaac PetscFunctionReturn(0); 7854396437dSToby Isaac } 7864396437dSToby Isaac 7874396437dSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_Cholesky(Mat A, Mat B, Mat X) 7884396437dSToby Isaac { 7894396437dSToby Isaac PetscScalar *y; 790bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 7914396437dSToby Isaac 7924396437dSToby Isaac PetscFunctionBegin; 7939566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7949566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_FALSE)); 7959566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 7964396437dSToby Isaac PetscFunctionReturn(0); 7974396437dSToby Isaac } 7984396437dSToby Isaac 7994396437dSToby Isaac static PetscErrorCode MatMatSolveTranspose_SeqDense_Cholesky(Mat A, Mat B, Mat X) 8004396437dSToby Isaac { 8014396437dSToby Isaac PetscScalar *y; 802bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 8034396437dSToby Isaac 8044396437dSToby Isaac PetscFunctionBegin; 8059566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 8069566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_TRUE)); 8079566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 8084396437dSToby Isaac PetscFunctionReturn(0); 8094396437dSToby Isaac } 8104396437dSToby Isaac 8114396437dSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_QR(Mat A, Mat B, Mat X) 8124396437dSToby Isaac { 8134396437dSToby Isaac PetscScalar *y; 814bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 8154396437dSToby Isaac 8164396437dSToby Isaac PetscFunctionBegin; 8179566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 8189566063dSJacob Faibussowitsch PetscCall(MatSolve_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k)); 8199566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 8204396437dSToby Isaac PetscFunctionReturn(0); 8214396437dSToby Isaac } 8224396437dSToby Isaac 8234396437dSToby Isaac static PetscErrorCode MatMatSolveTranspose_SeqDense_QR(Mat A, Mat B, Mat X) 8244396437dSToby Isaac { 8254396437dSToby Isaac PetscScalar *y; 826bf5a80bcSToby Isaac PetscBLASInt m, k, ldy, nrhs; 8274396437dSToby Isaac 8284396437dSToby Isaac PetscFunctionBegin; 8299566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k)); 8309566063dSJacob Faibussowitsch PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k)); 8319566063dSJacob Faibussowitsch PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k)); 8324396437dSToby Isaac PetscFunctionReturn(0); 8334396437dSToby Isaac } 8344396437dSToby Isaac 835db4efbfdSBarry Smith /* ---------------------------------------------------------------*/ 836db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots, 837db4efbfdSBarry Smith rather than put it in the Mat->row slot.*/ 838ca15aa20SStefano Zampini PetscErrorCode MatLUFactor_SeqDense(Mat A,IS row,IS col,const MatFactorInfo *minfo) 839db4efbfdSBarry Smith { 840db4efbfdSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 841db4efbfdSBarry Smith PetscBLASInt n,m,info; 842db4efbfdSBarry Smith 843db4efbfdSBarry Smith PetscFunctionBegin; 8449566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n,&n)); 8459566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n,&m)); 846db4efbfdSBarry Smith if (!mat->pivots) { 8479566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->rmap->n,&mat->pivots)); 8489566063dSJacob Faibussowitsch PetscCall(PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt))); 849db4efbfdSBarry Smith } 850db4efbfdSBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 8519566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 8528b83055fSJed Brown PetscStackCallBLAS("LAPACKgetrf",LAPACKgetrf_(&m,&n,mat->v,&mat->lda,mat->pivots,&info)); 8539566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 8548e57ea43SSatish Balay 85505fcb23eSStefano Zampini PetscCheck(info>=0,PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to LU factorization %d",(int)info); 85605fcb23eSStefano Zampini PetscCheck(info<=0,PETSC_COMM_SELF,PETSC_ERR_MAT_LU_ZRPVT,"Bad LU factorization %d",(int)info); 8578208b9aeSStefano Zampini 8584396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_LU; 8594396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_LU; 8604396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_LU; 8614396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_LU; 862d5f3da31SBarry Smith A->factortype = MAT_FACTOR_LU; 863db4efbfdSBarry Smith 8649566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 8659566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC,&A->solvertype)); 866f6224b95SHong Zhang 8679566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((2.0*A->cmap->n*A->cmap->n*A->cmap->n)/3)); 868db4efbfdSBarry Smith PetscFunctionReturn(0); 869db4efbfdSBarry Smith } 870db4efbfdSBarry Smith 8714396437dSToby Isaac static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy) 8724396437dSToby Isaac { 8734396437dSToby Isaac MatFactorInfo info; 8744396437dSToby Isaac 8754396437dSToby Isaac PetscFunctionBegin; 8769566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES)); 8779566063dSJacob Faibussowitsch PetscCall((*fact->ops->lufactor)(fact,NULL,NULL,&info)); 8784396437dSToby Isaac PetscFunctionReturn(0); 8794396437dSToby Isaac } 8804396437dSToby Isaac 8814396437dSToby Isaac PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,IS col,const MatFactorInfo *info) 8824396437dSToby Isaac { 8834396437dSToby Isaac PetscFunctionBegin; 8844396437dSToby Isaac fact->preallocated = PETSC_TRUE; 8854396437dSToby Isaac fact->assembled = PETSC_TRUE; 8864396437dSToby Isaac fact->ops->lufactornumeric = MatLUFactorNumeric_SeqDense; 8874396437dSToby Isaac PetscFunctionReturn(0); 8884396437dSToby Isaac } 8894396437dSToby Isaac 890a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */ 891ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactor_SeqDense(Mat A,IS perm,const MatFactorInfo *factinfo) 892db4efbfdSBarry Smith { 893db4efbfdSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 894c5df96a5SBarry Smith PetscBLASInt info,n; 895db4efbfdSBarry Smith 896db4efbfdSBarry Smith PetscFunctionBegin; 8979566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n,&n)); 898db4efbfdSBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 899a49dc2a2SStefano Zampini if (A->spd) { 9009566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 9018b83055fSJed Brown PetscStackCallBLAS("LAPACKpotrf",LAPACKpotrf_("L",&n,mat->v,&mat->lda,&info)); 9029566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 903a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX) 904a49dc2a2SStefano Zampini } else if (A->hermitian) { 905a49dc2a2SStefano Zampini if (!mat->pivots) { 9069566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->rmap->n,&mat->pivots)); 9079566063dSJacob Faibussowitsch PetscCall(PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt))); 908a49dc2a2SStefano Zampini } 909a49dc2a2SStefano Zampini if (!mat->fwork) { 910a49dc2a2SStefano Zampini PetscScalar dummy; 911a49dc2a2SStefano Zampini 912a49dc2a2SStefano Zampini mat->lfwork = -1; 9139566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 914a49dc2a2SStefano Zampini PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info)); 9159566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 916a49dc2a2SStefano Zampini mat->lfwork = (PetscInt)PetscRealPart(dummy); 9179566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork,&mat->fwork)); 9189566063dSJacob Faibussowitsch PetscCall(PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt))); 919a49dc2a2SStefano Zampini } 9209566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 921a49dc2a2SStefano Zampini PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info)); 9229566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 923a49dc2a2SStefano Zampini #endif 924a49dc2a2SStefano Zampini } else { /* symmetric case */ 925a49dc2a2SStefano Zampini if (!mat->pivots) { 9269566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->rmap->n,&mat->pivots)); 9279566063dSJacob Faibussowitsch PetscCall(PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt))); 928a49dc2a2SStefano Zampini } 929a49dc2a2SStefano Zampini if (!mat->fwork) { 930a49dc2a2SStefano Zampini PetscScalar dummy; 931a49dc2a2SStefano Zampini 932a49dc2a2SStefano Zampini mat->lfwork = -1; 9339566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 934a49dc2a2SStefano Zampini PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info)); 9359566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 936a49dc2a2SStefano Zampini mat->lfwork = (PetscInt)PetscRealPart(dummy); 9379566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork,&mat->fwork)); 9389566063dSJacob Faibussowitsch PetscCall(PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt))); 939a49dc2a2SStefano Zampini } 9409566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 941a49dc2a2SStefano Zampini PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info)); 9429566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 943a49dc2a2SStefano Zampini } 94428b400f6SJacob Faibussowitsch PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad factorization: zero pivot in row %" PetscInt_FMT,(PetscInt)info-1); 9458208b9aeSStefano Zampini 9464396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_Cholesky; 9474396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_Cholesky; 9484396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_Cholesky; 9494396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_Cholesky; 950d5f3da31SBarry Smith A->factortype = MAT_FACTOR_CHOLESKY; 9512205254eSKarl Rupp 9529566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 9539566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC,&A->solvertype)); 954f6224b95SHong Zhang 9559566063dSJacob Faibussowitsch PetscCall(PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0)); 956db4efbfdSBarry Smith PetscFunctionReturn(0); 957db4efbfdSBarry Smith } 958db4efbfdSBarry Smith 9594396437dSToby Isaac static PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy) 960db4efbfdSBarry Smith { 961db4efbfdSBarry Smith MatFactorInfo info; 962db4efbfdSBarry Smith 963db4efbfdSBarry Smith PetscFunctionBegin; 964db4efbfdSBarry Smith info.fill = 1.0; 9652205254eSKarl Rupp 9669566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES)); 9679566063dSJacob Faibussowitsch PetscCall((*fact->ops->choleskyfactor)(fact,NULL,&info)); 968db4efbfdSBarry Smith PetscFunctionReturn(0); 969db4efbfdSBarry Smith } 970db4efbfdSBarry Smith 971ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info) 972db4efbfdSBarry Smith { 973db4efbfdSBarry Smith PetscFunctionBegin; 974c3ef05f6SHong Zhang fact->assembled = PETSC_TRUE; 9751bbcc794SSatish Balay fact->preallocated = PETSC_TRUE; 976719d5645SBarry Smith fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense; 977db4efbfdSBarry Smith PetscFunctionReturn(0); 978db4efbfdSBarry Smith } 979db4efbfdSBarry Smith 980bf5a80bcSToby Isaac PetscErrorCode MatQRFactor_SeqDense(Mat A,IS col,const MatFactorInfo *minfo) 9814905a7bcSToby Isaac { 9824905a7bcSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 9834905a7bcSToby Isaac PetscBLASInt n,m,info, min, max; 9844905a7bcSToby Isaac 9854905a7bcSToby Isaac PetscFunctionBegin; 9869566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n,&n)); 9879566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n,&m)); 9884396437dSToby Isaac max = PetscMax(m, n); 9894396437dSToby Isaac min = PetscMin(m, n); 9904905a7bcSToby Isaac if (!mat->tau) { 9919566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(min,&mat->tau)); 9929566063dSJacob Faibussowitsch PetscCall(PetscLogObjectMemory((PetscObject)A,min*sizeof(PetscScalar))); 9934396437dSToby Isaac } 9944396437dSToby Isaac if (!mat->pivots) { 9959566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(n,&mat->pivots)); 9969566063dSJacob Faibussowitsch PetscCall(PetscLogObjectMemory((PetscObject)A,n*sizeof(PetscScalar))); 9974396437dSToby Isaac } 9984396437dSToby Isaac if (!mat->qrrhs) { 9999566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(A, NULL, &(mat->qrrhs))); 10004905a7bcSToby Isaac } 10014905a7bcSToby Isaac if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 10024905a7bcSToby Isaac if (!mat->fwork) { 10034905a7bcSToby Isaac PetscScalar dummy; 10044905a7bcSToby Isaac 10054905a7bcSToby Isaac mat->lfwork = -1; 10069566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 10074905a7bcSToby Isaac PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&m,&n,mat->v,&mat->lda,mat->tau,&dummy,&mat->lfwork,&info)); 10089566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 10094905a7bcSToby Isaac mat->lfwork = (PetscInt)PetscRealPart(dummy); 10109566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(mat->lfwork,&mat->fwork)); 10119566063dSJacob Faibussowitsch PetscCall(PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt))); 10124905a7bcSToby Isaac } 10139566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF)); 10144905a7bcSToby Isaac PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&m,&n,mat->v,&mat->lda,mat->tau,mat->fwork,&mat->lfwork,&info)); 10159566063dSJacob Faibussowitsch PetscCall(PetscFPTrapPop()); 101605fcb23eSStefano Zampini PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to QR factorization %d",(int)info); 10174905a7bcSToby 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 10184905a7bcSToby Isaac mat->rank = min; 10194905a7bcSToby Isaac 10204396437dSToby Isaac A->ops->solve = MatSolve_SeqDense_QR; 10214396437dSToby Isaac A->ops->matsolve = MatMatSolve_SeqDense_QR; 10224905a7bcSToby Isaac A->factortype = MAT_FACTOR_QR; 10234905a7bcSToby Isaac if (m == n) { 10244396437dSToby Isaac A->ops->solvetranspose = MatSolveTranspose_SeqDense_QR; 10254396437dSToby Isaac A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_QR; 10264905a7bcSToby Isaac } 10274905a7bcSToby Isaac 10289566063dSJacob Faibussowitsch PetscCall(PetscFree(A->solvertype)); 10299566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC,&A->solvertype)); 10304905a7bcSToby Isaac 10319566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0*min*min*(max-min/3.0))); 10324905a7bcSToby Isaac PetscFunctionReturn(0); 10334905a7bcSToby Isaac } 10344905a7bcSToby Isaac 10354905a7bcSToby Isaac static PetscErrorCode MatQRFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy) 10364905a7bcSToby Isaac { 10374905a7bcSToby Isaac MatFactorInfo info; 10384905a7bcSToby Isaac 10394905a7bcSToby Isaac PetscFunctionBegin; 10404905a7bcSToby Isaac info.fill = 1.0; 10414905a7bcSToby Isaac 10429566063dSJacob Faibussowitsch PetscCall(MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES)); 1043cac4c232SBarry Smith PetscUseMethod(fact,"MatQRFactor_C",(Mat,IS,const MatFactorInfo *),(fact,NULL,&info)); 10444905a7bcSToby Isaac PetscFunctionReturn(0); 10454905a7bcSToby Isaac } 10464905a7bcSToby Isaac 1047bf5a80bcSToby Isaac PetscErrorCode MatQRFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info) 10484905a7bcSToby Isaac { 10494905a7bcSToby Isaac PetscFunctionBegin; 10504905a7bcSToby Isaac fact->assembled = PETSC_TRUE; 10514905a7bcSToby Isaac fact->preallocated = PETSC_TRUE; 10529566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)fact,"MatQRFactorNumeric_C",MatQRFactorNumeric_SeqDense)); 10534905a7bcSToby Isaac PetscFunctionReturn(0); 10544905a7bcSToby Isaac } 10554905a7bcSToby Isaac 1056ca15aa20SStefano Zampini /* uses LAPACK */ 1057cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A,MatFactorType ftype,Mat *fact) 1058db4efbfdSBarry Smith { 1059db4efbfdSBarry Smith PetscFunctionBegin; 10609566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A),fact)); 10619566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*fact,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n)); 10629566063dSJacob Faibussowitsch PetscCall(MatSetType(*fact,MATDENSE)); 106366e17bc3SBarry Smith (*fact)->trivialsymbolic = PETSC_TRUE; 10642a350339SBarry Smith if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU) { 1065db4efbfdSBarry Smith (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense; 10662a350339SBarry Smith (*fact)->ops->ilufactorsymbolic = MatLUFactorSymbolic_SeqDense; 1067bf5a80bcSToby Isaac } else if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) { 1068db4efbfdSBarry Smith (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense; 1069bf5a80bcSToby Isaac } else if (ftype == MAT_FACTOR_QR) { 10709566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)(*fact),"MatQRFactorSymbolic_C",MatQRFactorSymbolic_SeqDense)); 1071db4efbfdSBarry Smith } 1072d5f3da31SBarry Smith (*fact)->factortype = ftype; 107300c67f3bSHong Zhang 10749566063dSJacob Faibussowitsch PetscCall(PetscFree((*fact)->solvertype)); 10759566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATSOLVERPETSC,&(*fact)->solvertype)); 10769566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_LU])); 10779566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_ILU])); 10789566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_CHOLESKY])); 10799566063dSJacob Faibussowitsch PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_ICC])); 1080db4efbfdSBarry Smith PetscFunctionReturn(0); 1081db4efbfdSBarry Smith } 1082db4efbfdSBarry Smith 1083289bc588SBarry Smith /* ------------------------------------------------------------------*/ 1084e0877f53SBarry Smith static PetscErrorCode MatSOR_SeqDense(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec xx) 1085289bc588SBarry Smith { 1086c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 1087d9ca1df4SBarry Smith PetscScalar *x,*v = mat->v,zero = 0.0,xt; 1088d9ca1df4SBarry Smith const PetscScalar *b; 1089d0f46423SBarry Smith PetscInt m = A->rmap->n,i; 109023fff9afSBarry Smith PetscBLASInt o = 1,bm = 0; 1091289bc588SBarry Smith 10923a40ed3dSBarry Smith PetscFunctionBegin; 1093ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA) 109408401ef6SPierre Jolivet PetscCheck(A->offloadmask != PETSC_OFFLOAD_GPU,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented"); 1095ca15aa20SStefano Zampini #endif 1096422a814eSBarry Smith if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */ 10979566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(m,&bm)); 1098289bc588SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 10993bffc371SBarry Smith /* this is a hack fix, should have another version without the second BLASdotu */ 11009566063dSJacob Faibussowitsch PetscCall(VecSet(xx,zero)); 1101289bc588SBarry Smith } 11029566063dSJacob Faibussowitsch PetscCall(VecGetArray(xx,&x)); 11039566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(bb,&b)); 1104b965ef7fSBarry Smith its = its*lits; 110508401ef6SPierre 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); 1106289bc588SBarry Smith while (its--) { 1107fccaa45eSBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 1108289bc588SBarry Smith for (i=0; i<m; i++) { 11093bffc371SBarry Smith PetscStackCallBLAS("BLASdotu",xt = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o)); 111055a1b374SBarry Smith x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift); 1111289bc588SBarry Smith } 1112289bc588SBarry Smith } 1113fccaa45eSBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 1114289bc588SBarry Smith for (i=m-1; i>=0; i--) { 11153bffc371SBarry Smith PetscStackCallBLAS("BLASdotu",xt = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o)); 111655a1b374SBarry Smith x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift); 1117289bc588SBarry Smith } 1118289bc588SBarry Smith } 1119289bc588SBarry Smith } 11209566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(bb,&b)); 11219566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(xx,&x)); 11223a40ed3dSBarry Smith PetscFunctionReturn(0); 1123289bc588SBarry Smith } 1124289bc588SBarry Smith 1125289bc588SBarry Smith /* -----------------------------------------------------------------*/ 1126ca15aa20SStefano Zampini PetscErrorCode MatMultTranspose_SeqDense(Mat A,Vec xx,Vec yy) 1127289bc588SBarry Smith { 1128c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 1129d9ca1df4SBarry Smith const PetscScalar *v = mat->v,*x; 1130d9ca1df4SBarry Smith PetscScalar *y; 11310805154bSBarry Smith PetscBLASInt m, n,_One=1; 1132ea709b57SSatish Balay PetscScalar _DOne=1.0,_DZero=0.0; 11333a40ed3dSBarry Smith 11343a40ed3dSBarry Smith PetscFunctionBegin; 11359566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n,&m)); 11369566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n,&n)); 11379566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx,&x)); 11389566063dSJacob Faibussowitsch PetscCall(VecGetArrayWrite(yy,&y)); 11395ac36cfcSBarry Smith if (!A->rmap->n || !A->cmap->n) { 11405ac36cfcSBarry Smith PetscBLASInt i; 11415ac36cfcSBarry Smith for (i=0; i<n; i++) y[i] = 0.0; 11425ac36cfcSBarry Smith } else { 11438b83055fSJed Brown PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&mat->lda,x,&_One,&_DZero,y,&_One)); 11449566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->cmap->n)); 11455ac36cfcSBarry Smith } 11469566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx,&x)); 11479566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayWrite(yy,&y)); 11483a40ed3dSBarry Smith PetscFunctionReturn(0); 1149289bc588SBarry Smith } 1150800995b7SMatthew Knepley 1151ca15aa20SStefano Zampini PetscErrorCode MatMult_SeqDense(Mat A,Vec xx,Vec yy) 1152289bc588SBarry Smith { 1153c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 1154d9ca1df4SBarry Smith PetscScalar *y,_DOne=1.0,_DZero=0.0; 11550805154bSBarry Smith PetscBLASInt m, n, _One=1; 1156d9ca1df4SBarry Smith const PetscScalar *v = mat->v,*x; 11573a40ed3dSBarry Smith 11583a40ed3dSBarry Smith PetscFunctionBegin; 11599566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n,&m)); 11609566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n,&n)); 11619566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx,&x)); 11629566063dSJacob Faibussowitsch PetscCall(VecGetArrayWrite(yy,&y)); 11635ac36cfcSBarry Smith if (!A->rmap->n || !A->cmap->n) { 11645ac36cfcSBarry Smith PetscBLASInt i; 11655ac36cfcSBarry Smith for (i=0; i<m; i++) y[i] = 0.0; 11665ac36cfcSBarry Smith } else { 11678b83055fSJed Brown PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DZero,y,&_One)); 11689566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->rmap->n)); 11695ac36cfcSBarry Smith } 11709566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx,&x)); 11719566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayWrite(yy,&y)); 11723a40ed3dSBarry Smith PetscFunctionReturn(0); 1173289bc588SBarry Smith } 11746ee01492SSatish Balay 1175ca15aa20SStefano Zampini PetscErrorCode MatMultAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy) 1176289bc588SBarry Smith { 1177c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 1178d9ca1df4SBarry Smith const PetscScalar *v = mat->v,*x; 1179d9ca1df4SBarry Smith PetscScalar *y,_DOne=1.0; 11800805154bSBarry Smith PetscBLASInt m, n, _One=1; 11813a40ed3dSBarry Smith 11823a40ed3dSBarry Smith PetscFunctionBegin; 11839566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n,&m)); 11849566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n,&n)); 11859566063dSJacob Faibussowitsch PetscCall(VecCopy(zz,yy)); 1186d0f46423SBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 11879566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx,&x)); 11889566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy,&y)); 11898b83055fSJed Brown PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One)); 11909566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx,&x)); 11919566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy,&y)); 11929566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0*A->rmap->n*A->cmap->n)); 11933a40ed3dSBarry Smith PetscFunctionReturn(0); 1194289bc588SBarry Smith } 11956ee01492SSatish Balay 1196ca15aa20SStefano Zampini PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy) 1197289bc588SBarry Smith { 1198c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 1199d9ca1df4SBarry Smith const PetscScalar *v = mat->v,*x; 1200d9ca1df4SBarry Smith PetscScalar *y; 12010805154bSBarry Smith PetscBLASInt m, n, _One=1; 120287828ca2SBarry Smith PetscScalar _DOne=1.0; 12033a40ed3dSBarry Smith 12043a40ed3dSBarry Smith PetscFunctionBegin; 12059566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n,&m)); 12069566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n,&n)); 12079566063dSJacob Faibussowitsch PetscCall(VecCopy(zz,yy)); 1208d0f46423SBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 12099566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(xx,&x)); 12109566063dSJacob Faibussowitsch PetscCall(VecGetArray(yy,&y)); 12118b83055fSJed Brown PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One)); 12129566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(xx,&x)); 12139566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(yy,&y)); 12149566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0*A->rmap->n*A->cmap->n)); 12153a40ed3dSBarry Smith PetscFunctionReturn(0); 1216289bc588SBarry Smith } 1217289bc588SBarry Smith 1218289bc588SBarry Smith /* -----------------------------------------------------------------*/ 1219e0877f53SBarry Smith static PetscErrorCode MatGetRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals) 1220289bc588SBarry Smith { 1221c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 122213f74950SBarry Smith PetscInt i; 122367e560aaSBarry Smith 12243a40ed3dSBarry Smith PetscFunctionBegin; 1225d0f46423SBarry Smith *ncols = A->cmap->n; 1226289bc588SBarry Smith if (cols) { 12279566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->cmap->n,cols)); 1228d0f46423SBarry Smith for (i=0; i<A->cmap->n; i++) (*cols)[i] = i; 1229289bc588SBarry Smith } 1230289bc588SBarry Smith if (vals) { 1231ca15aa20SStefano Zampini const PetscScalar *v; 1232ca15aa20SStefano Zampini 12339566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A,&v)); 12349566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(A->cmap->n,vals)); 1235ca15aa20SStefano Zampini v += row; 1236d0f46423SBarry Smith for (i=0; i<A->cmap->n; i++) {(*vals)[i] = *v; v += mat->lda;} 12379566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A,&v)); 1238289bc588SBarry Smith } 12393a40ed3dSBarry Smith PetscFunctionReturn(0); 1240289bc588SBarry Smith } 12416ee01492SSatish Balay 1242e0877f53SBarry Smith static PetscErrorCode MatRestoreRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals) 1243289bc588SBarry Smith { 1244606d414cSSatish Balay PetscFunctionBegin; 1245cb4a9cd9SHong Zhang if (ncols) *ncols = 0; 12469566063dSJacob Faibussowitsch if (cols) PetscCall(PetscFree(*cols)); 12479566063dSJacob Faibussowitsch if (vals) PetscCall(PetscFree(*vals)); 12483a40ed3dSBarry Smith PetscFunctionReturn(0); 1249289bc588SBarry Smith } 1250289bc588SBarry Smith /* ----------------------------------------------------------------*/ 1251e0877f53SBarry Smith static PetscErrorCode MatSetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],const PetscScalar v[],InsertMode addv) 1252289bc588SBarry Smith { 1253c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 1254ca15aa20SStefano Zampini PetscScalar *av; 125513f74950SBarry Smith PetscInt i,j,idx=0; 1256ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA) 1257c70f7ee4SJunchao Zhang PetscOffloadMask oldf; 1258ca15aa20SStefano Zampini #endif 1259d6dfbf8fSBarry Smith 12603a40ed3dSBarry Smith PetscFunctionBegin; 12619566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A,&av)); 1262289bc588SBarry Smith if (!mat->roworiented) { 1263dbb450caSBarry Smith if (addv == INSERT_VALUES) { 1264289bc588SBarry Smith for (j=0; j<n; j++) { 1265cddbea37SSatish Balay if (indexn[j] < 0) {idx += m; continue;} 12666bdcaf15SBarry 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); 1267289bc588SBarry Smith for (i=0; i<m; i++) { 1268cddbea37SSatish Balay if (indexm[i] < 0) {idx++; continue;} 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 } 12733a40ed3dSBarry Smith } else { 1274289bc588SBarry Smith for (j=0; j<n; j++) { 1275cddbea37SSatish Balay if (indexn[j] < 0) {idx += m; continue;} 12766bdcaf15SBarry 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); 1277289bc588SBarry Smith for (i=0; i<m; i++) { 1278cddbea37SSatish Balay if (indexm[i] < 0) {idx++; continue;} 12796bdcaf15SBarry 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); 1280ca15aa20SStefano Zampini av[indexn[j]*mat->lda + indexm[i]] += v[idx++]; 1281289bc588SBarry Smith } 1282289bc588SBarry Smith } 1283289bc588SBarry Smith } 12843a40ed3dSBarry Smith } else { 1285dbb450caSBarry Smith if (addv == INSERT_VALUES) { 1286e8d4e0b9SBarry Smith for (i=0; i<m; i++) { 1287cddbea37SSatish Balay if (indexm[i] < 0) { idx += n; continue;} 12886bdcaf15SBarry 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); 1289e8d4e0b9SBarry Smith for (j=0; j<n; j++) { 1290cddbea37SSatish Balay if (indexn[j] < 0) { idx++; continue;} 12916bdcaf15SBarry 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); 1292ca15aa20SStefano Zampini av[indexn[j]*mat->lda + indexm[i]] = v[idx++]; 1293e8d4e0b9SBarry Smith } 1294e8d4e0b9SBarry Smith } 12953a40ed3dSBarry Smith } else { 1296289bc588SBarry Smith for (i=0; i<m; i++) { 1297cddbea37SSatish Balay if (indexm[i] < 0) { idx += n; continue;} 12986bdcaf15SBarry 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); 1299289bc588SBarry Smith for (j=0; j<n; j++) { 1300cddbea37SSatish Balay if (indexn[j] < 0) { idx++; continue;} 13016bdcaf15SBarry 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); 1302ca15aa20SStefano Zampini av[indexn[j]*mat->lda + indexm[i]] += v[idx++]; 1303289bc588SBarry Smith } 1304289bc588SBarry Smith } 1305289bc588SBarry Smith } 1306e8d4e0b9SBarry Smith } 1307ca15aa20SStefano Zampini /* hack to prevent unneeded copy to the GPU while returning the array */ 1308ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA) 1309c70f7ee4SJunchao Zhang oldf = A->offloadmask; 1310c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_GPU; 1311ca15aa20SStefano Zampini #endif 13129566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A,&av)); 1313ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA) 1314c70f7ee4SJunchao Zhang A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU); 1315ca15aa20SStefano Zampini #endif 13163a40ed3dSBarry Smith PetscFunctionReturn(0); 1317289bc588SBarry Smith } 1318e8d4e0b9SBarry Smith 1319e0877f53SBarry Smith static PetscErrorCode MatGetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],PetscScalar v[]) 1320ae80bb75SLois Curfman McInnes { 1321ae80bb75SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 1322ca15aa20SStefano Zampini const PetscScalar *vv; 132313f74950SBarry Smith PetscInt i,j; 1324ae80bb75SLois Curfman McInnes 13253a40ed3dSBarry Smith PetscFunctionBegin; 13269566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A,&vv)); 1327ae80bb75SLois Curfman McInnes /* row-oriented output */ 1328ae80bb75SLois Curfman McInnes for (i=0; i<m; i++) { 132997e567efSBarry Smith if (indexm[i] < 0) {v += n;continue;} 133008401ef6SPierre 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); 1331ae80bb75SLois Curfman McInnes for (j=0; j<n; j++) { 13326f31f424SBarry Smith if (indexn[j] < 0) {v++; continue;} 133308401ef6SPierre Jolivet PetscCheck(indexn[j] < A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column %" PetscInt_FMT " requested larger than number columns %" PetscInt_FMT,indexn[j],A->cmap->n); 1334ca15aa20SStefano Zampini *v++ = vv[indexn[j]*mat->lda + indexm[i]]; 1335ae80bb75SLois Curfman McInnes } 1336ae80bb75SLois Curfman McInnes } 13379566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A,&vv)); 13383a40ed3dSBarry Smith PetscFunctionReturn(0); 1339ae80bb75SLois Curfman McInnes } 1340ae80bb75SLois Curfman McInnes 1341289bc588SBarry Smith /* -----------------------------------------------------------------*/ 1342289bc588SBarry Smith 13438491ab44SLisandro Dalcin PetscErrorCode MatView_Dense_Binary(Mat mat,PetscViewer viewer) 1344aabbc4fbSShri Abhyankar { 13458491ab44SLisandro Dalcin PetscBool skipHeader; 13468491ab44SLisandro Dalcin PetscViewerFormat format; 13478491ab44SLisandro Dalcin PetscInt header[4],M,N,m,lda,i,j,k; 13488491ab44SLisandro Dalcin const PetscScalar *v; 13498491ab44SLisandro Dalcin PetscScalar *vwork; 1350aabbc4fbSShri Abhyankar 1351aabbc4fbSShri Abhyankar PetscFunctionBegin; 13529566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 13539566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetSkipHeader(viewer,&skipHeader)); 13549566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer,&format)); 13558491ab44SLisandro Dalcin if (skipHeader) format = PETSC_VIEWER_NATIVE; 1356aabbc4fbSShri Abhyankar 13579566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat,&M,&N)); 13588491ab44SLisandro Dalcin 13598491ab44SLisandro Dalcin /* write matrix header */ 13608491ab44SLisandro Dalcin header[0] = MAT_FILE_CLASSID; header[1] = M; header[2] = N; 13618491ab44SLisandro Dalcin header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M*N; 13629566063dSJacob Faibussowitsch if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer,header,4,PETSC_INT)); 13638491ab44SLisandro Dalcin 13649566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mat,&m,NULL)); 13658491ab44SLisandro Dalcin if (format != PETSC_VIEWER_NATIVE) { 13668491ab44SLisandro Dalcin PetscInt nnz = m*N, *iwork; 13678491ab44SLisandro Dalcin /* store row lengths for each row */ 13689566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz,&iwork)); 13698491ab44SLisandro Dalcin for (i=0; i<m; i++) iwork[i] = N; 13709566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer,iwork,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT)); 13718491ab44SLisandro Dalcin /* store column indices (zero start index) */ 13728491ab44SLisandro Dalcin for (k=0, i=0; i<m; i++) 13738491ab44SLisandro Dalcin for (j=0; j<N; j++, k++) 13748491ab44SLisandro Dalcin iwork[k] = j; 13759566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer,iwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT)); 13769566063dSJacob Faibussowitsch PetscCall(PetscFree(iwork)); 13778491ab44SLisandro Dalcin } 13788491ab44SLisandro Dalcin /* store matrix values as a dense matrix in row major order */ 13799566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m*N,&vwork)); 13809566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(mat,&v)); 13819566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(mat,&lda)); 13828491ab44SLisandro Dalcin for (k=0, i=0; i<m; i++) 13838491ab44SLisandro Dalcin for (j=0; j<N; j++, k++) 13848491ab44SLisandro Dalcin vwork[k] = v[i+lda*j]; 13859566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(mat,&v)); 13869566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWriteAll(viewer,vwork,m*N,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR)); 13879566063dSJacob Faibussowitsch PetscCall(PetscFree(vwork)); 13888491ab44SLisandro Dalcin PetscFunctionReturn(0); 13898491ab44SLisandro Dalcin } 13908491ab44SLisandro Dalcin 13918491ab44SLisandro Dalcin PetscErrorCode MatLoad_Dense_Binary(Mat mat,PetscViewer viewer) 13928491ab44SLisandro Dalcin { 13938491ab44SLisandro Dalcin PetscBool skipHeader; 13948491ab44SLisandro Dalcin PetscInt header[4],M,N,m,nz,lda,i,j,k; 13958491ab44SLisandro Dalcin PetscInt rows,cols; 13968491ab44SLisandro Dalcin PetscScalar *v,*vwork; 13978491ab44SLisandro Dalcin 13988491ab44SLisandro Dalcin PetscFunctionBegin; 13999566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 14009566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryGetSkipHeader(viewer,&skipHeader)); 14018491ab44SLisandro Dalcin 14028491ab44SLisandro Dalcin if (!skipHeader) { 14039566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer,header,4,NULL,PETSC_INT)); 140408401ef6SPierre Jolivet PetscCheck(header[0] == MAT_FILE_CLASSID,PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Not a matrix object in file"); 14058491ab44SLisandro Dalcin M = header[1]; N = header[2]; 140608401ef6SPierre Jolivet PetscCheck(M >= 0,PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix row size (%" PetscInt_FMT ") in file is negative",M); 140708401ef6SPierre Jolivet PetscCheck(N >= 0,PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix column size (%" PetscInt_FMT ") in file is negative",N); 14088491ab44SLisandro Dalcin nz = header[3]; 1409aed4548fSBarry Smith PetscCheck(nz == MATRIX_BINARY_FORMAT_DENSE || nz >= 0,PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Unknown matrix format %" PetscInt_FMT " in file",nz); 1410aabbc4fbSShri Abhyankar } else { 14119566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat,&M,&N)); 1412aed4548fSBarry 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"); 14138491ab44SLisandro Dalcin nz = MATRIX_BINARY_FORMAT_DENSE; 1414e6324fbbSBarry Smith } 1415aabbc4fbSShri Abhyankar 14168491ab44SLisandro Dalcin /* setup global sizes if not set */ 14178491ab44SLisandro Dalcin if (mat->rmap->N < 0) mat->rmap->N = M; 14188491ab44SLisandro Dalcin if (mat->cmap->N < 0) mat->cmap->N = N; 14199566063dSJacob Faibussowitsch PetscCall(MatSetUp(mat)); 14208491ab44SLisandro Dalcin /* check if global sizes are correct */ 14219566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat,&rows,&cols)); 1422aed4548fSBarry 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); 1423aabbc4fbSShri Abhyankar 14249566063dSJacob Faibussowitsch PetscCall(MatGetSize(mat,NULL,&N)); 14259566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(mat,&m,NULL)); 14269566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(mat,&v)); 14279566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(mat,&lda)); 14288491ab44SLisandro Dalcin if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense format */ 14298491ab44SLisandro Dalcin PetscInt nnz = m*N; 14308491ab44SLisandro Dalcin /* read in matrix values */ 14319566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(nnz,&vwork)); 14329566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR)); 14338491ab44SLisandro Dalcin /* store values in column major order */ 14348491ab44SLisandro Dalcin for (j=0; j<N; j++) 14358491ab44SLisandro Dalcin for (i=0; i<m; i++) 14368491ab44SLisandro Dalcin v[i+lda*j] = vwork[i*N+j]; 14379566063dSJacob Faibussowitsch PetscCall(PetscFree(vwork)); 14388491ab44SLisandro Dalcin } else { /* matrix in file is sparse format */ 14398491ab44SLisandro Dalcin PetscInt nnz = 0, *rlens, *icols; 14408491ab44SLisandro Dalcin /* read in row lengths */ 14419566063dSJacob Faibussowitsch PetscCall(PetscMalloc1(m,&rlens)); 14429566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer,rlens,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT)); 14438491ab44SLisandro Dalcin for (i=0; i<m; i++) nnz += rlens[i]; 14448491ab44SLisandro Dalcin /* read in column indices and values */ 14459566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(nnz,&icols,nnz,&vwork)); 14469566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer,icols,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT)); 14479566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR)); 14488491ab44SLisandro Dalcin /* store values in column major order */ 14498491ab44SLisandro Dalcin for (k=0, i=0; i<m; i++) 14508491ab44SLisandro Dalcin for (j=0; j<rlens[i]; j++, k++) 14518491ab44SLisandro Dalcin v[i+lda*icols[k]] = vwork[k]; 14529566063dSJacob Faibussowitsch PetscCall(PetscFree(rlens)); 14539566063dSJacob Faibussowitsch PetscCall(PetscFree2(icols,vwork)); 1454aabbc4fbSShri Abhyankar } 14559566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(mat,&v)); 14569566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY)); 14579566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY)); 1458aabbc4fbSShri Abhyankar PetscFunctionReturn(0); 1459aabbc4fbSShri Abhyankar } 1460aabbc4fbSShri Abhyankar 1461eb91f321SVaclav Hapla PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer) 1462eb91f321SVaclav Hapla { 1463eb91f321SVaclav Hapla PetscBool isbinary, ishdf5; 1464eb91f321SVaclav Hapla 1465eb91f321SVaclav Hapla PetscFunctionBegin; 1466eb91f321SVaclav Hapla PetscValidHeaderSpecific(newMat,MAT_CLASSID,1); 1467eb91f321SVaclav Hapla PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 1468eb91f321SVaclav Hapla /* force binary viewer to load .info file if it has not yet done so */ 14699566063dSJacob Faibussowitsch PetscCall(PetscViewerSetUp(viewer)); 14709566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary)); 14719566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5, &ishdf5)); 1472eb91f321SVaclav Hapla if (isbinary) { 14739566063dSJacob Faibussowitsch PetscCall(MatLoad_Dense_Binary(newMat,viewer)); 1474eb91f321SVaclav Hapla } else if (ishdf5) { 1475eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5) 14769566063dSJacob Faibussowitsch PetscCall(MatLoad_Dense_HDF5(newMat,viewer)); 1477eb91f321SVaclav Hapla #else 1478eb91f321SVaclav Hapla SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5"); 1479eb91f321SVaclav Hapla #endif 1480eb91f321SVaclav Hapla } else { 148198921bdaSJacob 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); 1482eb91f321SVaclav Hapla } 1483eb91f321SVaclav Hapla PetscFunctionReturn(0); 1484eb91f321SVaclav Hapla } 1485eb91f321SVaclav Hapla 14866849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_ASCII(Mat A,PetscViewer viewer) 1487289bc588SBarry Smith { 1488932b0c3eSLois Curfman McInnes Mat_SeqDense *a = (Mat_SeqDense*)A->data; 148913f74950SBarry Smith PetscInt i,j; 14902dcb1b2aSMatthew Knepley const char *name; 1491ca15aa20SStefano Zampini PetscScalar *v,*av; 1492f3ef73ceSBarry Smith PetscViewerFormat format; 14935f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX) 1494ace3abfcSBarry Smith PetscBool allreal = PETSC_TRUE; 14955f481a85SSatish Balay #endif 1496932b0c3eSLois Curfman McInnes 14973a40ed3dSBarry Smith PetscFunctionBegin; 14989566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A,(const PetscScalar**)&av)); 14999566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer,&format)); 1500456192e2SBarry Smith if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 15013a40ed3dSBarry Smith PetscFunctionReturn(0); /* do nothing for now */ 1502fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 15039566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE)); 1504d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 1505ca15aa20SStefano Zampini v = av + i; 15069566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"row %" PetscInt_FMT ":",i)); 1507d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 1508aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 1509329f5518SBarry Smith if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) { 15109566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g + %g i) ",j,(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v))); 1511329f5518SBarry Smith } else if (PetscRealPart(*v)) { 15129566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g) ",j,(double)PetscRealPart(*v))); 15136831982aSBarry Smith } 151480cd9d93SLois Curfman McInnes #else 15156831982aSBarry Smith if (*v) { 15169566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g) ",j,(double)*v)); 15176831982aSBarry Smith } 151880cd9d93SLois Curfman McInnes #endif 15191b807ce4Svictorle v += a->lda; 152080cd9d93SLois Curfman McInnes } 15219566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"\n")); 152280cd9d93SLois Curfman McInnes } 15239566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE)); 15243a40ed3dSBarry Smith } else { 15259566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE)); 1526aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 152747989497SBarry Smith /* determine if matrix has all real values */ 1528bcd8d3a4SJose E. Roman for (j=0; j<A->cmap->n; j++) { 1529bcd8d3a4SJose E. Roman v = av + j*a->lda; 1530bcd8d3a4SJose E. Roman for (i=0; i<A->rmap->n; i++) { 1531ffac6cdbSBarry Smith if (PetscImaginaryPart(v[i])) { allreal = PETSC_FALSE; break;} 153247989497SBarry Smith } 1533bcd8d3a4SJose E. Roman } 153447989497SBarry Smith #endif 1535fb9695e5SSatish Balay if (format == PETSC_VIEWER_ASCII_MATLAB) { 15369566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)A,&name)); 15379566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"%% Size = %" PetscInt_FMT " %" PetscInt_FMT " \n",A->rmap->n,A->cmap->n)); 15389566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"%s = zeros(%" PetscInt_FMT ",%" PetscInt_FMT ");\n",name,A->rmap->n,A->cmap->n)); 15399566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"%s = [\n",name)); 1540ffac6cdbSBarry Smith } 1541ffac6cdbSBarry Smith 1542d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 1543ca15aa20SStefano Zampini v = av + i; 1544d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 1545aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 154647989497SBarry Smith if (allreal) { 15479566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)PetscRealPart(*v))); 154847989497SBarry Smith } else { 15499566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ei ",(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v))); 155047989497SBarry Smith } 1551289bc588SBarry Smith #else 15529566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)*v)); 1553289bc588SBarry Smith #endif 15541b807ce4Svictorle v += a->lda; 1555289bc588SBarry Smith } 15569566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"\n")); 1557289bc588SBarry Smith } 1558fb9695e5SSatish Balay if (format == PETSC_VIEWER_ASCII_MATLAB) { 15599566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"];\n")); 1560ffac6cdbSBarry Smith } 15619566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE)); 1562da3a660dSBarry Smith } 15639566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A,(const PetscScalar**)&av)); 15649566063dSJacob Faibussowitsch PetscCall(PetscViewerFlush(viewer)); 15653a40ed3dSBarry Smith PetscFunctionReturn(0); 1566289bc588SBarry Smith } 1567289bc588SBarry Smith 15689804daf3SBarry Smith #include <petscdraw.h> 1569e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw,void *Aa) 1570f1af5d2fSBarry Smith { 1571f1af5d2fSBarry Smith Mat A = (Mat) Aa; 1572383922c3SLisandro Dalcin PetscInt m = A->rmap->n,n = A->cmap->n,i,j; 1573383922c3SLisandro Dalcin int color = PETSC_DRAW_WHITE; 1574ca15aa20SStefano Zampini const PetscScalar *v; 1575b0a32e0cSBarry Smith PetscViewer viewer; 1576b05fc000SLisandro Dalcin PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r; 1577f3ef73ceSBarry Smith PetscViewerFormat format; 1578f1af5d2fSBarry Smith 1579f1af5d2fSBarry Smith PetscFunctionBegin; 15809566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer)); 15819566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer,&format)); 15829566063dSJacob Faibussowitsch PetscCall(PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr)); 1583f1af5d2fSBarry Smith 1584f1af5d2fSBarry Smith /* Loop over matrix elements drawing boxes */ 15859566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A,&v)); 1586fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 1587d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 1588f1af5d2fSBarry Smith /* Blue for negative and Red for positive */ 1589f1af5d2fSBarry Smith for (j = 0; j < n; j++) { 1590383922c3SLisandro Dalcin x_l = j; x_r = x_l + 1.0; 1591f1af5d2fSBarry Smith for (i = 0; i < m; i++) { 1592f1af5d2fSBarry Smith y_l = m - i - 1.0; 1593f1af5d2fSBarry Smith y_r = y_l + 1.0; 1594ca15aa20SStefano Zampini if (PetscRealPart(v[j*m+i]) > 0.) color = PETSC_DRAW_RED; 1595ca15aa20SStefano Zampini else if (PetscRealPart(v[j*m+i]) < 0.) color = PETSC_DRAW_BLUE; 1596ca15aa20SStefano Zampini else continue; 15979566063dSJacob Faibussowitsch PetscCall(PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color)); 1598f1af5d2fSBarry Smith } 1599f1af5d2fSBarry Smith } 1600d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 1601f1af5d2fSBarry Smith } else { 1602f1af5d2fSBarry Smith /* use contour shading to indicate magnitude of values */ 1603f1af5d2fSBarry Smith /* first determine max of all nonzero values */ 1604b05fc000SLisandro Dalcin PetscReal minv = 0.0, maxv = 0.0; 1605b05fc000SLisandro Dalcin PetscDraw popup; 1606b05fc000SLisandro Dalcin 1607f1af5d2fSBarry Smith for (i=0; i < m*n; i++) { 1608f1af5d2fSBarry Smith if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]); 1609f1af5d2fSBarry Smith } 1610383922c3SLisandro Dalcin if (minv >= maxv) maxv = minv + PETSC_SMALL; 16119566063dSJacob Faibussowitsch PetscCall(PetscDrawGetPopup(draw,&popup)); 16129566063dSJacob Faibussowitsch PetscCall(PetscDrawScalePopup(popup,minv,maxv)); 1613383922c3SLisandro Dalcin 1614d0609cedSBarry Smith PetscDrawCollectiveBegin(draw); 1615f1af5d2fSBarry Smith for (j=0; j<n; j++) { 1616f1af5d2fSBarry Smith x_l = j; 1617f1af5d2fSBarry Smith x_r = x_l + 1.0; 1618f1af5d2fSBarry Smith for (i=0; i<m; i++) { 1619f1af5d2fSBarry Smith y_l = m - i - 1.0; 1620f1af5d2fSBarry Smith y_r = y_l + 1.0; 1621b05fc000SLisandro Dalcin color = PetscDrawRealToColor(PetscAbsScalar(v[j*m+i]),minv,maxv); 16229566063dSJacob Faibussowitsch PetscCall(PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color)); 1623f1af5d2fSBarry Smith } 1624f1af5d2fSBarry Smith } 1625d0609cedSBarry Smith PetscDrawCollectiveEnd(draw); 1626f1af5d2fSBarry Smith } 16279566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A,&v)); 1628f1af5d2fSBarry Smith PetscFunctionReturn(0); 1629f1af5d2fSBarry Smith } 1630f1af5d2fSBarry Smith 1631e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw(Mat A,PetscViewer viewer) 1632f1af5d2fSBarry Smith { 1633b0a32e0cSBarry Smith PetscDraw draw; 1634ace3abfcSBarry Smith PetscBool isnull; 1635329f5518SBarry Smith PetscReal xr,yr,xl,yl,h,w; 1636f1af5d2fSBarry Smith 1637f1af5d2fSBarry Smith PetscFunctionBegin; 16389566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(viewer,0,&draw)); 16399566063dSJacob Faibussowitsch PetscCall(PetscDrawIsNull(draw,&isnull)); 1640abc0a331SBarry Smith if (isnull) PetscFunctionReturn(0); 1641f1af5d2fSBarry Smith 1642d0f46423SBarry Smith xr = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0; 1643f1af5d2fSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 16449566063dSJacob Faibussowitsch PetscCall(PetscDrawSetCoordinates(draw,xl,yl,xr,yr)); 16459566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer)); 16469566063dSJacob Faibussowitsch PetscCall(PetscDrawZoom(draw,MatView_SeqDense_Draw_Zoom,A)); 16479566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL)); 16489566063dSJacob Faibussowitsch PetscCall(PetscDrawSave(draw)); 1649f1af5d2fSBarry Smith PetscFunctionReturn(0); 1650f1af5d2fSBarry Smith } 1651f1af5d2fSBarry Smith 1652dfbe8321SBarry Smith PetscErrorCode MatView_SeqDense(Mat A,PetscViewer viewer) 1653932b0c3eSLois Curfman McInnes { 1654ace3abfcSBarry Smith PetscBool iascii,isbinary,isdraw; 1655932b0c3eSLois Curfman McInnes 16563a40ed3dSBarry Smith PetscFunctionBegin; 16579566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 16589566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary)); 16599566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw)); 16601baa6e33SBarry Smith if (iascii) PetscCall(MatView_SeqDense_ASCII(A,viewer)); 16611baa6e33SBarry Smith else if (isbinary) PetscCall(MatView_Dense_Binary(A,viewer)); 16621baa6e33SBarry Smith else if (isdraw) PetscCall(MatView_SeqDense_Draw(A,viewer)); 16633a40ed3dSBarry Smith PetscFunctionReturn(0); 1664932b0c3eSLois Curfman McInnes } 1665289bc588SBarry Smith 1666637a0070SStefano Zampini static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A,const PetscScalar *array) 1667d3042a70SBarry Smith { 1668d3042a70SBarry Smith Mat_SeqDense *a = (Mat_SeqDense*)A->data; 1669d3042a70SBarry Smith 1670d3042a70SBarry Smith PetscFunctionBegin; 167128b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first"); 167228b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first"); 167328b400f6SJacob Faibussowitsch PetscCheck(!a->unplacedarray,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreArray() first"); 1674d3042a70SBarry Smith a->unplacedarray = a->v; 1675d3042a70SBarry Smith a->unplaced_user_alloc = a->user_alloc; 1676d3042a70SBarry Smith a->v = (PetscScalar*) array; 1677637a0070SStefano Zampini a->user_alloc = PETSC_TRUE; 1678ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA) 1679c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_CPU; 1680ca15aa20SStefano Zampini #endif 1681d3042a70SBarry Smith PetscFunctionReturn(0); 1682d3042a70SBarry Smith } 1683d3042a70SBarry Smith 1684d3042a70SBarry Smith static PetscErrorCode MatDenseResetArray_SeqDense(Mat A) 1685d3042a70SBarry Smith { 1686d3042a70SBarry Smith Mat_SeqDense *a = (Mat_SeqDense*)A->data; 1687d3042a70SBarry Smith 1688d3042a70SBarry Smith PetscFunctionBegin; 168928b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first"); 169028b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first"); 1691d3042a70SBarry Smith a->v = a->unplacedarray; 1692d3042a70SBarry Smith a->user_alloc = a->unplaced_user_alloc; 1693d3042a70SBarry Smith a->unplacedarray = NULL; 1694ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA) 1695c70f7ee4SJunchao Zhang A->offloadmask = PETSC_OFFLOAD_CPU; 1696ca15aa20SStefano Zampini #endif 1697d3042a70SBarry Smith PetscFunctionReturn(0); 1698d3042a70SBarry Smith } 1699d3042a70SBarry Smith 1700d5ea218eSStefano Zampini static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A,const PetscScalar *array) 1701d5ea218eSStefano Zampini { 1702d5ea218eSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense*)A->data; 1703d5ea218eSStefano Zampini 1704d5ea218eSStefano Zampini PetscFunctionBegin; 170528b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first"); 170628b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first"); 17079566063dSJacob Faibussowitsch if (!a->user_alloc) PetscCall(PetscFree(a->v)); 1708d5ea218eSStefano Zampini a->v = (PetscScalar*) array; 1709d5ea218eSStefano Zampini a->user_alloc = PETSC_FALSE; 1710d5ea218eSStefano Zampini #if defined(PETSC_HAVE_CUDA) 1711d5ea218eSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 1712d5ea218eSStefano Zampini #endif 1713d5ea218eSStefano Zampini PetscFunctionReturn(0); 1714d5ea218eSStefano Zampini } 1715d5ea218eSStefano Zampini 1716ca15aa20SStefano Zampini PetscErrorCode MatDestroy_SeqDense(Mat mat) 1717289bc588SBarry Smith { 1718ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense*)mat->data; 171990f02eecSBarry Smith 17203a40ed3dSBarry Smith PetscFunctionBegin; 1721aa482453SBarry Smith #if defined(PETSC_USE_LOG) 1722c0aa6a63SJacob Faibussowitsch PetscLogObjectState((PetscObject)mat,"Rows %" PetscInt_FMT " Cols %" PetscInt_FMT,mat->rmap->n,mat->cmap->n); 1723a5a9c739SBarry Smith #endif 17249566063dSJacob Faibussowitsch PetscCall(VecDestroy(&(l->qrrhs))); 17259566063dSJacob Faibussowitsch PetscCall(PetscFree(l->tau)); 17269566063dSJacob Faibussowitsch PetscCall(PetscFree(l->pivots)); 17279566063dSJacob Faibussowitsch PetscCall(PetscFree(l->fwork)); 17289566063dSJacob Faibussowitsch PetscCall(MatDestroy(&l->ptapwork)); 17299566063dSJacob Faibussowitsch if (!l->user_alloc) PetscCall(PetscFree(l->v)); 17309566063dSJacob Faibussowitsch if (!l->unplaced_user_alloc) PetscCall(PetscFree(l->unplacedarray)); 173128b400f6SJacob Faibussowitsch PetscCheck(!l->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first"); 173228b400f6SJacob Faibussowitsch PetscCheck(!l->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first"); 17339566063dSJacob Faibussowitsch PetscCall(VecDestroy(&l->cvec)); 17349566063dSJacob Faibussowitsch PetscCall(MatDestroy(&l->cmat)); 17359566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->data)); 1736dbd8c25aSHong Zhang 17379566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)mat,NULL)); 17389566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatQRFactor_C",NULL)); 17392e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatQRFactorSymbolic_C",NULL)); 17402e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatQRFactorNumeric_C",NULL)); 17419566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetLDA_C",NULL)); 17429566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseSetLDA_C",NULL)); 17439566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArray_C",NULL)); 17449566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArray_C",NULL)); 17459566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDensePlaceArray_C",NULL)); 17469566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseResetArray_C",NULL)); 17479566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseReplaceArray_C",NULL)); 17489566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArrayRead_C",NULL)); 17499566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArrayRead_C",NULL)); 17509566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArrayWrite_C",NULL)); 17519566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArrayWrite_C",NULL)); 17529566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqaij_C",NULL)); 17538baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 17549566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_elemental_C",NULL)); 17558baccfbdSHong Zhang #endif 1756d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 17579566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_scalapack_C",NULL)); 1758d24d4204SJose E. Roman #endif 17592bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA) 17609566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqdensecuda_C",NULL)); 17619566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",NULL)); 17629566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdense_C",NULL)); 17632e956fe4SStefano Zampini PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdense_seqdensecuda_C",NULL)); 17642bf066beSStefano Zampini #endif 17659566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatSeqDenseSetPreallocation_C",NULL)); 17669566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqaij_seqdense_C",NULL)); 17679566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdense_seqdense_C",NULL)); 17689566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqbaij_seqdense_C",NULL)); 17699566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqsbaij_seqdense_C",NULL)); 177052c5f739Sprj- 17719566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumn_C",NULL)); 17729566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumn_C",NULL)); 17739566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVec_C",NULL)); 17749566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVec_C",NULL)); 17759566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVecRead_C",NULL)); 17769566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVecRead_C",NULL)); 17779566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVecWrite_C",NULL)); 17789566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVecWrite_C",NULL)); 17799566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetSubMatrix_C",NULL)); 17809566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreSubMatrix_C",NULL)); 17813a40ed3dSBarry Smith PetscFunctionReturn(0); 1782289bc588SBarry Smith } 1783289bc588SBarry Smith 1784e0877f53SBarry Smith static PetscErrorCode MatTranspose_SeqDense(Mat A,MatReuse reuse,Mat *matout) 1785289bc588SBarry Smith { 1786c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 17876536e3caSStefano Zampini PetscInt k,j,m = A->rmap->n, M = mat->lda, n = A->cmap->n; 178887828ca2SBarry Smith PetscScalar *v,tmp; 178948b35521SBarry Smith 17903a40ed3dSBarry Smith PetscFunctionBegin; 17916536e3caSStefano Zampini if (reuse == MAT_INPLACE_MATRIX) { 17926536e3caSStefano Zampini if (m == n) { /* in place transpose */ 17939566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A,&v)); 1794d3e5ee88SLois Curfman McInnes for (j=0; j<m; j++) { 1795289bc588SBarry Smith for (k=0; k<j; k++) { 17961b807ce4Svictorle tmp = v[j + k*M]; 17971b807ce4Svictorle v[j + k*M] = v[k + j*M]; 17981b807ce4Svictorle v[k + j*M] = tmp; 1799289bc588SBarry Smith } 1800289bc588SBarry Smith } 18019566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A,&v)); 18026536e3caSStefano Zampini } else { /* reuse memory, temporary allocates new memory */ 18036536e3caSStefano Zampini PetscScalar *v2; 18046536e3caSStefano Zampini PetscLayout tmplayout; 18056536e3caSStefano Zampini 18069566063dSJacob Faibussowitsch PetscCall(PetscMalloc1((size_t)m*n,&v2)); 18079566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A,&v)); 18086536e3caSStefano Zampini for (j=0; j<n; j++) { 18096536e3caSStefano Zampini for (k=0; k<m; k++) v2[j + (size_t)k*n] = v[k + (size_t)j*M]; 18106536e3caSStefano Zampini } 18119566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(v,v2,(size_t)m*n)); 18129566063dSJacob Faibussowitsch PetscCall(PetscFree(v2)); 18139566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A,&v)); 18146536e3caSStefano Zampini /* cleanup size dependent quantities */ 18159566063dSJacob Faibussowitsch PetscCall(VecDestroy(&mat->cvec)); 18169566063dSJacob Faibussowitsch PetscCall(MatDestroy(&mat->cmat)); 18179566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->pivots)); 18189566063dSJacob Faibussowitsch PetscCall(PetscFree(mat->fwork)); 18199566063dSJacob Faibussowitsch PetscCall(MatDestroy(&mat->ptapwork)); 18206536e3caSStefano Zampini /* swap row/col layouts */ 18216536e3caSStefano Zampini mat->lda = n; 18226536e3caSStefano Zampini tmplayout = A->rmap; 18236536e3caSStefano Zampini A->rmap = A->cmap; 18246536e3caSStefano Zampini A->cmap = tmplayout; 18256536e3caSStefano Zampini } 18263a40ed3dSBarry Smith } else { /* out-of-place transpose */ 1827d3e5ee88SLois Curfman McInnes Mat tmat; 1828ec8511deSBarry Smith Mat_SeqDense *tmatd; 182987828ca2SBarry Smith PetscScalar *v2; 1830af36a384SStefano Zampini PetscInt M2; 1831ea709b57SSatish Balay 18326536e3caSStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 18339566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&tmat)); 18349566063dSJacob Faibussowitsch PetscCall(MatSetSizes(tmat,A->cmap->n,A->rmap->n,A->cmap->n,A->rmap->n)); 18359566063dSJacob Faibussowitsch PetscCall(MatSetType(tmat,((PetscObject)A)->type_name)); 18369566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(tmat,NULL)); 1837ca15aa20SStefano Zampini } else tmat = *matout; 1838ca15aa20SStefano Zampini 18399566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A,(const PetscScalar**)&v)); 18409566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(tmat,&v2)); 1841ec8511deSBarry Smith tmatd = (Mat_SeqDense*)tmat->data; 1842ca15aa20SStefano Zampini M2 = tmatd->lda; 1843d3e5ee88SLois Curfman McInnes for (j=0; j<n; j++) { 1844af36a384SStefano Zampini for (k=0; k<m; k++) v2[j + k*M2] = v[k + j*M]; 1845d3e5ee88SLois Curfman McInnes } 18469566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(tmat,&v2)); 18479566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A,(const PetscScalar**)&v)); 18489566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY)); 18499566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY)); 18506536e3caSStefano Zampini *matout = tmat; 185148b35521SBarry Smith } 18523a40ed3dSBarry Smith PetscFunctionReturn(0); 1853289bc588SBarry Smith } 1854289bc588SBarry Smith 1855e0877f53SBarry Smith static PetscErrorCode MatEqual_SeqDense(Mat A1,Mat A2,PetscBool *flg) 1856289bc588SBarry Smith { 1857c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat1 = (Mat_SeqDense*)A1->data; 1858c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat2 = (Mat_SeqDense*)A2->data; 1859ca15aa20SStefano Zampini PetscInt i; 1860ca15aa20SStefano Zampini const PetscScalar *v1,*v2; 18619ea5d5aeSSatish Balay 18623a40ed3dSBarry Smith PetscFunctionBegin; 1863d0f46423SBarry Smith if (A1->rmap->n != A2->rmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);} 1864d0f46423SBarry Smith if (A1->cmap->n != A2->cmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);} 18659566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A1,&v1)); 18669566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A2,&v2)); 1867ca15aa20SStefano Zampini for (i=0; i<A1->cmap->n; i++) { 18689566063dSJacob Faibussowitsch PetscCall(PetscArraycmp(v1,v2,A1->rmap->n,flg)); 1869ca15aa20SStefano Zampini if (*flg == PETSC_FALSE) PetscFunctionReturn(0); 1870ca15aa20SStefano Zampini v1 += mat1->lda; 1871ca15aa20SStefano Zampini v2 += mat2->lda; 18721b807ce4Svictorle } 18739566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A1,&v1)); 18749566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A2,&v2)); 187577c4ece6SBarry Smith *flg = PETSC_TRUE; 18763a40ed3dSBarry Smith PetscFunctionReturn(0); 1877289bc588SBarry Smith } 1878289bc588SBarry Smith 1879e0877f53SBarry Smith static PetscErrorCode MatGetDiagonal_SeqDense(Mat A,Vec v) 1880289bc588SBarry Smith { 1881c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 188213f74950SBarry Smith PetscInt i,n,len; 1883ca15aa20SStefano Zampini PetscScalar *x; 1884ca15aa20SStefano Zampini const PetscScalar *vv; 188544cd7ae7SLois Curfman McInnes 18863a40ed3dSBarry Smith PetscFunctionBegin; 18879566063dSJacob Faibussowitsch PetscCall(VecGetSize(v,&n)); 18889566063dSJacob Faibussowitsch PetscCall(VecGetArray(v,&x)); 1889d0f46423SBarry Smith len = PetscMin(A->rmap->n,A->cmap->n); 18909566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A,&vv)); 189108401ef6SPierre Jolivet PetscCheck(n == A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming mat and vec"); 189244cd7ae7SLois Curfman McInnes for (i=0; i<len; i++) { 1893ca15aa20SStefano Zampini x[i] = vv[i*mat->lda + i]; 1894289bc588SBarry Smith } 18959566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A,&vv)); 18969566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v,&x)); 18973a40ed3dSBarry Smith PetscFunctionReturn(0); 1898289bc588SBarry Smith } 1899289bc588SBarry Smith 1900e0877f53SBarry Smith static PetscErrorCode MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr) 1901289bc588SBarry Smith { 1902c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 1903f1ceaac6SMatthew G. Knepley const PetscScalar *l,*r; 1904ca15aa20SStefano Zampini PetscScalar x,*v,*vv; 1905d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n; 190655659b69SBarry Smith 19073a40ed3dSBarry Smith PetscFunctionBegin; 19089566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A,&vv)); 190928988994SBarry Smith if (ll) { 19109566063dSJacob Faibussowitsch PetscCall(VecGetSize(ll,&m)); 19119566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(ll,&l)); 191208401ef6SPierre Jolivet PetscCheck(m == A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vec wrong size"); 1913da3a660dSBarry Smith for (i=0; i<m; i++) { 1914da3a660dSBarry Smith x = l[i]; 1915ca15aa20SStefano Zampini v = vv + i; 1916b43bac26SStefano Zampini for (j=0; j<n; j++) { (*v) *= x; v+= mat->lda;} 1917da3a660dSBarry Smith } 19189566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(ll,&l)); 19199566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0*n*m)); 1920da3a660dSBarry Smith } 192128988994SBarry Smith if (rr) { 19229566063dSJacob Faibussowitsch PetscCall(VecGetSize(rr,&n)); 19239566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(rr,&r)); 192408401ef6SPierre Jolivet PetscCheck(n == A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vec wrong size"); 1925da3a660dSBarry Smith for (i=0; i<n; i++) { 1926da3a660dSBarry Smith x = r[i]; 1927ca15aa20SStefano Zampini v = vv + i*mat->lda; 19282205254eSKarl Rupp for (j=0; j<m; j++) (*v++) *= x; 1929da3a660dSBarry Smith } 19309566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(rr,&r)); 19319566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0*n*m)); 1932da3a660dSBarry Smith } 19339566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A,&vv)); 19343a40ed3dSBarry Smith PetscFunctionReturn(0); 1935289bc588SBarry Smith } 1936289bc588SBarry Smith 1937ca15aa20SStefano Zampini PetscErrorCode MatNorm_SeqDense(Mat A,NormType type,PetscReal *nrm) 1938289bc588SBarry Smith { 1939c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 1940ca15aa20SStefano Zampini PetscScalar *v,*vv; 1941329f5518SBarry Smith PetscReal sum = 0.0; 194275f6d85dSStefano Zampini PetscInt lda, m=A->rmap->n,i,j; 194355659b69SBarry Smith 19443a40ed3dSBarry Smith PetscFunctionBegin; 19459566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A,(const PetscScalar**)&vv)); 19469566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(A,&lda)); 1947ca15aa20SStefano Zampini v = vv; 1948289bc588SBarry Smith if (type == NORM_FROBENIUS) { 1949a5ce6ee0Svictorle if (lda>m) { 1950d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 1951ca15aa20SStefano Zampini v = vv+j*lda; 1952a5ce6ee0Svictorle for (i=0; i<m; i++) { 1953a5ce6ee0Svictorle sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 1954a5ce6ee0Svictorle } 1955a5ce6ee0Svictorle } 1956a5ce6ee0Svictorle } else { 1957570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16) 1958570b7f6dSBarry Smith PetscBLASInt one = 1,cnt = A->cmap->n*A->rmap->n; 195973cf7048SBarry Smith PetscStackCallBLAS("BLASnrm2",*nrm = BLASnrm2_(&cnt,v,&one)); 1960570b7f6dSBarry Smith } 1961570b7f6dSBarry Smith #else 1962d0f46423SBarry Smith for (i=0; i<A->cmap->n*A->rmap->n; i++) { 1963329f5518SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 1964289bc588SBarry Smith } 1965a5ce6ee0Svictorle } 19668f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 1967570b7f6dSBarry Smith #endif 19689566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(2.0*A->cmap->n*A->rmap->n)); 19693a40ed3dSBarry Smith } else if (type == NORM_1) { 1970064f8208SBarry Smith *nrm = 0.0; 1971d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 1972ca15aa20SStefano Zampini v = vv + j*mat->lda; 1973289bc588SBarry Smith sum = 0.0; 1974d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 197533a8263dSBarry Smith sum += PetscAbsScalar(*v); v++; 1976289bc588SBarry Smith } 1977064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 1978289bc588SBarry Smith } 19799566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0*A->cmap->n*A->rmap->n)); 19803a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 1981064f8208SBarry Smith *nrm = 0.0; 1982d0f46423SBarry Smith for (j=0; j<A->rmap->n; j++) { 1983ca15aa20SStefano Zampini v = vv + j; 1984289bc588SBarry Smith sum = 0.0; 1985d0f46423SBarry Smith for (i=0; i<A->cmap->n; i++) { 19861b807ce4Svictorle sum += PetscAbsScalar(*v); v += mat->lda; 1987289bc588SBarry Smith } 1988064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 1989289bc588SBarry Smith } 19909566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0*A->cmap->n*A->rmap->n)); 1991e7e72b3dSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No two norm"); 19929566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A,(const PetscScalar**)&vv)); 19933a40ed3dSBarry Smith PetscFunctionReturn(0); 1994289bc588SBarry Smith } 1995289bc588SBarry Smith 1996e0877f53SBarry Smith static PetscErrorCode MatSetOption_SeqDense(Mat A,MatOption op,PetscBool flg) 1997289bc588SBarry Smith { 1998c0bbcb79SLois Curfman McInnes Mat_SeqDense *aij = (Mat_SeqDense*)A->data; 199967e560aaSBarry Smith 20003a40ed3dSBarry Smith PetscFunctionBegin; 2001b5a2b587SKris Buschelman switch (op) { 2002b5a2b587SKris Buschelman case MAT_ROW_ORIENTED: 20034e0d8c25SBarry Smith aij->roworiented = flg; 2004b5a2b587SKris Buschelman break; 2005512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 2006b5a2b587SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 20073971808eSMatthew Knepley case MAT_NEW_NONZERO_ALLOCATION_ERR: 20088c78258cSHong Zhang case MAT_FORCE_DIAGONAL_ENTRIES: 200913fa8e87SLisandro Dalcin case MAT_KEEP_NONZERO_PATTERN: 2010b5a2b587SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 2011b5a2b587SKris Buschelman case MAT_USE_HASH_TABLE: 20120f8fb01aSBarry Smith case MAT_IGNORE_ZERO_ENTRIES: 20135021d80fSJed Brown case MAT_IGNORE_LOWER_TRIANGULAR: 2014071fcb05SBarry Smith case MAT_SORTED_FULL: 20159566063dSJacob Faibussowitsch PetscCall(PetscInfo(A,"Option %s ignored\n",MatOptions[op])); 20165021d80fSJed Brown break; 20175021d80fSJed Brown case MAT_SPD: 201877e54ba9SKris Buschelman case MAT_SYMMETRIC: 201977e54ba9SKris Buschelman case MAT_STRUCTURALLY_SYMMETRIC: 20209a4540c5SBarry Smith case MAT_HERMITIAN: 20219a4540c5SBarry Smith case MAT_SYMMETRY_ETERNAL: 20225021d80fSJed Brown /* These options are handled directly by MatSetOption() */ 202377e54ba9SKris Buschelman break; 2024b5a2b587SKris Buschelman default: 202598921bdaSJacob Faibussowitsch SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %s",MatOptions[op]); 20263a40ed3dSBarry Smith } 20273a40ed3dSBarry Smith PetscFunctionReturn(0); 2028289bc588SBarry Smith } 2029289bc588SBarry Smith 20303d8925e7SStefano Zampini PetscErrorCode MatZeroEntries_SeqDense(Mat A) 20316f0a148fSBarry Smith { 2032ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense*)A->data; 20333d8925e7SStefano Zampini PetscInt lda=l->lda,m=A->rmap->n,n=A->cmap->n,j; 2034ca15aa20SStefano Zampini PetscScalar *v; 20353a40ed3dSBarry Smith 20363a40ed3dSBarry Smith PetscFunctionBegin; 20379566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(A,&v)); 2038a5ce6ee0Svictorle if (lda>m) { 20393d8925e7SStefano Zampini for (j=0; j<n; j++) { 20409566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(v+j*lda,m)); 2041a5ce6ee0Svictorle } 2042a5ce6ee0Svictorle } else { 20439566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(v,PetscInt64Mult(m,n))); 2044a5ce6ee0Svictorle } 20459566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(A,&v)); 20463a40ed3dSBarry Smith PetscFunctionReturn(0); 20476f0a148fSBarry Smith } 20486f0a148fSBarry Smith 2049e0877f53SBarry Smith static PetscErrorCode MatZeroRows_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 20506f0a148fSBarry Smith { 2051ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense*)A->data; 2052b9679d65SBarry Smith PetscInt m = l->lda, n = A->cmap->n, i,j; 2053ca15aa20SStefano Zampini PetscScalar *slot,*bb,*v; 205497b48c8fSBarry Smith const PetscScalar *xx; 205555659b69SBarry Smith 20563a40ed3dSBarry Smith PetscFunctionBegin; 205776bd3646SJed Brown if (PetscDefined(USE_DEBUG)) { 2058b9679d65SBarry Smith for (i=0; i<N; i++) { 205908401ef6SPierre Jolivet PetscCheck(rows[i] >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed"); 206008401ef6SPierre 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); 2061b9679d65SBarry Smith } 206276bd3646SJed Brown } 2063ca15aa20SStefano Zampini if (!N) PetscFunctionReturn(0); 2064b9679d65SBarry Smith 206597b48c8fSBarry Smith /* fix right hand side if needed */ 206697b48c8fSBarry Smith if (x && b) { 20679566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x,&xx)); 20689566063dSJacob Faibussowitsch PetscCall(VecGetArray(b,&bb)); 20692205254eSKarl Rupp for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]]; 20709566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x,&xx)); 20719566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(b,&bb)); 207297b48c8fSBarry Smith } 207397b48c8fSBarry Smith 20749566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A,&v)); 20756f0a148fSBarry Smith for (i=0; i<N; i++) { 2076ca15aa20SStefano Zampini slot = v + rows[i]; 2077b9679d65SBarry Smith for (j=0; j<n; j++) { *slot = 0.0; slot += m;} 20786f0a148fSBarry Smith } 2079f4df32b1SMatthew Knepley if (diag != 0.0) { 208008401ef6SPierre Jolivet PetscCheck(A->rmap->n == A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices"); 20816f0a148fSBarry Smith for (i=0; i<N; i++) { 2082ca15aa20SStefano Zampini slot = v + (m+1)*rows[i]; 2083f4df32b1SMatthew Knepley *slot = diag; 20846f0a148fSBarry Smith } 20856f0a148fSBarry Smith } 20869566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A,&v)); 20873a40ed3dSBarry Smith PetscFunctionReturn(0); 20886f0a148fSBarry Smith } 2089557bce09SLois Curfman McInnes 209049a6ff4bSBarry Smith static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A,PetscInt *lda) 209149a6ff4bSBarry Smith { 209249a6ff4bSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 209349a6ff4bSBarry Smith 209449a6ff4bSBarry Smith PetscFunctionBegin; 209549a6ff4bSBarry Smith *lda = mat->lda; 209649a6ff4bSBarry Smith PetscFunctionReturn(0); 209749a6ff4bSBarry Smith } 209849a6ff4bSBarry Smith 2099637a0070SStefano Zampini PetscErrorCode MatDenseGetArray_SeqDense(Mat A,PetscScalar **array) 210064e87e97SBarry Smith { 2101c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 21023a40ed3dSBarry Smith 21033a40ed3dSBarry Smith PetscFunctionBegin; 210428b400f6SJacob Faibussowitsch PetscCheck(!mat->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first"); 210564e87e97SBarry Smith *array = mat->v; 21063a40ed3dSBarry Smith PetscFunctionReturn(0); 210764e87e97SBarry Smith } 21080754003eSLois Curfman McInnes 2109637a0070SStefano Zampini PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A,PetscScalar **array) 2110ff14e315SSatish Balay { 21113a40ed3dSBarry Smith PetscFunctionBegin; 211275f6d85dSStefano Zampini if (array) *array = NULL; 21133a40ed3dSBarry Smith PetscFunctionReturn(0); 2114ff14e315SSatish Balay } 21150754003eSLois Curfman McInnes 21160f74d2c1SSatish Balay /*@ 211749a6ff4bSBarry Smith MatDenseGetLDA - gets the leading dimension of the array returned from MatDenseGetArray() 211849a6ff4bSBarry Smith 2119ad16ce7aSStefano Zampini Not collective 212049a6ff4bSBarry Smith 212149a6ff4bSBarry Smith Input Parameter: 212249a6ff4bSBarry Smith . mat - a MATSEQDENSE or MATMPIDENSE matrix 212349a6ff4bSBarry Smith 212449a6ff4bSBarry Smith Output Parameter: 212549a6ff4bSBarry Smith . lda - the leading dimension 212649a6ff4bSBarry Smith 212749a6ff4bSBarry Smith Level: intermediate 212849a6ff4bSBarry Smith 2129db781477SPatrick Sanan .seealso: `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseSetLDA()` 213049a6ff4bSBarry Smith @*/ 213149a6ff4bSBarry Smith PetscErrorCode MatDenseGetLDA(Mat A,PetscInt *lda) 213249a6ff4bSBarry Smith { 213349a6ff4bSBarry Smith PetscFunctionBegin; 2134d5ea218eSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2135dadcf809SJacob Faibussowitsch PetscValidIntPointer(lda,2); 213675f6d85dSStefano Zampini MatCheckPreallocated(A,1); 2137cac4c232SBarry Smith PetscUseMethod(A,"MatDenseGetLDA_C",(Mat,PetscInt*),(A,lda)); 213849a6ff4bSBarry Smith PetscFunctionReturn(0); 213949a6ff4bSBarry Smith } 214049a6ff4bSBarry Smith 21410f74d2c1SSatish Balay /*@ 2142ad16ce7aSStefano Zampini MatDenseSetLDA - Sets the leading dimension of the array used by the dense matrix 2143ad16ce7aSStefano Zampini 2144ad16ce7aSStefano Zampini Not collective 2145ad16ce7aSStefano Zampini 2146d8d19677SJose E. Roman Input Parameters: 2147ad16ce7aSStefano Zampini + mat - a MATSEQDENSE or MATMPIDENSE matrix 2148ad16ce7aSStefano Zampini - lda - the leading dimension 2149ad16ce7aSStefano Zampini 2150ad16ce7aSStefano Zampini Level: intermediate 2151ad16ce7aSStefano Zampini 2152db781477SPatrick Sanan .seealso: `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetLDA()` 2153ad16ce7aSStefano Zampini @*/ 2154ad16ce7aSStefano Zampini PetscErrorCode MatDenseSetLDA(Mat A,PetscInt lda) 2155ad16ce7aSStefano Zampini { 2156ad16ce7aSStefano Zampini PetscFunctionBegin; 2157ad16ce7aSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2158cac4c232SBarry Smith PetscTryMethod(A,"MatDenseSetLDA_C",(Mat,PetscInt),(A,lda)); 2159ad16ce7aSStefano Zampini PetscFunctionReturn(0); 2160ad16ce7aSStefano Zampini } 2161ad16ce7aSStefano Zampini 2162ad16ce7aSStefano Zampini /*@C 21636947451fSStefano Zampini MatDenseGetArray - gives read-write access to the array where the data for a dense matrix is stored 216473a71a0fSBarry Smith 21658572280aSBarry Smith Logically Collective on Mat 216673a71a0fSBarry Smith 216773a71a0fSBarry Smith Input Parameter: 21686947451fSStefano Zampini . mat - a dense matrix 216973a71a0fSBarry Smith 217073a71a0fSBarry Smith Output Parameter: 217173a71a0fSBarry Smith . array - pointer to the data 217273a71a0fSBarry Smith 217373a71a0fSBarry Smith Level: intermediate 217473a71a0fSBarry Smith 2175db781477SPatrick Sanan .seealso: `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 217673a71a0fSBarry Smith @*/ 21778c778c55SBarry Smith PetscErrorCode MatDenseGetArray(Mat A,PetscScalar **array) 217873a71a0fSBarry Smith { 217973a71a0fSBarry Smith PetscFunctionBegin; 2180d5ea218eSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2181d5ea218eSStefano Zampini PetscValidPointer(array,2); 2182cac4c232SBarry Smith PetscUseMethod(A,"MatDenseGetArray_C",(Mat,PetscScalar**),(A,array)); 218373a71a0fSBarry Smith PetscFunctionReturn(0); 218473a71a0fSBarry Smith } 218573a71a0fSBarry Smith 2186dec5eb66SMatthew G Knepley /*@C 2187579dbff0SBarry Smith MatDenseRestoreArray - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray() 218873a71a0fSBarry Smith 21898572280aSBarry Smith Logically Collective on Mat 21908572280aSBarry Smith 21918572280aSBarry Smith Input Parameters: 21926947451fSStefano Zampini + mat - a dense matrix 2193a2b725a8SWilliam Gropp - array - pointer to the data 21948572280aSBarry Smith 21958572280aSBarry Smith Level: intermediate 21968572280aSBarry Smith 2197db781477SPatrick Sanan .seealso: `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 21988572280aSBarry Smith @*/ 21998572280aSBarry Smith PetscErrorCode MatDenseRestoreArray(Mat A,PetscScalar **array) 22008572280aSBarry Smith { 22018572280aSBarry Smith PetscFunctionBegin; 2202d5ea218eSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2203d5ea218eSStefano Zampini PetscValidPointer(array,2); 2204cac4c232SBarry Smith PetscUseMethod(A,"MatDenseRestoreArray_C",(Mat,PetscScalar**),(A,array)); 22059566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)A)); 2206637a0070SStefano Zampini #if defined(PETSC_HAVE_CUDA) 2207637a0070SStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 2208637a0070SStefano Zampini #endif 22098572280aSBarry Smith PetscFunctionReturn(0); 22108572280aSBarry Smith } 22118572280aSBarry Smith 22128572280aSBarry Smith /*@C 22136947451fSStefano Zampini MatDenseGetArrayRead - gives read-only access to the array where the data for a dense matrix is stored 22148572280aSBarry Smith 22158572280aSBarry Smith Not Collective 22168572280aSBarry Smith 22178572280aSBarry Smith Input Parameter: 22186947451fSStefano Zampini . mat - a dense matrix 22198572280aSBarry Smith 22208572280aSBarry Smith Output Parameter: 22218572280aSBarry Smith . array - pointer to the data 22228572280aSBarry Smith 22238572280aSBarry Smith Level: intermediate 22248572280aSBarry Smith 2225db781477SPatrick Sanan .seealso: `MatDenseRestoreArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 22268572280aSBarry Smith @*/ 22278572280aSBarry Smith PetscErrorCode MatDenseGetArrayRead(Mat A,const PetscScalar **array) 22288572280aSBarry Smith { 22298572280aSBarry Smith PetscFunctionBegin; 2230d5ea218eSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2231d5ea218eSStefano Zampini PetscValidPointer(array,2); 2232cac4c232SBarry Smith PetscUseMethod(A,"MatDenseGetArrayRead_C",(Mat,const PetscScalar**),(A,array)); 22338572280aSBarry Smith PetscFunctionReturn(0); 22348572280aSBarry Smith } 22358572280aSBarry Smith 22368572280aSBarry Smith /*@C 22376947451fSStefano Zampini MatDenseRestoreArrayRead - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArrayRead() 22388572280aSBarry Smith 223973a71a0fSBarry Smith Not Collective 224073a71a0fSBarry Smith 224173a71a0fSBarry Smith Input Parameters: 22426947451fSStefano Zampini + mat - a dense matrix 2243a2b725a8SWilliam Gropp - array - pointer to the data 224473a71a0fSBarry Smith 224573a71a0fSBarry Smith Level: intermediate 224673a71a0fSBarry Smith 2247db781477SPatrick Sanan .seealso: `MatDenseGetArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()` 224873a71a0fSBarry Smith @*/ 22498572280aSBarry Smith PetscErrorCode MatDenseRestoreArrayRead(Mat A,const PetscScalar **array) 225073a71a0fSBarry Smith { 225173a71a0fSBarry Smith PetscFunctionBegin; 2252d5ea218eSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2253d5ea218eSStefano Zampini PetscValidPointer(array,2); 2254cac4c232SBarry Smith PetscUseMethod(A,"MatDenseRestoreArrayRead_C",(Mat,const PetscScalar**),(A,array)); 225573a71a0fSBarry Smith PetscFunctionReturn(0); 225673a71a0fSBarry Smith } 225773a71a0fSBarry Smith 22586947451fSStefano Zampini /*@C 22596947451fSStefano Zampini MatDenseGetArrayWrite - gives write-only access to the array where the data for a dense matrix is stored 22606947451fSStefano Zampini 22616947451fSStefano Zampini Not Collective 22626947451fSStefano Zampini 22636947451fSStefano Zampini Input Parameter: 22646947451fSStefano Zampini . mat - a dense matrix 22656947451fSStefano Zampini 22666947451fSStefano Zampini Output Parameter: 22676947451fSStefano Zampini . array - pointer to the data 22686947451fSStefano Zampini 22696947451fSStefano Zampini Level: intermediate 22706947451fSStefano Zampini 2271db781477SPatrick Sanan .seealso: `MatDenseRestoreArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()` 22726947451fSStefano Zampini @*/ 22736947451fSStefano Zampini PetscErrorCode MatDenseGetArrayWrite(Mat A,PetscScalar **array) 22746947451fSStefano Zampini { 22756947451fSStefano Zampini PetscFunctionBegin; 2276d5ea218eSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2277d5ea218eSStefano Zampini PetscValidPointer(array,2); 2278cac4c232SBarry Smith PetscUseMethod(A,"MatDenseGetArrayWrite_C",(Mat,PetscScalar**),(A,array)); 22796947451fSStefano Zampini PetscFunctionReturn(0); 22806947451fSStefano Zampini } 22816947451fSStefano Zampini 22826947451fSStefano Zampini /*@C 22836947451fSStefano Zampini MatDenseRestoreArrayWrite - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArrayWrite() 22846947451fSStefano Zampini 22856947451fSStefano Zampini Not Collective 22866947451fSStefano Zampini 22876947451fSStefano Zampini Input Parameters: 22886947451fSStefano Zampini + mat - a dense matrix 22896947451fSStefano Zampini - array - pointer to the data 22906947451fSStefano Zampini 22916947451fSStefano Zampini Level: intermediate 22926947451fSStefano Zampini 2293db781477SPatrick Sanan .seealso: `MatDenseGetArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()` 22946947451fSStefano Zampini @*/ 22956947451fSStefano Zampini PetscErrorCode MatDenseRestoreArrayWrite(Mat A,PetscScalar **array) 22966947451fSStefano Zampini { 22976947451fSStefano Zampini PetscFunctionBegin; 2298d5ea218eSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 2299d5ea218eSStefano Zampini PetscValidPointer(array,2); 2300cac4c232SBarry Smith PetscUseMethod(A,"MatDenseRestoreArrayWrite_C",(Mat,PetscScalar**),(A,array)); 23019566063dSJacob Faibussowitsch PetscCall(PetscObjectStateIncrease((PetscObject)A)); 23026947451fSStefano Zampini #if defined(PETSC_HAVE_CUDA) 23036947451fSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 23046947451fSStefano Zampini #endif 23056947451fSStefano Zampini PetscFunctionReturn(0); 23066947451fSStefano Zampini } 23076947451fSStefano Zampini 2308023c16fcSToby Isaac static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,MatReuse scall,Mat *B) 23090754003eSLois Curfman McInnes { 2310c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 2311bf5a80bcSToby Isaac PetscInt i,j,nrows,ncols,ldb; 23125d0c19d7SBarry Smith const PetscInt *irow,*icol; 231387828ca2SBarry Smith PetscScalar *av,*bv,*v = mat->v; 23140754003eSLois Curfman McInnes Mat newmat; 23150754003eSLois Curfman McInnes 23163a40ed3dSBarry Smith PetscFunctionBegin; 23179566063dSJacob Faibussowitsch PetscCall(ISGetIndices(isrow,&irow)); 23189566063dSJacob Faibussowitsch PetscCall(ISGetIndices(iscol,&icol)); 23199566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(isrow,&nrows)); 23209566063dSJacob Faibussowitsch PetscCall(ISGetLocalSize(iscol,&ncols)); 23210754003eSLois Curfman McInnes 2322182d2002SSatish Balay /* Check submatrixcall */ 2323182d2002SSatish Balay if (scall == MAT_REUSE_MATRIX) { 232413f74950SBarry Smith PetscInt n_cols,n_rows; 23259566063dSJacob Faibussowitsch PetscCall(MatGetSize(*B,&n_rows,&n_cols)); 232621a2c019SBarry Smith if (n_rows != nrows || n_cols != ncols) { 2327f746d493SDmitry Karpeev /* resize the result matrix to match number of requested rows/columns */ 23289566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*B,nrows,ncols,nrows,ncols)); 232921a2c019SBarry Smith } 2330182d2002SSatish Balay newmat = *B; 2331182d2002SSatish Balay } else { 23320754003eSLois Curfman McInnes /* Create and fill new matrix */ 23339566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&newmat)); 23349566063dSJacob Faibussowitsch PetscCall(MatSetSizes(newmat,nrows,ncols,nrows,ncols)); 23359566063dSJacob Faibussowitsch PetscCall(MatSetType(newmat,((PetscObject)A)->type_name)); 23369566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(newmat,NULL)); 2337182d2002SSatish Balay } 2338182d2002SSatish Balay 2339182d2002SSatish Balay /* Now extract the data pointers and do the copy,column at a time */ 23409566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(newmat,&bv)); 23419566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(newmat,&ldb)); 2342182d2002SSatish Balay for (i=0; i<ncols; i++) { 23436de62eeeSBarry Smith av = v + mat->lda*icol[i]; 2344ca15aa20SStefano Zampini for (j=0; j<nrows; j++) bv[j] = av[irow[j]]; 2345bf5a80bcSToby Isaac bv += ldb; 23460754003eSLois Curfman McInnes } 23479566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(newmat,&bv)); 2348182d2002SSatish Balay 2349182d2002SSatish Balay /* Assemble the matrices so that the correct flags are set */ 23509566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY)); 23519566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY)); 23520754003eSLois Curfman McInnes 23530754003eSLois Curfman McInnes /* Free work space */ 23549566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(isrow,&irow)); 23559566063dSJacob Faibussowitsch PetscCall(ISRestoreIndices(iscol,&icol)); 2356182d2002SSatish Balay *B = newmat; 23573a40ed3dSBarry Smith PetscFunctionReturn(0); 23580754003eSLois Curfman McInnes } 23590754003eSLois Curfman McInnes 23607dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[]) 2361905e6a2fSBarry Smith { 236213f74950SBarry Smith PetscInt i; 2363905e6a2fSBarry Smith 23643a40ed3dSBarry Smith PetscFunctionBegin; 2365905e6a2fSBarry Smith if (scall == MAT_INITIAL_MATRIX) { 23669566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(n,B)); 2367905e6a2fSBarry Smith } 2368905e6a2fSBarry Smith 2369905e6a2fSBarry Smith for (i=0; i<n; i++) { 23709566063dSJacob Faibussowitsch PetscCall(MatCreateSubMatrix_SeqDense(A,irow[i],icol[i],scall,&(*B)[i])); 2371905e6a2fSBarry Smith } 23723a40ed3dSBarry Smith PetscFunctionReturn(0); 2373905e6a2fSBarry Smith } 2374905e6a2fSBarry Smith 2375e0877f53SBarry Smith static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat,MatAssemblyType mode) 2376c0aa2d19SHong Zhang { 2377c0aa2d19SHong Zhang PetscFunctionBegin; 2378c0aa2d19SHong Zhang PetscFunctionReturn(0); 2379c0aa2d19SHong Zhang } 2380c0aa2d19SHong Zhang 2381e0877f53SBarry Smith static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat,MatAssemblyType mode) 2382c0aa2d19SHong Zhang { 2383c0aa2d19SHong Zhang PetscFunctionBegin; 2384c0aa2d19SHong Zhang PetscFunctionReturn(0); 2385c0aa2d19SHong Zhang } 2386c0aa2d19SHong Zhang 2387a76f77c3SStefano Zampini PetscErrorCode MatCopy_SeqDense(Mat A,Mat B,MatStructure str) 23884b0e389bSBarry Smith { 23894b0e389bSBarry Smith Mat_SeqDense *a = (Mat_SeqDense*)A->data,*b = (Mat_SeqDense*)B->data; 2390ca15aa20SStefano Zampini const PetscScalar *va; 2391ca15aa20SStefano Zampini PetscScalar *vb; 2392d0f46423SBarry Smith PetscInt lda1=a->lda,lda2=b->lda, m=A->rmap->n,n=A->cmap->n, j; 23933a40ed3dSBarry Smith 23943a40ed3dSBarry Smith PetscFunctionBegin; 239533f4a19fSKris Buschelman /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */ 239633f4a19fSKris Buschelman if (A->ops->copy != B->ops->copy) { 23979566063dSJacob Faibussowitsch PetscCall(MatCopy_Basic(A,B,str)); 23983a40ed3dSBarry Smith PetscFunctionReturn(0); 23993a40ed3dSBarry Smith } 2400aed4548fSBarry Smith PetscCheck(m == B->rmap->n && n == B->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"size(B) != size(A)"); 24019566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A,&va)); 24029566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(B,&vb)); 2403a5ce6ee0Svictorle if (lda1>m || lda2>m) { 24040dbb7854Svictorle for (j=0; j<n; j++) { 24059566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(vb+j*lda2,va+j*lda1,m)); 2406a5ce6ee0Svictorle } 2407a5ce6ee0Svictorle } else { 24089566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(vb,va,A->rmap->n*A->cmap->n)); 2409a5ce6ee0Svictorle } 24109566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(B,&vb)); 24119566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A,&va)); 24129566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY)); 24139566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY)); 2414273d9f13SBarry Smith PetscFunctionReturn(0); 2415273d9f13SBarry Smith } 2416273d9f13SBarry Smith 241775f6d85dSStefano Zampini PetscErrorCode MatSetUp_SeqDense(Mat A) 2418273d9f13SBarry Smith { 2419273d9f13SBarry Smith PetscFunctionBegin; 24209566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->rmap)); 24219566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(A->cmap)); 242218992e5dSStefano Zampini if (!A->preallocated) { 24239566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(A,NULL)); 242418992e5dSStefano Zampini } 24253a40ed3dSBarry Smith PetscFunctionReturn(0); 24264b0e389bSBarry Smith } 24274b0e389bSBarry Smith 2428ba337c44SJed Brown static PetscErrorCode MatConjugate_SeqDense(Mat A) 2429ba337c44SJed Brown { 24304396437dSToby Isaac Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 243106c5243aSJose E. Roman PetscInt i,j; 24324396437dSToby Isaac PetscInt min = PetscMin(A->rmap->n,A->cmap->n); 2433ca15aa20SStefano Zampini PetscScalar *aa; 2434ba337c44SJed Brown 2435ba337c44SJed Brown PetscFunctionBegin; 24369566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A,&aa)); 243706c5243aSJose E. Roman for (j=0; j<A->cmap->n; j++) { 243806c5243aSJose E. Roman for (i=0; i<A->rmap->n; i++) aa[i+j*mat->lda] = PetscConj(aa[i+j*mat->lda]); 243906c5243aSJose E. Roman } 24409566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A,&aa)); 24414396437dSToby Isaac if (mat->tau) for (i = 0; i < min; i++) mat->tau[i] = PetscConj(mat->tau[i]); 2442ba337c44SJed Brown PetscFunctionReturn(0); 2443ba337c44SJed Brown } 2444ba337c44SJed Brown 2445ba337c44SJed Brown static PetscErrorCode MatRealPart_SeqDense(Mat A) 2446ba337c44SJed Brown { 244706c5243aSJose E. Roman Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 244806c5243aSJose E. Roman PetscInt i,j; 2449ca15aa20SStefano Zampini PetscScalar *aa; 2450ba337c44SJed Brown 2451ba337c44SJed Brown PetscFunctionBegin; 24529566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A,&aa)); 245306c5243aSJose E. Roman for (j=0; j<A->cmap->n; j++) { 245406c5243aSJose E. Roman for (i=0; i<A->rmap->n; i++) aa[i+j*mat->lda] = PetscRealPart(aa[i+j*mat->lda]); 245506c5243aSJose E. Roman } 24569566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A,&aa)); 2457ba337c44SJed Brown PetscFunctionReturn(0); 2458ba337c44SJed Brown } 2459ba337c44SJed Brown 2460ba337c44SJed Brown static PetscErrorCode MatImaginaryPart_SeqDense(Mat A) 2461ba337c44SJed Brown { 246206c5243aSJose E. Roman Mat_SeqDense *mat = (Mat_SeqDense *) A->data; 246306c5243aSJose E. Roman PetscInt i,j; 2464ca15aa20SStefano Zampini PetscScalar *aa; 2465ba337c44SJed Brown 2466ba337c44SJed Brown PetscFunctionBegin; 24679566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A,&aa)); 246806c5243aSJose E. Roman for (j=0; j<A->cmap->n; j++) { 246906c5243aSJose E. Roman for (i=0; i<A->rmap->n; i++) aa[i+j*mat->lda] = PetscImaginaryPart(aa[i+j*mat->lda]); 247006c5243aSJose E. Roman } 24719566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A,&aa)); 2472ba337c44SJed Brown PetscFunctionReturn(0); 2473ba337c44SJed Brown } 2474284134d9SBarry Smith 2475a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/ 24764222ddf1SHong Zhang PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C) 2477a9fe9ddaSSatish Balay { 2478d0f46423SBarry Smith PetscInt m=A->rmap->n,n=B->cmap->n; 24797a3c3d58SStefano Zampini PetscBool cisdense; 2480a9fe9ddaSSatish Balay 2481ee16a9a1SHong Zhang PetscFunctionBegin; 24829566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C,m,n,m,n)); 24839566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"")); 24847a3c3d58SStefano Zampini if (!cisdense) { 24857a3c3d58SStefano Zampini PetscBool flg; 24867a3c3d58SStefano Zampini 24879566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg)); 24889566063dSJacob Faibussowitsch PetscCall(MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE)); 24897a3c3d58SStefano Zampini } 24909566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 2491ee16a9a1SHong Zhang PetscFunctionReturn(0); 2492ee16a9a1SHong Zhang } 2493a9fe9ddaSSatish Balay 2494a9fe9ddaSSatish Balay PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C) 2495a9fe9ddaSSatish Balay { 24966718818eSStefano Zampini Mat_SeqDense *a=(Mat_SeqDense*)A->data,*b=(Mat_SeqDense*)B->data,*c=(Mat_SeqDense*)C->data; 24970805154bSBarry Smith PetscBLASInt m,n,k; 2498ca15aa20SStefano Zampini const PetscScalar *av,*bv; 2499ca15aa20SStefano Zampini PetscScalar *cv; 2500a9fe9ddaSSatish Balay PetscScalar _DOne=1.0,_DZero=0.0; 2501a9fe9ddaSSatish Balay 2502a9fe9ddaSSatish Balay PetscFunctionBegin; 25039566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n,&m)); 25049566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n,&n)); 25059566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n,&k)); 250649d0e964SStefano Zampini if (!m || !n || !k) PetscFunctionReturn(0); 25079566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A,&av)); 25089566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B,&bv)); 25099566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C,&cv)); 2510ca15aa20SStefano Zampini PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda)); 25119566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1))); 25129566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A,&av)); 25139566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B,&bv)); 25149566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C,&cv)); 2515a9fe9ddaSSatish Balay PetscFunctionReturn(0); 2516a9fe9ddaSSatish Balay } 2517a9fe9ddaSSatish Balay 25184222ddf1SHong Zhang PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C) 251969f65d41SStefano Zampini { 252069f65d41SStefano Zampini PetscInt m=A->rmap->n,n=B->rmap->n; 25217a3c3d58SStefano Zampini PetscBool cisdense; 252269f65d41SStefano Zampini 252369f65d41SStefano Zampini PetscFunctionBegin; 25249566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C,m,n,m,n)); 25259566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"")); 25267a3c3d58SStefano Zampini if (!cisdense) { 25277a3c3d58SStefano Zampini PetscBool flg; 25287a3c3d58SStefano Zampini 25299566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg)); 25309566063dSJacob Faibussowitsch PetscCall(MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE)); 25317a3c3d58SStefano Zampini } 25329566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 253369f65d41SStefano Zampini PetscFunctionReturn(0); 253469f65d41SStefano Zampini } 253569f65d41SStefano Zampini 253669f65d41SStefano Zampini PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C) 253769f65d41SStefano Zampini { 253869f65d41SStefano Zampini Mat_SeqDense *a = (Mat_SeqDense*)A->data; 253969f65d41SStefano Zampini Mat_SeqDense *b = (Mat_SeqDense*)B->data; 254069f65d41SStefano Zampini Mat_SeqDense *c = (Mat_SeqDense*)C->data; 25416718818eSStefano Zampini const PetscScalar *av,*bv; 25426718818eSStefano Zampini PetscScalar *cv; 254369f65d41SStefano Zampini PetscBLASInt m,n,k; 254469f65d41SStefano Zampini PetscScalar _DOne=1.0,_DZero=0.0; 254569f65d41SStefano Zampini 254669f65d41SStefano Zampini PetscFunctionBegin; 25479566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n,&m)); 25489566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n,&n)); 25499566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->cmap->n,&k)); 255049d0e964SStefano Zampini if (!m || !n || !k) PetscFunctionReturn(0); 25519566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A,&av)); 25529566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B,&bv)); 25539566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C,&cv)); 25546718818eSStefano Zampini PetscStackCallBLAS("BLASgemm",BLASgemm_("N","T",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda)); 25559566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A,&av)); 25569566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B,&bv)); 25579566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C,&cv)); 25589566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1))); 255969f65d41SStefano Zampini PetscFunctionReturn(0); 256069f65d41SStefano Zampini } 256169f65d41SStefano Zampini 25624222ddf1SHong Zhang PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C) 2563a9fe9ddaSSatish Balay { 2564d0f46423SBarry Smith PetscInt m=A->cmap->n,n=B->cmap->n; 25657a3c3d58SStefano Zampini PetscBool cisdense; 2566a9fe9ddaSSatish Balay 2567ee16a9a1SHong Zhang PetscFunctionBegin; 25689566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C,m,n,m,n)); 25699566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"")); 25707a3c3d58SStefano Zampini if (!cisdense) { 25717a3c3d58SStefano Zampini PetscBool flg; 25727a3c3d58SStefano Zampini 25739566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg)); 25749566063dSJacob Faibussowitsch PetscCall(MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE)); 25757a3c3d58SStefano Zampini } 25769566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 2577ee16a9a1SHong Zhang PetscFunctionReturn(0); 2578ee16a9a1SHong Zhang } 2579a9fe9ddaSSatish Balay 258075648e8dSHong Zhang PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C) 2581a9fe9ddaSSatish Balay { 2582a9fe9ddaSSatish Balay Mat_SeqDense *a = (Mat_SeqDense*)A->data; 2583a9fe9ddaSSatish Balay Mat_SeqDense *b = (Mat_SeqDense*)B->data; 2584a9fe9ddaSSatish Balay Mat_SeqDense *c = (Mat_SeqDense*)C->data; 25856718818eSStefano Zampini const PetscScalar *av,*bv; 25866718818eSStefano Zampini PetscScalar *cv; 25870805154bSBarry Smith PetscBLASInt m,n,k; 2588a9fe9ddaSSatish Balay PetscScalar _DOne=1.0,_DZero=0.0; 2589a9fe9ddaSSatish Balay 2590a9fe9ddaSSatish Balay PetscFunctionBegin; 25919566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->rmap->n,&m)); 25929566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(C->cmap->n,&n)); 25939566063dSJacob Faibussowitsch PetscCall(PetscBLASIntCast(A->rmap->n,&k)); 259449d0e964SStefano Zampini if (!m || !n || !k) PetscFunctionReturn(0); 25959566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A,&av)); 25969566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B,&bv)); 25979566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(C,&cv)); 25986718818eSStefano Zampini PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda)); 25999566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A,&av)); 26009566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B,&bv)); 26019566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(C,&cv)); 26029566063dSJacob Faibussowitsch PetscCall(PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1))); 2603a9fe9ddaSSatish Balay PetscFunctionReturn(0); 2604a9fe9ddaSSatish Balay } 2605985db425SBarry Smith 26064222ddf1SHong Zhang /* ----------------------------------------------- */ 26074222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C) 26084222ddf1SHong Zhang { 26094222ddf1SHong Zhang PetscFunctionBegin; 26104222ddf1SHong Zhang C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense; 26114222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AB; 26124222ddf1SHong Zhang PetscFunctionReturn(0); 26134222ddf1SHong Zhang } 26144222ddf1SHong Zhang 26154222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C) 26164222ddf1SHong Zhang { 26174222ddf1SHong Zhang PetscFunctionBegin; 26184222ddf1SHong Zhang C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense; 26194222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_AtB; 26204222ddf1SHong Zhang PetscFunctionReturn(0); 26214222ddf1SHong Zhang } 26224222ddf1SHong Zhang 26234222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C) 26244222ddf1SHong Zhang { 26254222ddf1SHong Zhang PetscFunctionBegin; 26264222ddf1SHong Zhang C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense; 26274222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_ABt; 26284222ddf1SHong Zhang PetscFunctionReturn(0); 26294222ddf1SHong Zhang } 26304222ddf1SHong Zhang 26314222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C) 26324222ddf1SHong Zhang { 26334222ddf1SHong Zhang Mat_Product *product = C->product; 26344222ddf1SHong Zhang 26354222ddf1SHong Zhang PetscFunctionBegin; 26364222ddf1SHong Zhang switch (product->type) { 26374222ddf1SHong Zhang case MATPRODUCT_AB: 26389566063dSJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_AB(C)); 26394222ddf1SHong Zhang break; 26404222ddf1SHong Zhang case MATPRODUCT_AtB: 26419566063dSJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_AtB(C)); 26424222ddf1SHong Zhang break; 26434222ddf1SHong Zhang case MATPRODUCT_ABt: 26449566063dSJacob Faibussowitsch PetscCall(MatProductSetFromOptions_SeqDense_ABt(C)); 26454222ddf1SHong Zhang break; 26466718818eSStefano Zampini default: 26474222ddf1SHong Zhang break; 26484222ddf1SHong Zhang } 26494222ddf1SHong Zhang PetscFunctionReturn(0); 26504222ddf1SHong Zhang } 26514222ddf1SHong Zhang /* ----------------------------------------------- */ 26524222ddf1SHong Zhang 2653e0877f53SBarry Smith static PetscErrorCode MatGetRowMax_SeqDense(Mat A,Vec v,PetscInt idx[]) 2654985db425SBarry Smith { 2655985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense*)A->data; 2656d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n,p; 2657985db425SBarry Smith PetscScalar *x; 2658ca15aa20SStefano Zampini const PetscScalar *aa; 2659985db425SBarry Smith 2660985db425SBarry Smith PetscFunctionBegin; 266128b400f6SJacob Faibussowitsch PetscCheck(!A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 26629566063dSJacob Faibussowitsch PetscCall(VecGetArray(v,&x)); 26639566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v,&p)); 26649566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A,&aa)); 266508401ef6SPierre Jolivet PetscCheck(p == A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2666985db425SBarry Smith for (i=0; i<m; i++) { 2667985db425SBarry Smith x[i] = aa[i]; if (idx) idx[i] = 0; 2668985db425SBarry Smith for (j=1; j<n; j++) { 2669ca15aa20SStefano Zampini if (PetscRealPart(x[i]) < PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;} 2670985db425SBarry Smith } 2671985db425SBarry Smith } 26729566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A,&aa)); 26739566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v,&x)); 2674985db425SBarry Smith PetscFunctionReturn(0); 2675985db425SBarry Smith } 2676985db425SBarry Smith 2677e0877f53SBarry Smith static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A,Vec v,PetscInt idx[]) 2678985db425SBarry Smith { 2679985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense*)A->data; 2680d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n,p; 2681985db425SBarry Smith PetscScalar *x; 2682985db425SBarry Smith PetscReal atmp; 2683ca15aa20SStefano Zampini const PetscScalar *aa; 2684985db425SBarry Smith 2685985db425SBarry Smith PetscFunctionBegin; 268628b400f6SJacob Faibussowitsch PetscCheck(!A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 26879566063dSJacob Faibussowitsch PetscCall(VecGetArray(v,&x)); 26889566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v,&p)); 26899566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A,&aa)); 269008401ef6SPierre Jolivet PetscCheck(p == A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2691985db425SBarry Smith for (i=0; i<m; i++) { 26929189402eSHong Zhang x[i] = PetscAbsScalar(aa[i]); 2693985db425SBarry Smith for (j=1; j<n; j++) { 2694ca15aa20SStefano Zampini atmp = PetscAbsScalar(aa[i+a->lda*j]); 2695985db425SBarry Smith if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = j;} 2696985db425SBarry Smith } 2697985db425SBarry Smith } 26989566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A,&aa)); 26999566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v,&x)); 2700985db425SBarry Smith PetscFunctionReturn(0); 2701985db425SBarry Smith } 2702985db425SBarry Smith 2703e0877f53SBarry Smith static PetscErrorCode MatGetRowMin_SeqDense(Mat A,Vec v,PetscInt idx[]) 2704985db425SBarry Smith { 2705985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense*)A->data; 2706d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n,p; 2707985db425SBarry Smith PetscScalar *x; 2708ca15aa20SStefano Zampini const PetscScalar *aa; 2709985db425SBarry Smith 2710985db425SBarry Smith PetscFunctionBegin; 271128b400f6SJacob Faibussowitsch PetscCheck(!A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 27129566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A,&aa)); 27139566063dSJacob Faibussowitsch PetscCall(VecGetArray(v,&x)); 27149566063dSJacob Faibussowitsch PetscCall(VecGetLocalSize(v,&p)); 271508401ef6SPierre Jolivet PetscCheck(p == A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2716985db425SBarry Smith for (i=0; i<m; i++) { 2717985db425SBarry Smith x[i] = aa[i]; if (idx) idx[i] = 0; 2718985db425SBarry Smith for (j=1; j<n; j++) { 2719ca15aa20SStefano Zampini if (PetscRealPart(x[i]) > PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;} 2720985db425SBarry Smith } 2721985db425SBarry Smith } 27229566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v,&x)); 27239566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A,&aa)); 2724985db425SBarry Smith PetscFunctionReturn(0); 2725985db425SBarry Smith } 2726985db425SBarry Smith 2727637a0070SStefano Zampini PetscErrorCode MatGetColumnVector_SeqDense(Mat A,Vec v,PetscInt col) 27288d0534beSBarry Smith { 27298d0534beSBarry Smith Mat_SeqDense *a = (Mat_SeqDense*)A->data; 27308d0534beSBarry Smith PetscScalar *x; 2731ca15aa20SStefano Zampini const PetscScalar *aa; 27328d0534beSBarry Smith 27338d0534beSBarry Smith PetscFunctionBegin; 273428b400f6SJacob Faibussowitsch PetscCheck(!A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 27359566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A,&aa)); 27369566063dSJacob Faibussowitsch PetscCall(VecGetArray(v,&x)); 27379566063dSJacob Faibussowitsch PetscCall(PetscArraycpy(x,aa+col*a->lda,A->rmap->n)); 27389566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(v,&x)); 27399566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A,&aa)); 27408d0534beSBarry Smith PetscFunctionReturn(0); 27418d0534beSBarry Smith } 27428d0534beSBarry Smith 2743857cbf51SRichard Tran Mills PETSC_INTERN PetscErrorCode MatGetColumnReductions_SeqDense(Mat A,PetscInt type,PetscReal *reductions) 27440716a85fSBarry Smith { 27450716a85fSBarry Smith PetscInt i,j,m,n; 27461683a169SBarry Smith const PetscScalar *a; 27470716a85fSBarry Smith 27480716a85fSBarry Smith PetscFunctionBegin; 27499566063dSJacob Faibussowitsch PetscCall(MatGetSize(A,&m,&n)); 27509566063dSJacob Faibussowitsch PetscCall(PetscArrayzero(reductions,n)); 27519566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A,&a)); 2752857cbf51SRichard Tran Mills if (type == NORM_2) { 27530716a85fSBarry Smith for (i=0; i<n; i++) { 27540716a85fSBarry Smith for (j=0; j<m; j++) { 2755a873a8cdSSam Reynolds reductions[i] += PetscAbsScalar(a[j]*a[j]); 27560716a85fSBarry Smith } 27570716a85fSBarry Smith a += m; 27580716a85fSBarry Smith } 2759857cbf51SRichard Tran Mills } else if (type == NORM_1) { 27600716a85fSBarry Smith for (i=0; i<n; i++) { 27610716a85fSBarry Smith for (j=0; j<m; j++) { 2762a873a8cdSSam Reynolds reductions[i] += PetscAbsScalar(a[j]); 27630716a85fSBarry Smith } 27640716a85fSBarry Smith a += m; 27650716a85fSBarry Smith } 2766857cbf51SRichard Tran Mills } else if (type == NORM_INFINITY) { 27670716a85fSBarry Smith for (i=0; i<n; i++) { 27680716a85fSBarry Smith for (j=0; j<m; j++) { 2769a873a8cdSSam Reynolds reductions[i] = PetscMax(PetscAbsScalar(a[j]),reductions[i]); 27700716a85fSBarry Smith } 27710716a85fSBarry Smith a += m; 27720716a85fSBarry Smith } 2773857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_REALPART || type == REDUCTION_MEAN_REALPART) { 2774a873a8cdSSam Reynolds for (i=0; i<n; i++) { 2775a873a8cdSSam Reynolds for (j=0; j<m; j++) { 2776857cbf51SRichard Tran Mills reductions[i] += PetscRealPart(a[j]); 2777a873a8cdSSam Reynolds } 2778a873a8cdSSam Reynolds a += m; 2779a873a8cdSSam Reynolds } 2780857cbf51SRichard Tran Mills } else if (type == REDUCTION_SUM_IMAGINARYPART || type == REDUCTION_MEAN_IMAGINARYPART) { 2781857cbf51SRichard Tran Mills for (i=0; i<n; i++) { 2782857cbf51SRichard Tran Mills for (j=0; j<m; j++) { 2783857cbf51SRichard Tran Mills reductions[i] += PetscImaginaryPart(a[j]); 2784857cbf51SRichard Tran Mills } 2785857cbf51SRichard Tran Mills a += m; 2786857cbf51SRichard Tran Mills } 2787857cbf51SRichard Tran Mills } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Unknown reduction type"); 27889566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A,&a)); 2789857cbf51SRichard Tran Mills if (type == NORM_2) { 2790a873a8cdSSam Reynolds for (i=0; i<n; i++) reductions[i] = PetscSqrtReal(reductions[i]); 2791857cbf51SRichard Tran Mills } else if (type == REDUCTION_MEAN_REALPART || type == REDUCTION_MEAN_IMAGINARYPART) { 2792a873a8cdSSam Reynolds for (i=0; i<n; i++) reductions[i] /= m; 27930716a85fSBarry Smith } 27940716a85fSBarry Smith PetscFunctionReturn(0); 27950716a85fSBarry Smith } 27960716a85fSBarry Smith 279773a71a0fSBarry Smith static PetscErrorCode MatSetRandom_SeqDense(Mat x,PetscRandom rctx) 279873a71a0fSBarry Smith { 279973a71a0fSBarry Smith PetscScalar *a; 2800637a0070SStefano Zampini PetscInt lda,m,n,i,j; 280173a71a0fSBarry Smith 280273a71a0fSBarry Smith PetscFunctionBegin; 28039566063dSJacob Faibussowitsch PetscCall(MatGetSize(x,&m,&n)); 28049566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(x,&lda)); 28059566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(x,&a)); 2806637a0070SStefano Zampini for (j=0; j<n; j++) { 2807637a0070SStefano Zampini for (i=0; i<m; i++) { 28089566063dSJacob Faibussowitsch PetscCall(PetscRandomGetValue(rctx,a+j*lda+i)); 2809637a0070SStefano Zampini } 281073a71a0fSBarry Smith } 28119566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(x,&a)); 281273a71a0fSBarry Smith PetscFunctionReturn(0); 281373a71a0fSBarry Smith } 281473a71a0fSBarry Smith 28153b49f96aSBarry Smith static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A,PetscBool *missing,PetscInt *d) 28163b49f96aSBarry Smith { 28173b49f96aSBarry Smith PetscFunctionBegin; 28183b49f96aSBarry Smith *missing = PETSC_FALSE; 28193b49f96aSBarry Smith PetscFunctionReturn(0); 28203b49f96aSBarry Smith } 282173a71a0fSBarry Smith 2822ca15aa20SStefano Zampini /* vals is not const */ 2823af53bab2SHong Zhang static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A,PetscInt col,PetscScalar **vals) 282486aefd0dSHong Zhang { 282586aefd0dSHong Zhang Mat_SeqDense *a = (Mat_SeqDense*)A->data; 2826ca15aa20SStefano Zampini PetscScalar *v; 282786aefd0dSHong Zhang 282886aefd0dSHong Zhang PetscFunctionBegin; 282928b400f6SJacob Faibussowitsch PetscCheck(!A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 28309566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A,&v)); 2831ca15aa20SStefano Zampini *vals = v+col*a->lda; 28329566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A,&v)); 283386aefd0dSHong Zhang PetscFunctionReturn(0); 283486aefd0dSHong Zhang } 283586aefd0dSHong Zhang 2836af53bab2SHong Zhang static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A,PetscScalar **vals) 283786aefd0dSHong Zhang { 283886aefd0dSHong Zhang PetscFunctionBegin; 2839a5b23f4aSJose E. Roman *vals = NULL; /* user cannot accidentally use the array later */ 284086aefd0dSHong Zhang PetscFunctionReturn(0); 284186aefd0dSHong Zhang } 2842abc3b08eSStefano Zampini 2843289bc588SBarry Smith /* -------------------------------------------------------------------*/ 2844a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqDense, 2845905e6a2fSBarry Smith MatGetRow_SeqDense, 2846905e6a2fSBarry Smith MatRestoreRow_SeqDense, 2847905e6a2fSBarry Smith MatMult_SeqDense, 284897304618SKris Buschelman /* 4*/ MatMultAdd_SeqDense, 28497c922b88SBarry Smith MatMultTranspose_SeqDense, 28507c922b88SBarry Smith MatMultTransposeAdd_SeqDense, 2851f4259b30SLisandro Dalcin NULL, 2852f4259b30SLisandro Dalcin NULL, 2853f4259b30SLisandro Dalcin NULL, 2854f4259b30SLisandro Dalcin /* 10*/ NULL, 2855905e6a2fSBarry Smith MatLUFactor_SeqDense, 2856905e6a2fSBarry Smith MatCholeskyFactor_SeqDense, 285741f059aeSBarry Smith MatSOR_SeqDense, 2858ec8511deSBarry Smith MatTranspose_SeqDense, 285997304618SKris Buschelman /* 15*/ MatGetInfo_SeqDense, 2860905e6a2fSBarry Smith MatEqual_SeqDense, 2861905e6a2fSBarry Smith MatGetDiagonal_SeqDense, 2862905e6a2fSBarry Smith MatDiagonalScale_SeqDense, 2863905e6a2fSBarry Smith MatNorm_SeqDense, 2864c0aa2d19SHong Zhang /* 20*/ MatAssemblyBegin_SeqDense, 2865c0aa2d19SHong Zhang MatAssemblyEnd_SeqDense, 2866905e6a2fSBarry Smith MatSetOption_SeqDense, 2867905e6a2fSBarry Smith MatZeroEntries_SeqDense, 2868d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqDense, 2869f4259b30SLisandro Dalcin NULL, 2870f4259b30SLisandro Dalcin NULL, 2871f4259b30SLisandro Dalcin NULL, 2872f4259b30SLisandro Dalcin NULL, 28734994cf47SJed Brown /* 29*/ MatSetUp_SeqDense, 2874f4259b30SLisandro Dalcin NULL, 2875f4259b30SLisandro Dalcin NULL, 2876f4259b30SLisandro Dalcin NULL, 2877f4259b30SLisandro Dalcin NULL, 2878d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqDense, 2879f4259b30SLisandro Dalcin NULL, 2880f4259b30SLisandro Dalcin NULL, 2881f4259b30SLisandro Dalcin NULL, 2882f4259b30SLisandro Dalcin NULL, 2883d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqDense, 28847dae84e0SHong Zhang MatCreateSubMatrices_SeqDense, 2885f4259b30SLisandro Dalcin NULL, 28864b0e389bSBarry Smith MatGetValues_SeqDense, 2887a5ae1ecdSBarry Smith MatCopy_SeqDense, 2888d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqDense, 2889a5ae1ecdSBarry Smith MatScale_SeqDense, 28902f605a99SJose E. Roman MatShift_SeqDense, 2891f4259b30SLisandro Dalcin NULL, 28923f49a652SStefano Zampini MatZeroRowsColumns_SeqDense, 289373a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqDense, 2894f4259b30SLisandro Dalcin NULL, 2895f4259b30SLisandro Dalcin NULL, 2896f4259b30SLisandro Dalcin NULL, 2897f4259b30SLisandro Dalcin NULL, 2898f4259b30SLisandro Dalcin /* 54*/ NULL, 2899f4259b30SLisandro Dalcin NULL, 2900f4259b30SLisandro Dalcin NULL, 2901f4259b30SLisandro Dalcin NULL, 2902f4259b30SLisandro Dalcin NULL, 2903023c16fcSToby Isaac /* 59*/ MatCreateSubMatrix_SeqDense, 2904e03a110bSBarry Smith MatDestroy_SeqDense, 2905e03a110bSBarry Smith MatView_SeqDense, 2906f4259b30SLisandro Dalcin NULL, 2907f4259b30SLisandro Dalcin NULL, 2908f4259b30SLisandro Dalcin /* 64*/ NULL, 2909f4259b30SLisandro Dalcin NULL, 2910f4259b30SLisandro Dalcin NULL, 2911f4259b30SLisandro Dalcin NULL, 2912f4259b30SLisandro Dalcin NULL, 2913d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqDense, 2914f4259b30SLisandro Dalcin NULL, 2915f4259b30SLisandro Dalcin NULL, 2916f4259b30SLisandro Dalcin NULL, 2917f4259b30SLisandro Dalcin NULL, 2918f4259b30SLisandro Dalcin /* 74*/ NULL, 2919f4259b30SLisandro Dalcin NULL, 2920f4259b30SLisandro Dalcin NULL, 2921f4259b30SLisandro Dalcin NULL, 2922f4259b30SLisandro Dalcin NULL, 2923f4259b30SLisandro Dalcin /* 79*/ NULL, 2924f4259b30SLisandro Dalcin NULL, 2925f4259b30SLisandro Dalcin NULL, 2926f4259b30SLisandro Dalcin NULL, 29275bba2384SShri Abhyankar /* 83*/ MatLoad_SeqDense, 2928637a0070SStefano Zampini MatIsSymmetric_SeqDense, 29291cbb95d3SBarry Smith MatIsHermitian_SeqDense, 2930f4259b30SLisandro Dalcin NULL, 2931f4259b30SLisandro Dalcin NULL, 2932f4259b30SLisandro Dalcin NULL, 2933f4259b30SLisandro Dalcin /* 89*/ NULL, 2934f4259b30SLisandro Dalcin NULL, 2935a9fe9ddaSSatish Balay MatMatMultNumeric_SeqDense_SeqDense, 2936f4259b30SLisandro Dalcin NULL, 2937f4259b30SLisandro Dalcin NULL, 2938f4259b30SLisandro Dalcin /* 94*/ NULL, 2939f4259b30SLisandro Dalcin NULL, 2940f4259b30SLisandro Dalcin NULL, 294169f65d41SStefano Zampini MatMatTransposeMultNumeric_SeqDense_SeqDense, 2942f4259b30SLisandro Dalcin NULL, 29434222ddf1SHong Zhang /* 99*/ MatProductSetFromOptions_SeqDense, 2944f4259b30SLisandro Dalcin NULL, 2945f4259b30SLisandro Dalcin NULL, 2946ba337c44SJed Brown MatConjugate_SeqDense, 2947f4259b30SLisandro Dalcin NULL, 2948f4259b30SLisandro Dalcin /*104*/ NULL, 2949ba337c44SJed Brown MatRealPart_SeqDense, 2950ba337c44SJed Brown MatImaginaryPart_SeqDense, 2951f4259b30SLisandro Dalcin NULL, 2952f4259b30SLisandro Dalcin NULL, 2953f4259b30SLisandro Dalcin /*109*/ NULL, 2954f4259b30SLisandro Dalcin NULL, 29558d0534beSBarry Smith MatGetRowMin_SeqDense, 2956aabbc4fbSShri Abhyankar MatGetColumnVector_SeqDense, 29573b49f96aSBarry Smith MatMissingDiagonal_SeqDense, 2958f4259b30SLisandro Dalcin /*114*/ NULL, 2959f4259b30SLisandro Dalcin NULL, 2960f4259b30SLisandro Dalcin NULL, 2961f4259b30SLisandro Dalcin NULL, 2962f4259b30SLisandro Dalcin NULL, 2963f4259b30SLisandro Dalcin /*119*/ NULL, 2964f4259b30SLisandro Dalcin NULL, 2965f4259b30SLisandro Dalcin NULL, 2966f4259b30SLisandro Dalcin NULL, 2967f4259b30SLisandro Dalcin NULL, 2968f4259b30SLisandro Dalcin /*124*/ NULL, 2969a873a8cdSSam Reynolds MatGetColumnReductions_SeqDense, 2970f4259b30SLisandro Dalcin NULL, 2971f4259b30SLisandro Dalcin NULL, 2972f4259b30SLisandro Dalcin NULL, 2973f4259b30SLisandro Dalcin /*129*/ NULL, 2974f4259b30SLisandro Dalcin NULL, 2975f4259b30SLisandro Dalcin NULL, 297675648e8dSHong Zhang MatTransposeMatMultNumeric_SeqDense_SeqDense, 2977f4259b30SLisandro Dalcin NULL, 2978f4259b30SLisandro Dalcin /*134*/ NULL, 2979f4259b30SLisandro Dalcin NULL, 2980f4259b30SLisandro Dalcin NULL, 2981f4259b30SLisandro Dalcin NULL, 2982f4259b30SLisandro Dalcin NULL, 2983f4259b30SLisandro Dalcin /*139*/ NULL, 2984f4259b30SLisandro Dalcin NULL, 2985f4259b30SLisandro Dalcin NULL, 2986f4259b30SLisandro Dalcin NULL, 2987f4259b30SLisandro Dalcin NULL, 29884222ddf1SHong Zhang MatCreateMPIMatConcatenateSeqMat_SeqDense, 2989f4259b30SLisandro Dalcin /*145*/ NULL, 2990f4259b30SLisandro Dalcin NULL, 2991*99a7f59eSMark Adams NULL, 2992*99a7f59eSMark Adams NULL, 2993f4259b30SLisandro Dalcin NULL 2994985db425SBarry Smith }; 299590ace30eSBarry Smith 29964b828684SBarry Smith /*@C 2997fafbff53SBarry Smith MatCreateSeqDense - Creates a sequential dense matrix that 2998d65003e9SLois Curfman McInnes is stored in column major order (the usual Fortran 77 manner). Many 2999d65003e9SLois Curfman McInnes of the matrix operations use the BLAS and LAPACK routines. 3000289bc588SBarry Smith 3001d083f849SBarry Smith Collective 3002db81eaa0SLois Curfman McInnes 300320563c6bSBarry Smith Input Parameters: 3004db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 30050c775827SLois Curfman McInnes . m - number of rows 300618f449edSLois Curfman McInnes . n - number of columns 30070298fd71SBarry Smith - data - optional location of matrix data in column major order. Set data=NULL for PETSc 3008dfc5480cSLois Curfman McInnes to control all matrix memory allocation. 300920563c6bSBarry Smith 301020563c6bSBarry Smith Output Parameter: 301144cd7ae7SLois Curfman McInnes . A - the matrix 301220563c6bSBarry Smith 3013b259b22eSLois Curfman McInnes Notes: 301418f449edSLois Curfman McInnes The data input variable is intended primarily for Fortran programmers 301518f449edSLois Curfman McInnes who wish to allocate their own matrix memory space. Most users should 30160298fd71SBarry Smith set data=NULL. 301718f449edSLois Curfman McInnes 3018027ccd11SLois Curfman McInnes Level: intermediate 3019027ccd11SLois Curfman McInnes 3020db781477SPatrick Sanan .seealso: `MatCreate()`, `MatCreateDense()`, `MatSetValues()` 302120563c6bSBarry Smith @*/ 30227087cfbeSBarry Smith PetscErrorCode MatCreateSeqDense(MPI_Comm comm,PetscInt m,PetscInt n,PetscScalar *data,Mat *A) 3023289bc588SBarry Smith { 30243a40ed3dSBarry Smith PetscFunctionBegin; 30259566063dSJacob Faibussowitsch PetscCall(MatCreate(comm,A)); 30269566063dSJacob Faibussowitsch PetscCall(MatSetSizes(*A,m,n,m,n)); 30279566063dSJacob Faibussowitsch PetscCall(MatSetType(*A,MATSEQDENSE)); 30289566063dSJacob Faibussowitsch PetscCall(MatSeqDenseSetPreallocation(*A,data)); 3029273d9f13SBarry Smith PetscFunctionReturn(0); 3030273d9f13SBarry Smith } 3031273d9f13SBarry Smith 3032273d9f13SBarry Smith /*@C 3033273d9f13SBarry Smith MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements 3034273d9f13SBarry Smith 3035d083f849SBarry Smith Collective 3036273d9f13SBarry Smith 3037273d9f13SBarry Smith Input Parameters: 30381c4f3114SJed Brown + B - the matrix 30390298fd71SBarry Smith - data - the array (or NULL) 3040273d9f13SBarry Smith 3041273d9f13SBarry Smith Notes: 3042273d9f13SBarry Smith The data input variable is intended primarily for Fortran programmers 3043273d9f13SBarry Smith who wish to allocate their own matrix memory space. Most users should 3044284134d9SBarry Smith need not call this routine. 3045273d9f13SBarry Smith 3046273d9f13SBarry Smith Level: intermediate 3047273d9f13SBarry Smith 3048db781477SPatrick Sanan .seealso: `MatCreate()`, `MatCreateDense()`, `MatSetValues()`, `MatDenseSetLDA()` 3049867c911aSBarry Smith 3050273d9f13SBarry Smith @*/ 30517087cfbeSBarry Smith PetscErrorCode MatSeqDenseSetPreallocation(Mat B,PetscScalar data[]) 3052273d9f13SBarry Smith { 3053a23d5eceSKris Buschelman PetscFunctionBegin; 3054d5ea218eSStefano Zampini PetscValidHeaderSpecific(B,MAT_CLASSID,1); 3055cac4c232SBarry Smith PetscTryMethod(B,"MatSeqDenseSetPreallocation_C",(Mat,PetscScalar[]),(B,data)); 3056a23d5eceSKris Buschelman PetscFunctionReturn(0); 3057a23d5eceSKris Buschelman } 3058a23d5eceSKris Buschelman 30597087cfbeSBarry Smith PetscErrorCode MatSeqDenseSetPreallocation_SeqDense(Mat B,PetscScalar *data) 3060a23d5eceSKris Buschelman { 3061ad16ce7aSStefano Zampini Mat_SeqDense *b = (Mat_SeqDense*)B->data; 3062273d9f13SBarry Smith 3063273d9f13SBarry Smith PetscFunctionBegin; 306428b400f6SJacob Faibussowitsch PetscCheck(!b->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first"); 3065273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 3066a868139aSShri Abhyankar 30679566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(B->rmap)); 30689566063dSJacob Faibussowitsch PetscCall(PetscLayoutSetUp(B->cmap)); 306934ef9618SShri Abhyankar 3070ad16ce7aSStefano Zampini if (b->lda <= 0) b->lda = B->rmap->n; 307186d161a7SShri Abhyankar 30729e8f95c4SLisandro Dalcin if (!data) { /* petsc-allocated storage */ 30739566063dSJacob Faibussowitsch if (!b->user_alloc) PetscCall(PetscFree(b->v)); 30749566063dSJacob Faibussowitsch PetscCall(PetscCalloc1((size_t)b->lda*B->cmap->n,&b->v)); 30759566063dSJacob Faibussowitsch PetscCall(PetscLogObjectMemory((PetscObject)B,b->lda*B->cmap->n*sizeof(PetscScalar))); 30762205254eSKarl Rupp 30779e8f95c4SLisandro Dalcin b->user_alloc = PETSC_FALSE; 3078273d9f13SBarry Smith } else { /* user-allocated storage */ 30799566063dSJacob Faibussowitsch if (!b->user_alloc) PetscCall(PetscFree(b->v)); 3080273d9f13SBarry Smith b->v = data; 3081273d9f13SBarry Smith b->user_alloc = PETSC_TRUE; 3082273d9f13SBarry Smith } 30830450473dSBarry Smith B->assembled = PETSC_TRUE; 3084273d9f13SBarry Smith PetscFunctionReturn(0); 3085273d9f13SBarry Smith } 3086273d9f13SBarry Smith 308765b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 3088cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat) 30898baccfbdSHong Zhang { 3090d77f618aSHong Zhang Mat mat_elemental; 30911683a169SBarry Smith const PetscScalar *array; 30921683a169SBarry Smith PetscScalar *v_colwise; 3093d77f618aSHong Zhang PetscInt M=A->rmap->N,N=A->cmap->N,i,j,k,*rows,*cols; 3094d77f618aSHong Zhang 30958baccfbdSHong Zhang PetscFunctionBegin; 30969566063dSJacob Faibussowitsch PetscCall(PetscMalloc3(M*N,&v_colwise,M,&rows,N,&cols)); 30979566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A,&array)); 3098d77f618aSHong Zhang /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */ 3099d77f618aSHong Zhang k = 0; 3100d77f618aSHong Zhang for (j=0; j<N; j++) { 3101d77f618aSHong Zhang cols[j] = j; 3102d77f618aSHong Zhang for (i=0; i<M; i++) { 3103d77f618aSHong Zhang v_colwise[j*M+i] = array[k++]; 3104d77f618aSHong Zhang } 3105d77f618aSHong Zhang } 3106d77f618aSHong Zhang for (i=0; i<M; i++) { 3107d77f618aSHong Zhang rows[i] = i; 3108d77f618aSHong Zhang } 31099566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A,&array)); 3110d77f618aSHong Zhang 31119566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental)); 31129566063dSJacob Faibussowitsch PetscCall(MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N)); 31139566063dSJacob Faibussowitsch PetscCall(MatSetType(mat_elemental,MATELEMENTAL)); 31149566063dSJacob Faibussowitsch PetscCall(MatSetUp(mat_elemental)); 3115d77f618aSHong Zhang 3116d77f618aSHong Zhang /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */ 31179566063dSJacob Faibussowitsch PetscCall(MatSetValues(mat_elemental,M,rows,N,cols,v_colwise,ADD_VALUES)); 31189566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY)); 31199566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY)); 31209566063dSJacob Faibussowitsch PetscCall(PetscFree3(v_colwise,rows,cols)); 3121d77f618aSHong Zhang 3122511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 31239566063dSJacob Faibussowitsch PetscCall(MatHeaderReplace(A,&mat_elemental)); 3124d77f618aSHong Zhang } else { 3125d77f618aSHong Zhang *newmat = mat_elemental; 3126d77f618aSHong Zhang } 31278baccfbdSHong Zhang PetscFunctionReturn(0); 31288baccfbdSHong Zhang } 312965b80a83SHong Zhang #endif 31308baccfbdSHong Zhang 313117359960SJose E. Roman PetscErrorCode MatDenseSetLDA_SeqDense(Mat B,PetscInt lda) 31321b807ce4Svictorle { 31331b807ce4Svictorle Mat_SeqDense *b = (Mat_SeqDense*)B->data; 31347422da62SJose E. Roman PetscBool data; 313521a2c019SBarry Smith 31361b807ce4Svictorle PetscFunctionBegin; 31377422da62SJose E. Roman data = (PetscBool)((B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE); 3138aed4548fSBarry Smith PetscCheck(b->user_alloc || !data || b->lda == lda,PETSC_COMM_SELF,PETSC_ERR_ORDER,"LDA cannot be changed after allocation of internal storage"); 313908401ef6SPierre 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); 31401b807ce4Svictorle b->lda = lda; 31411b807ce4Svictorle PetscFunctionReturn(0); 31421b807ce4Svictorle } 31431b807ce4Svictorle 3144d528f656SJakub Kruzik PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat) 3145d528f656SJakub Kruzik { 3146d528f656SJakub Kruzik PetscMPIInt size; 3147d528f656SJakub Kruzik 3148d528f656SJakub Kruzik PetscFunctionBegin; 31499566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(comm,&size)); 3150d528f656SJakub Kruzik if (size == 1) { 3151d528f656SJakub Kruzik if (scall == MAT_INITIAL_MATRIX) { 31529566063dSJacob Faibussowitsch PetscCall(MatDuplicate(inmat,MAT_COPY_VALUES,outmat)); 3153d528f656SJakub Kruzik } else { 31549566063dSJacob Faibussowitsch PetscCall(MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN)); 3155d528f656SJakub Kruzik } 3156d528f656SJakub Kruzik } else { 31579566063dSJacob Faibussowitsch PetscCall(MatCreateMPIMatConcatenateSeqMat_MPIDense(comm,inmat,n,scall,outmat)); 3158d528f656SJakub Kruzik } 3159d528f656SJakub Kruzik PetscFunctionReturn(0); 3160d528f656SJakub Kruzik } 3161d528f656SJakub Kruzik 31626947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A,PetscInt col,Vec *v) 31636947451fSStefano Zampini { 31646947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense*)A->data; 31656947451fSStefano Zampini 31666947451fSStefano Zampini PetscFunctionBegin; 316728b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first"); 316828b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first"); 31696947451fSStefano Zampini if (!a->cvec) { 31709566063dSJacob Faibussowitsch PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec)); 31719566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec)); 31726947451fSStefano Zampini } 31736947451fSStefano Zampini a->vecinuse = col + 1; 31749566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(A,(PetscScalar**)&a->ptrinuse)); 31759566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda)); 31766947451fSStefano Zampini *v = a->cvec; 31776947451fSStefano Zampini PetscFunctionReturn(0); 31786947451fSStefano Zampini } 31796947451fSStefano Zampini 31806947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A,PetscInt col,Vec *v) 31816947451fSStefano Zampini { 31826947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense*)A->data; 31836947451fSStefano Zampini 31846947451fSStefano Zampini PetscFunctionBegin; 318528b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first"); 318628b400f6SJacob Faibussowitsch PetscCheck(a->cvec,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector"); 31876947451fSStefano Zampini a->vecinuse = 0; 31889566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(A,(PetscScalar**)&a->ptrinuse)); 31899566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 319075f6d85dSStefano Zampini if (v) *v = NULL; 31916947451fSStefano Zampini PetscFunctionReturn(0); 31926947451fSStefano Zampini } 31936947451fSStefano Zampini 31946947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A,PetscInt col,Vec *v) 31956947451fSStefano Zampini { 31966947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense*)A->data; 31976947451fSStefano Zampini 31986947451fSStefano Zampini PetscFunctionBegin; 319928b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first"); 320028b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first"); 32016947451fSStefano Zampini if (!a->cvec) { 32029566063dSJacob Faibussowitsch PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec)); 32039566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec)); 32046947451fSStefano Zampini } 32056947451fSStefano Zampini a->vecinuse = col + 1; 32069566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(A,&a->ptrinuse)); 32079566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda)); 32089566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(a->cvec)); 32096947451fSStefano Zampini *v = a->cvec; 32106947451fSStefano Zampini PetscFunctionReturn(0); 32116947451fSStefano Zampini } 32126947451fSStefano Zampini 32136947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A,PetscInt col,Vec *v) 32146947451fSStefano Zampini { 32156947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense*)A->data; 32166947451fSStefano Zampini 32176947451fSStefano Zampini PetscFunctionBegin; 321828b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first"); 321928b400f6SJacob Faibussowitsch PetscCheck(a->cvec,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector"); 32206947451fSStefano Zampini a->vecinuse = 0; 32219566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(A,&a->ptrinuse)); 32229566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(a->cvec)); 32239566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 322475f6d85dSStefano Zampini if (v) *v = NULL; 32256947451fSStefano Zampini PetscFunctionReturn(0); 32266947451fSStefano Zampini } 32276947451fSStefano Zampini 32286947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A,PetscInt col,Vec *v) 32296947451fSStefano Zampini { 32306947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense*)A->data; 32316947451fSStefano Zampini 32326947451fSStefano Zampini PetscFunctionBegin; 323328b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first"); 323428b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first"); 32356947451fSStefano Zampini if (!a->cvec) { 32369566063dSJacob Faibussowitsch PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec)); 32379566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec)); 32386947451fSStefano Zampini } 32396947451fSStefano Zampini a->vecinuse = col + 1; 32409566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayWrite(A,(PetscScalar**)&a->ptrinuse)); 32419566063dSJacob Faibussowitsch PetscCall(VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda)); 32426947451fSStefano Zampini *v = a->cvec; 32436947451fSStefano Zampini PetscFunctionReturn(0); 32446947451fSStefano Zampini } 32456947451fSStefano Zampini 32466947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A,PetscInt col,Vec *v) 32476947451fSStefano Zampini { 32486947451fSStefano Zampini Mat_SeqDense *a = (Mat_SeqDense*)A->data; 32496947451fSStefano Zampini 32506947451fSStefano Zampini PetscFunctionBegin; 325128b400f6SJacob Faibussowitsch PetscCheck(a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first"); 325228b400f6SJacob Faibussowitsch PetscCheck(a->cvec,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector"); 32536947451fSStefano Zampini a->vecinuse = 0; 32549566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayWrite(A,(PetscScalar**)&a->ptrinuse)); 32559566063dSJacob Faibussowitsch PetscCall(VecResetArray(a->cvec)); 325675f6d85dSStefano Zampini if (v) *v = NULL; 32576947451fSStefano Zampini PetscFunctionReturn(0); 32586947451fSStefano Zampini } 32596947451fSStefano Zampini 3260a2748737SPierre Jolivet PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A,PetscInt rbegin,PetscInt rend,PetscInt cbegin,PetscInt cend,Mat *v) 32615ea7661aSPierre Jolivet { 32625ea7661aSPierre Jolivet Mat_SeqDense *a = (Mat_SeqDense*)A->data; 32635ea7661aSPierre Jolivet 32645ea7661aSPierre Jolivet PetscFunctionBegin; 326528b400f6SJacob Faibussowitsch PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first"); 326628b400f6SJacob Faibussowitsch PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first"); 3267a2748737SPierre Jolivet if (a->cmat && (cend-cbegin != a->cmat->cmap->N || rend-rbegin != a->cmat->rmap->N)) PetscCall(MatDestroy(&a->cmat)); 32685ea7661aSPierre Jolivet if (!a->cmat) { 3269a2748737SPierre Jolivet PetscCall(MatCreateDense(PetscObjectComm((PetscObject)A),rend-rbegin,PETSC_DECIDE,rend-rbegin,cend-cbegin,a->v+rbegin+(size_t)cbegin*a->lda,&a->cmat)); 32709566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)A,(PetscObject)a->cmat)); 32715ea7661aSPierre Jolivet } else { 3272a2748737SPierre Jolivet PetscCall(MatDensePlaceArray(a->cmat,a->v+rbegin+(size_t)cbegin*a->lda)); 32735ea7661aSPierre Jolivet } 32749566063dSJacob Faibussowitsch PetscCall(MatDenseSetLDA(a->cmat,a->lda)); 32755ea7661aSPierre Jolivet a->matinuse = cbegin + 1; 32765ea7661aSPierre Jolivet *v = a->cmat; 327775f6d85dSStefano Zampini #if defined(PETSC_HAVE_CUDA) 327875f6d85dSStefano Zampini A->offloadmask = PETSC_OFFLOAD_CPU; 327975f6d85dSStefano Zampini #endif 32805ea7661aSPierre Jolivet PetscFunctionReturn(0); 32815ea7661aSPierre Jolivet } 32825ea7661aSPierre Jolivet 32835ea7661aSPierre Jolivet PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A,Mat *v) 32845ea7661aSPierre Jolivet { 32855ea7661aSPierre Jolivet Mat_SeqDense *a = (Mat_SeqDense*)A->data; 32865ea7661aSPierre Jolivet 32875ea7661aSPierre Jolivet PetscFunctionBegin; 328828b400f6SJacob Faibussowitsch PetscCheck(a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetSubMatrix() first"); 328928b400f6SJacob Faibussowitsch PetscCheck(a->cmat,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column matrix"); 329008401ef6SPierre Jolivet PetscCheck(*v == a->cmat,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not the matrix obtained from MatDenseGetSubMatrix()"); 32915ea7661aSPierre Jolivet a->matinuse = 0; 32929566063dSJacob Faibussowitsch PetscCall(MatDenseResetArray(a->cmat)); 32935ea7661aSPierre Jolivet *v = NULL; 32945ea7661aSPierre Jolivet PetscFunctionReturn(0); 32955ea7661aSPierre Jolivet } 32965ea7661aSPierre Jolivet 32970bad9183SKris Buschelman /*MC 3298fafad747SKris Buschelman MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices. 32990bad9183SKris Buschelman 33000bad9183SKris Buschelman Options Database Keys: 33010bad9183SKris Buschelman . -mat_type seqdense - sets the matrix type to "seqdense" during a call to MatSetFromOptions() 33020bad9183SKris Buschelman 33030bad9183SKris Buschelman Level: beginner 33040bad9183SKris Buschelman 3305db781477SPatrick Sanan .seealso: `MatCreateSeqDense()` 330689665df3SBarry Smith 33070bad9183SKris Buschelman M*/ 3308ca15aa20SStefano Zampini PetscErrorCode MatCreate_SeqDense(Mat B) 3309273d9f13SBarry Smith { 3310273d9f13SBarry Smith Mat_SeqDense *b; 33117c334f02SBarry Smith PetscMPIInt size; 3312273d9f13SBarry Smith 3313273d9f13SBarry Smith PetscFunctionBegin; 33149566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)B),&size)); 331508401ef6SPierre Jolivet PetscCheck(size <= 1,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Comm must be of size 1"); 331655659b69SBarry Smith 33179566063dSJacob Faibussowitsch PetscCall(PetscNewLog(B,&b)); 33189566063dSJacob Faibussowitsch PetscCall(PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps))); 331944cd7ae7SLois Curfman McInnes B->data = (void*)b; 332018f449edSLois Curfman McInnes 3321273d9f13SBarry Smith b->roworiented = PETSC_TRUE; 33224e220ebcSLois Curfman McInnes 33239566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatQRFactor_C",MatQRFactor_SeqDense)); 33249566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetLDA_C",MatDenseGetLDA_SeqDense)); 33259566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseSetLDA_C",MatDenseSetLDA_SeqDense)); 33269566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArray_C",MatDenseGetArray_SeqDense)); 33279566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArray_C",MatDenseRestoreArray_SeqDense)); 33289566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDensePlaceArray_C",MatDensePlaceArray_SeqDense)); 33299566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseResetArray_C",MatDenseResetArray_SeqDense)); 33309566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseReplaceArray_C",MatDenseReplaceArray_SeqDense)); 33319566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayRead_C",MatDenseGetArray_SeqDense)); 33329566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayRead_C",MatDenseRestoreArray_SeqDense)); 33339566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayWrite_C",MatDenseGetArray_SeqDense)); 33349566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayWrite_C",MatDenseRestoreArray_SeqDense)); 33359566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqaij_C",MatConvert_SeqDense_SeqAIJ)); 33368baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 33379566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_elemental_C",MatConvert_SeqDense_Elemental)); 33388baccfbdSHong Zhang #endif 3339d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK) 33409566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_scalapack_C",MatConvert_Dense_ScaLAPACK)); 3341d24d4204SJose E. Roman #endif 33422bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA) 33439566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqdensecuda_C",MatConvert_SeqDense_SeqDenseCUDA)); 33449566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",MatProductSetFromOptions_SeqDense)); 33459566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdense_C",MatProductSetFromOptions_SeqDense)); 33469566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqdensecuda_C",MatProductSetFromOptions_SeqDense)); 33472bf066beSStefano Zampini #endif 33489566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatSeqDenseSetPreallocation_C",MatSeqDenseSetPreallocation_SeqDense)); 33499566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqdense_C",MatProductSetFromOptions_SeqAIJ_SeqDense)); 33509566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqdense_C",MatProductSetFromOptions_SeqDense)); 33519566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense)); 33529566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqsbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense)); 335396e6d5c4SRichard Tran Mills 33549566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumn_C",MatDenseGetColumn_SeqDense)); 33559566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumn_C",MatDenseRestoreColumn_SeqDense)); 33569566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVec_C",MatDenseGetColumnVec_SeqDense)); 33579566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVec_C",MatDenseRestoreColumnVec_SeqDense)); 33589566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVecRead_C",MatDenseGetColumnVecRead_SeqDense)); 33599566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVecRead_C",MatDenseRestoreColumnVecRead_SeqDense)); 33609566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVecWrite_C",MatDenseGetColumnVecWrite_SeqDense)); 33619566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVecWrite_C",MatDenseRestoreColumnVecWrite_SeqDense)); 33629566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetSubMatrix_C",MatDenseGetSubMatrix_SeqDense)); 33639566063dSJacob Faibussowitsch PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreSubMatrix_C",MatDenseRestoreSubMatrix_SeqDense)); 33649566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)B,MATSEQDENSE)); 33653a40ed3dSBarry Smith PetscFunctionReturn(0); 3366289bc588SBarry Smith } 336786aefd0dSHong Zhang 336886aefd0dSHong Zhang /*@C 3369af53bab2SHong Zhang 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. 337086aefd0dSHong Zhang 337186aefd0dSHong Zhang Not Collective 337286aefd0dSHong Zhang 33735ea7661aSPierre Jolivet Input Parameters: 337486aefd0dSHong Zhang + mat - a MATSEQDENSE or MATMPIDENSE matrix 337586aefd0dSHong Zhang - col - column index 337686aefd0dSHong Zhang 337786aefd0dSHong Zhang Output Parameter: 337886aefd0dSHong Zhang . vals - pointer to the data 337986aefd0dSHong Zhang 338086aefd0dSHong Zhang Level: intermediate 338186aefd0dSHong Zhang 3382db781477SPatrick Sanan .seealso: `MatDenseRestoreColumn()` 338386aefd0dSHong Zhang @*/ 338486aefd0dSHong Zhang PetscErrorCode MatDenseGetColumn(Mat A,PetscInt col,PetscScalar **vals) 338586aefd0dSHong Zhang { 338686aefd0dSHong Zhang PetscFunctionBegin; 3387d5ea218eSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3388d5ea218eSStefano Zampini PetscValidLogicalCollectiveInt(A,col,2); 3389d5ea218eSStefano Zampini PetscValidPointer(vals,3); 3390cac4c232SBarry Smith PetscUseMethod(A,"MatDenseGetColumn_C",(Mat,PetscInt,PetscScalar**),(A,col,vals)); 339186aefd0dSHong Zhang PetscFunctionReturn(0); 339286aefd0dSHong Zhang } 339386aefd0dSHong Zhang 339486aefd0dSHong Zhang /*@C 339586aefd0dSHong Zhang MatDenseRestoreColumn - returns access to a column of a dense matrix which is returned by MatDenseGetColumn(). 339686aefd0dSHong Zhang 339786aefd0dSHong Zhang Not Collective 339886aefd0dSHong Zhang 339986aefd0dSHong Zhang Input Parameter: 340086aefd0dSHong Zhang . mat - a MATSEQDENSE or MATMPIDENSE matrix 340186aefd0dSHong Zhang 340286aefd0dSHong Zhang Output Parameter: 340386aefd0dSHong Zhang . vals - pointer to the data 340486aefd0dSHong Zhang 340586aefd0dSHong Zhang Level: intermediate 340686aefd0dSHong Zhang 3407db781477SPatrick Sanan .seealso: `MatDenseGetColumn()` 340886aefd0dSHong Zhang @*/ 340986aefd0dSHong Zhang PetscErrorCode MatDenseRestoreColumn(Mat A,PetscScalar **vals) 341086aefd0dSHong Zhang { 341186aefd0dSHong Zhang PetscFunctionBegin; 3412d5ea218eSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 3413d5ea218eSStefano Zampini PetscValidPointer(vals,2); 3414cac4c232SBarry Smith PetscUseMethod(A,"MatDenseRestoreColumn_C",(Mat,PetscScalar**),(A,vals)); 341586aefd0dSHong Zhang PetscFunctionReturn(0); 341686aefd0dSHong Zhang } 34176947451fSStefano Zampini 34180f74d2c1SSatish Balay /*@ 34196947451fSStefano Zampini MatDenseGetColumnVec - Gives read-write access to a column of a dense matrix, represented as a Vec. 34206947451fSStefano Zampini 34216947451fSStefano Zampini Collective 34226947451fSStefano Zampini 34235ea7661aSPierre Jolivet Input Parameters: 34246947451fSStefano Zampini + mat - the Mat object 34256947451fSStefano Zampini - col - the column index 34266947451fSStefano Zampini 34276947451fSStefano Zampini Output Parameter: 34286947451fSStefano Zampini . v - the vector 34296947451fSStefano Zampini 34306947451fSStefano Zampini Notes: 34316947451fSStefano Zampini The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVec() when the vector is no longer needed. 34326947451fSStefano Zampini Use MatDenseGetColumnVecRead() to obtain read-only access or MatDenseGetColumnVecWrite() for write-only access. 34336947451fSStefano Zampini 34346947451fSStefano Zampini Level: intermediate 34356947451fSStefano Zampini 3436db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 34376947451fSStefano Zampini @*/ 34386947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVec(Mat A,PetscInt col,Vec *v) 34396947451fSStefano Zampini { 34406947451fSStefano Zampini PetscFunctionBegin; 34416947451fSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 34426947451fSStefano Zampini PetscValidType(A,1); 34436947451fSStefano Zampini PetscValidLogicalCollectiveInt(A,col,2); 34446947451fSStefano Zampini PetscValidPointer(v,3); 344528b400f6SJacob Faibussowitsch PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated"); 34462cf15c64SPierre 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); 3447cac4c232SBarry Smith PetscUseMethod(A,"MatDenseGetColumnVec_C",(Mat,PetscInt,Vec*),(A,col,v)); 34486947451fSStefano Zampini PetscFunctionReturn(0); 34496947451fSStefano Zampini } 34506947451fSStefano Zampini 34510f74d2c1SSatish Balay /*@ 34526947451fSStefano Zampini MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVec(). 34536947451fSStefano Zampini 34546947451fSStefano Zampini Collective 34556947451fSStefano Zampini 34565ea7661aSPierre Jolivet Input Parameters: 34576947451fSStefano Zampini + mat - the Mat object 34586947451fSStefano Zampini . col - the column index 34596947451fSStefano Zampini - v - the Vec object 34606947451fSStefano Zampini 34616947451fSStefano Zampini Level: intermediate 34626947451fSStefano Zampini 3463db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 34646947451fSStefano Zampini @*/ 34656947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVec(Mat A,PetscInt col,Vec *v) 34666947451fSStefano Zampini { 34676947451fSStefano Zampini PetscFunctionBegin; 34686947451fSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 34696947451fSStefano Zampini PetscValidType(A,1); 34706947451fSStefano Zampini PetscValidLogicalCollectiveInt(A,col,2); 347108401ef6SPierre Jolivet PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated"); 34722cf15c64SPierre 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); 3473cac4c232SBarry Smith PetscUseMethod(A,"MatDenseRestoreColumnVec_C",(Mat,PetscInt,Vec*),(A,col,v)); 34746947451fSStefano Zampini PetscFunctionReturn(0); 34756947451fSStefano Zampini } 34766947451fSStefano Zampini 34770f74d2c1SSatish Balay /*@ 34786947451fSStefano Zampini MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a Vec. 34796947451fSStefano Zampini 34806947451fSStefano Zampini Collective 34816947451fSStefano Zampini 34825ea7661aSPierre Jolivet Input Parameters: 34836947451fSStefano Zampini + mat - the Mat object 34846947451fSStefano Zampini - col - the column index 34856947451fSStefano Zampini 34866947451fSStefano Zampini Output Parameter: 34876947451fSStefano Zampini . v - the vector 34886947451fSStefano Zampini 34896947451fSStefano Zampini Notes: 34906947451fSStefano Zampini The vector is owned by PETSc and users cannot modify it. 34916947451fSStefano Zampini Users need to call MatDenseRestoreColumnVecRead() when the vector is no longer needed. 34926947451fSStefano Zampini Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecWrite() for write-only access. 34936947451fSStefano Zampini 34946947451fSStefano Zampini Level: intermediate 34956947451fSStefano Zampini 3496db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 34976947451fSStefano Zampini @*/ 34986947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecRead(Mat A,PetscInt col,Vec *v) 34996947451fSStefano Zampini { 35006947451fSStefano Zampini PetscFunctionBegin; 35016947451fSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 35026947451fSStefano Zampini PetscValidType(A,1); 35036947451fSStefano Zampini PetscValidLogicalCollectiveInt(A,col,2); 35046947451fSStefano Zampini PetscValidPointer(v,3); 350528b400f6SJacob Faibussowitsch PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated"); 35062cf15c64SPierre 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); 3507cac4c232SBarry Smith PetscUseMethod(A,"MatDenseGetColumnVecRead_C",(Mat,PetscInt,Vec*),(A,col,v)); 35086947451fSStefano Zampini PetscFunctionReturn(0); 35096947451fSStefano Zampini } 35106947451fSStefano Zampini 35110f74d2c1SSatish Balay /*@ 35126947451fSStefano Zampini MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecRead(). 35136947451fSStefano Zampini 35146947451fSStefano Zampini Collective 35156947451fSStefano Zampini 35165ea7661aSPierre Jolivet Input Parameters: 35176947451fSStefano Zampini + mat - the Mat object 35186947451fSStefano Zampini . col - the column index 35196947451fSStefano Zampini - v - the Vec object 35206947451fSStefano Zampini 35216947451fSStefano Zampini Level: intermediate 35226947451fSStefano Zampini 3523db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecWrite()` 35246947451fSStefano Zampini @*/ 35256947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecRead(Mat A,PetscInt col,Vec *v) 35266947451fSStefano Zampini { 35276947451fSStefano Zampini PetscFunctionBegin; 35286947451fSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 35296947451fSStefano Zampini PetscValidType(A,1); 35306947451fSStefano Zampini PetscValidLogicalCollectiveInt(A,col,2); 353108401ef6SPierre Jolivet PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated"); 35322cf15c64SPierre 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); 3533cac4c232SBarry Smith PetscUseMethod(A,"MatDenseRestoreColumnVecRead_C",(Mat,PetscInt,Vec*),(A,col,v)); 35346947451fSStefano Zampini PetscFunctionReturn(0); 35356947451fSStefano Zampini } 35366947451fSStefano Zampini 35370f74d2c1SSatish Balay /*@ 35386947451fSStefano Zampini MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a Vec. 35396947451fSStefano Zampini 35406947451fSStefano Zampini Collective 35416947451fSStefano Zampini 35425ea7661aSPierre Jolivet Input Parameters: 35436947451fSStefano Zampini + mat - the Mat object 35446947451fSStefano Zampini - col - the column index 35456947451fSStefano Zampini 35466947451fSStefano Zampini Output Parameter: 35476947451fSStefano Zampini . v - the vector 35486947451fSStefano Zampini 35496947451fSStefano Zampini Notes: 35506947451fSStefano Zampini The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVecWrite() when the vector is no longer needed. 35516947451fSStefano Zampini Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecRead() for read-only access. 35526947451fSStefano Zampini 35536947451fSStefano Zampini Level: intermediate 35546947451fSStefano Zampini 3555db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()` 35566947451fSStefano Zampini @*/ 35576947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecWrite(Mat A,PetscInt col,Vec *v) 35586947451fSStefano Zampini { 35596947451fSStefano Zampini PetscFunctionBegin; 35606947451fSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 35616947451fSStefano Zampini PetscValidType(A,1); 35626947451fSStefano Zampini PetscValidLogicalCollectiveInt(A,col,2); 35636947451fSStefano Zampini PetscValidPointer(v,3); 356428b400f6SJacob Faibussowitsch PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated"); 3565aed4548fSBarry 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); 3566cac4c232SBarry Smith PetscUseMethod(A,"MatDenseGetColumnVecWrite_C",(Mat,PetscInt,Vec*),(A,col,v)); 35676947451fSStefano Zampini PetscFunctionReturn(0); 35686947451fSStefano Zampini } 35696947451fSStefano Zampini 35700f74d2c1SSatish Balay /*@ 35716947451fSStefano Zampini MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecWrite(). 35726947451fSStefano Zampini 35736947451fSStefano Zampini Collective 35746947451fSStefano Zampini 35755ea7661aSPierre Jolivet Input Parameters: 35766947451fSStefano Zampini + mat - the Mat object 35776947451fSStefano Zampini . col - the column index 35786947451fSStefano Zampini - v - the Vec object 35796947451fSStefano Zampini 35806947451fSStefano Zampini Level: intermediate 35816947451fSStefano Zampini 3582db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()` 35836947451fSStefano Zampini @*/ 35846947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A,PetscInt col,Vec *v) 35856947451fSStefano Zampini { 35866947451fSStefano Zampini PetscFunctionBegin; 35876947451fSStefano Zampini PetscValidHeaderSpecific(A,MAT_CLASSID,1); 35886947451fSStefano Zampini PetscValidType(A,1); 35896947451fSStefano Zampini PetscValidLogicalCollectiveInt(A,col,2); 359008401ef6SPierre Jolivet PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated"); 3591aed4548fSBarry Smith PetscCheck(col >= 0 && col < A->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")",col,A->cmap->N); 3592cac4c232SBarry Smith PetscUseMethod(A,"MatDenseRestoreColumnVecWrite_C",(Mat,PetscInt,Vec*),(A,col,v)); 35936947451fSStefano Zampini PetscFunctionReturn(0); 35946947451fSStefano Zampini } 35955ea7661aSPierre Jolivet 35960f74d2c1SSatish Balay /*@ 3597a2748737SPierre Jolivet MatDenseGetSubMatrix - Gives access to a block of rows and columns of a dense matrix, represented as a Mat. 35985ea7661aSPierre Jolivet 35995ea7661aSPierre Jolivet Collective 36005ea7661aSPierre Jolivet 36015ea7661aSPierre Jolivet Input Parameters: 36025ea7661aSPierre Jolivet + mat - the Mat object 3603a2748737SPierre Jolivet . rbegin - the first global row index in the block (if PETSC_DECIDE, is 0) 3604a2748737SPierre Jolivet . rend - the global row index past the last one in the block (if PETSC_DECIDE, is M) 3605a2748737SPierre Jolivet . cbegin - the first global column index in the block (if PETSC_DECIDE, is 0) 3606a2748737SPierre Jolivet - cend - the global column index past the last one in the block (if PETSC_DECIDE, is N) 36075ea7661aSPierre Jolivet 36085ea7661aSPierre Jolivet Output Parameter: 36095ea7661aSPierre Jolivet . v - the matrix 36105ea7661aSPierre Jolivet 36115ea7661aSPierre Jolivet Notes: 36125ea7661aSPierre Jolivet The matrix is owned by PETSc. Users need to call MatDenseRestoreSubMatrix() when the matrix is no longer needed. 3613a2748737SPierre 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. 36145ea7661aSPierre Jolivet 36155ea7661aSPierre Jolivet Level: intermediate 36165ea7661aSPierre Jolivet 3617db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreSubMatrix()` 36185ea7661aSPierre Jolivet @*/ 3619a2748737SPierre Jolivet PetscErrorCode MatDenseGetSubMatrix(Mat A,PetscInt rbegin,PetscInt rend,PetscInt cbegin,PetscInt cend,Mat *v) 36205ea7661aSPierre Jolivet { 36215ea7661aSPierre Jolivet PetscFunctionBegin; 36225ea7661aSPierre Jolivet PetscValidHeaderSpecific(A,MAT_CLASSID,1); 36235ea7661aSPierre Jolivet PetscValidType(A,1); 3624a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A,rbegin,2); 3625a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A,rend,3); 3626a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A,cbegin,4); 3627a2748737SPierre Jolivet PetscValidLogicalCollectiveInt(A,cend,5); 3628a2748737SPierre Jolivet PetscValidPointer(v,6); 3629a2748737SPierre Jolivet if (rbegin == PETSC_DECIDE) rbegin = 0; 3630a2748737SPierre Jolivet if (rend == PETSC_DECIDE) rend = A->rmap->N; 3631a2748737SPierre Jolivet if (cbegin == PETSC_DECIDE) cbegin = 0; 3632a2748737SPierre Jolivet if (cend == PETSC_DECIDE) cend = A->cmap->N; 363328b400f6SJacob Faibussowitsch PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated"); 3634a2748737SPierre 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); 3635a2748737SPierre 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); 3636a2748737SPierre 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); 3637a2748737SPierre 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); 3638a2748737SPierre Jolivet PetscUseMethod(A,"MatDenseGetSubMatrix_C",(Mat,PetscInt,PetscInt,PetscInt,PetscInt,Mat*),(A,rbegin,rend,cbegin,cend,v)); 36395ea7661aSPierre Jolivet PetscFunctionReturn(0); 36405ea7661aSPierre Jolivet } 36415ea7661aSPierre Jolivet 36420f74d2c1SSatish Balay /*@ 36435ea7661aSPierre Jolivet MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from MatDenseGetSubMatrix(). 36445ea7661aSPierre Jolivet 36455ea7661aSPierre Jolivet Collective 36465ea7661aSPierre Jolivet 36475ea7661aSPierre Jolivet Input Parameters: 36485ea7661aSPierre Jolivet + mat - the Mat object 36495ea7661aSPierre Jolivet - v - the Mat object 36505ea7661aSPierre Jolivet 36515ea7661aSPierre Jolivet Level: intermediate 36525ea7661aSPierre Jolivet 3653db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseGetSubMatrix()` 36545ea7661aSPierre Jolivet @*/ 36555ea7661aSPierre Jolivet PetscErrorCode MatDenseRestoreSubMatrix(Mat A,Mat *v) 36565ea7661aSPierre Jolivet { 36575ea7661aSPierre Jolivet PetscFunctionBegin; 36585ea7661aSPierre Jolivet PetscValidHeaderSpecific(A,MAT_CLASSID,1); 36595ea7661aSPierre Jolivet PetscValidType(A,1); 36605ea7661aSPierre Jolivet PetscValidPointer(v,2); 3661cac4c232SBarry Smith PetscUseMethod(A,"MatDenseRestoreSubMatrix_C",(Mat,Mat*),(A,v)); 36625ea7661aSPierre Jolivet PetscFunctionReturn(0); 36635ea7661aSPierre Jolivet } 36648a9c020eSBarry Smith 36658a9c020eSBarry Smith #include <petscblaslapack.h> 36668a9c020eSBarry Smith #include <petsc/private/kernels/blockinvert.h> 36678a9c020eSBarry Smith 36688a9c020eSBarry Smith PetscErrorCode MatSeqDenseInvert(Mat A) 36698a9c020eSBarry Smith { 36708a9c020eSBarry Smith Mat_SeqDense *a = (Mat_SeqDense*) A->data; 36718a9c020eSBarry Smith PetscInt bs = A->rmap->n; 36728a9c020eSBarry Smith MatScalar *values = a->v; 36738a9c020eSBarry Smith const PetscReal shift = 0.0; 36748a9c020eSBarry Smith PetscBool allowzeropivot = PetscNot(A->erroriffailure),zeropivotdetected=PETSC_FALSE; 36758a9c020eSBarry Smith 36768a9c020eSBarry Smith PetscFunctionBegin; 36778a9c020eSBarry Smith /* factor and invert each block */ 36788a9c020eSBarry Smith switch (bs) { 36798a9c020eSBarry Smith case 1: 36808a9c020eSBarry Smith values[0] = (PetscScalar)1.0 / (values[0] + shift); 36818a9c020eSBarry Smith break; 36828a9c020eSBarry Smith case 2: 36838a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_2(values,shift,allowzeropivot,&zeropivotdetected)); 36848a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 36858a9c020eSBarry Smith break; 36868a9c020eSBarry Smith case 3: 36878a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_3(values,shift,allowzeropivot,&zeropivotdetected)); 36888a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 36898a9c020eSBarry Smith break; 36908a9c020eSBarry Smith case 4: 36918a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_4(values,shift,allowzeropivot,&zeropivotdetected)); 36928a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 36938a9c020eSBarry Smith break; 36948a9c020eSBarry Smith case 5: 36958a9c020eSBarry Smith { 36968a9c020eSBarry Smith PetscScalar work[25]; 36978a9c020eSBarry Smith PetscInt ipvt[5]; 36988a9c020eSBarry Smith 36998a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_5(values,ipvt,work,shift,allowzeropivot,&zeropivotdetected)); 37008a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 37018a9c020eSBarry Smith } 37028a9c020eSBarry Smith break; 37038a9c020eSBarry Smith case 6: 37048a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_6(values,shift,allowzeropivot,&zeropivotdetected)); 37058a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 37068a9c020eSBarry Smith break; 37078a9c020eSBarry Smith case 7: 37088a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A_7(values,shift,allowzeropivot,&zeropivotdetected)); 37098a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 37108a9c020eSBarry Smith break; 37118a9c020eSBarry Smith default: 37128a9c020eSBarry Smith { 37138a9c020eSBarry Smith PetscInt *v_pivots,*IJ,j; 37148a9c020eSBarry Smith PetscScalar *v_work; 37158a9c020eSBarry Smith 37168a9c020eSBarry Smith PetscCall(PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ)); 37178a9c020eSBarry Smith for (j=0; j<bs; j++) { 37188a9c020eSBarry Smith IJ[j] = j; 37198a9c020eSBarry Smith } 37208a9c020eSBarry Smith PetscCall(PetscKernel_A_gets_inverse_A(bs,values,v_pivots,v_work,allowzeropivot,&zeropivotdetected)); 37218a9c020eSBarry Smith if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT; 37228a9c020eSBarry Smith PetscCall(PetscFree3(v_work,v_pivots,IJ)); 37238a9c020eSBarry Smith } 37248a9c020eSBarry Smith } 37258a9c020eSBarry Smith PetscFunctionReturn(0); 37268a9c020eSBarry Smith } 3727