xref: /petsc/src/mat/impls/dense/seq/dense.c (revision 2cf15c6421967b9c0d9cb8dc1db2ac3aee9bb19e)
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   }
3339566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nz));
3349566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&v));
3353a40ed3dSBarry Smith   PetscFunctionReturn(0);
33680cd9d93SLois Curfman McInnes }
33780cd9d93SLois Curfman McInnes 
338e0877f53SBarry Smith static PetscErrorCode MatIsHermitian_SeqDense(Mat A,PetscReal rtol,PetscBool  *fl)
3391cbb95d3SBarry Smith {
3401cbb95d3SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
341ca15aa20SStefano Zampini   PetscInt          i,j,m = A->rmap->n,N = a->lda;
342ca15aa20SStefano Zampini   const PetscScalar *v;
3431cbb95d3SBarry Smith 
3441cbb95d3SBarry Smith   PetscFunctionBegin;
3451cbb95d3SBarry Smith   *fl = PETSC_FALSE;
346d0f46423SBarry Smith   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
3479566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&v));
3481cbb95d3SBarry Smith   for (i=0; i<m; i++) {
349ca15aa20SStefano Zampini     for (j=i; j<m; j++) {
350637a0070SStefano Zampini       if (PetscAbsScalar(v[i+j*N] - PetscConj(v[j+i*N])) > rtol) {
351637a0070SStefano Zampini         goto restore;
3521cbb95d3SBarry Smith       }
3531cbb95d3SBarry Smith     }
354637a0070SStefano Zampini   }
3551cbb95d3SBarry Smith   *fl  = PETSC_TRUE;
356637a0070SStefano Zampini restore:
3579566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&v));
358637a0070SStefano Zampini   PetscFunctionReturn(0);
359637a0070SStefano Zampini }
360637a0070SStefano Zampini 
361637a0070SStefano Zampini static PetscErrorCode MatIsSymmetric_SeqDense(Mat A,PetscReal rtol,PetscBool  *fl)
362637a0070SStefano Zampini {
363637a0070SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
364637a0070SStefano Zampini   PetscInt          i,j,m = A->rmap->n,N = a->lda;
365637a0070SStefano Zampini   const PetscScalar *v;
366637a0070SStefano Zampini 
367637a0070SStefano Zampini   PetscFunctionBegin;
368637a0070SStefano Zampini   *fl = PETSC_FALSE;
369637a0070SStefano Zampini   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
3709566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&v));
371637a0070SStefano Zampini   for (i=0; i<m; i++) {
372637a0070SStefano Zampini     for (j=i; j<m; j++) {
373637a0070SStefano Zampini       if (PetscAbsScalar(v[i+j*N] - v[j+i*N]) > rtol) {
374637a0070SStefano Zampini         goto restore;
375637a0070SStefano Zampini       }
376637a0070SStefano Zampini     }
377637a0070SStefano Zampini   }
378637a0070SStefano Zampini   *fl  = PETSC_TRUE;
379637a0070SStefano Zampini restore:
3809566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&v));
3811cbb95d3SBarry Smith   PetscFunctionReturn(0);
3821cbb95d3SBarry Smith }
3831cbb95d3SBarry Smith 
384ca15aa20SStefano Zampini PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi,Mat A,MatDuplicateOption cpvalues)
385b24902e0SBarry Smith {
386ca15aa20SStefano Zampini   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
38723fc5dcaSStefano Zampini   PetscInt       lda = (PetscInt)mat->lda,j,m,nlda = lda;
38875f6d85dSStefano Zampini   PetscBool      isdensecpu;
389b24902e0SBarry Smith 
390b24902e0SBarry Smith   PetscFunctionBegin;
3919566063dSJacob Faibussowitsch   PetscCall(PetscLayoutReference(A->rmap,&newi->rmap));
3929566063dSJacob Faibussowitsch   PetscCall(PetscLayoutReference(A->cmap,&newi->cmap));
39323fc5dcaSStefano Zampini   if (cpvalues == MAT_SHARE_NONZERO_PATTERN) { /* propagate LDA */
3949566063dSJacob Faibussowitsch     PetscCall(MatDenseSetLDA(newi,lda));
39523fc5dcaSStefano Zampini   }
3969566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)newi,MATSEQDENSE,&isdensecpu));
3979566063dSJacob Faibussowitsch   if (isdensecpu) PetscCall(MatSeqDenseSetPreallocation(newi,NULL));
398b24902e0SBarry Smith   if (cpvalues == MAT_COPY_VALUES) {
399ca15aa20SStefano Zampini     const PetscScalar *av;
400ca15aa20SStefano Zampini     PetscScalar       *v;
401ca15aa20SStefano Zampini 
4029566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A,&av));
4039566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayWrite(newi,&v));
4049566063dSJacob Faibussowitsch     PetscCall(MatDenseGetLDA(newi,&nlda));
405d0f46423SBarry Smith     m    = A->rmap->n;
40623fc5dcaSStefano Zampini     if (lda>m || nlda>m) {
407d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
4089566063dSJacob Faibussowitsch         PetscCall(PetscArraycpy(v+j*nlda,av+j*lda,m));
409b24902e0SBarry Smith       }
410b24902e0SBarry Smith     } else {
4119566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(v,av,A->rmap->n*A->cmap->n));
412b24902e0SBarry Smith     }
4139566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayWrite(newi,&v));
4149566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A,&av));
415b24902e0SBarry Smith   }
416b24902e0SBarry Smith   PetscFunctionReturn(0);
417b24902e0SBarry Smith }
418b24902e0SBarry Smith 
419ca15aa20SStefano Zampini PetscErrorCode MatDuplicate_SeqDense(Mat A,MatDuplicateOption cpvalues,Mat *newmat)
42002cad45dSBarry Smith {
4213a40ed3dSBarry Smith   PetscFunctionBegin;
4229566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A),newmat));
4239566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*newmat,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n));
4249566063dSJacob Faibussowitsch   PetscCall(MatSetType(*newmat,((PetscObject)A)->type_name));
4259566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(*newmat,A,cpvalues));
426b24902e0SBarry Smith   PetscFunctionReturn(0);
427b24902e0SBarry Smith }
428b24902e0SBarry Smith 
429bf5a80bcSToby Isaac static PetscErrorCode MatSolve_SeqDense_Internal_LU(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T)
430289bc588SBarry Smith {
431c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
4324396437dSToby Isaac   PetscBLASInt    info;
43367e560aaSBarry Smith 
4343a40ed3dSBarry Smith   PetscFunctionBegin;
4359566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
4364396437dSToby Isaac   PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_(T ? "T" : "N",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
4379566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
43828b400f6SJacob Faibussowitsch   PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve");
4399566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs*(2.0*m*m - m)));
4404396437dSToby Isaac   PetscFunctionReturn(0);
4414396437dSToby Isaac }
4424396437dSToby Isaac 
4434396437dSToby Isaac static PetscErrorCode MatConjugate_SeqDense(Mat);
4444396437dSToby Isaac 
445bf5a80bcSToby Isaac static PetscErrorCode MatSolve_SeqDense_Internal_Cholesky(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T)
4464396437dSToby Isaac {
4474396437dSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
4484396437dSToby Isaac   PetscBLASInt    info;
4494396437dSToby Isaac 
4504396437dSToby Isaac   PetscFunctionBegin;
451a49dc2a2SStefano Zampini   if (A->spd) {
4529566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A));
4539566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
4548b83055fSJed Brown     PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&nrhs,mat->v,&mat->lda,x,&m,&info));
4559566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
45628b400f6SJacob Faibussowitsch     PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
4579566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A));
458a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
459a49dc2a2SStefano Zampini   } else if (A->hermitian) {
4609566063dSJacob Faibussowitsch     if (T) PetscCall(MatConjugate_SeqDense(A));
4619566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
462a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
4639566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
46428b400f6SJacob Faibussowitsch     PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve");
4659566063dSJacob Faibussowitsch     if (T) PetscCall(MatConjugate_SeqDense(A));
466a49dc2a2SStefano Zampini #endif
467a49dc2a2SStefano Zampini   } else { /* symmetric case */
4689566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
469a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
4709566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
47128b400f6SJacob Faibussowitsch     PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
472a49dc2a2SStefano Zampini   }
4739566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs*(2.0*m*m - m)));
4744396437dSToby Isaac   PetscFunctionReturn(0);
4754396437dSToby Isaac }
47685e2c93fSHong Zhang 
477bf5a80bcSToby Isaac static PetscErrorCode MatSolve_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k)
4784396437dSToby Isaac {
4794396437dSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
4804396437dSToby Isaac   PetscBLASInt    info;
4814396437dSToby Isaac   char            trans;
4824396437dSToby Isaac 
4834396437dSToby Isaac   PetscFunctionBegin;
4844905a7bcSToby Isaac   if (PetscDefined(USE_COMPLEX)) {
4854905a7bcSToby Isaac     trans = 'C';
4864905a7bcSToby Isaac   } else {
4874905a7bcSToby Isaac     trans = 'T';
4884905a7bcSToby Isaac   }
4899566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
490bf5a80bcSToby Isaac   PetscStackCallBLAS("LAPACKormqr",LAPACKormqr_("L", &trans, &m,&nrhs,&mat->rank,mat->v,&mat->lda,mat->tau,x,&ldx,mat->fwork,&mat->lfwork,&info));
4919566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
49228b400f6SJacob Faibussowitsch   PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"ORMQR - Bad orthogonal transform");
4939566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
494bf5a80bcSToby Isaac   PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U", "N", "N", &mat->rank,&nrhs,mat->v,&mat->lda,x,&ldx,&info));
4959566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
49628b400f6SJacob Faibussowitsch   PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"TRTRS - Bad triangular solve");
4974905a7bcSToby Isaac   for (PetscInt j = 0; j < nrhs; j++) {
4984905a7bcSToby Isaac     for (PetscInt i = mat->rank; i < k; i++) {
499bf5a80bcSToby Isaac       x[j*ldx + i] = 0.;
5004905a7bcSToby Isaac     }
5014905a7bcSToby Isaac   }
5029566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs*(4.0*m*mat->rank - PetscSqr(mat->rank))));
5034905a7bcSToby Isaac   PetscFunctionReturn(0);
5044905a7bcSToby Isaac }
5054905a7bcSToby Isaac 
506bf5a80bcSToby Isaac static PetscErrorCode MatSolveTranspose_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k)
5074905a7bcSToby Isaac {
5084396437dSToby Isaac   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
5094396437dSToby Isaac   PetscBLASInt      info;
5104396437dSToby Isaac 
5114396437dSToby Isaac   PetscFunctionBegin;
5124396437dSToby Isaac   if (A->rmap->n == A->cmap->n && mat->rank == A->rmap->n) {
5139566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
514bf5a80bcSToby Isaac     PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U", "T", "N", &m,&nrhs,mat->v,&mat->lda,x,&ldx,&info));
5159566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
51628b400f6SJacob Faibussowitsch     PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"TRTRS - Bad triangular solve");
5179566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A));
5189566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
519bf5a80bcSToby Isaac     PetscStackCallBLAS("LAPACKormqr",LAPACKormqr_("L", "N", &m,&nrhs,&mat->rank,mat->v,&mat->lda,mat->tau,x,&ldx,mat->fwork,&mat->lfwork,&info));
5209566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
52128b400f6SJacob Faibussowitsch     PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"ORMQR - Bad orthogonal transform");
5229566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A));
5234396437dSToby Isaac   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"QR factored matrix cannot be used for transpose solve");
5249566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs*(4.0*m*mat->rank - PetscSqr(mat->rank))));
5254396437dSToby Isaac   PetscFunctionReturn(0);
5264396437dSToby Isaac }
5274396437dSToby Isaac 
5284396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_SetUp(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k)
5294396437dSToby Isaac {
5304396437dSToby Isaac   Mat_SeqDense      *mat = (Mat_SeqDense *) A->data;
5314905a7bcSToby Isaac   PetscScalar       *y;
5324905a7bcSToby Isaac   PetscBLASInt      m=0, k=0;
5334905a7bcSToby Isaac 
5344905a7bcSToby Isaac   PetscFunctionBegin;
5359566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
5369566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&k));
5374905a7bcSToby Isaac   if (k < m) {
5389566063dSJacob Faibussowitsch     PetscCall(VecCopy(xx, mat->qrrhs));
5399566063dSJacob Faibussowitsch     PetscCall(VecGetArray(mat->qrrhs,&y));
5404905a7bcSToby Isaac   } else {
5419566063dSJacob Faibussowitsch     PetscCall(VecCopy(xx, yy));
5429566063dSJacob Faibussowitsch     PetscCall(VecGetArray(yy,&y));
5434905a7bcSToby Isaac   }
5444396437dSToby Isaac   *_y = y;
5454396437dSToby Isaac   *_k = k;
5464396437dSToby Isaac   *_m = m;
5474396437dSToby Isaac   PetscFunctionReturn(0);
5484396437dSToby Isaac }
5494396437dSToby Isaac 
5504396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_TearDown(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k)
5514396437dSToby Isaac {
5524396437dSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense *) A->data;
55342e9364cSSatish Balay   PetscScalar    *y = NULL;
5544396437dSToby Isaac   PetscBLASInt   m, k;
5554396437dSToby Isaac 
5564396437dSToby Isaac   PetscFunctionBegin;
5574396437dSToby Isaac   y   = *_y;
5584396437dSToby Isaac   *_y = NULL;
5594396437dSToby Isaac   k   = *_k;
5604396437dSToby Isaac   m   = *_m;
5614905a7bcSToby Isaac   if (k < m) {
5624905a7bcSToby Isaac     PetscScalar *yv;
5639566063dSJacob Faibussowitsch     PetscCall(VecGetArray(yy,&yv));
5649566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(yv, y, k));
5659566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(yy,&yv));
5669566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(mat->qrrhs, &y));
5674905a7bcSToby Isaac   } else {
5689566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(yy,&y));
5694905a7bcSToby Isaac   }
5704905a7bcSToby Isaac   PetscFunctionReturn(0);
5714905a7bcSToby Isaac }
5724905a7bcSToby Isaac 
5734396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_LU(Mat A, Vec xx, Vec yy)
5744396437dSToby Isaac {
57542e9364cSSatish Balay   PetscScalar    *y = NULL;
57642e9364cSSatish Balay   PetscBLASInt   m = 0, k = 0;
5774396437dSToby Isaac 
5784396437dSToby Isaac   PetscFunctionBegin;
5799566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
5809566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_FALSE));
5819566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
5824396437dSToby Isaac   PetscFunctionReturn(0);
5834396437dSToby Isaac }
5844396437dSToby Isaac 
5854396437dSToby Isaac static PetscErrorCode MatSolveTranspose_SeqDense_LU(Mat A, Vec xx, Vec yy)
5864396437dSToby Isaac {
58742e9364cSSatish Balay   PetscScalar    *y = NULL;
58842e9364cSSatish Balay   PetscBLASInt   m = 0, k = 0;
5894396437dSToby Isaac 
5904396437dSToby Isaac   PetscFunctionBegin;
5919566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
5929566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_TRUE));
5939566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
5944396437dSToby Isaac   PetscFunctionReturn(0);
5954396437dSToby Isaac }
5964396437dSToby Isaac 
5974396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_Cholesky(Mat A, Vec xx, Vec yy)
5984396437dSToby Isaac {
599e54beecaSStefano Zampini   PetscScalar    *y = NULL;
600e54beecaSStefano Zampini   PetscBLASInt   m = 0, k = 0;
6014396437dSToby Isaac 
6024396437dSToby Isaac   PetscFunctionBegin;
6039566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6049566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_FALSE));
6059566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6064396437dSToby Isaac   PetscFunctionReturn(0);
6074396437dSToby Isaac }
6084396437dSToby Isaac 
6094396437dSToby Isaac static PetscErrorCode MatSolveTranspose_SeqDense_Cholesky(Mat A, Vec xx, Vec yy)
6104396437dSToby Isaac {
611e54beecaSStefano Zampini   PetscScalar    *y = NULL;
612e54beecaSStefano Zampini   PetscBLASInt   m = 0, k = 0;
6134396437dSToby Isaac 
6144396437dSToby Isaac   PetscFunctionBegin;
6159566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6169566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_TRUE));
6179566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6184396437dSToby Isaac   PetscFunctionReturn(0);
6194396437dSToby Isaac }
6204396437dSToby Isaac 
6214396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_QR(Mat A, Vec xx, Vec yy)
6224396437dSToby Isaac {
623e54beecaSStefano Zampini   PetscScalar    *y = NULL;
624e54beecaSStefano Zampini   PetscBLASInt   m = 0, k = 0;
6254396437dSToby Isaac 
6264396437dSToby Isaac   PetscFunctionBegin;
6279566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6289566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_QR(A, y, PetscMax(m,k), m, 1, k));
6299566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6304396437dSToby Isaac   PetscFunctionReturn(0);
6314396437dSToby Isaac }
6324396437dSToby Isaac 
6334396437dSToby Isaac static PetscErrorCode MatSolveTranspose_SeqDense_QR(Mat A, Vec xx, Vec yy)
6344396437dSToby Isaac {
63542e9364cSSatish Balay   PetscScalar    *y = NULL;
63642e9364cSSatish Balay   PetscBLASInt   m = 0, k = 0;
6374396437dSToby Isaac 
6384396437dSToby Isaac   PetscFunctionBegin;
6399566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6409566063dSJacob Faibussowitsch   PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, PetscMax(m,k), m, 1, k));
6419566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6424396437dSToby Isaac   PetscFunctionReturn(0);
6434396437dSToby Isaac }
6444396437dSToby Isaac 
645bf5a80bcSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_SetUp(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k)
6464905a7bcSToby Isaac {
6474905a7bcSToby Isaac   const PetscScalar *b;
6484396437dSToby Isaac   PetscScalar       *y;
649bf5a80bcSToby Isaac   PetscInt          n, _ldb, _ldx;
650bf5a80bcSToby Isaac   PetscBLASInt      nrhs=0,m=0,k=0,ldb=0,ldx=0,ldy=0;
6514905a7bcSToby Isaac 
6524905a7bcSToby Isaac   PetscFunctionBegin;
6536280eecaSJose E. Roman   *_ldy=0; *_m=0; *_nrhs=0; *_k=0; *_y = NULL;
6549566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
6559566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&k));
6569566063dSJacob Faibussowitsch   PetscCall(MatGetSize(B,NULL,&n));
6579566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(n,&nrhs));
6589566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(B,&_ldb));
6599566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldb, &ldb));
6609566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(X,&_ldx));
6619566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldx, &ldx));
662bf5a80bcSToby Isaac   if (ldx < m) {
6639566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(B,&b));
6649566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nrhs * m, &y));
665bf5a80bcSToby Isaac     if (ldb == m) {
6669566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(y,b,ldb*nrhs));
6674905a7bcSToby Isaac     } else {
6684905a7bcSToby Isaac       for (PetscInt j = 0; j < nrhs; j++) {
6699566063dSJacob Faibussowitsch         PetscCall(PetscArraycpy(&y[j*m],&b[j*ldb],m));
6704905a7bcSToby Isaac       }
6714905a7bcSToby Isaac     }
672bf5a80bcSToby Isaac     ldy = m;
6739566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(B,&b));
6744905a7bcSToby Isaac   } else {
675bf5a80bcSToby Isaac     if (ldb == ldx) {
6769566063dSJacob Faibussowitsch       PetscCall(MatCopy(B, X, SAME_NONZERO_PATTERN));
6779566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(X,&y));
6784905a7bcSToby Isaac     } else {
6799566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(X,&y));
6809566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArrayRead(B,&b));
6814905a7bcSToby Isaac       for (PetscInt j = 0; j < nrhs; j++) {
6829566063dSJacob Faibussowitsch         PetscCall(PetscArraycpy(&y[j*ldx],&b[j*ldb],m));
6834905a7bcSToby Isaac       }
6849566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArrayRead(B,&b));
6854905a7bcSToby Isaac     }
686bf5a80bcSToby Isaac     ldy = ldx;
6874905a7bcSToby Isaac   }
6884396437dSToby Isaac   *_y    = y;
689bf5a80bcSToby Isaac   *_ldy = ldy;
6904396437dSToby Isaac   *_k    = k;
6914396437dSToby Isaac   *_m    = m;
6924396437dSToby Isaac   *_nrhs = nrhs;
6934396437dSToby Isaac   PetscFunctionReturn(0);
6944396437dSToby Isaac }
6954396437dSToby Isaac 
696bf5a80bcSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_TearDown(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k)
6974396437dSToby Isaac {
6984396437dSToby Isaac   PetscScalar       *y;
699bf5a80bcSToby Isaac   PetscInt          _ldx;
700bf5a80bcSToby Isaac   PetscBLASInt      k,ldy,nrhs,ldx=0;
7014396437dSToby Isaac 
7024396437dSToby Isaac   PetscFunctionBegin;
7034396437dSToby Isaac   y    = *_y;
7044396437dSToby Isaac   *_y  = NULL;
7054396437dSToby Isaac   k    = *_k;
706bf5a80bcSToby Isaac   ldy = *_ldy;
7074396437dSToby Isaac   nrhs = *_nrhs;
7089566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(X,&_ldx));
7099566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldx, &ldx));
710bf5a80bcSToby Isaac   if (ldx != ldy) {
7114905a7bcSToby Isaac     PetscScalar *xv;
7129566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArray(X,&xv));
7134905a7bcSToby Isaac     for (PetscInt j = 0; j < nrhs; j++) {
7149566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(&xv[j*ldx],&y[j*ldy],k));
7154905a7bcSToby Isaac     }
7169566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(X,&xv));
7179566063dSJacob Faibussowitsch     PetscCall(PetscFree(y));
7184905a7bcSToby Isaac   } else {
7199566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(X,&y));
7204905a7bcSToby Isaac   }
72185e2c93fSHong Zhang   PetscFunctionReturn(0);
72285e2c93fSHong Zhang }
72385e2c93fSHong Zhang 
7244396437dSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_LU(Mat A, Mat B, Mat X)
7254396437dSToby Isaac {
7264396437dSToby Isaac   PetscScalar    *y;
727bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
7284396437dSToby Isaac 
7294396437dSToby Isaac   PetscFunctionBegin;
7309566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7319566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_FALSE));
7329566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7334396437dSToby Isaac   PetscFunctionReturn(0);
7344396437dSToby Isaac }
7354396437dSToby Isaac 
7364396437dSToby Isaac static PetscErrorCode MatMatSolveTranspose_SeqDense_LU(Mat A, Mat B, Mat X)
7374396437dSToby Isaac {
7384396437dSToby Isaac   PetscScalar    *y;
739bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
7404396437dSToby Isaac 
7414396437dSToby Isaac   PetscFunctionBegin;
7429566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7439566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_TRUE));
7449566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7454396437dSToby Isaac   PetscFunctionReturn(0);
7464396437dSToby Isaac }
7474396437dSToby Isaac 
7484396437dSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_Cholesky(Mat A, Mat B, Mat X)
7494396437dSToby Isaac {
7504396437dSToby Isaac   PetscScalar    *y;
751bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
7524396437dSToby Isaac 
7534396437dSToby Isaac   PetscFunctionBegin;
7549566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7559566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_FALSE));
7569566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7574396437dSToby Isaac   PetscFunctionReturn(0);
7584396437dSToby Isaac }
7594396437dSToby Isaac 
7604396437dSToby Isaac static PetscErrorCode MatMatSolveTranspose_SeqDense_Cholesky(Mat A, Mat B, Mat X)
7614396437dSToby Isaac {
7624396437dSToby Isaac   PetscScalar    *y;
763bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
7644396437dSToby Isaac 
7654396437dSToby Isaac   PetscFunctionBegin;
7669566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7679566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_TRUE));
7689566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7694396437dSToby Isaac   PetscFunctionReturn(0);
7704396437dSToby Isaac }
7714396437dSToby Isaac 
7724396437dSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_QR(Mat A, Mat B, Mat X)
7734396437dSToby Isaac {
7744396437dSToby Isaac   PetscScalar    *y;
775bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
7764396437dSToby Isaac 
7774396437dSToby Isaac   PetscFunctionBegin;
7789566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7799566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k));
7809566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7814396437dSToby Isaac   PetscFunctionReturn(0);
7824396437dSToby Isaac }
7834396437dSToby Isaac 
7844396437dSToby Isaac static PetscErrorCode MatMatSolveTranspose_SeqDense_QR(Mat A, Mat B, Mat X)
7854396437dSToby Isaac {
7864396437dSToby Isaac   PetscScalar    *y;
787bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
7884396437dSToby Isaac 
7894396437dSToby Isaac   PetscFunctionBegin;
7909566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7919566063dSJacob Faibussowitsch   PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k));
7929566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7934396437dSToby Isaac   PetscFunctionReturn(0);
7944396437dSToby Isaac }
7954396437dSToby Isaac 
79600121966SStefano Zampini static PetscErrorCode MatConjugate_SeqDense(Mat);
79700121966SStefano Zampini 
798db4efbfdSBarry Smith /* ---------------------------------------------------------------*/
799db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots,
800db4efbfdSBarry Smith    rather than put it in the Mat->row slot.*/
801ca15aa20SStefano Zampini PetscErrorCode MatLUFactor_SeqDense(Mat A,IS row,IS col,const MatFactorInfo *minfo)
802db4efbfdSBarry Smith {
803db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
804db4efbfdSBarry Smith   PetscBLASInt   n,m,info;
805db4efbfdSBarry Smith 
806db4efbfdSBarry Smith   PetscFunctionBegin;
8079566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
8089566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
809db4efbfdSBarry Smith   if (!mat->pivots) {
8109566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(A->rmap->n,&mat->pivots));
8119566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt)));
812db4efbfdSBarry Smith   }
813db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
8149566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
8158b83055fSJed Brown   PetscStackCallBLAS("LAPACKgetrf",LAPACKgetrf_(&m,&n,mat->v,&mat->lda,mat->pivots,&info));
8169566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
8178e57ea43SSatish Balay 
81808401ef6SPierre Jolivet   PetscCheck(info>=0,PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to LU factorization");
81908401ef6SPierre Jolivet   PetscCheck(info<=0,PETSC_COMM_SELF,PETSC_ERR_MAT_LU_ZRPVT,"Bad LU factorization");
8208208b9aeSStefano Zampini 
8214396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_LU;
8224396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_LU;
8234396437dSToby Isaac   A->ops->solvetranspose    = MatSolveTranspose_SeqDense_LU;
8244396437dSToby Isaac   A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_LU;
825d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_LU;
826db4efbfdSBarry Smith 
8279566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
8289566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC,&A->solvertype));
829f6224b95SHong Zhang 
8309566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops((2.0*A->cmap->n*A->cmap->n*A->cmap->n)/3));
831db4efbfdSBarry Smith   PetscFunctionReturn(0);
832db4efbfdSBarry Smith }
833db4efbfdSBarry Smith 
8344396437dSToby Isaac static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
8354396437dSToby Isaac {
8364396437dSToby Isaac   MatFactorInfo  info;
8374396437dSToby Isaac 
8384396437dSToby Isaac   PetscFunctionBegin;
8399566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES));
8409566063dSJacob Faibussowitsch   PetscCall((*fact->ops->lufactor)(fact,NULL,NULL,&info));
8414396437dSToby Isaac   PetscFunctionReturn(0);
8424396437dSToby Isaac }
8434396437dSToby Isaac 
8444396437dSToby Isaac PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,IS col,const MatFactorInfo *info)
8454396437dSToby Isaac {
8464396437dSToby Isaac   PetscFunctionBegin;
8474396437dSToby Isaac   fact->preallocated           = PETSC_TRUE;
8484396437dSToby Isaac   fact->assembled              = PETSC_TRUE;
8494396437dSToby Isaac   fact->ops->lufactornumeric   = MatLUFactorNumeric_SeqDense;
8504396437dSToby Isaac   PetscFunctionReturn(0);
8514396437dSToby Isaac }
8524396437dSToby Isaac 
853a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */
854ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactor_SeqDense(Mat A,IS perm,const MatFactorInfo *factinfo)
855db4efbfdSBarry Smith {
856db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
857c5df96a5SBarry Smith   PetscBLASInt   info,n;
858db4efbfdSBarry Smith 
859db4efbfdSBarry Smith   PetscFunctionBegin;
8609566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
861db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
862a49dc2a2SStefano Zampini   if (A->spd) {
8639566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
8648b83055fSJed Brown     PetscStackCallBLAS("LAPACKpotrf",LAPACKpotrf_("L",&n,mat->v,&mat->lda,&info));
8659566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
866a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
867a49dc2a2SStefano Zampini   } else if (A->hermitian) {
868a49dc2a2SStefano Zampini     if (!mat->pivots) {
8699566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(A->rmap->n,&mat->pivots));
8709566063dSJacob Faibussowitsch       PetscCall(PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt)));
871a49dc2a2SStefano Zampini     }
872a49dc2a2SStefano Zampini     if (!mat->fwork) {
873a49dc2a2SStefano Zampini       PetscScalar dummy;
874a49dc2a2SStefano Zampini 
875a49dc2a2SStefano Zampini       mat->lfwork = -1;
8769566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
877a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
8789566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
879a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
8809566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(mat->lfwork,&mat->fwork));
8819566063dSJacob Faibussowitsch       PetscCall(PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt)));
882a49dc2a2SStefano Zampini     }
8839566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
884a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
8859566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
886a49dc2a2SStefano Zampini #endif
887a49dc2a2SStefano Zampini   } else { /* symmetric case */
888a49dc2a2SStefano Zampini     if (!mat->pivots) {
8899566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(A->rmap->n,&mat->pivots));
8909566063dSJacob Faibussowitsch       PetscCall(PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt)));
891a49dc2a2SStefano Zampini     }
892a49dc2a2SStefano Zampini     if (!mat->fwork) {
893a49dc2a2SStefano Zampini       PetscScalar dummy;
894a49dc2a2SStefano Zampini 
895a49dc2a2SStefano Zampini       mat->lfwork = -1;
8969566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
897a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
8989566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
899a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
9009566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(mat->lfwork,&mat->fwork));
9019566063dSJacob Faibussowitsch       PetscCall(PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt)));
902a49dc2a2SStefano Zampini     }
9039566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
904a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
9059566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
906a49dc2a2SStefano Zampini   }
90728b400f6SJacob Faibussowitsch   PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad factorization: zero pivot in row %" PetscInt_FMT,(PetscInt)info-1);
9088208b9aeSStefano Zampini 
9094396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_Cholesky;
9104396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_Cholesky;
9114396437dSToby Isaac   A->ops->solvetranspose    = MatSolveTranspose_SeqDense_Cholesky;
9124396437dSToby Isaac   A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_Cholesky;
913d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_CHOLESKY;
9142205254eSKarl Rupp 
9159566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
9169566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC,&A->solvertype));
917f6224b95SHong Zhang 
9189566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0));
919db4efbfdSBarry Smith   PetscFunctionReturn(0);
920db4efbfdSBarry Smith }
921db4efbfdSBarry Smith 
9224396437dSToby Isaac static PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
923db4efbfdSBarry Smith {
924db4efbfdSBarry Smith   MatFactorInfo  info;
925db4efbfdSBarry Smith 
926db4efbfdSBarry Smith   PetscFunctionBegin;
927db4efbfdSBarry Smith   info.fill = 1.0;
9282205254eSKarl Rupp 
9299566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES));
9309566063dSJacob Faibussowitsch   PetscCall((*fact->ops->choleskyfactor)(fact,NULL,&info));
931db4efbfdSBarry Smith   PetscFunctionReturn(0);
932db4efbfdSBarry Smith }
933db4efbfdSBarry Smith 
934ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info)
935db4efbfdSBarry Smith {
936db4efbfdSBarry Smith   PetscFunctionBegin;
937c3ef05f6SHong Zhang   fact->assembled                  = PETSC_TRUE;
9381bbcc794SSatish Balay   fact->preallocated               = PETSC_TRUE;
939719d5645SBarry Smith   fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense;
940db4efbfdSBarry Smith   PetscFunctionReturn(0);
941db4efbfdSBarry Smith }
942db4efbfdSBarry Smith 
943bf5a80bcSToby Isaac PetscErrorCode MatQRFactor_SeqDense(Mat A,IS col,const MatFactorInfo *minfo)
9444905a7bcSToby Isaac {
9454905a7bcSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
9464905a7bcSToby Isaac   PetscBLASInt   n,m,info, min, max;
9474905a7bcSToby Isaac 
9484905a7bcSToby Isaac   PetscFunctionBegin;
9499566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
9509566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
9514396437dSToby Isaac   max = PetscMax(m, n);
9524396437dSToby Isaac   min = PetscMin(m, n);
9534905a7bcSToby Isaac   if (!mat->tau) {
9549566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(min,&mat->tau));
9559566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)A,min*sizeof(PetscScalar)));
9564396437dSToby Isaac   }
9574396437dSToby Isaac   if (!mat->pivots) {
9589566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n,&mat->pivots));
9599566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)A,n*sizeof(PetscScalar)));
9604396437dSToby Isaac   }
9614396437dSToby Isaac   if (!mat->qrrhs) {
9629566063dSJacob Faibussowitsch     PetscCall(MatCreateVecs(A, NULL, &(mat->qrrhs)));
9634905a7bcSToby Isaac   }
9644905a7bcSToby Isaac   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
9654905a7bcSToby Isaac   if (!mat->fwork) {
9664905a7bcSToby Isaac     PetscScalar dummy;
9674905a7bcSToby Isaac 
9684905a7bcSToby Isaac     mat->lfwork = -1;
9699566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
9704905a7bcSToby Isaac     PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&m,&n,mat->v,&mat->lda,mat->tau,&dummy,&mat->lfwork,&info));
9719566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
9724905a7bcSToby Isaac     mat->lfwork = (PetscInt)PetscRealPart(dummy);
9739566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(mat->lfwork,&mat->fwork));
9749566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt)));
9754905a7bcSToby Isaac   }
9769566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
9774905a7bcSToby Isaac   PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&m,&n,mat->v,&mat->lda,mat->tau,mat->fwork,&mat->lfwork,&info));
9789566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
97928b400f6SJacob Faibussowitsch   PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to QR factorization");
9804905a7bcSToby 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
9814905a7bcSToby Isaac   mat->rank = min;
9824905a7bcSToby Isaac 
9834396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_QR;
9844396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_QR;
9854905a7bcSToby Isaac   A->factortype             = MAT_FACTOR_QR;
9864905a7bcSToby Isaac   if (m == n) {
9874396437dSToby Isaac     A->ops->solvetranspose    = MatSolveTranspose_SeqDense_QR;
9884396437dSToby Isaac     A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_QR;
9894905a7bcSToby Isaac   }
9904905a7bcSToby Isaac 
9919566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
9929566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC,&A->solvertype));
9934905a7bcSToby Isaac 
9949566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0*min*min*(max-min/3.0)));
9954905a7bcSToby Isaac   PetscFunctionReturn(0);
9964905a7bcSToby Isaac }
9974905a7bcSToby Isaac 
9984905a7bcSToby Isaac static PetscErrorCode MatQRFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
9994905a7bcSToby Isaac {
10004905a7bcSToby Isaac   MatFactorInfo  info;
10014905a7bcSToby Isaac 
10024905a7bcSToby Isaac   PetscFunctionBegin;
10034905a7bcSToby Isaac   info.fill = 1.0;
10044905a7bcSToby Isaac 
10059566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES));
1006cac4c232SBarry Smith   PetscUseMethod(fact,"MatQRFactor_C",(Mat,IS,const MatFactorInfo *),(fact,NULL,&info));
10074905a7bcSToby Isaac   PetscFunctionReturn(0);
10084905a7bcSToby Isaac }
10094905a7bcSToby Isaac 
1010bf5a80bcSToby Isaac PetscErrorCode MatQRFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info)
10114905a7bcSToby Isaac {
10124905a7bcSToby Isaac   PetscFunctionBegin;
10134905a7bcSToby Isaac   fact->assembled                  = PETSC_TRUE;
10144905a7bcSToby Isaac   fact->preallocated               = PETSC_TRUE;
10159566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)fact,"MatQRFactorNumeric_C",MatQRFactorNumeric_SeqDense));
10164905a7bcSToby Isaac   PetscFunctionReturn(0);
10174905a7bcSToby Isaac }
10184905a7bcSToby Isaac 
1019ca15aa20SStefano Zampini /* uses LAPACK */
1020cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A,MatFactorType ftype,Mat *fact)
1021db4efbfdSBarry Smith {
1022db4efbfdSBarry Smith   PetscFunctionBegin;
10239566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A),fact));
10249566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*fact,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n));
10259566063dSJacob Faibussowitsch   PetscCall(MatSetType(*fact,MATDENSE));
102666e17bc3SBarry Smith   (*fact)->trivialsymbolic = PETSC_TRUE;
10272a350339SBarry Smith   if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU) {
1028db4efbfdSBarry Smith     (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense;
10292a350339SBarry Smith     (*fact)->ops->ilufactorsymbolic = MatLUFactorSymbolic_SeqDense;
1030bf5a80bcSToby Isaac   } else if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) {
1031db4efbfdSBarry Smith     (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense;
1032bf5a80bcSToby Isaac   } else if (ftype == MAT_FACTOR_QR) {
10339566063dSJacob Faibussowitsch     PetscCall(PetscObjectComposeFunction((PetscObject)(*fact),"MatQRFactorSymbolic_C",MatQRFactorSymbolic_SeqDense));
1034db4efbfdSBarry Smith   }
1035d5f3da31SBarry Smith   (*fact)->factortype = ftype;
103600c67f3bSHong Zhang 
10379566063dSJacob Faibussowitsch   PetscCall(PetscFree((*fact)->solvertype));
10389566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC,&(*fact)->solvertype));
10399566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_LU]));
10409566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_ILU]));
10419566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_CHOLESKY]));
10429566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_ICC]));
1043db4efbfdSBarry Smith   PetscFunctionReturn(0);
1044db4efbfdSBarry Smith }
1045db4efbfdSBarry Smith 
1046289bc588SBarry Smith /* ------------------------------------------------------------------*/
1047e0877f53SBarry Smith static PetscErrorCode MatSOR_SeqDense(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec xx)
1048289bc588SBarry Smith {
1049c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1050d9ca1df4SBarry Smith   PetscScalar       *x,*v = mat->v,zero = 0.0,xt;
1051d9ca1df4SBarry Smith   const PetscScalar *b;
1052d0f46423SBarry Smith   PetscInt          m = A->rmap->n,i;
105323fff9afSBarry Smith   PetscBLASInt      o = 1,bm = 0;
1054289bc588SBarry Smith 
10553a40ed3dSBarry Smith   PetscFunctionBegin;
1056ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
105708401ef6SPierre Jolivet   PetscCheck(A->offloadmask != PETSC_OFFLOAD_GPU,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented");
1058ca15aa20SStefano Zampini #endif
1059422a814eSBarry Smith   if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */
10609566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(m,&bm));
1061289bc588SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
10623bffc371SBarry Smith     /* this is a hack fix, should have another version without the second BLASdotu */
10639566063dSJacob Faibussowitsch     PetscCall(VecSet(xx,zero));
1064289bc588SBarry Smith   }
10659566063dSJacob Faibussowitsch   PetscCall(VecGetArray(xx,&x));
10669566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(bb,&b));
1067b965ef7fSBarry Smith   its  = its*lits;
106808401ef6SPierre 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);
1069289bc588SBarry Smith   while (its--) {
1070fccaa45eSBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
1071289bc588SBarry Smith       for (i=0; i<m; i++) {
10723bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
107355a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
1074289bc588SBarry Smith       }
1075289bc588SBarry Smith     }
1076fccaa45eSBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
1077289bc588SBarry Smith       for (i=m-1; i>=0; i--) {
10783bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
107955a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
1080289bc588SBarry Smith       }
1081289bc588SBarry Smith     }
1082289bc588SBarry Smith   }
10839566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(bb,&b));
10849566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(xx,&x));
10853a40ed3dSBarry Smith   PetscFunctionReturn(0);
1086289bc588SBarry Smith }
1087289bc588SBarry Smith 
1088289bc588SBarry Smith /* -----------------------------------------------------------------*/
1089ca15aa20SStefano Zampini PetscErrorCode MatMultTranspose_SeqDense(Mat A,Vec xx,Vec yy)
1090289bc588SBarry Smith {
1091c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1092d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v,*x;
1093d9ca1df4SBarry Smith   PetscScalar       *y;
10940805154bSBarry Smith   PetscBLASInt      m, n,_One=1;
1095ea709b57SSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
10963a40ed3dSBarry Smith 
10973a40ed3dSBarry Smith   PetscFunctionBegin;
10989566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
10999566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
11009566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx,&x));
11019566063dSJacob Faibussowitsch   PetscCall(VecGetArrayWrite(yy,&y));
11025ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
11035ac36cfcSBarry Smith     PetscBLASInt i;
11045ac36cfcSBarry Smith     for (i=0; i<n; i++) y[i] = 0.0;
11055ac36cfcSBarry Smith   } else {
11068b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&mat->lda,x,&_One,&_DZero,y,&_One));
11079566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->cmap->n));
11085ac36cfcSBarry Smith   }
11099566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx,&x));
11109566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayWrite(yy,&y));
11113a40ed3dSBarry Smith   PetscFunctionReturn(0);
1112289bc588SBarry Smith }
1113800995b7SMatthew Knepley 
1114ca15aa20SStefano Zampini PetscErrorCode MatMult_SeqDense(Mat A,Vec xx,Vec yy)
1115289bc588SBarry Smith {
1116c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1117d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0,_DZero=0.0;
11180805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
1119d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
11203a40ed3dSBarry Smith 
11213a40ed3dSBarry Smith   PetscFunctionBegin;
11229566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
11239566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
11249566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx,&x));
11259566063dSJacob Faibussowitsch   PetscCall(VecGetArrayWrite(yy,&y));
11265ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
11275ac36cfcSBarry Smith     PetscBLASInt i;
11285ac36cfcSBarry Smith     for (i=0; i<m; i++) y[i] = 0.0;
11295ac36cfcSBarry Smith   } else {
11308b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DZero,y,&_One));
11319566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->rmap->n));
11325ac36cfcSBarry Smith   }
11339566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx,&x));
11349566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayWrite(yy,&y));
11353a40ed3dSBarry Smith   PetscFunctionReturn(0);
1136289bc588SBarry Smith }
11376ee01492SSatish Balay 
1138ca15aa20SStefano Zampini PetscErrorCode MatMultAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
1139289bc588SBarry Smith {
1140c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1141d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
1142d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0;
11430805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
11443a40ed3dSBarry Smith 
11453a40ed3dSBarry Smith   PetscFunctionBegin;
11469566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
11479566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
11489566063dSJacob Faibussowitsch   PetscCall(VecCopy(zz,yy));
1149d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
11509566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx,&x));
11519566063dSJacob Faibussowitsch   PetscCall(VecGetArray(yy,&y));
11528b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
11539566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx,&x));
11549566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(yy,&y));
11559566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0*A->rmap->n*A->cmap->n));
11563a40ed3dSBarry Smith   PetscFunctionReturn(0);
1157289bc588SBarry Smith }
11586ee01492SSatish Balay 
1159ca15aa20SStefano Zampini PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
1160289bc588SBarry Smith {
1161c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1162d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
1163d9ca1df4SBarry Smith   PetscScalar       *y;
11640805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
116587828ca2SBarry Smith   PetscScalar       _DOne=1.0;
11663a40ed3dSBarry Smith 
11673a40ed3dSBarry Smith   PetscFunctionBegin;
11689566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
11699566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
11709566063dSJacob Faibussowitsch   PetscCall(VecCopy(zz,yy));
1171d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
11729566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx,&x));
11739566063dSJacob Faibussowitsch   PetscCall(VecGetArray(yy,&y));
11748b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
11759566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx,&x));
11769566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(yy,&y));
11779566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0*A->rmap->n*A->cmap->n));
11783a40ed3dSBarry Smith   PetscFunctionReturn(0);
1179289bc588SBarry Smith }
1180289bc588SBarry Smith 
1181289bc588SBarry Smith /* -----------------------------------------------------------------*/
1182e0877f53SBarry Smith static PetscErrorCode MatGetRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
1183289bc588SBarry Smith {
1184c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
118513f74950SBarry Smith   PetscInt       i;
118667e560aaSBarry Smith 
11873a40ed3dSBarry Smith   PetscFunctionBegin;
1188d0f46423SBarry Smith   *ncols = A->cmap->n;
1189289bc588SBarry Smith   if (cols) {
11909566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(A->cmap->n,cols));
1191d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) (*cols)[i] = i;
1192289bc588SBarry Smith   }
1193289bc588SBarry Smith   if (vals) {
1194ca15aa20SStefano Zampini     const PetscScalar *v;
1195ca15aa20SStefano Zampini 
11969566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A,&v));
11979566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(A->cmap->n,vals));
1198ca15aa20SStefano Zampini     v   += row;
1199d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {(*vals)[i] = *v; v += mat->lda;}
12009566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A,&v));
1201289bc588SBarry Smith   }
12023a40ed3dSBarry Smith   PetscFunctionReturn(0);
1203289bc588SBarry Smith }
12046ee01492SSatish Balay 
1205e0877f53SBarry Smith static PetscErrorCode MatRestoreRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
1206289bc588SBarry Smith {
1207606d414cSSatish Balay   PetscFunctionBegin;
1208cb4a9cd9SHong Zhang   if (ncols) *ncols = 0;
12099566063dSJacob Faibussowitsch   if (cols) PetscCall(PetscFree(*cols));
12109566063dSJacob Faibussowitsch   if (vals) PetscCall(PetscFree(*vals));
12113a40ed3dSBarry Smith   PetscFunctionReturn(0);
1212289bc588SBarry Smith }
1213289bc588SBarry Smith /* ----------------------------------------------------------------*/
1214e0877f53SBarry Smith static PetscErrorCode MatSetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],const PetscScalar v[],InsertMode addv)
1215289bc588SBarry Smith {
1216c0bbcb79SLois Curfman McInnes   Mat_SeqDense     *mat = (Mat_SeqDense*)A->data;
1217ca15aa20SStefano Zampini   PetscScalar      *av;
121813f74950SBarry Smith   PetscInt         i,j,idx=0;
1219ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1220c70f7ee4SJunchao Zhang   PetscOffloadMask oldf;
1221ca15aa20SStefano Zampini #endif
1222d6dfbf8fSBarry Smith 
12233a40ed3dSBarry Smith   PetscFunctionBegin;
12249566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&av));
1225289bc588SBarry Smith   if (!mat->roworiented) {
1226dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1227289bc588SBarry Smith       for (j=0; j<n; j++) {
1228cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
12296bdcaf15SBarry 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);
1230289bc588SBarry Smith         for (i=0; i<m; i++) {
1231cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
12326bdcaf15SBarry 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);
1233ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
1234289bc588SBarry Smith         }
1235289bc588SBarry Smith       }
12363a40ed3dSBarry Smith     } else {
1237289bc588SBarry Smith       for (j=0; j<n; j++) {
1238cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
12396bdcaf15SBarry Smith         PetscCheck(indexn[j] < A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %" PetscInt_FMT " max %" PetscInt_FMT,indexn[j],A->cmap->n-1);
1240289bc588SBarry Smith         for (i=0; i<m; i++) {
1241cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
12426bdcaf15SBarry 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);
1243ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
1244289bc588SBarry Smith         }
1245289bc588SBarry Smith       }
1246289bc588SBarry Smith     }
12473a40ed3dSBarry Smith   } else {
1248dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1249e8d4e0b9SBarry Smith       for (i=0; i<m; i++) {
1250cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
12516bdcaf15SBarry 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);
1252e8d4e0b9SBarry Smith         for (j=0; j<n; j++) {
1253cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
12546bdcaf15SBarry 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);
1255ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
1256e8d4e0b9SBarry Smith         }
1257e8d4e0b9SBarry Smith       }
12583a40ed3dSBarry Smith     } else {
1259289bc588SBarry Smith       for (i=0; i<m; i++) {
1260cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
12616bdcaf15SBarry Smith         PetscCheck(indexm[i] < A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %" PetscInt_FMT " max %" PetscInt_FMT,indexm[i],A->rmap->n-1);
1262289bc588SBarry Smith         for (j=0; j<n; j++) {
1263cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
12646bdcaf15SBarry 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);
1265ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
1266289bc588SBarry Smith         }
1267289bc588SBarry Smith       }
1268289bc588SBarry Smith     }
1269e8d4e0b9SBarry Smith   }
1270ca15aa20SStefano Zampini   /* hack to prevent unneeded copy to the GPU while returning the array */
1271ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1272c70f7ee4SJunchao Zhang   oldf = A->offloadmask;
1273c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_GPU;
1274ca15aa20SStefano Zampini #endif
12759566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&av));
1276ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1277c70f7ee4SJunchao Zhang   A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU);
1278ca15aa20SStefano Zampini #endif
12793a40ed3dSBarry Smith   PetscFunctionReturn(0);
1280289bc588SBarry Smith }
1281e8d4e0b9SBarry Smith 
1282e0877f53SBarry Smith static PetscErrorCode MatGetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],PetscScalar v[])
1283ae80bb75SLois Curfman McInnes {
1284ae80bb75SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1285ca15aa20SStefano Zampini   const PetscScalar *vv;
128613f74950SBarry Smith   PetscInt          i,j;
1287ae80bb75SLois Curfman McInnes 
12883a40ed3dSBarry Smith   PetscFunctionBegin;
12899566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&vv));
1290ae80bb75SLois Curfman McInnes   /* row-oriented output */
1291ae80bb75SLois Curfman McInnes   for (i=0; i<m; i++) {
129297e567efSBarry Smith     if (indexm[i] < 0) {v += n;continue;}
129308401ef6SPierre 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);
1294ae80bb75SLois Curfman McInnes     for (j=0; j<n; j++) {
12956f31f424SBarry Smith       if (indexn[j] < 0) {v++; continue;}
129608401ef6SPierre 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);
1297ca15aa20SStefano Zampini       *v++ = vv[indexn[j]*mat->lda + indexm[i]];
1298ae80bb75SLois Curfman McInnes     }
1299ae80bb75SLois Curfman McInnes   }
13009566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&vv));
13013a40ed3dSBarry Smith   PetscFunctionReturn(0);
1302ae80bb75SLois Curfman McInnes }
1303ae80bb75SLois Curfman McInnes 
1304289bc588SBarry Smith /* -----------------------------------------------------------------*/
1305289bc588SBarry Smith 
13068491ab44SLisandro Dalcin PetscErrorCode MatView_Dense_Binary(Mat mat,PetscViewer viewer)
1307aabbc4fbSShri Abhyankar {
13088491ab44SLisandro Dalcin   PetscBool         skipHeader;
13098491ab44SLisandro Dalcin   PetscViewerFormat format;
13108491ab44SLisandro Dalcin   PetscInt          header[4],M,N,m,lda,i,j,k;
13118491ab44SLisandro Dalcin   const PetscScalar *v;
13128491ab44SLisandro Dalcin   PetscScalar       *vwork;
1313aabbc4fbSShri Abhyankar 
1314aabbc4fbSShri Abhyankar   PetscFunctionBegin;
13159566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
13169566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryGetSkipHeader(viewer,&skipHeader));
13179566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer,&format));
13188491ab44SLisandro Dalcin   if (skipHeader) format = PETSC_VIEWER_NATIVE;
1319aabbc4fbSShri Abhyankar 
13209566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat,&M,&N));
13218491ab44SLisandro Dalcin 
13228491ab44SLisandro Dalcin   /* write matrix header */
13238491ab44SLisandro Dalcin   header[0] = MAT_FILE_CLASSID; header[1] = M; header[2] = N;
13248491ab44SLisandro Dalcin   header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M*N;
13259566063dSJacob Faibussowitsch   if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer,header,4,PETSC_INT));
13268491ab44SLisandro Dalcin 
13279566063dSJacob Faibussowitsch   PetscCall(MatGetLocalSize(mat,&m,NULL));
13288491ab44SLisandro Dalcin   if (format != PETSC_VIEWER_NATIVE) {
13298491ab44SLisandro Dalcin     PetscInt nnz = m*N, *iwork;
13308491ab44SLisandro Dalcin     /* store row lengths for each row */
13319566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nnz,&iwork));
13328491ab44SLisandro Dalcin     for (i=0; i<m; i++) iwork[i] = N;
13339566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWriteAll(viewer,iwork,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT));
13348491ab44SLisandro Dalcin     /* store column indices (zero start index) */
13358491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
13368491ab44SLisandro Dalcin       for (j=0; j<N; j++, k++)
13378491ab44SLisandro Dalcin         iwork[k] = j;
13389566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWriteAll(viewer,iwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT));
13399566063dSJacob Faibussowitsch     PetscCall(PetscFree(iwork));
13408491ab44SLisandro Dalcin   }
13418491ab44SLisandro Dalcin   /* store matrix values as a dense matrix in row major order */
13429566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(m*N,&vwork));
13439566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(mat,&v));
13449566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(mat,&lda));
13458491ab44SLisandro Dalcin   for (k=0, i=0; i<m; i++)
13468491ab44SLisandro Dalcin     for (j=0; j<N; j++, k++)
13478491ab44SLisandro Dalcin       vwork[k] = v[i+lda*j];
13489566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(mat,&v));
13499566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryWriteAll(viewer,vwork,m*N,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR));
13509566063dSJacob Faibussowitsch   PetscCall(PetscFree(vwork));
13518491ab44SLisandro Dalcin   PetscFunctionReturn(0);
13528491ab44SLisandro Dalcin }
13538491ab44SLisandro Dalcin 
13548491ab44SLisandro Dalcin PetscErrorCode MatLoad_Dense_Binary(Mat mat,PetscViewer viewer)
13558491ab44SLisandro Dalcin {
13568491ab44SLisandro Dalcin   PetscBool      skipHeader;
13578491ab44SLisandro Dalcin   PetscInt       header[4],M,N,m,nz,lda,i,j,k;
13588491ab44SLisandro Dalcin   PetscInt       rows,cols;
13598491ab44SLisandro Dalcin   PetscScalar    *v,*vwork;
13608491ab44SLisandro Dalcin 
13618491ab44SLisandro Dalcin   PetscFunctionBegin;
13629566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
13639566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryGetSkipHeader(viewer,&skipHeader));
13648491ab44SLisandro Dalcin 
13658491ab44SLisandro Dalcin   if (!skipHeader) {
13669566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryRead(viewer,header,4,NULL,PETSC_INT));
136708401ef6SPierre Jolivet     PetscCheck(header[0] == MAT_FILE_CLASSID,PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Not a matrix object in file");
13688491ab44SLisandro Dalcin     M = header[1]; N = header[2];
136908401ef6SPierre Jolivet     PetscCheck(M >= 0,PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix row size (%" PetscInt_FMT ") in file is negative",M);
137008401ef6SPierre Jolivet     PetscCheck(N >= 0,PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix column size (%" PetscInt_FMT ") in file is negative",N);
13718491ab44SLisandro Dalcin     nz = header[3];
1372aed4548fSBarry Smith     PetscCheck(nz == MATRIX_BINARY_FORMAT_DENSE || nz >= 0,PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Unknown matrix format %" PetscInt_FMT " in file",nz);
1373aabbc4fbSShri Abhyankar   } else {
13749566063dSJacob Faibussowitsch     PetscCall(MatGetSize(mat,&M,&N));
1375aed4548fSBarry 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");
13768491ab44SLisandro Dalcin     nz = MATRIX_BINARY_FORMAT_DENSE;
1377e6324fbbSBarry Smith   }
1378aabbc4fbSShri Abhyankar 
13798491ab44SLisandro Dalcin   /* setup global sizes if not set */
13808491ab44SLisandro Dalcin   if (mat->rmap->N < 0) mat->rmap->N = M;
13818491ab44SLisandro Dalcin   if (mat->cmap->N < 0) mat->cmap->N = N;
13829566063dSJacob Faibussowitsch   PetscCall(MatSetUp(mat));
13838491ab44SLisandro Dalcin   /* check if global sizes are correct */
13849566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat,&rows,&cols));
1385aed4548fSBarry 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);
1386aabbc4fbSShri Abhyankar 
13879566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat,NULL,&N));
13889566063dSJacob Faibussowitsch   PetscCall(MatGetLocalSize(mat,&m,NULL));
13899566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(mat,&v));
13909566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(mat,&lda));
13918491ab44SLisandro Dalcin   if (nz == MATRIX_BINARY_FORMAT_DENSE) {  /* matrix in file is dense format */
13928491ab44SLisandro Dalcin     PetscInt nnz = m*N;
13938491ab44SLisandro Dalcin     /* read in matrix values */
13949566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nnz,&vwork));
13959566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR));
13968491ab44SLisandro Dalcin     /* store values in column major order */
13978491ab44SLisandro Dalcin     for (j=0; j<N; j++)
13988491ab44SLisandro Dalcin       for (i=0; i<m; i++)
13998491ab44SLisandro Dalcin         v[i+lda*j] = vwork[i*N+j];
14009566063dSJacob Faibussowitsch     PetscCall(PetscFree(vwork));
14018491ab44SLisandro Dalcin   } else { /* matrix in file is sparse format */
14028491ab44SLisandro Dalcin     PetscInt nnz = 0, *rlens, *icols;
14038491ab44SLisandro Dalcin     /* read in row lengths */
14049566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(m,&rlens));
14059566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer,rlens,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT));
14068491ab44SLisandro Dalcin     for (i=0; i<m; i++) nnz += rlens[i];
14078491ab44SLisandro Dalcin     /* read in column indices and values */
14089566063dSJacob Faibussowitsch     PetscCall(PetscMalloc2(nnz,&icols,nnz,&vwork));
14099566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer,icols,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT));
14109566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR));
14118491ab44SLisandro Dalcin     /* store values in column major order */
14128491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
14138491ab44SLisandro Dalcin       for (j=0; j<rlens[i]; j++, k++)
14148491ab44SLisandro Dalcin         v[i+lda*icols[k]] = vwork[k];
14159566063dSJacob Faibussowitsch     PetscCall(PetscFree(rlens));
14169566063dSJacob Faibussowitsch     PetscCall(PetscFree2(icols,vwork));
1417aabbc4fbSShri Abhyankar   }
14189566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(mat,&v));
14199566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY));
14209566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY));
1421aabbc4fbSShri Abhyankar   PetscFunctionReturn(0);
1422aabbc4fbSShri Abhyankar }
1423aabbc4fbSShri Abhyankar 
1424eb91f321SVaclav Hapla PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer)
1425eb91f321SVaclav Hapla {
1426eb91f321SVaclav Hapla   PetscBool      isbinary, ishdf5;
1427eb91f321SVaclav Hapla 
1428eb91f321SVaclav Hapla   PetscFunctionBegin;
1429eb91f321SVaclav Hapla   PetscValidHeaderSpecific(newMat,MAT_CLASSID,1);
1430eb91f321SVaclav Hapla   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1431eb91f321SVaclav Hapla   /* force binary viewer to load .info file if it has not yet done so */
14329566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
14339566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary));
14349566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,  &ishdf5));
1435eb91f321SVaclav Hapla   if (isbinary) {
14369566063dSJacob Faibussowitsch     PetscCall(MatLoad_Dense_Binary(newMat,viewer));
1437eb91f321SVaclav Hapla   } else if (ishdf5) {
1438eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5)
14399566063dSJacob Faibussowitsch     PetscCall(MatLoad_Dense_HDF5(newMat,viewer));
1440eb91f321SVaclav Hapla #else
1441eb91f321SVaclav Hapla     SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5");
1442eb91f321SVaclav Hapla #endif
1443eb91f321SVaclav Hapla   } else {
144498921bdaSJacob 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);
1445eb91f321SVaclav Hapla   }
1446eb91f321SVaclav Hapla   PetscFunctionReturn(0);
1447eb91f321SVaclav Hapla }
1448eb91f321SVaclav Hapla 
14496849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_ASCII(Mat A,PetscViewer viewer)
1450289bc588SBarry Smith {
1451932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
145213f74950SBarry Smith   PetscInt          i,j;
14532dcb1b2aSMatthew Knepley   const char        *name;
1454ca15aa20SStefano Zampini   PetscScalar       *v,*av;
1455f3ef73ceSBarry Smith   PetscViewerFormat format;
14565f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX)
1457ace3abfcSBarry Smith   PetscBool         allreal = PETSC_TRUE;
14585f481a85SSatish Balay #endif
1459932b0c3eSLois Curfman McInnes 
14603a40ed3dSBarry Smith   PetscFunctionBegin;
14619566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,(const PetscScalar**)&av));
14629566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer,&format));
1463456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
14643a40ed3dSBarry Smith     PetscFunctionReturn(0);  /* do nothing for now */
1465fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
14669566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE));
1467d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1468ca15aa20SStefano Zampini       v    = av + i;
14699566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"row %" PetscInt_FMT ":",i));
1470d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1471aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1472329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
14739566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g + %g i) ",j,(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v)));
1474329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
14759566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g) ",j,(double)PetscRealPart(*v)));
14766831982aSBarry Smith         }
147780cd9d93SLois Curfman McInnes #else
14786831982aSBarry Smith         if (*v) {
14799566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g) ",j,(double)*v));
14806831982aSBarry Smith         }
148180cd9d93SLois Curfman McInnes #endif
14821b807ce4Svictorle         v += a->lda;
148380cd9d93SLois Curfman McInnes       }
14849566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"\n"));
148580cd9d93SLois Curfman McInnes     }
14869566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE));
14873a40ed3dSBarry Smith   } else {
14889566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE));
1489aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
149047989497SBarry Smith     /* determine if matrix has all real values */
1491ca15aa20SStefano Zampini     v = av;
1492d0f46423SBarry Smith     for (i=0; i<A->rmap->n*A->cmap->n; i++) {
1493ffac6cdbSBarry Smith       if (PetscImaginaryPart(v[i])) { allreal = PETSC_FALSE; break;}
149447989497SBarry Smith     }
149547989497SBarry Smith #endif
1496fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
14979566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetName((PetscObject)A,&name));
14989566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"%% Size = %" PetscInt_FMT " %" PetscInt_FMT " \n",A->rmap->n,A->cmap->n));
14999566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"%s = zeros(%" PetscInt_FMT ",%" PetscInt_FMT ");\n",name,A->rmap->n,A->cmap->n));
15009566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"%s = [\n",name));
1501ffac6cdbSBarry Smith     }
1502ffac6cdbSBarry Smith 
1503d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1504ca15aa20SStefano Zampini       v = av + i;
1505d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1506aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
150747989497SBarry Smith         if (allreal) {
15089566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)PetscRealPart(*v)));
150947989497SBarry Smith         } else {
15109566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ei ",(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v)));
151147989497SBarry Smith         }
1512289bc588SBarry Smith #else
15139566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)*v));
1514289bc588SBarry Smith #endif
15151b807ce4Svictorle         v += a->lda;
1516289bc588SBarry Smith       }
15179566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"\n"));
1518289bc588SBarry Smith     }
1519fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
15209566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"];\n"));
1521ffac6cdbSBarry Smith     }
15229566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE));
1523da3a660dSBarry Smith   }
15249566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,(const PetscScalar**)&av));
15259566063dSJacob Faibussowitsch   PetscCall(PetscViewerFlush(viewer));
15263a40ed3dSBarry Smith   PetscFunctionReturn(0);
1527289bc588SBarry Smith }
1528289bc588SBarry Smith 
15299804daf3SBarry Smith #include <petscdraw.h>
1530e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw,void *Aa)
1531f1af5d2fSBarry Smith {
1532f1af5d2fSBarry Smith   Mat               A  = (Mat) Aa;
1533383922c3SLisandro Dalcin   PetscInt          m  = A->rmap->n,n = A->cmap->n,i,j;
1534383922c3SLisandro Dalcin   int               color = PETSC_DRAW_WHITE;
1535ca15aa20SStefano Zampini   const PetscScalar *v;
1536b0a32e0cSBarry Smith   PetscViewer       viewer;
1537b05fc000SLisandro Dalcin   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r;
1538f3ef73ceSBarry Smith   PetscViewerFormat format;
1539f1af5d2fSBarry Smith 
1540f1af5d2fSBarry Smith   PetscFunctionBegin;
15419566063dSJacob Faibussowitsch   PetscCall(PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer));
15429566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer,&format));
15439566063dSJacob Faibussowitsch   PetscCall(PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr));
1544f1af5d2fSBarry Smith 
1545f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
15469566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&v));
1547fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
1548d0609cedSBarry Smith     PetscDrawCollectiveBegin(draw);
1549f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
1550f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
1551383922c3SLisandro Dalcin       x_l = j; x_r = x_l + 1.0;
1552f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1553f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1554f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1555ca15aa20SStefano Zampini         if (PetscRealPart(v[j*m+i]) >  0.) color = PETSC_DRAW_RED;
1556ca15aa20SStefano Zampini         else if (PetscRealPart(v[j*m+i]) <  0.) color = PETSC_DRAW_BLUE;
1557ca15aa20SStefano Zampini         else continue;
15589566063dSJacob Faibussowitsch         PetscCall(PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color));
1559f1af5d2fSBarry Smith       }
1560f1af5d2fSBarry Smith     }
1561d0609cedSBarry Smith     PetscDrawCollectiveEnd(draw);
1562f1af5d2fSBarry Smith   } else {
1563f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
1564f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
1565b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1566b05fc000SLisandro Dalcin     PetscDraw popup;
1567b05fc000SLisandro Dalcin 
1568f1af5d2fSBarry Smith     for (i=0; i < m*n; i++) {
1569f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
1570f1af5d2fSBarry Smith     }
1571383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
15729566063dSJacob Faibussowitsch     PetscCall(PetscDrawGetPopup(draw,&popup));
15739566063dSJacob Faibussowitsch     PetscCall(PetscDrawScalePopup(popup,minv,maxv));
1574383922c3SLisandro Dalcin 
1575d0609cedSBarry Smith     PetscDrawCollectiveBegin(draw);
1576f1af5d2fSBarry Smith     for (j=0; j<n; j++) {
1577f1af5d2fSBarry Smith       x_l = j;
1578f1af5d2fSBarry Smith       x_r = x_l + 1.0;
1579f1af5d2fSBarry Smith       for (i=0; i<m; i++) {
1580f1af5d2fSBarry Smith         y_l   = m - i - 1.0;
1581f1af5d2fSBarry Smith         y_r   = y_l + 1.0;
1582b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(v[j*m+i]),minv,maxv);
15839566063dSJacob Faibussowitsch         PetscCall(PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color));
1584f1af5d2fSBarry Smith       }
1585f1af5d2fSBarry Smith     }
1586d0609cedSBarry Smith     PetscDrawCollectiveEnd(draw);
1587f1af5d2fSBarry Smith   }
15889566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&v));
1589f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1590f1af5d2fSBarry Smith }
1591f1af5d2fSBarry Smith 
1592e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw(Mat A,PetscViewer viewer)
1593f1af5d2fSBarry Smith {
1594b0a32e0cSBarry Smith   PetscDraw      draw;
1595ace3abfcSBarry Smith   PetscBool      isnull;
1596329f5518SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
1597f1af5d2fSBarry Smith 
1598f1af5d2fSBarry Smith   PetscFunctionBegin;
15999566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDraw(viewer,0,&draw));
16009566063dSJacob Faibussowitsch   PetscCall(PetscDrawIsNull(draw,&isnull));
1601abc0a331SBarry Smith   if (isnull) PetscFunctionReturn(0);
1602f1af5d2fSBarry Smith 
1603d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
1604f1af5d2fSBarry Smith   xr  += w;          yr += h;        xl = -w;     yl = -h;
16059566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetCoordinates(draw,xl,yl,xr,yr));
16069566063dSJacob Faibussowitsch   PetscCall(PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer));
16079566063dSJacob Faibussowitsch   PetscCall(PetscDrawZoom(draw,MatView_SeqDense_Draw_Zoom,A));
16089566063dSJacob Faibussowitsch   PetscCall(PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL));
16099566063dSJacob Faibussowitsch   PetscCall(PetscDrawSave(draw));
1610f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1611f1af5d2fSBarry Smith }
1612f1af5d2fSBarry Smith 
1613dfbe8321SBarry Smith PetscErrorCode MatView_SeqDense(Mat A,PetscViewer viewer)
1614932b0c3eSLois Curfman McInnes {
1615ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
1616932b0c3eSLois Curfman McInnes 
16173a40ed3dSBarry Smith   PetscFunctionBegin;
16189566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
16199566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary));
16209566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw));
1621c45a1595SBarry Smith   if (iascii) {
16229566063dSJacob Faibussowitsch     PetscCall(MatView_SeqDense_ASCII(A,viewer));
16230f5bd95cSBarry Smith   } else if (isbinary) {
16249566063dSJacob Faibussowitsch     PetscCall(MatView_Dense_Binary(A,viewer));
1625f1af5d2fSBarry Smith   } else if (isdraw) {
16269566063dSJacob Faibussowitsch     PetscCall(MatView_SeqDense_Draw(A,viewer));
1627932b0c3eSLois Curfman McInnes   }
16283a40ed3dSBarry Smith   PetscFunctionReturn(0);
1629932b0c3eSLois Curfman McInnes }
1630289bc588SBarry Smith 
1631637a0070SStefano Zampini static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A,const PetscScalar *array)
1632d3042a70SBarry Smith {
1633d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1634d3042a70SBarry Smith 
1635d3042a70SBarry Smith   PetscFunctionBegin;
163628b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
163728b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
163828b400f6SJacob Faibussowitsch   PetscCheck(!a->unplacedarray,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreArray() first");
1639d3042a70SBarry Smith   a->unplacedarray       = a->v;
1640d3042a70SBarry Smith   a->unplaced_user_alloc = a->user_alloc;
1641d3042a70SBarry Smith   a->v                   = (PetscScalar*) array;
1642637a0070SStefano Zampini   a->user_alloc          = PETSC_TRUE;
1643ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1644c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1645ca15aa20SStefano Zampini #endif
1646d3042a70SBarry Smith   PetscFunctionReturn(0);
1647d3042a70SBarry Smith }
1648d3042a70SBarry Smith 
1649d3042a70SBarry Smith static PetscErrorCode MatDenseResetArray_SeqDense(Mat A)
1650d3042a70SBarry Smith {
1651d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1652d3042a70SBarry Smith 
1653d3042a70SBarry Smith   PetscFunctionBegin;
165428b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
165528b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
1656d3042a70SBarry Smith   a->v             = a->unplacedarray;
1657d3042a70SBarry Smith   a->user_alloc    = a->unplaced_user_alloc;
1658d3042a70SBarry Smith   a->unplacedarray = NULL;
1659ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1660c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1661ca15aa20SStefano Zampini #endif
1662d3042a70SBarry Smith   PetscFunctionReturn(0);
1663d3042a70SBarry Smith }
1664d3042a70SBarry Smith 
1665d5ea218eSStefano Zampini static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A,const PetscScalar *array)
1666d5ea218eSStefano Zampini {
1667d5ea218eSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1668d5ea218eSStefano Zampini 
1669d5ea218eSStefano Zampini   PetscFunctionBegin;
167028b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
167128b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
16729566063dSJacob Faibussowitsch   if (!a->user_alloc) PetscCall(PetscFree(a->v));
1673d5ea218eSStefano Zampini   a->v           = (PetscScalar*) array;
1674d5ea218eSStefano Zampini   a->user_alloc  = PETSC_FALSE;
1675d5ea218eSStefano Zampini #if defined(PETSC_HAVE_CUDA)
1676d5ea218eSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
1677d5ea218eSStefano Zampini #endif
1678d5ea218eSStefano Zampini   PetscFunctionReturn(0);
1679d5ea218eSStefano Zampini }
1680d5ea218eSStefano Zampini 
1681ca15aa20SStefano Zampini PetscErrorCode MatDestroy_SeqDense(Mat mat)
1682289bc588SBarry Smith {
1683ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)mat->data;
168490f02eecSBarry Smith 
16853a40ed3dSBarry Smith   PetscFunctionBegin;
1686aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1687c0aa6a63SJacob Faibussowitsch   PetscLogObjectState((PetscObject)mat,"Rows %" PetscInt_FMT " Cols %" PetscInt_FMT,mat->rmap->n,mat->cmap->n);
1688a5a9c739SBarry Smith #endif
16899566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(l->qrrhs)));
16909566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->tau));
16919566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->pivots));
16929566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->fwork));
16939566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&l->ptapwork));
16949566063dSJacob Faibussowitsch   if (!l->user_alloc) PetscCall(PetscFree(l->v));
16959566063dSJacob Faibussowitsch   if (!l->unplaced_user_alloc) PetscCall(PetscFree(l->unplacedarray));
169628b400f6SJacob Faibussowitsch   PetscCheck(!l->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
169728b400f6SJacob Faibussowitsch   PetscCheck(!l->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
16989566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&l->cvec));
16999566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&l->cmat));
17009566063dSJacob Faibussowitsch   PetscCall(PetscFree(mat->data));
1701dbd8c25aSHong Zhang 
17029566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)mat,NULL));
17039566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatQRFactor_C",NULL));
17049566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetLDA_C",NULL));
17059566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseSetLDA_C",NULL));
17069566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArray_C",NULL));
17079566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArray_C",NULL));
17089566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDensePlaceArray_C",NULL));
17099566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseResetArray_C",NULL));
17109566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseReplaceArray_C",NULL));
17119566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArrayRead_C",NULL));
17129566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArrayRead_C",NULL));
17139566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArrayWrite_C",NULL));
17149566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArrayWrite_C",NULL));
17159566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqaij_C",NULL));
17168baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
17179566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_elemental_C",NULL));
17188baccfbdSHong Zhang #endif
1719d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
17209566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_scalapack_C",NULL));
1721d24d4204SJose E. Roman #endif
17222bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
17239566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqdensecuda_C",NULL));
17249566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",NULL));
17259566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdense_C",NULL));
17262bf066beSStefano Zampini #endif
17279566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatSeqDenseSetPreallocation_C",NULL));
17289566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqaij_seqdense_C",NULL));
17299566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdense_seqdense_C",NULL));
17309566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqbaij_seqdense_C",NULL));
17319566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqsbaij_seqdense_C",NULL));
173252c5f739Sprj- 
17339566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumn_C",NULL));
17349566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumn_C",NULL));
17359566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVec_C",NULL));
17369566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVec_C",NULL));
17379566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVecRead_C",NULL));
17389566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVecRead_C",NULL));
17399566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVecWrite_C",NULL));
17409566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVecWrite_C",NULL));
17419566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetSubMatrix_C",NULL));
17429566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreSubMatrix_C",NULL));
17433a40ed3dSBarry Smith   PetscFunctionReturn(0);
1744289bc588SBarry Smith }
1745289bc588SBarry Smith 
1746e0877f53SBarry Smith static PetscErrorCode MatTranspose_SeqDense(Mat A,MatReuse reuse,Mat *matout)
1747289bc588SBarry Smith {
1748c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
17496536e3caSStefano Zampini   PetscInt       k,j,m = A->rmap->n, M = mat->lda, n = A->cmap->n;
175087828ca2SBarry Smith   PetscScalar    *v,tmp;
175148b35521SBarry Smith 
17523a40ed3dSBarry Smith   PetscFunctionBegin;
17536536e3caSStefano Zampini   if (reuse == MAT_INPLACE_MATRIX) {
17546536e3caSStefano Zampini     if (m == n) { /* in place transpose */
17559566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(A,&v));
1756d3e5ee88SLois Curfman McInnes       for (j=0; j<m; j++) {
1757289bc588SBarry Smith         for (k=0; k<j; k++) {
17581b807ce4Svictorle           tmp        = v[j + k*M];
17591b807ce4Svictorle           v[j + k*M] = v[k + j*M];
17601b807ce4Svictorle           v[k + j*M] = tmp;
1761289bc588SBarry Smith         }
1762289bc588SBarry Smith       }
17639566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArray(A,&v));
17646536e3caSStefano Zampini     } else { /* reuse memory, temporary allocates new memory */
17656536e3caSStefano Zampini       PetscScalar *v2;
17666536e3caSStefano Zampini       PetscLayout tmplayout;
17676536e3caSStefano Zampini 
17689566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1((size_t)m*n,&v2));
17699566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(A,&v));
17706536e3caSStefano Zampini       for (j=0; j<n; j++) {
17716536e3caSStefano Zampini         for (k=0; k<m; k++) v2[j + (size_t)k*n] = v[k + (size_t)j*M];
17726536e3caSStefano Zampini       }
17739566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(v,v2,(size_t)m*n));
17749566063dSJacob Faibussowitsch       PetscCall(PetscFree(v2));
17759566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArray(A,&v));
17766536e3caSStefano Zampini       /* cleanup size dependent quantities */
17779566063dSJacob Faibussowitsch       PetscCall(VecDestroy(&mat->cvec));
17789566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&mat->cmat));
17799566063dSJacob Faibussowitsch       PetscCall(PetscFree(mat->pivots));
17809566063dSJacob Faibussowitsch       PetscCall(PetscFree(mat->fwork));
17819566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&mat->ptapwork));
17826536e3caSStefano Zampini       /* swap row/col layouts */
17836536e3caSStefano Zampini       mat->lda  = n;
17846536e3caSStefano Zampini       tmplayout = A->rmap;
17856536e3caSStefano Zampini       A->rmap   = A->cmap;
17866536e3caSStefano Zampini       A->cmap   = tmplayout;
17876536e3caSStefano Zampini     }
17883a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1789d3e5ee88SLois Curfman McInnes     Mat          tmat;
1790ec8511deSBarry Smith     Mat_SeqDense *tmatd;
179187828ca2SBarry Smith     PetscScalar  *v2;
1792af36a384SStefano Zampini     PetscInt     M2;
1793ea709b57SSatish Balay 
17946536e3caSStefano Zampini     if (reuse == MAT_INITIAL_MATRIX) {
17959566063dSJacob Faibussowitsch       PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&tmat));
17969566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(tmat,A->cmap->n,A->rmap->n,A->cmap->n,A->rmap->n));
17979566063dSJacob Faibussowitsch       PetscCall(MatSetType(tmat,((PetscObject)A)->type_name));
17989566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSetPreallocation(tmat,NULL));
1799ca15aa20SStefano Zampini     } else tmat = *matout;
1800ca15aa20SStefano Zampini 
18019566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A,(const PetscScalar**)&v));
18029566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArray(tmat,&v2));
1803ec8511deSBarry Smith     tmatd = (Mat_SeqDense*)tmat->data;
1804ca15aa20SStefano Zampini     M2    = tmatd->lda;
1805d3e5ee88SLois Curfman McInnes     for (j=0; j<n; j++) {
1806af36a384SStefano Zampini       for (k=0; k<m; k++) v2[j + k*M2] = v[k + j*M];
1807d3e5ee88SLois Curfman McInnes     }
18089566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(tmat,&v2));
18099566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A,(const PetscScalar**)&v));
18109566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY));
18119566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY));
18126536e3caSStefano Zampini     *matout = tmat;
181348b35521SBarry Smith   }
18143a40ed3dSBarry Smith   PetscFunctionReturn(0);
1815289bc588SBarry Smith }
1816289bc588SBarry Smith 
1817e0877f53SBarry Smith static PetscErrorCode MatEqual_SeqDense(Mat A1,Mat A2,PetscBool  *flg)
1818289bc588SBarry Smith {
1819c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat1 = (Mat_SeqDense*)A1->data;
1820c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat2 = (Mat_SeqDense*)A2->data;
1821ca15aa20SStefano Zampini   PetscInt          i;
1822ca15aa20SStefano Zampini   const PetscScalar *v1,*v2;
18239ea5d5aeSSatish Balay 
18243a40ed3dSBarry Smith   PetscFunctionBegin;
1825d0f46423SBarry Smith   if (A1->rmap->n != A2->rmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1826d0f46423SBarry Smith   if (A1->cmap->n != A2->cmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
18279566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A1,&v1));
18289566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A2,&v2));
1829ca15aa20SStefano Zampini   for (i=0; i<A1->cmap->n; i++) {
18309566063dSJacob Faibussowitsch     PetscCall(PetscArraycmp(v1,v2,A1->rmap->n,flg));
1831ca15aa20SStefano Zampini     if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
1832ca15aa20SStefano Zampini     v1 += mat1->lda;
1833ca15aa20SStefano Zampini     v2 += mat2->lda;
18341b807ce4Svictorle   }
18359566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A1,&v1));
18369566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A2,&v2));
183777c4ece6SBarry Smith   *flg = PETSC_TRUE;
18383a40ed3dSBarry Smith   PetscFunctionReturn(0);
1839289bc588SBarry Smith }
1840289bc588SBarry Smith 
1841e0877f53SBarry Smith static PetscErrorCode MatGetDiagonal_SeqDense(Mat A,Vec v)
1842289bc588SBarry Smith {
1843c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
184413f74950SBarry Smith   PetscInt          i,n,len;
1845ca15aa20SStefano Zampini   PetscScalar       *x;
1846ca15aa20SStefano Zampini   const PetscScalar *vv;
184744cd7ae7SLois Curfman McInnes 
18483a40ed3dSBarry Smith   PetscFunctionBegin;
18499566063dSJacob Faibussowitsch   PetscCall(VecGetSize(v,&n));
18509566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v,&x));
1851d0f46423SBarry Smith   len  = PetscMin(A->rmap->n,A->cmap->n);
18529566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&vv));
185308401ef6SPierre Jolivet   PetscCheck(n == A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming mat and vec");
185444cd7ae7SLois Curfman McInnes   for (i=0; i<len; i++) {
1855ca15aa20SStefano Zampini     x[i] = vv[i*mat->lda + i];
1856289bc588SBarry Smith   }
18579566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&vv));
18589566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v,&x));
18593a40ed3dSBarry Smith   PetscFunctionReturn(0);
1860289bc588SBarry Smith }
1861289bc588SBarry Smith 
1862e0877f53SBarry Smith static PetscErrorCode MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr)
1863289bc588SBarry Smith {
1864c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1865f1ceaac6SMatthew G. Knepley   const PetscScalar *l,*r;
1866ca15aa20SStefano Zampini   PetscScalar       x,*v,*vv;
1867d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n;
186855659b69SBarry Smith 
18693a40ed3dSBarry Smith   PetscFunctionBegin;
18709566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&vv));
187128988994SBarry Smith   if (ll) {
18729566063dSJacob Faibussowitsch     PetscCall(VecGetSize(ll,&m));
18739566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ll,&l));
187408401ef6SPierre Jolivet     PetscCheck(m == A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vec wrong size");
1875da3a660dSBarry Smith     for (i=0; i<m; i++) {
1876da3a660dSBarry Smith       x = l[i];
1877ca15aa20SStefano Zampini       v = vv + i;
1878b43bac26SStefano Zampini       for (j=0; j<n; j++) { (*v) *= x; v+= mat->lda;}
1879da3a660dSBarry Smith     }
18809566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ll,&l));
18819566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0*n*m));
1882da3a660dSBarry Smith   }
188328988994SBarry Smith   if (rr) {
18849566063dSJacob Faibussowitsch     PetscCall(VecGetSize(rr,&n));
18859566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(rr,&r));
188608401ef6SPierre Jolivet     PetscCheck(n == A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vec wrong size");
1887da3a660dSBarry Smith     for (i=0; i<n; i++) {
1888da3a660dSBarry Smith       x = r[i];
1889ca15aa20SStefano Zampini       v = vv + i*mat->lda;
18902205254eSKarl Rupp       for (j=0; j<m; j++) (*v++) *= x;
1891da3a660dSBarry Smith     }
18929566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(rr,&r));
18939566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0*n*m));
1894da3a660dSBarry Smith   }
18959566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&vv));
18963a40ed3dSBarry Smith   PetscFunctionReturn(0);
1897289bc588SBarry Smith }
1898289bc588SBarry Smith 
1899ca15aa20SStefano Zampini PetscErrorCode MatNorm_SeqDense(Mat A,NormType type,PetscReal *nrm)
1900289bc588SBarry Smith {
1901c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1902ca15aa20SStefano Zampini   PetscScalar       *v,*vv;
1903329f5518SBarry Smith   PetscReal         sum = 0.0;
190475f6d85dSStefano Zampini   PetscInt          lda, m=A->rmap->n,i,j;
190555659b69SBarry Smith 
19063a40ed3dSBarry Smith   PetscFunctionBegin;
19079566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,(const PetscScalar**)&vv));
19089566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(A,&lda));
1909ca15aa20SStefano Zampini   v    = vv;
1910289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1911a5ce6ee0Svictorle     if (lda>m) {
1912d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1913ca15aa20SStefano Zampini         v = vv+j*lda;
1914a5ce6ee0Svictorle         for (i=0; i<m; i++) {
1915a5ce6ee0Svictorle           sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1916a5ce6ee0Svictorle         }
1917a5ce6ee0Svictorle       }
1918a5ce6ee0Svictorle     } else {
1919570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1920570b7f6dSBarry Smith       PetscBLASInt one = 1,cnt = A->cmap->n*A->rmap->n;
192173cf7048SBarry Smith       PetscStackCallBLAS("BLASnrm2",*nrm = BLASnrm2_(&cnt,v,&one));
1922570b7f6dSBarry Smith     }
1923570b7f6dSBarry Smith #else
1924d0f46423SBarry Smith       for (i=0; i<A->cmap->n*A->rmap->n; i++) {
1925329f5518SBarry Smith         sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1926289bc588SBarry Smith       }
1927a5ce6ee0Svictorle     }
19288f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1929570b7f6dSBarry Smith #endif
19309566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0*A->cmap->n*A->rmap->n));
19313a40ed3dSBarry Smith   } else if (type == NORM_1) {
1932064f8208SBarry Smith     *nrm = 0.0;
1933d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1934ca15aa20SStefano Zampini       v   = vv + j*mat->lda;
1935289bc588SBarry Smith       sum = 0.0;
1936d0f46423SBarry Smith       for (i=0; i<A->rmap->n; i++) {
193733a8263dSBarry Smith         sum += PetscAbsScalar(*v);  v++;
1938289bc588SBarry Smith       }
1939064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1940289bc588SBarry Smith     }
19419566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0*A->cmap->n*A->rmap->n));
19423a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1943064f8208SBarry Smith     *nrm = 0.0;
1944d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1945ca15aa20SStefano Zampini       v   = vv + j;
1946289bc588SBarry Smith       sum = 0.0;
1947d0f46423SBarry Smith       for (i=0; i<A->cmap->n; i++) {
19481b807ce4Svictorle         sum += PetscAbsScalar(*v); v += mat->lda;
1949289bc588SBarry Smith       }
1950064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1951289bc588SBarry Smith     }
19529566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0*A->cmap->n*A->rmap->n));
1953e7e72b3dSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No two norm");
19549566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,(const PetscScalar**)&vv));
19553a40ed3dSBarry Smith   PetscFunctionReturn(0);
1956289bc588SBarry Smith }
1957289bc588SBarry Smith 
1958e0877f53SBarry Smith static PetscErrorCode MatSetOption_SeqDense(Mat A,MatOption op,PetscBool flg)
1959289bc588SBarry Smith {
1960c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *aij = (Mat_SeqDense*)A->data;
196167e560aaSBarry Smith 
19623a40ed3dSBarry Smith   PetscFunctionBegin;
1963b5a2b587SKris Buschelman   switch (op) {
1964b5a2b587SKris Buschelman   case MAT_ROW_ORIENTED:
19654e0d8c25SBarry Smith     aij->roworiented = flg;
1966b5a2b587SKris Buschelman     break;
1967512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1968b5a2b587SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
19693971808eSMatthew Knepley   case MAT_NEW_NONZERO_ALLOCATION_ERR:
19708c78258cSHong Zhang   case MAT_FORCE_DIAGONAL_ENTRIES:
197113fa8e87SLisandro Dalcin   case MAT_KEEP_NONZERO_PATTERN:
1972b5a2b587SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1973b5a2b587SKris Buschelman   case MAT_USE_HASH_TABLE:
19740f8fb01aSBarry Smith   case MAT_IGNORE_ZERO_ENTRIES:
19755021d80fSJed Brown   case MAT_IGNORE_LOWER_TRIANGULAR:
1976071fcb05SBarry Smith   case MAT_SORTED_FULL:
19779566063dSJacob Faibussowitsch     PetscCall(PetscInfo(A,"Option %s ignored\n",MatOptions[op]));
19785021d80fSJed Brown     break;
19795021d80fSJed Brown   case MAT_SPD:
198077e54ba9SKris Buschelman   case MAT_SYMMETRIC:
198177e54ba9SKris Buschelman   case MAT_STRUCTURALLY_SYMMETRIC:
19829a4540c5SBarry Smith   case MAT_HERMITIAN:
19839a4540c5SBarry Smith   case MAT_SYMMETRY_ETERNAL:
19845021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
198577e54ba9SKris Buschelman     break;
1986b5a2b587SKris Buschelman   default:
198798921bdaSJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %s",MatOptions[op]);
19883a40ed3dSBarry Smith   }
19893a40ed3dSBarry Smith   PetscFunctionReturn(0);
1990289bc588SBarry Smith }
1991289bc588SBarry Smith 
19923d8925e7SStefano Zampini PetscErrorCode MatZeroEntries_SeqDense(Mat A)
19936f0a148fSBarry Smith {
1994ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)A->data;
19953d8925e7SStefano Zampini   PetscInt       lda=l->lda,m=A->rmap->n,n=A->cmap->n,j;
1996ca15aa20SStefano Zampini   PetscScalar    *v;
19973a40ed3dSBarry Smith 
19983a40ed3dSBarry Smith   PetscFunctionBegin;
19999566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(A,&v));
2000a5ce6ee0Svictorle   if (lda>m) {
20013d8925e7SStefano Zampini     for (j=0; j<n; j++) {
20029566063dSJacob Faibussowitsch       PetscCall(PetscArrayzero(v+j*lda,m));
2003a5ce6ee0Svictorle     }
2004a5ce6ee0Svictorle   } else {
20059566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(v,PetscInt64Mult(m,n)));
2006a5ce6ee0Svictorle   }
20079566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(A,&v));
20083a40ed3dSBarry Smith   PetscFunctionReturn(0);
20096f0a148fSBarry Smith }
20106f0a148fSBarry Smith 
2011e0877f53SBarry Smith static PetscErrorCode MatZeroRows_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
20126f0a148fSBarry Smith {
2013ec8511deSBarry Smith   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
2014b9679d65SBarry Smith   PetscInt          m  = l->lda, n = A->cmap->n, i,j;
2015ca15aa20SStefano Zampini   PetscScalar       *slot,*bb,*v;
201697b48c8fSBarry Smith   const PetscScalar *xx;
201755659b69SBarry Smith 
20183a40ed3dSBarry Smith   PetscFunctionBegin;
201976bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
2020b9679d65SBarry Smith     for (i=0; i<N; i++) {
202108401ef6SPierre Jolivet       PetscCheck(rows[i] >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
202208401ef6SPierre 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);
2023b9679d65SBarry Smith     }
202476bd3646SJed Brown   }
2025ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
2026b9679d65SBarry Smith 
202797b48c8fSBarry Smith   /* fix right hand side if needed */
202897b48c8fSBarry Smith   if (x && b) {
20299566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(x,&xx));
20309566063dSJacob Faibussowitsch     PetscCall(VecGetArray(b,&bb));
20312205254eSKarl Rupp     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
20329566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(x,&xx));
20339566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(b,&bb));
203497b48c8fSBarry Smith   }
203597b48c8fSBarry Smith 
20369566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&v));
20376f0a148fSBarry Smith   for (i=0; i<N; i++) {
2038ca15aa20SStefano Zampini     slot = v + rows[i];
2039b9679d65SBarry Smith     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
20406f0a148fSBarry Smith   }
2041f4df32b1SMatthew Knepley   if (diag != 0.0) {
204208401ef6SPierre Jolivet     PetscCheck(A->rmap->n == A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
20436f0a148fSBarry Smith     for (i=0; i<N; i++) {
2044ca15aa20SStefano Zampini       slot  = v + (m+1)*rows[i];
2045f4df32b1SMatthew Knepley       *slot = diag;
20466f0a148fSBarry Smith     }
20476f0a148fSBarry Smith   }
20489566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&v));
20493a40ed3dSBarry Smith   PetscFunctionReturn(0);
20506f0a148fSBarry Smith }
2051557bce09SLois Curfman McInnes 
205249a6ff4bSBarry Smith static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A,PetscInt *lda)
205349a6ff4bSBarry Smith {
205449a6ff4bSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
205549a6ff4bSBarry Smith 
205649a6ff4bSBarry Smith   PetscFunctionBegin;
205749a6ff4bSBarry Smith   *lda = mat->lda;
205849a6ff4bSBarry Smith   PetscFunctionReturn(0);
205949a6ff4bSBarry Smith }
206049a6ff4bSBarry Smith 
2061637a0070SStefano Zampini PetscErrorCode MatDenseGetArray_SeqDense(Mat A,PetscScalar **array)
206264e87e97SBarry Smith {
2063c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
20643a40ed3dSBarry Smith 
20653a40ed3dSBarry Smith   PetscFunctionBegin;
206628b400f6SJacob Faibussowitsch   PetscCheck(!mat->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
206764e87e97SBarry Smith   *array = mat->v;
20683a40ed3dSBarry Smith   PetscFunctionReturn(0);
206964e87e97SBarry Smith }
20700754003eSLois Curfman McInnes 
2071637a0070SStefano Zampini PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A,PetscScalar **array)
2072ff14e315SSatish Balay {
20733a40ed3dSBarry Smith   PetscFunctionBegin;
207475f6d85dSStefano Zampini   if (array) *array = NULL;
20753a40ed3dSBarry Smith   PetscFunctionReturn(0);
2076ff14e315SSatish Balay }
20770754003eSLois Curfman McInnes 
20780f74d2c1SSatish Balay /*@
207949a6ff4bSBarry Smith    MatDenseGetLDA - gets the leading dimension of the array returned from MatDenseGetArray()
208049a6ff4bSBarry Smith 
2081ad16ce7aSStefano Zampini    Not collective
208249a6ff4bSBarry Smith 
208349a6ff4bSBarry Smith    Input Parameter:
208449a6ff4bSBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
208549a6ff4bSBarry Smith 
208649a6ff4bSBarry Smith    Output Parameter:
208749a6ff4bSBarry Smith .   lda - the leading dimension
208849a6ff4bSBarry Smith 
208949a6ff4bSBarry Smith    Level: intermediate
209049a6ff4bSBarry Smith 
2091ad16ce7aSStefano Zampini .seealso: MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseSetLDA()
209249a6ff4bSBarry Smith @*/
209349a6ff4bSBarry Smith PetscErrorCode  MatDenseGetLDA(Mat A,PetscInt *lda)
209449a6ff4bSBarry Smith {
209549a6ff4bSBarry Smith   PetscFunctionBegin;
2096d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2097dadcf809SJacob Faibussowitsch   PetscValidIntPointer(lda,2);
209875f6d85dSStefano Zampini   MatCheckPreallocated(A,1);
2099cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetLDA_C",(Mat,PetscInt*),(A,lda));
210049a6ff4bSBarry Smith   PetscFunctionReturn(0);
210149a6ff4bSBarry Smith }
210249a6ff4bSBarry Smith 
21030f74d2c1SSatish Balay /*@
2104ad16ce7aSStefano Zampini    MatDenseSetLDA - Sets the leading dimension of the array used by the dense matrix
2105ad16ce7aSStefano Zampini 
2106ad16ce7aSStefano Zampini    Not collective
2107ad16ce7aSStefano Zampini 
2108d8d19677SJose E. Roman    Input Parameters:
2109ad16ce7aSStefano Zampini +  mat - a MATSEQDENSE or MATMPIDENSE matrix
2110ad16ce7aSStefano Zampini -  lda - the leading dimension
2111ad16ce7aSStefano Zampini 
2112ad16ce7aSStefano Zampini    Level: intermediate
2113ad16ce7aSStefano Zampini 
2114ad16ce7aSStefano Zampini .seealso: MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseGetLDA()
2115ad16ce7aSStefano Zampini @*/
2116ad16ce7aSStefano Zampini PetscErrorCode  MatDenseSetLDA(Mat A,PetscInt lda)
2117ad16ce7aSStefano Zampini {
2118ad16ce7aSStefano Zampini   PetscFunctionBegin;
2119ad16ce7aSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2120cac4c232SBarry Smith   PetscTryMethod(A,"MatDenseSetLDA_C",(Mat,PetscInt),(A,lda));
2121ad16ce7aSStefano Zampini   PetscFunctionReturn(0);
2122ad16ce7aSStefano Zampini }
2123ad16ce7aSStefano Zampini 
2124ad16ce7aSStefano Zampini /*@C
21256947451fSStefano Zampini    MatDenseGetArray - gives read-write access to the array where the data for a dense matrix is stored
212673a71a0fSBarry Smith 
21278572280aSBarry Smith    Logically Collective on Mat
212873a71a0fSBarry Smith 
212973a71a0fSBarry Smith    Input Parameter:
21306947451fSStefano Zampini .  mat - a dense matrix
213173a71a0fSBarry Smith 
213273a71a0fSBarry Smith    Output Parameter:
213373a71a0fSBarry Smith .   array - pointer to the data
213473a71a0fSBarry Smith 
213573a71a0fSBarry Smith    Level: intermediate
213673a71a0fSBarry Smith 
21376947451fSStefano Zampini .seealso: MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
213873a71a0fSBarry Smith @*/
21398c778c55SBarry Smith PetscErrorCode  MatDenseGetArray(Mat A,PetscScalar **array)
214073a71a0fSBarry Smith {
214173a71a0fSBarry Smith   PetscFunctionBegin;
2142d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2143d5ea218eSStefano Zampini   PetscValidPointer(array,2);
2144cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetArray_C",(Mat,PetscScalar**),(A,array));
214573a71a0fSBarry Smith   PetscFunctionReturn(0);
214673a71a0fSBarry Smith }
214773a71a0fSBarry Smith 
2148dec5eb66SMatthew G Knepley /*@C
2149579dbff0SBarry Smith    MatDenseRestoreArray - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
215073a71a0fSBarry Smith 
21518572280aSBarry Smith    Logically Collective on Mat
21528572280aSBarry Smith 
21538572280aSBarry Smith    Input Parameters:
21546947451fSStefano Zampini +  mat - a dense matrix
2155a2b725a8SWilliam Gropp -  array - pointer to the data
21568572280aSBarry Smith 
21578572280aSBarry Smith    Level: intermediate
21588572280aSBarry Smith 
21596947451fSStefano Zampini .seealso: MatDenseGetArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
21608572280aSBarry Smith @*/
21618572280aSBarry Smith PetscErrorCode  MatDenseRestoreArray(Mat A,PetscScalar **array)
21628572280aSBarry Smith {
21638572280aSBarry Smith   PetscFunctionBegin;
2164d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2165d5ea218eSStefano Zampini   PetscValidPointer(array,2);
2166cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreArray_C",(Mat,PetscScalar**),(A,array));
21679566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)A));
2168637a0070SStefano Zampini #if defined(PETSC_HAVE_CUDA)
2169637a0070SStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
2170637a0070SStefano Zampini #endif
21718572280aSBarry Smith   PetscFunctionReturn(0);
21728572280aSBarry Smith }
21738572280aSBarry Smith 
21748572280aSBarry Smith /*@C
21756947451fSStefano Zampini    MatDenseGetArrayRead - gives read-only access to the array where the data for a dense matrix is stored
21768572280aSBarry Smith 
21778572280aSBarry Smith    Not Collective
21788572280aSBarry Smith 
21798572280aSBarry Smith    Input Parameter:
21806947451fSStefano Zampini .  mat - a dense matrix
21818572280aSBarry Smith 
21828572280aSBarry Smith    Output Parameter:
21838572280aSBarry Smith .   array - pointer to the data
21848572280aSBarry Smith 
21858572280aSBarry Smith    Level: intermediate
21868572280aSBarry Smith 
21876947451fSStefano Zampini .seealso: MatDenseRestoreArrayRead(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
21888572280aSBarry Smith @*/
21898572280aSBarry Smith PetscErrorCode  MatDenseGetArrayRead(Mat A,const PetscScalar **array)
21908572280aSBarry Smith {
21918572280aSBarry Smith   PetscFunctionBegin;
2192d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2193d5ea218eSStefano Zampini   PetscValidPointer(array,2);
2194cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetArrayRead_C",(Mat,const PetscScalar**),(A,array));
21958572280aSBarry Smith   PetscFunctionReturn(0);
21968572280aSBarry Smith }
21978572280aSBarry Smith 
21988572280aSBarry Smith /*@C
21996947451fSStefano Zampini    MatDenseRestoreArrayRead - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArrayRead()
22008572280aSBarry Smith 
220173a71a0fSBarry Smith    Not Collective
220273a71a0fSBarry Smith 
220373a71a0fSBarry Smith    Input Parameters:
22046947451fSStefano Zampini +  mat - a dense matrix
2205a2b725a8SWilliam Gropp -  array - pointer to the data
220673a71a0fSBarry Smith 
220773a71a0fSBarry Smith    Level: intermediate
220873a71a0fSBarry Smith 
22096947451fSStefano Zampini .seealso: MatDenseGetArrayRead(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
221073a71a0fSBarry Smith @*/
22118572280aSBarry Smith PetscErrorCode  MatDenseRestoreArrayRead(Mat A,const PetscScalar **array)
221273a71a0fSBarry Smith {
221373a71a0fSBarry Smith   PetscFunctionBegin;
2214d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2215d5ea218eSStefano Zampini   PetscValidPointer(array,2);
2216cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreArrayRead_C",(Mat,const PetscScalar**),(A,array));
221773a71a0fSBarry Smith   PetscFunctionReturn(0);
221873a71a0fSBarry Smith }
221973a71a0fSBarry Smith 
22206947451fSStefano Zampini /*@C
22216947451fSStefano Zampini    MatDenseGetArrayWrite - gives write-only access to the array where the data for a dense matrix is stored
22226947451fSStefano Zampini 
22236947451fSStefano Zampini    Not Collective
22246947451fSStefano Zampini 
22256947451fSStefano Zampini    Input Parameter:
22266947451fSStefano Zampini .  mat - a dense matrix
22276947451fSStefano Zampini 
22286947451fSStefano Zampini    Output Parameter:
22296947451fSStefano Zampini .   array - pointer to the data
22306947451fSStefano Zampini 
22316947451fSStefano Zampini    Level: intermediate
22326947451fSStefano Zampini 
22336947451fSStefano Zampini .seealso: MatDenseRestoreArrayWrite(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
22346947451fSStefano Zampini @*/
22356947451fSStefano Zampini PetscErrorCode  MatDenseGetArrayWrite(Mat A,PetscScalar **array)
22366947451fSStefano Zampini {
22376947451fSStefano Zampini   PetscFunctionBegin;
2238d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2239d5ea218eSStefano Zampini   PetscValidPointer(array,2);
2240cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetArrayWrite_C",(Mat,PetscScalar**),(A,array));
22416947451fSStefano Zampini   PetscFunctionReturn(0);
22426947451fSStefano Zampini }
22436947451fSStefano Zampini 
22446947451fSStefano Zampini /*@C
22456947451fSStefano Zampini    MatDenseRestoreArrayWrite - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArrayWrite()
22466947451fSStefano Zampini 
22476947451fSStefano Zampini    Not Collective
22486947451fSStefano Zampini 
22496947451fSStefano Zampini    Input Parameters:
22506947451fSStefano Zampini +  mat - a dense matrix
22516947451fSStefano Zampini -  array - pointer to the data
22526947451fSStefano Zampini 
22536947451fSStefano Zampini    Level: intermediate
22546947451fSStefano Zampini 
22556947451fSStefano Zampini .seealso: MatDenseGetArrayWrite(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
22566947451fSStefano Zampini @*/
22576947451fSStefano Zampini PetscErrorCode  MatDenseRestoreArrayWrite(Mat A,PetscScalar **array)
22586947451fSStefano Zampini {
22596947451fSStefano Zampini   PetscFunctionBegin;
2260d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2261d5ea218eSStefano Zampini   PetscValidPointer(array,2);
2262cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreArrayWrite_C",(Mat,PetscScalar**),(A,array));
22639566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)A));
22646947451fSStefano Zampini #if defined(PETSC_HAVE_CUDA)
22656947451fSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
22666947451fSStefano Zampini #endif
22676947451fSStefano Zampini   PetscFunctionReturn(0);
22686947451fSStefano Zampini }
22696947451fSStefano Zampini 
2270023c16fcSToby Isaac static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,MatReuse scall,Mat *B)
22710754003eSLois Curfman McInnes {
2272c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
2273bf5a80bcSToby Isaac   PetscInt       i,j,nrows,ncols,ldb;
22745d0c19d7SBarry Smith   const PetscInt *irow,*icol;
227587828ca2SBarry Smith   PetscScalar    *av,*bv,*v = mat->v;
22760754003eSLois Curfman McInnes   Mat            newmat;
22770754003eSLois Curfman McInnes 
22783a40ed3dSBarry Smith   PetscFunctionBegin;
22799566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(isrow,&irow));
22809566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(iscol,&icol));
22819566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(isrow,&nrows));
22829566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(iscol,&ncols));
22830754003eSLois Curfman McInnes 
2284182d2002SSatish Balay   /* Check submatrixcall */
2285182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
228613f74950SBarry Smith     PetscInt n_cols,n_rows;
22879566063dSJacob Faibussowitsch     PetscCall(MatGetSize(*B,&n_rows,&n_cols));
228821a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
2289f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
22909566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(*B,nrows,ncols,nrows,ncols));
229121a2c019SBarry Smith     }
2292182d2002SSatish Balay     newmat = *B;
2293182d2002SSatish Balay   } else {
22940754003eSLois Curfman McInnes     /* Create and fill new matrix */
22959566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&newmat));
22969566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(newmat,nrows,ncols,nrows,ncols));
22979566063dSJacob Faibussowitsch     PetscCall(MatSetType(newmat,((PetscObject)A)->type_name));
22989566063dSJacob Faibussowitsch     PetscCall(MatSeqDenseSetPreallocation(newmat,NULL));
2299182d2002SSatish Balay   }
2300182d2002SSatish Balay 
2301182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
23029566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(newmat,&bv));
23039566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(newmat,&ldb));
2304182d2002SSatish Balay   for (i=0; i<ncols; i++) {
23056de62eeeSBarry Smith     av = v + mat->lda*icol[i];
2306ca15aa20SStefano Zampini     for (j=0; j<nrows; j++) bv[j] = av[irow[j]];
2307bf5a80bcSToby Isaac     bv += ldb;
23080754003eSLois Curfman McInnes   }
23099566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(newmat,&bv));
2310182d2002SSatish Balay 
2311182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
23129566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY));
23139566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY));
23140754003eSLois Curfman McInnes 
23150754003eSLois Curfman McInnes   /* Free work space */
23169566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(isrow,&irow));
23179566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(iscol,&icol));
2318182d2002SSatish Balay   *B   = newmat;
23193a40ed3dSBarry Smith   PetscFunctionReturn(0);
23200754003eSLois Curfman McInnes }
23210754003eSLois Curfman McInnes 
23227dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2323905e6a2fSBarry Smith {
232413f74950SBarry Smith   PetscInt       i;
2325905e6a2fSBarry Smith 
23263a40ed3dSBarry Smith   PetscFunctionBegin;
2327905e6a2fSBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
23289566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1(n,B));
2329905e6a2fSBarry Smith   }
2330905e6a2fSBarry Smith 
2331905e6a2fSBarry Smith   for (i=0; i<n; i++) {
23329566063dSJacob Faibussowitsch     PetscCall(MatCreateSubMatrix_SeqDense(A,irow[i],icol[i],scall,&(*B)[i]));
2333905e6a2fSBarry Smith   }
23343a40ed3dSBarry Smith   PetscFunctionReturn(0);
2335905e6a2fSBarry Smith }
2336905e6a2fSBarry Smith 
2337e0877f53SBarry Smith static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat,MatAssemblyType mode)
2338c0aa2d19SHong Zhang {
2339c0aa2d19SHong Zhang   PetscFunctionBegin;
2340c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2341c0aa2d19SHong Zhang }
2342c0aa2d19SHong Zhang 
2343e0877f53SBarry Smith static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat,MatAssemblyType mode)
2344c0aa2d19SHong Zhang {
2345c0aa2d19SHong Zhang   PetscFunctionBegin;
2346c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2347c0aa2d19SHong Zhang }
2348c0aa2d19SHong Zhang 
2349a76f77c3SStefano Zampini PetscErrorCode MatCopy_SeqDense(Mat A,Mat B,MatStructure str)
23504b0e389bSBarry Smith {
23514b0e389bSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data,*b = (Mat_SeqDense*)B->data;
2352ca15aa20SStefano Zampini   const PetscScalar *va;
2353ca15aa20SStefano Zampini   PetscScalar       *vb;
2354d0f46423SBarry Smith   PetscInt          lda1=a->lda,lda2=b->lda, m=A->rmap->n,n=A->cmap->n, j;
23553a40ed3dSBarry Smith 
23563a40ed3dSBarry Smith   PetscFunctionBegin;
235733f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
235833f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
23599566063dSJacob Faibussowitsch     PetscCall(MatCopy_Basic(A,B,str));
23603a40ed3dSBarry Smith     PetscFunctionReturn(0);
23613a40ed3dSBarry Smith   }
2362aed4548fSBarry Smith   PetscCheck(m == B->rmap->n && n == B->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"size(B) != size(A)");
23639566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&va));
23649566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(B,&vb));
2365a5ce6ee0Svictorle   if (lda1>m || lda2>m) {
23660dbb7854Svictorle     for (j=0; j<n; j++) {
23679566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(vb+j*lda2,va+j*lda1,m));
2368a5ce6ee0Svictorle     }
2369a5ce6ee0Svictorle   } else {
23709566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(vb,va,A->rmap->n*A->cmap->n));
2371a5ce6ee0Svictorle   }
23729566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(B,&vb));
23739566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&va));
23749566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY));
23759566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY));
2376273d9f13SBarry Smith   PetscFunctionReturn(0);
2377273d9f13SBarry Smith }
2378273d9f13SBarry Smith 
237975f6d85dSStefano Zampini PetscErrorCode MatSetUp_SeqDense(Mat A)
2380273d9f13SBarry Smith {
2381273d9f13SBarry Smith   PetscFunctionBegin;
23829566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(A->rmap));
23839566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(A->cmap));
238418992e5dSStefano Zampini   if (!A->preallocated) {
23859566063dSJacob Faibussowitsch     PetscCall(MatSeqDenseSetPreallocation(A,NULL));
238618992e5dSStefano Zampini   }
23873a40ed3dSBarry Smith   PetscFunctionReturn(0);
23884b0e389bSBarry Smith }
23894b0e389bSBarry Smith 
2390ba337c44SJed Brown static PetscErrorCode MatConjugate_SeqDense(Mat A)
2391ba337c44SJed Brown {
23924396437dSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense *) A->data;
2393ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
23944396437dSToby Isaac   PetscInt       min = PetscMin(A->rmap->n,A->cmap->n);
2395ca15aa20SStefano Zampini   PetscScalar    *aa;
2396ba337c44SJed Brown 
2397ba337c44SJed Brown   PetscFunctionBegin;
23989566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&aa));
2399ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscConj(aa[i]);
24009566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&aa));
24014396437dSToby Isaac   if (mat->tau) for (i = 0; i < min; i++) mat->tau[i] = PetscConj(mat->tau[i]);
2402ba337c44SJed Brown   PetscFunctionReturn(0);
2403ba337c44SJed Brown }
2404ba337c44SJed Brown 
2405ba337c44SJed Brown static PetscErrorCode MatRealPart_SeqDense(Mat A)
2406ba337c44SJed Brown {
2407ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2408ca15aa20SStefano Zampini   PetscScalar    *aa;
2409ba337c44SJed Brown 
2410ba337c44SJed Brown   PetscFunctionBegin;
24119566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&aa));
2412ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
24139566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&aa));
2414ba337c44SJed Brown   PetscFunctionReturn(0);
2415ba337c44SJed Brown }
2416ba337c44SJed Brown 
2417ba337c44SJed Brown static PetscErrorCode MatImaginaryPart_SeqDense(Mat A)
2418ba337c44SJed Brown {
2419ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2420ca15aa20SStefano Zampini   PetscScalar    *aa;
2421ba337c44SJed Brown 
2422ba337c44SJed Brown   PetscFunctionBegin;
24239566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&aa));
2424ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
24259566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&aa));
2426ba337c44SJed Brown   PetscFunctionReturn(0);
2427ba337c44SJed Brown }
2428284134d9SBarry Smith 
2429a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/
24304222ddf1SHong Zhang PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
2431a9fe9ddaSSatish Balay {
2432d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
24337a3c3d58SStefano Zampini   PetscBool      cisdense;
2434a9fe9ddaSSatish Balay 
2435ee16a9a1SHong Zhang   PetscFunctionBegin;
24369566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C,m,n,m,n));
24379566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,""));
24387a3c3d58SStefano Zampini   if (!cisdense) {
24397a3c3d58SStefano Zampini     PetscBool flg;
24407a3c3d58SStefano Zampini 
24419566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg));
24429566063dSJacob Faibussowitsch     PetscCall(MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE));
24437a3c3d58SStefano Zampini   }
24449566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
2445ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2446ee16a9a1SHong Zhang }
2447a9fe9ddaSSatish Balay 
2448a9fe9ddaSSatish Balay PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2449a9fe9ddaSSatish Balay {
24506718818eSStefano Zampini   Mat_SeqDense       *a=(Mat_SeqDense*)A->data,*b=(Mat_SeqDense*)B->data,*c=(Mat_SeqDense*)C->data;
24510805154bSBarry Smith   PetscBLASInt       m,n,k;
2452ca15aa20SStefano Zampini   const PetscScalar *av,*bv;
2453ca15aa20SStefano Zampini   PetscScalar       *cv;
2454a9fe9ddaSSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
2455a9fe9ddaSSatish Balay 
2456a9fe9ddaSSatish Balay   PetscFunctionBegin;
24579566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n,&m));
24589566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n,&n));
24599566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&k));
246049d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
24619566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&av));
24629566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B,&bv));
24639566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C,&cv));
2464ca15aa20SStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
24659566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1)));
24669566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&av));
24679566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B,&bv));
24689566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C,&cv));
2469a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2470a9fe9ddaSSatish Balay }
2471a9fe9ddaSSatish Balay 
24724222ddf1SHong Zhang PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
247369f65d41SStefano Zampini {
247469f65d41SStefano Zampini   PetscInt       m=A->rmap->n,n=B->rmap->n;
24757a3c3d58SStefano Zampini   PetscBool      cisdense;
247669f65d41SStefano Zampini 
247769f65d41SStefano Zampini   PetscFunctionBegin;
24789566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C,m,n,m,n));
24799566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,""));
24807a3c3d58SStefano Zampini   if (!cisdense) {
24817a3c3d58SStefano Zampini     PetscBool flg;
24827a3c3d58SStefano Zampini 
24839566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg));
24849566063dSJacob Faibussowitsch     PetscCall(MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE));
24857a3c3d58SStefano Zampini   }
24869566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
248769f65d41SStefano Zampini   PetscFunctionReturn(0);
248869f65d41SStefano Zampini }
248969f65d41SStefano Zampini 
249069f65d41SStefano Zampini PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
249169f65d41SStefano Zampini {
249269f65d41SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
249369f65d41SStefano Zampini   Mat_SeqDense      *b = (Mat_SeqDense*)B->data;
249469f65d41SStefano Zampini   Mat_SeqDense      *c = (Mat_SeqDense*)C->data;
24956718818eSStefano Zampini   const PetscScalar *av,*bv;
24966718818eSStefano Zampini   PetscScalar       *cv;
249769f65d41SStefano Zampini   PetscBLASInt      m,n,k;
249869f65d41SStefano Zampini   PetscScalar       _DOne=1.0,_DZero=0.0;
249969f65d41SStefano Zampini 
250069f65d41SStefano Zampini   PetscFunctionBegin;
25019566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n,&m));
25029566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n,&n));
25039566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&k));
250449d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
25059566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&av));
25069566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B,&bv));
25079566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C,&cv));
25086718818eSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","T",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
25099566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&av));
25109566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B,&bv));
25119566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C,&cv));
25129566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1)));
251369f65d41SStefano Zampini   PetscFunctionReturn(0);
251469f65d41SStefano Zampini }
251569f65d41SStefano Zampini 
25164222ddf1SHong Zhang PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
2517a9fe9ddaSSatish Balay {
2518d0f46423SBarry Smith   PetscInt       m=A->cmap->n,n=B->cmap->n;
25197a3c3d58SStefano Zampini   PetscBool      cisdense;
2520a9fe9ddaSSatish Balay 
2521ee16a9a1SHong Zhang   PetscFunctionBegin;
25229566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C,m,n,m,n));
25239566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,""));
25247a3c3d58SStefano Zampini   if (!cisdense) {
25257a3c3d58SStefano Zampini     PetscBool flg;
25267a3c3d58SStefano Zampini 
25279566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg));
25289566063dSJacob Faibussowitsch     PetscCall(MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE));
25297a3c3d58SStefano Zampini   }
25309566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
2531ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2532ee16a9a1SHong Zhang }
2533a9fe9ddaSSatish Balay 
253475648e8dSHong Zhang PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2535a9fe9ddaSSatish Balay {
2536a9fe9ddaSSatish Balay   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2537a9fe9ddaSSatish Balay   Mat_SeqDense      *b = (Mat_SeqDense*)B->data;
2538a9fe9ddaSSatish Balay   Mat_SeqDense      *c = (Mat_SeqDense*)C->data;
25396718818eSStefano Zampini   const PetscScalar *av,*bv;
25406718818eSStefano Zampini   PetscScalar       *cv;
25410805154bSBarry Smith   PetscBLASInt      m,n,k;
2542a9fe9ddaSSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
2543a9fe9ddaSSatish Balay 
2544a9fe9ddaSSatish Balay   PetscFunctionBegin;
25459566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n,&m));
25469566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n,&n));
25479566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&k));
254849d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
25499566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&av));
25509566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B,&bv));
25519566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C,&cv));
25526718818eSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
25539566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&av));
25549566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B,&bv));
25559566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C,&cv));
25569566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1)));
2557a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2558a9fe9ddaSSatish Balay }
2559985db425SBarry Smith 
25604222ddf1SHong Zhang /* ----------------------------------------------- */
25614222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C)
25624222ddf1SHong Zhang {
25634222ddf1SHong Zhang   PetscFunctionBegin;
25644222ddf1SHong Zhang   C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense;
25654222ddf1SHong Zhang   C->ops->productsymbolic = MatProductSymbolic_AB;
25664222ddf1SHong Zhang   PetscFunctionReturn(0);
25674222ddf1SHong Zhang }
25684222ddf1SHong Zhang 
25694222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C)
25704222ddf1SHong Zhang {
25714222ddf1SHong Zhang   PetscFunctionBegin;
25724222ddf1SHong Zhang   C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense;
25734222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_AtB;
25744222ddf1SHong Zhang   PetscFunctionReturn(0);
25754222ddf1SHong Zhang }
25764222ddf1SHong Zhang 
25774222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C)
25784222ddf1SHong Zhang {
25794222ddf1SHong Zhang   PetscFunctionBegin;
25804222ddf1SHong Zhang   C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense;
25814222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_ABt;
25824222ddf1SHong Zhang   PetscFunctionReturn(0);
25834222ddf1SHong Zhang }
25844222ddf1SHong Zhang 
25854222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C)
25864222ddf1SHong Zhang {
25874222ddf1SHong Zhang   Mat_Product    *product = C->product;
25884222ddf1SHong Zhang 
25894222ddf1SHong Zhang   PetscFunctionBegin;
25904222ddf1SHong Zhang   switch (product->type) {
25914222ddf1SHong Zhang   case MATPRODUCT_AB:
25929566063dSJacob Faibussowitsch     PetscCall(MatProductSetFromOptions_SeqDense_AB(C));
25934222ddf1SHong Zhang     break;
25944222ddf1SHong Zhang   case MATPRODUCT_AtB:
25959566063dSJacob Faibussowitsch     PetscCall(MatProductSetFromOptions_SeqDense_AtB(C));
25964222ddf1SHong Zhang     break;
25974222ddf1SHong Zhang   case MATPRODUCT_ABt:
25989566063dSJacob Faibussowitsch     PetscCall(MatProductSetFromOptions_SeqDense_ABt(C));
25994222ddf1SHong Zhang     break;
26006718818eSStefano Zampini   default:
26014222ddf1SHong Zhang     break;
26024222ddf1SHong Zhang   }
26034222ddf1SHong Zhang   PetscFunctionReturn(0);
26044222ddf1SHong Zhang }
26054222ddf1SHong Zhang /* ----------------------------------------------- */
26064222ddf1SHong Zhang 
2607e0877f53SBarry Smith static PetscErrorCode MatGetRowMax_SeqDense(Mat A,Vec v,PetscInt idx[])
2608985db425SBarry Smith {
2609985db425SBarry Smith   Mat_SeqDense       *a = (Mat_SeqDense*)A->data;
2610d0f46423SBarry Smith   PetscInt           i,j,m = A->rmap->n,n = A->cmap->n,p;
2611985db425SBarry Smith   PetscScalar        *x;
2612ca15aa20SStefano Zampini   const PetscScalar *aa;
2613985db425SBarry Smith 
2614985db425SBarry Smith   PetscFunctionBegin;
261528b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
26169566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v,&x));
26179566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v,&p));
26189566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&aa));
261908401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2620985db425SBarry Smith   for (i=0; i<m; i++) {
2621985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2622985db425SBarry Smith     for (j=1; j<n; j++) {
2623ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) < PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2624985db425SBarry Smith     }
2625985db425SBarry Smith   }
26269566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&aa));
26279566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v,&x));
2628985db425SBarry Smith   PetscFunctionReturn(0);
2629985db425SBarry Smith }
2630985db425SBarry Smith 
2631e0877f53SBarry Smith static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A,Vec v,PetscInt idx[])
2632985db425SBarry Smith {
2633985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2634d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2635985db425SBarry Smith   PetscScalar       *x;
2636985db425SBarry Smith   PetscReal         atmp;
2637ca15aa20SStefano Zampini   const PetscScalar *aa;
2638985db425SBarry Smith 
2639985db425SBarry Smith   PetscFunctionBegin;
264028b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
26419566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v,&x));
26429566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v,&p));
26439566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&aa));
264408401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2645985db425SBarry Smith   for (i=0; i<m; i++) {
26469189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
2647985db425SBarry Smith     for (j=1; j<n; j++) {
2648ca15aa20SStefano Zampini       atmp = PetscAbsScalar(aa[i+a->lda*j]);
2649985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = j;}
2650985db425SBarry Smith     }
2651985db425SBarry Smith   }
26529566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&aa));
26539566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v,&x));
2654985db425SBarry Smith   PetscFunctionReturn(0);
2655985db425SBarry Smith }
2656985db425SBarry Smith 
2657e0877f53SBarry Smith static PetscErrorCode MatGetRowMin_SeqDense(Mat A,Vec v,PetscInt idx[])
2658985db425SBarry Smith {
2659985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2660d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2661985db425SBarry Smith   PetscScalar       *x;
2662ca15aa20SStefano Zampini   const PetscScalar *aa;
2663985db425SBarry Smith 
2664985db425SBarry Smith   PetscFunctionBegin;
266528b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
26669566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&aa));
26679566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v,&x));
26689566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v,&p));
266908401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2670985db425SBarry Smith   for (i=0; i<m; i++) {
2671985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2672985db425SBarry Smith     for (j=1; j<n; j++) {
2673ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) > PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2674985db425SBarry Smith     }
2675985db425SBarry Smith   }
26769566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v,&x));
26779566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&aa));
2678985db425SBarry Smith   PetscFunctionReturn(0);
2679985db425SBarry Smith }
2680985db425SBarry Smith 
2681637a0070SStefano Zampini PetscErrorCode MatGetColumnVector_SeqDense(Mat A,Vec v,PetscInt col)
26828d0534beSBarry Smith {
26838d0534beSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
26848d0534beSBarry Smith   PetscScalar       *x;
2685ca15aa20SStefano Zampini   const PetscScalar *aa;
26868d0534beSBarry Smith 
26878d0534beSBarry Smith   PetscFunctionBegin;
268828b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
26899566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&aa));
26909566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v,&x));
26919566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(x,aa+col*a->lda,A->rmap->n));
26929566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v,&x));
26939566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&aa));
26948d0534beSBarry Smith   PetscFunctionReturn(0);
26958d0534beSBarry Smith }
26968d0534beSBarry Smith 
2697857cbf51SRichard Tran Mills PETSC_INTERN PetscErrorCode MatGetColumnReductions_SeqDense(Mat A,PetscInt type,PetscReal *reductions)
26980716a85fSBarry Smith {
26990716a85fSBarry Smith   PetscInt          i,j,m,n;
27001683a169SBarry Smith   const PetscScalar *a;
27010716a85fSBarry Smith 
27020716a85fSBarry Smith   PetscFunctionBegin;
27039566063dSJacob Faibussowitsch   PetscCall(MatGetSize(A,&m,&n));
27049566063dSJacob Faibussowitsch   PetscCall(PetscArrayzero(reductions,n));
27059566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&a));
2706857cbf51SRichard Tran Mills   if (type == NORM_2) {
27070716a85fSBarry Smith     for (i=0; i<n; i++) {
27080716a85fSBarry Smith       for (j=0; j<m; j++) {
2709a873a8cdSSam Reynolds         reductions[i] += PetscAbsScalar(a[j]*a[j]);
27100716a85fSBarry Smith       }
27110716a85fSBarry Smith       a += m;
27120716a85fSBarry Smith     }
2713857cbf51SRichard Tran Mills   } else if (type == NORM_1) {
27140716a85fSBarry Smith     for (i=0; i<n; i++) {
27150716a85fSBarry Smith       for (j=0; j<m; j++) {
2716a873a8cdSSam Reynolds         reductions[i] += PetscAbsScalar(a[j]);
27170716a85fSBarry Smith       }
27180716a85fSBarry Smith       a += m;
27190716a85fSBarry Smith     }
2720857cbf51SRichard Tran Mills   } else if (type == NORM_INFINITY) {
27210716a85fSBarry Smith     for (i=0; i<n; i++) {
27220716a85fSBarry Smith       for (j=0; j<m; j++) {
2723a873a8cdSSam Reynolds         reductions[i] = PetscMax(PetscAbsScalar(a[j]),reductions[i]);
27240716a85fSBarry Smith       }
27250716a85fSBarry Smith       a += m;
27260716a85fSBarry Smith     }
2727857cbf51SRichard Tran Mills   } else if (type == REDUCTION_SUM_REALPART || type == REDUCTION_MEAN_REALPART) {
2728a873a8cdSSam Reynolds     for (i=0; i<n; i++) {
2729a873a8cdSSam Reynolds       for (j=0; j<m; j++) {
2730857cbf51SRichard Tran Mills         reductions[i] += PetscRealPart(a[j]);
2731a873a8cdSSam Reynolds       }
2732a873a8cdSSam Reynolds       a += m;
2733a873a8cdSSam Reynolds     }
2734857cbf51SRichard Tran Mills   } else if (type == REDUCTION_SUM_IMAGINARYPART || type == REDUCTION_MEAN_IMAGINARYPART) {
2735857cbf51SRichard Tran Mills     for (i=0; i<n; i++) {
2736857cbf51SRichard Tran Mills       for (j=0; j<m; j++) {
2737857cbf51SRichard Tran Mills         reductions[i] += PetscImaginaryPart(a[j]);
2738857cbf51SRichard Tran Mills       }
2739857cbf51SRichard Tran Mills       a += m;
2740857cbf51SRichard Tran Mills     }
2741857cbf51SRichard Tran Mills   } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Unknown reduction type");
27429566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&a));
2743857cbf51SRichard Tran Mills   if (type == NORM_2) {
2744a873a8cdSSam Reynolds     for (i=0; i<n; i++) reductions[i] = PetscSqrtReal(reductions[i]);
2745857cbf51SRichard Tran Mills   } else if (type == REDUCTION_MEAN_REALPART || type == REDUCTION_MEAN_IMAGINARYPART) {
2746a873a8cdSSam Reynolds     for (i=0; i<n; i++) reductions[i] /= m;
27470716a85fSBarry Smith   }
27480716a85fSBarry Smith   PetscFunctionReturn(0);
27490716a85fSBarry Smith }
27500716a85fSBarry Smith 
275173a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqDense(Mat x,PetscRandom rctx)
275273a71a0fSBarry Smith {
275373a71a0fSBarry Smith   PetscScalar    *a;
2754637a0070SStefano Zampini   PetscInt       lda,m,n,i,j;
275573a71a0fSBarry Smith 
275673a71a0fSBarry Smith   PetscFunctionBegin;
27579566063dSJacob Faibussowitsch   PetscCall(MatGetSize(x,&m,&n));
27589566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(x,&lda));
27599566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(x,&a));
2760637a0070SStefano Zampini   for (j=0; j<n; j++) {
2761637a0070SStefano Zampini     for (i=0; i<m; i++) {
27629566063dSJacob Faibussowitsch       PetscCall(PetscRandomGetValue(rctx,a+j*lda+i));
2763637a0070SStefano Zampini     }
276473a71a0fSBarry Smith   }
27659566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(x,&a));
276673a71a0fSBarry Smith   PetscFunctionReturn(0);
276773a71a0fSBarry Smith }
276873a71a0fSBarry Smith 
27693b49f96aSBarry Smith static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A,PetscBool  *missing,PetscInt *d)
27703b49f96aSBarry Smith {
27713b49f96aSBarry Smith   PetscFunctionBegin;
27723b49f96aSBarry Smith   *missing = PETSC_FALSE;
27733b49f96aSBarry Smith   PetscFunctionReturn(0);
27743b49f96aSBarry Smith }
277573a71a0fSBarry Smith 
2776ca15aa20SStefano Zampini /* vals is not const */
2777af53bab2SHong Zhang static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A,PetscInt col,PetscScalar **vals)
277886aefd0dSHong Zhang {
277986aefd0dSHong Zhang   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2780ca15aa20SStefano Zampini   PetscScalar    *v;
278186aefd0dSHong Zhang 
278286aefd0dSHong Zhang   PetscFunctionBegin;
278328b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
27849566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&v));
2785ca15aa20SStefano Zampini   *vals = v+col*a->lda;
27869566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&v));
278786aefd0dSHong Zhang   PetscFunctionReturn(0);
278886aefd0dSHong Zhang }
278986aefd0dSHong Zhang 
2790af53bab2SHong Zhang static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A,PetscScalar **vals)
279186aefd0dSHong Zhang {
279286aefd0dSHong Zhang   PetscFunctionBegin;
2793a5b23f4aSJose E. Roman   *vals = NULL; /* user cannot accidentally use the array later */
279486aefd0dSHong Zhang   PetscFunctionReturn(0);
279586aefd0dSHong Zhang }
2796abc3b08eSStefano Zampini 
2797289bc588SBarry Smith /* -------------------------------------------------------------------*/
2798a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqDense,
2799905e6a2fSBarry Smith                                         MatGetRow_SeqDense,
2800905e6a2fSBarry Smith                                         MatRestoreRow_SeqDense,
2801905e6a2fSBarry Smith                                         MatMult_SeqDense,
280297304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqDense,
28037c922b88SBarry Smith                                         MatMultTranspose_SeqDense,
28047c922b88SBarry Smith                                         MatMultTransposeAdd_SeqDense,
2805f4259b30SLisandro Dalcin                                         NULL,
2806f4259b30SLisandro Dalcin                                         NULL,
2807f4259b30SLisandro Dalcin                                         NULL,
2808f4259b30SLisandro Dalcin                                 /* 10*/ NULL,
2809905e6a2fSBarry Smith                                         MatLUFactor_SeqDense,
2810905e6a2fSBarry Smith                                         MatCholeskyFactor_SeqDense,
281141f059aeSBarry Smith                                         MatSOR_SeqDense,
2812ec8511deSBarry Smith                                         MatTranspose_SeqDense,
281397304618SKris Buschelman                                 /* 15*/ MatGetInfo_SeqDense,
2814905e6a2fSBarry Smith                                         MatEqual_SeqDense,
2815905e6a2fSBarry Smith                                         MatGetDiagonal_SeqDense,
2816905e6a2fSBarry Smith                                         MatDiagonalScale_SeqDense,
2817905e6a2fSBarry Smith                                         MatNorm_SeqDense,
2818c0aa2d19SHong Zhang                                 /* 20*/ MatAssemblyBegin_SeqDense,
2819c0aa2d19SHong Zhang                                         MatAssemblyEnd_SeqDense,
2820905e6a2fSBarry Smith                                         MatSetOption_SeqDense,
2821905e6a2fSBarry Smith                                         MatZeroEntries_SeqDense,
2822d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqDense,
2823f4259b30SLisandro Dalcin                                         NULL,
2824f4259b30SLisandro Dalcin                                         NULL,
2825f4259b30SLisandro Dalcin                                         NULL,
2826f4259b30SLisandro Dalcin                                         NULL,
28274994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqDense,
2828f4259b30SLisandro Dalcin                                         NULL,
2829f4259b30SLisandro Dalcin                                         NULL,
2830f4259b30SLisandro Dalcin                                         NULL,
2831f4259b30SLisandro Dalcin                                         NULL,
2832d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqDense,
2833f4259b30SLisandro Dalcin                                         NULL,
2834f4259b30SLisandro Dalcin                                         NULL,
2835f4259b30SLisandro Dalcin                                         NULL,
2836f4259b30SLisandro Dalcin                                         NULL,
2837d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqDense,
28387dae84e0SHong Zhang                                         MatCreateSubMatrices_SeqDense,
2839f4259b30SLisandro Dalcin                                         NULL,
28404b0e389bSBarry Smith                                         MatGetValues_SeqDense,
2841a5ae1ecdSBarry Smith                                         MatCopy_SeqDense,
2842d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqDense,
2843a5ae1ecdSBarry Smith                                         MatScale_SeqDense,
28447d68702bSBarry Smith                                         MatShift_Basic,
2845f4259b30SLisandro Dalcin                                         NULL,
28463f49a652SStefano Zampini                                         MatZeroRowsColumns_SeqDense,
284773a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqDense,
2848f4259b30SLisandro Dalcin                                         NULL,
2849f4259b30SLisandro Dalcin                                         NULL,
2850f4259b30SLisandro Dalcin                                         NULL,
2851f4259b30SLisandro Dalcin                                         NULL,
2852f4259b30SLisandro Dalcin                                 /* 54*/ NULL,
2853f4259b30SLisandro Dalcin                                         NULL,
2854f4259b30SLisandro Dalcin                                         NULL,
2855f4259b30SLisandro Dalcin                                         NULL,
2856f4259b30SLisandro Dalcin                                         NULL,
2857023c16fcSToby Isaac                                 /* 59*/ MatCreateSubMatrix_SeqDense,
2858e03a110bSBarry Smith                                         MatDestroy_SeqDense,
2859e03a110bSBarry Smith                                         MatView_SeqDense,
2860f4259b30SLisandro Dalcin                                         NULL,
2861f4259b30SLisandro Dalcin                                         NULL,
2862f4259b30SLisandro Dalcin                                 /* 64*/ NULL,
2863f4259b30SLisandro Dalcin                                         NULL,
2864f4259b30SLisandro Dalcin                                         NULL,
2865f4259b30SLisandro Dalcin                                         NULL,
2866f4259b30SLisandro Dalcin                                         NULL,
2867d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqDense,
2868f4259b30SLisandro Dalcin                                         NULL,
2869f4259b30SLisandro Dalcin                                         NULL,
2870f4259b30SLisandro Dalcin                                         NULL,
2871f4259b30SLisandro Dalcin                                         NULL,
2872f4259b30SLisandro Dalcin                                 /* 74*/ NULL,
2873f4259b30SLisandro Dalcin                                         NULL,
2874f4259b30SLisandro Dalcin                                         NULL,
2875f4259b30SLisandro Dalcin                                         NULL,
2876f4259b30SLisandro Dalcin                                         NULL,
2877f4259b30SLisandro Dalcin                                 /* 79*/ NULL,
2878f4259b30SLisandro Dalcin                                         NULL,
2879f4259b30SLisandro Dalcin                                         NULL,
2880f4259b30SLisandro Dalcin                                         NULL,
28815bba2384SShri Abhyankar                                 /* 83*/ MatLoad_SeqDense,
2882637a0070SStefano Zampini                                         MatIsSymmetric_SeqDense,
28831cbb95d3SBarry Smith                                         MatIsHermitian_SeqDense,
2884f4259b30SLisandro Dalcin                                         NULL,
2885f4259b30SLisandro Dalcin                                         NULL,
2886f4259b30SLisandro Dalcin                                         NULL,
2887f4259b30SLisandro Dalcin                                 /* 89*/ NULL,
2888f4259b30SLisandro Dalcin                                         NULL,
2889a9fe9ddaSSatish Balay                                         MatMatMultNumeric_SeqDense_SeqDense,
2890f4259b30SLisandro Dalcin                                         NULL,
2891f4259b30SLisandro Dalcin                                         NULL,
2892f4259b30SLisandro Dalcin                                 /* 94*/ NULL,
2893f4259b30SLisandro Dalcin                                         NULL,
2894f4259b30SLisandro Dalcin                                         NULL,
289569f65d41SStefano Zampini                                         MatMatTransposeMultNumeric_SeqDense_SeqDense,
2896f4259b30SLisandro Dalcin                                         NULL,
28974222ddf1SHong Zhang                                 /* 99*/ MatProductSetFromOptions_SeqDense,
2898f4259b30SLisandro Dalcin                                         NULL,
2899f4259b30SLisandro Dalcin                                         NULL,
2900ba337c44SJed Brown                                         MatConjugate_SeqDense,
2901f4259b30SLisandro Dalcin                                         NULL,
2902f4259b30SLisandro Dalcin                                 /*104*/ NULL,
2903ba337c44SJed Brown                                         MatRealPart_SeqDense,
2904ba337c44SJed Brown                                         MatImaginaryPart_SeqDense,
2905f4259b30SLisandro Dalcin                                         NULL,
2906f4259b30SLisandro Dalcin                                         NULL,
2907f4259b30SLisandro Dalcin                                 /*109*/ NULL,
2908f4259b30SLisandro Dalcin                                         NULL,
29098d0534beSBarry Smith                                         MatGetRowMin_SeqDense,
2910aabbc4fbSShri Abhyankar                                         MatGetColumnVector_SeqDense,
29113b49f96aSBarry Smith                                         MatMissingDiagonal_SeqDense,
2912f4259b30SLisandro Dalcin                                 /*114*/ NULL,
2913f4259b30SLisandro Dalcin                                         NULL,
2914f4259b30SLisandro Dalcin                                         NULL,
2915f4259b30SLisandro Dalcin                                         NULL,
2916f4259b30SLisandro Dalcin                                         NULL,
2917f4259b30SLisandro Dalcin                                 /*119*/ NULL,
2918f4259b30SLisandro Dalcin                                         NULL,
2919f4259b30SLisandro Dalcin                                         NULL,
2920f4259b30SLisandro Dalcin                                         NULL,
2921f4259b30SLisandro Dalcin                                         NULL,
2922f4259b30SLisandro Dalcin                                 /*124*/ NULL,
2923a873a8cdSSam Reynolds                                         MatGetColumnReductions_SeqDense,
2924f4259b30SLisandro Dalcin                                         NULL,
2925f4259b30SLisandro Dalcin                                         NULL,
2926f4259b30SLisandro Dalcin                                         NULL,
2927f4259b30SLisandro Dalcin                                 /*129*/ NULL,
2928f4259b30SLisandro Dalcin                                         NULL,
2929f4259b30SLisandro Dalcin                                         NULL,
293075648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqDense_SeqDense,
2931f4259b30SLisandro Dalcin                                         NULL,
2932f4259b30SLisandro Dalcin                                 /*134*/ NULL,
2933f4259b30SLisandro Dalcin                                         NULL,
2934f4259b30SLisandro Dalcin                                         NULL,
2935f4259b30SLisandro Dalcin                                         NULL,
2936f4259b30SLisandro Dalcin                                         NULL,
2937f4259b30SLisandro Dalcin                                 /*139*/ NULL,
2938f4259b30SLisandro Dalcin                                         NULL,
2939f4259b30SLisandro Dalcin                                         NULL,
2940f4259b30SLisandro Dalcin                                         NULL,
2941f4259b30SLisandro Dalcin                                         NULL,
29424222ddf1SHong Zhang                                         MatCreateMPIMatConcatenateSeqMat_SeqDense,
2943f4259b30SLisandro Dalcin                                 /*145*/ NULL,
2944f4259b30SLisandro Dalcin                                         NULL,
2945f4259b30SLisandro Dalcin                                         NULL
2946985db425SBarry Smith };
294790ace30eSBarry Smith 
29484b828684SBarry Smith /*@C
2949fafbff53SBarry Smith    MatCreateSeqDense - Creates a sequential dense matrix that
2950d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
2951d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
2952289bc588SBarry Smith 
2953d083f849SBarry Smith    Collective
2954db81eaa0SLois Curfman McInnes 
295520563c6bSBarry Smith    Input Parameters:
2956db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
29570c775827SLois Curfman McInnes .  m - number of rows
295818f449edSLois Curfman McInnes .  n - number of columns
29590298fd71SBarry Smith -  data - optional location of matrix data in column major order.  Set data=NULL for PETSc
2960dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
296120563c6bSBarry Smith 
296220563c6bSBarry Smith    Output Parameter:
296344cd7ae7SLois Curfman McInnes .  A - the matrix
296420563c6bSBarry Smith 
2965b259b22eSLois Curfman McInnes    Notes:
296618f449edSLois Curfman McInnes    The data input variable is intended primarily for Fortran programmers
296718f449edSLois Curfman McInnes    who wish to allocate their own matrix memory space.  Most users should
29680298fd71SBarry Smith    set data=NULL.
296918f449edSLois Curfman McInnes 
2970027ccd11SLois Curfman McInnes    Level: intermediate
2971027ccd11SLois Curfman McInnes 
297269b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues()
297320563c6bSBarry Smith @*/
29747087cfbeSBarry Smith PetscErrorCode  MatCreateSeqDense(MPI_Comm comm,PetscInt m,PetscInt n,PetscScalar *data,Mat *A)
2975289bc588SBarry Smith {
29763a40ed3dSBarry Smith   PetscFunctionBegin;
29779566063dSJacob Faibussowitsch   PetscCall(MatCreate(comm,A));
29789566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*A,m,n,m,n));
29799566063dSJacob Faibussowitsch   PetscCall(MatSetType(*A,MATSEQDENSE));
29809566063dSJacob Faibussowitsch   PetscCall(MatSeqDenseSetPreallocation(*A,data));
2981273d9f13SBarry Smith   PetscFunctionReturn(0);
2982273d9f13SBarry Smith }
2983273d9f13SBarry Smith 
2984273d9f13SBarry Smith /*@C
2985273d9f13SBarry Smith    MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements
2986273d9f13SBarry Smith 
2987d083f849SBarry Smith    Collective
2988273d9f13SBarry Smith 
2989273d9f13SBarry Smith    Input Parameters:
29901c4f3114SJed Brown +  B - the matrix
29910298fd71SBarry Smith -  data - the array (or NULL)
2992273d9f13SBarry Smith 
2993273d9f13SBarry Smith    Notes:
2994273d9f13SBarry Smith    The data input variable is intended primarily for Fortran programmers
2995273d9f13SBarry Smith    who wish to allocate their own matrix memory space.  Most users should
2996284134d9SBarry Smith    need not call this routine.
2997273d9f13SBarry Smith 
2998273d9f13SBarry Smith    Level: intermediate
2999273d9f13SBarry Smith 
3000ad16ce7aSStefano Zampini .seealso: MatCreate(), MatCreateDense(), MatSetValues(), MatDenseSetLDA()
3001867c911aSBarry Smith 
3002273d9f13SBarry Smith @*/
30037087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation(Mat B,PetscScalar data[])
3004273d9f13SBarry Smith {
3005a23d5eceSKris Buschelman   PetscFunctionBegin;
3006d5ea218eSStefano Zampini   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
3007cac4c232SBarry Smith   PetscTryMethod(B,"MatSeqDenseSetPreallocation_C",(Mat,PetscScalar[]),(B,data));
3008a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3009a23d5eceSKris Buschelman }
3010a23d5eceSKris Buschelman 
30117087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation_SeqDense(Mat B,PetscScalar *data)
3012a23d5eceSKris Buschelman {
3013ad16ce7aSStefano Zampini   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
3014273d9f13SBarry Smith 
3015273d9f13SBarry Smith   PetscFunctionBegin;
301628b400f6SJacob Faibussowitsch   PetscCheck(!b->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
3017273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
3018a868139aSShri Abhyankar 
30199566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(B->rmap));
30209566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(B->cmap));
302134ef9618SShri Abhyankar 
3022ad16ce7aSStefano Zampini   if (b->lda <= 0) b->lda = B->rmap->n;
302386d161a7SShri Abhyankar 
30249e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
30259566063dSJacob Faibussowitsch     if (!b->user_alloc) PetscCall(PetscFree(b->v));
30269566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1((size_t)b->lda*B->cmap->n,&b->v));
30279566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)B,b->lda*B->cmap->n*sizeof(PetscScalar)));
30282205254eSKarl Rupp 
30299e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
3030273d9f13SBarry Smith   } else { /* user-allocated storage */
30319566063dSJacob Faibussowitsch     if (!b->user_alloc) PetscCall(PetscFree(b->v));
3032273d9f13SBarry Smith     b->v          = data;
3033273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
3034273d9f13SBarry Smith   }
30350450473dSBarry Smith   B->assembled = PETSC_TRUE;
3036273d9f13SBarry Smith   PetscFunctionReturn(0);
3037273d9f13SBarry Smith }
3038273d9f13SBarry Smith 
303965b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
3040cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
30418baccfbdSHong Zhang {
3042d77f618aSHong Zhang   Mat               mat_elemental;
30431683a169SBarry Smith   const PetscScalar *array;
30441683a169SBarry Smith   PetscScalar       *v_colwise;
3045d77f618aSHong Zhang   PetscInt          M=A->rmap->N,N=A->cmap->N,i,j,k,*rows,*cols;
3046d77f618aSHong Zhang 
30478baccfbdSHong Zhang   PetscFunctionBegin;
30489566063dSJacob Faibussowitsch   PetscCall(PetscMalloc3(M*N,&v_colwise,M,&rows,N,&cols));
30499566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&array));
3050d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
3051d77f618aSHong Zhang   k = 0;
3052d77f618aSHong Zhang   for (j=0; j<N; j++) {
3053d77f618aSHong Zhang     cols[j] = j;
3054d77f618aSHong Zhang     for (i=0; i<M; i++) {
3055d77f618aSHong Zhang       v_colwise[j*M+i] = array[k++];
3056d77f618aSHong Zhang     }
3057d77f618aSHong Zhang   }
3058d77f618aSHong Zhang   for (i=0; i<M; i++) {
3059d77f618aSHong Zhang     rows[i] = i;
3060d77f618aSHong Zhang   }
30619566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&array));
3062d77f618aSHong Zhang 
30639566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental));
30649566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N));
30659566063dSJacob Faibussowitsch   PetscCall(MatSetType(mat_elemental,MATELEMENTAL));
30669566063dSJacob Faibussowitsch   PetscCall(MatSetUp(mat_elemental));
3067d77f618aSHong Zhang 
3068d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
30699566063dSJacob Faibussowitsch   PetscCall(MatSetValues(mat_elemental,M,rows,N,cols,v_colwise,ADD_VALUES));
30709566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY));
30719566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY));
30729566063dSJacob Faibussowitsch   PetscCall(PetscFree3(v_colwise,rows,cols));
3073d77f618aSHong Zhang 
3074511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
30759566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A,&mat_elemental));
3076d77f618aSHong Zhang   } else {
3077d77f618aSHong Zhang     *newmat = mat_elemental;
3078d77f618aSHong Zhang   }
30798baccfbdSHong Zhang   PetscFunctionReturn(0);
30808baccfbdSHong Zhang }
308165b80a83SHong Zhang #endif
30828baccfbdSHong Zhang 
308317359960SJose E. Roman PetscErrorCode  MatDenseSetLDA_SeqDense(Mat B,PetscInt lda)
30841b807ce4Svictorle {
30851b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense*)B->data;
30867422da62SJose E. Roman   PetscBool    data;
308721a2c019SBarry Smith 
30881b807ce4Svictorle   PetscFunctionBegin;
30897422da62SJose E. Roman   data = (PetscBool)((B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE);
3090aed4548fSBarry Smith   PetscCheck(b->user_alloc || !data || b->lda == lda,PETSC_COMM_SELF,PETSC_ERR_ORDER,"LDA cannot be changed after allocation of internal storage");
309108401ef6SPierre 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);
30921b807ce4Svictorle   b->lda = lda;
30931b807ce4Svictorle   PetscFunctionReturn(0);
30941b807ce4Svictorle }
30951b807ce4Svictorle 
3096d528f656SJakub Kruzik PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat)
3097d528f656SJakub Kruzik {
3098d528f656SJakub Kruzik   PetscMPIInt    size;
3099d528f656SJakub Kruzik 
3100d528f656SJakub Kruzik   PetscFunctionBegin;
31019566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(comm,&size));
3102d528f656SJakub Kruzik   if (size == 1) {
3103d528f656SJakub Kruzik     if (scall == MAT_INITIAL_MATRIX) {
31049566063dSJacob Faibussowitsch       PetscCall(MatDuplicate(inmat,MAT_COPY_VALUES,outmat));
3105d528f656SJakub Kruzik     } else {
31069566063dSJacob Faibussowitsch       PetscCall(MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN));
3107d528f656SJakub Kruzik     }
3108d528f656SJakub Kruzik   } else {
31099566063dSJacob Faibussowitsch     PetscCall(MatCreateMPIMatConcatenateSeqMat_MPIDense(comm,inmat,n,scall,outmat));
3110d528f656SJakub Kruzik   }
3111d528f656SJakub Kruzik   PetscFunctionReturn(0);
3112d528f656SJakub Kruzik }
3113d528f656SJakub Kruzik 
31146947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A,PetscInt col,Vec *v)
31156947451fSStefano Zampini {
31166947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
31176947451fSStefano Zampini 
31186947451fSStefano Zampini   PetscFunctionBegin;
311928b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
312028b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
31216947451fSStefano Zampini   if (!a->cvec) {
31229566063dSJacob Faibussowitsch     PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec));
31239566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec));
31246947451fSStefano Zampini   }
31256947451fSStefano Zampini   a->vecinuse = col + 1;
31269566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,(PetscScalar**)&a->ptrinuse));
31279566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda));
31286947451fSStefano Zampini   *v   = a->cvec;
31296947451fSStefano Zampini   PetscFunctionReturn(0);
31306947451fSStefano Zampini }
31316947451fSStefano Zampini 
31326947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A,PetscInt col,Vec *v)
31336947451fSStefano Zampini {
31346947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
31356947451fSStefano Zampini 
31366947451fSStefano Zampini   PetscFunctionBegin;
313728b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first");
313828b400f6SJacob Faibussowitsch   PetscCheck(a->cvec,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
31396947451fSStefano Zampini   a->vecinuse = 0;
31409566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,(PetscScalar**)&a->ptrinuse));
31419566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
314275f6d85dSStefano Zampini   if (v) *v = NULL;
31436947451fSStefano Zampini   PetscFunctionReturn(0);
31446947451fSStefano Zampini }
31456947451fSStefano Zampini 
31466947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A,PetscInt col,Vec *v)
31476947451fSStefano Zampini {
31486947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
31496947451fSStefano Zampini 
31506947451fSStefano Zampini   PetscFunctionBegin;
315128b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
315228b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
31536947451fSStefano Zampini   if (!a->cvec) {
31549566063dSJacob Faibussowitsch     PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec));
31559566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec));
31566947451fSStefano Zampini   }
31576947451fSStefano Zampini   a->vecinuse = col + 1;
31589566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&a->ptrinuse));
31599566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda));
31609566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(a->cvec));
31616947451fSStefano Zampini   *v   = a->cvec;
31626947451fSStefano Zampini   PetscFunctionReturn(0);
31636947451fSStefano Zampini }
31646947451fSStefano Zampini 
31656947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A,PetscInt col,Vec *v)
31666947451fSStefano Zampini {
31676947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
31686947451fSStefano Zampini 
31696947451fSStefano Zampini   PetscFunctionBegin;
317028b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first");
317128b400f6SJacob Faibussowitsch   PetscCheck(a->cvec,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
31726947451fSStefano Zampini   a->vecinuse = 0;
31739566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&a->ptrinuse));
31749566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(a->cvec));
31759566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
317675f6d85dSStefano Zampini   if (v) *v = NULL;
31776947451fSStefano Zampini   PetscFunctionReturn(0);
31786947451fSStefano Zampini }
31796947451fSStefano Zampini 
31806947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecWrite_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 MatDenseRestoreColumnVec() first");
318628b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
31876947451fSStefano Zampini   if (!a->cvec) {
31889566063dSJacob Faibussowitsch     PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec));
31899566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec));
31906947451fSStefano Zampini   }
31916947451fSStefano Zampini   a->vecinuse = col + 1;
31929566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(A,(PetscScalar**)&a->ptrinuse));
31939566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda));
31946947451fSStefano Zampini   *v   = a->cvec;
31956947451fSStefano Zampini   PetscFunctionReturn(0);
31966947451fSStefano Zampini }
31976947451fSStefano Zampini 
31986947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A,PetscInt col,Vec *v)
31996947451fSStefano Zampini {
32006947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32016947451fSStefano Zampini 
32026947451fSStefano Zampini   PetscFunctionBegin;
320328b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first");
320428b400f6SJacob Faibussowitsch   PetscCheck(a->cvec,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
32056947451fSStefano Zampini   a->vecinuse = 0;
32069566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(A,(PetscScalar**)&a->ptrinuse));
32079566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
320875f6d85dSStefano Zampini   if (v) *v = NULL;
32096947451fSStefano Zampini   PetscFunctionReturn(0);
32106947451fSStefano Zampini }
32116947451fSStefano Zampini 
32125ea7661aSPierre Jolivet PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A,PetscInt cbegin,PetscInt cend,Mat *v)
32135ea7661aSPierre Jolivet {
32145ea7661aSPierre Jolivet   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32155ea7661aSPierre Jolivet 
32165ea7661aSPierre Jolivet   PetscFunctionBegin;
321728b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
321828b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
32195ea7661aSPierre Jolivet   if (a->cmat && cend-cbegin != a->cmat->cmap->N) {
32209566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&a->cmat));
32215ea7661aSPierre Jolivet   }
32225ea7661aSPierre Jolivet   if (!a->cmat) {
32239566063dSJacob Faibussowitsch     PetscCall(MatCreateDense(PetscObjectComm((PetscObject)A),A->rmap->n,PETSC_DECIDE,A->rmap->N,cend-cbegin,a->v+(size_t)cbegin*a->lda,&a->cmat));
32249566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)A,(PetscObject)a->cmat));
32255ea7661aSPierre Jolivet   } else {
32269566063dSJacob Faibussowitsch     PetscCall(MatDensePlaceArray(a->cmat,a->v+(size_t)cbegin*a->lda));
32275ea7661aSPierre Jolivet   }
32289566063dSJacob Faibussowitsch   PetscCall(MatDenseSetLDA(a->cmat,a->lda));
32295ea7661aSPierre Jolivet   a->matinuse = cbegin + 1;
32305ea7661aSPierre Jolivet   *v = a->cmat;
323175f6d85dSStefano Zampini #if defined(PETSC_HAVE_CUDA)
323275f6d85dSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
323375f6d85dSStefano Zampini #endif
32345ea7661aSPierre Jolivet   PetscFunctionReturn(0);
32355ea7661aSPierre Jolivet }
32365ea7661aSPierre Jolivet 
32375ea7661aSPierre Jolivet PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A,Mat *v)
32385ea7661aSPierre Jolivet {
32395ea7661aSPierre Jolivet   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32405ea7661aSPierre Jolivet 
32415ea7661aSPierre Jolivet   PetscFunctionBegin;
324228b400f6SJacob Faibussowitsch   PetscCheck(a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetSubMatrix() first");
324328b400f6SJacob Faibussowitsch   PetscCheck(a->cmat,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column matrix");
324408401ef6SPierre Jolivet   PetscCheck(*v == a->cmat,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not the matrix obtained from MatDenseGetSubMatrix()");
32455ea7661aSPierre Jolivet   a->matinuse = 0;
32469566063dSJacob Faibussowitsch   PetscCall(MatDenseResetArray(a->cmat));
32475ea7661aSPierre Jolivet   *v   = NULL;
32485ea7661aSPierre Jolivet   PetscFunctionReturn(0);
32495ea7661aSPierre Jolivet }
32505ea7661aSPierre Jolivet 
32510bad9183SKris Buschelman /*MC
3252fafad747SKris Buschelman    MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices.
32530bad9183SKris Buschelman 
32540bad9183SKris Buschelman    Options Database Keys:
32550bad9183SKris Buschelman . -mat_type seqdense - sets the matrix type to "seqdense" during a call to MatSetFromOptions()
32560bad9183SKris Buschelman 
32570bad9183SKris Buschelman   Level: beginner
32580bad9183SKris Buschelman 
325989665df3SBarry Smith .seealso: MatCreateSeqDense()
326089665df3SBarry Smith 
32610bad9183SKris Buschelman M*/
3262ca15aa20SStefano Zampini PetscErrorCode MatCreate_SeqDense(Mat B)
3263273d9f13SBarry Smith {
3264273d9f13SBarry Smith   Mat_SeqDense   *b;
32657c334f02SBarry Smith   PetscMPIInt    size;
3266273d9f13SBarry Smith 
3267273d9f13SBarry Smith   PetscFunctionBegin;
32689566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)B),&size));
326908401ef6SPierre Jolivet   PetscCheck(size <= 1,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
327055659b69SBarry Smith 
32719566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(B,&b));
32729566063dSJacob Faibussowitsch   PetscCall(PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps)));
327344cd7ae7SLois Curfman McInnes   B->data = (void*)b;
327418f449edSLois Curfman McInnes 
3275273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
32764e220ebcSLois Curfman McInnes 
32779566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatQRFactor_C",MatQRFactor_SeqDense));
32789566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetLDA_C",MatDenseGetLDA_SeqDense));
32799566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseSetLDA_C",MatDenseSetLDA_SeqDense));
32809566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArray_C",MatDenseGetArray_SeqDense));
32819566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArray_C",MatDenseRestoreArray_SeqDense));
32829566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDensePlaceArray_C",MatDensePlaceArray_SeqDense));
32839566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseResetArray_C",MatDenseResetArray_SeqDense));
32849566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseReplaceArray_C",MatDenseReplaceArray_SeqDense));
32859566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayRead_C",MatDenseGetArray_SeqDense));
32869566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayRead_C",MatDenseRestoreArray_SeqDense));
32879566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayWrite_C",MatDenseGetArray_SeqDense));
32889566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayWrite_C",MatDenseRestoreArray_SeqDense));
32899566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqaij_C",MatConvert_SeqDense_SeqAIJ));
32908baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
32919566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_elemental_C",MatConvert_SeqDense_Elemental));
32928baccfbdSHong Zhang #endif
3293d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
32949566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_scalapack_C",MatConvert_Dense_ScaLAPACK));
3295d24d4204SJose E. Roman #endif
32962bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
32979566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqdensecuda_C",MatConvert_SeqDense_SeqDenseCUDA));
32989566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",MatProductSetFromOptions_SeqDense));
32999566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdense_C",MatProductSetFromOptions_SeqDense));
33009566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqdensecuda_C",MatProductSetFromOptions_SeqDense));
33012bf066beSStefano Zampini #endif
33029566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatSeqDenseSetPreallocation_C",MatSeqDenseSetPreallocation_SeqDense));
33039566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqdense_C",MatProductSetFromOptions_SeqAIJ_SeqDense));
33049566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqdense_C",MatProductSetFromOptions_SeqDense));
33059566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense));
33069566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqsbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense));
330796e6d5c4SRichard Tran Mills 
33089566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumn_C",MatDenseGetColumn_SeqDense));
33099566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumn_C",MatDenseRestoreColumn_SeqDense));
33109566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVec_C",MatDenseGetColumnVec_SeqDense));
33119566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVec_C",MatDenseRestoreColumnVec_SeqDense));
33129566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVecRead_C",MatDenseGetColumnVecRead_SeqDense));
33139566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVecRead_C",MatDenseRestoreColumnVecRead_SeqDense));
33149566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVecWrite_C",MatDenseGetColumnVecWrite_SeqDense));
33159566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVecWrite_C",MatDenseRestoreColumnVecWrite_SeqDense));
33169566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetSubMatrix_C",MatDenseGetSubMatrix_SeqDense));
33179566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreSubMatrix_C",MatDenseRestoreSubMatrix_SeqDense));
33189566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)B,MATSEQDENSE));
33193a40ed3dSBarry Smith   PetscFunctionReturn(0);
3320289bc588SBarry Smith }
332186aefd0dSHong Zhang 
332286aefd0dSHong Zhang /*@C
3323af53bab2SHong 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.
332486aefd0dSHong Zhang 
332586aefd0dSHong Zhang    Not Collective
332686aefd0dSHong Zhang 
33275ea7661aSPierre Jolivet    Input Parameters:
332886aefd0dSHong Zhang +  mat - a MATSEQDENSE or MATMPIDENSE matrix
332986aefd0dSHong Zhang -  col - column index
333086aefd0dSHong Zhang 
333186aefd0dSHong Zhang    Output Parameter:
333286aefd0dSHong Zhang .  vals - pointer to the data
333386aefd0dSHong Zhang 
333486aefd0dSHong Zhang    Level: intermediate
333586aefd0dSHong Zhang 
333686aefd0dSHong Zhang .seealso: MatDenseRestoreColumn()
333786aefd0dSHong Zhang @*/
333886aefd0dSHong Zhang PetscErrorCode MatDenseGetColumn(Mat A,PetscInt col,PetscScalar **vals)
333986aefd0dSHong Zhang {
334086aefd0dSHong Zhang   PetscFunctionBegin;
3341d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3342d5ea218eSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
3343d5ea218eSStefano Zampini   PetscValidPointer(vals,3);
3344cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetColumn_C",(Mat,PetscInt,PetscScalar**),(A,col,vals));
334586aefd0dSHong Zhang   PetscFunctionReturn(0);
334686aefd0dSHong Zhang }
334786aefd0dSHong Zhang 
334886aefd0dSHong Zhang /*@C
334986aefd0dSHong Zhang    MatDenseRestoreColumn - returns access to a column of a dense matrix which is returned by MatDenseGetColumn().
335086aefd0dSHong Zhang 
335186aefd0dSHong Zhang    Not Collective
335286aefd0dSHong Zhang 
335386aefd0dSHong Zhang    Input Parameter:
335486aefd0dSHong Zhang .  mat - a MATSEQDENSE or MATMPIDENSE matrix
335586aefd0dSHong Zhang 
335686aefd0dSHong Zhang    Output Parameter:
335786aefd0dSHong Zhang .  vals - pointer to the data
335886aefd0dSHong Zhang 
335986aefd0dSHong Zhang    Level: intermediate
336086aefd0dSHong Zhang 
336186aefd0dSHong Zhang .seealso: MatDenseGetColumn()
336286aefd0dSHong Zhang @*/
336386aefd0dSHong Zhang PetscErrorCode MatDenseRestoreColumn(Mat A,PetscScalar **vals)
336486aefd0dSHong Zhang {
336586aefd0dSHong Zhang   PetscFunctionBegin;
3366d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3367d5ea218eSStefano Zampini   PetscValidPointer(vals,2);
3368cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreColumn_C",(Mat,PetscScalar**),(A,vals));
336986aefd0dSHong Zhang   PetscFunctionReturn(0);
337086aefd0dSHong Zhang }
33716947451fSStefano Zampini 
33720f74d2c1SSatish Balay /*@
33736947451fSStefano Zampini    MatDenseGetColumnVec - Gives read-write access to a column of a dense matrix, represented as a Vec.
33746947451fSStefano Zampini 
33756947451fSStefano Zampini    Collective
33766947451fSStefano Zampini 
33775ea7661aSPierre Jolivet    Input Parameters:
33786947451fSStefano Zampini +  mat - the Mat object
33796947451fSStefano Zampini -  col - the column index
33806947451fSStefano Zampini 
33816947451fSStefano Zampini    Output Parameter:
33826947451fSStefano Zampini .  v - the vector
33836947451fSStefano Zampini 
33846947451fSStefano Zampini    Notes:
33856947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVec() when the vector is no longer needed.
33866947451fSStefano Zampini      Use MatDenseGetColumnVecRead() to obtain read-only access or MatDenseGetColumnVecWrite() for write-only access.
33876947451fSStefano Zampini 
33886947451fSStefano Zampini    Level: intermediate
33896947451fSStefano Zampini 
33906947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
33916947451fSStefano Zampini @*/
33926947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVec(Mat A,PetscInt col,Vec *v)
33936947451fSStefano Zampini {
33946947451fSStefano Zampini   PetscFunctionBegin;
33956947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
33966947451fSStefano Zampini   PetscValidType(A,1);
33976947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
33986947451fSStefano Zampini   PetscValidPointer(v,3);
339928b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
3400*2cf15c64SPierre 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);
3401cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetColumnVec_C",(Mat,PetscInt,Vec*),(A,col,v));
34026947451fSStefano Zampini   PetscFunctionReturn(0);
34036947451fSStefano Zampini }
34046947451fSStefano Zampini 
34050f74d2c1SSatish Balay /*@
34066947451fSStefano Zampini    MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVec().
34076947451fSStefano Zampini 
34086947451fSStefano Zampini    Collective
34096947451fSStefano Zampini 
34105ea7661aSPierre Jolivet    Input Parameters:
34116947451fSStefano Zampini +  mat - the Mat object
34126947451fSStefano Zampini .  col - the column index
34136947451fSStefano Zampini -  v - the Vec object
34146947451fSStefano Zampini 
34156947451fSStefano Zampini    Level: intermediate
34166947451fSStefano Zampini 
34176947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
34186947451fSStefano Zampini @*/
34196947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVec(Mat A,PetscInt col,Vec *v)
34206947451fSStefano Zampini {
34216947451fSStefano Zampini   PetscFunctionBegin;
34226947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
34236947451fSStefano Zampini   PetscValidType(A,1);
34246947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
342508401ef6SPierre Jolivet   PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
3426*2cf15c64SPierre 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);
3427cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreColumnVec_C",(Mat,PetscInt,Vec*),(A,col,v));
34286947451fSStefano Zampini   PetscFunctionReturn(0);
34296947451fSStefano Zampini }
34306947451fSStefano Zampini 
34310f74d2c1SSatish Balay /*@
34326947451fSStefano Zampini    MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a Vec.
34336947451fSStefano Zampini 
34346947451fSStefano Zampini    Collective
34356947451fSStefano Zampini 
34365ea7661aSPierre Jolivet    Input Parameters:
34376947451fSStefano Zampini +  mat - the Mat object
34386947451fSStefano Zampini -  col - the column index
34396947451fSStefano Zampini 
34406947451fSStefano Zampini    Output Parameter:
34416947451fSStefano Zampini .  v - the vector
34426947451fSStefano Zampini 
34436947451fSStefano Zampini    Notes:
34446947451fSStefano Zampini      The vector is owned by PETSc and users cannot modify it.
34456947451fSStefano Zampini      Users need to call MatDenseRestoreColumnVecRead() when the vector is no longer needed.
34466947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecWrite() for write-only access.
34476947451fSStefano Zampini 
34486947451fSStefano Zampini    Level: intermediate
34496947451fSStefano Zampini 
34506947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
34516947451fSStefano Zampini @*/
34526947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecRead(Mat A,PetscInt col,Vec *v)
34536947451fSStefano Zampini {
34546947451fSStefano Zampini   PetscFunctionBegin;
34556947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
34566947451fSStefano Zampini   PetscValidType(A,1);
34576947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
34586947451fSStefano Zampini   PetscValidPointer(v,3);
345928b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
3460*2cf15c64SPierre Jolivet   PetscCheck(col >= 0 && col < A->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")",col,A->cmap->N);
3461cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetColumnVecRead_C",(Mat,PetscInt,Vec*),(A,col,v));
34626947451fSStefano Zampini   PetscFunctionReturn(0);
34636947451fSStefano Zampini }
34646947451fSStefano Zampini 
34650f74d2c1SSatish Balay /*@
34666947451fSStefano Zampini    MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecRead().
34676947451fSStefano Zampini 
34686947451fSStefano Zampini    Collective
34696947451fSStefano Zampini 
34705ea7661aSPierre Jolivet    Input Parameters:
34716947451fSStefano Zampini +  mat - the Mat object
34726947451fSStefano Zampini .  col - the column index
34736947451fSStefano Zampini -  v - the Vec object
34746947451fSStefano Zampini 
34756947451fSStefano Zampini    Level: intermediate
34766947451fSStefano Zampini 
34776947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecWrite()
34786947451fSStefano Zampini @*/
34796947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecRead(Mat A,PetscInt col,Vec *v)
34806947451fSStefano Zampini {
34816947451fSStefano Zampini   PetscFunctionBegin;
34826947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
34836947451fSStefano Zampini   PetscValidType(A,1);
34846947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
348508401ef6SPierre Jolivet   PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
3486*2cf15c64SPierre 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);
3487cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreColumnVecRead_C",(Mat,PetscInt,Vec*),(A,col,v));
34886947451fSStefano Zampini   PetscFunctionReturn(0);
34896947451fSStefano Zampini }
34906947451fSStefano Zampini 
34910f74d2c1SSatish Balay /*@
34926947451fSStefano Zampini    MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a Vec.
34936947451fSStefano Zampini 
34946947451fSStefano Zampini    Collective
34956947451fSStefano Zampini 
34965ea7661aSPierre Jolivet    Input Parameters:
34976947451fSStefano Zampini +  mat - the Mat object
34986947451fSStefano Zampini -  col - the column index
34996947451fSStefano Zampini 
35006947451fSStefano Zampini    Output Parameter:
35016947451fSStefano Zampini .  v - the vector
35026947451fSStefano Zampini 
35036947451fSStefano Zampini    Notes:
35046947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVecWrite() when the vector is no longer needed.
35056947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecRead() for read-only access.
35066947451fSStefano Zampini 
35076947451fSStefano Zampini    Level: intermediate
35086947451fSStefano Zampini 
35096947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
35106947451fSStefano Zampini @*/
35116947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecWrite(Mat A,PetscInt col,Vec *v)
35126947451fSStefano Zampini {
35136947451fSStefano Zampini   PetscFunctionBegin;
35146947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
35156947451fSStefano Zampini   PetscValidType(A,1);
35166947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
35176947451fSStefano Zampini   PetscValidPointer(v,3);
351828b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
3519aed4548fSBarry 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);
3520cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetColumnVecWrite_C",(Mat,PetscInt,Vec*),(A,col,v));
35216947451fSStefano Zampini   PetscFunctionReturn(0);
35226947451fSStefano Zampini }
35236947451fSStefano Zampini 
35240f74d2c1SSatish Balay /*@
35256947451fSStefano Zampini    MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecWrite().
35266947451fSStefano Zampini 
35276947451fSStefano Zampini    Collective
35286947451fSStefano Zampini 
35295ea7661aSPierre Jolivet    Input Parameters:
35306947451fSStefano Zampini +  mat - the Mat object
35316947451fSStefano Zampini .  col - the column index
35326947451fSStefano Zampini -  v - the Vec object
35336947451fSStefano Zampini 
35346947451fSStefano Zampini    Level: intermediate
35356947451fSStefano Zampini 
35366947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead()
35376947451fSStefano Zampini @*/
35386947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A,PetscInt col,Vec *v)
35396947451fSStefano Zampini {
35406947451fSStefano Zampini   PetscFunctionBegin;
35416947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
35426947451fSStefano Zampini   PetscValidType(A,1);
35436947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
354408401ef6SPierre Jolivet   PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
3545aed4548fSBarry 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);
3546cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreColumnVecWrite_C",(Mat,PetscInt,Vec*),(A,col,v));
35476947451fSStefano Zampini   PetscFunctionReturn(0);
35486947451fSStefano Zampini }
35495ea7661aSPierre Jolivet 
35500f74d2c1SSatish Balay /*@
35515ea7661aSPierre Jolivet    MatDenseGetSubMatrix - Gives access to a block of columns of a dense matrix, represented as a Mat.
35525ea7661aSPierre Jolivet 
35535ea7661aSPierre Jolivet    Collective
35545ea7661aSPierre Jolivet 
35555ea7661aSPierre Jolivet    Input Parameters:
35565ea7661aSPierre Jolivet +  mat - the Mat object
35575ea7661aSPierre Jolivet .  cbegin - the first index in the block
3558*2cf15c64SPierre Jolivet -  cend - the index past the last one in the block
35595ea7661aSPierre Jolivet 
35605ea7661aSPierre Jolivet    Output Parameter:
35615ea7661aSPierre Jolivet .  v - the matrix
35625ea7661aSPierre Jolivet 
35635ea7661aSPierre Jolivet    Notes:
35645ea7661aSPierre Jolivet      The matrix is owned by PETSc. Users need to call MatDenseRestoreSubMatrix() when the matrix is no longer needed.
35655ea7661aSPierre Jolivet 
35665ea7661aSPierre Jolivet    Level: intermediate
35675ea7661aSPierre Jolivet 
35685ea7661aSPierre Jolivet .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseRestoreColumnVec(), MatDenseRestoreSubMatrix()
35695ea7661aSPierre Jolivet @*/
35705ea7661aSPierre Jolivet PetscErrorCode MatDenseGetSubMatrix(Mat A,PetscInt cbegin,PetscInt cend,Mat *v)
35715ea7661aSPierre Jolivet {
35725ea7661aSPierre Jolivet   PetscFunctionBegin;
35735ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
35745ea7661aSPierre Jolivet   PetscValidType(A,1);
35755ea7661aSPierre Jolivet   PetscValidLogicalCollectiveInt(A,cbegin,2);
35765ea7661aSPierre Jolivet   PetscValidLogicalCollectiveInt(A,cend,3);
35775ea7661aSPierre Jolivet   PetscValidPointer(v,4);
357828b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
3579*2cf15c64SPierre 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);
3580*2cf15c64SPierre 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);
3581cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetSubMatrix_C",(Mat,PetscInt,PetscInt,Mat*),(A,cbegin,cend,v));
35825ea7661aSPierre Jolivet   PetscFunctionReturn(0);
35835ea7661aSPierre Jolivet }
35845ea7661aSPierre Jolivet 
35850f74d2c1SSatish Balay /*@
35865ea7661aSPierre Jolivet    MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from MatDenseGetSubMatrix().
35875ea7661aSPierre Jolivet 
35885ea7661aSPierre Jolivet    Collective
35895ea7661aSPierre Jolivet 
35905ea7661aSPierre Jolivet    Input Parameters:
35915ea7661aSPierre Jolivet +  mat - the Mat object
35925ea7661aSPierre Jolivet -  v - the Mat object
35935ea7661aSPierre Jolivet 
35945ea7661aSPierre Jolivet    Level: intermediate
35955ea7661aSPierre Jolivet 
35965ea7661aSPierre Jolivet .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseRestoreColumnVec(), MatDenseGetSubMatrix()
35975ea7661aSPierre Jolivet @*/
35985ea7661aSPierre Jolivet PetscErrorCode MatDenseRestoreSubMatrix(Mat A,Mat *v)
35995ea7661aSPierre Jolivet {
36005ea7661aSPierre Jolivet   PetscFunctionBegin;
36015ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
36025ea7661aSPierre Jolivet   PetscValidType(A,1);
36035ea7661aSPierre Jolivet   PetscValidPointer(v,2);
3604cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreSubMatrix_C",(Mat,Mat*),(A,v));
36055ea7661aSPierre Jolivet   PetscFunctionReturn(0);
36065ea7661aSPierre Jolivet }
36078a9c020eSBarry Smith 
36088a9c020eSBarry Smith #include <petscblaslapack.h>
36098a9c020eSBarry Smith #include <petsc/private/kernels/blockinvert.h>
36108a9c020eSBarry Smith 
36118a9c020eSBarry Smith PetscErrorCode MatSeqDenseInvert(Mat A)
36128a9c020eSBarry Smith {
36138a9c020eSBarry Smith   Mat_SeqDense    *a = (Mat_SeqDense*) A->data;
36148a9c020eSBarry Smith   PetscInt        bs = A->rmap->n;
36158a9c020eSBarry Smith   MatScalar       *values = a->v;
36168a9c020eSBarry Smith   const PetscReal shift = 0.0;
36178a9c020eSBarry Smith   PetscBool       allowzeropivot = PetscNot(A->erroriffailure),zeropivotdetected=PETSC_FALSE;
36188a9c020eSBarry Smith 
36198a9c020eSBarry Smith   PetscFunctionBegin;
36208a9c020eSBarry Smith   /* factor and invert each block */
36218a9c020eSBarry Smith   switch (bs) {
36228a9c020eSBarry Smith   case 1:
36238a9c020eSBarry Smith     values[0] = (PetscScalar)1.0 / (values[0] + shift);
36248a9c020eSBarry Smith     break;
36258a9c020eSBarry Smith   case 2:
36268a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_2(values,shift,allowzeropivot,&zeropivotdetected));
36278a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
36288a9c020eSBarry Smith     break;
36298a9c020eSBarry Smith   case 3:
36308a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_3(values,shift,allowzeropivot,&zeropivotdetected));
36318a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
36328a9c020eSBarry Smith     break;
36338a9c020eSBarry Smith   case 4:
36348a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_4(values,shift,allowzeropivot,&zeropivotdetected));
36358a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
36368a9c020eSBarry Smith     break;
36378a9c020eSBarry Smith   case 5:
36388a9c020eSBarry Smith   {
36398a9c020eSBarry Smith     PetscScalar work[25];
36408a9c020eSBarry Smith     PetscInt    ipvt[5];
36418a9c020eSBarry Smith 
36428a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_5(values,ipvt,work,shift,allowzeropivot,&zeropivotdetected));
36438a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
36448a9c020eSBarry Smith   }
36458a9c020eSBarry Smith     break;
36468a9c020eSBarry Smith   case 6:
36478a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_6(values,shift,allowzeropivot,&zeropivotdetected));
36488a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
36498a9c020eSBarry Smith     break;
36508a9c020eSBarry Smith   case 7:
36518a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_7(values,shift,allowzeropivot,&zeropivotdetected));
36528a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
36538a9c020eSBarry Smith     break;
36548a9c020eSBarry Smith   default:
36558a9c020eSBarry Smith   {
36568a9c020eSBarry Smith     PetscInt    *v_pivots,*IJ,j;
36578a9c020eSBarry Smith     PetscScalar *v_work;
36588a9c020eSBarry Smith 
36598a9c020eSBarry Smith     PetscCall(PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ));
36608a9c020eSBarry Smith     for (j=0; j<bs; j++) {
36618a9c020eSBarry Smith       IJ[j] = j;
36628a9c020eSBarry Smith     }
36638a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A(bs,values,v_pivots,v_work,allowzeropivot,&zeropivotdetected));
36648a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
36658a9c020eSBarry Smith     PetscCall(PetscFree3(v_work,v_pivots,IJ));
36668a9c020eSBarry Smith   }
36678a9c020eSBarry Smith   }
36688a9c020eSBarry Smith   PetscFunctionReturn(0);
36698a9c020eSBarry Smith }
3670