xref: /petsc/src/mat/impls/dense/seq/dense.c (revision 04cbc0058eadf63b30e356b415cf83f8fd6ecc3b)
1be1d678aSKris Buschelman 
267e560aaSBarry Smith /*
367e560aaSBarry Smith      Defines the basic matrix operations for sequential dense.
467e560aaSBarry Smith */
5289bc588SBarry Smith 
6dec5eb66SMatthew G Knepley #include <../src/mat/impls/dense/seq/dense.h> /*I "petscmat.h" I*/
7c6db04a5SJed Brown #include <petscblaslapack.h>
8289bc588SBarry Smith 
96a63e612SBarry Smith #include <../src/mat/impls/aij/seq/aij.h>
10b2573a8aSBarry Smith 
11ca15aa20SStefano Zampini PetscErrorCode MatSeqDenseSymmetrize_Private(Mat A, PetscBool hermitian)
128c178816SStefano Zampini {
138c178816SStefano Zampini   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
148c178816SStefano Zampini   PetscInt       j, k, n = A->rmap->n;
15ca15aa20SStefano Zampini   PetscScalar    *v;
168c178816SStefano Zampini 
178c178816SStefano Zampini   PetscFunctionBegin;
1808401ef6SPierre Jolivet   PetscCheck(A->rmap->n == A->cmap->n,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Cannot symmetrize a rectangular matrix");
199566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&v));
208c178816SStefano Zampini   if (!hermitian) {
218c178816SStefano Zampini     for (k=0;k<n;k++) {
228c178816SStefano Zampini       for (j=k;j<n;j++) {
23ca15aa20SStefano Zampini         v[j*mat->lda + k] = v[k*mat->lda + j];
248c178816SStefano Zampini       }
258c178816SStefano Zampini     }
268c178816SStefano Zampini   } else {
278c178816SStefano Zampini     for (k=0;k<n;k++) {
288c178816SStefano Zampini       for (j=k;j<n;j++) {
29ca15aa20SStefano Zampini         v[j*mat->lda + k] = PetscConj(v[k*mat->lda + j]);
308c178816SStefano Zampini       }
318c178816SStefano Zampini     }
328c178816SStefano Zampini   }
339566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&v));
348c178816SStefano Zampini   PetscFunctionReturn(0);
358c178816SStefano Zampini }
368c178816SStefano Zampini 
3705709791SSatish Balay PETSC_EXTERN PetscErrorCode MatSeqDenseInvertFactors_Private(Mat A)
388c178816SStefano Zampini {
398c178816SStefano Zampini   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
408c178816SStefano Zampini   PetscBLASInt   info,n;
418c178816SStefano Zampini 
428c178816SStefano Zampini   PetscFunctionBegin;
438c178816SStefano Zampini   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
449566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
458c178816SStefano Zampini   if (A->factortype == MAT_FACTOR_LU) {
4628b400f6SJacob Faibussowitsch     PetscCheck(mat->pivots,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present");
478c178816SStefano Zampini     if (!mat->fwork) {
488c178816SStefano Zampini       mat->lfwork = n;
499566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(mat->lfwork,&mat->fwork));
509566063dSJacob Faibussowitsch       PetscCall(PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt)));
518c178816SStefano Zampini     }
529566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
538c178816SStefano Zampini     PetscStackCallBLAS("LAPACKgetri",LAPACKgetri_(&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
549566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
559566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0));
568c178816SStefano Zampini   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
578c178816SStefano Zampini     if (A->spd) {
589566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
598c178816SStefano Zampini       PetscStackCallBLAS("LAPACKpotri",LAPACKpotri_("L",&n,mat->v,&mat->lda,&info));
609566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
619566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSymmetrize_Private(A,PETSC_TRUE));
628c178816SStefano Zampini #if defined(PETSC_USE_COMPLEX)
638c178816SStefano Zampini     } else if (A->hermitian) {
6428b400f6SJacob Faibussowitsch       PetscCheck(mat->pivots,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present");
6528b400f6SJacob Faibussowitsch       PetscCheck(mat->fwork,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Fwork not present");
669566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
678c178816SStefano Zampini       PetscStackCallBLAS("LAPACKhetri",LAPACKhetri_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&info));
689566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
699566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSymmetrize_Private(A,PETSC_TRUE));
708c178816SStefano Zampini #endif
718c178816SStefano Zampini     } else { /* symmetric case */
7228b400f6SJacob Faibussowitsch       PetscCheck(mat->pivots,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present");
7328b400f6SJacob Faibussowitsch       PetscCheck(mat->fwork,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Fwork not present");
749566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
758c178816SStefano Zampini       PetscStackCallBLAS("LAPACKsytri",LAPACKsytri_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&info));
769566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
779566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSymmetrize_Private(A,PETSC_FALSE));
788c178816SStefano Zampini     }
7928b400f6SJacob Faibussowitsch     PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad Inversion: zero pivot in row %" PetscInt_FMT,(PetscInt)info-1);
809566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0));
818c178816SStefano Zampini   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
828c178816SStefano Zampini 
838c178816SStefano Zampini   A->ops->solve             = NULL;
848c178816SStefano Zampini   A->ops->matsolve          = NULL;
858c178816SStefano Zampini   A->ops->solvetranspose    = NULL;
868c178816SStefano Zampini   A->ops->matsolvetranspose = NULL;
878c178816SStefano Zampini   A->ops->solveadd          = NULL;
888c178816SStefano Zampini   A->ops->solvetransposeadd = NULL;
898c178816SStefano Zampini   A->factortype             = MAT_FACTOR_NONE;
909566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
918c178816SStefano Zampini   PetscFunctionReturn(0);
928c178816SStefano Zampini }
938c178816SStefano Zampini 
943f49a652SStefano Zampini PetscErrorCode MatZeroRowsColumns_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
953f49a652SStefano Zampini {
963f49a652SStefano Zampini   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
973f49a652SStefano Zampini   PetscInt          m  = l->lda, n = A->cmap->n,r = A->rmap->n, i,j;
98ca15aa20SStefano Zampini   PetscScalar       *slot,*bb,*v;
993f49a652SStefano Zampini   const PetscScalar *xx;
1003f49a652SStefano Zampini 
1013f49a652SStefano Zampini   PetscFunctionBegin;
10276bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
1033f49a652SStefano Zampini     for (i=0; i<N; i++) {
10408401ef6SPierre Jolivet       PetscCheck(rows[i] >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
10508401ef6SPierre Jolivet       PetscCheck(rows[i] < A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %" PetscInt_FMT " requested to be zeroed greater than or equal number of rows %" PetscInt_FMT,rows[i],A->rmap->n);
10608401ef6SPierre Jolivet       PetscCheck(rows[i] < A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Col %" PetscInt_FMT " requested to be zeroed greater than or equal number of cols %" PetscInt_FMT,rows[i],A->cmap->n);
1073f49a652SStefano Zampini     }
10876bd3646SJed Brown   }
109ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
1103f49a652SStefano Zampini 
1113f49a652SStefano Zampini   /* fix right hand side if needed */
1123f49a652SStefano Zampini   if (x && b) {
1136c4d906cSStefano Zampini     Vec xt;
1146c4d906cSStefano Zampini 
11508401ef6SPierre Jolivet     PetscCheck(A->rmap->n == A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
1169566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(x,&xt));
1179566063dSJacob Faibussowitsch     PetscCall(VecCopy(x,xt));
1189566063dSJacob Faibussowitsch     PetscCall(VecScale(xt,-1.0));
1199566063dSJacob Faibussowitsch     PetscCall(MatMultAdd(A,xt,b,b));
1209566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&xt));
1219566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(x,&xx));
1229566063dSJacob Faibussowitsch     PetscCall(VecGetArray(b,&bb));
1233f49a652SStefano Zampini     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
1249566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(x,&xx));
1259566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(b,&bb));
1263f49a652SStefano Zampini   }
1273f49a652SStefano Zampini 
1289566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&v));
1293f49a652SStefano Zampini   for (i=0; i<N; i++) {
130ca15aa20SStefano Zampini     slot = v + rows[i]*m;
1319566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(slot,r));
1323f49a652SStefano Zampini   }
1333f49a652SStefano Zampini   for (i=0; i<N; i++) {
134ca15aa20SStefano Zampini     slot = v + rows[i];
1353f49a652SStefano Zampini     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
1363f49a652SStefano Zampini   }
1373f49a652SStefano Zampini   if (diag != 0.0) {
13808401ef6SPierre Jolivet     PetscCheck(A->rmap->n == A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
1393f49a652SStefano Zampini     for (i=0; i<N; i++) {
140ca15aa20SStefano Zampini       slot  = v + (m+1)*rows[i];
1413f49a652SStefano Zampini       *slot = diag;
1423f49a652SStefano Zampini     }
1433f49a652SStefano Zampini   }
1449566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&v));
1453f49a652SStefano Zampini   PetscFunctionReturn(0);
1463f49a652SStefano Zampini }
1473f49a652SStefano Zampini 
148abc3b08eSStefano Zampini PetscErrorCode MatPtAPNumeric_SeqDense_SeqDense(Mat A,Mat P,Mat C)
149abc3b08eSStefano Zampini {
150abc3b08eSStefano Zampini   Mat_SeqDense   *c = (Mat_SeqDense*)(C->data);
151abc3b08eSStefano Zampini 
152abc3b08eSStefano Zampini   PetscFunctionBegin;
153ca15aa20SStefano Zampini   if (c->ptapwork) {
1549566063dSJacob Faibussowitsch     PetscCall((*C->ops->matmultnumeric)(A,P,c->ptapwork));
1559566063dSJacob Faibussowitsch     PetscCall((*C->ops->transposematmultnumeric)(P,c->ptapwork,C));
1564222ddf1SHong Zhang   } else SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_SUP,"Must call MatPtAPSymbolic_SeqDense_SeqDense() first");
157abc3b08eSStefano Zampini   PetscFunctionReturn(0);
158abc3b08eSStefano Zampini }
159abc3b08eSStefano Zampini 
1604222ddf1SHong Zhang PetscErrorCode MatPtAPSymbolic_SeqDense_SeqDense(Mat A,Mat P,PetscReal fill,Mat C)
161abc3b08eSStefano Zampini {
162abc3b08eSStefano Zampini   Mat_SeqDense   *c;
1637a3c3d58SStefano Zampini   PetscBool      cisdense;
164abc3b08eSStefano Zampini 
165abc3b08eSStefano Zampini   PetscFunctionBegin;
1669566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C,P->cmap->n,P->cmap->n,P->cmap->N,P->cmap->N));
1679566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,""));
1687a3c3d58SStefano Zampini   if (!cisdense) {
1697a3c3d58SStefano Zampini     PetscBool flg;
1707a3c3d58SStefano Zampini 
1719566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)P,((PetscObject)A)->type_name,&flg));
1729566063dSJacob Faibussowitsch     PetscCall(MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE));
1737a3c3d58SStefano Zampini   }
1749566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
1754222ddf1SHong Zhang   c    = (Mat_SeqDense*)C->data;
1769566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&c->ptapwork));
1779566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(c->ptapwork,A->rmap->n,P->cmap->n,A->rmap->N,P->cmap->N));
1789566063dSJacob Faibussowitsch   PetscCall(MatSetType(c->ptapwork,((PetscObject)C)->type_name));
1799566063dSJacob Faibussowitsch   PetscCall(MatSetUp(c->ptapwork));
180abc3b08eSStefano Zampini   PetscFunctionReturn(0);
181abc3b08eSStefano Zampini }
182abc3b08eSStefano Zampini 
183cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat A,MatType newtype,MatReuse reuse,Mat *newmat)
184b49cda9fSStefano Zampini {
185a13144ffSStefano Zampini   Mat             B = NULL;
186b49cda9fSStefano Zampini   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
187b49cda9fSStefano Zampini   Mat_SeqDense    *b;
188b49cda9fSStefano Zampini   PetscInt        *ai=a->i,*aj=a->j,m=A->rmap->N,n=A->cmap->N,i;
1892e5835c6SStefano Zampini   const MatScalar *av;
190a13144ffSStefano Zampini   PetscBool       isseqdense;
191b49cda9fSStefano Zampini 
192b49cda9fSStefano Zampini   PetscFunctionBegin;
193a13144ffSStefano Zampini   if (reuse == MAT_REUSE_MATRIX) {
1949566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)*newmat,MATSEQDENSE,&isseqdense));
19528b400f6SJacob Faibussowitsch     PetscCheck(isseqdense,PetscObjectComm((PetscObject)*newmat),PETSC_ERR_USER,"Cannot reuse matrix of type %s",((PetscObject)(*newmat))->type_name);
196a13144ffSStefano Zampini   }
197a13144ffSStefano Zampini   if (reuse != MAT_REUSE_MATRIX) {
1989566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&B));
1999566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(B,m,n,m,n));
2009566063dSJacob Faibussowitsch     PetscCall(MatSetType(B,MATSEQDENSE));
2019566063dSJacob Faibussowitsch     PetscCall(MatSeqDenseSetPreallocation(B,NULL));
202b49cda9fSStefano Zampini     b    = (Mat_SeqDense*)(B->data);
203a13144ffSStefano Zampini   } else {
204a13144ffSStefano Zampini     b    = (Mat_SeqDense*)((*newmat)->data);
2059566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(b->v,m*n));
206a13144ffSStefano Zampini   }
2079566063dSJacob Faibussowitsch   PetscCall(MatSeqAIJGetArrayRead(A,&av));
208b49cda9fSStefano Zampini   for (i=0; i<m; i++) {
209b49cda9fSStefano Zampini     PetscInt j;
210b49cda9fSStefano Zampini     for (j=0;j<ai[1]-ai[0];j++) {
211b49cda9fSStefano Zampini       b->v[*aj*m+i] = *av;
212b49cda9fSStefano Zampini       aj++;
213b49cda9fSStefano Zampini       av++;
214b49cda9fSStefano Zampini     }
215b49cda9fSStefano Zampini     ai++;
216b49cda9fSStefano Zampini   }
2179566063dSJacob Faibussowitsch   PetscCall(MatSeqAIJRestoreArrayRead(A,&av));
218b49cda9fSStefano Zampini 
219511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
2209566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY));
2219566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY));
2229566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A,&B));
223b49cda9fSStefano Zampini   } else {
224a13144ffSStefano Zampini     if (B) *newmat = B;
2259566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY));
2269566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY));
227b49cda9fSStefano Zampini   }
228b49cda9fSStefano Zampini   PetscFunctionReturn(0);
229b49cda9fSStefano Zampini }
230b49cda9fSStefano Zampini 
231cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_SeqAIJ(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
2326a63e612SBarry Smith {
2336d4ec7b0SPierre Jolivet   Mat            B = NULL;
2346a63e612SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2359399e1b8SMatthew G. Knepley   PetscInt       i, j;
2369399e1b8SMatthew G. Knepley   PetscInt       *rows, *nnz;
2379399e1b8SMatthew G. Knepley   MatScalar      *aa = a->v, *vals;
2386a63e612SBarry Smith 
2396a63e612SBarry Smith   PetscFunctionBegin;
2409566063dSJacob Faibussowitsch   PetscCall(PetscCalloc3(A->rmap->n,&rows,A->rmap->n,&nnz,A->rmap->n,&vals));
2416d4ec7b0SPierre Jolivet   if (reuse != MAT_REUSE_MATRIX) {
2429566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&B));
2439566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N));
2449566063dSJacob Faibussowitsch     PetscCall(MatSetType(B,MATSEQAIJ));
2459399e1b8SMatthew G. Knepley     for (j=0; j<A->cmap->n; j++) {
2466d4ec7b0SPierre Jolivet       for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) ++nnz[i];
2476a63e612SBarry Smith       aa += a->lda;
2486a63e612SBarry Smith     }
2499566063dSJacob Faibussowitsch     PetscCall(MatSeqAIJSetPreallocation(B,PETSC_DETERMINE,nnz));
2506d4ec7b0SPierre Jolivet   } else B = *newmat;
2519399e1b8SMatthew G. Knepley   aa = a->v;
2529399e1b8SMatthew G. Knepley   for (j=0; j<A->cmap->n; j++) {
2539399e1b8SMatthew G. Knepley     PetscInt numRows = 0;
2546d4ec7b0SPierre Jolivet     for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) {rows[numRows] = i; vals[numRows++] = aa[i];}
2559566063dSJacob Faibussowitsch     PetscCall(MatSetValues(B,numRows,rows,1,&j,vals,INSERT_VALUES));
2569399e1b8SMatthew G. Knepley     aa  += a->lda;
2579399e1b8SMatthew G. Knepley   }
2589566063dSJacob Faibussowitsch   PetscCall(PetscFree3(rows,nnz,vals));
2599566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY));
2609566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY));
2616a63e612SBarry Smith 
262511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
2639566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A,&B));
2646d4ec7b0SPierre Jolivet   } else if (reuse != MAT_REUSE_MATRIX) *newmat = B;
2656a63e612SBarry Smith   PetscFunctionReturn(0);
2666a63e612SBarry Smith }
2676a63e612SBarry Smith 
268ca15aa20SStefano Zampini PetscErrorCode MatAXPY_SeqDense(Mat Y,PetscScalar alpha,Mat X,MatStructure str)
2691987afe7SBarry Smith {
2701987afe7SBarry Smith   Mat_SeqDense      *x = (Mat_SeqDense*)X->data,*y = (Mat_SeqDense*)Y->data;
271ca15aa20SStefano Zampini   const PetscScalar *xv;
272ca15aa20SStefano Zampini   PetscScalar       *yv;
27323fff9afSBarry Smith   PetscBLASInt      N,m,ldax = 0,lday = 0,one = 1;
2743a40ed3dSBarry Smith 
2753a40ed3dSBarry Smith   PetscFunctionBegin;
2769566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(X,&xv));
2779566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(Y,&yv));
2789566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(X->rmap->n*X->cmap->n,&N));
2799566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(X->rmap->n,&m));
2809566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(x->lda,&ldax));
2819566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(y->lda,&lday));
282a5ce6ee0Svictorle   if (ldax>m || lday>m) {
283ca15aa20SStefano Zampini     PetscInt j;
284ca15aa20SStefano Zampini 
285d0f46423SBarry Smith     for (j=0; j<X->cmap->n; j++) {
286ca15aa20SStefano Zampini       PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&m,&alpha,xv+j*ldax,&one,yv+j*lday,&one));
287a5ce6ee0Svictorle     }
288a5ce6ee0Svictorle   } else {
289ca15aa20SStefano Zampini     PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&N,&alpha,xv,&one,yv,&one));
290a5ce6ee0Svictorle   }
2919566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(X,&xv));
2929566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(Y,&yv));
2939566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(PetscMax(2.0*N-1,0)));
2943a40ed3dSBarry Smith   PetscFunctionReturn(0);
2951987afe7SBarry Smith }
2961987afe7SBarry Smith 
297e0877f53SBarry Smith static PetscErrorCode MatGetInfo_SeqDense(Mat A,MatInfoType flag,MatInfo *info)
298289bc588SBarry Smith {
299ca15aa20SStefano Zampini   PetscLogDouble N = A->rmap->n*A->cmap->n;
3003a40ed3dSBarry Smith 
3013a40ed3dSBarry Smith   PetscFunctionBegin;
3024e220ebcSLois Curfman McInnes   info->block_size        = 1.0;
303ca15aa20SStefano Zampini   info->nz_allocated      = N;
304ca15aa20SStefano Zampini   info->nz_used           = N;
305ca15aa20SStefano Zampini   info->nz_unneeded       = 0;
306ca15aa20SStefano Zampini   info->assemblies        = A->num_ass;
3074e220ebcSLois Curfman McInnes   info->mallocs           = 0;
3087adad957SLisandro Dalcin   info->memory            = ((PetscObject)A)->mem;
3094e220ebcSLois Curfman McInnes   info->fill_ratio_given  = 0;
3104e220ebcSLois Curfman McInnes   info->fill_ratio_needed = 0;
3114e220ebcSLois Curfman McInnes   info->factor_mallocs    = 0;
3123a40ed3dSBarry Smith   PetscFunctionReturn(0);
313289bc588SBarry Smith }
314289bc588SBarry Smith 
315637a0070SStefano Zampini PetscErrorCode MatScale_SeqDense(Mat A,PetscScalar alpha)
31680cd9d93SLois Curfman McInnes {
317273d9f13SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
318ca15aa20SStefano Zampini   PetscScalar    *v;
31923fff9afSBarry Smith   PetscBLASInt   one = 1,j,nz,lda = 0;
32080cd9d93SLois Curfman McInnes 
3213a40ed3dSBarry Smith   PetscFunctionBegin;
3229566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&v));
3239566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(a->lda,&lda));
324d0f46423SBarry Smith   if (lda>A->rmap->n) {
3259566063dSJacob Faibussowitsch     PetscCall(PetscBLASIntCast(A->rmap->n,&nz));
326d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
327ca15aa20SStefano Zampini       PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&alpha,v+j*lda,&one));
328a5ce6ee0Svictorle     }
329a5ce6ee0Svictorle   } else {
3309566063dSJacob Faibussowitsch     PetscCall(PetscBLASIntCast(A->rmap->n*A->cmap->n,&nz));
331ca15aa20SStefano Zampini     PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&alpha,v,&one));
332a5ce6ee0Svictorle   }
333*04cbc005SJose E. Roman   PetscCall(PetscLogFlops(A->rmap->n*A->cmap->n));
3349566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&v));
3353a40ed3dSBarry Smith   PetscFunctionReturn(0);
33680cd9d93SLois Curfman McInnes }
33780cd9d93SLois Curfman McInnes 
3382f605a99SJose E. Roman PetscErrorCode MatShift_SeqDense(Mat A,PetscScalar alpha)
3392f605a99SJose E. Roman {
3402f605a99SJose E. Roman   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
3412f605a99SJose E. Roman   PetscScalar    *v;
3422f605a99SJose E. Roman   PetscInt       j,k;
3432f605a99SJose E. Roman 
3442f605a99SJose E. Roman   PetscFunctionBegin;
3452f605a99SJose E. Roman   PetscCall(MatDenseGetArray(A,&v));
3462f605a99SJose E. Roman   k = PetscMin(A->rmap->n,A->cmap->n);
3472f605a99SJose E. Roman   for (j=0; j<k; j++) v[j+j*a->lda] += alpha;
3482f605a99SJose E. Roman   PetscCall(PetscLogFlops(k));
3492f605a99SJose E. Roman   PetscCall(MatDenseRestoreArray(A,&v));
3502f605a99SJose E. Roman   PetscFunctionReturn(0);
3512f605a99SJose E. Roman }
3522f605a99SJose E. Roman 
353e0877f53SBarry Smith static PetscErrorCode MatIsHermitian_SeqDense(Mat A,PetscReal rtol,PetscBool  *fl)
3541cbb95d3SBarry Smith {
3551cbb95d3SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
356ca15aa20SStefano Zampini   PetscInt          i,j,m = A->rmap->n,N = a->lda;
357ca15aa20SStefano Zampini   const PetscScalar *v;
3581cbb95d3SBarry Smith 
3591cbb95d3SBarry Smith   PetscFunctionBegin;
3601cbb95d3SBarry Smith   *fl = PETSC_FALSE;
361d0f46423SBarry Smith   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
3629566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&v));
3631cbb95d3SBarry Smith   for (i=0; i<m; i++) {
364ca15aa20SStefano Zampini     for (j=i; j<m; j++) {
365637a0070SStefano Zampini       if (PetscAbsScalar(v[i+j*N] - PetscConj(v[j+i*N])) > rtol) {
366637a0070SStefano Zampini         goto restore;
3671cbb95d3SBarry Smith       }
3681cbb95d3SBarry Smith     }
369637a0070SStefano Zampini   }
3701cbb95d3SBarry Smith   *fl  = PETSC_TRUE;
371637a0070SStefano Zampini restore:
3729566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&v));
373637a0070SStefano Zampini   PetscFunctionReturn(0);
374637a0070SStefano Zampini }
375637a0070SStefano Zampini 
376637a0070SStefano Zampini static PetscErrorCode MatIsSymmetric_SeqDense(Mat A,PetscReal rtol,PetscBool  *fl)
377637a0070SStefano Zampini {
378637a0070SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
379637a0070SStefano Zampini   PetscInt          i,j,m = A->rmap->n,N = a->lda;
380637a0070SStefano Zampini   const PetscScalar *v;
381637a0070SStefano Zampini 
382637a0070SStefano Zampini   PetscFunctionBegin;
383637a0070SStefano Zampini   *fl = PETSC_FALSE;
384637a0070SStefano Zampini   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
3859566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&v));
386637a0070SStefano Zampini   for (i=0; i<m; i++) {
387637a0070SStefano Zampini     for (j=i; j<m; j++) {
388637a0070SStefano Zampini       if (PetscAbsScalar(v[i+j*N] - v[j+i*N]) > rtol) {
389637a0070SStefano Zampini         goto restore;
390637a0070SStefano Zampini       }
391637a0070SStefano Zampini     }
392637a0070SStefano Zampini   }
393637a0070SStefano Zampini   *fl  = PETSC_TRUE;
394637a0070SStefano Zampini restore:
3959566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&v));
3961cbb95d3SBarry Smith   PetscFunctionReturn(0);
3971cbb95d3SBarry Smith }
3981cbb95d3SBarry Smith 
399ca15aa20SStefano Zampini PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi,Mat A,MatDuplicateOption cpvalues)
400b24902e0SBarry Smith {
401ca15aa20SStefano Zampini   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
40223fc5dcaSStefano Zampini   PetscInt       lda = (PetscInt)mat->lda,j,m,nlda = lda;
40375f6d85dSStefano Zampini   PetscBool      isdensecpu;
404b24902e0SBarry Smith 
405b24902e0SBarry Smith   PetscFunctionBegin;
4069566063dSJacob Faibussowitsch   PetscCall(PetscLayoutReference(A->rmap,&newi->rmap));
4079566063dSJacob Faibussowitsch   PetscCall(PetscLayoutReference(A->cmap,&newi->cmap));
40823fc5dcaSStefano Zampini   if (cpvalues == MAT_SHARE_NONZERO_PATTERN) { /* propagate LDA */
4099566063dSJacob Faibussowitsch     PetscCall(MatDenseSetLDA(newi,lda));
41023fc5dcaSStefano Zampini   }
4119566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)newi,MATSEQDENSE,&isdensecpu));
4129566063dSJacob Faibussowitsch   if (isdensecpu) PetscCall(MatSeqDenseSetPreallocation(newi,NULL));
413b24902e0SBarry Smith   if (cpvalues == MAT_COPY_VALUES) {
414ca15aa20SStefano Zampini     const PetscScalar *av;
415ca15aa20SStefano Zampini     PetscScalar       *v;
416ca15aa20SStefano Zampini 
4179566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A,&av));
4189566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayWrite(newi,&v));
4199566063dSJacob Faibussowitsch     PetscCall(MatDenseGetLDA(newi,&nlda));
420d0f46423SBarry Smith     m    = A->rmap->n;
42123fc5dcaSStefano Zampini     if (lda>m || nlda>m) {
422d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
4239566063dSJacob Faibussowitsch         PetscCall(PetscArraycpy(v+j*nlda,av+j*lda,m));
424b24902e0SBarry Smith       }
425b24902e0SBarry Smith     } else {
4269566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(v,av,A->rmap->n*A->cmap->n));
427b24902e0SBarry Smith     }
4289566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayWrite(newi,&v));
4299566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A,&av));
430b24902e0SBarry Smith   }
431b24902e0SBarry Smith   PetscFunctionReturn(0);
432b24902e0SBarry Smith }
433b24902e0SBarry Smith 
434ca15aa20SStefano Zampini PetscErrorCode MatDuplicate_SeqDense(Mat A,MatDuplicateOption cpvalues,Mat *newmat)
43502cad45dSBarry Smith {
4363a40ed3dSBarry Smith   PetscFunctionBegin;
4379566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A),newmat));
4389566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*newmat,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n));
4399566063dSJacob Faibussowitsch   PetscCall(MatSetType(*newmat,((PetscObject)A)->type_name));
4409566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(*newmat,A,cpvalues));
441b24902e0SBarry Smith   PetscFunctionReturn(0);
442b24902e0SBarry Smith }
443b24902e0SBarry Smith 
444bf5a80bcSToby Isaac static PetscErrorCode MatSolve_SeqDense_Internal_LU(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T)
445289bc588SBarry Smith {
446c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
4474396437dSToby Isaac   PetscBLASInt    info;
44867e560aaSBarry Smith 
4493a40ed3dSBarry Smith   PetscFunctionBegin;
4509566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
4514396437dSToby Isaac   PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_(T ? "T" : "N",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
4529566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
45328b400f6SJacob Faibussowitsch   PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve");
4549566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs*(2.0*m*m - m)));
4554396437dSToby Isaac   PetscFunctionReturn(0);
4564396437dSToby Isaac }
4574396437dSToby Isaac 
4584396437dSToby Isaac static PetscErrorCode MatConjugate_SeqDense(Mat);
4594396437dSToby Isaac 
460bf5a80bcSToby Isaac static PetscErrorCode MatSolve_SeqDense_Internal_Cholesky(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T)
4614396437dSToby Isaac {
4624396437dSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
4634396437dSToby Isaac   PetscBLASInt    info;
4644396437dSToby Isaac 
4654396437dSToby Isaac   PetscFunctionBegin;
466a49dc2a2SStefano Zampini   if (A->spd) {
4679566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A));
4689566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
4698b83055fSJed Brown     PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&nrhs,mat->v,&mat->lda,x,&m,&info));
4709566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
47128b400f6SJacob Faibussowitsch     PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve");
4729566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A));
473a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
474a49dc2a2SStefano Zampini   } else if (A->hermitian) {
4759566063dSJacob Faibussowitsch     if (T) PetscCall(MatConjugate_SeqDense(A));
4769566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
477a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
4789566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
47928b400f6SJacob Faibussowitsch     PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve");
4809566063dSJacob Faibussowitsch     if (T) PetscCall(MatConjugate_SeqDense(A));
481a49dc2a2SStefano Zampini #endif
482a49dc2a2SStefano Zampini   } else { /* symmetric case */
4839566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
484a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
4859566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
48628b400f6SJacob Faibussowitsch     PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve");
487a49dc2a2SStefano Zampini   }
4889566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs*(2.0*m*m - m)));
4894396437dSToby Isaac   PetscFunctionReturn(0);
4904396437dSToby Isaac }
49185e2c93fSHong Zhang 
492bf5a80bcSToby Isaac static PetscErrorCode MatSolve_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k)
4934396437dSToby Isaac {
4944396437dSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
4954396437dSToby Isaac   PetscBLASInt    info;
4964396437dSToby Isaac   char            trans;
4974396437dSToby Isaac 
4984396437dSToby Isaac   PetscFunctionBegin;
4994905a7bcSToby Isaac   if (PetscDefined(USE_COMPLEX)) {
5004905a7bcSToby Isaac     trans = 'C';
5014905a7bcSToby Isaac   } else {
5024905a7bcSToby Isaac     trans = 'T';
5034905a7bcSToby Isaac   }
5049566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
505bf5a80bcSToby Isaac   PetscStackCallBLAS("LAPACKormqr",LAPACKormqr_("L", &trans, &m,&nrhs,&mat->rank,mat->v,&mat->lda,mat->tau,x,&ldx,mat->fwork,&mat->lfwork,&info));
5069566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
50728b400f6SJacob Faibussowitsch   PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"ORMQR - Bad orthogonal transform");
5089566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
509bf5a80bcSToby Isaac   PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U", "N", "N", &mat->rank,&nrhs,mat->v,&mat->lda,x,&ldx,&info));
5109566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
51128b400f6SJacob Faibussowitsch   PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"TRTRS - Bad triangular solve");
5124905a7bcSToby Isaac   for (PetscInt j = 0; j < nrhs; j++) {
5134905a7bcSToby Isaac     for (PetscInt i = mat->rank; i < k; i++) {
514bf5a80bcSToby Isaac       x[j*ldx + i] = 0.;
5154905a7bcSToby Isaac     }
5164905a7bcSToby Isaac   }
5179566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs*(4.0*m*mat->rank - PetscSqr(mat->rank))));
5184905a7bcSToby Isaac   PetscFunctionReturn(0);
5194905a7bcSToby Isaac }
5204905a7bcSToby Isaac 
521bf5a80bcSToby Isaac static PetscErrorCode MatSolveTranspose_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k)
5224905a7bcSToby Isaac {
5234396437dSToby Isaac   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
5244396437dSToby Isaac   PetscBLASInt      info;
5254396437dSToby Isaac 
5264396437dSToby Isaac   PetscFunctionBegin;
5274396437dSToby Isaac   if (A->rmap->n == A->cmap->n && mat->rank == A->rmap->n) {
5289566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
529bf5a80bcSToby Isaac     PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U", "T", "N", &m,&nrhs,mat->v,&mat->lda,x,&ldx,&info));
5309566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
53128b400f6SJacob Faibussowitsch     PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"TRTRS - Bad triangular solve");
5329566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A));
5339566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
534bf5a80bcSToby Isaac     PetscStackCallBLAS("LAPACKormqr",LAPACKormqr_("L", "N", &m,&nrhs,&mat->rank,mat->v,&mat->lda,mat->tau,x,&ldx,mat->fwork,&mat->lfwork,&info));
5359566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
53628b400f6SJacob Faibussowitsch     PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"ORMQR - Bad orthogonal transform");
5379566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A));
5384396437dSToby Isaac   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"QR factored matrix cannot be used for transpose solve");
5399566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs*(4.0*m*mat->rank - PetscSqr(mat->rank))));
5404396437dSToby Isaac   PetscFunctionReturn(0);
5414396437dSToby Isaac }
5424396437dSToby Isaac 
5434396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_SetUp(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k)
5444396437dSToby Isaac {
5454396437dSToby Isaac   Mat_SeqDense      *mat = (Mat_SeqDense *) A->data;
5464905a7bcSToby Isaac   PetscScalar       *y;
5474905a7bcSToby Isaac   PetscBLASInt      m=0, k=0;
5484905a7bcSToby Isaac 
5494905a7bcSToby Isaac   PetscFunctionBegin;
5509566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
5519566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&k));
5524905a7bcSToby Isaac   if (k < m) {
5539566063dSJacob Faibussowitsch     PetscCall(VecCopy(xx, mat->qrrhs));
5549566063dSJacob Faibussowitsch     PetscCall(VecGetArray(mat->qrrhs,&y));
5554905a7bcSToby Isaac   } else {
5569566063dSJacob Faibussowitsch     PetscCall(VecCopy(xx, yy));
5579566063dSJacob Faibussowitsch     PetscCall(VecGetArray(yy,&y));
5584905a7bcSToby Isaac   }
5594396437dSToby Isaac   *_y = y;
5604396437dSToby Isaac   *_k = k;
5614396437dSToby Isaac   *_m = m;
5624396437dSToby Isaac   PetscFunctionReturn(0);
5634396437dSToby Isaac }
5644396437dSToby Isaac 
5654396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_TearDown(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k)
5664396437dSToby Isaac {
5674396437dSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense *) A->data;
56842e9364cSSatish Balay   PetscScalar    *y = NULL;
5694396437dSToby Isaac   PetscBLASInt   m, k;
5704396437dSToby Isaac 
5714396437dSToby Isaac   PetscFunctionBegin;
5724396437dSToby Isaac   y   = *_y;
5734396437dSToby Isaac   *_y = NULL;
5744396437dSToby Isaac   k   = *_k;
5754396437dSToby Isaac   m   = *_m;
5764905a7bcSToby Isaac   if (k < m) {
5774905a7bcSToby Isaac     PetscScalar *yv;
5789566063dSJacob Faibussowitsch     PetscCall(VecGetArray(yy,&yv));
5799566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(yv, y, k));
5809566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(yy,&yv));
5819566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(mat->qrrhs, &y));
5824905a7bcSToby Isaac   } else {
5839566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(yy,&y));
5844905a7bcSToby Isaac   }
5854905a7bcSToby Isaac   PetscFunctionReturn(0);
5864905a7bcSToby Isaac }
5874905a7bcSToby Isaac 
5884396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_LU(Mat A, Vec xx, Vec yy)
5894396437dSToby Isaac {
59042e9364cSSatish Balay   PetscScalar    *y = NULL;
59142e9364cSSatish Balay   PetscBLASInt   m = 0, k = 0;
5924396437dSToby Isaac 
5934396437dSToby Isaac   PetscFunctionBegin;
5949566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
5959566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_FALSE));
5969566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
5974396437dSToby Isaac   PetscFunctionReturn(0);
5984396437dSToby Isaac }
5994396437dSToby Isaac 
6004396437dSToby Isaac static PetscErrorCode MatSolveTranspose_SeqDense_LU(Mat A, Vec xx, Vec yy)
6014396437dSToby Isaac {
60242e9364cSSatish Balay   PetscScalar    *y = NULL;
60342e9364cSSatish Balay   PetscBLASInt   m = 0, k = 0;
6044396437dSToby Isaac 
6054396437dSToby Isaac   PetscFunctionBegin;
6069566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6079566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_TRUE));
6089566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6094396437dSToby Isaac   PetscFunctionReturn(0);
6104396437dSToby Isaac }
6114396437dSToby Isaac 
6124396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_Cholesky(Mat A, Vec xx, Vec yy)
6134396437dSToby Isaac {
614e54beecaSStefano Zampini   PetscScalar    *y = NULL;
615e54beecaSStefano Zampini   PetscBLASInt   m = 0, k = 0;
6164396437dSToby Isaac 
6174396437dSToby Isaac   PetscFunctionBegin;
6189566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6199566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_FALSE));
6209566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6214396437dSToby Isaac   PetscFunctionReturn(0);
6224396437dSToby Isaac }
6234396437dSToby Isaac 
6244396437dSToby Isaac static PetscErrorCode MatSolveTranspose_SeqDense_Cholesky(Mat A, Vec xx, Vec yy)
6254396437dSToby Isaac {
626e54beecaSStefano Zampini   PetscScalar    *y = NULL;
627e54beecaSStefano Zampini   PetscBLASInt   m = 0, k = 0;
6284396437dSToby Isaac 
6294396437dSToby Isaac   PetscFunctionBegin;
6309566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6319566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_TRUE));
6329566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6334396437dSToby Isaac   PetscFunctionReturn(0);
6344396437dSToby Isaac }
6354396437dSToby Isaac 
6364396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_QR(Mat A, Vec xx, Vec yy)
6374396437dSToby Isaac {
638e54beecaSStefano Zampini   PetscScalar    *y = NULL;
639e54beecaSStefano Zampini   PetscBLASInt   m = 0, k = 0;
6404396437dSToby Isaac 
6414396437dSToby Isaac   PetscFunctionBegin;
6429566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6439566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_QR(A, y, PetscMax(m,k), m, 1, k));
6449566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6454396437dSToby Isaac   PetscFunctionReturn(0);
6464396437dSToby Isaac }
6474396437dSToby Isaac 
6484396437dSToby Isaac static PetscErrorCode MatSolveTranspose_SeqDense_QR(Mat A, Vec xx, Vec yy)
6494396437dSToby Isaac {
65042e9364cSSatish Balay   PetscScalar    *y = NULL;
65142e9364cSSatish Balay   PetscBLASInt   m = 0, k = 0;
6524396437dSToby Isaac 
6534396437dSToby Isaac   PetscFunctionBegin;
6549566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6559566063dSJacob Faibussowitsch   PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, PetscMax(m,k), m, 1, k));
6569566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6574396437dSToby Isaac   PetscFunctionReturn(0);
6584396437dSToby Isaac }
6594396437dSToby Isaac 
660bf5a80bcSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_SetUp(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k)
6614905a7bcSToby Isaac {
6624905a7bcSToby Isaac   const PetscScalar *b;
6634396437dSToby Isaac   PetscScalar       *y;
664bf5a80bcSToby Isaac   PetscInt          n, _ldb, _ldx;
665bf5a80bcSToby Isaac   PetscBLASInt      nrhs=0,m=0,k=0,ldb=0,ldx=0,ldy=0;
6664905a7bcSToby Isaac 
6674905a7bcSToby Isaac   PetscFunctionBegin;
6686280eecaSJose E. Roman   *_ldy=0; *_m=0; *_nrhs=0; *_k=0; *_y = NULL;
6699566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
6709566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&k));
6719566063dSJacob Faibussowitsch   PetscCall(MatGetSize(B,NULL,&n));
6729566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(n,&nrhs));
6739566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(B,&_ldb));
6749566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldb, &ldb));
6759566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(X,&_ldx));
6769566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldx, &ldx));
677bf5a80bcSToby Isaac   if (ldx < m) {
6789566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(B,&b));
6799566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nrhs * m, &y));
680bf5a80bcSToby Isaac     if (ldb == m) {
6819566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(y,b,ldb*nrhs));
6824905a7bcSToby Isaac     } else {
6834905a7bcSToby Isaac       for (PetscInt j = 0; j < nrhs; j++) {
6849566063dSJacob Faibussowitsch         PetscCall(PetscArraycpy(&y[j*m],&b[j*ldb],m));
6854905a7bcSToby Isaac       }
6864905a7bcSToby Isaac     }
687bf5a80bcSToby Isaac     ldy = m;
6889566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(B,&b));
6894905a7bcSToby Isaac   } else {
690bf5a80bcSToby Isaac     if (ldb == ldx) {
6919566063dSJacob Faibussowitsch       PetscCall(MatCopy(B, X, SAME_NONZERO_PATTERN));
6929566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(X,&y));
6934905a7bcSToby Isaac     } else {
6949566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(X,&y));
6959566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArrayRead(B,&b));
6964905a7bcSToby Isaac       for (PetscInt j = 0; j < nrhs; j++) {
6979566063dSJacob Faibussowitsch         PetscCall(PetscArraycpy(&y[j*ldx],&b[j*ldb],m));
6984905a7bcSToby Isaac       }
6999566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArrayRead(B,&b));
7004905a7bcSToby Isaac     }
701bf5a80bcSToby Isaac     ldy = ldx;
7024905a7bcSToby Isaac   }
7034396437dSToby Isaac   *_y    = y;
704bf5a80bcSToby Isaac   *_ldy = ldy;
7054396437dSToby Isaac   *_k    = k;
7064396437dSToby Isaac   *_m    = m;
7074396437dSToby Isaac   *_nrhs = nrhs;
7084396437dSToby Isaac   PetscFunctionReturn(0);
7094396437dSToby Isaac }
7104396437dSToby Isaac 
711bf5a80bcSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_TearDown(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k)
7124396437dSToby Isaac {
7134396437dSToby Isaac   PetscScalar       *y;
714bf5a80bcSToby Isaac   PetscInt          _ldx;
715bf5a80bcSToby Isaac   PetscBLASInt      k,ldy,nrhs,ldx=0;
7164396437dSToby Isaac 
7174396437dSToby Isaac   PetscFunctionBegin;
7184396437dSToby Isaac   y    = *_y;
7194396437dSToby Isaac   *_y  = NULL;
7204396437dSToby Isaac   k    = *_k;
721bf5a80bcSToby Isaac   ldy = *_ldy;
7224396437dSToby Isaac   nrhs = *_nrhs;
7239566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(X,&_ldx));
7249566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldx, &ldx));
725bf5a80bcSToby Isaac   if (ldx != ldy) {
7264905a7bcSToby Isaac     PetscScalar *xv;
7279566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArray(X,&xv));
7284905a7bcSToby Isaac     for (PetscInt j = 0; j < nrhs; j++) {
7299566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(&xv[j*ldx],&y[j*ldy],k));
7304905a7bcSToby Isaac     }
7319566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(X,&xv));
7329566063dSJacob Faibussowitsch     PetscCall(PetscFree(y));
7334905a7bcSToby Isaac   } else {
7349566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(X,&y));
7354905a7bcSToby Isaac   }
73685e2c93fSHong Zhang   PetscFunctionReturn(0);
73785e2c93fSHong Zhang }
73885e2c93fSHong Zhang 
7394396437dSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_LU(Mat A, Mat B, Mat X)
7404396437dSToby Isaac {
7414396437dSToby Isaac   PetscScalar    *y;
742bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
7434396437dSToby Isaac 
7444396437dSToby Isaac   PetscFunctionBegin;
7459566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7469566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_FALSE));
7479566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7484396437dSToby Isaac   PetscFunctionReturn(0);
7494396437dSToby Isaac }
7504396437dSToby Isaac 
7514396437dSToby Isaac static PetscErrorCode MatMatSolveTranspose_SeqDense_LU(Mat A, Mat B, Mat X)
7524396437dSToby Isaac {
7534396437dSToby Isaac   PetscScalar    *y;
754bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
7554396437dSToby Isaac 
7564396437dSToby Isaac   PetscFunctionBegin;
7579566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7589566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_TRUE));
7599566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7604396437dSToby Isaac   PetscFunctionReturn(0);
7614396437dSToby Isaac }
7624396437dSToby Isaac 
7634396437dSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_Cholesky(Mat A, Mat B, Mat X)
7644396437dSToby Isaac {
7654396437dSToby Isaac   PetscScalar    *y;
766bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
7674396437dSToby Isaac 
7684396437dSToby Isaac   PetscFunctionBegin;
7699566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7709566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_FALSE));
7719566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7724396437dSToby Isaac   PetscFunctionReturn(0);
7734396437dSToby Isaac }
7744396437dSToby Isaac 
7754396437dSToby Isaac static PetscErrorCode MatMatSolveTranspose_SeqDense_Cholesky(Mat A, Mat B, Mat X)
7764396437dSToby Isaac {
7774396437dSToby Isaac   PetscScalar    *y;
778bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
7794396437dSToby Isaac 
7804396437dSToby Isaac   PetscFunctionBegin;
7819566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7829566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_TRUE));
7839566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7844396437dSToby Isaac   PetscFunctionReturn(0);
7854396437dSToby Isaac }
7864396437dSToby Isaac 
7874396437dSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_QR(Mat A, Mat B, Mat X)
7884396437dSToby Isaac {
7894396437dSToby Isaac   PetscScalar    *y;
790bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
7914396437dSToby Isaac 
7924396437dSToby Isaac   PetscFunctionBegin;
7939566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7949566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k));
7959566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7964396437dSToby Isaac   PetscFunctionReturn(0);
7974396437dSToby Isaac }
7984396437dSToby Isaac 
7994396437dSToby Isaac static PetscErrorCode MatMatSolveTranspose_SeqDense_QR(Mat A, Mat B, Mat X)
8004396437dSToby Isaac {
8014396437dSToby Isaac   PetscScalar    *y;
802bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
8034396437dSToby Isaac 
8044396437dSToby Isaac   PetscFunctionBegin;
8059566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
8069566063dSJacob Faibussowitsch   PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k));
8079566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
8084396437dSToby Isaac   PetscFunctionReturn(0);
8094396437dSToby Isaac }
8104396437dSToby Isaac 
81100121966SStefano Zampini static PetscErrorCode MatConjugate_SeqDense(Mat);
81200121966SStefano Zampini 
813db4efbfdSBarry Smith /* ---------------------------------------------------------------*/
814db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots,
815db4efbfdSBarry Smith    rather than put it in the Mat->row slot.*/
816ca15aa20SStefano Zampini PetscErrorCode MatLUFactor_SeqDense(Mat A,IS row,IS col,const MatFactorInfo *minfo)
817db4efbfdSBarry Smith {
818db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
819db4efbfdSBarry Smith   PetscBLASInt   n,m,info;
820db4efbfdSBarry Smith 
821db4efbfdSBarry Smith   PetscFunctionBegin;
8229566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
8239566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
824db4efbfdSBarry Smith   if (!mat->pivots) {
8259566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(A->rmap->n,&mat->pivots));
8269566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt)));
827db4efbfdSBarry Smith   }
828db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
8299566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
8308b83055fSJed Brown   PetscStackCallBLAS("LAPACKgetrf",LAPACKgetrf_(&m,&n,mat->v,&mat->lda,mat->pivots,&info));
8319566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
8328e57ea43SSatish Balay 
83308401ef6SPierre Jolivet   PetscCheck(info>=0,PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to LU factorization");
83408401ef6SPierre Jolivet   PetscCheck(info<=0,PETSC_COMM_SELF,PETSC_ERR_MAT_LU_ZRPVT,"Bad LU factorization");
8358208b9aeSStefano Zampini 
8364396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_LU;
8374396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_LU;
8384396437dSToby Isaac   A->ops->solvetranspose    = MatSolveTranspose_SeqDense_LU;
8394396437dSToby Isaac   A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_LU;
840d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_LU;
841db4efbfdSBarry Smith 
8429566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
8439566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC,&A->solvertype));
844f6224b95SHong Zhang 
8459566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops((2.0*A->cmap->n*A->cmap->n*A->cmap->n)/3));
846db4efbfdSBarry Smith   PetscFunctionReturn(0);
847db4efbfdSBarry Smith }
848db4efbfdSBarry Smith 
8494396437dSToby Isaac static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
8504396437dSToby Isaac {
8514396437dSToby Isaac   MatFactorInfo  info;
8524396437dSToby Isaac 
8534396437dSToby Isaac   PetscFunctionBegin;
8549566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES));
8559566063dSJacob Faibussowitsch   PetscCall((*fact->ops->lufactor)(fact,NULL,NULL,&info));
8564396437dSToby Isaac   PetscFunctionReturn(0);
8574396437dSToby Isaac }
8584396437dSToby Isaac 
8594396437dSToby Isaac PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,IS col,const MatFactorInfo *info)
8604396437dSToby Isaac {
8614396437dSToby Isaac   PetscFunctionBegin;
8624396437dSToby Isaac   fact->preallocated           = PETSC_TRUE;
8634396437dSToby Isaac   fact->assembled              = PETSC_TRUE;
8644396437dSToby Isaac   fact->ops->lufactornumeric   = MatLUFactorNumeric_SeqDense;
8654396437dSToby Isaac   PetscFunctionReturn(0);
8664396437dSToby Isaac }
8674396437dSToby Isaac 
868a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */
869ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactor_SeqDense(Mat A,IS perm,const MatFactorInfo *factinfo)
870db4efbfdSBarry Smith {
871db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
872c5df96a5SBarry Smith   PetscBLASInt   info,n;
873db4efbfdSBarry Smith 
874db4efbfdSBarry Smith   PetscFunctionBegin;
8759566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
876db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
877a49dc2a2SStefano Zampini   if (A->spd) {
8789566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
8798b83055fSJed Brown     PetscStackCallBLAS("LAPACKpotrf",LAPACKpotrf_("L",&n,mat->v,&mat->lda,&info));
8809566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
881a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
882a49dc2a2SStefano Zampini   } else if (A->hermitian) {
883a49dc2a2SStefano Zampini     if (!mat->pivots) {
8849566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(A->rmap->n,&mat->pivots));
8859566063dSJacob Faibussowitsch       PetscCall(PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt)));
886a49dc2a2SStefano Zampini     }
887a49dc2a2SStefano Zampini     if (!mat->fwork) {
888a49dc2a2SStefano Zampini       PetscScalar dummy;
889a49dc2a2SStefano Zampini 
890a49dc2a2SStefano Zampini       mat->lfwork = -1;
8919566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
892a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
8939566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
894a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
8959566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(mat->lfwork,&mat->fwork));
8969566063dSJacob Faibussowitsch       PetscCall(PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt)));
897a49dc2a2SStefano Zampini     }
8989566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
899a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
9009566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
901a49dc2a2SStefano Zampini #endif
902a49dc2a2SStefano Zampini   } else { /* symmetric case */
903a49dc2a2SStefano Zampini     if (!mat->pivots) {
9049566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(A->rmap->n,&mat->pivots));
9059566063dSJacob Faibussowitsch       PetscCall(PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt)));
906a49dc2a2SStefano Zampini     }
907a49dc2a2SStefano Zampini     if (!mat->fwork) {
908a49dc2a2SStefano Zampini       PetscScalar dummy;
909a49dc2a2SStefano Zampini 
910a49dc2a2SStefano Zampini       mat->lfwork = -1;
9119566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
912a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
9139566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
914a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
9159566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(mat->lfwork,&mat->fwork));
9169566063dSJacob Faibussowitsch       PetscCall(PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt)));
917a49dc2a2SStefano Zampini     }
9189566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
919a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
9209566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
921a49dc2a2SStefano Zampini   }
92228b400f6SJacob Faibussowitsch   PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad factorization: zero pivot in row %" PetscInt_FMT,(PetscInt)info-1);
9238208b9aeSStefano Zampini 
9244396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_Cholesky;
9254396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_Cholesky;
9264396437dSToby Isaac   A->ops->solvetranspose    = MatSolveTranspose_SeqDense_Cholesky;
9274396437dSToby Isaac   A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_Cholesky;
928d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_CHOLESKY;
9292205254eSKarl Rupp 
9309566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
9319566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC,&A->solvertype));
932f6224b95SHong Zhang 
9339566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0));
934db4efbfdSBarry Smith   PetscFunctionReturn(0);
935db4efbfdSBarry Smith }
936db4efbfdSBarry Smith 
9374396437dSToby Isaac static PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
938db4efbfdSBarry Smith {
939db4efbfdSBarry Smith   MatFactorInfo  info;
940db4efbfdSBarry Smith 
941db4efbfdSBarry Smith   PetscFunctionBegin;
942db4efbfdSBarry Smith   info.fill = 1.0;
9432205254eSKarl Rupp 
9449566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES));
9459566063dSJacob Faibussowitsch   PetscCall((*fact->ops->choleskyfactor)(fact,NULL,&info));
946db4efbfdSBarry Smith   PetscFunctionReturn(0);
947db4efbfdSBarry Smith }
948db4efbfdSBarry Smith 
949ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info)
950db4efbfdSBarry Smith {
951db4efbfdSBarry Smith   PetscFunctionBegin;
952c3ef05f6SHong Zhang   fact->assembled                  = PETSC_TRUE;
9531bbcc794SSatish Balay   fact->preallocated               = PETSC_TRUE;
954719d5645SBarry Smith   fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense;
955db4efbfdSBarry Smith   PetscFunctionReturn(0);
956db4efbfdSBarry Smith }
957db4efbfdSBarry Smith 
958bf5a80bcSToby Isaac PetscErrorCode MatQRFactor_SeqDense(Mat A,IS col,const MatFactorInfo *minfo)
9594905a7bcSToby Isaac {
9604905a7bcSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
9614905a7bcSToby Isaac   PetscBLASInt   n,m,info, min, max;
9624905a7bcSToby Isaac 
9634905a7bcSToby Isaac   PetscFunctionBegin;
9649566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
9659566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
9664396437dSToby Isaac   max = PetscMax(m, n);
9674396437dSToby Isaac   min = PetscMin(m, n);
9684905a7bcSToby Isaac   if (!mat->tau) {
9699566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(min,&mat->tau));
9709566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)A,min*sizeof(PetscScalar)));
9714396437dSToby Isaac   }
9724396437dSToby Isaac   if (!mat->pivots) {
9739566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n,&mat->pivots));
9749566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)A,n*sizeof(PetscScalar)));
9754396437dSToby Isaac   }
9764396437dSToby Isaac   if (!mat->qrrhs) {
9779566063dSJacob Faibussowitsch     PetscCall(MatCreateVecs(A, NULL, &(mat->qrrhs)));
9784905a7bcSToby Isaac   }
9794905a7bcSToby Isaac   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
9804905a7bcSToby Isaac   if (!mat->fwork) {
9814905a7bcSToby Isaac     PetscScalar dummy;
9824905a7bcSToby Isaac 
9834905a7bcSToby Isaac     mat->lfwork = -1;
9849566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
9854905a7bcSToby Isaac     PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&m,&n,mat->v,&mat->lda,mat->tau,&dummy,&mat->lfwork,&info));
9869566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
9874905a7bcSToby Isaac     mat->lfwork = (PetscInt)PetscRealPart(dummy);
9889566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(mat->lfwork,&mat->fwork));
9899566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt)));
9904905a7bcSToby Isaac   }
9919566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
9924905a7bcSToby Isaac   PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&m,&n,mat->v,&mat->lda,mat->tau,mat->fwork,&mat->lfwork,&info));
9939566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
99428b400f6SJacob Faibussowitsch   PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to QR factorization");
9954905a7bcSToby 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
9964905a7bcSToby Isaac   mat->rank = min;
9974905a7bcSToby Isaac 
9984396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_QR;
9994396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_QR;
10004905a7bcSToby Isaac   A->factortype             = MAT_FACTOR_QR;
10014905a7bcSToby Isaac   if (m == n) {
10024396437dSToby Isaac     A->ops->solvetranspose    = MatSolveTranspose_SeqDense_QR;
10034396437dSToby Isaac     A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_QR;
10044905a7bcSToby Isaac   }
10054905a7bcSToby Isaac 
10069566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
10079566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC,&A->solvertype));
10084905a7bcSToby Isaac 
10099566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0*min*min*(max-min/3.0)));
10104905a7bcSToby Isaac   PetscFunctionReturn(0);
10114905a7bcSToby Isaac }
10124905a7bcSToby Isaac 
10134905a7bcSToby Isaac static PetscErrorCode MatQRFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
10144905a7bcSToby Isaac {
10154905a7bcSToby Isaac   MatFactorInfo  info;
10164905a7bcSToby Isaac 
10174905a7bcSToby Isaac   PetscFunctionBegin;
10184905a7bcSToby Isaac   info.fill = 1.0;
10194905a7bcSToby Isaac 
10209566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES));
1021cac4c232SBarry Smith   PetscUseMethod(fact,"MatQRFactor_C",(Mat,IS,const MatFactorInfo *),(fact,NULL,&info));
10224905a7bcSToby Isaac   PetscFunctionReturn(0);
10234905a7bcSToby Isaac }
10244905a7bcSToby Isaac 
1025bf5a80bcSToby Isaac PetscErrorCode MatQRFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info)
10264905a7bcSToby Isaac {
10274905a7bcSToby Isaac   PetscFunctionBegin;
10284905a7bcSToby Isaac   fact->assembled                  = PETSC_TRUE;
10294905a7bcSToby Isaac   fact->preallocated               = PETSC_TRUE;
10309566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)fact,"MatQRFactorNumeric_C",MatQRFactorNumeric_SeqDense));
10314905a7bcSToby Isaac   PetscFunctionReturn(0);
10324905a7bcSToby Isaac }
10334905a7bcSToby Isaac 
1034ca15aa20SStefano Zampini /* uses LAPACK */
1035cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A,MatFactorType ftype,Mat *fact)
1036db4efbfdSBarry Smith {
1037db4efbfdSBarry Smith   PetscFunctionBegin;
10389566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A),fact));
10399566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*fact,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n));
10409566063dSJacob Faibussowitsch   PetscCall(MatSetType(*fact,MATDENSE));
104166e17bc3SBarry Smith   (*fact)->trivialsymbolic = PETSC_TRUE;
10422a350339SBarry Smith   if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU) {
1043db4efbfdSBarry Smith     (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense;
10442a350339SBarry Smith     (*fact)->ops->ilufactorsymbolic = MatLUFactorSymbolic_SeqDense;
1045bf5a80bcSToby Isaac   } else if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) {
1046db4efbfdSBarry Smith     (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense;
1047bf5a80bcSToby Isaac   } else if (ftype == MAT_FACTOR_QR) {
10489566063dSJacob Faibussowitsch     PetscCall(PetscObjectComposeFunction((PetscObject)(*fact),"MatQRFactorSymbolic_C",MatQRFactorSymbolic_SeqDense));
1049db4efbfdSBarry Smith   }
1050d5f3da31SBarry Smith   (*fact)->factortype = ftype;
105100c67f3bSHong Zhang 
10529566063dSJacob Faibussowitsch   PetscCall(PetscFree((*fact)->solvertype));
10539566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC,&(*fact)->solvertype));
10549566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_LU]));
10559566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_ILU]));
10569566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_CHOLESKY]));
10579566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_ICC]));
1058db4efbfdSBarry Smith   PetscFunctionReturn(0);
1059db4efbfdSBarry Smith }
1060db4efbfdSBarry Smith 
1061289bc588SBarry Smith /* ------------------------------------------------------------------*/
1062e0877f53SBarry Smith static PetscErrorCode MatSOR_SeqDense(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec xx)
1063289bc588SBarry Smith {
1064c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1065d9ca1df4SBarry Smith   PetscScalar       *x,*v = mat->v,zero = 0.0,xt;
1066d9ca1df4SBarry Smith   const PetscScalar *b;
1067d0f46423SBarry Smith   PetscInt          m = A->rmap->n,i;
106823fff9afSBarry Smith   PetscBLASInt      o = 1,bm = 0;
1069289bc588SBarry Smith 
10703a40ed3dSBarry Smith   PetscFunctionBegin;
1071ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
107208401ef6SPierre Jolivet   PetscCheck(A->offloadmask != PETSC_OFFLOAD_GPU,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented");
1073ca15aa20SStefano Zampini #endif
1074422a814eSBarry Smith   if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */
10759566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(m,&bm));
1076289bc588SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
10773bffc371SBarry Smith     /* this is a hack fix, should have another version without the second BLASdotu */
10789566063dSJacob Faibussowitsch     PetscCall(VecSet(xx,zero));
1079289bc588SBarry Smith   }
10809566063dSJacob Faibussowitsch   PetscCall(VecGetArray(xx,&x));
10819566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(bb,&b));
1082b965ef7fSBarry Smith   its  = its*lits;
108308401ef6SPierre Jolivet   PetscCheck(its > 0,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %" PetscInt_FMT " and local its %" PetscInt_FMT " both positive",its,lits);
1084289bc588SBarry Smith   while (its--) {
1085fccaa45eSBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
1086289bc588SBarry Smith       for (i=0; i<m; i++) {
10873bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
108855a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
1089289bc588SBarry Smith       }
1090289bc588SBarry Smith     }
1091fccaa45eSBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
1092289bc588SBarry Smith       for (i=m-1; i>=0; i--) {
10933bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
109455a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
1095289bc588SBarry Smith       }
1096289bc588SBarry Smith     }
1097289bc588SBarry Smith   }
10989566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(bb,&b));
10999566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(xx,&x));
11003a40ed3dSBarry Smith   PetscFunctionReturn(0);
1101289bc588SBarry Smith }
1102289bc588SBarry Smith 
1103289bc588SBarry Smith /* -----------------------------------------------------------------*/
1104ca15aa20SStefano Zampini PetscErrorCode MatMultTranspose_SeqDense(Mat A,Vec xx,Vec yy)
1105289bc588SBarry Smith {
1106c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1107d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v,*x;
1108d9ca1df4SBarry Smith   PetscScalar       *y;
11090805154bSBarry Smith   PetscBLASInt      m, n,_One=1;
1110ea709b57SSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
11113a40ed3dSBarry Smith 
11123a40ed3dSBarry Smith   PetscFunctionBegin;
11139566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
11149566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
11159566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx,&x));
11169566063dSJacob Faibussowitsch   PetscCall(VecGetArrayWrite(yy,&y));
11175ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
11185ac36cfcSBarry Smith     PetscBLASInt i;
11195ac36cfcSBarry Smith     for (i=0; i<n; i++) y[i] = 0.0;
11205ac36cfcSBarry Smith   } else {
11218b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&mat->lda,x,&_One,&_DZero,y,&_One));
11229566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->cmap->n));
11235ac36cfcSBarry Smith   }
11249566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx,&x));
11259566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayWrite(yy,&y));
11263a40ed3dSBarry Smith   PetscFunctionReturn(0);
1127289bc588SBarry Smith }
1128800995b7SMatthew Knepley 
1129ca15aa20SStefano Zampini PetscErrorCode MatMult_SeqDense(Mat A,Vec xx,Vec yy)
1130289bc588SBarry Smith {
1131c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1132d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0,_DZero=0.0;
11330805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
1134d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
11353a40ed3dSBarry Smith 
11363a40ed3dSBarry Smith   PetscFunctionBegin;
11379566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
11389566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
11399566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx,&x));
11409566063dSJacob Faibussowitsch   PetscCall(VecGetArrayWrite(yy,&y));
11415ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
11425ac36cfcSBarry Smith     PetscBLASInt i;
11435ac36cfcSBarry Smith     for (i=0; i<m; i++) y[i] = 0.0;
11445ac36cfcSBarry Smith   } else {
11458b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DZero,y,&_One));
11469566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->rmap->n));
11475ac36cfcSBarry Smith   }
11489566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx,&x));
11499566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayWrite(yy,&y));
11503a40ed3dSBarry Smith   PetscFunctionReturn(0);
1151289bc588SBarry Smith }
11526ee01492SSatish Balay 
1153ca15aa20SStefano Zampini PetscErrorCode MatMultAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
1154289bc588SBarry Smith {
1155c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1156d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
1157d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0;
11580805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
11593a40ed3dSBarry Smith 
11603a40ed3dSBarry Smith   PetscFunctionBegin;
11619566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
11629566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
11639566063dSJacob Faibussowitsch   PetscCall(VecCopy(zz,yy));
1164d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
11659566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx,&x));
11669566063dSJacob Faibussowitsch   PetscCall(VecGetArray(yy,&y));
11678b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
11689566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx,&x));
11699566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(yy,&y));
11709566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0*A->rmap->n*A->cmap->n));
11713a40ed3dSBarry Smith   PetscFunctionReturn(0);
1172289bc588SBarry Smith }
11736ee01492SSatish Balay 
1174ca15aa20SStefano Zampini PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
1175289bc588SBarry Smith {
1176c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1177d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
1178d9ca1df4SBarry Smith   PetscScalar       *y;
11790805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
118087828ca2SBarry Smith   PetscScalar       _DOne=1.0;
11813a40ed3dSBarry Smith 
11823a40ed3dSBarry Smith   PetscFunctionBegin;
11839566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
11849566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
11859566063dSJacob Faibussowitsch   PetscCall(VecCopy(zz,yy));
1186d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
11879566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx,&x));
11889566063dSJacob Faibussowitsch   PetscCall(VecGetArray(yy,&y));
11898b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
11909566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx,&x));
11919566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(yy,&y));
11929566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0*A->rmap->n*A->cmap->n));
11933a40ed3dSBarry Smith   PetscFunctionReturn(0);
1194289bc588SBarry Smith }
1195289bc588SBarry Smith 
1196289bc588SBarry Smith /* -----------------------------------------------------------------*/
1197e0877f53SBarry Smith static PetscErrorCode MatGetRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
1198289bc588SBarry Smith {
1199c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
120013f74950SBarry Smith   PetscInt       i;
120167e560aaSBarry Smith 
12023a40ed3dSBarry Smith   PetscFunctionBegin;
1203d0f46423SBarry Smith   *ncols = A->cmap->n;
1204289bc588SBarry Smith   if (cols) {
12059566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(A->cmap->n,cols));
1206d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) (*cols)[i] = i;
1207289bc588SBarry Smith   }
1208289bc588SBarry Smith   if (vals) {
1209ca15aa20SStefano Zampini     const PetscScalar *v;
1210ca15aa20SStefano Zampini 
12119566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A,&v));
12129566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(A->cmap->n,vals));
1213ca15aa20SStefano Zampini     v   += row;
1214d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {(*vals)[i] = *v; v += mat->lda;}
12159566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A,&v));
1216289bc588SBarry Smith   }
12173a40ed3dSBarry Smith   PetscFunctionReturn(0);
1218289bc588SBarry Smith }
12196ee01492SSatish Balay 
1220e0877f53SBarry Smith static PetscErrorCode MatRestoreRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
1221289bc588SBarry Smith {
1222606d414cSSatish Balay   PetscFunctionBegin;
1223cb4a9cd9SHong Zhang   if (ncols) *ncols = 0;
12249566063dSJacob Faibussowitsch   if (cols) PetscCall(PetscFree(*cols));
12259566063dSJacob Faibussowitsch   if (vals) PetscCall(PetscFree(*vals));
12263a40ed3dSBarry Smith   PetscFunctionReturn(0);
1227289bc588SBarry Smith }
1228289bc588SBarry Smith /* ----------------------------------------------------------------*/
1229e0877f53SBarry Smith static PetscErrorCode MatSetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],const PetscScalar v[],InsertMode addv)
1230289bc588SBarry Smith {
1231c0bbcb79SLois Curfman McInnes   Mat_SeqDense     *mat = (Mat_SeqDense*)A->data;
1232ca15aa20SStefano Zampini   PetscScalar      *av;
123313f74950SBarry Smith   PetscInt         i,j,idx=0;
1234ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1235c70f7ee4SJunchao Zhang   PetscOffloadMask oldf;
1236ca15aa20SStefano Zampini #endif
1237d6dfbf8fSBarry Smith 
12383a40ed3dSBarry Smith   PetscFunctionBegin;
12399566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&av));
1240289bc588SBarry Smith   if (!mat->roworiented) {
1241dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1242289bc588SBarry Smith       for (j=0; j<n; j++) {
1243cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
12446bdcaf15SBarry 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);
1245289bc588SBarry Smith         for (i=0; i<m; i++) {
1246cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
12476bdcaf15SBarry 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);
1248ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
1249289bc588SBarry Smith         }
1250289bc588SBarry Smith       }
12513a40ed3dSBarry Smith     } else {
1252289bc588SBarry Smith       for (j=0; j<n; j++) {
1253cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
12546bdcaf15SBarry Smith         PetscCheck(indexn[j] < A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %" PetscInt_FMT " max %" PetscInt_FMT,indexn[j],A->cmap->n-1);
1255289bc588SBarry Smith         for (i=0; i<m; i++) {
1256cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
12576bdcaf15SBarry 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);
1258ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
1259289bc588SBarry Smith         }
1260289bc588SBarry Smith       }
1261289bc588SBarry Smith     }
12623a40ed3dSBarry Smith   } else {
1263dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1264e8d4e0b9SBarry Smith       for (i=0; i<m; i++) {
1265cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
12666bdcaf15SBarry 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);
1267e8d4e0b9SBarry Smith         for (j=0; j<n; j++) {
1268cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
12696bdcaf15SBarry 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);
1270ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
1271e8d4e0b9SBarry Smith         }
1272e8d4e0b9SBarry Smith       }
12733a40ed3dSBarry Smith     } else {
1274289bc588SBarry Smith       for (i=0; i<m; i++) {
1275cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
12766bdcaf15SBarry 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);
1277289bc588SBarry Smith         for (j=0; j<n; j++) {
1278cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
12796bdcaf15SBarry 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);
1280ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
1281289bc588SBarry Smith         }
1282289bc588SBarry Smith       }
1283289bc588SBarry Smith     }
1284e8d4e0b9SBarry Smith   }
1285ca15aa20SStefano Zampini   /* hack to prevent unneeded copy to the GPU while returning the array */
1286ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1287c70f7ee4SJunchao Zhang   oldf = A->offloadmask;
1288c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_GPU;
1289ca15aa20SStefano Zampini #endif
12909566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&av));
1291ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1292c70f7ee4SJunchao Zhang   A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU);
1293ca15aa20SStefano Zampini #endif
12943a40ed3dSBarry Smith   PetscFunctionReturn(0);
1295289bc588SBarry Smith }
1296e8d4e0b9SBarry Smith 
1297e0877f53SBarry Smith static PetscErrorCode MatGetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],PetscScalar v[])
1298ae80bb75SLois Curfman McInnes {
1299ae80bb75SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1300ca15aa20SStefano Zampini   const PetscScalar *vv;
130113f74950SBarry Smith   PetscInt          i,j;
1302ae80bb75SLois Curfman McInnes 
13033a40ed3dSBarry Smith   PetscFunctionBegin;
13049566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&vv));
1305ae80bb75SLois Curfman McInnes   /* row-oriented output */
1306ae80bb75SLois Curfman McInnes   for (i=0; i<m; i++) {
130797e567efSBarry Smith     if (indexm[i] < 0) {v += n;continue;}
130808401ef6SPierre Jolivet     PetscCheck(indexm[i] < A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %" PetscInt_FMT " requested larger than number rows %" PetscInt_FMT,indexm[i],A->rmap->n);
1309ae80bb75SLois Curfman McInnes     for (j=0; j<n; j++) {
13106f31f424SBarry Smith       if (indexn[j] < 0) {v++; continue;}
131108401ef6SPierre Jolivet       PetscCheck(indexn[j] < A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column %" PetscInt_FMT " requested larger than number columns %" PetscInt_FMT,indexn[j],A->cmap->n);
1312ca15aa20SStefano Zampini       *v++ = vv[indexn[j]*mat->lda + indexm[i]];
1313ae80bb75SLois Curfman McInnes     }
1314ae80bb75SLois Curfman McInnes   }
13159566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&vv));
13163a40ed3dSBarry Smith   PetscFunctionReturn(0);
1317ae80bb75SLois Curfman McInnes }
1318ae80bb75SLois Curfman McInnes 
1319289bc588SBarry Smith /* -----------------------------------------------------------------*/
1320289bc588SBarry Smith 
13218491ab44SLisandro Dalcin PetscErrorCode MatView_Dense_Binary(Mat mat,PetscViewer viewer)
1322aabbc4fbSShri Abhyankar {
13238491ab44SLisandro Dalcin   PetscBool         skipHeader;
13248491ab44SLisandro Dalcin   PetscViewerFormat format;
13258491ab44SLisandro Dalcin   PetscInt          header[4],M,N,m,lda,i,j,k;
13268491ab44SLisandro Dalcin   const PetscScalar *v;
13278491ab44SLisandro Dalcin   PetscScalar       *vwork;
1328aabbc4fbSShri Abhyankar 
1329aabbc4fbSShri Abhyankar   PetscFunctionBegin;
13309566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
13319566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryGetSkipHeader(viewer,&skipHeader));
13329566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer,&format));
13338491ab44SLisandro Dalcin   if (skipHeader) format = PETSC_VIEWER_NATIVE;
1334aabbc4fbSShri Abhyankar 
13359566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat,&M,&N));
13368491ab44SLisandro Dalcin 
13378491ab44SLisandro Dalcin   /* write matrix header */
13388491ab44SLisandro Dalcin   header[0] = MAT_FILE_CLASSID; header[1] = M; header[2] = N;
13398491ab44SLisandro Dalcin   header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M*N;
13409566063dSJacob Faibussowitsch   if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer,header,4,PETSC_INT));
13418491ab44SLisandro Dalcin 
13429566063dSJacob Faibussowitsch   PetscCall(MatGetLocalSize(mat,&m,NULL));
13438491ab44SLisandro Dalcin   if (format != PETSC_VIEWER_NATIVE) {
13448491ab44SLisandro Dalcin     PetscInt nnz = m*N, *iwork;
13458491ab44SLisandro Dalcin     /* store row lengths for each row */
13469566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nnz,&iwork));
13478491ab44SLisandro Dalcin     for (i=0; i<m; i++) iwork[i] = N;
13489566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWriteAll(viewer,iwork,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT));
13498491ab44SLisandro Dalcin     /* store column indices (zero start index) */
13508491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
13518491ab44SLisandro Dalcin       for (j=0; j<N; j++, k++)
13528491ab44SLisandro Dalcin         iwork[k] = j;
13539566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWriteAll(viewer,iwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT));
13549566063dSJacob Faibussowitsch     PetscCall(PetscFree(iwork));
13558491ab44SLisandro Dalcin   }
13568491ab44SLisandro Dalcin   /* store matrix values as a dense matrix in row major order */
13579566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(m*N,&vwork));
13589566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(mat,&v));
13599566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(mat,&lda));
13608491ab44SLisandro Dalcin   for (k=0, i=0; i<m; i++)
13618491ab44SLisandro Dalcin     for (j=0; j<N; j++, k++)
13628491ab44SLisandro Dalcin       vwork[k] = v[i+lda*j];
13639566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(mat,&v));
13649566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryWriteAll(viewer,vwork,m*N,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR));
13659566063dSJacob Faibussowitsch   PetscCall(PetscFree(vwork));
13668491ab44SLisandro Dalcin   PetscFunctionReturn(0);
13678491ab44SLisandro Dalcin }
13688491ab44SLisandro Dalcin 
13698491ab44SLisandro Dalcin PetscErrorCode MatLoad_Dense_Binary(Mat mat,PetscViewer viewer)
13708491ab44SLisandro Dalcin {
13718491ab44SLisandro Dalcin   PetscBool      skipHeader;
13728491ab44SLisandro Dalcin   PetscInt       header[4],M,N,m,nz,lda,i,j,k;
13738491ab44SLisandro Dalcin   PetscInt       rows,cols;
13748491ab44SLisandro Dalcin   PetscScalar    *v,*vwork;
13758491ab44SLisandro Dalcin 
13768491ab44SLisandro Dalcin   PetscFunctionBegin;
13779566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
13789566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryGetSkipHeader(viewer,&skipHeader));
13798491ab44SLisandro Dalcin 
13808491ab44SLisandro Dalcin   if (!skipHeader) {
13819566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryRead(viewer,header,4,NULL,PETSC_INT));
138208401ef6SPierre Jolivet     PetscCheck(header[0] == MAT_FILE_CLASSID,PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Not a matrix object in file");
13838491ab44SLisandro Dalcin     M = header[1]; N = header[2];
138408401ef6SPierre Jolivet     PetscCheck(M >= 0,PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix row size (%" PetscInt_FMT ") in file is negative",M);
138508401ef6SPierre Jolivet     PetscCheck(N >= 0,PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix column size (%" PetscInt_FMT ") in file is negative",N);
13868491ab44SLisandro Dalcin     nz = header[3];
1387aed4548fSBarry Smith     PetscCheck(nz == MATRIX_BINARY_FORMAT_DENSE || nz >= 0,PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Unknown matrix format %" PetscInt_FMT " in file",nz);
1388aabbc4fbSShri Abhyankar   } else {
13899566063dSJacob Faibussowitsch     PetscCall(MatGetSize(mat,&M,&N));
1390aed4548fSBarry Smith     PetscCheck(M >= 0 && N >= 0,PETSC_COMM_SELF,PETSC_ERR_USER,"Matrix binary file header was skipped, thus the user must specify the global sizes of input matrix");
13918491ab44SLisandro Dalcin     nz = MATRIX_BINARY_FORMAT_DENSE;
1392e6324fbbSBarry Smith   }
1393aabbc4fbSShri Abhyankar 
13948491ab44SLisandro Dalcin   /* setup global sizes if not set */
13958491ab44SLisandro Dalcin   if (mat->rmap->N < 0) mat->rmap->N = M;
13968491ab44SLisandro Dalcin   if (mat->cmap->N < 0) mat->cmap->N = N;
13979566063dSJacob Faibussowitsch   PetscCall(MatSetUp(mat));
13988491ab44SLisandro Dalcin   /* check if global sizes are correct */
13999566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat,&rows,&cols));
1400aed4548fSBarry Smith   PetscCheck(M == rows && N == cols,PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED, "Matrix in file of different sizes (%" PetscInt_FMT ", %" PetscInt_FMT ") than the input matrix (%" PetscInt_FMT ", %" PetscInt_FMT ")",M,N,rows,cols);
1401aabbc4fbSShri Abhyankar 
14029566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat,NULL,&N));
14039566063dSJacob Faibussowitsch   PetscCall(MatGetLocalSize(mat,&m,NULL));
14049566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(mat,&v));
14059566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(mat,&lda));
14068491ab44SLisandro Dalcin   if (nz == MATRIX_BINARY_FORMAT_DENSE) {  /* matrix in file is dense format */
14078491ab44SLisandro Dalcin     PetscInt nnz = m*N;
14088491ab44SLisandro Dalcin     /* read in matrix values */
14099566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nnz,&vwork));
14109566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR));
14118491ab44SLisandro Dalcin     /* store values in column major order */
14128491ab44SLisandro Dalcin     for (j=0; j<N; j++)
14138491ab44SLisandro Dalcin       for (i=0; i<m; i++)
14148491ab44SLisandro Dalcin         v[i+lda*j] = vwork[i*N+j];
14159566063dSJacob Faibussowitsch     PetscCall(PetscFree(vwork));
14168491ab44SLisandro Dalcin   } else { /* matrix in file is sparse format */
14178491ab44SLisandro Dalcin     PetscInt nnz = 0, *rlens, *icols;
14188491ab44SLisandro Dalcin     /* read in row lengths */
14199566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(m,&rlens));
14209566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer,rlens,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT));
14218491ab44SLisandro Dalcin     for (i=0; i<m; i++) nnz += rlens[i];
14228491ab44SLisandro Dalcin     /* read in column indices and values */
14239566063dSJacob Faibussowitsch     PetscCall(PetscMalloc2(nnz,&icols,nnz,&vwork));
14249566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer,icols,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT));
14259566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR));
14268491ab44SLisandro Dalcin     /* store values in column major order */
14278491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
14288491ab44SLisandro Dalcin       for (j=0; j<rlens[i]; j++, k++)
14298491ab44SLisandro Dalcin         v[i+lda*icols[k]] = vwork[k];
14309566063dSJacob Faibussowitsch     PetscCall(PetscFree(rlens));
14319566063dSJacob Faibussowitsch     PetscCall(PetscFree2(icols,vwork));
1432aabbc4fbSShri Abhyankar   }
14339566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(mat,&v));
14349566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY));
14359566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY));
1436aabbc4fbSShri Abhyankar   PetscFunctionReturn(0);
1437aabbc4fbSShri Abhyankar }
1438aabbc4fbSShri Abhyankar 
1439eb91f321SVaclav Hapla PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer)
1440eb91f321SVaclav Hapla {
1441eb91f321SVaclav Hapla   PetscBool      isbinary, ishdf5;
1442eb91f321SVaclav Hapla 
1443eb91f321SVaclav Hapla   PetscFunctionBegin;
1444eb91f321SVaclav Hapla   PetscValidHeaderSpecific(newMat,MAT_CLASSID,1);
1445eb91f321SVaclav Hapla   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1446eb91f321SVaclav Hapla   /* force binary viewer to load .info file if it has not yet done so */
14479566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
14489566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary));
14499566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,  &ishdf5));
1450eb91f321SVaclav Hapla   if (isbinary) {
14519566063dSJacob Faibussowitsch     PetscCall(MatLoad_Dense_Binary(newMat,viewer));
1452eb91f321SVaclav Hapla   } else if (ishdf5) {
1453eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5)
14549566063dSJacob Faibussowitsch     PetscCall(MatLoad_Dense_HDF5(newMat,viewer));
1455eb91f321SVaclav Hapla #else
1456eb91f321SVaclav Hapla     SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5");
1457eb91f321SVaclav Hapla #endif
1458eb91f321SVaclav Hapla   } else {
145998921bdaSJacob 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);
1460eb91f321SVaclav Hapla   }
1461eb91f321SVaclav Hapla   PetscFunctionReturn(0);
1462eb91f321SVaclav Hapla }
1463eb91f321SVaclav Hapla 
14646849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_ASCII(Mat A,PetscViewer viewer)
1465289bc588SBarry Smith {
1466932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
146713f74950SBarry Smith   PetscInt          i,j;
14682dcb1b2aSMatthew Knepley   const char        *name;
1469ca15aa20SStefano Zampini   PetscScalar       *v,*av;
1470f3ef73ceSBarry Smith   PetscViewerFormat format;
14715f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX)
1472ace3abfcSBarry Smith   PetscBool         allreal = PETSC_TRUE;
14735f481a85SSatish Balay #endif
1474932b0c3eSLois Curfman McInnes 
14753a40ed3dSBarry Smith   PetscFunctionBegin;
14769566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,(const PetscScalar**)&av));
14779566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer,&format));
1478456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
14793a40ed3dSBarry Smith     PetscFunctionReturn(0);  /* do nothing for now */
1480fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
14819566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE));
1482d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1483ca15aa20SStefano Zampini       v    = av + i;
14849566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"row %" PetscInt_FMT ":",i));
1485d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1486aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1487329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
14889566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g + %g i) ",j,(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v)));
1489329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
14909566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g) ",j,(double)PetscRealPart(*v)));
14916831982aSBarry Smith         }
149280cd9d93SLois Curfman McInnes #else
14936831982aSBarry Smith         if (*v) {
14949566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g) ",j,(double)*v));
14956831982aSBarry Smith         }
149680cd9d93SLois Curfman McInnes #endif
14971b807ce4Svictorle         v += a->lda;
149880cd9d93SLois Curfman McInnes       }
14999566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"\n"));
150080cd9d93SLois Curfman McInnes     }
15019566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE));
15023a40ed3dSBarry Smith   } else {
15039566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE));
1504aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
150547989497SBarry Smith     /* determine if matrix has all real values */
1506ca15aa20SStefano Zampini     v = av;
1507d0f46423SBarry Smith     for (i=0; i<A->rmap->n*A->cmap->n; i++) {
1508ffac6cdbSBarry Smith       if (PetscImaginaryPart(v[i])) { allreal = PETSC_FALSE; break;}
150947989497SBarry Smith     }
151047989497SBarry Smith #endif
1511fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
15129566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetName((PetscObject)A,&name));
15139566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"%% Size = %" PetscInt_FMT " %" PetscInt_FMT " \n",A->rmap->n,A->cmap->n));
15149566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"%s = zeros(%" PetscInt_FMT ",%" PetscInt_FMT ");\n",name,A->rmap->n,A->cmap->n));
15159566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"%s = [\n",name));
1516ffac6cdbSBarry Smith     }
1517ffac6cdbSBarry Smith 
1518d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1519ca15aa20SStefano Zampini       v = av + i;
1520d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1521aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
152247989497SBarry Smith         if (allreal) {
15239566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)PetscRealPart(*v)));
152447989497SBarry Smith         } else {
15259566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ei ",(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v)));
152647989497SBarry Smith         }
1527289bc588SBarry Smith #else
15289566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)*v));
1529289bc588SBarry Smith #endif
15301b807ce4Svictorle         v += a->lda;
1531289bc588SBarry Smith       }
15329566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"\n"));
1533289bc588SBarry Smith     }
1534fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
15359566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"];\n"));
1536ffac6cdbSBarry Smith     }
15379566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE));
1538da3a660dSBarry Smith   }
15399566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,(const PetscScalar**)&av));
15409566063dSJacob Faibussowitsch   PetscCall(PetscViewerFlush(viewer));
15413a40ed3dSBarry Smith   PetscFunctionReturn(0);
1542289bc588SBarry Smith }
1543289bc588SBarry Smith 
15449804daf3SBarry Smith #include <petscdraw.h>
1545e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw,void *Aa)
1546f1af5d2fSBarry Smith {
1547f1af5d2fSBarry Smith   Mat               A  = (Mat) Aa;
1548383922c3SLisandro Dalcin   PetscInt          m  = A->rmap->n,n = A->cmap->n,i,j;
1549383922c3SLisandro Dalcin   int               color = PETSC_DRAW_WHITE;
1550ca15aa20SStefano Zampini   const PetscScalar *v;
1551b0a32e0cSBarry Smith   PetscViewer       viewer;
1552b05fc000SLisandro Dalcin   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r;
1553f3ef73ceSBarry Smith   PetscViewerFormat format;
1554f1af5d2fSBarry Smith 
1555f1af5d2fSBarry Smith   PetscFunctionBegin;
15569566063dSJacob Faibussowitsch   PetscCall(PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer));
15579566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer,&format));
15589566063dSJacob Faibussowitsch   PetscCall(PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr));
1559f1af5d2fSBarry Smith 
1560f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
15619566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&v));
1562fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
1563d0609cedSBarry Smith     PetscDrawCollectiveBegin(draw);
1564f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
1565f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
1566383922c3SLisandro Dalcin       x_l = j; x_r = x_l + 1.0;
1567f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1568f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1569f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1570ca15aa20SStefano Zampini         if (PetscRealPart(v[j*m+i]) >  0.) color = PETSC_DRAW_RED;
1571ca15aa20SStefano Zampini         else if (PetscRealPart(v[j*m+i]) <  0.) color = PETSC_DRAW_BLUE;
1572ca15aa20SStefano Zampini         else continue;
15739566063dSJacob Faibussowitsch         PetscCall(PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color));
1574f1af5d2fSBarry Smith       }
1575f1af5d2fSBarry Smith     }
1576d0609cedSBarry Smith     PetscDrawCollectiveEnd(draw);
1577f1af5d2fSBarry Smith   } else {
1578f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
1579f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
1580b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1581b05fc000SLisandro Dalcin     PetscDraw popup;
1582b05fc000SLisandro Dalcin 
1583f1af5d2fSBarry Smith     for (i=0; i < m*n; i++) {
1584f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
1585f1af5d2fSBarry Smith     }
1586383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
15879566063dSJacob Faibussowitsch     PetscCall(PetscDrawGetPopup(draw,&popup));
15889566063dSJacob Faibussowitsch     PetscCall(PetscDrawScalePopup(popup,minv,maxv));
1589383922c3SLisandro Dalcin 
1590d0609cedSBarry Smith     PetscDrawCollectiveBegin(draw);
1591f1af5d2fSBarry Smith     for (j=0; j<n; j++) {
1592f1af5d2fSBarry Smith       x_l = j;
1593f1af5d2fSBarry Smith       x_r = x_l + 1.0;
1594f1af5d2fSBarry Smith       for (i=0; i<m; i++) {
1595f1af5d2fSBarry Smith         y_l   = m - i - 1.0;
1596f1af5d2fSBarry Smith         y_r   = y_l + 1.0;
1597b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(v[j*m+i]),minv,maxv);
15989566063dSJacob Faibussowitsch         PetscCall(PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color));
1599f1af5d2fSBarry Smith       }
1600f1af5d2fSBarry Smith     }
1601d0609cedSBarry Smith     PetscDrawCollectiveEnd(draw);
1602f1af5d2fSBarry Smith   }
16039566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&v));
1604f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1605f1af5d2fSBarry Smith }
1606f1af5d2fSBarry Smith 
1607e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw(Mat A,PetscViewer viewer)
1608f1af5d2fSBarry Smith {
1609b0a32e0cSBarry Smith   PetscDraw      draw;
1610ace3abfcSBarry Smith   PetscBool      isnull;
1611329f5518SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
1612f1af5d2fSBarry Smith 
1613f1af5d2fSBarry Smith   PetscFunctionBegin;
16149566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDraw(viewer,0,&draw));
16159566063dSJacob Faibussowitsch   PetscCall(PetscDrawIsNull(draw,&isnull));
1616abc0a331SBarry Smith   if (isnull) PetscFunctionReturn(0);
1617f1af5d2fSBarry Smith 
1618d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
1619f1af5d2fSBarry Smith   xr  += w;          yr += h;        xl = -w;     yl = -h;
16209566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetCoordinates(draw,xl,yl,xr,yr));
16219566063dSJacob Faibussowitsch   PetscCall(PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer));
16229566063dSJacob Faibussowitsch   PetscCall(PetscDrawZoom(draw,MatView_SeqDense_Draw_Zoom,A));
16239566063dSJacob Faibussowitsch   PetscCall(PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL));
16249566063dSJacob Faibussowitsch   PetscCall(PetscDrawSave(draw));
1625f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1626f1af5d2fSBarry Smith }
1627f1af5d2fSBarry Smith 
1628dfbe8321SBarry Smith PetscErrorCode MatView_SeqDense(Mat A,PetscViewer viewer)
1629932b0c3eSLois Curfman McInnes {
1630ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
1631932b0c3eSLois Curfman McInnes 
16323a40ed3dSBarry Smith   PetscFunctionBegin;
16339566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
16349566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary));
16359566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw));
1636c45a1595SBarry Smith   if (iascii) {
16379566063dSJacob Faibussowitsch     PetscCall(MatView_SeqDense_ASCII(A,viewer));
16380f5bd95cSBarry Smith   } else if (isbinary) {
16399566063dSJacob Faibussowitsch     PetscCall(MatView_Dense_Binary(A,viewer));
1640f1af5d2fSBarry Smith   } else if (isdraw) {
16419566063dSJacob Faibussowitsch     PetscCall(MatView_SeqDense_Draw(A,viewer));
1642932b0c3eSLois Curfman McInnes   }
16433a40ed3dSBarry Smith   PetscFunctionReturn(0);
1644932b0c3eSLois Curfman McInnes }
1645289bc588SBarry Smith 
1646637a0070SStefano Zampini static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A,const PetscScalar *array)
1647d3042a70SBarry Smith {
1648d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1649d3042a70SBarry Smith 
1650d3042a70SBarry Smith   PetscFunctionBegin;
165128b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
165228b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
165328b400f6SJacob Faibussowitsch   PetscCheck(!a->unplacedarray,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreArray() first");
1654d3042a70SBarry Smith   a->unplacedarray       = a->v;
1655d3042a70SBarry Smith   a->unplaced_user_alloc = a->user_alloc;
1656d3042a70SBarry Smith   a->v                   = (PetscScalar*) array;
1657637a0070SStefano Zampini   a->user_alloc          = PETSC_TRUE;
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 
1664d3042a70SBarry Smith static PetscErrorCode MatDenseResetArray_SeqDense(Mat A)
1665d3042a70SBarry Smith {
1666d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1667d3042a70SBarry Smith 
1668d3042a70SBarry Smith   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");
1671d3042a70SBarry Smith   a->v             = a->unplacedarray;
1672d3042a70SBarry Smith   a->user_alloc    = a->unplaced_user_alloc;
1673d3042a70SBarry Smith   a->unplacedarray = NULL;
1674ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1675c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1676ca15aa20SStefano Zampini #endif
1677d3042a70SBarry Smith   PetscFunctionReturn(0);
1678d3042a70SBarry Smith }
1679d3042a70SBarry Smith 
1680d5ea218eSStefano Zampini static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A,const PetscScalar *array)
1681d5ea218eSStefano Zampini {
1682d5ea218eSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1683d5ea218eSStefano Zampini 
1684d5ea218eSStefano Zampini   PetscFunctionBegin;
168528b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
168628b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
16879566063dSJacob Faibussowitsch   if (!a->user_alloc) PetscCall(PetscFree(a->v));
1688d5ea218eSStefano Zampini   a->v           = (PetscScalar*) array;
1689d5ea218eSStefano Zampini   a->user_alloc  = PETSC_FALSE;
1690d5ea218eSStefano Zampini #if defined(PETSC_HAVE_CUDA)
1691d5ea218eSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
1692d5ea218eSStefano Zampini #endif
1693d5ea218eSStefano Zampini   PetscFunctionReturn(0);
1694d5ea218eSStefano Zampini }
1695d5ea218eSStefano Zampini 
1696ca15aa20SStefano Zampini PetscErrorCode MatDestroy_SeqDense(Mat mat)
1697289bc588SBarry Smith {
1698ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)mat->data;
169990f02eecSBarry Smith 
17003a40ed3dSBarry Smith   PetscFunctionBegin;
1701aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1702c0aa6a63SJacob Faibussowitsch   PetscLogObjectState((PetscObject)mat,"Rows %" PetscInt_FMT " Cols %" PetscInt_FMT,mat->rmap->n,mat->cmap->n);
1703a5a9c739SBarry Smith #endif
17049566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(l->qrrhs)));
17059566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->tau));
17069566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->pivots));
17079566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->fwork));
17089566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&l->ptapwork));
17099566063dSJacob Faibussowitsch   if (!l->user_alloc) PetscCall(PetscFree(l->v));
17109566063dSJacob Faibussowitsch   if (!l->unplaced_user_alloc) PetscCall(PetscFree(l->unplacedarray));
171128b400f6SJacob Faibussowitsch   PetscCheck(!l->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
171228b400f6SJacob Faibussowitsch   PetscCheck(!l->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
17139566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&l->cvec));
17149566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&l->cmat));
17159566063dSJacob Faibussowitsch   PetscCall(PetscFree(mat->data));
1716dbd8c25aSHong Zhang 
17179566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)mat,NULL));
17189566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatQRFactor_C",NULL));
17199566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetLDA_C",NULL));
17209566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseSetLDA_C",NULL));
17219566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArray_C",NULL));
17229566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArray_C",NULL));
17239566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDensePlaceArray_C",NULL));
17249566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseResetArray_C",NULL));
17259566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseReplaceArray_C",NULL));
17269566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArrayRead_C",NULL));
17279566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArrayRead_C",NULL));
17289566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArrayWrite_C",NULL));
17299566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArrayWrite_C",NULL));
17309566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqaij_C",NULL));
17318baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
17329566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_elemental_C",NULL));
17338baccfbdSHong Zhang #endif
1734d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
17359566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_scalapack_C",NULL));
1736d24d4204SJose E. Roman #endif
17372bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
17389566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqdensecuda_C",NULL));
17399566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",NULL));
17409566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdense_C",NULL));
17412bf066beSStefano Zampini #endif
17429566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatSeqDenseSetPreallocation_C",NULL));
17439566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqaij_seqdense_C",NULL));
17449566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdense_seqdense_C",NULL));
17459566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqbaij_seqdense_C",NULL));
17469566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqsbaij_seqdense_C",NULL));
174752c5f739Sprj- 
17489566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumn_C",NULL));
17499566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumn_C",NULL));
17509566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVec_C",NULL));
17519566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVec_C",NULL));
17529566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVecRead_C",NULL));
17539566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVecRead_C",NULL));
17549566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVecWrite_C",NULL));
17559566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVecWrite_C",NULL));
17569566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetSubMatrix_C",NULL));
17579566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreSubMatrix_C",NULL));
17583a40ed3dSBarry Smith   PetscFunctionReturn(0);
1759289bc588SBarry Smith }
1760289bc588SBarry Smith 
1761e0877f53SBarry Smith static PetscErrorCode MatTranspose_SeqDense(Mat A,MatReuse reuse,Mat *matout)
1762289bc588SBarry Smith {
1763c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
17646536e3caSStefano Zampini   PetscInt       k,j,m = A->rmap->n, M = mat->lda, n = A->cmap->n;
176587828ca2SBarry Smith   PetscScalar    *v,tmp;
176648b35521SBarry Smith 
17673a40ed3dSBarry Smith   PetscFunctionBegin;
17686536e3caSStefano Zampini   if (reuse == MAT_INPLACE_MATRIX) {
17696536e3caSStefano Zampini     if (m == n) { /* in place transpose */
17709566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(A,&v));
1771d3e5ee88SLois Curfman McInnes       for (j=0; j<m; j++) {
1772289bc588SBarry Smith         for (k=0; k<j; k++) {
17731b807ce4Svictorle           tmp        = v[j + k*M];
17741b807ce4Svictorle           v[j + k*M] = v[k + j*M];
17751b807ce4Svictorle           v[k + j*M] = tmp;
1776289bc588SBarry Smith         }
1777289bc588SBarry Smith       }
17789566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArray(A,&v));
17796536e3caSStefano Zampini     } else { /* reuse memory, temporary allocates new memory */
17806536e3caSStefano Zampini       PetscScalar *v2;
17816536e3caSStefano Zampini       PetscLayout tmplayout;
17826536e3caSStefano Zampini 
17839566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1((size_t)m*n,&v2));
17849566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(A,&v));
17856536e3caSStefano Zampini       for (j=0; j<n; j++) {
17866536e3caSStefano Zampini         for (k=0; k<m; k++) v2[j + (size_t)k*n] = v[k + (size_t)j*M];
17876536e3caSStefano Zampini       }
17889566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(v,v2,(size_t)m*n));
17899566063dSJacob Faibussowitsch       PetscCall(PetscFree(v2));
17909566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArray(A,&v));
17916536e3caSStefano Zampini       /* cleanup size dependent quantities */
17929566063dSJacob Faibussowitsch       PetscCall(VecDestroy(&mat->cvec));
17939566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&mat->cmat));
17949566063dSJacob Faibussowitsch       PetscCall(PetscFree(mat->pivots));
17959566063dSJacob Faibussowitsch       PetscCall(PetscFree(mat->fwork));
17969566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&mat->ptapwork));
17976536e3caSStefano Zampini       /* swap row/col layouts */
17986536e3caSStefano Zampini       mat->lda  = n;
17996536e3caSStefano Zampini       tmplayout = A->rmap;
18006536e3caSStefano Zampini       A->rmap   = A->cmap;
18016536e3caSStefano Zampini       A->cmap   = tmplayout;
18026536e3caSStefano Zampini     }
18033a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1804d3e5ee88SLois Curfman McInnes     Mat          tmat;
1805ec8511deSBarry Smith     Mat_SeqDense *tmatd;
180687828ca2SBarry Smith     PetscScalar  *v2;
1807af36a384SStefano Zampini     PetscInt     M2;
1808ea709b57SSatish Balay 
18096536e3caSStefano Zampini     if (reuse == MAT_INITIAL_MATRIX) {
18109566063dSJacob Faibussowitsch       PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&tmat));
18119566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(tmat,A->cmap->n,A->rmap->n,A->cmap->n,A->rmap->n));
18129566063dSJacob Faibussowitsch       PetscCall(MatSetType(tmat,((PetscObject)A)->type_name));
18139566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSetPreallocation(tmat,NULL));
1814ca15aa20SStefano Zampini     } else tmat = *matout;
1815ca15aa20SStefano Zampini 
18169566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A,(const PetscScalar**)&v));
18179566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArray(tmat,&v2));
1818ec8511deSBarry Smith     tmatd = (Mat_SeqDense*)tmat->data;
1819ca15aa20SStefano Zampini     M2    = tmatd->lda;
1820d3e5ee88SLois Curfman McInnes     for (j=0; j<n; j++) {
1821af36a384SStefano Zampini       for (k=0; k<m; k++) v2[j + k*M2] = v[k + j*M];
1822d3e5ee88SLois Curfman McInnes     }
18239566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(tmat,&v2));
18249566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A,(const PetscScalar**)&v));
18259566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY));
18269566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY));
18276536e3caSStefano Zampini     *matout = tmat;
182848b35521SBarry Smith   }
18293a40ed3dSBarry Smith   PetscFunctionReturn(0);
1830289bc588SBarry Smith }
1831289bc588SBarry Smith 
1832e0877f53SBarry Smith static PetscErrorCode MatEqual_SeqDense(Mat A1,Mat A2,PetscBool  *flg)
1833289bc588SBarry Smith {
1834c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat1 = (Mat_SeqDense*)A1->data;
1835c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat2 = (Mat_SeqDense*)A2->data;
1836ca15aa20SStefano Zampini   PetscInt          i;
1837ca15aa20SStefano Zampini   const PetscScalar *v1,*v2;
18389ea5d5aeSSatish Balay 
18393a40ed3dSBarry Smith   PetscFunctionBegin;
1840d0f46423SBarry Smith   if (A1->rmap->n != A2->rmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1841d0f46423SBarry Smith   if (A1->cmap->n != A2->cmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
18429566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A1,&v1));
18439566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A2,&v2));
1844ca15aa20SStefano Zampini   for (i=0; i<A1->cmap->n; i++) {
18459566063dSJacob Faibussowitsch     PetscCall(PetscArraycmp(v1,v2,A1->rmap->n,flg));
1846ca15aa20SStefano Zampini     if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
1847ca15aa20SStefano Zampini     v1 += mat1->lda;
1848ca15aa20SStefano Zampini     v2 += mat2->lda;
18491b807ce4Svictorle   }
18509566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A1,&v1));
18519566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A2,&v2));
185277c4ece6SBarry Smith   *flg = PETSC_TRUE;
18533a40ed3dSBarry Smith   PetscFunctionReturn(0);
1854289bc588SBarry Smith }
1855289bc588SBarry Smith 
1856e0877f53SBarry Smith static PetscErrorCode MatGetDiagonal_SeqDense(Mat A,Vec v)
1857289bc588SBarry Smith {
1858c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
185913f74950SBarry Smith   PetscInt          i,n,len;
1860ca15aa20SStefano Zampini   PetscScalar       *x;
1861ca15aa20SStefano Zampini   const PetscScalar *vv;
186244cd7ae7SLois Curfman McInnes 
18633a40ed3dSBarry Smith   PetscFunctionBegin;
18649566063dSJacob Faibussowitsch   PetscCall(VecGetSize(v,&n));
18659566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v,&x));
1866d0f46423SBarry Smith   len  = PetscMin(A->rmap->n,A->cmap->n);
18679566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&vv));
186808401ef6SPierre Jolivet   PetscCheck(n == A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming mat and vec");
186944cd7ae7SLois Curfman McInnes   for (i=0; i<len; i++) {
1870ca15aa20SStefano Zampini     x[i] = vv[i*mat->lda + i];
1871289bc588SBarry Smith   }
18729566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&vv));
18739566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v,&x));
18743a40ed3dSBarry Smith   PetscFunctionReturn(0);
1875289bc588SBarry Smith }
1876289bc588SBarry Smith 
1877e0877f53SBarry Smith static PetscErrorCode MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr)
1878289bc588SBarry Smith {
1879c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1880f1ceaac6SMatthew G. Knepley   const PetscScalar *l,*r;
1881ca15aa20SStefano Zampini   PetscScalar       x,*v,*vv;
1882d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n;
188355659b69SBarry Smith 
18843a40ed3dSBarry Smith   PetscFunctionBegin;
18859566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&vv));
188628988994SBarry Smith   if (ll) {
18879566063dSJacob Faibussowitsch     PetscCall(VecGetSize(ll,&m));
18889566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ll,&l));
188908401ef6SPierre Jolivet     PetscCheck(m == A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vec wrong size");
1890da3a660dSBarry Smith     for (i=0; i<m; i++) {
1891da3a660dSBarry Smith       x = l[i];
1892ca15aa20SStefano Zampini       v = vv + i;
1893b43bac26SStefano Zampini       for (j=0; j<n; j++) { (*v) *= x; v+= mat->lda;}
1894da3a660dSBarry Smith     }
18959566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ll,&l));
18969566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0*n*m));
1897da3a660dSBarry Smith   }
189828988994SBarry Smith   if (rr) {
18999566063dSJacob Faibussowitsch     PetscCall(VecGetSize(rr,&n));
19009566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(rr,&r));
190108401ef6SPierre Jolivet     PetscCheck(n == A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vec wrong size");
1902da3a660dSBarry Smith     for (i=0; i<n; i++) {
1903da3a660dSBarry Smith       x = r[i];
1904ca15aa20SStefano Zampini       v = vv + i*mat->lda;
19052205254eSKarl Rupp       for (j=0; j<m; j++) (*v++) *= x;
1906da3a660dSBarry Smith     }
19079566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(rr,&r));
19089566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0*n*m));
1909da3a660dSBarry Smith   }
19109566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&vv));
19113a40ed3dSBarry Smith   PetscFunctionReturn(0);
1912289bc588SBarry Smith }
1913289bc588SBarry Smith 
1914ca15aa20SStefano Zampini PetscErrorCode MatNorm_SeqDense(Mat A,NormType type,PetscReal *nrm)
1915289bc588SBarry Smith {
1916c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1917ca15aa20SStefano Zampini   PetscScalar       *v,*vv;
1918329f5518SBarry Smith   PetscReal         sum = 0.0;
191975f6d85dSStefano Zampini   PetscInt          lda, m=A->rmap->n,i,j;
192055659b69SBarry Smith 
19213a40ed3dSBarry Smith   PetscFunctionBegin;
19229566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,(const PetscScalar**)&vv));
19239566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(A,&lda));
1924ca15aa20SStefano Zampini   v    = vv;
1925289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1926a5ce6ee0Svictorle     if (lda>m) {
1927d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1928ca15aa20SStefano Zampini         v = vv+j*lda;
1929a5ce6ee0Svictorle         for (i=0; i<m; i++) {
1930a5ce6ee0Svictorle           sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1931a5ce6ee0Svictorle         }
1932a5ce6ee0Svictorle       }
1933a5ce6ee0Svictorle     } else {
1934570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1935570b7f6dSBarry Smith       PetscBLASInt one = 1,cnt = A->cmap->n*A->rmap->n;
193673cf7048SBarry Smith       PetscStackCallBLAS("BLASnrm2",*nrm = BLASnrm2_(&cnt,v,&one));
1937570b7f6dSBarry Smith     }
1938570b7f6dSBarry Smith #else
1939d0f46423SBarry Smith       for (i=0; i<A->cmap->n*A->rmap->n; i++) {
1940329f5518SBarry Smith         sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1941289bc588SBarry Smith       }
1942a5ce6ee0Svictorle     }
19438f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1944570b7f6dSBarry Smith #endif
19459566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0*A->cmap->n*A->rmap->n));
19463a40ed3dSBarry Smith   } else if (type == NORM_1) {
1947064f8208SBarry Smith     *nrm = 0.0;
1948d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1949ca15aa20SStefano Zampini       v   = vv + j*mat->lda;
1950289bc588SBarry Smith       sum = 0.0;
1951d0f46423SBarry Smith       for (i=0; i<A->rmap->n; i++) {
195233a8263dSBarry Smith         sum += PetscAbsScalar(*v);  v++;
1953289bc588SBarry Smith       }
1954064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1955289bc588SBarry Smith     }
19569566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0*A->cmap->n*A->rmap->n));
19573a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1958064f8208SBarry Smith     *nrm = 0.0;
1959d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1960ca15aa20SStefano Zampini       v   = vv + j;
1961289bc588SBarry Smith       sum = 0.0;
1962d0f46423SBarry Smith       for (i=0; i<A->cmap->n; i++) {
19631b807ce4Svictorle         sum += PetscAbsScalar(*v); v += mat->lda;
1964289bc588SBarry Smith       }
1965064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1966289bc588SBarry Smith     }
19679566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0*A->cmap->n*A->rmap->n));
1968e7e72b3dSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No two norm");
19699566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,(const PetscScalar**)&vv));
19703a40ed3dSBarry Smith   PetscFunctionReturn(0);
1971289bc588SBarry Smith }
1972289bc588SBarry Smith 
1973e0877f53SBarry Smith static PetscErrorCode MatSetOption_SeqDense(Mat A,MatOption op,PetscBool flg)
1974289bc588SBarry Smith {
1975c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *aij = (Mat_SeqDense*)A->data;
197667e560aaSBarry Smith 
19773a40ed3dSBarry Smith   PetscFunctionBegin;
1978b5a2b587SKris Buschelman   switch (op) {
1979b5a2b587SKris Buschelman   case MAT_ROW_ORIENTED:
19804e0d8c25SBarry Smith     aij->roworiented = flg;
1981b5a2b587SKris Buschelman     break;
1982512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
1983b5a2b587SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
19843971808eSMatthew Knepley   case MAT_NEW_NONZERO_ALLOCATION_ERR:
19858c78258cSHong Zhang   case MAT_FORCE_DIAGONAL_ENTRIES:
198613fa8e87SLisandro Dalcin   case MAT_KEEP_NONZERO_PATTERN:
1987b5a2b587SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
1988b5a2b587SKris Buschelman   case MAT_USE_HASH_TABLE:
19890f8fb01aSBarry Smith   case MAT_IGNORE_ZERO_ENTRIES:
19905021d80fSJed Brown   case MAT_IGNORE_LOWER_TRIANGULAR:
1991071fcb05SBarry Smith   case MAT_SORTED_FULL:
19929566063dSJacob Faibussowitsch     PetscCall(PetscInfo(A,"Option %s ignored\n",MatOptions[op]));
19935021d80fSJed Brown     break;
19945021d80fSJed Brown   case MAT_SPD:
199577e54ba9SKris Buschelman   case MAT_SYMMETRIC:
199677e54ba9SKris Buschelman   case MAT_STRUCTURALLY_SYMMETRIC:
19979a4540c5SBarry Smith   case MAT_HERMITIAN:
19989a4540c5SBarry Smith   case MAT_SYMMETRY_ETERNAL:
19995021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
200077e54ba9SKris Buschelman     break;
2001b5a2b587SKris Buschelman   default:
200298921bdaSJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %s",MatOptions[op]);
20033a40ed3dSBarry Smith   }
20043a40ed3dSBarry Smith   PetscFunctionReturn(0);
2005289bc588SBarry Smith }
2006289bc588SBarry Smith 
20073d8925e7SStefano Zampini PetscErrorCode MatZeroEntries_SeqDense(Mat A)
20086f0a148fSBarry Smith {
2009ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)A->data;
20103d8925e7SStefano Zampini   PetscInt       lda=l->lda,m=A->rmap->n,n=A->cmap->n,j;
2011ca15aa20SStefano Zampini   PetscScalar    *v;
20123a40ed3dSBarry Smith 
20133a40ed3dSBarry Smith   PetscFunctionBegin;
20149566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(A,&v));
2015a5ce6ee0Svictorle   if (lda>m) {
20163d8925e7SStefano Zampini     for (j=0; j<n; j++) {
20179566063dSJacob Faibussowitsch       PetscCall(PetscArrayzero(v+j*lda,m));
2018a5ce6ee0Svictorle     }
2019a5ce6ee0Svictorle   } else {
20209566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(v,PetscInt64Mult(m,n)));
2021a5ce6ee0Svictorle   }
20229566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(A,&v));
20233a40ed3dSBarry Smith   PetscFunctionReturn(0);
20246f0a148fSBarry Smith }
20256f0a148fSBarry Smith 
2026e0877f53SBarry Smith static PetscErrorCode MatZeroRows_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
20276f0a148fSBarry Smith {
2028ec8511deSBarry Smith   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
2029b9679d65SBarry Smith   PetscInt          m  = l->lda, n = A->cmap->n, i,j;
2030ca15aa20SStefano Zampini   PetscScalar       *slot,*bb,*v;
203197b48c8fSBarry Smith   const PetscScalar *xx;
203255659b69SBarry Smith 
20333a40ed3dSBarry Smith   PetscFunctionBegin;
203476bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
2035b9679d65SBarry Smith     for (i=0; i<N; i++) {
203608401ef6SPierre Jolivet       PetscCheck(rows[i] >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
203708401ef6SPierre Jolivet       PetscCheck(rows[i] < A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %" PetscInt_FMT " requested to be zeroed greater than or equal number of rows %" PetscInt_FMT,rows[i],A->rmap->n);
2038b9679d65SBarry Smith     }
203976bd3646SJed Brown   }
2040ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
2041b9679d65SBarry Smith 
204297b48c8fSBarry Smith   /* fix right hand side if needed */
204397b48c8fSBarry Smith   if (x && b) {
20449566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(x,&xx));
20459566063dSJacob Faibussowitsch     PetscCall(VecGetArray(b,&bb));
20462205254eSKarl Rupp     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
20479566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(x,&xx));
20489566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(b,&bb));
204997b48c8fSBarry Smith   }
205097b48c8fSBarry Smith 
20519566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&v));
20526f0a148fSBarry Smith   for (i=0; i<N; i++) {
2053ca15aa20SStefano Zampini     slot = v + rows[i];
2054b9679d65SBarry Smith     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
20556f0a148fSBarry Smith   }
2056f4df32b1SMatthew Knepley   if (diag != 0.0) {
205708401ef6SPierre Jolivet     PetscCheck(A->rmap->n == A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
20586f0a148fSBarry Smith     for (i=0; i<N; i++) {
2059ca15aa20SStefano Zampini       slot  = v + (m+1)*rows[i];
2060f4df32b1SMatthew Knepley       *slot = diag;
20616f0a148fSBarry Smith     }
20626f0a148fSBarry Smith   }
20639566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&v));
20643a40ed3dSBarry Smith   PetscFunctionReturn(0);
20656f0a148fSBarry Smith }
2066557bce09SLois Curfman McInnes 
206749a6ff4bSBarry Smith static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A,PetscInt *lda)
206849a6ff4bSBarry Smith {
206949a6ff4bSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
207049a6ff4bSBarry Smith 
207149a6ff4bSBarry Smith   PetscFunctionBegin;
207249a6ff4bSBarry Smith   *lda = mat->lda;
207349a6ff4bSBarry Smith   PetscFunctionReturn(0);
207449a6ff4bSBarry Smith }
207549a6ff4bSBarry Smith 
2076637a0070SStefano Zampini PetscErrorCode MatDenseGetArray_SeqDense(Mat A,PetscScalar **array)
207764e87e97SBarry Smith {
2078c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
20793a40ed3dSBarry Smith 
20803a40ed3dSBarry Smith   PetscFunctionBegin;
208128b400f6SJacob Faibussowitsch   PetscCheck(!mat->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
208264e87e97SBarry Smith   *array = mat->v;
20833a40ed3dSBarry Smith   PetscFunctionReturn(0);
208464e87e97SBarry Smith }
20850754003eSLois Curfman McInnes 
2086637a0070SStefano Zampini PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A,PetscScalar **array)
2087ff14e315SSatish Balay {
20883a40ed3dSBarry Smith   PetscFunctionBegin;
208975f6d85dSStefano Zampini   if (array) *array = NULL;
20903a40ed3dSBarry Smith   PetscFunctionReturn(0);
2091ff14e315SSatish Balay }
20920754003eSLois Curfman McInnes 
20930f74d2c1SSatish Balay /*@
209449a6ff4bSBarry Smith    MatDenseGetLDA - gets the leading dimension of the array returned from MatDenseGetArray()
209549a6ff4bSBarry Smith 
2096ad16ce7aSStefano Zampini    Not collective
209749a6ff4bSBarry Smith 
209849a6ff4bSBarry Smith    Input Parameter:
209949a6ff4bSBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
210049a6ff4bSBarry Smith 
210149a6ff4bSBarry Smith    Output Parameter:
210249a6ff4bSBarry Smith .   lda - the leading dimension
210349a6ff4bSBarry Smith 
210449a6ff4bSBarry Smith    Level: intermediate
210549a6ff4bSBarry Smith 
2106db781477SPatrick Sanan .seealso: `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseSetLDA()`
210749a6ff4bSBarry Smith @*/
210849a6ff4bSBarry Smith PetscErrorCode  MatDenseGetLDA(Mat A,PetscInt *lda)
210949a6ff4bSBarry Smith {
211049a6ff4bSBarry Smith   PetscFunctionBegin;
2111d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2112dadcf809SJacob Faibussowitsch   PetscValidIntPointer(lda,2);
211375f6d85dSStefano Zampini   MatCheckPreallocated(A,1);
2114cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetLDA_C",(Mat,PetscInt*),(A,lda));
211549a6ff4bSBarry Smith   PetscFunctionReturn(0);
211649a6ff4bSBarry Smith }
211749a6ff4bSBarry Smith 
21180f74d2c1SSatish Balay /*@
2119ad16ce7aSStefano Zampini    MatDenseSetLDA - Sets the leading dimension of the array used by the dense matrix
2120ad16ce7aSStefano Zampini 
2121ad16ce7aSStefano Zampini    Not collective
2122ad16ce7aSStefano Zampini 
2123d8d19677SJose E. Roman    Input Parameters:
2124ad16ce7aSStefano Zampini +  mat - a MATSEQDENSE or MATMPIDENSE matrix
2125ad16ce7aSStefano Zampini -  lda - the leading dimension
2126ad16ce7aSStefano Zampini 
2127ad16ce7aSStefano Zampini    Level: intermediate
2128ad16ce7aSStefano Zampini 
2129db781477SPatrick Sanan .seealso: `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetLDA()`
2130ad16ce7aSStefano Zampini @*/
2131ad16ce7aSStefano Zampini PetscErrorCode  MatDenseSetLDA(Mat A,PetscInt lda)
2132ad16ce7aSStefano Zampini {
2133ad16ce7aSStefano Zampini   PetscFunctionBegin;
2134ad16ce7aSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2135cac4c232SBarry Smith   PetscTryMethod(A,"MatDenseSetLDA_C",(Mat,PetscInt),(A,lda));
2136ad16ce7aSStefano Zampini   PetscFunctionReturn(0);
2137ad16ce7aSStefano Zampini }
2138ad16ce7aSStefano Zampini 
2139ad16ce7aSStefano Zampini /*@C
21406947451fSStefano Zampini    MatDenseGetArray - gives read-write access to the array where the data for a dense matrix is stored
214173a71a0fSBarry Smith 
21428572280aSBarry Smith    Logically Collective on Mat
214373a71a0fSBarry Smith 
214473a71a0fSBarry Smith    Input Parameter:
21456947451fSStefano Zampini .  mat - a dense matrix
214673a71a0fSBarry Smith 
214773a71a0fSBarry Smith    Output Parameter:
214873a71a0fSBarry Smith .   array - pointer to the data
214973a71a0fSBarry Smith 
215073a71a0fSBarry Smith    Level: intermediate
215173a71a0fSBarry Smith 
2152db781477SPatrick Sanan .seealso: `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
215373a71a0fSBarry Smith @*/
21548c778c55SBarry Smith PetscErrorCode  MatDenseGetArray(Mat A,PetscScalar **array)
215573a71a0fSBarry Smith {
215673a71a0fSBarry Smith   PetscFunctionBegin;
2157d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2158d5ea218eSStefano Zampini   PetscValidPointer(array,2);
2159cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetArray_C",(Mat,PetscScalar**),(A,array));
216073a71a0fSBarry Smith   PetscFunctionReturn(0);
216173a71a0fSBarry Smith }
216273a71a0fSBarry Smith 
2163dec5eb66SMatthew G Knepley /*@C
2164579dbff0SBarry Smith    MatDenseRestoreArray - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
216573a71a0fSBarry Smith 
21668572280aSBarry Smith    Logically Collective on Mat
21678572280aSBarry Smith 
21688572280aSBarry Smith    Input Parameters:
21696947451fSStefano Zampini +  mat - a dense matrix
2170a2b725a8SWilliam Gropp -  array - pointer to the data
21718572280aSBarry Smith 
21728572280aSBarry Smith    Level: intermediate
21738572280aSBarry Smith 
2174db781477SPatrick Sanan .seealso: `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
21758572280aSBarry Smith @*/
21768572280aSBarry Smith PetscErrorCode  MatDenseRestoreArray(Mat A,PetscScalar **array)
21778572280aSBarry Smith {
21788572280aSBarry Smith   PetscFunctionBegin;
2179d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2180d5ea218eSStefano Zampini   PetscValidPointer(array,2);
2181cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreArray_C",(Mat,PetscScalar**),(A,array));
21829566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)A));
2183637a0070SStefano Zampini #if defined(PETSC_HAVE_CUDA)
2184637a0070SStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
2185637a0070SStefano Zampini #endif
21868572280aSBarry Smith   PetscFunctionReturn(0);
21878572280aSBarry Smith }
21888572280aSBarry Smith 
21898572280aSBarry Smith /*@C
21906947451fSStefano Zampini    MatDenseGetArrayRead - gives read-only access to the array where the data for a dense matrix is stored
21918572280aSBarry Smith 
21928572280aSBarry Smith    Not Collective
21938572280aSBarry Smith 
21948572280aSBarry Smith    Input Parameter:
21956947451fSStefano Zampini .  mat - a dense matrix
21968572280aSBarry Smith 
21978572280aSBarry Smith    Output Parameter:
21988572280aSBarry Smith .   array - pointer to the data
21998572280aSBarry Smith 
22008572280aSBarry Smith    Level: intermediate
22018572280aSBarry Smith 
2202db781477SPatrick Sanan .seealso: `MatDenseRestoreArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
22038572280aSBarry Smith @*/
22048572280aSBarry Smith PetscErrorCode  MatDenseGetArrayRead(Mat A,const PetscScalar **array)
22058572280aSBarry Smith {
22068572280aSBarry Smith   PetscFunctionBegin;
2207d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2208d5ea218eSStefano Zampini   PetscValidPointer(array,2);
2209cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetArrayRead_C",(Mat,const PetscScalar**),(A,array));
22108572280aSBarry Smith   PetscFunctionReturn(0);
22118572280aSBarry Smith }
22128572280aSBarry Smith 
22138572280aSBarry Smith /*@C
22146947451fSStefano Zampini    MatDenseRestoreArrayRead - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArrayRead()
22158572280aSBarry Smith 
221673a71a0fSBarry Smith    Not Collective
221773a71a0fSBarry Smith 
221873a71a0fSBarry Smith    Input Parameters:
22196947451fSStefano Zampini +  mat - a dense matrix
2220a2b725a8SWilliam Gropp -  array - pointer to the data
222173a71a0fSBarry Smith 
222273a71a0fSBarry Smith    Level: intermediate
222373a71a0fSBarry Smith 
2224db781477SPatrick Sanan .seealso: `MatDenseGetArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
222573a71a0fSBarry Smith @*/
22268572280aSBarry Smith PetscErrorCode  MatDenseRestoreArrayRead(Mat A,const PetscScalar **array)
222773a71a0fSBarry Smith {
222873a71a0fSBarry Smith   PetscFunctionBegin;
2229d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2230d5ea218eSStefano Zampini   PetscValidPointer(array,2);
2231cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreArrayRead_C",(Mat,const PetscScalar**),(A,array));
223273a71a0fSBarry Smith   PetscFunctionReturn(0);
223373a71a0fSBarry Smith }
223473a71a0fSBarry Smith 
22356947451fSStefano Zampini /*@C
22366947451fSStefano Zampini    MatDenseGetArrayWrite - gives write-only access to the array where the data for a dense matrix is stored
22376947451fSStefano Zampini 
22386947451fSStefano Zampini    Not Collective
22396947451fSStefano Zampini 
22406947451fSStefano Zampini    Input Parameter:
22416947451fSStefano Zampini .  mat - a dense matrix
22426947451fSStefano Zampini 
22436947451fSStefano Zampini    Output Parameter:
22446947451fSStefano Zampini .   array - pointer to the data
22456947451fSStefano Zampini 
22466947451fSStefano Zampini    Level: intermediate
22476947451fSStefano Zampini 
2248db781477SPatrick Sanan .seealso: `MatDenseRestoreArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`
22496947451fSStefano Zampini @*/
22506947451fSStefano Zampini PetscErrorCode  MatDenseGetArrayWrite(Mat A,PetscScalar **array)
22516947451fSStefano Zampini {
22526947451fSStefano Zampini   PetscFunctionBegin;
2253d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2254d5ea218eSStefano Zampini   PetscValidPointer(array,2);
2255cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetArrayWrite_C",(Mat,PetscScalar**),(A,array));
22566947451fSStefano Zampini   PetscFunctionReturn(0);
22576947451fSStefano Zampini }
22586947451fSStefano Zampini 
22596947451fSStefano Zampini /*@C
22606947451fSStefano Zampini    MatDenseRestoreArrayWrite - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArrayWrite()
22616947451fSStefano Zampini 
22626947451fSStefano Zampini    Not Collective
22636947451fSStefano Zampini 
22646947451fSStefano Zampini    Input Parameters:
22656947451fSStefano Zampini +  mat - a dense matrix
22666947451fSStefano Zampini -  array - pointer to the data
22676947451fSStefano Zampini 
22686947451fSStefano Zampini    Level: intermediate
22696947451fSStefano Zampini 
2270db781477SPatrick Sanan .seealso: `MatDenseGetArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`
22716947451fSStefano Zampini @*/
22726947451fSStefano Zampini PetscErrorCode  MatDenseRestoreArrayWrite(Mat A,PetscScalar **array)
22736947451fSStefano Zampini {
22746947451fSStefano Zampini   PetscFunctionBegin;
2275d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2276d5ea218eSStefano Zampini   PetscValidPointer(array,2);
2277cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreArrayWrite_C",(Mat,PetscScalar**),(A,array));
22789566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)A));
22796947451fSStefano Zampini #if defined(PETSC_HAVE_CUDA)
22806947451fSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
22816947451fSStefano Zampini #endif
22826947451fSStefano Zampini   PetscFunctionReturn(0);
22836947451fSStefano Zampini }
22846947451fSStefano Zampini 
2285023c16fcSToby Isaac static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,MatReuse scall,Mat *B)
22860754003eSLois Curfman McInnes {
2287c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
2288bf5a80bcSToby Isaac   PetscInt       i,j,nrows,ncols,ldb;
22895d0c19d7SBarry Smith   const PetscInt *irow,*icol;
229087828ca2SBarry Smith   PetscScalar    *av,*bv,*v = mat->v;
22910754003eSLois Curfman McInnes   Mat            newmat;
22920754003eSLois Curfman McInnes 
22933a40ed3dSBarry Smith   PetscFunctionBegin;
22949566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(isrow,&irow));
22959566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(iscol,&icol));
22969566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(isrow,&nrows));
22979566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(iscol,&ncols));
22980754003eSLois Curfman McInnes 
2299182d2002SSatish Balay   /* Check submatrixcall */
2300182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
230113f74950SBarry Smith     PetscInt n_cols,n_rows;
23029566063dSJacob Faibussowitsch     PetscCall(MatGetSize(*B,&n_rows,&n_cols));
230321a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
2304f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
23059566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(*B,nrows,ncols,nrows,ncols));
230621a2c019SBarry Smith     }
2307182d2002SSatish Balay     newmat = *B;
2308182d2002SSatish Balay   } else {
23090754003eSLois Curfman McInnes     /* Create and fill new matrix */
23109566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&newmat));
23119566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(newmat,nrows,ncols,nrows,ncols));
23129566063dSJacob Faibussowitsch     PetscCall(MatSetType(newmat,((PetscObject)A)->type_name));
23139566063dSJacob Faibussowitsch     PetscCall(MatSeqDenseSetPreallocation(newmat,NULL));
2314182d2002SSatish Balay   }
2315182d2002SSatish Balay 
2316182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
23179566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(newmat,&bv));
23189566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(newmat,&ldb));
2319182d2002SSatish Balay   for (i=0; i<ncols; i++) {
23206de62eeeSBarry Smith     av = v + mat->lda*icol[i];
2321ca15aa20SStefano Zampini     for (j=0; j<nrows; j++) bv[j] = av[irow[j]];
2322bf5a80bcSToby Isaac     bv += ldb;
23230754003eSLois Curfman McInnes   }
23249566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(newmat,&bv));
2325182d2002SSatish Balay 
2326182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
23279566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY));
23289566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY));
23290754003eSLois Curfman McInnes 
23300754003eSLois Curfman McInnes   /* Free work space */
23319566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(isrow,&irow));
23329566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(iscol,&icol));
2333182d2002SSatish Balay   *B   = newmat;
23343a40ed3dSBarry Smith   PetscFunctionReturn(0);
23350754003eSLois Curfman McInnes }
23360754003eSLois Curfman McInnes 
23377dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2338905e6a2fSBarry Smith {
233913f74950SBarry Smith   PetscInt       i;
2340905e6a2fSBarry Smith 
23413a40ed3dSBarry Smith   PetscFunctionBegin;
2342905e6a2fSBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
23439566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1(n,B));
2344905e6a2fSBarry Smith   }
2345905e6a2fSBarry Smith 
2346905e6a2fSBarry Smith   for (i=0; i<n; i++) {
23479566063dSJacob Faibussowitsch     PetscCall(MatCreateSubMatrix_SeqDense(A,irow[i],icol[i],scall,&(*B)[i]));
2348905e6a2fSBarry Smith   }
23493a40ed3dSBarry Smith   PetscFunctionReturn(0);
2350905e6a2fSBarry Smith }
2351905e6a2fSBarry Smith 
2352e0877f53SBarry Smith static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat,MatAssemblyType mode)
2353c0aa2d19SHong Zhang {
2354c0aa2d19SHong Zhang   PetscFunctionBegin;
2355c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2356c0aa2d19SHong Zhang }
2357c0aa2d19SHong Zhang 
2358e0877f53SBarry Smith static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat,MatAssemblyType mode)
2359c0aa2d19SHong Zhang {
2360c0aa2d19SHong Zhang   PetscFunctionBegin;
2361c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2362c0aa2d19SHong Zhang }
2363c0aa2d19SHong Zhang 
2364a76f77c3SStefano Zampini PetscErrorCode MatCopy_SeqDense(Mat A,Mat B,MatStructure str)
23654b0e389bSBarry Smith {
23664b0e389bSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data,*b = (Mat_SeqDense*)B->data;
2367ca15aa20SStefano Zampini   const PetscScalar *va;
2368ca15aa20SStefano Zampini   PetscScalar       *vb;
2369d0f46423SBarry Smith   PetscInt          lda1=a->lda,lda2=b->lda, m=A->rmap->n,n=A->cmap->n, j;
23703a40ed3dSBarry Smith 
23713a40ed3dSBarry Smith   PetscFunctionBegin;
237233f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
237333f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
23749566063dSJacob Faibussowitsch     PetscCall(MatCopy_Basic(A,B,str));
23753a40ed3dSBarry Smith     PetscFunctionReturn(0);
23763a40ed3dSBarry Smith   }
2377aed4548fSBarry Smith   PetscCheck(m == B->rmap->n && n == B->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"size(B) != size(A)");
23789566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&va));
23799566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(B,&vb));
2380a5ce6ee0Svictorle   if (lda1>m || lda2>m) {
23810dbb7854Svictorle     for (j=0; j<n; j++) {
23829566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(vb+j*lda2,va+j*lda1,m));
2383a5ce6ee0Svictorle     }
2384a5ce6ee0Svictorle   } else {
23859566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(vb,va,A->rmap->n*A->cmap->n));
2386a5ce6ee0Svictorle   }
23879566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(B,&vb));
23889566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&va));
23899566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY));
23909566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY));
2391273d9f13SBarry Smith   PetscFunctionReturn(0);
2392273d9f13SBarry Smith }
2393273d9f13SBarry Smith 
239475f6d85dSStefano Zampini PetscErrorCode MatSetUp_SeqDense(Mat A)
2395273d9f13SBarry Smith {
2396273d9f13SBarry Smith   PetscFunctionBegin;
23979566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(A->rmap));
23989566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(A->cmap));
239918992e5dSStefano Zampini   if (!A->preallocated) {
24009566063dSJacob Faibussowitsch     PetscCall(MatSeqDenseSetPreallocation(A,NULL));
240118992e5dSStefano Zampini   }
24023a40ed3dSBarry Smith   PetscFunctionReturn(0);
24034b0e389bSBarry Smith }
24044b0e389bSBarry Smith 
2405ba337c44SJed Brown static PetscErrorCode MatConjugate_SeqDense(Mat A)
2406ba337c44SJed Brown {
24074396437dSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense *) A->data;
2408ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
24094396437dSToby Isaac   PetscInt       min = PetscMin(A->rmap->n,A->cmap->n);
2410ca15aa20SStefano Zampini   PetscScalar    *aa;
2411ba337c44SJed Brown 
2412ba337c44SJed Brown   PetscFunctionBegin;
24139566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&aa));
2414ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscConj(aa[i]);
24159566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&aa));
24164396437dSToby Isaac   if (mat->tau) for (i = 0; i < min; i++) mat->tau[i] = PetscConj(mat->tau[i]);
2417ba337c44SJed Brown   PetscFunctionReturn(0);
2418ba337c44SJed Brown }
2419ba337c44SJed Brown 
2420ba337c44SJed Brown static PetscErrorCode MatRealPart_SeqDense(Mat A)
2421ba337c44SJed Brown {
2422ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2423ca15aa20SStefano Zampini   PetscScalar    *aa;
2424ba337c44SJed Brown 
2425ba337c44SJed Brown   PetscFunctionBegin;
24269566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&aa));
2427ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
24289566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&aa));
2429ba337c44SJed Brown   PetscFunctionReturn(0);
2430ba337c44SJed Brown }
2431ba337c44SJed Brown 
2432ba337c44SJed Brown static PetscErrorCode MatImaginaryPart_SeqDense(Mat A)
2433ba337c44SJed Brown {
2434ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2435ca15aa20SStefano Zampini   PetscScalar    *aa;
2436ba337c44SJed Brown 
2437ba337c44SJed Brown   PetscFunctionBegin;
24389566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&aa));
2439ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
24409566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&aa));
2441ba337c44SJed Brown   PetscFunctionReturn(0);
2442ba337c44SJed Brown }
2443284134d9SBarry Smith 
2444a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/
24454222ddf1SHong Zhang PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
2446a9fe9ddaSSatish Balay {
2447d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
24487a3c3d58SStefano Zampini   PetscBool      cisdense;
2449a9fe9ddaSSatish Balay 
2450ee16a9a1SHong Zhang   PetscFunctionBegin;
24519566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C,m,n,m,n));
24529566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,""));
24537a3c3d58SStefano Zampini   if (!cisdense) {
24547a3c3d58SStefano Zampini     PetscBool flg;
24557a3c3d58SStefano Zampini 
24569566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg));
24579566063dSJacob Faibussowitsch     PetscCall(MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE));
24587a3c3d58SStefano Zampini   }
24599566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
2460ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2461ee16a9a1SHong Zhang }
2462a9fe9ddaSSatish Balay 
2463a9fe9ddaSSatish Balay PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2464a9fe9ddaSSatish Balay {
24656718818eSStefano Zampini   Mat_SeqDense       *a=(Mat_SeqDense*)A->data,*b=(Mat_SeqDense*)B->data,*c=(Mat_SeqDense*)C->data;
24660805154bSBarry Smith   PetscBLASInt       m,n,k;
2467ca15aa20SStefano Zampini   const PetscScalar *av,*bv;
2468ca15aa20SStefano Zampini   PetscScalar       *cv;
2469a9fe9ddaSSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
2470a9fe9ddaSSatish Balay 
2471a9fe9ddaSSatish Balay   PetscFunctionBegin;
24729566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n,&m));
24739566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n,&n));
24749566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&k));
247549d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
24769566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&av));
24779566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B,&bv));
24789566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C,&cv));
2479ca15aa20SStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
24809566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1)));
24819566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&av));
24829566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B,&bv));
24839566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C,&cv));
2484a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2485a9fe9ddaSSatish Balay }
2486a9fe9ddaSSatish Balay 
24874222ddf1SHong Zhang PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
248869f65d41SStefano Zampini {
248969f65d41SStefano Zampini   PetscInt       m=A->rmap->n,n=B->rmap->n;
24907a3c3d58SStefano Zampini   PetscBool      cisdense;
249169f65d41SStefano Zampini 
249269f65d41SStefano Zampini   PetscFunctionBegin;
24939566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C,m,n,m,n));
24949566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,""));
24957a3c3d58SStefano Zampini   if (!cisdense) {
24967a3c3d58SStefano Zampini     PetscBool flg;
24977a3c3d58SStefano Zampini 
24989566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg));
24999566063dSJacob Faibussowitsch     PetscCall(MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE));
25007a3c3d58SStefano Zampini   }
25019566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
250269f65d41SStefano Zampini   PetscFunctionReturn(0);
250369f65d41SStefano Zampini }
250469f65d41SStefano Zampini 
250569f65d41SStefano Zampini PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
250669f65d41SStefano Zampini {
250769f65d41SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
250869f65d41SStefano Zampini   Mat_SeqDense      *b = (Mat_SeqDense*)B->data;
250969f65d41SStefano Zampini   Mat_SeqDense      *c = (Mat_SeqDense*)C->data;
25106718818eSStefano Zampini   const PetscScalar *av,*bv;
25116718818eSStefano Zampini   PetscScalar       *cv;
251269f65d41SStefano Zampini   PetscBLASInt      m,n,k;
251369f65d41SStefano Zampini   PetscScalar       _DOne=1.0,_DZero=0.0;
251469f65d41SStefano Zampini 
251569f65d41SStefano Zampini   PetscFunctionBegin;
25169566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n,&m));
25179566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n,&n));
25189566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&k));
251949d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
25209566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&av));
25219566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B,&bv));
25229566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C,&cv));
25236718818eSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","T",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
25249566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&av));
25259566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B,&bv));
25269566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C,&cv));
25279566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1)));
252869f65d41SStefano Zampini   PetscFunctionReturn(0);
252969f65d41SStefano Zampini }
253069f65d41SStefano Zampini 
25314222ddf1SHong Zhang PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
2532a9fe9ddaSSatish Balay {
2533d0f46423SBarry Smith   PetscInt       m=A->cmap->n,n=B->cmap->n;
25347a3c3d58SStefano Zampini   PetscBool      cisdense;
2535a9fe9ddaSSatish Balay 
2536ee16a9a1SHong Zhang   PetscFunctionBegin;
25379566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C,m,n,m,n));
25389566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,""));
25397a3c3d58SStefano Zampini   if (!cisdense) {
25407a3c3d58SStefano Zampini     PetscBool flg;
25417a3c3d58SStefano Zampini 
25429566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg));
25439566063dSJacob Faibussowitsch     PetscCall(MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE));
25447a3c3d58SStefano Zampini   }
25459566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
2546ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2547ee16a9a1SHong Zhang }
2548a9fe9ddaSSatish Balay 
254975648e8dSHong Zhang PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2550a9fe9ddaSSatish Balay {
2551a9fe9ddaSSatish Balay   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2552a9fe9ddaSSatish Balay   Mat_SeqDense      *b = (Mat_SeqDense*)B->data;
2553a9fe9ddaSSatish Balay   Mat_SeqDense      *c = (Mat_SeqDense*)C->data;
25546718818eSStefano Zampini   const PetscScalar *av,*bv;
25556718818eSStefano Zampini   PetscScalar       *cv;
25560805154bSBarry Smith   PetscBLASInt      m,n,k;
2557a9fe9ddaSSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
2558a9fe9ddaSSatish Balay 
2559a9fe9ddaSSatish Balay   PetscFunctionBegin;
25609566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n,&m));
25619566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n,&n));
25629566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&k));
256349d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
25649566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&av));
25659566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B,&bv));
25669566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C,&cv));
25676718818eSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
25689566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&av));
25699566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B,&bv));
25709566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C,&cv));
25719566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1)));
2572a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2573a9fe9ddaSSatish Balay }
2574985db425SBarry Smith 
25754222ddf1SHong Zhang /* ----------------------------------------------- */
25764222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C)
25774222ddf1SHong Zhang {
25784222ddf1SHong Zhang   PetscFunctionBegin;
25794222ddf1SHong Zhang   C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense;
25804222ddf1SHong Zhang   C->ops->productsymbolic = MatProductSymbolic_AB;
25814222ddf1SHong Zhang   PetscFunctionReturn(0);
25824222ddf1SHong Zhang }
25834222ddf1SHong Zhang 
25844222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C)
25854222ddf1SHong Zhang {
25864222ddf1SHong Zhang   PetscFunctionBegin;
25874222ddf1SHong Zhang   C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense;
25884222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_AtB;
25894222ddf1SHong Zhang   PetscFunctionReturn(0);
25904222ddf1SHong Zhang }
25914222ddf1SHong Zhang 
25924222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C)
25934222ddf1SHong Zhang {
25944222ddf1SHong Zhang   PetscFunctionBegin;
25954222ddf1SHong Zhang   C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense;
25964222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_ABt;
25974222ddf1SHong Zhang   PetscFunctionReturn(0);
25984222ddf1SHong Zhang }
25994222ddf1SHong Zhang 
26004222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C)
26014222ddf1SHong Zhang {
26024222ddf1SHong Zhang   Mat_Product    *product = C->product;
26034222ddf1SHong Zhang 
26044222ddf1SHong Zhang   PetscFunctionBegin;
26054222ddf1SHong Zhang   switch (product->type) {
26064222ddf1SHong Zhang   case MATPRODUCT_AB:
26079566063dSJacob Faibussowitsch     PetscCall(MatProductSetFromOptions_SeqDense_AB(C));
26084222ddf1SHong Zhang     break;
26094222ddf1SHong Zhang   case MATPRODUCT_AtB:
26109566063dSJacob Faibussowitsch     PetscCall(MatProductSetFromOptions_SeqDense_AtB(C));
26114222ddf1SHong Zhang     break;
26124222ddf1SHong Zhang   case MATPRODUCT_ABt:
26139566063dSJacob Faibussowitsch     PetscCall(MatProductSetFromOptions_SeqDense_ABt(C));
26144222ddf1SHong Zhang     break;
26156718818eSStefano Zampini   default:
26164222ddf1SHong Zhang     break;
26174222ddf1SHong Zhang   }
26184222ddf1SHong Zhang   PetscFunctionReturn(0);
26194222ddf1SHong Zhang }
26204222ddf1SHong Zhang /* ----------------------------------------------- */
26214222ddf1SHong Zhang 
2622e0877f53SBarry Smith static PetscErrorCode MatGetRowMax_SeqDense(Mat A,Vec v,PetscInt idx[])
2623985db425SBarry Smith {
2624985db425SBarry Smith   Mat_SeqDense       *a = (Mat_SeqDense*)A->data;
2625d0f46423SBarry Smith   PetscInt           i,j,m = A->rmap->n,n = A->cmap->n,p;
2626985db425SBarry Smith   PetscScalar        *x;
2627ca15aa20SStefano Zampini   const PetscScalar *aa;
2628985db425SBarry Smith 
2629985db425SBarry Smith   PetscFunctionBegin;
263028b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
26319566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v,&x));
26329566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v,&p));
26339566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&aa));
263408401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2635985db425SBarry Smith   for (i=0; i<m; i++) {
2636985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2637985db425SBarry Smith     for (j=1; j<n; j++) {
2638ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) < PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2639985db425SBarry Smith     }
2640985db425SBarry Smith   }
26419566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&aa));
26429566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v,&x));
2643985db425SBarry Smith   PetscFunctionReturn(0);
2644985db425SBarry Smith }
2645985db425SBarry Smith 
2646e0877f53SBarry Smith static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A,Vec v,PetscInt idx[])
2647985db425SBarry Smith {
2648985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2649d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2650985db425SBarry Smith   PetscScalar       *x;
2651985db425SBarry Smith   PetscReal         atmp;
2652ca15aa20SStefano Zampini   const PetscScalar *aa;
2653985db425SBarry Smith 
2654985db425SBarry Smith   PetscFunctionBegin;
265528b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
26569566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v,&x));
26579566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v,&p));
26589566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&aa));
265908401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2660985db425SBarry Smith   for (i=0; i<m; i++) {
26619189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
2662985db425SBarry Smith     for (j=1; j<n; j++) {
2663ca15aa20SStefano Zampini       atmp = PetscAbsScalar(aa[i+a->lda*j]);
2664985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = j;}
2665985db425SBarry Smith     }
2666985db425SBarry Smith   }
26679566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&aa));
26689566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v,&x));
2669985db425SBarry Smith   PetscFunctionReturn(0);
2670985db425SBarry Smith }
2671985db425SBarry Smith 
2672e0877f53SBarry Smith static PetscErrorCode MatGetRowMin_SeqDense(Mat A,Vec v,PetscInt idx[])
2673985db425SBarry Smith {
2674985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2675d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2676985db425SBarry Smith   PetscScalar       *x;
2677ca15aa20SStefano Zampini   const PetscScalar *aa;
2678985db425SBarry Smith 
2679985db425SBarry Smith   PetscFunctionBegin;
268028b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
26819566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&aa));
26829566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v,&x));
26839566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v,&p));
268408401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2685985db425SBarry Smith   for (i=0; i<m; i++) {
2686985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2687985db425SBarry Smith     for (j=1; j<n; j++) {
2688ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) > PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2689985db425SBarry Smith     }
2690985db425SBarry Smith   }
26919566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v,&x));
26929566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&aa));
2693985db425SBarry Smith   PetscFunctionReturn(0);
2694985db425SBarry Smith }
2695985db425SBarry Smith 
2696637a0070SStefano Zampini PetscErrorCode MatGetColumnVector_SeqDense(Mat A,Vec v,PetscInt col)
26978d0534beSBarry Smith {
26988d0534beSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
26998d0534beSBarry Smith   PetscScalar       *x;
2700ca15aa20SStefano Zampini   const PetscScalar *aa;
27018d0534beSBarry Smith 
27028d0534beSBarry Smith   PetscFunctionBegin;
270328b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
27049566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&aa));
27059566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v,&x));
27069566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(x,aa+col*a->lda,A->rmap->n));
27079566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v,&x));
27089566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&aa));
27098d0534beSBarry Smith   PetscFunctionReturn(0);
27108d0534beSBarry Smith }
27118d0534beSBarry Smith 
2712857cbf51SRichard Tran Mills PETSC_INTERN PetscErrorCode MatGetColumnReductions_SeqDense(Mat A,PetscInt type,PetscReal *reductions)
27130716a85fSBarry Smith {
27140716a85fSBarry Smith   PetscInt          i,j,m,n;
27151683a169SBarry Smith   const PetscScalar *a;
27160716a85fSBarry Smith 
27170716a85fSBarry Smith   PetscFunctionBegin;
27189566063dSJacob Faibussowitsch   PetscCall(MatGetSize(A,&m,&n));
27199566063dSJacob Faibussowitsch   PetscCall(PetscArrayzero(reductions,n));
27209566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&a));
2721857cbf51SRichard Tran Mills   if (type == NORM_2) {
27220716a85fSBarry Smith     for (i=0; i<n; i++) {
27230716a85fSBarry Smith       for (j=0; j<m; j++) {
2724a873a8cdSSam Reynolds         reductions[i] += PetscAbsScalar(a[j]*a[j]);
27250716a85fSBarry Smith       }
27260716a85fSBarry Smith       a += m;
27270716a85fSBarry Smith     }
2728857cbf51SRichard Tran Mills   } else if (type == NORM_1) {
27290716a85fSBarry Smith     for (i=0; i<n; i++) {
27300716a85fSBarry Smith       for (j=0; j<m; j++) {
2731a873a8cdSSam Reynolds         reductions[i] += PetscAbsScalar(a[j]);
27320716a85fSBarry Smith       }
27330716a85fSBarry Smith       a += m;
27340716a85fSBarry Smith     }
2735857cbf51SRichard Tran Mills   } else if (type == NORM_INFINITY) {
27360716a85fSBarry Smith     for (i=0; i<n; i++) {
27370716a85fSBarry Smith       for (j=0; j<m; j++) {
2738a873a8cdSSam Reynolds         reductions[i] = PetscMax(PetscAbsScalar(a[j]),reductions[i]);
27390716a85fSBarry Smith       }
27400716a85fSBarry Smith       a += m;
27410716a85fSBarry Smith     }
2742857cbf51SRichard Tran Mills   } else if (type == REDUCTION_SUM_REALPART || type == REDUCTION_MEAN_REALPART) {
2743a873a8cdSSam Reynolds     for (i=0; i<n; i++) {
2744a873a8cdSSam Reynolds       for (j=0; j<m; j++) {
2745857cbf51SRichard Tran Mills         reductions[i] += PetscRealPart(a[j]);
2746a873a8cdSSam Reynolds       }
2747a873a8cdSSam Reynolds       a += m;
2748a873a8cdSSam Reynolds     }
2749857cbf51SRichard Tran Mills   } else if (type == REDUCTION_SUM_IMAGINARYPART || type == REDUCTION_MEAN_IMAGINARYPART) {
2750857cbf51SRichard Tran Mills     for (i=0; i<n; i++) {
2751857cbf51SRichard Tran Mills       for (j=0; j<m; j++) {
2752857cbf51SRichard Tran Mills         reductions[i] += PetscImaginaryPart(a[j]);
2753857cbf51SRichard Tran Mills       }
2754857cbf51SRichard Tran Mills       a += m;
2755857cbf51SRichard Tran Mills     }
2756857cbf51SRichard Tran Mills   } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Unknown reduction type");
27579566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&a));
2758857cbf51SRichard Tran Mills   if (type == NORM_2) {
2759a873a8cdSSam Reynolds     for (i=0; i<n; i++) reductions[i] = PetscSqrtReal(reductions[i]);
2760857cbf51SRichard Tran Mills   } else if (type == REDUCTION_MEAN_REALPART || type == REDUCTION_MEAN_IMAGINARYPART) {
2761a873a8cdSSam Reynolds     for (i=0; i<n; i++) reductions[i] /= m;
27620716a85fSBarry Smith   }
27630716a85fSBarry Smith   PetscFunctionReturn(0);
27640716a85fSBarry Smith }
27650716a85fSBarry Smith 
276673a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqDense(Mat x,PetscRandom rctx)
276773a71a0fSBarry Smith {
276873a71a0fSBarry Smith   PetscScalar    *a;
2769637a0070SStefano Zampini   PetscInt       lda,m,n,i,j;
277073a71a0fSBarry Smith 
277173a71a0fSBarry Smith   PetscFunctionBegin;
27729566063dSJacob Faibussowitsch   PetscCall(MatGetSize(x,&m,&n));
27739566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(x,&lda));
27749566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(x,&a));
2775637a0070SStefano Zampini   for (j=0; j<n; j++) {
2776637a0070SStefano Zampini     for (i=0; i<m; i++) {
27779566063dSJacob Faibussowitsch       PetscCall(PetscRandomGetValue(rctx,a+j*lda+i));
2778637a0070SStefano Zampini     }
277973a71a0fSBarry Smith   }
27809566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(x,&a));
278173a71a0fSBarry Smith   PetscFunctionReturn(0);
278273a71a0fSBarry Smith }
278373a71a0fSBarry Smith 
27843b49f96aSBarry Smith static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A,PetscBool  *missing,PetscInt *d)
27853b49f96aSBarry Smith {
27863b49f96aSBarry Smith   PetscFunctionBegin;
27873b49f96aSBarry Smith   *missing = PETSC_FALSE;
27883b49f96aSBarry Smith   PetscFunctionReturn(0);
27893b49f96aSBarry Smith }
279073a71a0fSBarry Smith 
2791ca15aa20SStefano Zampini /* vals is not const */
2792af53bab2SHong Zhang static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A,PetscInt col,PetscScalar **vals)
279386aefd0dSHong Zhang {
279486aefd0dSHong Zhang   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2795ca15aa20SStefano Zampini   PetscScalar    *v;
279686aefd0dSHong Zhang 
279786aefd0dSHong Zhang   PetscFunctionBegin;
279828b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
27999566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&v));
2800ca15aa20SStefano Zampini   *vals = v+col*a->lda;
28019566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&v));
280286aefd0dSHong Zhang   PetscFunctionReturn(0);
280386aefd0dSHong Zhang }
280486aefd0dSHong Zhang 
2805af53bab2SHong Zhang static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A,PetscScalar **vals)
280686aefd0dSHong Zhang {
280786aefd0dSHong Zhang   PetscFunctionBegin;
2808a5b23f4aSJose E. Roman   *vals = NULL; /* user cannot accidentally use the array later */
280986aefd0dSHong Zhang   PetscFunctionReturn(0);
281086aefd0dSHong Zhang }
2811abc3b08eSStefano Zampini 
2812289bc588SBarry Smith /* -------------------------------------------------------------------*/
2813a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqDense,
2814905e6a2fSBarry Smith                                         MatGetRow_SeqDense,
2815905e6a2fSBarry Smith                                         MatRestoreRow_SeqDense,
2816905e6a2fSBarry Smith                                         MatMult_SeqDense,
281797304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqDense,
28187c922b88SBarry Smith                                         MatMultTranspose_SeqDense,
28197c922b88SBarry Smith                                         MatMultTransposeAdd_SeqDense,
2820f4259b30SLisandro Dalcin                                         NULL,
2821f4259b30SLisandro Dalcin                                         NULL,
2822f4259b30SLisandro Dalcin                                         NULL,
2823f4259b30SLisandro Dalcin                                 /* 10*/ NULL,
2824905e6a2fSBarry Smith                                         MatLUFactor_SeqDense,
2825905e6a2fSBarry Smith                                         MatCholeskyFactor_SeqDense,
282641f059aeSBarry Smith                                         MatSOR_SeqDense,
2827ec8511deSBarry Smith                                         MatTranspose_SeqDense,
282897304618SKris Buschelman                                 /* 15*/ MatGetInfo_SeqDense,
2829905e6a2fSBarry Smith                                         MatEqual_SeqDense,
2830905e6a2fSBarry Smith                                         MatGetDiagonal_SeqDense,
2831905e6a2fSBarry Smith                                         MatDiagonalScale_SeqDense,
2832905e6a2fSBarry Smith                                         MatNorm_SeqDense,
2833c0aa2d19SHong Zhang                                 /* 20*/ MatAssemblyBegin_SeqDense,
2834c0aa2d19SHong Zhang                                         MatAssemblyEnd_SeqDense,
2835905e6a2fSBarry Smith                                         MatSetOption_SeqDense,
2836905e6a2fSBarry Smith                                         MatZeroEntries_SeqDense,
2837d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqDense,
2838f4259b30SLisandro Dalcin                                         NULL,
2839f4259b30SLisandro Dalcin                                         NULL,
2840f4259b30SLisandro Dalcin                                         NULL,
2841f4259b30SLisandro Dalcin                                         NULL,
28424994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqDense,
2843f4259b30SLisandro Dalcin                                         NULL,
2844f4259b30SLisandro Dalcin                                         NULL,
2845f4259b30SLisandro Dalcin                                         NULL,
2846f4259b30SLisandro Dalcin                                         NULL,
2847d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqDense,
2848f4259b30SLisandro Dalcin                                         NULL,
2849f4259b30SLisandro Dalcin                                         NULL,
2850f4259b30SLisandro Dalcin                                         NULL,
2851f4259b30SLisandro Dalcin                                         NULL,
2852d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqDense,
28537dae84e0SHong Zhang                                         MatCreateSubMatrices_SeqDense,
2854f4259b30SLisandro Dalcin                                         NULL,
28554b0e389bSBarry Smith                                         MatGetValues_SeqDense,
2856a5ae1ecdSBarry Smith                                         MatCopy_SeqDense,
2857d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqDense,
2858a5ae1ecdSBarry Smith                                         MatScale_SeqDense,
28592f605a99SJose E. Roman                                         MatShift_SeqDense,
2860f4259b30SLisandro Dalcin                                         NULL,
28613f49a652SStefano Zampini                                         MatZeroRowsColumns_SeqDense,
286273a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqDense,
2863f4259b30SLisandro Dalcin                                         NULL,
2864f4259b30SLisandro Dalcin                                         NULL,
2865f4259b30SLisandro Dalcin                                         NULL,
2866f4259b30SLisandro Dalcin                                         NULL,
2867f4259b30SLisandro Dalcin                                 /* 54*/ NULL,
2868f4259b30SLisandro Dalcin                                         NULL,
2869f4259b30SLisandro Dalcin                                         NULL,
2870f4259b30SLisandro Dalcin                                         NULL,
2871f4259b30SLisandro Dalcin                                         NULL,
2872023c16fcSToby Isaac                                 /* 59*/ MatCreateSubMatrix_SeqDense,
2873e03a110bSBarry Smith                                         MatDestroy_SeqDense,
2874e03a110bSBarry Smith                                         MatView_SeqDense,
2875f4259b30SLisandro Dalcin                                         NULL,
2876f4259b30SLisandro Dalcin                                         NULL,
2877f4259b30SLisandro Dalcin                                 /* 64*/ NULL,
2878f4259b30SLisandro Dalcin                                         NULL,
2879f4259b30SLisandro Dalcin                                         NULL,
2880f4259b30SLisandro Dalcin                                         NULL,
2881f4259b30SLisandro Dalcin                                         NULL,
2882d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqDense,
2883f4259b30SLisandro Dalcin                                         NULL,
2884f4259b30SLisandro Dalcin                                         NULL,
2885f4259b30SLisandro Dalcin                                         NULL,
2886f4259b30SLisandro Dalcin                                         NULL,
2887f4259b30SLisandro Dalcin                                 /* 74*/ NULL,
2888f4259b30SLisandro Dalcin                                         NULL,
2889f4259b30SLisandro Dalcin                                         NULL,
2890f4259b30SLisandro Dalcin                                         NULL,
2891f4259b30SLisandro Dalcin                                         NULL,
2892f4259b30SLisandro Dalcin                                 /* 79*/ NULL,
2893f4259b30SLisandro Dalcin                                         NULL,
2894f4259b30SLisandro Dalcin                                         NULL,
2895f4259b30SLisandro Dalcin                                         NULL,
28965bba2384SShri Abhyankar                                 /* 83*/ MatLoad_SeqDense,
2897637a0070SStefano Zampini                                         MatIsSymmetric_SeqDense,
28981cbb95d3SBarry Smith                                         MatIsHermitian_SeqDense,
2899f4259b30SLisandro Dalcin                                         NULL,
2900f4259b30SLisandro Dalcin                                         NULL,
2901f4259b30SLisandro Dalcin                                         NULL,
2902f4259b30SLisandro Dalcin                                 /* 89*/ NULL,
2903f4259b30SLisandro Dalcin                                         NULL,
2904a9fe9ddaSSatish Balay                                         MatMatMultNumeric_SeqDense_SeqDense,
2905f4259b30SLisandro Dalcin                                         NULL,
2906f4259b30SLisandro Dalcin                                         NULL,
2907f4259b30SLisandro Dalcin                                 /* 94*/ NULL,
2908f4259b30SLisandro Dalcin                                         NULL,
2909f4259b30SLisandro Dalcin                                         NULL,
291069f65d41SStefano Zampini                                         MatMatTransposeMultNumeric_SeqDense_SeqDense,
2911f4259b30SLisandro Dalcin                                         NULL,
29124222ddf1SHong Zhang                                 /* 99*/ MatProductSetFromOptions_SeqDense,
2913f4259b30SLisandro Dalcin                                         NULL,
2914f4259b30SLisandro Dalcin                                         NULL,
2915ba337c44SJed Brown                                         MatConjugate_SeqDense,
2916f4259b30SLisandro Dalcin                                         NULL,
2917f4259b30SLisandro Dalcin                                 /*104*/ NULL,
2918ba337c44SJed Brown                                         MatRealPart_SeqDense,
2919ba337c44SJed Brown                                         MatImaginaryPart_SeqDense,
2920f4259b30SLisandro Dalcin                                         NULL,
2921f4259b30SLisandro Dalcin                                         NULL,
2922f4259b30SLisandro Dalcin                                 /*109*/ NULL,
2923f4259b30SLisandro Dalcin                                         NULL,
29248d0534beSBarry Smith                                         MatGetRowMin_SeqDense,
2925aabbc4fbSShri Abhyankar                                         MatGetColumnVector_SeqDense,
29263b49f96aSBarry Smith                                         MatMissingDiagonal_SeqDense,
2927f4259b30SLisandro Dalcin                                 /*114*/ NULL,
2928f4259b30SLisandro Dalcin                                         NULL,
2929f4259b30SLisandro Dalcin                                         NULL,
2930f4259b30SLisandro Dalcin                                         NULL,
2931f4259b30SLisandro Dalcin                                         NULL,
2932f4259b30SLisandro Dalcin                                 /*119*/ NULL,
2933f4259b30SLisandro Dalcin                                         NULL,
2934f4259b30SLisandro Dalcin                                         NULL,
2935f4259b30SLisandro Dalcin                                         NULL,
2936f4259b30SLisandro Dalcin                                         NULL,
2937f4259b30SLisandro Dalcin                                 /*124*/ NULL,
2938a873a8cdSSam Reynolds                                         MatGetColumnReductions_SeqDense,
2939f4259b30SLisandro Dalcin                                         NULL,
2940f4259b30SLisandro Dalcin                                         NULL,
2941f4259b30SLisandro Dalcin                                         NULL,
2942f4259b30SLisandro Dalcin                                 /*129*/ NULL,
2943f4259b30SLisandro Dalcin                                         NULL,
2944f4259b30SLisandro Dalcin                                         NULL,
294575648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqDense_SeqDense,
2946f4259b30SLisandro Dalcin                                         NULL,
2947f4259b30SLisandro Dalcin                                 /*134*/ NULL,
2948f4259b30SLisandro Dalcin                                         NULL,
2949f4259b30SLisandro Dalcin                                         NULL,
2950f4259b30SLisandro Dalcin                                         NULL,
2951f4259b30SLisandro Dalcin                                         NULL,
2952f4259b30SLisandro Dalcin                                 /*139*/ NULL,
2953f4259b30SLisandro Dalcin                                         NULL,
2954f4259b30SLisandro Dalcin                                         NULL,
2955f4259b30SLisandro Dalcin                                         NULL,
2956f4259b30SLisandro Dalcin                                         NULL,
29574222ddf1SHong Zhang                                         MatCreateMPIMatConcatenateSeqMat_SeqDense,
2958f4259b30SLisandro Dalcin                                 /*145*/ NULL,
2959f4259b30SLisandro Dalcin                                         NULL,
2960f4259b30SLisandro Dalcin                                         NULL
2961985db425SBarry Smith };
296290ace30eSBarry Smith 
29634b828684SBarry Smith /*@C
2964fafbff53SBarry Smith    MatCreateSeqDense - Creates a sequential dense matrix that
2965d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
2966d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
2967289bc588SBarry Smith 
2968d083f849SBarry Smith    Collective
2969db81eaa0SLois Curfman McInnes 
297020563c6bSBarry Smith    Input Parameters:
2971db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
29720c775827SLois Curfman McInnes .  m - number of rows
297318f449edSLois Curfman McInnes .  n - number of columns
29740298fd71SBarry Smith -  data - optional location of matrix data in column major order.  Set data=NULL for PETSc
2975dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
297620563c6bSBarry Smith 
297720563c6bSBarry Smith    Output Parameter:
297844cd7ae7SLois Curfman McInnes .  A - the matrix
297920563c6bSBarry Smith 
2980b259b22eSLois Curfman McInnes    Notes:
298118f449edSLois Curfman McInnes    The data input variable is intended primarily for Fortran programmers
298218f449edSLois Curfman McInnes    who wish to allocate their own matrix memory space.  Most users should
29830298fd71SBarry Smith    set data=NULL.
298418f449edSLois Curfman McInnes 
2985027ccd11SLois Curfman McInnes    Level: intermediate
2986027ccd11SLois Curfman McInnes 
2987db781477SPatrick Sanan .seealso: `MatCreate()`, `MatCreateDense()`, `MatSetValues()`
298820563c6bSBarry Smith @*/
29897087cfbeSBarry Smith PetscErrorCode  MatCreateSeqDense(MPI_Comm comm,PetscInt m,PetscInt n,PetscScalar *data,Mat *A)
2990289bc588SBarry Smith {
29913a40ed3dSBarry Smith   PetscFunctionBegin;
29929566063dSJacob Faibussowitsch   PetscCall(MatCreate(comm,A));
29939566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*A,m,n,m,n));
29949566063dSJacob Faibussowitsch   PetscCall(MatSetType(*A,MATSEQDENSE));
29959566063dSJacob Faibussowitsch   PetscCall(MatSeqDenseSetPreallocation(*A,data));
2996273d9f13SBarry Smith   PetscFunctionReturn(0);
2997273d9f13SBarry Smith }
2998273d9f13SBarry Smith 
2999273d9f13SBarry Smith /*@C
3000273d9f13SBarry Smith    MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements
3001273d9f13SBarry Smith 
3002d083f849SBarry Smith    Collective
3003273d9f13SBarry Smith 
3004273d9f13SBarry Smith    Input Parameters:
30051c4f3114SJed Brown +  B - the matrix
30060298fd71SBarry Smith -  data - the array (or NULL)
3007273d9f13SBarry Smith 
3008273d9f13SBarry Smith    Notes:
3009273d9f13SBarry Smith    The data input variable is intended primarily for Fortran programmers
3010273d9f13SBarry Smith    who wish to allocate their own matrix memory space.  Most users should
3011284134d9SBarry Smith    need not call this routine.
3012273d9f13SBarry Smith 
3013273d9f13SBarry Smith    Level: intermediate
3014273d9f13SBarry Smith 
3015db781477SPatrick Sanan .seealso: `MatCreate()`, `MatCreateDense()`, `MatSetValues()`, `MatDenseSetLDA()`
3016867c911aSBarry Smith 
3017273d9f13SBarry Smith @*/
30187087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation(Mat B,PetscScalar data[])
3019273d9f13SBarry Smith {
3020a23d5eceSKris Buschelman   PetscFunctionBegin;
3021d5ea218eSStefano Zampini   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
3022cac4c232SBarry Smith   PetscTryMethod(B,"MatSeqDenseSetPreallocation_C",(Mat,PetscScalar[]),(B,data));
3023a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3024a23d5eceSKris Buschelman }
3025a23d5eceSKris Buschelman 
30267087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation_SeqDense(Mat B,PetscScalar *data)
3027a23d5eceSKris Buschelman {
3028ad16ce7aSStefano Zampini   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
3029273d9f13SBarry Smith 
3030273d9f13SBarry Smith   PetscFunctionBegin;
303128b400f6SJacob Faibussowitsch   PetscCheck(!b->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
3032273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
3033a868139aSShri Abhyankar 
30349566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(B->rmap));
30359566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(B->cmap));
303634ef9618SShri Abhyankar 
3037ad16ce7aSStefano Zampini   if (b->lda <= 0) b->lda = B->rmap->n;
303886d161a7SShri Abhyankar 
30399e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
30409566063dSJacob Faibussowitsch     if (!b->user_alloc) PetscCall(PetscFree(b->v));
30419566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1((size_t)b->lda*B->cmap->n,&b->v));
30429566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)B,b->lda*B->cmap->n*sizeof(PetscScalar)));
30432205254eSKarl Rupp 
30449e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
3045273d9f13SBarry Smith   } else { /* user-allocated storage */
30469566063dSJacob Faibussowitsch     if (!b->user_alloc) PetscCall(PetscFree(b->v));
3047273d9f13SBarry Smith     b->v          = data;
3048273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
3049273d9f13SBarry Smith   }
30500450473dSBarry Smith   B->assembled = PETSC_TRUE;
3051273d9f13SBarry Smith   PetscFunctionReturn(0);
3052273d9f13SBarry Smith }
3053273d9f13SBarry Smith 
305465b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
3055cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
30568baccfbdSHong Zhang {
3057d77f618aSHong Zhang   Mat               mat_elemental;
30581683a169SBarry Smith   const PetscScalar *array;
30591683a169SBarry Smith   PetscScalar       *v_colwise;
3060d77f618aSHong Zhang   PetscInt          M=A->rmap->N,N=A->cmap->N,i,j,k,*rows,*cols;
3061d77f618aSHong Zhang 
30628baccfbdSHong Zhang   PetscFunctionBegin;
30639566063dSJacob Faibussowitsch   PetscCall(PetscMalloc3(M*N,&v_colwise,M,&rows,N,&cols));
30649566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&array));
3065d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
3066d77f618aSHong Zhang   k = 0;
3067d77f618aSHong Zhang   for (j=0; j<N; j++) {
3068d77f618aSHong Zhang     cols[j] = j;
3069d77f618aSHong Zhang     for (i=0; i<M; i++) {
3070d77f618aSHong Zhang       v_colwise[j*M+i] = array[k++];
3071d77f618aSHong Zhang     }
3072d77f618aSHong Zhang   }
3073d77f618aSHong Zhang   for (i=0; i<M; i++) {
3074d77f618aSHong Zhang     rows[i] = i;
3075d77f618aSHong Zhang   }
30769566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&array));
3077d77f618aSHong Zhang 
30789566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental));
30799566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N));
30809566063dSJacob Faibussowitsch   PetscCall(MatSetType(mat_elemental,MATELEMENTAL));
30819566063dSJacob Faibussowitsch   PetscCall(MatSetUp(mat_elemental));
3082d77f618aSHong Zhang 
3083d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
30849566063dSJacob Faibussowitsch   PetscCall(MatSetValues(mat_elemental,M,rows,N,cols,v_colwise,ADD_VALUES));
30859566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY));
30869566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY));
30879566063dSJacob Faibussowitsch   PetscCall(PetscFree3(v_colwise,rows,cols));
3088d77f618aSHong Zhang 
3089511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
30909566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A,&mat_elemental));
3091d77f618aSHong Zhang   } else {
3092d77f618aSHong Zhang     *newmat = mat_elemental;
3093d77f618aSHong Zhang   }
30948baccfbdSHong Zhang   PetscFunctionReturn(0);
30958baccfbdSHong Zhang }
309665b80a83SHong Zhang #endif
30978baccfbdSHong Zhang 
309817359960SJose E. Roman PetscErrorCode  MatDenseSetLDA_SeqDense(Mat B,PetscInt lda)
30991b807ce4Svictorle {
31001b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense*)B->data;
31017422da62SJose E. Roman   PetscBool    data;
310221a2c019SBarry Smith 
31031b807ce4Svictorle   PetscFunctionBegin;
31047422da62SJose E. Roman   data = (PetscBool)((B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE);
3105aed4548fSBarry Smith   PetscCheck(b->user_alloc || !data || b->lda == lda,PETSC_COMM_SELF,PETSC_ERR_ORDER,"LDA cannot be changed after allocation of internal storage");
310608401ef6SPierre Jolivet   PetscCheck(lda >= B->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"LDA %" PetscInt_FMT " must be at least matrix dimension %" PetscInt_FMT,lda,B->rmap->n);
31071b807ce4Svictorle   b->lda = lda;
31081b807ce4Svictorle   PetscFunctionReturn(0);
31091b807ce4Svictorle }
31101b807ce4Svictorle 
3111d528f656SJakub Kruzik PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat)
3112d528f656SJakub Kruzik {
3113d528f656SJakub Kruzik   PetscMPIInt    size;
3114d528f656SJakub Kruzik 
3115d528f656SJakub Kruzik   PetscFunctionBegin;
31169566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(comm,&size));
3117d528f656SJakub Kruzik   if (size == 1) {
3118d528f656SJakub Kruzik     if (scall == MAT_INITIAL_MATRIX) {
31199566063dSJacob Faibussowitsch       PetscCall(MatDuplicate(inmat,MAT_COPY_VALUES,outmat));
3120d528f656SJakub Kruzik     } else {
31219566063dSJacob Faibussowitsch       PetscCall(MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN));
3122d528f656SJakub Kruzik     }
3123d528f656SJakub Kruzik   } else {
31249566063dSJacob Faibussowitsch     PetscCall(MatCreateMPIMatConcatenateSeqMat_MPIDense(comm,inmat,n,scall,outmat));
3125d528f656SJakub Kruzik   }
3126d528f656SJakub Kruzik   PetscFunctionReturn(0);
3127d528f656SJakub Kruzik }
3128d528f656SJakub Kruzik 
31296947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A,PetscInt col,Vec *v)
31306947451fSStefano Zampini {
31316947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
31326947451fSStefano Zampini 
31336947451fSStefano Zampini   PetscFunctionBegin;
313428b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
313528b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
31366947451fSStefano Zampini   if (!a->cvec) {
31379566063dSJacob Faibussowitsch     PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec));
31389566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec));
31396947451fSStefano Zampini   }
31406947451fSStefano Zampini   a->vecinuse = col + 1;
31419566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,(PetscScalar**)&a->ptrinuse));
31429566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda));
31436947451fSStefano Zampini   *v   = a->cvec;
31446947451fSStefano Zampini   PetscFunctionReturn(0);
31456947451fSStefano Zampini }
31466947451fSStefano Zampini 
31476947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A,PetscInt col,Vec *v)
31486947451fSStefano Zampini {
31496947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
31506947451fSStefano Zampini 
31516947451fSStefano Zampini   PetscFunctionBegin;
315228b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first");
315328b400f6SJacob Faibussowitsch   PetscCheck(a->cvec,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
31546947451fSStefano Zampini   a->vecinuse = 0;
31559566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,(PetscScalar**)&a->ptrinuse));
31569566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
315775f6d85dSStefano Zampini   if (v) *v = NULL;
31586947451fSStefano Zampini   PetscFunctionReturn(0);
31596947451fSStefano Zampini }
31606947451fSStefano Zampini 
31616947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A,PetscInt col,Vec *v)
31626947451fSStefano Zampini {
31636947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
31646947451fSStefano Zampini 
31656947451fSStefano Zampini   PetscFunctionBegin;
316628b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
316728b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
31686947451fSStefano Zampini   if (!a->cvec) {
31699566063dSJacob Faibussowitsch     PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec));
31709566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec));
31716947451fSStefano Zampini   }
31726947451fSStefano Zampini   a->vecinuse = col + 1;
31739566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&a->ptrinuse));
31749566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda));
31759566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(a->cvec));
31766947451fSStefano Zampini   *v   = a->cvec;
31776947451fSStefano Zampini   PetscFunctionReturn(0);
31786947451fSStefano Zampini }
31796947451fSStefano Zampini 
31806947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A,PetscInt col,Vec *v)
31816947451fSStefano Zampini {
31826947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
31836947451fSStefano Zampini 
31846947451fSStefano Zampini   PetscFunctionBegin;
318528b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first");
318628b400f6SJacob Faibussowitsch   PetscCheck(a->cvec,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
31876947451fSStefano Zampini   a->vecinuse = 0;
31889566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&a->ptrinuse));
31899566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(a->cvec));
31909566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
319175f6d85dSStefano Zampini   if (v) *v = NULL;
31926947451fSStefano Zampini   PetscFunctionReturn(0);
31936947451fSStefano Zampini }
31946947451fSStefano Zampini 
31956947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A,PetscInt col,Vec *v)
31966947451fSStefano Zampini {
31976947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
31986947451fSStefano Zampini 
31996947451fSStefano Zampini   PetscFunctionBegin;
320028b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
320128b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
32026947451fSStefano Zampini   if (!a->cvec) {
32039566063dSJacob Faibussowitsch     PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec));
32049566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec));
32056947451fSStefano Zampini   }
32066947451fSStefano Zampini   a->vecinuse = col + 1;
32079566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(A,(PetscScalar**)&a->ptrinuse));
32089566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda));
32096947451fSStefano Zampini   *v   = a->cvec;
32106947451fSStefano Zampini   PetscFunctionReturn(0);
32116947451fSStefano Zampini }
32126947451fSStefano Zampini 
32136947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A,PetscInt col,Vec *v)
32146947451fSStefano Zampini {
32156947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32166947451fSStefano Zampini 
32176947451fSStefano Zampini   PetscFunctionBegin;
321828b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first");
321928b400f6SJacob Faibussowitsch   PetscCheck(a->cvec,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
32206947451fSStefano Zampini   a->vecinuse = 0;
32219566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(A,(PetscScalar**)&a->ptrinuse));
32229566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
322375f6d85dSStefano Zampini   if (v) *v = NULL;
32246947451fSStefano Zampini   PetscFunctionReturn(0);
32256947451fSStefano Zampini }
32266947451fSStefano Zampini 
32275ea7661aSPierre Jolivet PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A,PetscInt cbegin,PetscInt cend,Mat *v)
32285ea7661aSPierre Jolivet {
32295ea7661aSPierre Jolivet   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32305ea7661aSPierre Jolivet 
32315ea7661aSPierre Jolivet   PetscFunctionBegin;
323228b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
323328b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
32345ea7661aSPierre Jolivet   if (a->cmat && cend-cbegin != a->cmat->cmap->N) {
32359566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&a->cmat));
32365ea7661aSPierre Jolivet   }
32375ea7661aSPierre Jolivet   if (!a->cmat) {
32389566063dSJacob 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));
32399566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)A,(PetscObject)a->cmat));
32405ea7661aSPierre Jolivet   } else {
32419566063dSJacob Faibussowitsch     PetscCall(MatDensePlaceArray(a->cmat,a->v+(size_t)cbegin*a->lda));
32425ea7661aSPierre Jolivet   }
32439566063dSJacob Faibussowitsch   PetscCall(MatDenseSetLDA(a->cmat,a->lda));
32445ea7661aSPierre Jolivet   a->matinuse = cbegin + 1;
32455ea7661aSPierre Jolivet   *v = a->cmat;
324675f6d85dSStefano Zampini #if defined(PETSC_HAVE_CUDA)
324775f6d85dSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
324875f6d85dSStefano Zampini #endif
32495ea7661aSPierre Jolivet   PetscFunctionReturn(0);
32505ea7661aSPierre Jolivet }
32515ea7661aSPierre Jolivet 
32525ea7661aSPierre Jolivet PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A,Mat *v)
32535ea7661aSPierre Jolivet {
32545ea7661aSPierre Jolivet   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32555ea7661aSPierre Jolivet 
32565ea7661aSPierre Jolivet   PetscFunctionBegin;
325728b400f6SJacob Faibussowitsch   PetscCheck(a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetSubMatrix() first");
325828b400f6SJacob Faibussowitsch   PetscCheck(a->cmat,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column matrix");
325908401ef6SPierre Jolivet   PetscCheck(*v == a->cmat,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not the matrix obtained from MatDenseGetSubMatrix()");
32605ea7661aSPierre Jolivet   a->matinuse = 0;
32619566063dSJacob Faibussowitsch   PetscCall(MatDenseResetArray(a->cmat));
32625ea7661aSPierre Jolivet   *v   = NULL;
32635ea7661aSPierre Jolivet   PetscFunctionReturn(0);
32645ea7661aSPierre Jolivet }
32655ea7661aSPierre Jolivet 
32660bad9183SKris Buschelman /*MC
3267fafad747SKris Buschelman    MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices.
32680bad9183SKris Buschelman 
32690bad9183SKris Buschelman    Options Database Keys:
32700bad9183SKris Buschelman . -mat_type seqdense - sets the matrix type to "seqdense" during a call to MatSetFromOptions()
32710bad9183SKris Buschelman 
32720bad9183SKris Buschelman   Level: beginner
32730bad9183SKris Buschelman 
3274db781477SPatrick Sanan .seealso: `MatCreateSeqDense()`
327589665df3SBarry Smith 
32760bad9183SKris Buschelman M*/
3277ca15aa20SStefano Zampini PetscErrorCode MatCreate_SeqDense(Mat B)
3278273d9f13SBarry Smith {
3279273d9f13SBarry Smith   Mat_SeqDense   *b;
32807c334f02SBarry Smith   PetscMPIInt    size;
3281273d9f13SBarry Smith 
3282273d9f13SBarry Smith   PetscFunctionBegin;
32839566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)B),&size));
328408401ef6SPierre Jolivet   PetscCheck(size <= 1,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
328555659b69SBarry Smith 
32869566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(B,&b));
32879566063dSJacob Faibussowitsch   PetscCall(PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps)));
328844cd7ae7SLois Curfman McInnes   B->data = (void*)b;
328918f449edSLois Curfman McInnes 
3290273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
32914e220ebcSLois Curfman McInnes 
32929566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatQRFactor_C",MatQRFactor_SeqDense));
32939566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetLDA_C",MatDenseGetLDA_SeqDense));
32949566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseSetLDA_C",MatDenseSetLDA_SeqDense));
32959566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArray_C",MatDenseGetArray_SeqDense));
32969566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArray_C",MatDenseRestoreArray_SeqDense));
32979566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDensePlaceArray_C",MatDensePlaceArray_SeqDense));
32989566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseResetArray_C",MatDenseResetArray_SeqDense));
32999566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseReplaceArray_C",MatDenseReplaceArray_SeqDense));
33009566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayRead_C",MatDenseGetArray_SeqDense));
33019566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayRead_C",MatDenseRestoreArray_SeqDense));
33029566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayWrite_C",MatDenseGetArray_SeqDense));
33039566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayWrite_C",MatDenseRestoreArray_SeqDense));
33049566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqaij_C",MatConvert_SeqDense_SeqAIJ));
33058baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
33069566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_elemental_C",MatConvert_SeqDense_Elemental));
33078baccfbdSHong Zhang #endif
3308d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
33099566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_scalapack_C",MatConvert_Dense_ScaLAPACK));
3310d24d4204SJose E. Roman #endif
33112bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
33129566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqdensecuda_C",MatConvert_SeqDense_SeqDenseCUDA));
33139566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",MatProductSetFromOptions_SeqDense));
33149566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdense_C",MatProductSetFromOptions_SeqDense));
33159566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqdensecuda_C",MatProductSetFromOptions_SeqDense));
33162bf066beSStefano Zampini #endif
33179566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatSeqDenseSetPreallocation_C",MatSeqDenseSetPreallocation_SeqDense));
33189566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqdense_C",MatProductSetFromOptions_SeqAIJ_SeqDense));
33199566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqdense_C",MatProductSetFromOptions_SeqDense));
33209566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense));
33219566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqsbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense));
332296e6d5c4SRichard Tran Mills 
33239566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumn_C",MatDenseGetColumn_SeqDense));
33249566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumn_C",MatDenseRestoreColumn_SeqDense));
33259566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVec_C",MatDenseGetColumnVec_SeqDense));
33269566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVec_C",MatDenseRestoreColumnVec_SeqDense));
33279566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVecRead_C",MatDenseGetColumnVecRead_SeqDense));
33289566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVecRead_C",MatDenseRestoreColumnVecRead_SeqDense));
33299566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVecWrite_C",MatDenseGetColumnVecWrite_SeqDense));
33309566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVecWrite_C",MatDenseRestoreColumnVecWrite_SeqDense));
33319566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetSubMatrix_C",MatDenseGetSubMatrix_SeqDense));
33329566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreSubMatrix_C",MatDenseRestoreSubMatrix_SeqDense));
33339566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)B,MATSEQDENSE));
33343a40ed3dSBarry Smith   PetscFunctionReturn(0);
3335289bc588SBarry Smith }
333686aefd0dSHong Zhang 
333786aefd0dSHong Zhang /*@C
3338af53bab2SHong 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.
333986aefd0dSHong Zhang 
334086aefd0dSHong Zhang    Not Collective
334186aefd0dSHong Zhang 
33425ea7661aSPierre Jolivet    Input Parameters:
334386aefd0dSHong Zhang +  mat - a MATSEQDENSE or MATMPIDENSE matrix
334486aefd0dSHong Zhang -  col - column index
334586aefd0dSHong Zhang 
334686aefd0dSHong Zhang    Output Parameter:
334786aefd0dSHong Zhang .  vals - pointer to the data
334886aefd0dSHong Zhang 
334986aefd0dSHong Zhang    Level: intermediate
335086aefd0dSHong Zhang 
3351db781477SPatrick Sanan .seealso: `MatDenseRestoreColumn()`
335286aefd0dSHong Zhang @*/
335386aefd0dSHong Zhang PetscErrorCode MatDenseGetColumn(Mat A,PetscInt col,PetscScalar **vals)
335486aefd0dSHong Zhang {
335586aefd0dSHong Zhang   PetscFunctionBegin;
3356d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3357d5ea218eSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
3358d5ea218eSStefano Zampini   PetscValidPointer(vals,3);
3359cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetColumn_C",(Mat,PetscInt,PetscScalar**),(A,col,vals));
336086aefd0dSHong Zhang   PetscFunctionReturn(0);
336186aefd0dSHong Zhang }
336286aefd0dSHong Zhang 
336386aefd0dSHong Zhang /*@C
336486aefd0dSHong Zhang    MatDenseRestoreColumn - returns access to a column of a dense matrix which is returned by MatDenseGetColumn().
336586aefd0dSHong Zhang 
336686aefd0dSHong Zhang    Not Collective
336786aefd0dSHong Zhang 
336886aefd0dSHong Zhang    Input Parameter:
336986aefd0dSHong Zhang .  mat - a MATSEQDENSE or MATMPIDENSE matrix
337086aefd0dSHong Zhang 
337186aefd0dSHong Zhang    Output Parameter:
337286aefd0dSHong Zhang .  vals - pointer to the data
337386aefd0dSHong Zhang 
337486aefd0dSHong Zhang    Level: intermediate
337586aefd0dSHong Zhang 
3376db781477SPatrick Sanan .seealso: `MatDenseGetColumn()`
337786aefd0dSHong Zhang @*/
337886aefd0dSHong Zhang PetscErrorCode MatDenseRestoreColumn(Mat A,PetscScalar **vals)
337986aefd0dSHong Zhang {
338086aefd0dSHong Zhang   PetscFunctionBegin;
3381d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3382d5ea218eSStefano Zampini   PetscValidPointer(vals,2);
3383cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreColumn_C",(Mat,PetscScalar**),(A,vals));
338486aefd0dSHong Zhang   PetscFunctionReturn(0);
338586aefd0dSHong Zhang }
33866947451fSStefano Zampini 
33870f74d2c1SSatish Balay /*@
33886947451fSStefano Zampini    MatDenseGetColumnVec - Gives read-write access to a column of a dense matrix, represented as a Vec.
33896947451fSStefano Zampini 
33906947451fSStefano Zampini    Collective
33916947451fSStefano Zampini 
33925ea7661aSPierre Jolivet    Input Parameters:
33936947451fSStefano Zampini +  mat - the Mat object
33946947451fSStefano Zampini -  col - the column index
33956947451fSStefano Zampini 
33966947451fSStefano Zampini    Output Parameter:
33976947451fSStefano Zampini .  v - the vector
33986947451fSStefano Zampini 
33996947451fSStefano Zampini    Notes:
34006947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVec() when the vector is no longer needed.
34016947451fSStefano Zampini      Use MatDenseGetColumnVecRead() to obtain read-only access or MatDenseGetColumnVecWrite() for write-only access.
34026947451fSStefano Zampini 
34036947451fSStefano Zampini    Level: intermediate
34046947451fSStefano Zampini 
3405db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
34066947451fSStefano Zampini @*/
34076947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVec(Mat A,PetscInt col,Vec *v)
34086947451fSStefano Zampini {
34096947451fSStefano Zampini   PetscFunctionBegin;
34106947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
34116947451fSStefano Zampini   PetscValidType(A,1);
34126947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
34136947451fSStefano Zampini   PetscValidPointer(v,3);
341428b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
34152cf15c64SPierre Jolivet   PetscCheck(col >= 0 && col < A->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")",col,A->cmap->N);
3416cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetColumnVec_C",(Mat,PetscInt,Vec*),(A,col,v));
34176947451fSStefano Zampini   PetscFunctionReturn(0);
34186947451fSStefano Zampini }
34196947451fSStefano Zampini 
34200f74d2c1SSatish Balay /*@
34216947451fSStefano Zampini    MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVec().
34226947451fSStefano Zampini 
34236947451fSStefano Zampini    Collective
34246947451fSStefano Zampini 
34255ea7661aSPierre Jolivet    Input Parameters:
34266947451fSStefano Zampini +  mat - the Mat object
34276947451fSStefano Zampini .  col - the column index
34286947451fSStefano Zampini -  v - the Vec object
34296947451fSStefano Zampini 
34306947451fSStefano Zampini    Level: intermediate
34316947451fSStefano Zampini 
3432db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
34336947451fSStefano Zampini @*/
34346947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVec(Mat A,PetscInt col,Vec *v)
34356947451fSStefano Zampini {
34366947451fSStefano Zampini   PetscFunctionBegin;
34376947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
34386947451fSStefano Zampini   PetscValidType(A,1);
34396947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
344008401ef6SPierre Jolivet   PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
34412cf15c64SPierre Jolivet   PetscCheck(col >= 0 && col < A->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")",col,A->cmap->N);
3442cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreColumnVec_C",(Mat,PetscInt,Vec*),(A,col,v));
34436947451fSStefano Zampini   PetscFunctionReturn(0);
34446947451fSStefano Zampini }
34456947451fSStefano Zampini 
34460f74d2c1SSatish Balay /*@
34476947451fSStefano Zampini    MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a Vec.
34486947451fSStefano Zampini 
34496947451fSStefano Zampini    Collective
34506947451fSStefano Zampini 
34515ea7661aSPierre Jolivet    Input Parameters:
34526947451fSStefano Zampini +  mat - the Mat object
34536947451fSStefano Zampini -  col - the column index
34546947451fSStefano Zampini 
34556947451fSStefano Zampini    Output Parameter:
34566947451fSStefano Zampini .  v - the vector
34576947451fSStefano Zampini 
34586947451fSStefano Zampini    Notes:
34596947451fSStefano Zampini      The vector is owned by PETSc and users cannot modify it.
34606947451fSStefano Zampini      Users need to call MatDenseRestoreColumnVecRead() when the vector is no longer needed.
34616947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecWrite() for write-only access.
34626947451fSStefano Zampini 
34636947451fSStefano Zampini    Level: intermediate
34646947451fSStefano Zampini 
3465db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
34666947451fSStefano Zampini @*/
34676947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecRead(Mat A,PetscInt col,Vec *v)
34686947451fSStefano Zampini {
34696947451fSStefano Zampini   PetscFunctionBegin;
34706947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
34716947451fSStefano Zampini   PetscValidType(A,1);
34726947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
34736947451fSStefano Zampini   PetscValidPointer(v,3);
347428b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
34752cf15c64SPierre Jolivet   PetscCheck(col >= 0 && col < A->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")",col,A->cmap->N);
3476cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetColumnVecRead_C",(Mat,PetscInt,Vec*),(A,col,v));
34776947451fSStefano Zampini   PetscFunctionReturn(0);
34786947451fSStefano Zampini }
34796947451fSStefano Zampini 
34800f74d2c1SSatish Balay /*@
34816947451fSStefano Zampini    MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecRead().
34826947451fSStefano Zampini 
34836947451fSStefano Zampini    Collective
34846947451fSStefano Zampini 
34855ea7661aSPierre Jolivet    Input Parameters:
34866947451fSStefano Zampini +  mat - the Mat object
34876947451fSStefano Zampini .  col - the column index
34886947451fSStefano Zampini -  v - the Vec object
34896947451fSStefano Zampini 
34906947451fSStefano Zampini    Level: intermediate
34916947451fSStefano Zampini 
3492db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecWrite()`
34936947451fSStefano Zampini @*/
34946947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecRead(Mat A,PetscInt col,Vec *v)
34956947451fSStefano Zampini {
34966947451fSStefano Zampini   PetscFunctionBegin;
34976947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
34986947451fSStefano Zampini   PetscValidType(A,1);
34996947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
350008401ef6SPierre Jolivet   PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
35012cf15c64SPierre Jolivet   PetscCheck(col >= 0 && col < A->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")",col,A->cmap->N);
3502cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreColumnVecRead_C",(Mat,PetscInt,Vec*),(A,col,v));
35036947451fSStefano Zampini   PetscFunctionReturn(0);
35046947451fSStefano Zampini }
35056947451fSStefano Zampini 
35060f74d2c1SSatish Balay /*@
35076947451fSStefano Zampini    MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a Vec.
35086947451fSStefano Zampini 
35096947451fSStefano Zampini    Collective
35106947451fSStefano Zampini 
35115ea7661aSPierre Jolivet    Input Parameters:
35126947451fSStefano Zampini +  mat - the Mat object
35136947451fSStefano Zampini -  col - the column index
35146947451fSStefano Zampini 
35156947451fSStefano Zampini    Output Parameter:
35166947451fSStefano Zampini .  v - the vector
35176947451fSStefano Zampini 
35186947451fSStefano Zampini    Notes:
35196947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVecWrite() when the vector is no longer needed.
35206947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecRead() for read-only access.
35216947451fSStefano Zampini 
35226947451fSStefano Zampini    Level: intermediate
35236947451fSStefano Zampini 
3524db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
35256947451fSStefano Zampini @*/
35266947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecWrite(Mat A,PetscInt col,Vec *v)
35276947451fSStefano Zampini {
35286947451fSStefano Zampini   PetscFunctionBegin;
35296947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
35306947451fSStefano Zampini   PetscValidType(A,1);
35316947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
35326947451fSStefano Zampini   PetscValidPointer(v,3);
353328b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
3534aed4548fSBarry Smith   PetscCheck(col >= 0 && col < A->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")",col,A->cmap->N);
3535cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetColumnVecWrite_C",(Mat,PetscInt,Vec*),(A,col,v));
35366947451fSStefano Zampini   PetscFunctionReturn(0);
35376947451fSStefano Zampini }
35386947451fSStefano Zampini 
35390f74d2c1SSatish Balay /*@
35406947451fSStefano Zampini    MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecWrite().
35416947451fSStefano Zampini 
35426947451fSStefano Zampini    Collective
35436947451fSStefano Zampini 
35445ea7661aSPierre Jolivet    Input Parameters:
35456947451fSStefano Zampini +  mat - the Mat object
35466947451fSStefano Zampini .  col - the column index
35476947451fSStefano Zampini -  v - the Vec object
35486947451fSStefano Zampini 
35496947451fSStefano Zampini    Level: intermediate
35506947451fSStefano Zampini 
3551db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`
35526947451fSStefano Zampini @*/
35536947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A,PetscInt col,Vec *v)
35546947451fSStefano Zampini {
35556947451fSStefano Zampini   PetscFunctionBegin;
35566947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
35576947451fSStefano Zampini   PetscValidType(A,1);
35586947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
355908401ef6SPierre Jolivet   PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
3560aed4548fSBarry Smith   PetscCheck(col >= 0 && col < A->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid col %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")",col,A->cmap->N);
3561cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreColumnVecWrite_C",(Mat,PetscInt,Vec*),(A,col,v));
35626947451fSStefano Zampini   PetscFunctionReturn(0);
35636947451fSStefano Zampini }
35645ea7661aSPierre Jolivet 
35650f74d2c1SSatish Balay /*@
35665ea7661aSPierre Jolivet    MatDenseGetSubMatrix - Gives access to a block of columns of a dense matrix, represented as a Mat.
35675ea7661aSPierre Jolivet 
35685ea7661aSPierre Jolivet    Collective
35695ea7661aSPierre Jolivet 
35705ea7661aSPierre Jolivet    Input Parameters:
35715ea7661aSPierre Jolivet +  mat - the Mat object
35725ea7661aSPierre Jolivet .  cbegin - the first index in the block
35732cf15c64SPierre Jolivet -  cend - the index past the last one in the block
35745ea7661aSPierre Jolivet 
35755ea7661aSPierre Jolivet    Output Parameter:
35765ea7661aSPierre Jolivet .  v - the matrix
35775ea7661aSPierre Jolivet 
35785ea7661aSPierre Jolivet    Notes:
35795ea7661aSPierre Jolivet      The matrix is owned by PETSc. Users need to call MatDenseRestoreSubMatrix() when the matrix is no longer needed.
35805ea7661aSPierre Jolivet 
35815ea7661aSPierre Jolivet    Level: intermediate
35825ea7661aSPierre Jolivet 
3583db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreSubMatrix()`
35845ea7661aSPierre Jolivet @*/
35855ea7661aSPierre Jolivet PetscErrorCode MatDenseGetSubMatrix(Mat A,PetscInt cbegin,PetscInt cend,Mat *v)
35865ea7661aSPierre Jolivet {
35875ea7661aSPierre Jolivet   PetscFunctionBegin;
35885ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
35895ea7661aSPierre Jolivet   PetscValidType(A,1);
35905ea7661aSPierre Jolivet   PetscValidLogicalCollectiveInt(A,cbegin,2);
35915ea7661aSPierre Jolivet   PetscValidLogicalCollectiveInt(A,cend,3);
35925ea7661aSPierre Jolivet   PetscValidPointer(v,4);
359328b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
35942cf15c64SPierre Jolivet   PetscCheck(cbegin >= 0 && cbegin < A->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid cbegin %" PetscInt_FMT ", should be in [0,%" PetscInt_FMT ")",cbegin,A->cmap->N);
35952cf15c64SPierre Jolivet   PetscCheck(cend > cbegin && cend <= A->cmap->N,PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Invalid cend %" PetscInt_FMT ", should be in (%" PetscInt_FMT ",%" PetscInt_FMT "]",cend,cbegin,A->cmap->N);
3596cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetSubMatrix_C",(Mat,PetscInt,PetscInt,Mat*),(A,cbegin,cend,v));
35975ea7661aSPierre Jolivet   PetscFunctionReturn(0);
35985ea7661aSPierre Jolivet }
35995ea7661aSPierre Jolivet 
36000f74d2c1SSatish Balay /*@
36015ea7661aSPierre Jolivet    MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from MatDenseGetSubMatrix().
36025ea7661aSPierre Jolivet 
36035ea7661aSPierre Jolivet    Collective
36045ea7661aSPierre Jolivet 
36055ea7661aSPierre Jolivet    Input Parameters:
36065ea7661aSPierre Jolivet +  mat - the Mat object
36075ea7661aSPierre Jolivet -  v - the Mat object
36085ea7661aSPierre Jolivet 
36095ea7661aSPierre Jolivet    Level: intermediate
36105ea7661aSPierre Jolivet 
3611db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseGetSubMatrix()`
36125ea7661aSPierre Jolivet @*/
36135ea7661aSPierre Jolivet PetscErrorCode MatDenseRestoreSubMatrix(Mat A,Mat *v)
36145ea7661aSPierre Jolivet {
36155ea7661aSPierre Jolivet   PetscFunctionBegin;
36165ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
36175ea7661aSPierre Jolivet   PetscValidType(A,1);
36185ea7661aSPierre Jolivet   PetscValidPointer(v,2);
3619cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreSubMatrix_C",(Mat,Mat*),(A,v));
36205ea7661aSPierre Jolivet   PetscFunctionReturn(0);
36215ea7661aSPierre Jolivet }
36228a9c020eSBarry Smith 
36238a9c020eSBarry Smith #include <petscblaslapack.h>
36248a9c020eSBarry Smith #include <petsc/private/kernels/blockinvert.h>
36258a9c020eSBarry Smith 
36268a9c020eSBarry Smith PetscErrorCode MatSeqDenseInvert(Mat A)
36278a9c020eSBarry Smith {
36288a9c020eSBarry Smith   Mat_SeqDense    *a = (Mat_SeqDense*) A->data;
36298a9c020eSBarry Smith   PetscInt        bs = A->rmap->n;
36308a9c020eSBarry Smith   MatScalar       *values = a->v;
36318a9c020eSBarry Smith   const PetscReal shift = 0.0;
36328a9c020eSBarry Smith   PetscBool       allowzeropivot = PetscNot(A->erroriffailure),zeropivotdetected=PETSC_FALSE;
36338a9c020eSBarry Smith 
36348a9c020eSBarry Smith   PetscFunctionBegin;
36358a9c020eSBarry Smith   /* factor and invert each block */
36368a9c020eSBarry Smith   switch (bs) {
36378a9c020eSBarry Smith   case 1:
36388a9c020eSBarry Smith     values[0] = (PetscScalar)1.0 / (values[0] + shift);
36398a9c020eSBarry Smith     break;
36408a9c020eSBarry Smith   case 2:
36418a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_2(values,shift,allowzeropivot,&zeropivotdetected));
36428a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
36438a9c020eSBarry Smith     break;
36448a9c020eSBarry Smith   case 3:
36458a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_3(values,shift,allowzeropivot,&zeropivotdetected));
36468a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
36478a9c020eSBarry Smith     break;
36488a9c020eSBarry Smith   case 4:
36498a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_4(values,shift,allowzeropivot,&zeropivotdetected));
36508a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
36518a9c020eSBarry Smith     break;
36528a9c020eSBarry Smith   case 5:
36538a9c020eSBarry Smith   {
36548a9c020eSBarry Smith     PetscScalar work[25];
36558a9c020eSBarry Smith     PetscInt    ipvt[5];
36568a9c020eSBarry Smith 
36578a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_5(values,ipvt,work,shift,allowzeropivot,&zeropivotdetected));
36588a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
36598a9c020eSBarry Smith   }
36608a9c020eSBarry Smith     break;
36618a9c020eSBarry Smith   case 6:
36628a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_6(values,shift,allowzeropivot,&zeropivotdetected));
36638a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
36648a9c020eSBarry Smith     break;
36658a9c020eSBarry Smith   case 7:
36668a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_7(values,shift,allowzeropivot,&zeropivotdetected));
36678a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
36688a9c020eSBarry Smith     break;
36698a9c020eSBarry Smith   default:
36708a9c020eSBarry Smith   {
36718a9c020eSBarry Smith     PetscInt    *v_pivots,*IJ,j;
36728a9c020eSBarry Smith     PetscScalar *v_work;
36738a9c020eSBarry Smith 
36748a9c020eSBarry Smith     PetscCall(PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ));
36758a9c020eSBarry Smith     for (j=0; j<bs; j++) {
36768a9c020eSBarry Smith       IJ[j] = j;
36778a9c020eSBarry Smith     }
36788a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A(bs,values,v_pivots,v_work,allowzeropivot,&zeropivotdetected));
36798a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
36808a9c020eSBarry Smith     PetscCall(PetscFree3(v_work,v_pivots,IJ));
36818a9c020eSBarry Smith   }
36828a9c020eSBarry Smith   }
36838a9c020eSBarry Smith   PetscFunctionReturn(0);
36848a9c020eSBarry Smith }
3685