xref: /petsc/src/mat/impls/dense/seq/dense.c (revision 06c5243adf84d0fa86c5567284a8ca67e7df82ea)
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;
182c71b3e2SJacob Faibussowitsch   PetscCheckFalse(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++) {
1042c71b3e2SJacob Faibussowitsch       PetscCheckFalse(rows[i] < 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
1052c71b3e2SJacob Faibussowitsch       PetscCheckFalse(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);
1062c71b3e2SJacob Faibussowitsch       PetscCheckFalse(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 
1152c71b3e2SJacob Faibussowitsch     PetscCheckFalse(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) {
1382c71b3e2SJacob Faibussowitsch     PetscCheckFalse(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 
796db4efbfdSBarry Smith /* ---------------------------------------------------------------*/
797db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots,
798db4efbfdSBarry Smith    rather than put it in the Mat->row slot.*/
799ca15aa20SStefano Zampini PetscErrorCode MatLUFactor_SeqDense(Mat A,IS row,IS col,const MatFactorInfo *minfo)
800db4efbfdSBarry Smith {
801db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
802db4efbfdSBarry Smith   PetscBLASInt   n,m,info;
803db4efbfdSBarry Smith 
804db4efbfdSBarry Smith   PetscFunctionBegin;
8059566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
8069566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
807db4efbfdSBarry Smith   if (!mat->pivots) {
8089566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(A->rmap->n,&mat->pivots));
8099566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt)));
810db4efbfdSBarry Smith   }
811db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
8129566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
8138b83055fSJed Brown   PetscStackCallBLAS("LAPACKgetrf",LAPACKgetrf_(&m,&n,mat->v,&mat->lda,mat->pivots,&info));
8149566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
8158e57ea43SSatish Balay 
8162c71b3e2SJacob Faibussowitsch   PetscCheckFalse(info<0,PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to LU factorization");
8172c71b3e2SJacob Faibussowitsch   PetscCheckFalse(info>0,PETSC_COMM_SELF,PETSC_ERR_MAT_LU_ZRPVT,"Bad LU factorization");
8188208b9aeSStefano Zampini 
8194396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_LU;
8204396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_LU;
8214396437dSToby Isaac   A->ops->solvetranspose    = MatSolveTranspose_SeqDense_LU;
8224396437dSToby Isaac   A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_LU;
823d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_LU;
824db4efbfdSBarry Smith 
8259566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
8269566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC,&A->solvertype));
827f6224b95SHong Zhang 
8289566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops((2.0*A->cmap->n*A->cmap->n*A->cmap->n)/3));
829db4efbfdSBarry Smith   PetscFunctionReturn(0);
830db4efbfdSBarry Smith }
831db4efbfdSBarry Smith 
8324396437dSToby Isaac static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
8334396437dSToby Isaac {
8344396437dSToby Isaac   MatFactorInfo  info;
8354396437dSToby Isaac 
8364396437dSToby Isaac   PetscFunctionBegin;
8379566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES));
8389566063dSJacob Faibussowitsch   PetscCall((*fact->ops->lufactor)(fact,NULL,NULL,&info));
8394396437dSToby Isaac   PetscFunctionReturn(0);
8404396437dSToby Isaac }
8414396437dSToby Isaac 
8424396437dSToby Isaac PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,IS col,const MatFactorInfo *info)
8434396437dSToby Isaac {
8444396437dSToby Isaac   PetscFunctionBegin;
8454396437dSToby Isaac   fact->preallocated           = PETSC_TRUE;
8464396437dSToby Isaac   fact->assembled              = PETSC_TRUE;
8474396437dSToby Isaac   fact->ops->lufactornumeric   = MatLUFactorNumeric_SeqDense;
8484396437dSToby Isaac   PetscFunctionReturn(0);
8494396437dSToby Isaac }
8504396437dSToby Isaac 
851a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */
852ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactor_SeqDense(Mat A,IS perm,const MatFactorInfo *factinfo)
853db4efbfdSBarry Smith {
854db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
855c5df96a5SBarry Smith   PetscBLASInt   info,n;
856db4efbfdSBarry Smith 
857db4efbfdSBarry Smith   PetscFunctionBegin;
8589566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
859db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
860a49dc2a2SStefano Zampini   if (A->spd) {
8619566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
8628b83055fSJed Brown     PetscStackCallBLAS("LAPACKpotrf",LAPACKpotrf_("L",&n,mat->v,&mat->lda,&info));
8639566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
864a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
865a49dc2a2SStefano Zampini   } else if (A->hermitian) {
866a49dc2a2SStefano Zampini     if (!mat->pivots) {
8679566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(A->rmap->n,&mat->pivots));
8689566063dSJacob Faibussowitsch       PetscCall(PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt)));
869a49dc2a2SStefano Zampini     }
870a49dc2a2SStefano Zampini     if (!mat->fwork) {
871a49dc2a2SStefano Zampini       PetscScalar dummy;
872a49dc2a2SStefano Zampini 
873a49dc2a2SStefano Zampini       mat->lfwork = -1;
8749566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
875a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
8769566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
877a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
8789566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(mat->lfwork,&mat->fwork));
8799566063dSJacob Faibussowitsch       PetscCall(PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt)));
880a49dc2a2SStefano Zampini     }
8819566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
882a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
8839566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
884a49dc2a2SStefano Zampini #endif
885a49dc2a2SStefano Zampini   } else { /* symmetric case */
886a49dc2a2SStefano Zampini     if (!mat->pivots) {
8879566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(A->rmap->n,&mat->pivots));
8889566063dSJacob Faibussowitsch       PetscCall(PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt)));
889a49dc2a2SStefano Zampini     }
890a49dc2a2SStefano Zampini     if (!mat->fwork) {
891a49dc2a2SStefano Zampini       PetscScalar dummy;
892a49dc2a2SStefano Zampini 
893a49dc2a2SStefano Zampini       mat->lfwork = -1;
8949566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
895a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
8969566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
897a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
8989566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(mat->lfwork,&mat->fwork));
8999566063dSJacob Faibussowitsch       PetscCall(PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt)));
900a49dc2a2SStefano Zampini     }
9019566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
902a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
9039566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
904a49dc2a2SStefano Zampini   }
90528b400f6SJacob Faibussowitsch   PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad factorization: zero pivot in row %" PetscInt_FMT,(PetscInt)info-1);
9068208b9aeSStefano Zampini 
9074396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_Cholesky;
9084396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_Cholesky;
9094396437dSToby Isaac   A->ops->solvetranspose    = MatSolveTranspose_SeqDense_Cholesky;
9104396437dSToby Isaac   A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_Cholesky;
911d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_CHOLESKY;
9122205254eSKarl Rupp 
9139566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
9149566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC,&A->solvertype));
915f6224b95SHong Zhang 
9169566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0));
917db4efbfdSBarry Smith   PetscFunctionReturn(0);
918db4efbfdSBarry Smith }
919db4efbfdSBarry Smith 
9204396437dSToby Isaac static PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
921db4efbfdSBarry Smith {
922db4efbfdSBarry Smith   MatFactorInfo  info;
923db4efbfdSBarry Smith 
924db4efbfdSBarry Smith   PetscFunctionBegin;
925db4efbfdSBarry Smith   info.fill = 1.0;
9262205254eSKarl Rupp 
9279566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES));
9289566063dSJacob Faibussowitsch   PetscCall((*fact->ops->choleskyfactor)(fact,NULL,&info));
929db4efbfdSBarry Smith   PetscFunctionReturn(0);
930db4efbfdSBarry Smith }
931db4efbfdSBarry Smith 
932ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info)
933db4efbfdSBarry Smith {
934db4efbfdSBarry Smith   PetscFunctionBegin;
935c3ef05f6SHong Zhang   fact->assembled                  = PETSC_TRUE;
9361bbcc794SSatish Balay   fact->preallocated               = PETSC_TRUE;
937719d5645SBarry Smith   fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense;
938db4efbfdSBarry Smith   PetscFunctionReturn(0);
939db4efbfdSBarry Smith }
940db4efbfdSBarry Smith 
941bf5a80bcSToby Isaac PetscErrorCode MatQRFactor_SeqDense(Mat A,IS col,const MatFactorInfo *minfo)
9424905a7bcSToby Isaac {
9434905a7bcSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
9444905a7bcSToby Isaac   PetscBLASInt   n,m,info, min, max;
9454905a7bcSToby Isaac 
9464905a7bcSToby Isaac   PetscFunctionBegin;
9479566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
9489566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
9494396437dSToby Isaac   max = PetscMax(m, n);
9504396437dSToby Isaac   min = PetscMin(m, n);
9514905a7bcSToby Isaac   if (!mat->tau) {
9529566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(min,&mat->tau));
9539566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)A,min*sizeof(PetscScalar)));
9544396437dSToby Isaac   }
9554396437dSToby Isaac   if (!mat->pivots) {
9569566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n,&mat->pivots));
9579566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)A,n*sizeof(PetscScalar)));
9584396437dSToby Isaac   }
9594396437dSToby Isaac   if (!mat->qrrhs) {
9609566063dSJacob Faibussowitsch     PetscCall(MatCreateVecs(A, NULL, &(mat->qrrhs)));
9614905a7bcSToby Isaac   }
9624905a7bcSToby Isaac   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
9634905a7bcSToby Isaac   if (!mat->fwork) {
9644905a7bcSToby Isaac     PetscScalar dummy;
9654905a7bcSToby Isaac 
9664905a7bcSToby Isaac     mat->lfwork = -1;
9679566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
9684905a7bcSToby Isaac     PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&m,&n,mat->v,&mat->lda,mat->tau,&dummy,&mat->lfwork,&info));
9699566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
9704905a7bcSToby Isaac     mat->lfwork = (PetscInt)PetscRealPart(dummy);
9719566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(mat->lfwork,&mat->fwork));
9729566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt)));
9734905a7bcSToby Isaac   }
9749566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
9754905a7bcSToby Isaac   PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&m,&n,mat->v,&mat->lda,mat->tau,mat->fwork,&mat->lfwork,&info));
9769566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
97728b400f6SJacob Faibussowitsch   PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to QR factorization");
9784905a7bcSToby 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
9794905a7bcSToby Isaac   mat->rank = min;
9804905a7bcSToby Isaac 
9814396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_QR;
9824396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_QR;
9834905a7bcSToby Isaac   A->factortype             = MAT_FACTOR_QR;
9844905a7bcSToby Isaac   if (m == n) {
9854396437dSToby Isaac     A->ops->solvetranspose    = MatSolveTranspose_SeqDense_QR;
9864396437dSToby Isaac     A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_QR;
9874905a7bcSToby Isaac   }
9884905a7bcSToby Isaac 
9899566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
9909566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC,&A->solvertype));
9914905a7bcSToby Isaac 
9929566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0*min*min*(max-min/3.0)));
9934905a7bcSToby Isaac   PetscFunctionReturn(0);
9944905a7bcSToby Isaac }
9954905a7bcSToby Isaac 
9964905a7bcSToby Isaac static PetscErrorCode MatQRFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
9974905a7bcSToby Isaac {
9984905a7bcSToby Isaac   MatFactorInfo  info;
9994905a7bcSToby Isaac 
10004905a7bcSToby Isaac   PetscFunctionBegin;
10014905a7bcSToby Isaac   info.fill = 1.0;
10024905a7bcSToby Isaac 
10039566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES));
1004cac4c232SBarry Smith   PetscUseMethod(fact,"MatQRFactor_C",(Mat,IS,const MatFactorInfo *),(fact,NULL,&info));
10054905a7bcSToby Isaac   PetscFunctionReturn(0);
10064905a7bcSToby Isaac }
10074905a7bcSToby Isaac 
1008bf5a80bcSToby Isaac PetscErrorCode MatQRFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info)
10094905a7bcSToby Isaac {
10104905a7bcSToby Isaac   PetscFunctionBegin;
10114905a7bcSToby Isaac   fact->assembled                  = PETSC_TRUE;
10124905a7bcSToby Isaac   fact->preallocated               = PETSC_TRUE;
10139566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)fact,"MatQRFactorNumeric_C",MatQRFactorNumeric_SeqDense));
10144905a7bcSToby Isaac   PetscFunctionReturn(0);
10154905a7bcSToby Isaac }
10164905a7bcSToby Isaac 
1017ca15aa20SStefano Zampini /* uses LAPACK */
1018cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A,MatFactorType ftype,Mat *fact)
1019db4efbfdSBarry Smith {
1020db4efbfdSBarry Smith   PetscFunctionBegin;
10219566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A),fact));
10229566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*fact,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n));
10239566063dSJacob Faibussowitsch   PetscCall(MatSetType(*fact,MATDENSE));
102466e17bc3SBarry Smith   (*fact)->trivialsymbolic = PETSC_TRUE;
10252a350339SBarry Smith   if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU) {
1026db4efbfdSBarry Smith     (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense;
10272a350339SBarry Smith     (*fact)->ops->ilufactorsymbolic = MatLUFactorSymbolic_SeqDense;
1028bf5a80bcSToby Isaac   } else if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) {
1029db4efbfdSBarry Smith     (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense;
1030bf5a80bcSToby Isaac   } else if (ftype == MAT_FACTOR_QR) {
10319566063dSJacob Faibussowitsch     PetscCall(PetscObjectComposeFunction((PetscObject)(*fact),"MatQRFactorSymbolic_C",MatQRFactorSymbolic_SeqDense));
1032db4efbfdSBarry Smith   }
1033d5f3da31SBarry Smith   (*fact)->factortype = ftype;
103400c67f3bSHong Zhang 
10359566063dSJacob Faibussowitsch   PetscCall(PetscFree((*fact)->solvertype));
10369566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC,&(*fact)->solvertype));
10379566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_LU]));
10389566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_ILU]));
10399566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_CHOLESKY]));
10409566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_ICC]));
1041db4efbfdSBarry Smith   PetscFunctionReturn(0);
1042db4efbfdSBarry Smith }
1043db4efbfdSBarry Smith 
1044289bc588SBarry Smith /* ------------------------------------------------------------------*/
1045e0877f53SBarry Smith static PetscErrorCode MatSOR_SeqDense(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec xx)
1046289bc588SBarry Smith {
1047c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1048d9ca1df4SBarry Smith   PetscScalar       *x,*v = mat->v,zero = 0.0,xt;
1049d9ca1df4SBarry Smith   const PetscScalar *b;
1050d0f46423SBarry Smith   PetscInt          m = A->rmap->n,i;
105123fff9afSBarry Smith   PetscBLASInt      o = 1,bm = 0;
1052289bc588SBarry Smith 
10533a40ed3dSBarry Smith   PetscFunctionBegin;
1054ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
10552c71b3e2SJacob Faibussowitsch   PetscCheckFalse(A->offloadmask == PETSC_OFFLOAD_GPU,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented");
1056ca15aa20SStefano Zampini #endif
1057422a814eSBarry Smith   if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */
10589566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(m,&bm));
1059289bc588SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
10603bffc371SBarry Smith     /* this is a hack fix, should have another version without the second BLASdotu */
10619566063dSJacob Faibussowitsch     PetscCall(VecSet(xx,zero));
1062289bc588SBarry Smith   }
10639566063dSJacob Faibussowitsch   PetscCall(VecGetArray(xx,&x));
10649566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(bb,&b));
1065b965ef7fSBarry Smith   its  = its*lits;
10662c71b3e2SJacob Faibussowitsch   PetscCheckFalse(its <= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %" PetscInt_FMT " and local its %" PetscInt_FMT " both positive",its,lits);
1067289bc588SBarry Smith   while (its--) {
1068fccaa45eSBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
1069289bc588SBarry Smith       for (i=0; i<m; i++) {
10703bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
107155a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
1072289bc588SBarry Smith       }
1073289bc588SBarry Smith     }
1074fccaa45eSBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
1075289bc588SBarry Smith       for (i=m-1; i>=0; i--) {
10763bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
107755a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
1078289bc588SBarry Smith       }
1079289bc588SBarry Smith     }
1080289bc588SBarry Smith   }
10819566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(bb,&b));
10829566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(xx,&x));
10833a40ed3dSBarry Smith   PetscFunctionReturn(0);
1084289bc588SBarry Smith }
1085289bc588SBarry Smith 
1086289bc588SBarry Smith /* -----------------------------------------------------------------*/
1087ca15aa20SStefano Zampini PetscErrorCode MatMultTranspose_SeqDense(Mat A,Vec xx,Vec yy)
1088289bc588SBarry Smith {
1089c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1090d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v,*x;
1091d9ca1df4SBarry Smith   PetscScalar       *y;
10920805154bSBarry Smith   PetscBLASInt      m, n,_One=1;
1093ea709b57SSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
10943a40ed3dSBarry Smith 
10953a40ed3dSBarry Smith   PetscFunctionBegin;
10969566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
10979566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
10989566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx,&x));
10999566063dSJacob Faibussowitsch   PetscCall(VecGetArrayWrite(yy,&y));
11005ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
11015ac36cfcSBarry Smith     PetscBLASInt i;
11025ac36cfcSBarry Smith     for (i=0; i<n; i++) y[i] = 0.0;
11035ac36cfcSBarry Smith   } else {
11048b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&mat->lda,x,&_One,&_DZero,y,&_One));
11059566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->cmap->n));
11065ac36cfcSBarry Smith   }
11079566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx,&x));
11089566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayWrite(yy,&y));
11093a40ed3dSBarry Smith   PetscFunctionReturn(0);
1110289bc588SBarry Smith }
1111800995b7SMatthew Knepley 
1112ca15aa20SStefano Zampini PetscErrorCode MatMult_SeqDense(Mat A,Vec xx,Vec yy)
1113289bc588SBarry Smith {
1114c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1115d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0,_DZero=0.0;
11160805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
1117d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
11183a40ed3dSBarry Smith 
11193a40ed3dSBarry Smith   PetscFunctionBegin;
11209566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
11219566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
11229566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx,&x));
11239566063dSJacob Faibussowitsch   PetscCall(VecGetArrayWrite(yy,&y));
11245ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
11255ac36cfcSBarry Smith     PetscBLASInt i;
11265ac36cfcSBarry Smith     for (i=0; i<m; i++) y[i] = 0.0;
11275ac36cfcSBarry Smith   } else {
11288b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DZero,y,&_One));
11299566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->rmap->n));
11305ac36cfcSBarry Smith   }
11319566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx,&x));
11329566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayWrite(yy,&y));
11333a40ed3dSBarry Smith   PetscFunctionReturn(0);
1134289bc588SBarry Smith }
11356ee01492SSatish Balay 
1136ca15aa20SStefano Zampini PetscErrorCode MatMultAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
1137289bc588SBarry Smith {
1138c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1139d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
1140d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0;
11410805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
11423a40ed3dSBarry Smith 
11433a40ed3dSBarry Smith   PetscFunctionBegin;
11449566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
11459566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
11469566063dSJacob Faibussowitsch   PetscCall(VecCopy(zz,yy));
1147d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
11489566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx,&x));
11499566063dSJacob Faibussowitsch   PetscCall(VecGetArray(yy,&y));
11508b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
11519566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx,&x));
11529566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(yy,&y));
11539566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0*A->rmap->n*A->cmap->n));
11543a40ed3dSBarry Smith   PetscFunctionReturn(0);
1155289bc588SBarry Smith }
11566ee01492SSatish Balay 
1157ca15aa20SStefano Zampini PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
1158289bc588SBarry Smith {
1159c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1160d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
1161d9ca1df4SBarry Smith   PetscScalar       *y;
11620805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
116387828ca2SBarry Smith   PetscScalar       _DOne=1.0;
11643a40ed3dSBarry Smith 
11653a40ed3dSBarry Smith   PetscFunctionBegin;
11669566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
11679566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
11689566063dSJacob Faibussowitsch   PetscCall(VecCopy(zz,yy));
1169d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
11709566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx,&x));
11719566063dSJacob Faibussowitsch   PetscCall(VecGetArray(yy,&y));
11728b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
11739566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx,&x));
11749566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(yy,&y));
11759566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0*A->rmap->n*A->cmap->n));
11763a40ed3dSBarry Smith   PetscFunctionReturn(0);
1177289bc588SBarry Smith }
1178289bc588SBarry Smith 
1179289bc588SBarry Smith /* -----------------------------------------------------------------*/
1180e0877f53SBarry Smith static PetscErrorCode MatGetRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
1181289bc588SBarry Smith {
1182c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
118313f74950SBarry Smith   PetscInt       i;
118467e560aaSBarry Smith 
11853a40ed3dSBarry Smith   PetscFunctionBegin;
1186d0f46423SBarry Smith   *ncols = A->cmap->n;
1187289bc588SBarry Smith   if (cols) {
11889566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(A->cmap->n,cols));
1189d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) (*cols)[i] = i;
1190289bc588SBarry Smith   }
1191289bc588SBarry Smith   if (vals) {
1192ca15aa20SStefano Zampini     const PetscScalar *v;
1193ca15aa20SStefano Zampini 
11949566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A,&v));
11959566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(A->cmap->n,vals));
1196ca15aa20SStefano Zampini     v   += row;
1197d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {(*vals)[i] = *v; v += mat->lda;}
11989566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A,&v));
1199289bc588SBarry Smith   }
12003a40ed3dSBarry Smith   PetscFunctionReturn(0);
1201289bc588SBarry Smith }
12026ee01492SSatish Balay 
1203e0877f53SBarry Smith static PetscErrorCode MatRestoreRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
1204289bc588SBarry Smith {
1205606d414cSSatish Balay   PetscFunctionBegin;
1206cb4a9cd9SHong Zhang   if (ncols) *ncols = 0;
12079566063dSJacob Faibussowitsch   if (cols) PetscCall(PetscFree(*cols));
12089566063dSJacob Faibussowitsch   if (vals) PetscCall(PetscFree(*vals));
12093a40ed3dSBarry Smith   PetscFunctionReturn(0);
1210289bc588SBarry Smith }
1211289bc588SBarry Smith /* ----------------------------------------------------------------*/
1212e0877f53SBarry Smith static PetscErrorCode MatSetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],const PetscScalar v[],InsertMode addv)
1213289bc588SBarry Smith {
1214c0bbcb79SLois Curfman McInnes   Mat_SeqDense     *mat = (Mat_SeqDense*)A->data;
1215ca15aa20SStefano Zampini   PetscScalar      *av;
121613f74950SBarry Smith   PetscInt         i,j,idx=0;
1217ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1218c70f7ee4SJunchao Zhang   PetscOffloadMask oldf;
1219ca15aa20SStefano Zampini #endif
1220d6dfbf8fSBarry Smith 
12213a40ed3dSBarry Smith   PetscFunctionBegin;
12229566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&av));
1223289bc588SBarry Smith   if (!mat->roworiented) {
1224dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1225289bc588SBarry Smith       for (j=0; j<n; j++) {
1226cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
12276bdcaf15SBarry 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);
1228289bc588SBarry Smith         for (i=0; i<m; i++) {
1229cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
12306bdcaf15SBarry 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);
1231ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
1232289bc588SBarry Smith         }
1233289bc588SBarry Smith       }
12343a40ed3dSBarry Smith     } else {
1235289bc588SBarry Smith       for (j=0; j<n; j++) {
1236cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
12376bdcaf15SBarry 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);
1238289bc588SBarry Smith         for (i=0; i<m; i++) {
1239cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
12406bdcaf15SBarry 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);
1241ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
1242289bc588SBarry Smith         }
1243289bc588SBarry Smith       }
1244289bc588SBarry Smith     }
12453a40ed3dSBarry Smith   } else {
1246dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1247e8d4e0b9SBarry Smith       for (i=0; i<m; i++) {
1248cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
12496bdcaf15SBarry 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);
1250e8d4e0b9SBarry Smith         for (j=0; j<n; j++) {
1251cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
12526bdcaf15SBarry 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);
1253ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
1254e8d4e0b9SBarry Smith         }
1255e8d4e0b9SBarry Smith       }
12563a40ed3dSBarry Smith     } else {
1257289bc588SBarry Smith       for (i=0; i<m; i++) {
1258cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
12596bdcaf15SBarry 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);
1260289bc588SBarry Smith         for (j=0; j<n; j++) {
1261cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
12626bdcaf15SBarry 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);
1263ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
1264289bc588SBarry Smith         }
1265289bc588SBarry Smith       }
1266289bc588SBarry Smith     }
1267e8d4e0b9SBarry Smith   }
1268ca15aa20SStefano Zampini   /* hack to prevent unneeded copy to the GPU while returning the array */
1269ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1270c70f7ee4SJunchao Zhang   oldf = A->offloadmask;
1271c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_GPU;
1272ca15aa20SStefano Zampini #endif
12739566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&av));
1274ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1275c70f7ee4SJunchao Zhang   A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU);
1276ca15aa20SStefano Zampini #endif
12773a40ed3dSBarry Smith   PetscFunctionReturn(0);
1278289bc588SBarry Smith }
1279e8d4e0b9SBarry Smith 
1280e0877f53SBarry Smith static PetscErrorCode MatGetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],PetscScalar v[])
1281ae80bb75SLois Curfman McInnes {
1282ae80bb75SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1283ca15aa20SStefano Zampini   const PetscScalar *vv;
128413f74950SBarry Smith   PetscInt          i,j;
1285ae80bb75SLois Curfman McInnes 
12863a40ed3dSBarry Smith   PetscFunctionBegin;
12879566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&vv));
1288ae80bb75SLois Curfman McInnes   /* row-oriented output */
1289ae80bb75SLois Curfman McInnes   for (i=0; i<m; i++) {
129097e567efSBarry Smith     if (indexm[i] < 0) {v += n;continue;}
12912c71b3e2SJacob Faibussowitsch     PetscCheckFalse(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);
1292ae80bb75SLois Curfman McInnes     for (j=0; j<n; j++) {
12936f31f424SBarry Smith       if (indexn[j] < 0) {v++; continue;}
12942c71b3e2SJacob Faibussowitsch       PetscCheckFalse(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);
1295ca15aa20SStefano Zampini       *v++ = vv[indexn[j]*mat->lda + indexm[i]];
1296ae80bb75SLois Curfman McInnes     }
1297ae80bb75SLois Curfman McInnes   }
12989566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&vv));
12993a40ed3dSBarry Smith   PetscFunctionReturn(0);
1300ae80bb75SLois Curfman McInnes }
1301ae80bb75SLois Curfman McInnes 
1302289bc588SBarry Smith /* -----------------------------------------------------------------*/
1303289bc588SBarry Smith 
13048491ab44SLisandro Dalcin PetscErrorCode MatView_Dense_Binary(Mat mat,PetscViewer viewer)
1305aabbc4fbSShri Abhyankar {
13068491ab44SLisandro Dalcin   PetscBool         skipHeader;
13078491ab44SLisandro Dalcin   PetscViewerFormat format;
13088491ab44SLisandro Dalcin   PetscInt          header[4],M,N,m,lda,i,j,k;
13098491ab44SLisandro Dalcin   const PetscScalar *v;
13108491ab44SLisandro Dalcin   PetscScalar       *vwork;
1311aabbc4fbSShri Abhyankar 
1312aabbc4fbSShri Abhyankar   PetscFunctionBegin;
13139566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
13149566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryGetSkipHeader(viewer,&skipHeader));
13159566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer,&format));
13168491ab44SLisandro Dalcin   if (skipHeader) format = PETSC_VIEWER_NATIVE;
1317aabbc4fbSShri Abhyankar 
13189566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat,&M,&N));
13198491ab44SLisandro Dalcin 
13208491ab44SLisandro Dalcin   /* write matrix header */
13218491ab44SLisandro Dalcin   header[0] = MAT_FILE_CLASSID; header[1] = M; header[2] = N;
13228491ab44SLisandro Dalcin   header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M*N;
13239566063dSJacob Faibussowitsch   if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer,header,4,PETSC_INT));
13248491ab44SLisandro Dalcin 
13259566063dSJacob Faibussowitsch   PetscCall(MatGetLocalSize(mat,&m,NULL));
13268491ab44SLisandro Dalcin   if (format != PETSC_VIEWER_NATIVE) {
13278491ab44SLisandro Dalcin     PetscInt nnz = m*N, *iwork;
13288491ab44SLisandro Dalcin     /* store row lengths for each row */
13299566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nnz,&iwork));
13308491ab44SLisandro Dalcin     for (i=0; i<m; i++) iwork[i] = N;
13319566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWriteAll(viewer,iwork,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT));
13328491ab44SLisandro Dalcin     /* store column indices (zero start index) */
13338491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
13348491ab44SLisandro Dalcin       for (j=0; j<N; j++, k++)
13358491ab44SLisandro Dalcin         iwork[k] = j;
13369566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWriteAll(viewer,iwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT));
13379566063dSJacob Faibussowitsch     PetscCall(PetscFree(iwork));
13388491ab44SLisandro Dalcin   }
13398491ab44SLisandro Dalcin   /* store matrix values as a dense matrix in row major order */
13409566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(m*N,&vwork));
13419566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(mat,&v));
13429566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(mat,&lda));
13438491ab44SLisandro Dalcin   for (k=0, i=0; i<m; i++)
13448491ab44SLisandro Dalcin     for (j=0; j<N; j++, k++)
13458491ab44SLisandro Dalcin       vwork[k] = v[i+lda*j];
13469566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(mat,&v));
13479566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryWriteAll(viewer,vwork,m*N,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR));
13489566063dSJacob Faibussowitsch   PetscCall(PetscFree(vwork));
13498491ab44SLisandro Dalcin   PetscFunctionReturn(0);
13508491ab44SLisandro Dalcin }
13518491ab44SLisandro Dalcin 
13528491ab44SLisandro Dalcin PetscErrorCode MatLoad_Dense_Binary(Mat mat,PetscViewer viewer)
13538491ab44SLisandro Dalcin {
13548491ab44SLisandro Dalcin   PetscBool      skipHeader;
13558491ab44SLisandro Dalcin   PetscInt       header[4],M,N,m,nz,lda,i,j,k;
13568491ab44SLisandro Dalcin   PetscInt       rows,cols;
13578491ab44SLisandro Dalcin   PetscScalar    *v,*vwork;
13588491ab44SLisandro Dalcin 
13598491ab44SLisandro Dalcin   PetscFunctionBegin;
13609566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
13619566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryGetSkipHeader(viewer,&skipHeader));
13628491ab44SLisandro Dalcin 
13638491ab44SLisandro Dalcin   if (!skipHeader) {
13649566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryRead(viewer,header,4,NULL,PETSC_INT));
13652c71b3e2SJacob Faibussowitsch     PetscCheckFalse(header[0] != MAT_FILE_CLASSID,PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Not a matrix object in file");
13668491ab44SLisandro Dalcin     M = header[1]; N = header[2];
13672c71b3e2SJacob Faibussowitsch     PetscCheckFalse(M < 0,PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix row size (%" PetscInt_FMT ") in file is negative",M);
13682c71b3e2SJacob Faibussowitsch     PetscCheckFalse(N < 0,PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix column size (%" PetscInt_FMT ") in file is negative",N);
13698491ab44SLisandro Dalcin     nz = header[3];
13702c71b3e2SJacob Faibussowitsch     PetscCheckFalse(nz != MATRIX_BINARY_FORMAT_DENSE && nz < 0,PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Unknown matrix format %" PetscInt_FMT " in file",nz);
1371aabbc4fbSShri Abhyankar   } else {
13729566063dSJacob Faibussowitsch     PetscCall(MatGetSize(mat,&M,&N));
13732c71b3e2SJacob Faibussowitsch     PetscCheckFalse(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");
13748491ab44SLisandro Dalcin     nz = MATRIX_BINARY_FORMAT_DENSE;
1375e6324fbbSBarry Smith   }
1376aabbc4fbSShri Abhyankar 
13778491ab44SLisandro Dalcin   /* setup global sizes if not set */
13788491ab44SLisandro Dalcin   if (mat->rmap->N < 0) mat->rmap->N = M;
13798491ab44SLisandro Dalcin   if (mat->cmap->N < 0) mat->cmap->N = N;
13809566063dSJacob Faibussowitsch   PetscCall(MatSetUp(mat));
13818491ab44SLisandro Dalcin   /* check if global sizes are correct */
13829566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat,&rows,&cols));
13832c71b3e2SJacob Faibussowitsch   PetscCheckFalse(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);
1384aabbc4fbSShri Abhyankar 
13859566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat,NULL,&N));
13869566063dSJacob Faibussowitsch   PetscCall(MatGetLocalSize(mat,&m,NULL));
13879566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(mat,&v));
13889566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(mat,&lda));
13898491ab44SLisandro Dalcin   if (nz == MATRIX_BINARY_FORMAT_DENSE) {  /* matrix in file is dense format */
13908491ab44SLisandro Dalcin     PetscInt nnz = m*N;
13918491ab44SLisandro Dalcin     /* read in matrix values */
13929566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nnz,&vwork));
13939566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR));
13948491ab44SLisandro Dalcin     /* store values in column major order */
13958491ab44SLisandro Dalcin     for (j=0; j<N; j++)
13968491ab44SLisandro Dalcin       for (i=0; i<m; i++)
13978491ab44SLisandro Dalcin         v[i+lda*j] = vwork[i*N+j];
13989566063dSJacob Faibussowitsch     PetscCall(PetscFree(vwork));
13998491ab44SLisandro Dalcin   } else { /* matrix in file is sparse format */
14008491ab44SLisandro Dalcin     PetscInt nnz = 0, *rlens, *icols;
14018491ab44SLisandro Dalcin     /* read in row lengths */
14029566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(m,&rlens));
14039566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer,rlens,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT));
14048491ab44SLisandro Dalcin     for (i=0; i<m; i++) nnz += rlens[i];
14058491ab44SLisandro Dalcin     /* read in column indices and values */
14069566063dSJacob Faibussowitsch     PetscCall(PetscMalloc2(nnz,&icols,nnz,&vwork));
14079566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer,icols,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT));
14089566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR));
14098491ab44SLisandro Dalcin     /* store values in column major order */
14108491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
14118491ab44SLisandro Dalcin       for (j=0; j<rlens[i]; j++, k++)
14128491ab44SLisandro Dalcin         v[i+lda*icols[k]] = vwork[k];
14139566063dSJacob Faibussowitsch     PetscCall(PetscFree(rlens));
14149566063dSJacob Faibussowitsch     PetscCall(PetscFree2(icols,vwork));
1415aabbc4fbSShri Abhyankar   }
14169566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(mat,&v));
14179566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY));
14189566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY));
1419aabbc4fbSShri Abhyankar   PetscFunctionReturn(0);
1420aabbc4fbSShri Abhyankar }
1421aabbc4fbSShri Abhyankar 
1422eb91f321SVaclav Hapla PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer)
1423eb91f321SVaclav Hapla {
1424eb91f321SVaclav Hapla   PetscBool      isbinary, ishdf5;
1425eb91f321SVaclav Hapla 
1426eb91f321SVaclav Hapla   PetscFunctionBegin;
1427eb91f321SVaclav Hapla   PetscValidHeaderSpecific(newMat,MAT_CLASSID,1);
1428eb91f321SVaclav Hapla   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1429eb91f321SVaclav Hapla   /* force binary viewer to load .info file if it has not yet done so */
14309566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
14319566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary));
14329566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,  &ishdf5));
1433eb91f321SVaclav Hapla   if (isbinary) {
14349566063dSJacob Faibussowitsch     PetscCall(MatLoad_Dense_Binary(newMat,viewer));
1435eb91f321SVaclav Hapla   } else if (ishdf5) {
1436eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5)
14379566063dSJacob Faibussowitsch     PetscCall(MatLoad_Dense_HDF5(newMat,viewer));
1438eb91f321SVaclav Hapla #else
1439eb91f321SVaclav Hapla     SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5");
1440eb91f321SVaclav Hapla #endif
1441eb91f321SVaclav Hapla   } else {
144298921bdaSJacob Faibussowitsch     SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"Viewer type %s not yet supported for reading %s matrices",((PetscObject)viewer)->type_name,((PetscObject)newMat)->type_name);
1443eb91f321SVaclav Hapla   }
1444eb91f321SVaclav Hapla   PetscFunctionReturn(0);
1445eb91f321SVaclav Hapla }
1446eb91f321SVaclav Hapla 
14476849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_ASCII(Mat A,PetscViewer viewer)
1448289bc588SBarry Smith {
1449932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
145013f74950SBarry Smith   PetscInt          i,j;
14512dcb1b2aSMatthew Knepley   const char        *name;
1452ca15aa20SStefano Zampini   PetscScalar       *v,*av;
1453f3ef73ceSBarry Smith   PetscViewerFormat format;
14545f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX)
1455ace3abfcSBarry Smith   PetscBool         allreal = PETSC_TRUE;
14565f481a85SSatish Balay #endif
1457932b0c3eSLois Curfman McInnes 
14583a40ed3dSBarry Smith   PetscFunctionBegin;
14599566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,(const PetscScalar**)&av));
14609566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer,&format));
1461456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
14623a40ed3dSBarry Smith     PetscFunctionReturn(0);  /* do nothing for now */
1463fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
14649566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE));
1465d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1466ca15aa20SStefano Zampini       v    = av + i;
14679566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"row %" PetscInt_FMT ":",i));
1468d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1469aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1470329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
14719566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g + %g i) ",j,(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v)));
1472329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
14739566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g) ",j,(double)PetscRealPart(*v)));
14746831982aSBarry Smith         }
147580cd9d93SLois Curfman McInnes #else
14766831982aSBarry Smith         if (*v) {
14779566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g) ",j,(double)*v));
14786831982aSBarry Smith         }
147980cd9d93SLois Curfman McInnes #endif
14801b807ce4Svictorle         v += a->lda;
148180cd9d93SLois Curfman McInnes       }
14829566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"\n"));
148380cd9d93SLois Curfman McInnes     }
14849566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE));
14853a40ed3dSBarry Smith   } else {
14869566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE));
1487aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
148847989497SBarry Smith     /* determine if matrix has all real values */
1489ca15aa20SStefano Zampini     v = av;
1490d0f46423SBarry Smith     for (i=0; i<A->rmap->n*A->cmap->n; i++) {
1491ffac6cdbSBarry Smith       if (PetscImaginaryPart(v[i])) { allreal = PETSC_FALSE; break;}
149247989497SBarry Smith     }
149347989497SBarry Smith #endif
1494fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
14959566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetName((PetscObject)A,&name));
14969566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"%% Size = %" PetscInt_FMT " %" PetscInt_FMT " \n",A->rmap->n,A->cmap->n));
14979566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"%s = zeros(%" PetscInt_FMT ",%" PetscInt_FMT ");\n",name,A->rmap->n,A->cmap->n));
14989566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"%s = [\n",name));
1499ffac6cdbSBarry Smith     }
1500ffac6cdbSBarry Smith 
1501d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1502ca15aa20SStefano Zampini       v = av + i;
1503d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1504aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
150547989497SBarry Smith         if (allreal) {
15069566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)PetscRealPart(*v)));
150747989497SBarry Smith         } else {
15089566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ei ",(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v)));
150947989497SBarry Smith         }
1510289bc588SBarry Smith #else
15119566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)*v));
1512289bc588SBarry Smith #endif
15131b807ce4Svictorle         v += a->lda;
1514289bc588SBarry Smith       }
15159566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"\n"));
1516289bc588SBarry Smith     }
1517fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
15189566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"];\n"));
1519ffac6cdbSBarry Smith     }
15209566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE));
1521da3a660dSBarry Smith   }
15229566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,(const PetscScalar**)&av));
15239566063dSJacob Faibussowitsch   PetscCall(PetscViewerFlush(viewer));
15243a40ed3dSBarry Smith   PetscFunctionReturn(0);
1525289bc588SBarry Smith }
1526289bc588SBarry Smith 
15279804daf3SBarry Smith #include <petscdraw.h>
1528e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw,void *Aa)
1529f1af5d2fSBarry Smith {
1530f1af5d2fSBarry Smith   Mat               A  = (Mat) Aa;
1531383922c3SLisandro Dalcin   PetscInt          m  = A->rmap->n,n = A->cmap->n,i,j;
1532383922c3SLisandro Dalcin   int               color = PETSC_DRAW_WHITE;
1533ca15aa20SStefano Zampini   const PetscScalar *v;
1534b0a32e0cSBarry Smith   PetscViewer       viewer;
1535b05fc000SLisandro Dalcin   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r;
1536f3ef73ceSBarry Smith   PetscViewerFormat format;
15375f80ce2aSJacob Faibussowitsch   PetscErrorCode    ierr;
1538f1af5d2fSBarry Smith 
1539f1af5d2fSBarry Smith   PetscFunctionBegin;
15409566063dSJacob Faibussowitsch   PetscCall(PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer));
15419566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer,&format));
15429566063dSJacob Faibussowitsch   PetscCall(PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr));
1543f1af5d2fSBarry Smith 
1544f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
15459566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&v));
1546fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
15479566063dSJacob Faibussowitsch     ierr = PetscDrawCollectiveBegin(draw);PetscCall(ierr);
1548f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
1549f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
1550383922c3SLisandro Dalcin       x_l = j; x_r = x_l + 1.0;
1551f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1552f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1553f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1554ca15aa20SStefano Zampini         if (PetscRealPart(v[j*m+i]) >  0.) color = PETSC_DRAW_RED;
1555ca15aa20SStefano Zampini         else if (PetscRealPart(v[j*m+i]) <  0.) color = PETSC_DRAW_BLUE;
1556ca15aa20SStefano Zampini         else continue;
15579566063dSJacob Faibussowitsch         PetscCall(PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color));
1558f1af5d2fSBarry Smith       }
1559f1af5d2fSBarry Smith     }
15609566063dSJacob Faibussowitsch     ierr = PetscDrawCollectiveEnd(draw);PetscCall(ierr);
1561f1af5d2fSBarry Smith   } else {
1562f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
1563f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
1564b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1565b05fc000SLisandro Dalcin     PetscDraw popup;
1566b05fc000SLisandro Dalcin 
1567f1af5d2fSBarry Smith     for (i=0; i < m*n; i++) {
1568f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
1569f1af5d2fSBarry Smith     }
1570383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
15719566063dSJacob Faibussowitsch     PetscCall(PetscDrawGetPopup(draw,&popup));
15729566063dSJacob Faibussowitsch     PetscCall(PetscDrawScalePopup(popup,minv,maxv));
1573383922c3SLisandro Dalcin 
15749566063dSJacob Faibussowitsch     ierr = PetscDrawCollectiveBegin(draw);PetscCall(ierr);
1575f1af5d2fSBarry Smith     for (j=0; j<n; j++) {
1576f1af5d2fSBarry Smith       x_l = j;
1577f1af5d2fSBarry Smith       x_r = x_l + 1.0;
1578f1af5d2fSBarry Smith       for (i=0; i<m; i++) {
1579f1af5d2fSBarry Smith         y_l   = m - i - 1.0;
1580f1af5d2fSBarry Smith         y_r   = y_l + 1.0;
1581b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(v[j*m+i]),minv,maxv);
15829566063dSJacob Faibussowitsch         PetscCall(PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color));
1583f1af5d2fSBarry Smith       }
1584f1af5d2fSBarry Smith     }
15859566063dSJacob Faibussowitsch     ierr = PetscDrawCollectiveEnd(draw);PetscCall(ierr);
1586f1af5d2fSBarry Smith   }
15879566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&v));
1588f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1589f1af5d2fSBarry Smith }
1590f1af5d2fSBarry Smith 
1591e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw(Mat A,PetscViewer viewer)
1592f1af5d2fSBarry Smith {
1593b0a32e0cSBarry Smith   PetscDraw      draw;
1594ace3abfcSBarry Smith   PetscBool      isnull;
1595329f5518SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
1596f1af5d2fSBarry Smith 
1597f1af5d2fSBarry Smith   PetscFunctionBegin;
15989566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDraw(viewer,0,&draw));
15999566063dSJacob Faibussowitsch   PetscCall(PetscDrawIsNull(draw,&isnull));
1600abc0a331SBarry Smith   if (isnull) PetscFunctionReturn(0);
1601f1af5d2fSBarry Smith 
1602d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
1603f1af5d2fSBarry Smith   xr  += w;          yr += h;        xl = -w;     yl = -h;
16049566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetCoordinates(draw,xl,yl,xr,yr));
16059566063dSJacob Faibussowitsch   PetscCall(PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer));
16069566063dSJacob Faibussowitsch   PetscCall(PetscDrawZoom(draw,MatView_SeqDense_Draw_Zoom,A));
16079566063dSJacob Faibussowitsch   PetscCall(PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL));
16089566063dSJacob Faibussowitsch   PetscCall(PetscDrawSave(draw));
1609f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1610f1af5d2fSBarry Smith }
1611f1af5d2fSBarry Smith 
1612dfbe8321SBarry Smith PetscErrorCode MatView_SeqDense(Mat A,PetscViewer viewer)
1613932b0c3eSLois Curfman McInnes {
1614ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
1615932b0c3eSLois Curfman McInnes 
16163a40ed3dSBarry Smith   PetscFunctionBegin;
16179566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
16189566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary));
16199566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw));
1620c45a1595SBarry Smith   if (iascii) {
16219566063dSJacob Faibussowitsch     PetscCall(MatView_SeqDense_ASCII(A,viewer));
16220f5bd95cSBarry Smith   } else if (isbinary) {
16239566063dSJacob Faibussowitsch     PetscCall(MatView_Dense_Binary(A,viewer));
1624f1af5d2fSBarry Smith   } else if (isdraw) {
16259566063dSJacob Faibussowitsch     PetscCall(MatView_SeqDense_Draw(A,viewer));
1626932b0c3eSLois Curfman McInnes   }
16273a40ed3dSBarry Smith   PetscFunctionReturn(0);
1628932b0c3eSLois Curfman McInnes }
1629289bc588SBarry Smith 
1630637a0070SStefano Zampini static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A,const PetscScalar *array)
1631d3042a70SBarry Smith {
1632d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1633d3042a70SBarry Smith 
1634d3042a70SBarry Smith   PetscFunctionBegin;
163528b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
163628b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
163728b400f6SJacob Faibussowitsch   PetscCheck(!a->unplacedarray,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreArray() first");
1638d3042a70SBarry Smith   a->unplacedarray       = a->v;
1639d3042a70SBarry Smith   a->unplaced_user_alloc = a->user_alloc;
1640d3042a70SBarry Smith   a->v                   = (PetscScalar*) array;
1641637a0070SStefano Zampini   a->user_alloc          = PETSC_TRUE;
1642ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1643c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1644ca15aa20SStefano Zampini #endif
1645d3042a70SBarry Smith   PetscFunctionReturn(0);
1646d3042a70SBarry Smith }
1647d3042a70SBarry Smith 
1648d3042a70SBarry Smith static PetscErrorCode MatDenseResetArray_SeqDense(Mat A)
1649d3042a70SBarry Smith {
1650d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1651d3042a70SBarry Smith 
1652d3042a70SBarry Smith   PetscFunctionBegin;
165328b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
165428b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
1655d3042a70SBarry Smith   a->v             = a->unplacedarray;
1656d3042a70SBarry Smith   a->user_alloc    = a->unplaced_user_alloc;
1657d3042a70SBarry Smith   a->unplacedarray = NULL;
1658ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1659c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1660ca15aa20SStefano Zampini #endif
1661d3042a70SBarry Smith   PetscFunctionReturn(0);
1662d3042a70SBarry Smith }
1663d3042a70SBarry Smith 
1664d5ea218eSStefano Zampini static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A,const PetscScalar *array)
1665d5ea218eSStefano Zampini {
1666d5ea218eSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1667d5ea218eSStefano Zampini 
1668d5ea218eSStefano Zampini   PetscFunctionBegin;
166928b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
167028b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
16719566063dSJacob Faibussowitsch   if (!a->user_alloc) PetscCall(PetscFree(a->v));
1672d5ea218eSStefano Zampini   a->v           = (PetscScalar*) array;
1673d5ea218eSStefano Zampini   a->user_alloc  = PETSC_FALSE;
1674d5ea218eSStefano Zampini #if defined(PETSC_HAVE_CUDA)
1675d5ea218eSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
1676d5ea218eSStefano Zampini #endif
1677d5ea218eSStefano Zampini   PetscFunctionReturn(0);
1678d5ea218eSStefano Zampini }
1679d5ea218eSStefano Zampini 
1680ca15aa20SStefano Zampini PetscErrorCode MatDestroy_SeqDense(Mat mat)
1681289bc588SBarry Smith {
1682ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)mat->data;
168390f02eecSBarry Smith 
16843a40ed3dSBarry Smith   PetscFunctionBegin;
1685aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1686c0aa6a63SJacob Faibussowitsch   PetscLogObjectState((PetscObject)mat,"Rows %" PetscInt_FMT " Cols %" PetscInt_FMT,mat->rmap->n,mat->cmap->n);
1687a5a9c739SBarry Smith #endif
16889566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(l->qrrhs)));
16899566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->tau));
16909566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->pivots));
16919566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->fwork));
16929566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&l->ptapwork));
16939566063dSJacob Faibussowitsch   if (!l->user_alloc) PetscCall(PetscFree(l->v));
16949566063dSJacob Faibussowitsch   if (!l->unplaced_user_alloc) PetscCall(PetscFree(l->unplacedarray));
169528b400f6SJacob Faibussowitsch   PetscCheck(!l->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
169628b400f6SJacob Faibussowitsch   PetscCheck(!l->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
16979566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&l->cvec));
16989566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&l->cmat));
16999566063dSJacob Faibussowitsch   PetscCall(PetscFree(mat->data));
1700dbd8c25aSHong Zhang 
17019566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)mat,NULL));
17029566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatQRFactor_C",NULL));
17039566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetLDA_C",NULL));
17049566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseSetLDA_C",NULL));
17059566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArray_C",NULL));
17069566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArray_C",NULL));
17079566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDensePlaceArray_C",NULL));
17089566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseResetArray_C",NULL));
17099566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseReplaceArray_C",NULL));
17109566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArrayRead_C",NULL));
17119566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArrayRead_C",NULL));
17129566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArrayWrite_C",NULL));
17139566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArrayWrite_C",NULL));
17149566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqaij_C",NULL));
17158baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
17169566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_elemental_C",NULL));
17178baccfbdSHong Zhang #endif
1718d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
17199566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_scalapack_C",NULL));
1720d24d4204SJose E. Roman #endif
17212bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
17229566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqdensecuda_C",NULL));
17239566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",NULL));
17249566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdense_C",NULL));
17252bf066beSStefano Zampini #endif
17269566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatSeqDenseSetPreallocation_C",NULL));
17279566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqaij_seqdense_C",NULL));
17289566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdense_seqdense_C",NULL));
17299566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqbaij_seqdense_C",NULL));
17309566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqsbaij_seqdense_C",NULL));
173152c5f739Sprj- 
17329566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumn_C",NULL));
17339566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumn_C",NULL));
17349566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVec_C",NULL));
17359566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVec_C",NULL));
17369566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVecRead_C",NULL));
17379566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVecRead_C",NULL));
17389566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVecWrite_C",NULL));
17399566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVecWrite_C",NULL));
17409566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetSubMatrix_C",NULL));
17419566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreSubMatrix_C",NULL));
17423a40ed3dSBarry Smith   PetscFunctionReturn(0);
1743289bc588SBarry Smith }
1744289bc588SBarry Smith 
1745e0877f53SBarry Smith static PetscErrorCode MatTranspose_SeqDense(Mat A,MatReuse reuse,Mat *matout)
1746289bc588SBarry Smith {
1747c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
17486536e3caSStefano Zampini   PetscInt       k,j,m = A->rmap->n, M = mat->lda, n = A->cmap->n;
174987828ca2SBarry Smith   PetscScalar    *v,tmp;
175048b35521SBarry Smith 
17513a40ed3dSBarry Smith   PetscFunctionBegin;
17526536e3caSStefano Zampini   if (reuse == MAT_INPLACE_MATRIX) {
17536536e3caSStefano Zampini     if (m == n) { /* in place transpose */
17549566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(A,&v));
1755d3e5ee88SLois Curfman McInnes       for (j=0; j<m; j++) {
1756289bc588SBarry Smith         for (k=0; k<j; k++) {
17571b807ce4Svictorle           tmp        = v[j + k*M];
17581b807ce4Svictorle           v[j + k*M] = v[k + j*M];
17591b807ce4Svictorle           v[k + j*M] = tmp;
1760289bc588SBarry Smith         }
1761289bc588SBarry Smith       }
17629566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArray(A,&v));
17636536e3caSStefano Zampini     } else { /* reuse memory, temporary allocates new memory */
17646536e3caSStefano Zampini       PetscScalar *v2;
17656536e3caSStefano Zampini       PetscLayout tmplayout;
17666536e3caSStefano Zampini 
17679566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1((size_t)m*n,&v2));
17689566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(A,&v));
17696536e3caSStefano Zampini       for (j=0; j<n; j++) {
17706536e3caSStefano Zampini         for (k=0; k<m; k++) v2[j + (size_t)k*n] = v[k + (size_t)j*M];
17716536e3caSStefano Zampini       }
17729566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(v,v2,(size_t)m*n));
17739566063dSJacob Faibussowitsch       PetscCall(PetscFree(v2));
17749566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArray(A,&v));
17756536e3caSStefano Zampini       /* cleanup size dependent quantities */
17769566063dSJacob Faibussowitsch       PetscCall(VecDestroy(&mat->cvec));
17779566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&mat->cmat));
17789566063dSJacob Faibussowitsch       PetscCall(PetscFree(mat->pivots));
17799566063dSJacob Faibussowitsch       PetscCall(PetscFree(mat->fwork));
17809566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&mat->ptapwork));
17816536e3caSStefano Zampini       /* swap row/col layouts */
17826536e3caSStefano Zampini       mat->lda  = n;
17836536e3caSStefano Zampini       tmplayout = A->rmap;
17846536e3caSStefano Zampini       A->rmap   = A->cmap;
17856536e3caSStefano Zampini       A->cmap   = tmplayout;
17866536e3caSStefano Zampini     }
17873a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1788d3e5ee88SLois Curfman McInnes     Mat          tmat;
1789ec8511deSBarry Smith     Mat_SeqDense *tmatd;
179087828ca2SBarry Smith     PetscScalar  *v2;
1791af36a384SStefano Zampini     PetscInt     M2;
1792ea709b57SSatish Balay 
17936536e3caSStefano Zampini     if (reuse == MAT_INITIAL_MATRIX) {
17949566063dSJacob Faibussowitsch       PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&tmat));
17959566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(tmat,A->cmap->n,A->rmap->n,A->cmap->n,A->rmap->n));
17969566063dSJacob Faibussowitsch       PetscCall(MatSetType(tmat,((PetscObject)A)->type_name));
17979566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSetPreallocation(tmat,NULL));
1798ca15aa20SStefano Zampini     } else tmat = *matout;
1799ca15aa20SStefano Zampini 
18009566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A,(const PetscScalar**)&v));
18019566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArray(tmat,&v2));
1802ec8511deSBarry Smith     tmatd = (Mat_SeqDense*)tmat->data;
1803ca15aa20SStefano Zampini     M2    = tmatd->lda;
1804d3e5ee88SLois Curfman McInnes     for (j=0; j<n; j++) {
1805af36a384SStefano Zampini       for (k=0; k<m; k++) v2[j + k*M2] = v[k + j*M];
1806d3e5ee88SLois Curfman McInnes     }
18079566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(tmat,&v2));
18089566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A,(const PetscScalar**)&v));
18099566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY));
18109566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY));
18116536e3caSStefano Zampini     *matout = tmat;
181248b35521SBarry Smith   }
18133a40ed3dSBarry Smith   PetscFunctionReturn(0);
1814289bc588SBarry Smith }
1815289bc588SBarry Smith 
1816e0877f53SBarry Smith static PetscErrorCode MatEqual_SeqDense(Mat A1,Mat A2,PetscBool  *flg)
1817289bc588SBarry Smith {
1818c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat1 = (Mat_SeqDense*)A1->data;
1819c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat2 = (Mat_SeqDense*)A2->data;
1820ca15aa20SStefano Zampini   PetscInt          i;
1821ca15aa20SStefano Zampini   const PetscScalar *v1,*v2;
18229ea5d5aeSSatish Balay 
18233a40ed3dSBarry Smith   PetscFunctionBegin;
1824d0f46423SBarry Smith   if (A1->rmap->n != A2->rmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1825d0f46423SBarry Smith   if (A1->cmap->n != A2->cmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
18269566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A1,&v1));
18279566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A2,&v2));
1828ca15aa20SStefano Zampini   for (i=0; i<A1->cmap->n; i++) {
18299566063dSJacob Faibussowitsch     PetscCall(PetscArraycmp(v1,v2,A1->rmap->n,flg));
1830ca15aa20SStefano Zampini     if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
1831ca15aa20SStefano Zampini     v1 += mat1->lda;
1832ca15aa20SStefano Zampini     v2 += mat2->lda;
18331b807ce4Svictorle   }
18349566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A1,&v1));
18359566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A2,&v2));
183677c4ece6SBarry Smith   *flg = PETSC_TRUE;
18373a40ed3dSBarry Smith   PetscFunctionReturn(0);
1838289bc588SBarry Smith }
1839289bc588SBarry Smith 
1840e0877f53SBarry Smith static PetscErrorCode MatGetDiagonal_SeqDense(Mat A,Vec v)
1841289bc588SBarry Smith {
1842c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
184313f74950SBarry Smith   PetscInt          i,n,len;
1844ca15aa20SStefano Zampini   PetscScalar       *x;
1845ca15aa20SStefano Zampini   const PetscScalar *vv;
184644cd7ae7SLois Curfman McInnes 
18473a40ed3dSBarry Smith   PetscFunctionBegin;
18489566063dSJacob Faibussowitsch   PetscCall(VecGetSize(v,&n));
18499566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v,&x));
1850d0f46423SBarry Smith   len  = PetscMin(A->rmap->n,A->cmap->n);
18519566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&vv));
18522c71b3e2SJacob Faibussowitsch   PetscCheckFalse(n != A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming mat and vec");
185344cd7ae7SLois Curfman McInnes   for (i=0; i<len; i++) {
1854ca15aa20SStefano Zampini     x[i] = vv[i*mat->lda + i];
1855289bc588SBarry Smith   }
18569566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&vv));
18579566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v,&x));
18583a40ed3dSBarry Smith   PetscFunctionReturn(0);
1859289bc588SBarry Smith }
1860289bc588SBarry Smith 
1861e0877f53SBarry Smith static PetscErrorCode MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr)
1862289bc588SBarry Smith {
1863c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1864f1ceaac6SMatthew G. Knepley   const PetscScalar *l,*r;
1865ca15aa20SStefano Zampini   PetscScalar       x,*v,*vv;
1866d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n;
186755659b69SBarry Smith 
18683a40ed3dSBarry Smith   PetscFunctionBegin;
18699566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&vv));
187028988994SBarry Smith   if (ll) {
18719566063dSJacob Faibussowitsch     PetscCall(VecGetSize(ll,&m));
18729566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ll,&l));
18732c71b3e2SJacob Faibussowitsch     PetscCheckFalse(m != A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vec wrong size");
1874da3a660dSBarry Smith     for (i=0; i<m; i++) {
1875da3a660dSBarry Smith       x = l[i];
1876ca15aa20SStefano Zampini       v = vv + i;
1877b43bac26SStefano Zampini       for (j=0; j<n; j++) { (*v) *= x; v+= mat->lda;}
1878da3a660dSBarry Smith     }
18799566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ll,&l));
18809566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0*n*m));
1881da3a660dSBarry Smith   }
188228988994SBarry Smith   if (rr) {
18839566063dSJacob Faibussowitsch     PetscCall(VecGetSize(rr,&n));
18849566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(rr,&r));
18852c71b3e2SJacob Faibussowitsch     PetscCheckFalse(n != A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vec wrong size");
1886da3a660dSBarry Smith     for (i=0; i<n; i++) {
1887da3a660dSBarry Smith       x = r[i];
1888ca15aa20SStefano Zampini       v = vv + i*mat->lda;
18892205254eSKarl Rupp       for (j=0; j<m; j++) (*v++) *= x;
1890da3a660dSBarry Smith     }
18919566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(rr,&r));
18929566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0*n*m));
1893da3a660dSBarry Smith   }
18949566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&vv));
18953a40ed3dSBarry Smith   PetscFunctionReturn(0);
1896289bc588SBarry Smith }
1897289bc588SBarry Smith 
1898ca15aa20SStefano Zampini PetscErrorCode MatNorm_SeqDense(Mat A,NormType type,PetscReal *nrm)
1899289bc588SBarry Smith {
1900c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1901ca15aa20SStefano Zampini   PetscScalar       *v,*vv;
1902329f5518SBarry Smith   PetscReal         sum = 0.0;
190375f6d85dSStefano Zampini   PetscInt          lda, m=A->rmap->n,i,j;
190455659b69SBarry Smith 
19053a40ed3dSBarry Smith   PetscFunctionBegin;
19069566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,(const PetscScalar**)&vv));
19079566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(A,&lda));
1908ca15aa20SStefano Zampini   v    = vv;
1909289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1910a5ce6ee0Svictorle     if (lda>m) {
1911d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1912ca15aa20SStefano Zampini         v = vv+j*lda;
1913a5ce6ee0Svictorle         for (i=0; i<m; i++) {
1914a5ce6ee0Svictorle           sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1915a5ce6ee0Svictorle         }
1916a5ce6ee0Svictorle       }
1917a5ce6ee0Svictorle     } else {
1918570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1919570b7f6dSBarry Smith       PetscBLASInt one = 1,cnt = A->cmap->n*A->rmap->n;
192073cf7048SBarry Smith       PetscStackCallBLAS("BLASnrm2",*nrm = BLASnrm2_(&cnt,v,&one));
1921570b7f6dSBarry Smith     }
1922570b7f6dSBarry Smith #else
1923d0f46423SBarry Smith       for (i=0; i<A->cmap->n*A->rmap->n; i++) {
1924329f5518SBarry Smith         sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1925289bc588SBarry Smith       }
1926a5ce6ee0Svictorle     }
19278f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1928570b7f6dSBarry Smith #endif
19299566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0*A->cmap->n*A->rmap->n));
19303a40ed3dSBarry Smith   } else if (type == NORM_1) {
1931064f8208SBarry Smith     *nrm = 0.0;
1932d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1933ca15aa20SStefano Zampini       v   = vv + j*mat->lda;
1934289bc588SBarry Smith       sum = 0.0;
1935d0f46423SBarry Smith       for (i=0; i<A->rmap->n; i++) {
193633a8263dSBarry Smith         sum += PetscAbsScalar(*v);  v++;
1937289bc588SBarry Smith       }
1938064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1939289bc588SBarry Smith     }
19409566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0*A->cmap->n*A->rmap->n));
19413a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1942064f8208SBarry Smith     *nrm = 0.0;
1943d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1944ca15aa20SStefano Zampini       v   = vv + j;
1945289bc588SBarry Smith       sum = 0.0;
1946d0f46423SBarry Smith       for (i=0; i<A->cmap->n; i++) {
19471b807ce4Svictorle         sum += PetscAbsScalar(*v); v += mat->lda;
1948289bc588SBarry Smith       }
1949064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1950289bc588SBarry Smith     }
19519566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0*A->cmap->n*A->rmap->n));
1952e7e72b3dSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No two norm");
19539566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,(const PetscScalar**)&vv));
19543a40ed3dSBarry Smith   PetscFunctionReturn(0);
1955289bc588SBarry Smith }
1956289bc588SBarry Smith 
1957e0877f53SBarry Smith static PetscErrorCode MatSetOption_SeqDense(Mat A,MatOption op,PetscBool flg)
1958289bc588SBarry Smith {
1959c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *aij = (Mat_SeqDense*)A->data;
196067e560aaSBarry Smith 
19613a40ed3dSBarry Smith   PetscFunctionBegin;
1962b5a2b587SKris Buschelman   switch (op) {
1963b5a2b587SKris Buschelman   case MAT_ROW_ORIENTED:
19644e0d8c25SBarry Smith     aij->roworiented = flg;
1965b5a2b587SKris Buschelman     break;
1966512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1967b5a2b587SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
19683971808eSMatthew Knepley   case MAT_NEW_NONZERO_ALLOCATION_ERR:
19698c78258cSHong Zhang   case MAT_FORCE_DIAGONAL_ENTRIES:
197013fa8e87SLisandro Dalcin   case MAT_KEEP_NONZERO_PATTERN:
1971b5a2b587SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1972b5a2b587SKris Buschelman   case MAT_USE_HASH_TABLE:
19730f8fb01aSBarry Smith   case MAT_IGNORE_ZERO_ENTRIES:
19745021d80fSJed Brown   case MAT_IGNORE_LOWER_TRIANGULAR:
1975071fcb05SBarry Smith   case MAT_SORTED_FULL:
19769566063dSJacob Faibussowitsch     PetscCall(PetscInfo(A,"Option %s ignored\n",MatOptions[op]));
19775021d80fSJed Brown     break;
19785021d80fSJed Brown   case MAT_SPD:
197977e54ba9SKris Buschelman   case MAT_SYMMETRIC:
198077e54ba9SKris Buschelman   case MAT_STRUCTURALLY_SYMMETRIC:
19819a4540c5SBarry Smith   case MAT_HERMITIAN:
19829a4540c5SBarry Smith   case MAT_SYMMETRY_ETERNAL:
19835021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
198477e54ba9SKris Buschelman     break;
1985b5a2b587SKris Buschelman   default:
198698921bdaSJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %s",MatOptions[op]);
19873a40ed3dSBarry Smith   }
19883a40ed3dSBarry Smith   PetscFunctionReturn(0);
1989289bc588SBarry Smith }
1990289bc588SBarry Smith 
19913d8925e7SStefano Zampini PetscErrorCode MatZeroEntries_SeqDense(Mat A)
19926f0a148fSBarry Smith {
1993ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)A->data;
19943d8925e7SStefano Zampini   PetscInt       lda=l->lda,m=A->rmap->n,n=A->cmap->n,j;
1995ca15aa20SStefano Zampini   PetscScalar    *v;
19963a40ed3dSBarry Smith 
19973a40ed3dSBarry Smith   PetscFunctionBegin;
19989566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(A,&v));
1999a5ce6ee0Svictorle   if (lda>m) {
20003d8925e7SStefano Zampini     for (j=0; j<n; j++) {
20019566063dSJacob Faibussowitsch       PetscCall(PetscArrayzero(v+j*lda,m));
2002a5ce6ee0Svictorle     }
2003a5ce6ee0Svictorle   } else {
20049566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(v,PetscInt64Mult(m,n)));
2005a5ce6ee0Svictorle   }
20069566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(A,&v));
20073a40ed3dSBarry Smith   PetscFunctionReturn(0);
20086f0a148fSBarry Smith }
20096f0a148fSBarry Smith 
2010e0877f53SBarry Smith static PetscErrorCode MatZeroRows_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
20116f0a148fSBarry Smith {
2012ec8511deSBarry Smith   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
2013b9679d65SBarry Smith   PetscInt          m  = l->lda, n = A->cmap->n, i,j;
2014ca15aa20SStefano Zampini   PetscScalar       *slot,*bb,*v;
201597b48c8fSBarry Smith   const PetscScalar *xx;
201655659b69SBarry Smith 
20173a40ed3dSBarry Smith   PetscFunctionBegin;
201876bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
2019b9679d65SBarry Smith     for (i=0; i<N; i++) {
20202c71b3e2SJacob Faibussowitsch       PetscCheckFalse(rows[i] < 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
20212c71b3e2SJacob Faibussowitsch       PetscCheckFalse(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);
2022b9679d65SBarry Smith     }
202376bd3646SJed Brown   }
2024ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
2025b9679d65SBarry Smith 
202697b48c8fSBarry Smith   /* fix right hand side if needed */
202797b48c8fSBarry Smith   if (x && b) {
20289566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(x,&xx));
20299566063dSJacob Faibussowitsch     PetscCall(VecGetArray(b,&bb));
20302205254eSKarl Rupp     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
20319566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(x,&xx));
20329566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(b,&bb));
203397b48c8fSBarry Smith   }
203497b48c8fSBarry Smith 
20359566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&v));
20366f0a148fSBarry Smith   for (i=0; i<N; i++) {
2037ca15aa20SStefano Zampini     slot = v + rows[i];
2038b9679d65SBarry Smith     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
20396f0a148fSBarry Smith   }
2040f4df32b1SMatthew Knepley   if (diag != 0.0) {
20412c71b3e2SJacob Faibussowitsch     PetscCheckFalse(A->rmap->n != A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
20426f0a148fSBarry Smith     for (i=0; i<N; i++) {
2043ca15aa20SStefano Zampini       slot  = v + (m+1)*rows[i];
2044f4df32b1SMatthew Knepley       *slot = diag;
20456f0a148fSBarry Smith     }
20466f0a148fSBarry Smith   }
20479566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&v));
20483a40ed3dSBarry Smith   PetscFunctionReturn(0);
20496f0a148fSBarry Smith }
2050557bce09SLois Curfman McInnes 
205149a6ff4bSBarry Smith static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A,PetscInt *lda)
205249a6ff4bSBarry Smith {
205349a6ff4bSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
205449a6ff4bSBarry Smith 
205549a6ff4bSBarry Smith   PetscFunctionBegin;
205649a6ff4bSBarry Smith   *lda = mat->lda;
205749a6ff4bSBarry Smith   PetscFunctionReturn(0);
205849a6ff4bSBarry Smith }
205949a6ff4bSBarry Smith 
2060637a0070SStefano Zampini PetscErrorCode MatDenseGetArray_SeqDense(Mat A,PetscScalar **array)
206164e87e97SBarry Smith {
2062c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
20633a40ed3dSBarry Smith 
20643a40ed3dSBarry Smith   PetscFunctionBegin;
206528b400f6SJacob Faibussowitsch   PetscCheck(!mat->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
206664e87e97SBarry Smith   *array = mat->v;
20673a40ed3dSBarry Smith   PetscFunctionReturn(0);
206864e87e97SBarry Smith }
20690754003eSLois Curfman McInnes 
2070637a0070SStefano Zampini PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A,PetscScalar **array)
2071ff14e315SSatish Balay {
20723a40ed3dSBarry Smith   PetscFunctionBegin;
207375f6d85dSStefano Zampini   if (array) *array = NULL;
20743a40ed3dSBarry Smith   PetscFunctionReturn(0);
2075ff14e315SSatish Balay }
20760754003eSLois Curfman McInnes 
20770f74d2c1SSatish Balay /*@
207849a6ff4bSBarry Smith    MatDenseGetLDA - gets the leading dimension of the array returned from MatDenseGetArray()
207949a6ff4bSBarry Smith 
2080ad16ce7aSStefano Zampini    Not collective
208149a6ff4bSBarry Smith 
208249a6ff4bSBarry Smith    Input Parameter:
208349a6ff4bSBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
208449a6ff4bSBarry Smith 
208549a6ff4bSBarry Smith    Output Parameter:
208649a6ff4bSBarry Smith .   lda - the leading dimension
208749a6ff4bSBarry Smith 
208849a6ff4bSBarry Smith    Level: intermediate
208949a6ff4bSBarry Smith 
2090ad16ce7aSStefano Zampini .seealso: MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseSetLDA()
209149a6ff4bSBarry Smith @*/
209249a6ff4bSBarry Smith PetscErrorCode  MatDenseGetLDA(Mat A,PetscInt *lda)
209349a6ff4bSBarry Smith {
209449a6ff4bSBarry Smith   PetscFunctionBegin;
2095d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2096dadcf809SJacob Faibussowitsch   PetscValidIntPointer(lda,2);
209775f6d85dSStefano Zampini   MatCheckPreallocated(A,1);
2098cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetLDA_C",(Mat,PetscInt*),(A,lda));
209949a6ff4bSBarry Smith   PetscFunctionReturn(0);
210049a6ff4bSBarry Smith }
210149a6ff4bSBarry Smith 
21020f74d2c1SSatish Balay /*@
2103ad16ce7aSStefano Zampini    MatDenseSetLDA - Sets the leading dimension of the array used by the dense matrix
2104ad16ce7aSStefano Zampini 
2105ad16ce7aSStefano Zampini    Not collective
2106ad16ce7aSStefano Zampini 
2107d8d19677SJose E. Roman    Input Parameters:
2108ad16ce7aSStefano Zampini +  mat - a MATSEQDENSE or MATMPIDENSE matrix
2109ad16ce7aSStefano Zampini -  lda - the leading dimension
2110ad16ce7aSStefano Zampini 
2111ad16ce7aSStefano Zampini    Level: intermediate
2112ad16ce7aSStefano Zampini 
2113ad16ce7aSStefano Zampini .seealso: MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseGetLDA()
2114ad16ce7aSStefano Zampini @*/
2115ad16ce7aSStefano Zampini PetscErrorCode  MatDenseSetLDA(Mat A,PetscInt lda)
2116ad16ce7aSStefano Zampini {
2117ad16ce7aSStefano Zampini   PetscFunctionBegin;
2118ad16ce7aSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2119cac4c232SBarry Smith   PetscTryMethod(A,"MatDenseSetLDA_C",(Mat,PetscInt),(A,lda));
2120ad16ce7aSStefano Zampini   PetscFunctionReturn(0);
2121ad16ce7aSStefano Zampini }
2122ad16ce7aSStefano Zampini 
2123ad16ce7aSStefano Zampini /*@C
21246947451fSStefano Zampini    MatDenseGetArray - gives read-write access to the array where the data for a dense matrix is stored
212573a71a0fSBarry Smith 
21268572280aSBarry Smith    Logically Collective on Mat
212773a71a0fSBarry Smith 
212873a71a0fSBarry Smith    Input Parameter:
21296947451fSStefano Zampini .  mat - a dense matrix
213073a71a0fSBarry Smith 
213173a71a0fSBarry Smith    Output Parameter:
213273a71a0fSBarry Smith .   array - pointer to the data
213373a71a0fSBarry Smith 
213473a71a0fSBarry Smith    Level: intermediate
213573a71a0fSBarry Smith 
21366947451fSStefano Zampini .seealso: MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
213773a71a0fSBarry Smith @*/
21388c778c55SBarry Smith PetscErrorCode  MatDenseGetArray(Mat A,PetscScalar **array)
213973a71a0fSBarry Smith {
214073a71a0fSBarry Smith   PetscFunctionBegin;
2141d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2142d5ea218eSStefano Zampini   PetscValidPointer(array,2);
2143cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetArray_C",(Mat,PetscScalar**),(A,array));
214473a71a0fSBarry Smith   PetscFunctionReturn(0);
214573a71a0fSBarry Smith }
214673a71a0fSBarry Smith 
2147dec5eb66SMatthew G Knepley /*@C
2148579dbff0SBarry Smith    MatDenseRestoreArray - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
214973a71a0fSBarry Smith 
21508572280aSBarry Smith    Logically Collective on Mat
21518572280aSBarry Smith 
21528572280aSBarry Smith    Input Parameters:
21536947451fSStefano Zampini +  mat - a dense matrix
2154a2b725a8SWilliam Gropp -  array - pointer to the data
21558572280aSBarry Smith 
21568572280aSBarry Smith    Level: intermediate
21578572280aSBarry Smith 
21586947451fSStefano Zampini .seealso: MatDenseGetArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
21598572280aSBarry Smith @*/
21608572280aSBarry Smith PetscErrorCode  MatDenseRestoreArray(Mat A,PetscScalar **array)
21618572280aSBarry Smith {
21628572280aSBarry Smith   PetscFunctionBegin;
2163d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2164d5ea218eSStefano Zampini   PetscValidPointer(array,2);
2165cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreArray_C",(Mat,PetscScalar**),(A,array));
21669566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)A));
2167637a0070SStefano Zampini #if defined(PETSC_HAVE_CUDA)
2168637a0070SStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
2169637a0070SStefano Zampini #endif
21708572280aSBarry Smith   PetscFunctionReturn(0);
21718572280aSBarry Smith }
21728572280aSBarry Smith 
21738572280aSBarry Smith /*@C
21746947451fSStefano Zampini    MatDenseGetArrayRead - gives read-only access to the array where the data for a dense matrix is stored
21758572280aSBarry Smith 
21768572280aSBarry Smith    Not Collective
21778572280aSBarry Smith 
21788572280aSBarry Smith    Input Parameter:
21796947451fSStefano Zampini .  mat - a dense matrix
21808572280aSBarry Smith 
21818572280aSBarry Smith    Output Parameter:
21828572280aSBarry Smith .   array - pointer to the data
21838572280aSBarry Smith 
21848572280aSBarry Smith    Level: intermediate
21858572280aSBarry Smith 
21866947451fSStefano Zampini .seealso: MatDenseRestoreArrayRead(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
21878572280aSBarry Smith @*/
21888572280aSBarry Smith PetscErrorCode  MatDenseGetArrayRead(Mat A,const PetscScalar **array)
21898572280aSBarry Smith {
21908572280aSBarry Smith   PetscFunctionBegin;
2191d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2192d5ea218eSStefano Zampini   PetscValidPointer(array,2);
2193cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetArrayRead_C",(Mat,const PetscScalar**),(A,array));
21948572280aSBarry Smith   PetscFunctionReturn(0);
21958572280aSBarry Smith }
21968572280aSBarry Smith 
21978572280aSBarry Smith /*@C
21986947451fSStefano Zampini    MatDenseRestoreArrayRead - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArrayRead()
21998572280aSBarry Smith 
220073a71a0fSBarry Smith    Not Collective
220173a71a0fSBarry Smith 
220273a71a0fSBarry Smith    Input Parameters:
22036947451fSStefano Zampini +  mat - a dense matrix
2204a2b725a8SWilliam Gropp -  array - pointer to the data
220573a71a0fSBarry Smith 
220673a71a0fSBarry Smith    Level: intermediate
220773a71a0fSBarry Smith 
22086947451fSStefano Zampini .seealso: MatDenseGetArrayRead(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayWrite(), MatDenseRestoreArrayWrite()
220973a71a0fSBarry Smith @*/
22108572280aSBarry Smith PetscErrorCode  MatDenseRestoreArrayRead(Mat A,const PetscScalar **array)
221173a71a0fSBarry Smith {
221273a71a0fSBarry Smith   PetscFunctionBegin;
2213d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2214d5ea218eSStefano Zampini   PetscValidPointer(array,2);
2215cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreArrayRead_C",(Mat,const PetscScalar**),(A,array));
221673a71a0fSBarry Smith   PetscFunctionReturn(0);
221773a71a0fSBarry Smith }
221873a71a0fSBarry Smith 
22196947451fSStefano Zampini /*@C
22206947451fSStefano Zampini    MatDenseGetArrayWrite - gives write-only access to the array where the data for a dense matrix is stored
22216947451fSStefano Zampini 
22226947451fSStefano Zampini    Not Collective
22236947451fSStefano Zampini 
22246947451fSStefano Zampini    Input Parameter:
22256947451fSStefano Zampini .  mat - a dense matrix
22266947451fSStefano Zampini 
22276947451fSStefano Zampini    Output Parameter:
22286947451fSStefano Zampini .   array - pointer to the data
22296947451fSStefano Zampini 
22306947451fSStefano Zampini    Level: intermediate
22316947451fSStefano Zampini 
22326947451fSStefano Zampini .seealso: MatDenseRestoreArrayWrite(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
22336947451fSStefano Zampini @*/
22346947451fSStefano Zampini PetscErrorCode  MatDenseGetArrayWrite(Mat A,PetscScalar **array)
22356947451fSStefano Zampini {
22366947451fSStefano Zampini   PetscFunctionBegin;
2237d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2238d5ea218eSStefano Zampini   PetscValidPointer(array,2);
2239cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetArrayWrite_C",(Mat,PetscScalar**),(A,array));
22406947451fSStefano Zampini   PetscFunctionReturn(0);
22416947451fSStefano Zampini }
22426947451fSStefano Zampini 
22436947451fSStefano Zampini /*@C
22446947451fSStefano Zampini    MatDenseRestoreArrayWrite - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArrayWrite()
22456947451fSStefano Zampini 
22466947451fSStefano Zampini    Not Collective
22476947451fSStefano Zampini 
22486947451fSStefano Zampini    Input Parameters:
22496947451fSStefano Zampini +  mat - a dense matrix
22506947451fSStefano Zampini -  array - pointer to the data
22516947451fSStefano Zampini 
22526947451fSStefano Zampini    Level: intermediate
22536947451fSStefano Zampini 
22546947451fSStefano Zampini .seealso: MatDenseGetArrayWrite(), MatDenseGetArray(), MatDenseRestoreArray(), MatDenseGetArrayRead(), MatDenseRestoreArrayRead()
22556947451fSStefano Zampini @*/
22566947451fSStefano Zampini PetscErrorCode  MatDenseRestoreArrayWrite(Mat A,PetscScalar **array)
22576947451fSStefano Zampini {
22586947451fSStefano Zampini   PetscFunctionBegin;
2259d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2260d5ea218eSStefano Zampini   PetscValidPointer(array,2);
2261cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreArrayWrite_C",(Mat,PetscScalar**),(A,array));
22629566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)A));
22636947451fSStefano Zampini #if defined(PETSC_HAVE_CUDA)
22646947451fSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
22656947451fSStefano Zampini #endif
22666947451fSStefano Zampini   PetscFunctionReturn(0);
22676947451fSStefano Zampini }
22686947451fSStefano Zampini 
2269023c16fcSToby Isaac static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,MatReuse scall,Mat *B)
22700754003eSLois Curfman McInnes {
2271c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
2272bf5a80bcSToby Isaac   PetscInt       i,j,nrows,ncols,ldb;
22735d0c19d7SBarry Smith   const PetscInt *irow,*icol;
227487828ca2SBarry Smith   PetscScalar    *av,*bv,*v = mat->v;
22750754003eSLois Curfman McInnes   Mat            newmat;
22760754003eSLois Curfman McInnes 
22773a40ed3dSBarry Smith   PetscFunctionBegin;
22789566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(isrow,&irow));
22799566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(iscol,&icol));
22809566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(isrow,&nrows));
22819566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(iscol,&ncols));
22820754003eSLois Curfman McInnes 
2283182d2002SSatish Balay   /* Check submatrixcall */
2284182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
228513f74950SBarry Smith     PetscInt n_cols,n_rows;
22869566063dSJacob Faibussowitsch     PetscCall(MatGetSize(*B,&n_rows,&n_cols));
228721a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
2288f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
22899566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(*B,nrows,ncols,nrows,ncols));
229021a2c019SBarry Smith     }
2291182d2002SSatish Balay     newmat = *B;
2292182d2002SSatish Balay   } else {
22930754003eSLois Curfman McInnes     /* Create and fill new matrix */
22949566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&newmat));
22959566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(newmat,nrows,ncols,nrows,ncols));
22969566063dSJacob Faibussowitsch     PetscCall(MatSetType(newmat,((PetscObject)A)->type_name));
22979566063dSJacob Faibussowitsch     PetscCall(MatSeqDenseSetPreallocation(newmat,NULL));
2298182d2002SSatish Balay   }
2299182d2002SSatish Balay 
2300182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
23019566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(newmat,&bv));
23029566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(newmat,&ldb));
2303182d2002SSatish Balay   for (i=0; i<ncols; i++) {
23046de62eeeSBarry Smith     av = v + mat->lda*icol[i];
2305ca15aa20SStefano Zampini     for (j=0; j<nrows; j++) bv[j] = av[irow[j]];
2306bf5a80bcSToby Isaac     bv += ldb;
23070754003eSLois Curfman McInnes   }
23089566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(newmat,&bv));
2309182d2002SSatish Balay 
2310182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
23119566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY));
23129566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY));
23130754003eSLois Curfman McInnes 
23140754003eSLois Curfman McInnes   /* Free work space */
23159566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(isrow,&irow));
23169566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(iscol,&icol));
2317182d2002SSatish Balay   *B   = newmat;
23183a40ed3dSBarry Smith   PetscFunctionReturn(0);
23190754003eSLois Curfman McInnes }
23200754003eSLois Curfman McInnes 
23217dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2322905e6a2fSBarry Smith {
232313f74950SBarry Smith   PetscInt       i;
2324905e6a2fSBarry Smith 
23253a40ed3dSBarry Smith   PetscFunctionBegin;
2326905e6a2fSBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
23279566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1(n,B));
2328905e6a2fSBarry Smith   }
2329905e6a2fSBarry Smith 
2330905e6a2fSBarry Smith   for (i=0; i<n; i++) {
23319566063dSJacob Faibussowitsch     PetscCall(MatCreateSubMatrix_SeqDense(A,irow[i],icol[i],scall,&(*B)[i]));
2332905e6a2fSBarry Smith   }
23333a40ed3dSBarry Smith   PetscFunctionReturn(0);
2334905e6a2fSBarry Smith }
2335905e6a2fSBarry Smith 
2336e0877f53SBarry Smith static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat,MatAssemblyType mode)
2337c0aa2d19SHong Zhang {
2338c0aa2d19SHong Zhang   PetscFunctionBegin;
2339c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2340c0aa2d19SHong Zhang }
2341c0aa2d19SHong Zhang 
2342e0877f53SBarry Smith static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat,MatAssemblyType mode)
2343c0aa2d19SHong Zhang {
2344c0aa2d19SHong Zhang   PetscFunctionBegin;
2345c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2346c0aa2d19SHong Zhang }
2347c0aa2d19SHong Zhang 
2348a76f77c3SStefano Zampini PetscErrorCode MatCopy_SeqDense(Mat A,Mat B,MatStructure str)
23494b0e389bSBarry Smith {
23504b0e389bSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data,*b = (Mat_SeqDense*)B->data;
2351ca15aa20SStefano Zampini   const PetscScalar *va;
2352ca15aa20SStefano Zampini   PetscScalar       *vb;
2353d0f46423SBarry Smith   PetscInt          lda1=a->lda,lda2=b->lda, m=A->rmap->n,n=A->cmap->n, j;
23543a40ed3dSBarry Smith 
23553a40ed3dSBarry Smith   PetscFunctionBegin;
235633f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
235733f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
23589566063dSJacob Faibussowitsch     PetscCall(MatCopy_Basic(A,B,str));
23593a40ed3dSBarry Smith     PetscFunctionReturn(0);
23603a40ed3dSBarry Smith   }
23612c71b3e2SJacob Faibussowitsch   PetscCheckFalse(m != B->rmap->n || n != B->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"size(B) != size(A)");
23629566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&va));
23639566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(B,&vb));
2364a5ce6ee0Svictorle   if (lda1>m || lda2>m) {
23650dbb7854Svictorle     for (j=0; j<n; j++) {
23669566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(vb+j*lda2,va+j*lda1,m));
2367a5ce6ee0Svictorle     }
2368a5ce6ee0Svictorle   } else {
23699566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(vb,va,A->rmap->n*A->cmap->n));
2370a5ce6ee0Svictorle   }
23719566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(B,&vb));
23729566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&va));
23739566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY));
23749566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY));
2375273d9f13SBarry Smith   PetscFunctionReturn(0);
2376273d9f13SBarry Smith }
2377273d9f13SBarry Smith 
237875f6d85dSStefano Zampini PetscErrorCode MatSetUp_SeqDense(Mat A)
2379273d9f13SBarry Smith {
2380273d9f13SBarry Smith   PetscFunctionBegin;
23819566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(A->rmap));
23829566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(A->cmap));
238318992e5dSStefano Zampini   if (!A->preallocated) {
23849566063dSJacob Faibussowitsch     PetscCall(MatSeqDenseSetPreallocation(A,NULL));
238518992e5dSStefano Zampini   }
23863a40ed3dSBarry Smith   PetscFunctionReturn(0);
23874b0e389bSBarry Smith }
23884b0e389bSBarry Smith 
2389ba337c44SJed Brown static PetscErrorCode MatConjugate_SeqDense(Mat A)
2390ba337c44SJed Brown {
23914396437dSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense *) A->data;
2392*06c5243aSJose E. Roman   PetscInt       i,j;
23934396437dSToby Isaac   PetscInt       min = PetscMin(A->rmap->n,A->cmap->n);
2394ca15aa20SStefano Zampini   PetscScalar    *aa;
2395ba337c44SJed Brown 
2396ba337c44SJed Brown   PetscFunctionBegin;
23979566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&aa));
2398*06c5243aSJose E. Roman   for (j=0; j<A->cmap->n; j++) {
2399*06c5243aSJose E. Roman     for (i=0; i<A->rmap->n; i++) aa[i+j*mat->lda] = PetscConj(aa[i+j*mat->lda]);
2400*06c5243aSJose E. Roman   }
24019566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&aa));
24024396437dSToby Isaac   if (mat->tau) for (i = 0; i < min; i++) mat->tau[i] = PetscConj(mat->tau[i]);
2403ba337c44SJed Brown   PetscFunctionReturn(0);
2404ba337c44SJed Brown }
2405ba337c44SJed Brown 
2406ba337c44SJed Brown static PetscErrorCode MatRealPart_SeqDense(Mat A)
2407ba337c44SJed Brown {
2408*06c5243aSJose E. Roman   Mat_SeqDense   *mat = (Mat_SeqDense *) A->data;
2409*06c5243aSJose E. Roman   PetscInt       i,j;
2410ca15aa20SStefano Zampini   PetscScalar    *aa;
2411ba337c44SJed Brown 
2412ba337c44SJed Brown   PetscFunctionBegin;
24139566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&aa));
2414*06c5243aSJose E. Roman   for (j=0; j<A->cmap->n; j++) {
2415*06c5243aSJose E. Roman     for (i=0; i<A->rmap->n; i++) aa[i+j*mat->lda] = PetscRealPart(aa[i+j*mat->lda]);
2416*06c5243aSJose E. Roman   }
24179566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&aa));
2418ba337c44SJed Brown   PetscFunctionReturn(0);
2419ba337c44SJed Brown }
2420ba337c44SJed Brown 
2421ba337c44SJed Brown static PetscErrorCode MatImaginaryPart_SeqDense(Mat A)
2422ba337c44SJed Brown {
2423*06c5243aSJose E. Roman   Mat_SeqDense   *mat = (Mat_SeqDense *) A->data;
2424*06c5243aSJose E. Roman   PetscInt       i,j;
2425ca15aa20SStefano Zampini   PetscScalar    *aa;
2426ba337c44SJed Brown 
2427ba337c44SJed Brown   PetscFunctionBegin;
24289566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&aa));
2429*06c5243aSJose E. Roman   for (j=0; j<A->cmap->n; j++) {
2430*06c5243aSJose E. Roman     for (i=0; i<A->rmap->n; i++) aa[i+j*mat->lda] = PetscImaginaryPart(aa[i+j*mat->lda]);
2431*06c5243aSJose E. Roman   }
24329566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&aa));
2433ba337c44SJed Brown   PetscFunctionReturn(0);
2434ba337c44SJed Brown }
2435284134d9SBarry Smith 
2436a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/
24374222ddf1SHong Zhang PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
2438a9fe9ddaSSatish Balay {
2439d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
24407a3c3d58SStefano Zampini   PetscBool      cisdense;
2441a9fe9ddaSSatish Balay 
2442ee16a9a1SHong Zhang   PetscFunctionBegin;
24439566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C,m,n,m,n));
24449566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,""));
24457a3c3d58SStefano Zampini   if (!cisdense) {
24467a3c3d58SStefano Zampini     PetscBool flg;
24477a3c3d58SStefano Zampini 
24489566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg));
24499566063dSJacob Faibussowitsch     PetscCall(MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE));
24507a3c3d58SStefano Zampini   }
24519566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
2452ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2453ee16a9a1SHong Zhang }
2454a9fe9ddaSSatish Balay 
2455a9fe9ddaSSatish Balay PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2456a9fe9ddaSSatish Balay {
24576718818eSStefano Zampini   Mat_SeqDense       *a=(Mat_SeqDense*)A->data,*b=(Mat_SeqDense*)B->data,*c=(Mat_SeqDense*)C->data;
24580805154bSBarry Smith   PetscBLASInt       m,n,k;
2459ca15aa20SStefano Zampini   const PetscScalar *av,*bv;
2460ca15aa20SStefano Zampini   PetscScalar       *cv;
2461a9fe9ddaSSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
2462a9fe9ddaSSatish Balay 
2463a9fe9ddaSSatish Balay   PetscFunctionBegin;
24649566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n,&m));
24659566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n,&n));
24669566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&k));
246749d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
24689566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&av));
24699566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B,&bv));
24709566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C,&cv));
2471ca15aa20SStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
24729566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1)));
24739566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&av));
24749566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B,&bv));
24759566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C,&cv));
2476a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2477a9fe9ddaSSatish Balay }
2478a9fe9ddaSSatish Balay 
24794222ddf1SHong Zhang PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
248069f65d41SStefano Zampini {
248169f65d41SStefano Zampini   PetscInt       m=A->rmap->n,n=B->rmap->n;
24827a3c3d58SStefano Zampini   PetscBool      cisdense;
248369f65d41SStefano Zampini 
248469f65d41SStefano Zampini   PetscFunctionBegin;
24859566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C,m,n,m,n));
24869566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,""));
24877a3c3d58SStefano Zampini   if (!cisdense) {
24887a3c3d58SStefano Zampini     PetscBool flg;
24897a3c3d58SStefano Zampini 
24909566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg));
24919566063dSJacob Faibussowitsch     PetscCall(MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE));
24927a3c3d58SStefano Zampini   }
24939566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
249469f65d41SStefano Zampini   PetscFunctionReturn(0);
249569f65d41SStefano Zampini }
249669f65d41SStefano Zampini 
249769f65d41SStefano Zampini PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
249869f65d41SStefano Zampini {
249969f65d41SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
250069f65d41SStefano Zampini   Mat_SeqDense      *b = (Mat_SeqDense*)B->data;
250169f65d41SStefano Zampini   Mat_SeqDense      *c = (Mat_SeqDense*)C->data;
25026718818eSStefano Zampini   const PetscScalar *av,*bv;
25036718818eSStefano Zampini   PetscScalar       *cv;
250469f65d41SStefano Zampini   PetscBLASInt      m,n,k;
250569f65d41SStefano Zampini   PetscScalar       _DOne=1.0,_DZero=0.0;
250669f65d41SStefano Zampini 
250769f65d41SStefano Zampini   PetscFunctionBegin;
25089566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n,&m));
25099566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n,&n));
25109566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&k));
251149d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
25129566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&av));
25139566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B,&bv));
25149566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C,&cv));
25156718818eSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","T",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
25169566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&av));
25179566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B,&bv));
25189566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C,&cv));
25199566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1)));
252069f65d41SStefano Zampini   PetscFunctionReturn(0);
252169f65d41SStefano Zampini }
252269f65d41SStefano Zampini 
25234222ddf1SHong Zhang PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
2524a9fe9ddaSSatish Balay {
2525d0f46423SBarry Smith   PetscInt       m=A->cmap->n,n=B->cmap->n;
25267a3c3d58SStefano Zampini   PetscBool      cisdense;
2527a9fe9ddaSSatish Balay 
2528ee16a9a1SHong Zhang   PetscFunctionBegin;
25299566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C,m,n,m,n));
25309566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,""));
25317a3c3d58SStefano Zampini   if (!cisdense) {
25327a3c3d58SStefano Zampini     PetscBool flg;
25337a3c3d58SStefano Zampini 
25349566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg));
25359566063dSJacob Faibussowitsch     PetscCall(MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE));
25367a3c3d58SStefano Zampini   }
25379566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
2538ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2539ee16a9a1SHong Zhang }
2540a9fe9ddaSSatish Balay 
254175648e8dSHong Zhang PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2542a9fe9ddaSSatish Balay {
2543a9fe9ddaSSatish Balay   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2544a9fe9ddaSSatish Balay   Mat_SeqDense      *b = (Mat_SeqDense*)B->data;
2545a9fe9ddaSSatish Balay   Mat_SeqDense      *c = (Mat_SeqDense*)C->data;
25466718818eSStefano Zampini   const PetscScalar *av,*bv;
25476718818eSStefano Zampini   PetscScalar       *cv;
25480805154bSBarry Smith   PetscBLASInt      m,n,k;
2549a9fe9ddaSSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
2550a9fe9ddaSSatish Balay 
2551a9fe9ddaSSatish Balay   PetscFunctionBegin;
25529566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n,&m));
25539566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n,&n));
25549566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&k));
255549d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
25569566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&av));
25579566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B,&bv));
25589566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C,&cv));
25596718818eSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
25609566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&av));
25619566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B,&bv));
25629566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C,&cv));
25639566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1)));
2564a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2565a9fe9ddaSSatish Balay }
2566985db425SBarry Smith 
25674222ddf1SHong Zhang /* ----------------------------------------------- */
25684222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C)
25694222ddf1SHong Zhang {
25704222ddf1SHong Zhang   PetscFunctionBegin;
25714222ddf1SHong Zhang   C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense;
25724222ddf1SHong Zhang   C->ops->productsymbolic = MatProductSymbolic_AB;
25734222ddf1SHong Zhang   PetscFunctionReturn(0);
25744222ddf1SHong Zhang }
25754222ddf1SHong Zhang 
25764222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C)
25774222ddf1SHong Zhang {
25784222ddf1SHong Zhang   PetscFunctionBegin;
25794222ddf1SHong Zhang   C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense;
25804222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_AtB;
25814222ddf1SHong Zhang   PetscFunctionReturn(0);
25824222ddf1SHong Zhang }
25834222ddf1SHong Zhang 
25844222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C)
25854222ddf1SHong Zhang {
25864222ddf1SHong Zhang   PetscFunctionBegin;
25874222ddf1SHong Zhang   C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense;
25884222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_ABt;
25894222ddf1SHong Zhang   PetscFunctionReturn(0);
25904222ddf1SHong Zhang }
25914222ddf1SHong Zhang 
25924222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C)
25934222ddf1SHong Zhang {
25944222ddf1SHong Zhang   Mat_Product    *product = C->product;
25954222ddf1SHong Zhang 
25964222ddf1SHong Zhang   PetscFunctionBegin;
25974222ddf1SHong Zhang   switch (product->type) {
25984222ddf1SHong Zhang   case MATPRODUCT_AB:
25999566063dSJacob Faibussowitsch     PetscCall(MatProductSetFromOptions_SeqDense_AB(C));
26004222ddf1SHong Zhang     break;
26014222ddf1SHong Zhang   case MATPRODUCT_AtB:
26029566063dSJacob Faibussowitsch     PetscCall(MatProductSetFromOptions_SeqDense_AtB(C));
26034222ddf1SHong Zhang     break;
26044222ddf1SHong Zhang   case MATPRODUCT_ABt:
26059566063dSJacob Faibussowitsch     PetscCall(MatProductSetFromOptions_SeqDense_ABt(C));
26064222ddf1SHong Zhang     break;
26076718818eSStefano Zampini   default:
26084222ddf1SHong Zhang     break;
26094222ddf1SHong Zhang   }
26104222ddf1SHong Zhang   PetscFunctionReturn(0);
26114222ddf1SHong Zhang }
26124222ddf1SHong Zhang /* ----------------------------------------------- */
26134222ddf1SHong Zhang 
2614e0877f53SBarry Smith static PetscErrorCode MatGetRowMax_SeqDense(Mat A,Vec v,PetscInt idx[])
2615985db425SBarry Smith {
2616985db425SBarry Smith   Mat_SeqDense       *a = (Mat_SeqDense*)A->data;
2617d0f46423SBarry Smith   PetscInt           i,j,m = A->rmap->n,n = A->cmap->n,p;
2618985db425SBarry Smith   PetscScalar        *x;
2619ca15aa20SStefano Zampini   const PetscScalar *aa;
2620985db425SBarry Smith 
2621985db425SBarry Smith   PetscFunctionBegin;
262228b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
26239566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v,&x));
26249566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v,&p));
26259566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&aa));
26262c71b3e2SJacob Faibussowitsch   PetscCheckFalse(p != A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2627985db425SBarry Smith   for (i=0; i<m; i++) {
2628985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2629985db425SBarry Smith     for (j=1; j<n; j++) {
2630ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) < PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2631985db425SBarry Smith     }
2632985db425SBarry Smith   }
26339566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&aa));
26349566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v,&x));
2635985db425SBarry Smith   PetscFunctionReturn(0);
2636985db425SBarry Smith }
2637985db425SBarry Smith 
2638e0877f53SBarry Smith static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A,Vec v,PetscInt idx[])
2639985db425SBarry Smith {
2640985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2641d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2642985db425SBarry Smith   PetscScalar       *x;
2643985db425SBarry Smith   PetscReal         atmp;
2644ca15aa20SStefano Zampini   const PetscScalar *aa;
2645985db425SBarry Smith 
2646985db425SBarry Smith   PetscFunctionBegin;
264728b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
26489566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v,&x));
26499566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v,&p));
26509566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&aa));
26512c71b3e2SJacob Faibussowitsch   PetscCheckFalse(p != A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2652985db425SBarry Smith   for (i=0; i<m; i++) {
26539189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
2654985db425SBarry Smith     for (j=1; j<n; j++) {
2655ca15aa20SStefano Zampini       atmp = PetscAbsScalar(aa[i+a->lda*j]);
2656985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = j;}
2657985db425SBarry Smith     }
2658985db425SBarry Smith   }
26599566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&aa));
26609566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v,&x));
2661985db425SBarry Smith   PetscFunctionReturn(0);
2662985db425SBarry Smith }
2663985db425SBarry Smith 
2664e0877f53SBarry Smith static PetscErrorCode MatGetRowMin_SeqDense(Mat A,Vec v,PetscInt idx[])
2665985db425SBarry Smith {
2666985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2667d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2668985db425SBarry Smith   PetscScalar       *x;
2669ca15aa20SStefano Zampini   const PetscScalar *aa;
2670985db425SBarry Smith 
2671985db425SBarry Smith   PetscFunctionBegin;
267228b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
26739566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&aa));
26749566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v,&x));
26759566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v,&p));
26762c71b3e2SJacob Faibussowitsch   PetscCheckFalse(p != A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2677985db425SBarry Smith   for (i=0; i<m; i++) {
2678985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2679985db425SBarry Smith     for (j=1; j<n; j++) {
2680ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) > PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2681985db425SBarry Smith     }
2682985db425SBarry Smith   }
26839566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v,&x));
26849566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&aa));
2685985db425SBarry Smith   PetscFunctionReturn(0);
2686985db425SBarry Smith }
2687985db425SBarry Smith 
2688637a0070SStefano Zampini PetscErrorCode MatGetColumnVector_SeqDense(Mat A,Vec v,PetscInt col)
26898d0534beSBarry Smith {
26908d0534beSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
26918d0534beSBarry Smith   PetscScalar       *x;
2692ca15aa20SStefano Zampini   const PetscScalar *aa;
26938d0534beSBarry Smith 
26948d0534beSBarry Smith   PetscFunctionBegin;
269528b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
26969566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&aa));
26979566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v,&x));
26989566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(x,aa+col*a->lda,A->rmap->n));
26999566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v,&x));
27009566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&aa));
27018d0534beSBarry Smith   PetscFunctionReturn(0);
27028d0534beSBarry Smith }
27038d0534beSBarry Smith 
2704857cbf51SRichard Tran Mills PETSC_INTERN PetscErrorCode MatGetColumnReductions_SeqDense(Mat A,PetscInt type,PetscReal *reductions)
27050716a85fSBarry Smith {
27060716a85fSBarry Smith   PetscInt          i,j,m,n;
27071683a169SBarry Smith   const PetscScalar *a;
27080716a85fSBarry Smith 
27090716a85fSBarry Smith   PetscFunctionBegin;
27109566063dSJacob Faibussowitsch   PetscCall(MatGetSize(A,&m,&n));
27119566063dSJacob Faibussowitsch   PetscCall(PetscArrayzero(reductions,n));
27129566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&a));
2713857cbf51SRichard Tran Mills   if (type == NORM_2) {
27140716a85fSBarry Smith     for (i=0; i<n; i++) {
27150716a85fSBarry Smith       for (j=0; j<m; j++) {
2716a873a8cdSSam Reynolds         reductions[i] += PetscAbsScalar(a[j]*a[j]);
27170716a85fSBarry Smith       }
27180716a85fSBarry Smith       a += m;
27190716a85fSBarry Smith     }
2720857cbf51SRichard Tran Mills   } else if (type == NORM_1) {
27210716a85fSBarry Smith     for (i=0; i<n; i++) {
27220716a85fSBarry Smith       for (j=0; j<m; j++) {
2723a873a8cdSSam Reynolds         reductions[i] += PetscAbsScalar(a[j]);
27240716a85fSBarry Smith       }
27250716a85fSBarry Smith       a += m;
27260716a85fSBarry Smith     }
2727857cbf51SRichard Tran Mills   } else if (type == NORM_INFINITY) {
27280716a85fSBarry Smith     for (i=0; i<n; i++) {
27290716a85fSBarry Smith       for (j=0; j<m; j++) {
2730a873a8cdSSam Reynolds         reductions[i] = PetscMax(PetscAbsScalar(a[j]),reductions[i]);
27310716a85fSBarry Smith       }
27320716a85fSBarry Smith       a += m;
27330716a85fSBarry Smith     }
2734857cbf51SRichard Tran Mills   } else if (type == REDUCTION_SUM_REALPART || type == REDUCTION_MEAN_REALPART) {
2735a873a8cdSSam Reynolds     for (i=0; i<n; i++) {
2736a873a8cdSSam Reynolds       for (j=0; j<m; j++) {
2737857cbf51SRichard Tran Mills         reductions[i] += PetscRealPart(a[j]);
2738a873a8cdSSam Reynolds       }
2739a873a8cdSSam Reynolds       a += m;
2740a873a8cdSSam Reynolds     }
2741857cbf51SRichard Tran Mills   } else if (type == REDUCTION_SUM_IMAGINARYPART || type == REDUCTION_MEAN_IMAGINARYPART) {
2742857cbf51SRichard Tran Mills     for (i=0; i<n; i++) {
2743857cbf51SRichard Tran Mills       for (j=0; j<m; j++) {
2744857cbf51SRichard Tran Mills         reductions[i] += PetscImaginaryPart(a[j]);
2745857cbf51SRichard Tran Mills       }
2746857cbf51SRichard Tran Mills       a += m;
2747857cbf51SRichard Tran Mills     }
2748857cbf51SRichard Tran Mills   } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Unknown reduction type");
27499566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&a));
2750857cbf51SRichard Tran Mills   if (type == NORM_2) {
2751a873a8cdSSam Reynolds     for (i=0; i<n; i++) reductions[i] = PetscSqrtReal(reductions[i]);
2752857cbf51SRichard Tran Mills   } else if (type == REDUCTION_MEAN_REALPART || type == REDUCTION_MEAN_IMAGINARYPART) {
2753a873a8cdSSam Reynolds     for (i=0; i<n; i++) reductions[i] /= m;
27540716a85fSBarry Smith   }
27550716a85fSBarry Smith   PetscFunctionReturn(0);
27560716a85fSBarry Smith }
27570716a85fSBarry Smith 
275873a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqDense(Mat x,PetscRandom rctx)
275973a71a0fSBarry Smith {
276073a71a0fSBarry Smith   PetscScalar    *a;
2761637a0070SStefano Zampini   PetscInt       lda,m,n,i,j;
276273a71a0fSBarry Smith 
276373a71a0fSBarry Smith   PetscFunctionBegin;
27649566063dSJacob Faibussowitsch   PetscCall(MatGetSize(x,&m,&n));
27659566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(x,&lda));
27669566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(x,&a));
2767637a0070SStefano Zampini   for (j=0; j<n; j++) {
2768637a0070SStefano Zampini     for (i=0; i<m; i++) {
27699566063dSJacob Faibussowitsch       PetscCall(PetscRandomGetValue(rctx,a+j*lda+i));
2770637a0070SStefano Zampini     }
277173a71a0fSBarry Smith   }
27729566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(x,&a));
277373a71a0fSBarry Smith   PetscFunctionReturn(0);
277473a71a0fSBarry Smith }
277573a71a0fSBarry Smith 
27763b49f96aSBarry Smith static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A,PetscBool  *missing,PetscInt *d)
27773b49f96aSBarry Smith {
27783b49f96aSBarry Smith   PetscFunctionBegin;
27793b49f96aSBarry Smith   *missing = PETSC_FALSE;
27803b49f96aSBarry Smith   PetscFunctionReturn(0);
27813b49f96aSBarry Smith }
278273a71a0fSBarry Smith 
2783ca15aa20SStefano Zampini /* vals is not const */
2784af53bab2SHong Zhang static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A,PetscInt col,PetscScalar **vals)
278586aefd0dSHong Zhang {
278686aefd0dSHong Zhang   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2787ca15aa20SStefano Zampini   PetscScalar    *v;
278886aefd0dSHong Zhang 
278986aefd0dSHong Zhang   PetscFunctionBegin;
279028b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
27919566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&v));
2792ca15aa20SStefano Zampini   *vals = v+col*a->lda;
27939566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&v));
279486aefd0dSHong Zhang   PetscFunctionReturn(0);
279586aefd0dSHong Zhang }
279686aefd0dSHong Zhang 
2797af53bab2SHong Zhang static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A,PetscScalar **vals)
279886aefd0dSHong Zhang {
279986aefd0dSHong Zhang   PetscFunctionBegin;
2800a5b23f4aSJose E. Roman   *vals = NULL; /* user cannot accidentally use the array later */
280186aefd0dSHong Zhang   PetscFunctionReturn(0);
280286aefd0dSHong Zhang }
2803abc3b08eSStefano Zampini 
2804289bc588SBarry Smith /* -------------------------------------------------------------------*/
2805a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqDense,
2806905e6a2fSBarry Smith                                         MatGetRow_SeqDense,
2807905e6a2fSBarry Smith                                         MatRestoreRow_SeqDense,
2808905e6a2fSBarry Smith                                         MatMult_SeqDense,
280997304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqDense,
28107c922b88SBarry Smith                                         MatMultTranspose_SeqDense,
28117c922b88SBarry Smith                                         MatMultTransposeAdd_SeqDense,
2812f4259b30SLisandro Dalcin                                         NULL,
2813f4259b30SLisandro Dalcin                                         NULL,
2814f4259b30SLisandro Dalcin                                         NULL,
2815f4259b30SLisandro Dalcin                                 /* 10*/ NULL,
2816905e6a2fSBarry Smith                                         MatLUFactor_SeqDense,
2817905e6a2fSBarry Smith                                         MatCholeskyFactor_SeqDense,
281841f059aeSBarry Smith                                         MatSOR_SeqDense,
2819ec8511deSBarry Smith                                         MatTranspose_SeqDense,
282097304618SKris Buschelman                                 /* 15*/ MatGetInfo_SeqDense,
2821905e6a2fSBarry Smith                                         MatEqual_SeqDense,
2822905e6a2fSBarry Smith                                         MatGetDiagonal_SeqDense,
2823905e6a2fSBarry Smith                                         MatDiagonalScale_SeqDense,
2824905e6a2fSBarry Smith                                         MatNorm_SeqDense,
2825c0aa2d19SHong Zhang                                 /* 20*/ MatAssemblyBegin_SeqDense,
2826c0aa2d19SHong Zhang                                         MatAssemblyEnd_SeqDense,
2827905e6a2fSBarry Smith                                         MatSetOption_SeqDense,
2828905e6a2fSBarry Smith                                         MatZeroEntries_SeqDense,
2829d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqDense,
2830f4259b30SLisandro Dalcin                                         NULL,
2831f4259b30SLisandro Dalcin                                         NULL,
2832f4259b30SLisandro Dalcin                                         NULL,
2833f4259b30SLisandro Dalcin                                         NULL,
28344994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqDense,
2835f4259b30SLisandro Dalcin                                         NULL,
2836f4259b30SLisandro Dalcin                                         NULL,
2837f4259b30SLisandro Dalcin                                         NULL,
2838f4259b30SLisandro Dalcin                                         NULL,
2839d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqDense,
2840f4259b30SLisandro Dalcin                                         NULL,
2841f4259b30SLisandro Dalcin                                         NULL,
2842f4259b30SLisandro Dalcin                                         NULL,
2843f4259b30SLisandro Dalcin                                         NULL,
2844d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqDense,
28457dae84e0SHong Zhang                                         MatCreateSubMatrices_SeqDense,
2846f4259b30SLisandro Dalcin                                         NULL,
28474b0e389bSBarry Smith                                         MatGetValues_SeqDense,
2848a5ae1ecdSBarry Smith                                         MatCopy_SeqDense,
2849d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqDense,
2850a5ae1ecdSBarry Smith                                         MatScale_SeqDense,
28517d68702bSBarry Smith                                         MatShift_Basic,
2852f4259b30SLisandro Dalcin                                         NULL,
28533f49a652SStefano Zampini                                         MatZeroRowsColumns_SeqDense,
285473a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqDense,
2855f4259b30SLisandro Dalcin                                         NULL,
2856f4259b30SLisandro Dalcin                                         NULL,
2857f4259b30SLisandro Dalcin                                         NULL,
2858f4259b30SLisandro Dalcin                                         NULL,
2859f4259b30SLisandro Dalcin                                 /* 54*/ NULL,
2860f4259b30SLisandro Dalcin                                         NULL,
2861f4259b30SLisandro Dalcin                                         NULL,
2862f4259b30SLisandro Dalcin                                         NULL,
2863f4259b30SLisandro Dalcin                                         NULL,
2864023c16fcSToby Isaac                                 /* 59*/ MatCreateSubMatrix_SeqDense,
2865e03a110bSBarry Smith                                         MatDestroy_SeqDense,
2866e03a110bSBarry Smith                                         MatView_SeqDense,
2867f4259b30SLisandro Dalcin                                         NULL,
2868f4259b30SLisandro Dalcin                                         NULL,
2869f4259b30SLisandro Dalcin                                 /* 64*/ NULL,
2870f4259b30SLisandro Dalcin                                         NULL,
2871f4259b30SLisandro Dalcin                                         NULL,
2872f4259b30SLisandro Dalcin                                         NULL,
2873f4259b30SLisandro Dalcin                                         NULL,
2874d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqDense,
2875f4259b30SLisandro Dalcin                                         NULL,
2876f4259b30SLisandro Dalcin                                         NULL,
2877f4259b30SLisandro Dalcin                                         NULL,
2878f4259b30SLisandro Dalcin                                         NULL,
2879f4259b30SLisandro Dalcin                                 /* 74*/ NULL,
2880f4259b30SLisandro Dalcin                                         NULL,
2881f4259b30SLisandro Dalcin                                         NULL,
2882f4259b30SLisandro Dalcin                                         NULL,
2883f4259b30SLisandro Dalcin                                         NULL,
2884f4259b30SLisandro Dalcin                                 /* 79*/ NULL,
2885f4259b30SLisandro Dalcin                                         NULL,
2886f4259b30SLisandro Dalcin                                         NULL,
2887f4259b30SLisandro Dalcin                                         NULL,
28885bba2384SShri Abhyankar                                 /* 83*/ MatLoad_SeqDense,
2889637a0070SStefano Zampini                                         MatIsSymmetric_SeqDense,
28901cbb95d3SBarry Smith                                         MatIsHermitian_SeqDense,
2891f4259b30SLisandro Dalcin                                         NULL,
2892f4259b30SLisandro Dalcin                                         NULL,
2893f4259b30SLisandro Dalcin                                         NULL,
2894f4259b30SLisandro Dalcin                                 /* 89*/ NULL,
2895f4259b30SLisandro Dalcin                                         NULL,
2896a9fe9ddaSSatish Balay                                         MatMatMultNumeric_SeqDense_SeqDense,
2897f4259b30SLisandro Dalcin                                         NULL,
2898f4259b30SLisandro Dalcin                                         NULL,
2899f4259b30SLisandro Dalcin                                 /* 94*/ NULL,
2900f4259b30SLisandro Dalcin                                         NULL,
2901f4259b30SLisandro Dalcin                                         NULL,
290269f65d41SStefano Zampini                                         MatMatTransposeMultNumeric_SeqDense_SeqDense,
2903f4259b30SLisandro Dalcin                                         NULL,
29044222ddf1SHong Zhang                                 /* 99*/ MatProductSetFromOptions_SeqDense,
2905f4259b30SLisandro Dalcin                                         NULL,
2906f4259b30SLisandro Dalcin                                         NULL,
2907ba337c44SJed Brown                                         MatConjugate_SeqDense,
2908f4259b30SLisandro Dalcin                                         NULL,
2909f4259b30SLisandro Dalcin                                 /*104*/ NULL,
2910ba337c44SJed Brown                                         MatRealPart_SeqDense,
2911ba337c44SJed Brown                                         MatImaginaryPart_SeqDense,
2912f4259b30SLisandro Dalcin                                         NULL,
2913f4259b30SLisandro Dalcin                                         NULL,
2914f4259b30SLisandro Dalcin                                 /*109*/ NULL,
2915f4259b30SLisandro Dalcin                                         NULL,
29168d0534beSBarry Smith                                         MatGetRowMin_SeqDense,
2917aabbc4fbSShri Abhyankar                                         MatGetColumnVector_SeqDense,
29183b49f96aSBarry Smith                                         MatMissingDiagonal_SeqDense,
2919f4259b30SLisandro Dalcin                                 /*114*/ NULL,
2920f4259b30SLisandro Dalcin                                         NULL,
2921f4259b30SLisandro Dalcin                                         NULL,
2922f4259b30SLisandro Dalcin                                         NULL,
2923f4259b30SLisandro Dalcin                                         NULL,
2924f4259b30SLisandro Dalcin                                 /*119*/ NULL,
2925f4259b30SLisandro Dalcin                                         NULL,
2926f4259b30SLisandro Dalcin                                         NULL,
2927f4259b30SLisandro Dalcin                                         NULL,
2928f4259b30SLisandro Dalcin                                         NULL,
2929f4259b30SLisandro Dalcin                                 /*124*/ NULL,
2930a873a8cdSSam Reynolds                                         MatGetColumnReductions_SeqDense,
2931f4259b30SLisandro Dalcin                                         NULL,
2932f4259b30SLisandro Dalcin                                         NULL,
2933f4259b30SLisandro Dalcin                                         NULL,
2934f4259b30SLisandro Dalcin                                 /*129*/ NULL,
2935f4259b30SLisandro Dalcin                                         NULL,
2936f4259b30SLisandro Dalcin                                         NULL,
293775648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqDense_SeqDense,
2938f4259b30SLisandro Dalcin                                         NULL,
2939f4259b30SLisandro Dalcin                                 /*134*/ NULL,
2940f4259b30SLisandro Dalcin                                         NULL,
2941f4259b30SLisandro Dalcin                                         NULL,
2942f4259b30SLisandro Dalcin                                         NULL,
2943f4259b30SLisandro Dalcin                                         NULL,
2944f4259b30SLisandro Dalcin                                 /*139*/ NULL,
2945f4259b30SLisandro Dalcin                                         NULL,
2946f4259b30SLisandro Dalcin                                         NULL,
2947f4259b30SLisandro Dalcin                                         NULL,
2948f4259b30SLisandro Dalcin                                         NULL,
29494222ddf1SHong Zhang                                         MatCreateMPIMatConcatenateSeqMat_SeqDense,
2950f4259b30SLisandro Dalcin                                 /*145*/ NULL,
2951f4259b30SLisandro Dalcin                                         NULL,
2952f4259b30SLisandro Dalcin                                         NULL
2953985db425SBarry Smith };
295490ace30eSBarry Smith 
29554b828684SBarry Smith /*@C
2956fafbff53SBarry Smith    MatCreateSeqDense - Creates a sequential dense matrix that
2957d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
2958d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
2959289bc588SBarry Smith 
2960d083f849SBarry Smith    Collective
2961db81eaa0SLois Curfman McInnes 
296220563c6bSBarry Smith    Input Parameters:
2963db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
29640c775827SLois Curfman McInnes .  m - number of rows
296518f449edSLois Curfman McInnes .  n - number of columns
29660298fd71SBarry Smith -  data - optional location of matrix data in column major order.  Set data=NULL for PETSc
2967dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
296820563c6bSBarry Smith 
296920563c6bSBarry Smith    Output Parameter:
297044cd7ae7SLois Curfman McInnes .  A - the matrix
297120563c6bSBarry Smith 
2972b259b22eSLois Curfman McInnes    Notes:
297318f449edSLois Curfman McInnes    The data input variable is intended primarily for Fortran programmers
297418f449edSLois Curfman McInnes    who wish to allocate their own matrix memory space.  Most users should
29750298fd71SBarry Smith    set data=NULL.
297618f449edSLois Curfman McInnes 
2977027ccd11SLois Curfman McInnes    Level: intermediate
2978027ccd11SLois Curfman McInnes 
297969b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues()
298020563c6bSBarry Smith @*/
29817087cfbeSBarry Smith PetscErrorCode  MatCreateSeqDense(MPI_Comm comm,PetscInt m,PetscInt n,PetscScalar *data,Mat *A)
2982289bc588SBarry Smith {
29833a40ed3dSBarry Smith   PetscFunctionBegin;
29849566063dSJacob Faibussowitsch   PetscCall(MatCreate(comm,A));
29859566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*A,m,n,m,n));
29869566063dSJacob Faibussowitsch   PetscCall(MatSetType(*A,MATSEQDENSE));
29879566063dSJacob Faibussowitsch   PetscCall(MatSeqDenseSetPreallocation(*A,data));
2988273d9f13SBarry Smith   PetscFunctionReturn(0);
2989273d9f13SBarry Smith }
2990273d9f13SBarry Smith 
2991273d9f13SBarry Smith /*@C
2992273d9f13SBarry Smith    MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements
2993273d9f13SBarry Smith 
2994d083f849SBarry Smith    Collective
2995273d9f13SBarry Smith 
2996273d9f13SBarry Smith    Input Parameters:
29971c4f3114SJed Brown +  B - the matrix
29980298fd71SBarry Smith -  data - the array (or NULL)
2999273d9f13SBarry Smith 
3000273d9f13SBarry Smith    Notes:
3001273d9f13SBarry Smith    The data input variable is intended primarily for Fortran programmers
3002273d9f13SBarry Smith    who wish to allocate their own matrix memory space.  Most users should
3003284134d9SBarry Smith    need not call this routine.
3004273d9f13SBarry Smith 
3005273d9f13SBarry Smith    Level: intermediate
3006273d9f13SBarry Smith 
3007ad16ce7aSStefano Zampini .seealso: MatCreate(), MatCreateDense(), MatSetValues(), MatDenseSetLDA()
3008867c911aSBarry Smith 
3009273d9f13SBarry Smith @*/
30107087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation(Mat B,PetscScalar data[])
3011273d9f13SBarry Smith {
3012a23d5eceSKris Buschelman   PetscFunctionBegin;
3013d5ea218eSStefano Zampini   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
3014cac4c232SBarry Smith   PetscTryMethod(B,"MatSeqDenseSetPreallocation_C",(Mat,PetscScalar[]),(B,data));
3015a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3016a23d5eceSKris Buschelman }
3017a23d5eceSKris Buschelman 
30187087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation_SeqDense(Mat B,PetscScalar *data)
3019a23d5eceSKris Buschelman {
3020ad16ce7aSStefano Zampini   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
3021273d9f13SBarry Smith 
3022273d9f13SBarry Smith   PetscFunctionBegin;
302328b400f6SJacob Faibussowitsch   PetscCheck(!b->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
3024273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
3025a868139aSShri Abhyankar 
30269566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(B->rmap));
30279566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(B->cmap));
302834ef9618SShri Abhyankar 
3029ad16ce7aSStefano Zampini   if (b->lda <= 0) b->lda = B->rmap->n;
303086d161a7SShri Abhyankar 
30319e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
30329566063dSJacob Faibussowitsch     if (!b->user_alloc) PetscCall(PetscFree(b->v));
30339566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1((size_t)b->lda*B->cmap->n,&b->v));
30349566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)B,b->lda*B->cmap->n*sizeof(PetscScalar)));
30352205254eSKarl Rupp 
30369e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
3037273d9f13SBarry Smith   } else { /* user-allocated storage */
30389566063dSJacob Faibussowitsch     if (!b->user_alloc) PetscCall(PetscFree(b->v));
3039273d9f13SBarry Smith     b->v          = data;
3040273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
3041273d9f13SBarry Smith   }
30420450473dSBarry Smith   B->assembled = PETSC_TRUE;
3043273d9f13SBarry Smith   PetscFunctionReturn(0);
3044273d9f13SBarry Smith }
3045273d9f13SBarry Smith 
304665b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
3047cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
30488baccfbdSHong Zhang {
3049d77f618aSHong Zhang   Mat               mat_elemental;
30501683a169SBarry Smith   const PetscScalar *array;
30511683a169SBarry Smith   PetscScalar       *v_colwise;
3052d77f618aSHong Zhang   PetscInt          M=A->rmap->N,N=A->cmap->N,i,j,k,*rows,*cols;
3053d77f618aSHong Zhang 
30548baccfbdSHong Zhang   PetscFunctionBegin;
30559566063dSJacob Faibussowitsch   PetscCall(PetscMalloc3(M*N,&v_colwise,M,&rows,N,&cols));
30569566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&array));
3057d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
3058d77f618aSHong Zhang   k = 0;
3059d77f618aSHong Zhang   for (j=0; j<N; j++) {
3060d77f618aSHong Zhang     cols[j] = j;
3061d77f618aSHong Zhang     for (i=0; i<M; i++) {
3062d77f618aSHong Zhang       v_colwise[j*M+i] = array[k++];
3063d77f618aSHong Zhang     }
3064d77f618aSHong Zhang   }
3065d77f618aSHong Zhang   for (i=0; i<M; i++) {
3066d77f618aSHong Zhang     rows[i] = i;
3067d77f618aSHong Zhang   }
30689566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&array));
3069d77f618aSHong Zhang 
30709566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental));
30719566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N));
30729566063dSJacob Faibussowitsch   PetscCall(MatSetType(mat_elemental,MATELEMENTAL));
30739566063dSJacob Faibussowitsch   PetscCall(MatSetUp(mat_elemental));
3074d77f618aSHong Zhang 
3075d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
30769566063dSJacob Faibussowitsch   PetscCall(MatSetValues(mat_elemental,M,rows,N,cols,v_colwise,ADD_VALUES));
30779566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY));
30789566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY));
30799566063dSJacob Faibussowitsch   PetscCall(PetscFree3(v_colwise,rows,cols));
3080d77f618aSHong Zhang 
3081511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
30829566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A,&mat_elemental));
3083d77f618aSHong Zhang   } else {
3084d77f618aSHong Zhang     *newmat = mat_elemental;
3085d77f618aSHong Zhang   }
30868baccfbdSHong Zhang   PetscFunctionReturn(0);
30878baccfbdSHong Zhang }
308865b80a83SHong Zhang #endif
30898baccfbdSHong Zhang 
309017359960SJose E. Roman PetscErrorCode  MatDenseSetLDA_SeqDense(Mat B,PetscInt lda)
30911b807ce4Svictorle {
30921b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense*)B->data;
30937422da62SJose E. Roman   PetscBool    data;
309421a2c019SBarry Smith 
30951b807ce4Svictorle   PetscFunctionBegin;
30967422da62SJose E. Roman   data = (PetscBool)((B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE);
30972c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!b->user_alloc && data && b->lda!=lda,PETSC_COMM_SELF,PETSC_ERR_ORDER,"LDA cannot be changed after allocation of internal storage");
30982c71b3e2SJacob Faibussowitsch   PetscCheckFalse(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);
30991b807ce4Svictorle   b->lda = lda;
31001b807ce4Svictorle   PetscFunctionReturn(0);
31011b807ce4Svictorle }
31021b807ce4Svictorle 
3103d528f656SJakub Kruzik PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat)
3104d528f656SJakub Kruzik {
3105d528f656SJakub Kruzik   PetscMPIInt    size;
3106d528f656SJakub Kruzik 
3107d528f656SJakub Kruzik   PetscFunctionBegin;
31089566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(comm,&size));
3109d528f656SJakub Kruzik   if (size == 1) {
3110d528f656SJakub Kruzik     if (scall == MAT_INITIAL_MATRIX) {
31119566063dSJacob Faibussowitsch       PetscCall(MatDuplicate(inmat,MAT_COPY_VALUES,outmat));
3112d528f656SJakub Kruzik     } else {
31139566063dSJacob Faibussowitsch       PetscCall(MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN));
3114d528f656SJakub Kruzik     }
3115d528f656SJakub Kruzik   } else {
31169566063dSJacob Faibussowitsch     PetscCall(MatCreateMPIMatConcatenateSeqMat_MPIDense(comm,inmat,n,scall,outmat));
3117d528f656SJakub Kruzik   }
3118d528f656SJakub Kruzik   PetscFunctionReturn(0);
3119d528f656SJakub Kruzik }
3120d528f656SJakub Kruzik 
31216947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A,PetscInt col,Vec *v)
31226947451fSStefano Zampini {
31236947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
31246947451fSStefano Zampini 
31256947451fSStefano Zampini   PetscFunctionBegin;
312628b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
312728b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
31286947451fSStefano Zampini   if (!a->cvec) {
31299566063dSJacob Faibussowitsch     PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec));
31309566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec));
31316947451fSStefano Zampini   }
31326947451fSStefano Zampini   a->vecinuse = col + 1;
31339566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,(PetscScalar**)&a->ptrinuse));
31349566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda));
31356947451fSStefano Zampini   *v   = a->cvec;
31366947451fSStefano Zampini   PetscFunctionReturn(0);
31376947451fSStefano Zampini }
31386947451fSStefano Zampini 
31396947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A,PetscInt col,Vec *v)
31406947451fSStefano Zampini {
31416947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
31426947451fSStefano Zampini 
31436947451fSStefano Zampini   PetscFunctionBegin;
314428b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first");
314528b400f6SJacob Faibussowitsch   PetscCheck(a->cvec,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
31466947451fSStefano Zampini   a->vecinuse = 0;
31479566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,(PetscScalar**)&a->ptrinuse));
31489566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
314975f6d85dSStefano Zampini   if (v) *v = NULL;
31506947451fSStefano Zampini   PetscFunctionReturn(0);
31516947451fSStefano Zampini }
31526947451fSStefano Zampini 
31536947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A,PetscInt col,Vec *v)
31546947451fSStefano Zampini {
31556947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
31566947451fSStefano Zampini 
31576947451fSStefano Zampini   PetscFunctionBegin;
315828b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
315928b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
31606947451fSStefano Zampini   if (!a->cvec) {
31619566063dSJacob Faibussowitsch     PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec));
31629566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec));
31636947451fSStefano Zampini   }
31646947451fSStefano Zampini   a->vecinuse = col + 1;
31659566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&a->ptrinuse));
31669566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda));
31679566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(a->cvec));
31686947451fSStefano Zampini   *v   = a->cvec;
31696947451fSStefano Zampini   PetscFunctionReturn(0);
31706947451fSStefano Zampini }
31716947451fSStefano Zampini 
31726947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A,PetscInt col,Vec *v)
31736947451fSStefano Zampini {
31746947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
31756947451fSStefano Zampini 
31766947451fSStefano Zampini   PetscFunctionBegin;
317728b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first");
317828b400f6SJacob Faibussowitsch   PetscCheck(a->cvec,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
31796947451fSStefano Zampini   a->vecinuse = 0;
31809566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&a->ptrinuse));
31819566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(a->cvec));
31829566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
318375f6d85dSStefano Zampini   if (v) *v = NULL;
31846947451fSStefano Zampini   PetscFunctionReturn(0);
31856947451fSStefano Zampini }
31866947451fSStefano Zampini 
31876947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A,PetscInt col,Vec *v)
31886947451fSStefano Zampini {
31896947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
31906947451fSStefano Zampini 
31916947451fSStefano Zampini   PetscFunctionBegin;
319228b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
319328b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
31946947451fSStefano Zampini   if (!a->cvec) {
31959566063dSJacob Faibussowitsch     PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec));
31969566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec));
31976947451fSStefano Zampini   }
31986947451fSStefano Zampini   a->vecinuse = col + 1;
31999566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(A,(PetscScalar**)&a->ptrinuse));
32009566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda));
32016947451fSStefano Zampini   *v   = a->cvec;
32026947451fSStefano Zampini   PetscFunctionReturn(0);
32036947451fSStefano Zampini }
32046947451fSStefano Zampini 
32056947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A,PetscInt col,Vec *v)
32066947451fSStefano Zampini {
32076947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32086947451fSStefano Zampini 
32096947451fSStefano Zampini   PetscFunctionBegin;
321028b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first");
321128b400f6SJacob Faibussowitsch   PetscCheck(a->cvec,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
32126947451fSStefano Zampini   a->vecinuse = 0;
32139566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(A,(PetscScalar**)&a->ptrinuse));
32149566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
321575f6d85dSStefano Zampini   if (v) *v = NULL;
32166947451fSStefano Zampini   PetscFunctionReturn(0);
32176947451fSStefano Zampini }
32186947451fSStefano Zampini 
32195ea7661aSPierre Jolivet PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A,PetscInt cbegin,PetscInt cend,Mat *v)
32205ea7661aSPierre Jolivet {
32215ea7661aSPierre Jolivet   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32225ea7661aSPierre Jolivet 
32235ea7661aSPierre Jolivet   PetscFunctionBegin;
322428b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
322528b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
32265ea7661aSPierre Jolivet   if (a->cmat && cend-cbegin != a->cmat->cmap->N) {
32279566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&a->cmat));
32285ea7661aSPierre Jolivet   }
32295ea7661aSPierre Jolivet   if (!a->cmat) {
32309566063dSJacob 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));
32319566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)A,(PetscObject)a->cmat));
32325ea7661aSPierre Jolivet   } else {
32339566063dSJacob Faibussowitsch     PetscCall(MatDensePlaceArray(a->cmat,a->v+(size_t)cbegin*a->lda));
32345ea7661aSPierre Jolivet   }
32359566063dSJacob Faibussowitsch   PetscCall(MatDenseSetLDA(a->cmat,a->lda));
32365ea7661aSPierre Jolivet   a->matinuse = cbegin + 1;
32375ea7661aSPierre Jolivet   *v = a->cmat;
323875f6d85dSStefano Zampini #if defined(PETSC_HAVE_CUDA)
323975f6d85dSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
324075f6d85dSStefano Zampini #endif
32415ea7661aSPierre Jolivet   PetscFunctionReturn(0);
32425ea7661aSPierre Jolivet }
32435ea7661aSPierre Jolivet 
32445ea7661aSPierre Jolivet PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A,Mat *v)
32455ea7661aSPierre Jolivet {
32465ea7661aSPierre Jolivet   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32475ea7661aSPierre Jolivet 
32485ea7661aSPierre Jolivet   PetscFunctionBegin;
324928b400f6SJacob Faibussowitsch   PetscCheck(a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetSubMatrix() first");
325028b400f6SJacob Faibussowitsch   PetscCheck(a->cmat,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column matrix");
32512c71b3e2SJacob Faibussowitsch   PetscCheckFalse(*v != a->cmat,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not the matrix obtained from MatDenseGetSubMatrix()");
32525ea7661aSPierre Jolivet   a->matinuse = 0;
32539566063dSJacob Faibussowitsch   PetscCall(MatDenseResetArray(a->cmat));
32545ea7661aSPierre Jolivet   *v   = NULL;
32555ea7661aSPierre Jolivet   PetscFunctionReturn(0);
32565ea7661aSPierre Jolivet }
32575ea7661aSPierre Jolivet 
32580bad9183SKris Buschelman /*MC
3259fafad747SKris Buschelman    MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices.
32600bad9183SKris Buschelman 
32610bad9183SKris Buschelman    Options Database Keys:
32620bad9183SKris Buschelman . -mat_type seqdense - sets the matrix type to "seqdense" during a call to MatSetFromOptions()
32630bad9183SKris Buschelman 
32640bad9183SKris Buschelman   Level: beginner
32650bad9183SKris Buschelman 
326689665df3SBarry Smith .seealso: MatCreateSeqDense()
326789665df3SBarry Smith 
32680bad9183SKris Buschelman M*/
3269ca15aa20SStefano Zampini PetscErrorCode MatCreate_SeqDense(Mat B)
3270273d9f13SBarry Smith {
3271273d9f13SBarry Smith   Mat_SeqDense   *b;
32727c334f02SBarry Smith   PetscMPIInt    size;
3273273d9f13SBarry Smith 
3274273d9f13SBarry Smith   PetscFunctionBegin;
32759566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)B),&size));
32762c71b3e2SJacob Faibussowitsch   PetscCheckFalse(size > 1,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
327755659b69SBarry Smith 
32789566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(B,&b));
32799566063dSJacob Faibussowitsch   PetscCall(PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps)));
328044cd7ae7SLois Curfman McInnes   B->data = (void*)b;
328118f449edSLois Curfman McInnes 
3282273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
32834e220ebcSLois Curfman McInnes 
32849566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatQRFactor_C",MatQRFactor_SeqDense));
32859566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetLDA_C",MatDenseGetLDA_SeqDense));
32869566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseSetLDA_C",MatDenseSetLDA_SeqDense));
32879566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArray_C",MatDenseGetArray_SeqDense));
32889566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArray_C",MatDenseRestoreArray_SeqDense));
32899566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDensePlaceArray_C",MatDensePlaceArray_SeqDense));
32909566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseResetArray_C",MatDenseResetArray_SeqDense));
32919566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseReplaceArray_C",MatDenseReplaceArray_SeqDense));
32929566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayRead_C",MatDenseGetArray_SeqDense));
32939566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayRead_C",MatDenseRestoreArray_SeqDense));
32949566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayWrite_C",MatDenseGetArray_SeqDense));
32959566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayWrite_C",MatDenseRestoreArray_SeqDense));
32969566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqaij_C",MatConvert_SeqDense_SeqAIJ));
32978baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
32989566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_elemental_C",MatConvert_SeqDense_Elemental));
32998baccfbdSHong Zhang #endif
3300d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
33019566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_scalapack_C",MatConvert_Dense_ScaLAPACK));
3302d24d4204SJose E. Roman #endif
33032bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
33049566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqdensecuda_C",MatConvert_SeqDense_SeqDenseCUDA));
33059566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",MatProductSetFromOptions_SeqDense));
33069566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdense_C",MatProductSetFromOptions_SeqDense));
33079566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqdensecuda_C",MatProductSetFromOptions_SeqDense));
33082bf066beSStefano Zampini #endif
33099566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatSeqDenseSetPreallocation_C",MatSeqDenseSetPreallocation_SeqDense));
33109566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqdense_C",MatProductSetFromOptions_SeqAIJ_SeqDense));
33119566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqdense_C",MatProductSetFromOptions_SeqDense));
33129566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense));
33139566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqsbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense));
331496e6d5c4SRichard Tran Mills 
33159566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumn_C",MatDenseGetColumn_SeqDense));
33169566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumn_C",MatDenseRestoreColumn_SeqDense));
33179566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVec_C",MatDenseGetColumnVec_SeqDense));
33189566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVec_C",MatDenseRestoreColumnVec_SeqDense));
33199566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVecRead_C",MatDenseGetColumnVecRead_SeqDense));
33209566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVecRead_C",MatDenseRestoreColumnVecRead_SeqDense));
33219566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVecWrite_C",MatDenseGetColumnVecWrite_SeqDense));
33229566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVecWrite_C",MatDenseRestoreColumnVecWrite_SeqDense));
33239566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetSubMatrix_C",MatDenseGetSubMatrix_SeqDense));
33249566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreSubMatrix_C",MatDenseRestoreSubMatrix_SeqDense));
33259566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)B,MATSEQDENSE));
33263a40ed3dSBarry Smith   PetscFunctionReturn(0);
3327289bc588SBarry Smith }
332886aefd0dSHong Zhang 
332986aefd0dSHong Zhang /*@C
3330af53bab2SHong 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.
333186aefd0dSHong Zhang 
333286aefd0dSHong Zhang    Not Collective
333386aefd0dSHong Zhang 
33345ea7661aSPierre Jolivet    Input Parameters:
333586aefd0dSHong Zhang +  mat - a MATSEQDENSE or MATMPIDENSE matrix
333686aefd0dSHong Zhang -  col - column index
333786aefd0dSHong Zhang 
333886aefd0dSHong Zhang    Output Parameter:
333986aefd0dSHong Zhang .  vals - pointer to the data
334086aefd0dSHong Zhang 
334186aefd0dSHong Zhang    Level: intermediate
334286aefd0dSHong Zhang 
334386aefd0dSHong Zhang .seealso: MatDenseRestoreColumn()
334486aefd0dSHong Zhang @*/
334586aefd0dSHong Zhang PetscErrorCode MatDenseGetColumn(Mat A,PetscInt col,PetscScalar **vals)
334686aefd0dSHong Zhang {
334786aefd0dSHong Zhang   PetscFunctionBegin;
3348d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3349d5ea218eSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
3350d5ea218eSStefano Zampini   PetscValidPointer(vals,3);
3351cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetColumn_C",(Mat,PetscInt,PetscScalar**),(A,col,vals));
335286aefd0dSHong Zhang   PetscFunctionReturn(0);
335386aefd0dSHong Zhang }
335486aefd0dSHong Zhang 
335586aefd0dSHong Zhang /*@C
335686aefd0dSHong Zhang    MatDenseRestoreColumn - returns access to a column of a dense matrix which is returned by MatDenseGetColumn().
335786aefd0dSHong Zhang 
335886aefd0dSHong Zhang    Not Collective
335986aefd0dSHong Zhang 
336086aefd0dSHong Zhang    Input Parameter:
336186aefd0dSHong Zhang .  mat - a MATSEQDENSE or MATMPIDENSE matrix
336286aefd0dSHong Zhang 
336386aefd0dSHong Zhang    Output Parameter:
336486aefd0dSHong Zhang .  vals - pointer to the data
336586aefd0dSHong Zhang 
336686aefd0dSHong Zhang    Level: intermediate
336786aefd0dSHong Zhang 
336886aefd0dSHong Zhang .seealso: MatDenseGetColumn()
336986aefd0dSHong Zhang @*/
337086aefd0dSHong Zhang PetscErrorCode MatDenseRestoreColumn(Mat A,PetscScalar **vals)
337186aefd0dSHong Zhang {
337286aefd0dSHong Zhang   PetscFunctionBegin;
3373d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3374d5ea218eSStefano Zampini   PetscValidPointer(vals,2);
3375cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreColumn_C",(Mat,PetscScalar**),(A,vals));
337686aefd0dSHong Zhang   PetscFunctionReturn(0);
337786aefd0dSHong Zhang }
33786947451fSStefano Zampini 
33790f74d2c1SSatish Balay /*@
33806947451fSStefano Zampini    MatDenseGetColumnVec - Gives read-write access to a column of a dense matrix, represented as a Vec.
33816947451fSStefano Zampini 
33826947451fSStefano Zampini    Collective
33836947451fSStefano Zampini 
33845ea7661aSPierre Jolivet    Input Parameters:
33856947451fSStefano Zampini +  mat - the Mat object
33866947451fSStefano Zampini -  col - the column index
33876947451fSStefano Zampini 
33886947451fSStefano Zampini    Output Parameter:
33896947451fSStefano Zampini .  v - the vector
33906947451fSStefano Zampini 
33916947451fSStefano Zampini    Notes:
33926947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVec() when the vector is no longer needed.
33936947451fSStefano Zampini      Use MatDenseGetColumnVecRead() to obtain read-only access or MatDenseGetColumnVecWrite() for write-only access.
33946947451fSStefano Zampini 
33956947451fSStefano Zampini    Level: intermediate
33966947451fSStefano Zampini 
33976947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
33986947451fSStefano Zampini @*/
33996947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVec(Mat A,PetscInt col,Vec *v)
34006947451fSStefano Zampini {
34016947451fSStefano Zampini   PetscFunctionBegin;
34026947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
34036947451fSStefano Zampini   PetscValidType(A,1);
34046947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
34056947451fSStefano Zampini   PetscValidPointer(v,3);
340628b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
34072c71b3e2SJacob Faibussowitsch   PetscCheckFalse(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);
3408cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetColumnVec_C",(Mat,PetscInt,Vec*),(A,col,v));
34096947451fSStefano Zampini   PetscFunctionReturn(0);
34106947451fSStefano Zampini }
34116947451fSStefano Zampini 
34120f74d2c1SSatish Balay /*@
34136947451fSStefano Zampini    MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVec().
34146947451fSStefano Zampini 
34156947451fSStefano Zampini    Collective
34166947451fSStefano Zampini 
34175ea7661aSPierre Jolivet    Input Parameters:
34186947451fSStefano Zampini +  mat - the Mat object
34196947451fSStefano Zampini .  col - the column index
34206947451fSStefano Zampini -  v - the Vec object
34216947451fSStefano Zampini 
34226947451fSStefano Zampini    Level: intermediate
34236947451fSStefano Zampini 
34246947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
34256947451fSStefano Zampini @*/
34266947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVec(Mat A,PetscInt col,Vec *v)
34276947451fSStefano Zampini {
34286947451fSStefano Zampini   PetscFunctionBegin;
34296947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
34306947451fSStefano Zampini   PetscValidType(A,1);
34316947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
34322c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
34332c71b3e2SJacob Faibussowitsch   PetscCheckFalse(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);
3434cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreColumnVec_C",(Mat,PetscInt,Vec*),(A,col,v));
34356947451fSStefano Zampini   PetscFunctionReturn(0);
34366947451fSStefano Zampini }
34376947451fSStefano Zampini 
34380f74d2c1SSatish Balay /*@
34396947451fSStefano Zampini    MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a Vec.
34406947451fSStefano Zampini 
34416947451fSStefano Zampini    Collective
34426947451fSStefano Zampini 
34435ea7661aSPierre Jolivet    Input Parameters:
34446947451fSStefano Zampini +  mat - the Mat object
34456947451fSStefano Zampini -  col - the column index
34466947451fSStefano Zampini 
34476947451fSStefano Zampini    Output Parameter:
34486947451fSStefano Zampini .  v - the vector
34496947451fSStefano Zampini 
34506947451fSStefano Zampini    Notes:
34516947451fSStefano Zampini      The vector is owned by PETSc and users cannot modify it.
34526947451fSStefano Zampini      Users need to call MatDenseRestoreColumnVecRead() when the vector is no longer needed.
34536947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecWrite() for write-only access.
34546947451fSStefano Zampini 
34556947451fSStefano Zampini    Level: intermediate
34566947451fSStefano Zampini 
34576947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
34586947451fSStefano Zampini @*/
34596947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecRead(Mat A,PetscInt col,Vec *v)
34606947451fSStefano Zampini {
34616947451fSStefano Zampini   PetscFunctionBegin;
34626947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
34636947451fSStefano Zampini   PetscValidType(A,1);
34646947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
34656947451fSStefano Zampini   PetscValidPointer(v,3);
346628b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
34672c71b3e2SJacob Faibussowitsch   PetscCheckFalse(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);
3468cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetColumnVecRead_C",(Mat,PetscInt,Vec*),(A,col,v));
34696947451fSStefano Zampini   PetscFunctionReturn(0);
34706947451fSStefano Zampini }
34716947451fSStefano Zampini 
34720f74d2c1SSatish Balay /*@
34736947451fSStefano Zampini    MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecRead().
34746947451fSStefano Zampini 
34756947451fSStefano Zampini    Collective
34766947451fSStefano Zampini 
34775ea7661aSPierre Jolivet    Input Parameters:
34786947451fSStefano Zampini +  mat - the Mat object
34796947451fSStefano Zampini .  col - the column index
34806947451fSStefano Zampini -  v - the Vec object
34816947451fSStefano Zampini 
34826947451fSStefano Zampini    Level: intermediate
34836947451fSStefano Zampini 
34846947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecWrite()
34856947451fSStefano Zampini @*/
34866947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecRead(Mat A,PetscInt col,Vec *v)
34876947451fSStefano Zampini {
34886947451fSStefano Zampini   PetscFunctionBegin;
34896947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
34906947451fSStefano Zampini   PetscValidType(A,1);
34916947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
34922c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
34932c71b3e2SJacob Faibussowitsch   PetscCheckFalse(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);
3494cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreColumnVecRead_C",(Mat,PetscInt,Vec*),(A,col,v));
34956947451fSStefano Zampini   PetscFunctionReturn(0);
34966947451fSStefano Zampini }
34976947451fSStefano Zampini 
34980f74d2c1SSatish Balay /*@
34996947451fSStefano Zampini    MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a Vec.
35006947451fSStefano Zampini 
35016947451fSStefano Zampini    Collective
35026947451fSStefano Zampini 
35035ea7661aSPierre Jolivet    Input Parameters:
35046947451fSStefano Zampini +  mat - the Mat object
35056947451fSStefano Zampini -  col - the column index
35066947451fSStefano Zampini 
35076947451fSStefano Zampini    Output Parameter:
35086947451fSStefano Zampini .  v - the vector
35096947451fSStefano Zampini 
35106947451fSStefano Zampini    Notes:
35116947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVecWrite() when the vector is no longer needed.
35126947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecRead() for read-only access.
35136947451fSStefano Zampini 
35146947451fSStefano Zampini    Level: intermediate
35156947451fSStefano Zampini 
35166947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead(), MatDenseRestoreColumnVecWrite()
35176947451fSStefano Zampini @*/
35186947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecWrite(Mat A,PetscInt col,Vec *v)
35196947451fSStefano Zampini {
35206947451fSStefano Zampini   PetscFunctionBegin;
35216947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
35226947451fSStefano Zampini   PetscValidType(A,1);
35236947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
35246947451fSStefano Zampini   PetscValidPointer(v,3);
352528b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
35262c71b3e2SJacob Faibussowitsch   PetscCheckFalse(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);
3527cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetColumnVecWrite_C",(Mat,PetscInt,Vec*),(A,col,v));
35286947451fSStefano Zampini   PetscFunctionReturn(0);
35296947451fSStefano Zampini }
35306947451fSStefano Zampini 
35310f74d2c1SSatish Balay /*@
35326947451fSStefano Zampini    MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecWrite().
35336947451fSStefano Zampini 
35346947451fSStefano Zampini    Collective
35356947451fSStefano Zampini 
35365ea7661aSPierre Jolivet    Input Parameters:
35376947451fSStefano Zampini +  mat - the Mat object
35386947451fSStefano Zampini .  col - the column index
35396947451fSStefano Zampini -  v - the Vec object
35406947451fSStefano Zampini 
35416947451fSStefano Zampini    Level: intermediate
35426947451fSStefano Zampini 
35436947451fSStefano Zampini .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseGetColumnVecRead(), MatDenseGetColumnVecWrite(), MatDenseRestoreColumnVec(), MatDenseRestoreColumnVecRead()
35446947451fSStefano Zampini @*/
35456947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A,PetscInt col,Vec *v)
35466947451fSStefano Zampini {
35476947451fSStefano Zampini   PetscFunctionBegin;
35486947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
35496947451fSStefano Zampini   PetscValidType(A,1);
35506947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
35512c71b3e2SJacob Faibussowitsch   PetscCheckFalse(!A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
35522c71b3e2SJacob Faibussowitsch   PetscCheckFalse(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);
3553cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreColumnVecWrite_C",(Mat,PetscInt,Vec*),(A,col,v));
35546947451fSStefano Zampini   PetscFunctionReturn(0);
35556947451fSStefano Zampini }
35565ea7661aSPierre Jolivet 
35570f74d2c1SSatish Balay /*@
35585ea7661aSPierre Jolivet    MatDenseGetSubMatrix - Gives access to a block of columns of a dense matrix, represented as a Mat.
35595ea7661aSPierre Jolivet 
35605ea7661aSPierre Jolivet    Collective
35615ea7661aSPierre Jolivet 
35625ea7661aSPierre Jolivet    Input Parameters:
35635ea7661aSPierre Jolivet +  mat - the Mat object
35645ea7661aSPierre Jolivet .  cbegin - the first index in the block
35655ea7661aSPierre Jolivet -  cend - the last index in the block
35665ea7661aSPierre Jolivet 
35675ea7661aSPierre Jolivet    Output Parameter:
35685ea7661aSPierre Jolivet .  v - the matrix
35695ea7661aSPierre Jolivet 
35705ea7661aSPierre Jolivet    Notes:
35715ea7661aSPierre Jolivet      The matrix is owned by PETSc. Users need to call MatDenseRestoreSubMatrix() when the matrix is no longer needed.
35725ea7661aSPierre Jolivet 
35735ea7661aSPierre Jolivet    Level: intermediate
35745ea7661aSPierre Jolivet 
35755ea7661aSPierre Jolivet .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseRestoreColumnVec(), MatDenseRestoreSubMatrix()
35765ea7661aSPierre Jolivet @*/
35775ea7661aSPierre Jolivet PetscErrorCode MatDenseGetSubMatrix(Mat A,PetscInt cbegin,PetscInt cend,Mat *v)
35785ea7661aSPierre Jolivet {
35795ea7661aSPierre Jolivet   PetscFunctionBegin;
35805ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
35815ea7661aSPierre Jolivet   PetscValidType(A,1);
35825ea7661aSPierre Jolivet   PetscValidLogicalCollectiveInt(A,cbegin,2);
35835ea7661aSPierre Jolivet   PetscValidLogicalCollectiveInt(A,cend,3);
35845ea7661aSPierre Jolivet   PetscValidPointer(v,4);
358528b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
35862c71b3e2SJacob Faibussowitsch   PetscCheckFalse(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);
35872c71b3e2SJacob Faibussowitsch   PetscCheckFalse(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);
3588cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetSubMatrix_C",(Mat,PetscInt,PetscInt,Mat*),(A,cbegin,cend,v));
35895ea7661aSPierre Jolivet   PetscFunctionReturn(0);
35905ea7661aSPierre Jolivet }
35915ea7661aSPierre Jolivet 
35920f74d2c1SSatish Balay /*@
35935ea7661aSPierre Jolivet    MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from MatDenseGetSubMatrix().
35945ea7661aSPierre Jolivet 
35955ea7661aSPierre Jolivet    Collective
35965ea7661aSPierre Jolivet 
35975ea7661aSPierre Jolivet    Input Parameters:
35985ea7661aSPierre Jolivet +  mat - the Mat object
35995ea7661aSPierre Jolivet -  v - the Mat object
36005ea7661aSPierre Jolivet 
36015ea7661aSPierre Jolivet    Level: intermediate
36025ea7661aSPierre Jolivet 
36035ea7661aSPierre Jolivet .seealso: MATDENSE, MATDENSECUDA, MatDenseGetColumnVec(), MatDenseRestoreColumnVec(), MatDenseGetSubMatrix()
36045ea7661aSPierre Jolivet @*/
36055ea7661aSPierre Jolivet PetscErrorCode MatDenseRestoreSubMatrix(Mat A,Mat *v)
36065ea7661aSPierre Jolivet {
36075ea7661aSPierre Jolivet   PetscFunctionBegin;
36085ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
36095ea7661aSPierre Jolivet   PetscValidType(A,1);
36105ea7661aSPierre Jolivet   PetscValidPointer(v,2);
3611cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreSubMatrix_C",(Mat,Mat*),(A,v));
36125ea7661aSPierre Jolivet   PetscFunctionReturn(0);
36135ea7661aSPierre Jolivet }
3614