xref: /petsc/src/mat/impls/dense/seq/dense.c (revision 05fcb23edf2823021ddce16b01b3ee8030132b38)
1be1d678aSKris Buschelman 
267e560aaSBarry Smith /*
367e560aaSBarry Smith      Defines the basic matrix operations for sequential dense.
467e560aaSBarry Smith */
5289bc588SBarry Smith 
6dec5eb66SMatthew G Knepley #include <../src/mat/impls/dense/seq/dense.h> /*I "petscmat.h" I*/
7c6db04a5SJed Brown #include <petscblaslapack.h>
8289bc588SBarry Smith 
96a63e612SBarry Smith #include <../src/mat/impls/aij/seq/aij.h>
10b2573a8aSBarry Smith 
11ca15aa20SStefano Zampini PetscErrorCode MatSeqDenseSymmetrize_Private(Mat A, PetscBool hermitian)
128c178816SStefano Zampini {
138c178816SStefano Zampini   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
148c178816SStefano Zampini   PetscInt       j, k, n = A->rmap->n;
15ca15aa20SStefano Zampini   PetscScalar    *v;
168c178816SStefano Zampini 
178c178816SStefano Zampini   PetscFunctionBegin;
1808401ef6SPierre Jolivet   PetscCheck(A->rmap->n == A->cmap->n,PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Cannot symmetrize a rectangular matrix");
199566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&v));
208c178816SStefano Zampini   if (!hermitian) {
218c178816SStefano Zampini     for (k=0;k<n;k++) {
228c178816SStefano Zampini       for (j=k;j<n;j++) {
23ca15aa20SStefano Zampini         v[j*mat->lda + k] = v[k*mat->lda + j];
248c178816SStefano Zampini       }
258c178816SStefano Zampini     }
268c178816SStefano Zampini   } else {
278c178816SStefano Zampini     for (k=0;k<n;k++) {
288c178816SStefano Zampini       for (j=k;j<n;j++) {
29ca15aa20SStefano Zampini         v[j*mat->lda + k] = PetscConj(v[k*mat->lda + j]);
308c178816SStefano Zampini       }
318c178816SStefano Zampini     }
328c178816SStefano Zampini   }
339566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&v));
348c178816SStefano Zampini   PetscFunctionReturn(0);
358c178816SStefano Zampini }
368c178816SStefano Zampini 
3705709791SSatish Balay PETSC_EXTERN PetscErrorCode MatSeqDenseInvertFactors_Private(Mat A)
388c178816SStefano Zampini {
398c178816SStefano Zampini   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
408c178816SStefano Zampini   PetscBLASInt   info,n;
418c178816SStefano Zampini 
428c178816SStefano Zampini   PetscFunctionBegin;
438c178816SStefano Zampini   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
449566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
458c178816SStefano Zampini   if (A->factortype == MAT_FACTOR_LU) {
4628b400f6SJacob Faibussowitsch     PetscCheck(mat->pivots,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present");
478c178816SStefano Zampini     if (!mat->fwork) {
488c178816SStefano Zampini       mat->lfwork = n;
499566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(mat->lfwork,&mat->fwork));
509566063dSJacob Faibussowitsch       PetscCall(PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt)));
518c178816SStefano Zampini     }
529566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
538c178816SStefano Zampini     PetscStackCallBLAS("LAPACKgetri",LAPACKgetri_(&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
549566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
559566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0));
568c178816SStefano Zampini   } else if (A->factortype == MAT_FACTOR_CHOLESKY) {
578c178816SStefano Zampini     if (A->spd) {
589566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
598c178816SStefano Zampini       PetscStackCallBLAS("LAPACKpotri",LAPACKpotri_("L",&n,mat->v,&mat->lda,&info));
609566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
619566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSymmetrize_Private(A,PETSC_TRUE));
628c178816SStefano Zampini #if defined(PETSC_USE_COMPLEX)
638c178816SStefano Zampini     } else if (A->hermitian) {
6428b400f6SJacob Faibussowitsch       PetscCheck(mat->pivots,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present");
6528b400f6SJacob Faibussowitsch       PetscCheck(mat->fwork,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Fwork not present");
669566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
678c178816SStefano Zampini       PetscStackCallBLAS("LAPACKhetri",LAPACKhetri_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&info));
689566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
699566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSymmetrize_Private(A,PETSC_TRUE));
708c178816SStefano Zampini #endif
718c178816SStefano Zampini     } else { /* symmetric case */
7228b400f6SJacob Faibussowitsch       PetscCheck(mat->pivots,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present");
7328b400f6SJacob Faibussowitsch       PetscCheck(mat->fwork,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Fwork not present");
749566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
758c178816SStefano Zampini       PetscStackCallBLAS("LAPACKsytri",LAPACKsytri_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&info));
769566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
779566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSymmetrize_Private(A,PETSC_FALSE));
788c178816SStefano Zampini     }
7928b400f6SJacob Faibussowitsch     PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad Inversion: zero pivot in row %" PetscInt_FMT,(PetscInt)info-1);
809566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0));
818c178816SStefano Zampini   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve");
828c178816SStefano Zampini 
838c178816SStefano Zampini   A->ops->solve             = NULL;
848c178816SStefano Zampini   A->ops->matsolve          = NULL;
858c178816SStefano Zampini   A->ops->solvetranspose    = NULL;
868c178816SStefano Zampini   A->ops->matsolvetranspose = NULL;
878c178816SStefano Zampini   A->ops->solveadd          = NULL;
888c178816SStefano Zampini   A->ops->solvetransposeadd = NULL;
898c178816SStefano Zampini   A->factortype             = MAT_FACTOR_NONE;
909566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
918c178816SStefano Zampini   PetscFunctionReturn(0);
928c178816SStefano Zampini }
938c178816SStefano Zampini 
943f49a652SStefano Zampini PetscErrorCode MatZeroRowsColumns_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
953f49a652SStefano Zampini {
963f49a652SStefano Zampini   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
973f49a652SStefano Zampini   PetscInt          m  = l->lda, n = A->cmap->n,r = A->rmap->n, i,j;
98ca15aa20SStefano Zampini   PetscScalar       *slot,*bb,*v;
993f49a652SStefano Zampini   const PetscScalar *xx;
1003f49a652SStefano Zampini 
1013f49a652SStefano Zampini   PetscFunctionBegin;
10276bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
1033f49a652SStefano Zampini     for (i=0; i<N; i++) {
10408401ef6SPierre Jolivet       PetscCheck(rows[i] >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
10508401ef6SPierre Jolivet       PetscCheck(rows[i] < A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %" PetscInt_FMT " requested to be zeroed greater than or equal number of rows %" PetscInt_FMT,rows[i],A->rmap->n);
10608401ef6SPierre Jolivet       PetscCheck(rows[i] < A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Col %" PetscInt_FMT " requested to be zeroed greater than or equal number of cols %" PetscInt_FMT,rows[i],A->cmap->n);
1073f49a652SStefano Zampini     }
10876bd3646SJed Brown   }
109ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
1103f49a652SStefano Zampini 
1113f49a652SStefano Zampini   /* fix right hand side if needed */
1123f49a652SStefano Zampini   if (x && b) {
1136c4d906cSStefano Zampini     Vec xt;
1146c4d906cSStefano Zampini 
11508401ef6SPierre Jolivet     PetscCheck(A->rmap->n == A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
1169566063dSJacob Faibussowitsch     PetscCall(VecDuplicate(x,&xt));
1179566063dSJacob Faibussowitsch     PetscCall(VecCopy(x,xt));
1189566063dSJacob Faibussowitsch     PetscCall(VecScale(xt,-1.0));
1199566063dSJacob Faibussowitsch     PetscCall(MatMultAdd(A,xt,b,b));
1209566063dSJacob Faibussowitsch     PetscCall(VecDestroy(&xt));
1219566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(x,&xx));
1229566063dSJacob Faibussowitsch     PetscCall(VecGetArray(b,&bb));
1233f49a652SStefano Zampini     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
1249566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(x,&xx));
1259566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(b,&bb));
1263f49a652SStefano Zampini   }
1273f49a652SStefano Zampini 
1289566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&v));
1293f49a652SStefano Zampini   for (i=0; i<N; i++) {
130ca15aa20SStefano Zampini     slot = v + rows[i]*m;
1319566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(slot,r));
1323f49a652SStefano Zampini   }
1333f49a652SStefano Zampini   for (i=0; i<N; i++) {
134ca15aa20SStefano Zampini     slot = v + rows[i];
1353f49a652SStefano Zampini     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
1363f49a652SStefano Zampini   }
1373f49a652SStefano Zampini   if (diag != 0.0) {
13808401ef6SPierre Jolivet     PetscCheck(A->rmap->n == A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
1393f49a652SStefano Zampini     for (i=0; i<N; i++) {
140ca15aa20SStefano Zampini       slot  = v + (m+1)*rows[i];
1413f49a652SStefano Zampini       *slot = diag;
1423f49a652SStefano Zampini     }
1433f49a652SStefano Zampini   }
1449566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&v));
1453f49a652SStefano Zampini   PetscFunctionReturn(0);
1463f49a652SStefano Zampini }
1473f49a652SStefano Zampini 
148abc3b08eSStefano Zampini PetscErrorCode MatPtAPNumeric_SeqDense_SeqDense(Mat A,Mat P,Mat C)
149abc3b08eSStefano Zampini {
150abc3b08eSStefano Zampini   Mat_SeqDense   *c = (Mat_SeqDense*)(C->data);
151abc3b08eSStefano Zampini 
152abc3b08eSStefano Zampini   PetscFunctionBegin;
153ca15aa20SStefano Zampini   if (c->ptapwork) {
1549566063dSJacob Faibussowitsch     PetscCall((*C->ops->matmultnumeric)(A,P,c->ptapwork));
1559566063dSJacob Faibussowitsch     PetscCall((*C->ops->transposematmultnumeric)(P,c->ptapwork,C));
1564222ddf1SHong Zhang   } else SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_SUP,"Must call MatPtAPSymbolic_SeqDense_SeqDense() first");
157abc3b08eSStefano Zampini   PetscFunctionReturn(0);
158abc3b08eSStefano Zampini }
159abc3b08eSStefano Zampini 
1604222ddf1SHong Zhang PetscErrorCode MatPtAPSymbolic_SeqDense_SeqDense(Mat A,Mat P,PetscReal fill,Mat C)
161abc3b08eSStefano Zampini {
162abc3b08eSStefano Zampini   Mat_SeqDense   *c;
1637a3c3d58SStefano Zampini   PetscBool      cisdense;
164abc3b08eSStefano Zampini 
165abc3b08eSStefano Zampini   PetscFunctionBegin;
1669566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C,P->cmap->n,P->cmap->n,P->cmap->N,P->cmap->N));
1679566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,""));
1687a3c3d58SStefano Zampini   if (!cisdense) {
1697a3c3d58SStefano Zampini     PetscBool flg;
1707a3c3d58SStefano Zampini 
1719566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)P,((PetscObject)A)->type_name,&flg));
1729566063dSJacob Faibussowitsch     PetscCall(MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE));
1737a3c3d58SStefano Zampini   }
1749566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
1754222ddf1SHong Zhang   c    = (Mat_SeqDense*)C->data;
1769566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&c->ptapwork));
1779566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(c->ptapwork,A->rmap->n,P->cmap->n,A->rmap->N,P->cmap->N));
1789566063dSJacob Faibussowitsch   PetscCall(MatSetType(c->ptapwork,((PetscObject)C)->type_name));
1799566063dSJacob Faibussowitsch   PetscCall(MatSetUp(c->ptapwork));
180abc3b08eSStefano Zampini   PetscFunctionReturn(0);
181abc3b08eSStefano Zampini }
182abc3b08eSStefano Zampini 
183cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat A,MatType newtype,MatReuse reuse,Mat *newmat)
184b49cda9fSStefano Zampini {
185a13144ffSStefano Zampini   Mat             B = NULL;
186b49cda9fSStefano Zampini   Mat_SeqAIJ      *a = (Mat_SeqAIJ*)A->data;
187b49cda9fSStefano Zampini   Mat_SeqDense    *b;
188b49cda9fSStefano Zampini   PetscInt        *ai=a->i,*aj=a->j,m=A->rmap->N,n=A->cmap->N,i;
1892e5835c6SStefano Zampini   const MatScalar *av;
190a13144ffSStefano Zampini   PetscBool       isseqdense;
191b49cda9fSStefano Zampini 
192b49cda9fSStefano Zampini   PetscFunctionBegin;
193a13144ffSStefano Zampini   if (reuse == MAT_REUSE_MATRIX) {
1949566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)*newmat,MATSEQDENSE,&isseqdense));
19528b400f6SJacob Faibussowitsch     PetscCheck(isseqdense,PetscObjectComm((PetscObject)*newmat),PETSC_ERR_USER,"Cannot reuse matrix of type %s",((PetscObject)(*newmat))->type_name);
196a13144ffSStefano Zampini   }
197a13144ffSStefano Zampini   if (reuse != MAT_REUSE_MATRIX) {
1989566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&B));
1999566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(B,m,n,m,n));
2009566063dSJacob Faibussowitsch     PetscCall(MatSetType(B,MATSEQDENSE));
2019566063dSJacob Faibussowitsch     PetscCall(MatSeqDenseSetPreallocation(B,NULL));
202b49cda9fSStefano Zampini     b    = (Mat_SeqDense*)(B->data);
203a13144ffSStefano Zampini   } else {
204a13144ffSStefano Zampini     b    = (Mat_SeqDense*)((*newmat)->data);
2059566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(b->v,m*n));
206a13144ffSStefano Zampini   }
2079566063dSJacob Faibussowitsch   PetscCall(MatSeqAIJGetArrayRead(A,&av));
208b49cda9fSStefano Zampini   for (i=0; i<m; i++) {
209b49cda9fSStefano Zampini     PetscInt j;
210b49cda9fSStefano Zampini     for (j=0;j<ai[1]-ai[0];j++) {
211b49cda9fSStefano Zampini       b->v[*aj*m+i] = *av;
212b49cda9fSStefano Zampini       aj++;
213b49cda9fSStefano Zampini       av++;
214b49cda9fSStefano Zampini     }
215b49cda9fSStefano Zampini     ai++;
216b49cda9fSStefano Zampini   }
2179566063dSJacob Faibussowitsch   PetscCall(MatSeqAIJRestoreArrayRead(A,&av));
218b49cda9fSStefano Zampini 
219511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
2209566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY));
2219566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY));
2229566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A,&B));
223b49cda9fSStefano Zampini   } else {
224a13144ffSStefano Zampini     if (B) *newmat = B;
2259566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY));
2269566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY));
227b49cda9fSStefano Zampini   }
228b49cda9fSStefano Zampini   PetscFunctionReturn(0);
229b49cda9fSStefano Zampini }
230b49cda9fSStefano Zampini 
231cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_SeqAIJ(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
2326a63e612SBarry Smith {
2336d4ec7b0SPierre Jolivet   Mat            B = NULL;
2346a63e612SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2359399e1b8SMatthew G. Knepley   PetscInt       i, j;
2369399e1b8SMatthew G. Knepley   PetscInt       *rows, *nnz;
2379399e1b8SMatthew G. Knepley   MatScalar      *aa = a->v, *vals;
2386a63e612SBarry Smith 
2396a63e612SBarry Smith   PetscFunctionBegin;
2409566063dSJacob Faibussowitsch   PetscCall(PetscCalloc3(A->rmap->n,&rows,A->rmap->n,&nnz,A->rmap->n,&vals));
2416d4ec7b0SPierre Jolivet   if (reuse != MAT_REUSE_MATRIX) {
2429566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&B));
2439566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N));
2449566063dSJacob Faibussowitsch     PetscCall(MatSetType(B,MATSEQAIJ));
2459399e1b8SMatthew G. Knepley     for (j=0; j<A->cmap->n; j++) {
2466d4ec7b0SPierre Jolivet       for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) ++nnz[i];
2476a63e612SBarry Smith       aa += a->lda;
2486a63e612SBarry Smith     }
2499566063dSJacob Faibussowitsch     PetscCall(MatSeqAIJSetPreallocation(B,PETSC_DETERMINE,nnz));
2506d4ec7b0SPierre Jolivet   } else B = *newmat;
2519399e1b8SMatthew G. Knepley   aa = a->v;
2529399e1b8SMatthew G. Knepley   for (j=0; j<A->cmap->n; j++) {
2539399e1b8SMatthew G. Knepley     PetscInt numRows = 0;
2546d4ec7b0SPierre Jolivet     for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || (i == j && A->cmap->n == A->rmap->n)) {rows[numRows] = i; vals[numRows++] = aa[i];}
2559566063dSJacob Faibussowitsch     PetscCall(MatSetValues(B,numRows,rows,1,&j,vals,INSERT_VALUES));
2569399e1b8SMatthew G. Knepley     aa  += a->lda;
2579399e1b8SMatthew G. Knepley   }
2589566063dSJacob Faibussowitsch   PetscCall(PetscFree3(rows,nnz,vals));
2599566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY));
2609566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY));
2616a63e612SBarry Smith 
262511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
2639566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A,&B));
2646d4ec7b0SPierre Jolivet   } else if (reuse != MAT_REUSE_MATRIX) *newmat = B;
2656a63e612SBarry Smith   PetscFunctionReturn(0);
2666a63e612SBarry Smith }
2676a63e612SBarry Smith 
268ca15aa20SStefano Zampini PetscErrorCode MatAXPY_SeqDense(Mat Y,PetscScalar alpha,Mat X,MatStructure str)
2691987afe7SBarry Smith {
2701987afe7SBarry Smith   Mat_SeqDense      *x = (Mat_SeqDense*)X->data,*y = (Mat_SeqDense*)Y->data;
271ca15aa20SStefano Zampini   const PetscScalar *xv;
272ca15aa20SStefano Zampini   PetscScalar       *yv;
27323fff9afSBarry Smith   PetscBLASInt      N,m,ldax = 0,lday = 0,one = 1;
2743a40ed3dSBarry Smith 
2753a40ed3dSBarry Smith   PetscFunctionBegin;
2769566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(X,&xv));
2779566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(Y,&yv));
2789566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(X->rmap->n*X->cmap->n,&N));
2799566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(X->rmap->n,&m));
2809566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(x->lda,&ldax));
2819566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(y->lda,&lday));
282a5ce6ee0Svictorle   if (ldax>m || lday>m) {
283ca15aa20SStefano Zampini     PetscInt j;
284ca15aa20SStefano Zampini 
285d0f46423SBarry Smith     for (j=0; j<X->cmap->n; j++) {
286ca15aa20SStefano Zampini       PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&m,&alpha,xv+j*ldax,&one,yv+j*lday,&one));
287a5ce6ee0Svictorle     }
288a5ce6ee0Svictorle   } else {
289ca15aa20SStefano Zampini     PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&N,&alpha,xv,&one,yv,&one));
290a5ce6ee0Svictorle   }
2919566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(X,&xv));
2929566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(Y,&yv));
2939566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(PetscMax(2.0*N-1,0)));
2943a40ed3dSBarry Smith   PetscFunctionReturn(0);
2951987afe7SBarry Smith }
2961987afe7SBarry Smith 
297e0877f53SBarry Smith static PetscErrorCode MatGetInfo_SeqDense(Mat A,MatInfoType flag,MatInfo *info)
298289bc588SBarry Smith {
299ca15aa20SStefano Zampini   PetscLogDouble N = A->rmap->n*A->cmap->n;
3003a40ed3dSBarry Smith 
3013a40ed3dSBarry Smith   PetscFunctionBegin;
3024e220ebcSLois Curfman McInnes   info->block_size        = 1.0;
303ca15aa20SStefano Zampini   info->nz_allocated      = N;
304ca15aa20SStefano Zampini   info->nz_used           = N;
305ca15aa20SStefano Zampini   info->nz_unneeded       = 0;
306ca15aa20SStefano Zampini   info->assemblies        = A->num_ass;
3074e220ebcSLois Curfman McInnes   info->mallocs           = 0;
3087adad957SLisandro Dalcin   info->memory            = ((PetscObject)A)->mem;
3094e220ebcSLois Curfman McInnes   info->fill_ratio_given  = 0;
3104e220ebcSLois Curfman McInnes   info->fill_ratio_needed = 0;
3114e220ebcSLois Curfman McInnes   info->factor_mallocs    = 0;
3123a40ed3dSBarry Smith   PetscFunctionReturn(0);
313289bc588SBarry Smith }
314289bc588SBarry Smith 
315637a0070SStefano Zampini PetscErrorCode MatScale_SeqDense(Mat A,PetscScalar alpha)
31680cd9d93SLois Curfman McInnes {
317273d9f13SBarry Smith   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
318ca15aa20SStefano Zampini   PetscScalar    *v;
31923fff9afSBarry Smith   PetscBLASInt   one = 1,j,nz,lda = 0;
32080cd9d93SLois Curfman McInnes 
3213a40ed3dSBarry Smith   PetscFunctionBegin;
3229566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&v));
3239566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(a->lda,&lda));
324d0f46423SBarry Smith   if (lda>A->rmap->n) {
3259566063dSJacob Faibussowitsch     PetscCall(PetscBLASIntCast(A->rmap->n,&nz));
326d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
327ca15aa20SStefano Zampini       PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&alpha,v+j*lda,&one));
328a5ce6ee0Svictorle     }
329a5ce6ee0Svictorle   } else {
3309566063dSJacob Faibussowitsch     PetscCall(PetscBLASIntCast(A->rmap->n*A->cmap->n,&nz));
331ca15aa20SStefano Zampini     PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&alpha,v,&one));
332a5ce6ee0Svictorle   }
33304cbc005SJose E. Roman   PetscCall(PetscLogFlops(A->rmap->n*A->cmap->n));
3349566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&v));
3353a40ed3dSBarry Smith   PetscFunctionReturn(0);
33680cd9d93SLois Curfman McInnes }
33780cd9d93SLois Curfman McInnes 
3382f605a99SJose E. Roman PetscErrorCode MatShift_SeqDense(Mat A,PetscScalar alpha)
3392f605a99SJose E. Roman {
3402f605a99SJose E. Roman   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
3412f605a99SJose E. Roman   PetscScalar    *v;
3422f605a99SJose E. Roman   PetscInt       j,k;
3432f605a99SJose E. Roman 
3442f605a99SJose E. Roman   PetscFunctionBegin;
3452f605a99SJose E. Roman   PetscCall(MatDenseGetArray(A,&v));
3462f605a99SJose E. Roman   k = PetscMin(A->rmap->n,A->cmap->n);
3472f605a99SJose E. Roman   for (j=0; j<k; j++) v[j+j*a->lda] += alpha;
3482f605a99SJose E. Roman   PetscCall(PetscLogFlops(k));
3492f605a99SJose E. Roman   PetscCall(MatDenseRestoreArray(A,&v));
3502f605a99SJose E. Roman   PetscFunctionReturn(0);
3512f605a99SJose E. Roman }
3522f605a99SJose E. Roman 
353e0877f53SBarry Smith static PetscErrorCode MatIsHermitian_SeqDense(Mat A,PetscReal rtol,PetscBool  *fl)
3541cbb95d3SBarry Smith {
3551cbb95d3SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
356ca15aa20SStefano Zampini   PetscInt          i,j,m = A->rmap->n,N = a->lda;
357ca15aa20SStefano Zampini   const PetscScalar *v;
3581cbb95d3SBarry Smith 
3591cbb95d3SBarry Smith   PetscFunctionBegin;
3601cbb95d3SBarry Smith   *fl = PETSC_FALSE;
361d0f46423SBarry Smith   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
3629566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&v));
3631cbb95d3SBarry Smith   for (i=0; i<m; i++) {
364ca15aa20SStefano Zampini     for (j=i; j<m; j++) {
365637a0070SStefano Zampini       if (PetscAbsScalar(v[i+j*N] - PetscConj(v[j+i*N])) > rtol) {
366637a0070SStefano Zampini         goto restore;
3671cbb95d3SBarry Smith       }
3681cbb95d3SBarry Smith     }
369637a0070SStefano Zampini   }
3701cbb95d3SBarry Smith   *fl  = PETSC_TRUE;
371637a0070SStefano Zampini restore:
3729566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&v));
373637a0070SStefano Zampini   PetscFunctionReturn(0);
374637a0070SStefano Zampini }
375637a0070SStefano Zampini 
376637a0070SStefano Zampini static PetscErrorCode MatIsSymmetric_SeqDense(Mat A,PetscReal rtol,PetscBool  *fl)
377637a0070SStefano Zampini {
378637a0070SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
379637a0070SStefano Zampini   PetscInt          i,j,m = A->rmap->n,N = a->lda;
380637a0070SStefano Zampini   const PetscScalar *v;
381637a0070SStefano Zampini 
382637a0070SStefano Zampini   PetscFunctionBegin;
383637a0070SStefano Zampini   *fl = PETSC_FALSE;
384637a0070SStefano Zampini   if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0);
3859566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&v));
386637a0070SStefano Zampini   for (i=0; i<m; i++) {
387637a0070SStefano Zampini     for (j=i; j<m; j++) {
388637a0070SStefano Zampini       if (PetscAbsScalar(v[i+j*N] - v[j+i*N]) > rtol) {
389637a0070SStefano Zampini         goto restore;
390637a0070SStefano Zampini       }
391637a0070SStefano Zampini     }
392637a0070SStefano Zampini   }
393637a0070SStefano Zampini   *fl  = PETSC_TRUE;
394637a0070SStefano Zampini restore:
3959566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&v));
3961cbb95d3SBarry Smith   PetscFunctionReturn(0);
3971cbb95d3SBarry Smith }
3981cbb95d3SBarry Smith 
399ca15aa20SStefano Zampini PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi,Mat A,MatDuplicateOption cpvalues)
400b24902e0SBarry Smith {
401ca15aa20SStefano Zampini   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
40223fc5dcaSStefano Zampini   PetscInt       lda = (PetscInt)mat->lda,j,m,nlda = lda;
40375f6d85dSStefano Zampini   PetscBool      isdensecpu;
404b24902e0SBarry Smith 
405b24902e0SBarry Smith   PetscFunctionBegin;
4069566063dSJacob Faibussowitsch   PetscCall(PetscLayoutReference(A->rmap,&newi->rmap));
4079566063dSJacob Faibussowitsch   PetscCall(PetscLayoutReference(A->cmap,&newi->cmap));
40823fc5dcaSStefano Zampini   if (cpvalues == MAT_SHARE_NONZERO_PATTERN) { /* propagate LDA */
4099566063dSJacob Faibussowitsch     PetscCall(MatDenseSetLDA(newi,lda));
41023fc5dcaSStefano Zampini   }
4119566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)newi,MATSEQDENSE,&isdensecpu));
4129566063dSJacob Faibussowitsch   if (isdensecpu) PetscCall(MatSeqDenseSetPreallocation(newi,NULL));
413b24902e0SBarry Smith   if (cpvalues == MAT_COPY_VALUES) {
414ca15aa20SStefano Zampini     const PetscScalar *av;
415ca15aa20SStefano Zampini     PetscScalar       *v;
416ca15aa20SStefano Zampini 
4179566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A,&av));
4189566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayWrite(newi,&v));
4199566063dSJacob Faibussowitsch     PetscCall(MatDenseGetLDA(newi,&nlda));
420d0f46423SBarry Smith     m    = A->rmap->n;
42123fc5dcaSStefano Zampini     if (lda>m || nlda>m) {
422d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
4239566063dSJacob Faibussowitsch         PetscCall(PetscArraycpy(v+j*nlda,av+j*lda,m));
424b24902e0SBarry Smith       }
425b24902e0SBarry Smith     } else {
4269566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(v,av,A->rmap->n*A->cmap->n));
427b24902e0SBarry Smith     }
4289566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayWrite(newi,&v));
4299566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A,&av));
430b24902e0SBarry Smith   }
431b24902e0SBarry Smith   PetscFunctionReturn(0);
432b24902e0SBarry Smith }
433b24902e0SBarry Smith 
434ca15aa20SStefano Zampini PetscErrorCode MatDuplicate_SeqDense(Mat A,MatDuplicateOption cpvalues,Mat *newmat)
43502cad45dSBarry Smith {
4363a40ed3dSBarry Smith   PetscFunctionBegin;
4379566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A),newmat));
4389566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*newmat,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n));
4399566063dSJacob Faibussowitsch   PetscCall(MatSetType(*newmat,((PetscObject)A)->type_name));
4409566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(*newmat,A,cpvalues));
441b24902e0SBarry Smith   PetscFunctionReturn(0);
442b24902e0SBarry Smith }
443b24902e0SBarry Smith 
444bf5a80bcSToby Isaac static PetscErrorCode MatSolve_SeqDense_Internal_LU(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T)
445289bc588SBarry Smith {
446c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
4474396437dSToby Isaac   PetscBLASInt    info;
44867e560aaSBarry Smith 
4493a40ed3dSBarry Smith   PetscFunctionBegin;
4509566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
4514396437dSToby Isaac   PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_(T ? "T" : "N",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
4529566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
453*05fcb23eSStefano Zampini   PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve %d",(int)info);
4549566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs*(2.0*m*m - m)));
4554396437dSToby Isaac   PetscFunctionReturn(0);
4564396437dSToby Isaac }
4574396437dSToby Isaac 
4584396437dSToby Isaac static PetscErrorCode MatConjugate_SeqDense(Mat);
4594396437dSToby Isaac 
460bf5a80bcSToby Isaac static PetscErrorCode MatSolve_SeqDense_Internal_Cholesky(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k, PetscBool T)
4614396437dSToby Isaac {
4624396437dSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
4634396437dSToby Isaac   PetscBLASInt    info;
4644396437dSToby Isaac 
4654396437dSToby Isaac   PetscFunctionBegin;
466a49dc2a2SStefano Zampini   if (A->spd) {
4679566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A));
4689566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
4698b83055fSJed Brown     PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&nrhs,mat->v,&mat->lda,x,&m,&info));
4709566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
471*05fcb23eSStefano Zampini     PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve %d",(int)info);
4729566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX) && T) PetscCall(MatConjugate_SeqDense(A));
473a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
474a49dc2a2SStefano Zampini   } else if (A->hermitian) {
4759566063dSJacob Faibussowitsch     if (T) PetscCall(MatConjugate_SeqDense(A));
4769566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
477a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
4789566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
479*05fcb23eSStefano Zampini     PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve %d",(int)info);
4809566063dSJacob Faibussowitsch     if (T) PetscCall(MatConjugate_SeqDense(A));
481a49dc2a2SStefano Zampini #endif
482a49dc2a2SStefano Zampini   } else { /* symmetric case */
4839566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
484a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info));
4859566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
486*05fcb23eSStefano Zampini     PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve %d",(int)info);
487a49dc2a2SStefano Zampini   }
4889566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs*(2.0*m*m - m)));
4894396437dSToby Isaac   PetscFunctionReturn(0);
4904396437dSToby Isaac }
49185e2c93fSHong Zhang 
492bf5a80bcSToby Isaac static PetscErrorCode MatSolve_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k)
4934396437dSToby Isaac {
4944396437dSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
4954396437dSToby Isaac   PetscBLASInt    info;
4964396437dSToby Isaac   char            trans;
4974396437dSToby Isaac 
4984396437dSToby Isaac   PetscFunctionBegin;
4994905a7bcSToby Isaac   if (PetscDefined(USE_COMPLEX)) {
5004905a7bcSToby Isaac     trans = 'C';
5014905a7bcSToby Isaac   } else {
5024905a7bcSToby Isaac     trans = 'T';
5034905a7bcSToby Isaac   }
5049566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
505*05fcb23eSStefano Zampini   { /* lwork depends on the number of right-hand sides */
506*05fcb23eSStefano Zampini     PetscBLASInt nlfwork, lfwork = -1;
507*05fcb23eSStefano Zampini     PetscScalar  fwork;
508*05fcb23eSStefano Zampini 
509*05fcb23eSStefano Zampini     PetscStackCallBLAS("LAPACKormqr",LAPACKormqr_("L", &trans, &m,&nrhs,&mat->rank,mat->v,&mat->lda,mat->tau,x,&ldx,&fwork,&lfwork,&info));
510*05fcb23eSStefano Zampini     nlfwork = (PetscBLASInt)PetscRealPart(fwork);
511*05fcb23eSStefano Zampini     if (nlfwork > mat->lfwork) {
512*05fcb23eSStefano Zampini       mat->lfwork = nlfwork;
513*05fcb23eSStefano Zampini       PetscCall(PetscFree(mat->fwork));
514*05fcb23eSStefano Zampini       PetscCall(PetscMalloc1(mat->lfwork,&mat->fwork));
515*05fcb23eSStefano Zampini     }
516*05fcb23eSStefano Zampini   }
517bf5a80bcSToby Isaac   PetscStackCallBLAS("LAPACKormqr",LAPACKormqr_("L", &trans, &m,&nrhs,&mat->rank,mat->v,&mat->lda,mat->tau,x,&ldx,mat->fwork,&mat->lfwork,&info));
5189566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
519*05fcb23eSStefano Zampini   PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"ORMQR - Bad orthogonal transform %d",(int)info);
5209566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
521bf5a80bcSToby Isaac   PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U", "N", "N", &mat->rank,&nrhs,mat->v,&mat->lda,x,&ldx,&info));
5229566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
523*05fcb23eSStefano Zampini   PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"TRTRS - Bad triangular solve %d",(int)info);
5244905a7bcSToby Isaac   for (PetscInt j = 0; j < nrhs; j++) {
5254905a7bcSToby Isaac     for (PetscInt i = mat->rank; i < k; i++) {
526bf5a80bcSToby Isaac       x[j*ldx + i] = 0.;
5274905a7bcSToby Isaac     }
5284905a7bcSToby Isaac   }
5299566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs*(4.0*m*mat->rank - PetscSqr(mat->rank))));
5304905a7bcSToby Isaac   PetscFunctionReturn(0);
5314905a7bcSToby Isaac }
5324905a7bcSToby Isaac 
533bf5a80bcSToby Isaac static PetscErrorCode MatSolveTranspose_SeqDense_Internal_QR(Mat A, PetscScalar *x, PetscBLASInt ldx, PetscBLASInt m, PetscBLASInt nrhs, PetscBLASInt k)
5344905a7bcSToby Isaac {
5354396437dSToby Isaac   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
5364396437dSToby Isaac   PetscBLASInt      info;
5374396437dSToby Isaac 
5384396437dSToby Isaac   PetscFunctionBegin;
5394396437dSToby Isaac   if (A->rmap->n == A->cmap->n && mat->rank == A->rmap->n) {
5409566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
541bf5a80bcSToby Isaac     PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U", "T", "N", &m,&nrhs,mat->v,&mat->lda,x,&ldx,&info));
5429566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
543*05fcb23eSStefano Zampini     PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"TRTRS - Bad triangular solve %d",(int)info);
5449566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A));
545*05fcb23eSStefano Zampini     { /* lwork depends on the number of right-hand sides */
546*05fcb23eSStefano Zampini       PetscBLASInt nlfwork, lfwork = -1;
547*05fcb23eSStefano Zampini       PetscScalar  fwork;
548*05fcb23eSStefano Zampini 
549*05fcb23eSStefano Zampini       PetscStackCallBLAS("LAPACKormqr",LAPACKormqr_("L", "N", &m,&nrhs,&mat->rank,mat->v,&mat->lda,mat->tau,x,&ldx,&fwork,&lfwork,&info));
550*05fcb23eSStefano Zampini       nlfwork = (PetscBLASInt)PetscRealPart(fwork);
551*05fcb23eSStefano Zampini       if (nlfwork > mat->lfwork) {
552*05fcb23eSStefano Zampini         mat->lfwork = nlfwork;
553*05fcb23eSStefano Zampini         PetscCall(PetscFree(mat->fwork));
554*05fcb23eSStefano Zampini         PetscCall(PetscMalloc1(mat->lfwork,&mat->fwork));
555*05fcb23eSStefano Zampini       }
556*05fcb23eSStefano Zampini     }
5579566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
558bf5a80bcSToby Isaac     PetscStackCallBLAS("LAPACKormqr",LAPACKormqr_("L", "N", &m,&nrhs,&mat->rank,mat->v,&mat->lda,mat->tau,x,&ldx,mat->fwork,&mat->lfwork,&info));
5599566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
560*05fcb23eSStefano Zampini     PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"ORMQR - Bad orthogonal transform %d",(int)info);
5619566063dSJacob Faibussowitsch     if (PetscDefined(USE_COMPLEX)) PetscCall(MatConjugate_SeqDense(A));
5624396437dSToby Isaac   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"QR factored matrix cannot be used for transpose solve");
5639566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(nrhs*(4.0*m*mat->rank - PetscSqr(mat->rank))));
5644396437dSToby Isaac   PetscFunctionReturn(0);
5654396437dSToby Isaac }
5664396437dSToby Isaac 
5674396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_SetUp(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k)
5684396437dSToby Isaac {
5694396437dSToby Isaac   Mat_SeqDense      *mat = (Mat_SeqDense *) A->data;
5704905a7bcSToby Isaac   PetscScalar       *y;
5714905a7bcSToby Isaac   PetscBLASInt      m=0, k=0;
5724905a7bcSToby Isaac 
5734905a7bcSToby Isaac   PetscFunctionBegin;
5749566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
5759566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&k));
5764905a7bcSToby Isaac   if (k < m) {
5779566063dSJacob Faibussowitsch     PetscCall(VecCopy(xx, mat->qrrhs));
5789566063dSJacob Faibussowitsch     PetscCall(VecGetArray(mat->qrrhs,&y));
5794905a7bcSToby Isaac   } else {
5809566063dSJacob Faibussowitsch     PetscCall(VecCopy(xx, yy));
5819566063dSJacob Faibussowitsch     PetscCall(VecGetArray(yy,&y));
5824905a7bcSToby Isaac   }
5834396437dSToby Isaac   *_y = y;
5844396437dSToby Isaac   *_k = k;
5854396437dSToby Isaac   *_m = m;
5864396437dSToby Isaac   PetscFunctionReturn(0);
5874396437dSToby Isaac }
5884396437dSToby Isaac 
5894396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_TearDown(Mat A, Vec xx, Vec yy, PetscScalar **_y, PetscBLASInt *_m, PetscBLASInt *_k)
5904396437dSToby Isaac {
5914396437dSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense *) A->data;
59242e9364cSSatish Balay   PetscScalar    *y = NULL;
5934396437dSToby Isaac   PetscBLASInt   m, k;
5944396437dSToby Isaac 
5954396437dSToby Isaac   PetscFunctionBegin;
5964396437dSToby Isaac   y   = *_y;
5974396437dSToby Isaac   *_y = NULL;
5984396437dSToby Isaac   k   = *_k;
5994396437dSToby Isaac   m   = *_m;
6004905a7bcSToby Isaac   if (k < m) {
6014905a7bcSToby Isaac     PetscScalar *yv;
6029566063dSJacob Faibussowitsch     PetscCall(VecGetArray(yy,&yv));
6039566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(yv, y, k));
6049566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(yy,&yv));
6059566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(mat->qrrhs, &y));
6064905a7bcSToby Isaac   } else {
6079566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(yy,&y));
6084905a7bcSToby Isaac   }
6094905a7bcSToby Isaac   PetscFunctionReturn(0);
6104905a7bcSToby Isaac }
6114905a7bcSToby Isaac 
6124396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_LU(Mat A, Vec xx, Vec yy)
6134396437dSToby Isaac {
61442e9364cSSatish Balay   PetscScalar    *y = NULL;
61542e9364cSSatish Balay   PetscBLASInt   m = 0, k = 0;
6164396437dSToby Isaac 
6174396437dSToby Isaac   PetscFunctionBegin;
6189566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6199566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_FALSE));
6209566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6214396437dSToby Isaac   PetscFunctionReturn(0);
6224396437dSToby Isaac }
6234396437dSToby Isaac 
6244396437dSToby Isaac static PetscErrorCode MatSolveTranspose_SeqDense_LU(Mat A, Vec xx, Vec yy)
6254396437dSToby Isaac {
62642e9364cSSatish Balay   PetscScalar    *y = NULL;
62742e9364cSSatish Balay   PetscBLASInt   m = 0, k = 0;
6284396437dSToby Isaac 
6294396437dSToby Isaac   PetscFunctionBegin;
6309566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6319566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, m, m, 1, k, PETSC_TRUE));
6329566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6334396437dSToby Isaac   PetscFunctionReturn(0);
6344396437dSToby Isaac }
6354396437dSToby Isaac 
6364396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_Cholesky(Mat A, Vec xx, Vec yy)
6374396437dSToby Isaac {
638e54beecaSStefano Zampini   PetscScalar    *y = NULL;
639e54beecaSStefano Zampini   PetscBLASInt   m = 0, k = 0;
6404396437dSToby Isaac 
6414396437dSToby Isaac   PetscFunctionBegin;
6429566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6439566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_FALSE));
6449566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6454396437dSToby Isaac   PetscFunctionReturn(0);
6464396437dSToby Isaac }
6474396437dSToby Isaac 
6484396437dSToby Isaac static PetscErrorCode MatSolveTranspose_SeqDense_Cholesky(Mat A, Vec xx, Vec yy)
6494396437dSToby Isaac {
650e54beecaSStefano Zampini   PetscScalar    *y = NULL;
651e54beecaSStefano Zampini   PetscBLASInt   m = 0, k = 0;
6524396437dSToby Isaac 
6534396437dSToby Isaac   PetscFunctionBegin;
6549566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6559566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, m, m, 1, k, PETSC_TRUE));
6569566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6574396437dSToby Isaac   PetscFunctionReturn(0);
6584396437dSToby Isaac }
6594396437dSToby Isaac 
6604396437dSToby Isaac static PetscErrorCode MatSolve_SeqDense_QR(Mat A, Vec xx, Vec yy)
6614396437dSToby Isaac {
662e54beecaSStefano Zampini   PetscScalar    *y = NULL;
663e54beecaSStefano Zampini   PetscBLASInt   m = 0, k = 0;
6644396437dSToby Isaac 
6654396437dSToby Isaac   PetscFunctionBegin;
6669566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6679566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_QR(A, y, PetscMax(m,k), m, 1, k));
6689566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6694396437dSToby Isaac   PetscFunctionReturn(0);
6704396437dSToby Isaac }
6714396437dSToby Isaac 
6724396437dSToby Isaac static PetscErrorCode MatSolveTranspose_SeqDense_QR(Mat A, Vec xx, Vec yy)
6734396437dSToby Isaac {
67442e9364cSSatish Balay   PetscScalar    *y = NULL;
67542e9364cSSatish Balay   PetscBLASInt   m = 0, k = 0;
6764396437dSToby Isaac 
6774396437dSToby Isaac   PetscFunctionBegin;
6789566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_SetUp(A, xx, yy, &y, &m, &k));
6799566063dSJacob Faibussowitsch   PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, PetscMax(m,k), m, 1, k));
6809566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_TearDown(A, xx, yy, &y, &m, &k));
6814396437dSToby Isaac   PetscFunctionReturn(0);
6824396437dSToby Isaac }
6834396437dSToby Isaac 
684bf5a80bcSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_SetUp(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k)
6854905a7bcSToby Isaac {
6864905a7bcSToby Isaac   const PetscScalar *b;
6874396437dSToby Isaac   PetscScalar       *y;
688bf5a80bcSToby Isaac   PetscInt          n, _ldb, _ldx;
689bf5a80bcSToby Isaac   PetscBLASInt      nrhs=0,m=0,k=0,ldb=0,ldx=0,ldy=0;
6904905a7bcSToby Isaac 
6914905a7bcSToby Isaac   PetscFunctionBegin;
6926280eecaSJose E. Roman   *_ldy=0; *_m=0; *_nrhs=0; *_k=0; *_y = NULL;
6939566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
6949566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&k));
6959566063dSJacob Faibussowitsch   PetscCall(MatGetSize(B,NULL,&n));
6969566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(n,&nrhs));
6979566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(B,&_ldb));
6989566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldb, &ldb));
6999566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(X,&_ldx));
7009566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldx, &ldx));
701bf5a80bcSToby Isaac   if (ldx < m) {
7029566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(B,&b));
7039566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nrhs * m, &y));
704bf5a80bcSToby Isaac     if (ldb == m) {
7059566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(y,b,ldb*nrhs));
7064905a7bcSToby Isaac     } else {
7074905a7bcSToby Isaac       for (PetscInt j = 0; j < nrhs; j++) {
7089566063dSJacob Faibussowitsch         PetscCall(PetscArraycpy(&y[j*m],&b[j*ldb],m));
7094905a7bcSToby Isaac       }
7104905a7bcSToby Isaac     }
711bf5a80bcSToby Isaac     ldy = m;
7129566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(B,&b));
7134905a7bcSToby Isaac   } else {
714bf5a80bcSToby Isaac     if (ldb == ldx) {
7159566063dSJacob Faibussowitsch       PetscCall(MatCopy(B, X, SAME_NONZERO_PATTERN));
7169566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(X,&y));
7174905a7bcSToby Isaac     } else {
7189566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(X,&y));
7199566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArrayRead(B,&b));
7204905a7bcSToby Isaac       for (PetscInt j = 0; j < nrhs; j++) {
7219566063dSJacob Faibussowitsch         PetscCall(PetscArraycpy(&y[j*ldx],&b[j*ldb],m));
7224905a7bcSToby Isaac       }
7239566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArrayRead(B,&b));
7244905a7bcSToby Isaac     }
725bf5a80bcSToby Isaac     ldy = ldx;
7264905a7bcSToby Isaac   }
7274396437dSToby Isaac   *_y    = y;
728bf5a80bcSToby Isaac   *_ldy = ldy;
7294396437dSToby Isaac   *_k    = k;
7304396437dSToby Isaac   *_m    = m;
7314396437dSToby Isaac   *_nrhs = nrhs;
7324396437dSToby Isaac   PetscFunctionReturn(0);
7334396437dSToby Isaac }
7344396437dSToby Isaac 
735bf5a80bcSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_TearDown(Mat A, Mat B, Mat X, PetscScalar **_y, PetscBLASInt *_ldy, PetscBLASInt *_m, PetscBLASInt *_nrhs, PetscBLASInt *_k)
7364396437dSToby Isaac {
7374396437dSToby Isaac   PetscScalar       *y;
738bf5a80bcSToby Isaac   PetscInt          _ldx;
739bf5a80bcSToby Isaac   PetscBLASInt      k,ldy,nrhs,ldx=0;
7404396437dSToby Isaac 
7414396437dSToby Isaac   PetscFunctionBegin;
7424396437dSToby Isaac   y    = *_y;
7434396437dSToby Isaac   *_y  = NULL;
7444396437dSToby Isaac   k    = *_k;
745bf5a80bcSToby Isaac   ldy = *_ldy;
7464396437dSToby Isaac   nrhs = *_nrhs;
7479566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(X,&_ldx));
7489566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(_ldx, &ldx));
749bf5a80bcSToby Isaac   if (ldx != ldy) {
7504905a7bcSToby Isaac     PetscScalar *xv;
7519566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArray(X,&xv));
7524905a7bcSToby Isaac     for (PetscInt j = 0; j < nrhs; j++) {
7539566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(&xv[j*ldx],&y[j*ldy],k));
7544905a7bcSToby Isaac     }
7559566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(X,&xv));
7569566063dSJacob Faibussowitsch     PetscCall(PetscFree(y));
7574905a7bcSToby Isaac   } else {
7589566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(X,&y));
7594905a7bcSToby Isaac   }
76085e2c93fSHong Zhang   PetscFunctionReturn(0);
76185e2c93fSHong Zhang }
76285e2c93fSHong Zhang 
7634396437dSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_LU(Mat A, Mat B, Mat X)
7644396437dSToby Isaac {
7654396437dSToby Isaac   PetscScalar    *y;
766bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
7674396437dSToby Isaac 
7684396437dSToby Isaac   PetscFunctionBegin;
7699566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7709566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_FALSE));
7719566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7724396437dSToby Isaac   PetscFunctionReturn(0);
7734396437dSToby Isaac }
7744396437dSToby Isaac 
7754396437dSToby Isaac static PetscErrorCode MatMatSolveTranspose_SeqDense_LU(Mat A, Mat B, Mat X)
7764396437dSToby Isaac {
7774396437dSToby Isaac   PetscScalar    *y;
778bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
7794396437dSToby Isaac 
7804396437dSToby Isaac   PetscFunctionBegin;
7819566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7829566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_LU(A, y, ldy, m, nrhs, k, PETSC_TRUE));
7839566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7844396437dSToby Isaac   PetscFunctionReturn(0);
7854396437dSToby Isaac }
7864396437dSToby Isaac 
7874396437dSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_Cholesky(Mat A, Mat B, Mat X)
7884396437dSToby Isaac {
7894396437dSToby Isaac   PetscScalar    *y;
790bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
7914396437dSToby Isaac 
7924396437dSToby Isaac   PetscFunctionBegin;
7939566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
7949566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_FALSE));
7959566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
7964396437dSToby Isaac   PetscFunctionReturn(0);
7974396437dSToby Isaac }
7984396437dSToby Isaac 
7994396437dSToby Isaac static PetscErrorCode MatMatSolveTranspose_SeqDense_Cholesky(Mat A, Mat B, Mat X)
8004396437dSToby Isaac {
8014396437dSToby Isaac   PetscScalar    *y;
802bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
8034396437dSToby Isaac 
8044396437dSToby Isaac   PetscFunctionBegin;
8059566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
8069566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_Cholesky(A, y, ldy, m, nrhs, k, PETSC_TRUE));
8079566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
8084396437dSToby Isaac   PetscFunctionReturn(0);
8094396437dSToby Isaac }
8104396437dSToby Isaac 
8114396437dSToby Isaac static PetscErrorCode MatMatSolve_SeqDense_QR(Mat A, Mat B, Mat X)
8124396437dSToby Isaac {
8134396437dSToby Isaac   PetscScalar    *y;
814bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
8154396437dSToby Isaac 
8164396437dSToby Isaac   PetscFunctionBegin;
8179566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
8189566063dSJacob Faibussowitsch   PetscCall(MatSolve_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k));
8199566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
8204396437dSToby Isaac   PetscFunctionReturn(0);
8214396437dSToby Isaac }
8224396437dSToby Isaac 
8234396437dSToby Isaac static PetscErrorCode MatMatSolveTranspose_SeqDense_QR(Mat A, Mat B, Mat X)
8244396437dSToby Isaac {
8254396437dSToby Isaac   PetscScalar    *y;
826bf5a80bcSToby Isaac   PetscBLASInt   m, k, ldy, nrhs;
8274396437dSToby Isaac 
8284396437dSToby Isaac   PetscFunctionBegin;
8299566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_SetUp(A, B, X, &y, &ldy, &m, &nrhs, &k));
8309566063dSJacob Faibussowitsch   PetscCall(MatSolveTranspose_SeqDense_Internal_QR(A, y, ldy, m, nrhs, k));
8319566063dSJacob Faibussowitsch   PetscCall(MatMatSolve_SeqDense_TearDown(A, B, X, &y, &ldy, &m, &nrhs, &k));
8324396437dSToby Isaac   PetscFunctionReturn(0);
8334396437dSToby Isaac }
8344396437dSToby Isaac 
83500121966SStefano Zampini static PetscErrorCode MatConjugate_SeqDense(Mat);
83600121966SStefano Zampini 
837db4efbfdSBarry Smith /* ---------------------------------------------------------------*/
838db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots,
839db4efbfdSBarry Smith    rather than put it in the Mat->row slot.*/
840ca15aa20SStefano Zampini PetscErrorCode MatLUFactor_SeqDense(Mat A,IS row,IS col,const MatFactorInfo *minfo)
841db4efbfdSBarry Smith {
842db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
843db4efbfdSBarry Smith   PetscBLASInt   n,m,info;
844db4efbfdSBarry Smith 
845db4efbfdSBarry Smith   PetscFunctionBegin;
8469566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
8479566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
848db4efbfdSBarry Smith   if (!mat->pivots) {
8499566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(A->rmap->n,&mat->pivots));
8509566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt)));
851db4efbfdSBarry Smith   }
852db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
8539566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
8548b83055fSJed Brown   PetscStackCallBLAS("LAPACKgetrf",LAPACKgetrf_(&m,&n,mat->v,&mat->lda,mat->pivots,&info));
8559566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
8568e57ea43SSatish Balay 
857*05fcb23eSStefano Zampini   PetscCheck(info>=0,PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to LU factorization %d",(int)info);
858*05fcb23eSStefano Zampini   PetscCheck(info<=0,PETSC_COMM_SELF,PETSC_ERR_MAT_LU_ZRPVT,"Bad LU factorization %d",(int)info);
8598208b9aeSStefano Zampini 
8604396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_LU;
8614396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_LU;
8624396437dSToby Isaac   A->ops->solvetranspose    = MatSolveTranspose_SeqDense_LU;
8634396437dSToby Isaac   A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_LU;
864d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_LU;
865db4efbfdSBarry Smith 
8669566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
8679566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC,&A->solvertype));
868f6224b95SHong Zhang 
8699566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops((2.0*A->cmap->n*A->cmap->n*A->cmap->n)/3));
870db4efbfdSBarry Smith   PetscFunctionReturn(0);
871db4efbfdSBarry Smith }
872db4efbfdSBarry Smith 
8734396437dSToby Isaac static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
8744396437dSToby Isaac {
8754396437dSToby Isaac   MatFactorInfo  info;
8764396437dSToby Isaac 
8774396437dSToby Isaac   PetscFunctionBegin;
8789566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES));
8799566063dSJacob Faibussowitsch   PetscCall((*fact->ops->lufactor)(fact,NULL,NULL,&info));
8804396437dSToby Isaac   PetscFunctionReturn(0);
8814396437dSToby Isaac }
8824396437dSToby Isaac 
8834396437dSToby Isaac PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,IS col,const MatFactorInfo *info)
8844396437dSToby Isaac {
8854396437dSToby Isaac   PetscFunctionBegin;
8864396437dSToby Isaac   fact->preallocated           = PETSC_TRUE;
8874396437dSToby Isaac   fact->assembled              = PETSC_TRUE;
8884396437dSToby Isaac   fact->ops->lufactornumeric   = MatLUFactorNumeric_SeqDense;
8894396437dSToby Isaac   PetscFunctionReturn(0);
8904396437dSToby Isaac }
8914396437dSToby Isaac 
892a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */
893ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactor_SeqDense(Mat A,IS perm,const MatFactorInfo *factinfo)
894db4efbfdSBarry Smith {
895db4efbfdSBarry Smith   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
896c5df96a5SBarry Smith   PetscBLASInt   info,n;
897db4efbfdSBarry Smith 
898db4efbfdSBarry Smith   PetscFunctionBegin;
8999566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
900db4efbfdSBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
901a49dc2a2SStefano Zampini   if (A->spd) {
9029566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
9038b83055fSJed Brown     PetscStackCallBLAS("LAPACKpotrf",LAPACKpotrf_("L",&n,mat->v,&mat->lda,&info));
9049566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
905a49dc2a2SStefano Zampini #if defined(PETSC_USE_COMPLEX)
906a49dc2a2SStefano Zampini   } else if (A->hermitian) {
907a49dc2a2SStefano Zampini     if (!mat->pivots) {
9089566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(A->rmap->n,&mat->pivots));
9099566063dSJacob Faibussowitsch       PetscCall(PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt)));
910a49dc2a2SStefano Zampini     }
911a49dc2a2SStefano Zampini     if (!mat->fwork) {
912a49dc2a2SStefano Zampini       PetscScalar dummy;
913a49dc2a2SStefano Zampini 
914a49dc2a2SStefano Zampini       mat->lfwork = -1;
9159566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
916a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
9179566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
918a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
9199566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(mat->lfwork,&mat->fwork));
9209566063dSJacob Faibussowitsch       PetscCall(PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt)));
921a49dc2a2SStefano Zampini     }
9229566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
923a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
9249566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
925a49dc2a2SStefano Zampini #endif
926a49dc2a2SStefano Zampini   } else { /* symmetric case */
927a49dc2a2SStefano Zampini     if (!mat->pivots) {
9289566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(A->rmap->n,&mat->pivots));
9299566063dSJacob Faibussowitsch       PetscCall(PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt)));
930a49dc2a2SStefano Zampini     }
931a49dc2a2SStefano Zampini     if (!mat->fwork) {
932a49dc2a2SStefano Zampini       PetscScalar dummy;
933a49dc2a2SStefano Zampini 
934a49dc2a2SStefano Zampini       mat->lfwork = -1;
9359566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
936a49dc2a2SStefano Zampini       PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info));
9379566063dSJacob Faibussowitsch       PetscCall(PetscFPTrapPop());
938a49dc2a2SStefano Zampini       mat->lfwork = (PetscInt)PetscRealPart(dummy);
9399566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1(mat->lfwork,&mat->fwork));
9409566063dSJacob Faibussowitsch       PetscCall(PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt)));
941a49dc2a2SStefano Zampini     }
9429566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
943a49dc2a2SStefano Zampini     PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info));
9449566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
945a49dc2a2SStefano Zampini   }
94628b400f6SJacob Faibussowitsch   PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad factorization: zero pivot in row %" PetscInt_FMT,(PetscInt)info-1);
9478208b9aeSStefano Zampini 
9484396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_Cholesky;
9494396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_Cholesky;
9504396437dSToby Isaac   A->ops->solvetranspose    = MatSolveTranspose_SeqDense_Cholesky;
9514396437dSToby Isaac   A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_Cholesky;
952d5f3da31SBarry Smith   A->factortype             = MAT_FACTOR_CHOLESKY;
9532205254eSKarl Rupp 
9549566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
9559566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC,&A->solvertype));
956f6224b95SHong Zhang 
9579566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0));
958db4efbfdSBarry Smith   PetscFunctionReturn(0);
959db4efbfdSBarry Smith }
960db4efbfdSBarry Smith 
9614396437dSToby Isaac static PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
962db4efbfdSBarry Smith {
963db4efbfdSBarry Smith   MatFactorInfo  info;
964db4efbfdSBarry Smith 
965db4efbfdSBarry Smith   PetscFunctionBegin;
966db4efbfdSBarry Smith   info.fill = 1.0;
9672205254eSKarl Rupp 
9689566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES));
9699566063dSJacob Faibussowitsch   PetscCall((*fact->ops->choleskyfactor)(fact,NULL,&info));
970db4efbfdSBarry Smith   PetscFunctionReturn(0);
971db4efbfdSBarry Smith }
972db4efbfdSBarry Smith 
973ca15aa20SStefano Zampini PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info)
974db4efbfdSBarry Smith {
975db4efbfdSBarry Smith   PetscFunctionBegin;
976c3ef05f6SHong Zhang   fact->assembled                  = PETSC_TRUE;
9771bbcc794SSatish Balay   fact->preallocated               = PETSC_TRUE;
978719d5645SBarry Smith   fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense;
979db4efbfdSBarry Smith   PetscFunctionReturn(0);
980db4efbfdSBarry Smith }
981db4efbfdSBarry Smith 
982bf5a80bcSToby Isaac PetscErrorCode MatQRFactor_SeqDense(Mat A,IS col,const MatFactorInfo *minfo)
9834905a7bcSToby Isaac {
9844905a7bcSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
9854905a7bcSToby Isaac   PetscBLASInt   n,m,info, min, max;
9864905a7bcSToby Isaac 
9874905a7bcSToby Isaac   PetscFunctionBegin;
9889566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
9899566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
9904396437dSToby Isaac   max = PetscMax(m, n);
9914396437dSToby Isaac   min = PetscMin(m, n);
9924905a7bcSToby Isaac   if (!mat->tau) {
9939566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(min,&mat->tau));
9949566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)A,min*sizeof(PetscScalar)));
9954396437dSToby Isaac   }
9964396437dSToby Isaac   if (!mat->pivots) {
9979566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(n,&mat->pivots));
9989566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)A,n*sizeof(PetscScalar)));
9994396437dSToby Isaac   }
10004396437dSToby Isaac   if (!mat->qrrhs) {
10019566063dSJacob Faibussowitsch     PetscCall(MatCreateVecs(A, NULL, &(mat->qrrhs)));
10024905a7bcSToby Isaac   }
10034905a7bcSToby Isaac   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
10044905a7bcSToby Isaac   if (!mat->fwork) {
10054905a7bcSToby Isaac     PetscScalar dummy;
10064905a7bcSToby Isaac 
10074905a7bcSToby Isaac     mat->lfwork = -1;
10089566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
10094905a7bcSToby Isaac     PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&m,&n,mat->v,&mat->lda,mat->tau,&dummy,&mat->lfwork,&info));
10109566063dSJacob Faibussowitsch     PetscCall(PetscFPTrapPop());
10114905a7bcSToby Isaac     mat->lfwork = (PetscInt)PetscRealPart(dummy);
10129566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(mat->lfwork,&mat->fwork));
10139566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt)));
10144905a7bcSToby Isaac   }
10159566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPush(PETSC_FP_TRAP_OFF));
10164905a7bcSToby Isaac   PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&m,&n,mat->v,&mat->lda,mat->tau,mat->fwork,&mat->lfwork,&info));
10179566063dSJacob Faibussowitsch   PetscCall(PetscFPTrapPop());
1018*05fcb23eSStefano Zampini   PetscCheck(!info,PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to QR factorization %d",(int)info);
10194905a7bcSToby 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
10204905a7bcSToby Isaac   mat->rank = min;
10214905a7bcSToby Isaac 
10224396437dSToby Isaac   A->ops->solve             = MatSolve_SeqDense_QR;
10234396437dSToby Isaac   A->ops->matsolve          = MatMatSolve_SeqDense_QR;
10244905a7bcSToby Isaac   A->factortype             = MAT_FACTOR_QR;
10254905a7bcSToby Isaac   if (m == n) {
10264396437dSToby Isaac     A->ops->solvetranspose    = MatSolveTranspose_SeqDense_QR;
10274396437dSToby Isaac     A->ops->matsolvetranspose = MatMatSolveTranspose_SeqDense_QR;
10284905a7bcSToby Isaac   }
10294905a7bcSToby Isaac 
10309566063dSJacob Faibussowitsch   PetscCall(PetscFree(A->solvertype));
10319566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC,&A->solvertype));
10324905a7bcSToby Isaac 
10339566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0*min*min*(max-min/3.0)));
10344905a7bcSToby Isaac   PetscFunctionReturn(0);
10354905a7bcSToby Isaac }
10364905a7bcSToby Isaac 
10374905a7bcSToby Isaac static PetscErrorCode MatQRFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy)
10384905a7bcSToby Isaac {
10394905a7bcSToby Isaac   MatFactorInfo  info;
10404905a7bcSToby Isaac 
10414905a7bcSToby Isaac   PetscFunctionBegin;
10424905a7bcSToby Isaac   info.fill = 1.0;
10434905a7bcSToby Isaac 
10449566063dSJacob Faibussowitsch   PetscCall(MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES));
1045cac4c232SBarry Smith   PetscUseMethod(fact,"MatQRFactor_C",(Mat,IS,const MatFactorInfo *),(fact,NULL,&info));
10464905a7bcSToby Isaac   PetscFunctionReturn(0);
10474905a7bcSToby Isaac }
10484905a7bcSToby Isaac 
1049bf5a80bcSToby Isaac PetscErrorCode MatQRFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info)
10504905a7bcSToby Isaac {
10514905a7bcSToby Isaac   PetscFunctionBegin;
10524905a7bcSToby Isaac   fact->assembled                  = PETSC_TRUE;
10534905a7bcSToby Isaac   fact->preallocated               = PETSC_TRUE;
10549566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)fact,"MatQRFactorNumeric_C",MatQRFactorNumeric_SeqDense));
10554905a7bcSToby Isaac   PetscFunctionReturn(0);
10564905a7bcSToby Isaac }
10574905a7bcSToby Isaac 
1058ca15aa20SStefano Zampini /* uses LAPACK */
1059cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A,MatFactorType ftype,Mat *fact)
1060db4efbfdSBarry Smith {
1061db4efbfdSBarry Smith   PetscFunctionBegin;
10629566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A),fact));
10639566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*fact,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n));
10649566063dSJacob Faibussowitsch   PetscCall(MatSetType(*fact,MATDENSE));
106566e17bc3SBarry Smith   (*fact)->trivialsymbolic = PETSC_TRUE;
10662a350339SBarry Smith   if (ftype == MAT_FACTOR_LU || ftype == MAT_FACTOR_ILU) {
1067db4efbfdSBarry Smith     (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense;
10682a350339SBarry Smith     (*fact)->ops->ilufactorsymbolic = MatLUFactorSymbolic_SeqDense;
1069bf5a80bcSToby Isaac   } else if (ftype == MAT_FACTOR_CHOLESKY || ftype == MAT_FACTOR_ICC) {
1070db4efbfdSBarry Smith     (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense;
1071bf5a80bcSToby Isaac   } else if (ftype == MAT_FACTOR_QR) {
10729566063dSJacob Faibussowitsch     PetscCall(PetscObjectComposeFunction((PetscObject)(*fact),"MatQRFactorSymbolic_C",MatQRFactorSymbolic_SeqDense));
1073db4efbfdSBarry Smith   }
1074d5f3da31SBarry Smith   (*fact)->factortype = ftype;
107500c67f3bSHong Zhang 
10769566063dSJacob Faibussowitsch   PetscCall(PetscFree((*fact)->solvertype));
10779566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATSOLVERPETSC,&(*fact)->solvertype));
10789566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_LU]));
10799566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_ILU]));
10809566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_CHOLESKY]));
10819566063dSJacob Faibussowitsch   PetscCall(PetscStrallocpy(MATORDERINGEXTERNAL,(char**)&(*fact)->preferredordering[MAT_FACTOR_ICC]));
1082db4efbfdSBarry Smith   PetscFunctionReturn(0);
1083db4efbfdSBarry Smith }
1084db4efbfdSBarry Smith 
1085289bc588SBarry Smith /* ------------------------------------------------------------------*/
1086e0877f53SBarry Smith static PetscErrorCode MatSOR_SeqDense(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec xx)
1087289bc588SBarry Smith {
1088c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1089d9ca1df4SBarry Smith   PetscScalar       *x,*v = mat->v,zero = 0.0,xt;
1090d9ca1df4SBarry Smith   const PetscScalar *b;
1091d0f46423SBarry Smith   PetscInt          m = A->rmap->n,i;
109223fff9afSBarry Smith   PetscBLASInt      o = 1,bm = 0;
1093289bc588SBarry Smith 
10943a40ed3dSBarry Smith   PetscFunctionBegin;
1095ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
109608401ef6SPierre Jolivet   PetscCheck(A->offloadmask != PETSC_OFFLOAD_GPU,PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented");
1097ca15aa20SStefano Zampini #endif
1098422a814eSBarry Smith   if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */
10999566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(m,&bm));
1100289bc588SBarry Smith   if (flag & SOR_ZERO_INITIAL_GUESS) {
11013bffc371SBarry Smith     /* this is a hack fix, should have another version without the second BLASdotu */
11029566063dSJacob Faibussowitsch     PetscCall(VecSet(xx,zero));
1103289bc588SBarry Smith   }
11049566063dSJacob Faibussowitsch   PetscCall(VecGetArray(xx,&x));
11059566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(bb,&b));
1106b965ef7fSBarry Smith   its  = its*lits;
110708401ef6SPierre 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);
1108289bc588SBarry Smith   while (its--) {
1109fccaa45eSBarry Smith     if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) {
1110289bc588SBarry Smith       for (i=0; i<m; i++) {
11113bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
111255a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
1113289bc588SBarry Smith       }
1114289bc588SBarry Smith     }
1115fccaa45eSBarry Smith     if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) {
1116289bc588SBarry Smith       for (i=m-1; i>=0; i--) {
11173bffc371SBarry Smith         PetscStackCallBLAS("BLASdotu",xt   = b[i] - BLASdotu_(&bm,v+i,&bm,x,&o));
111855a1b374SBarry Smith         x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift);
1119289bc588SBarry Smith       }
1120289bc588SBarry Smith     }
1121289bc588SBarry Smith   }
11229566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(bb,&b));
11239566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(xx,&x));
11243a40ed3dSBarry Smith   PetscFunctionReturn(0);
1125289bc588SBarry Smith }
1126289bc588SBarry Smith 
1127289bc588SBarry Smith /* -----------------------------------------------------------------*/
1128ca15aa20SStefano Zampini PetscErrorCode MatMultTranspose_SeqDense(Mat A,Vec xx,Vec yy)
1129289bc588SBarry Smith {
1130c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1131d9ca1df4SBarry Smith   const PetscScalar *v   = mat->v,*x;
1132d9ca1df4SBarry Smith   PetscScalar       *y;
11330805154bSBarry Smith   PetscBLASInt      m, n,_One=1;
1134ea709b57SSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
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<n; i++) y[i] = 0.0;
11445ac36cfcSBarry Smith   } else {
11458b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&mat->lda,x,&_One,&_DZero,y,&_One));
11469566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->cmap->n));
11475ac36cfcSBarry Smith   }
11489566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx,&x));
11499566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayWrite(yy,&y));
11503a40ed3dSBarry Smith   PetscFunctionReturn(0);
1151289bc588SBarry Smith }
1152800995b7SMatthew Knepley 
1153ca15aa20SStefano Zampini PetscErrorCode MatMult_SeqDense(Mat A,Vec xx,Vec yy)
1154289bc588SBarry Smith {
1155c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1156d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0,_DZero=0.0;
11570805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
1158d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
11593a40ed3dSBarry Smith 
11603a40ed3dSBarry Smith   PetscFunctionBegin;
11619566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
11629566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
11639566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx,&x));
11649566063dSJacob Faibussowitsch   PetscCall(VecGetArrayWrite(yy,&y));
11655ac36cfcSBarry Smith   if (!A->rmap->n || !A->cmap->n) {
11665ac36cfcSBarry Smith     PetscBLASInt i;
11675ac36cfcSBarry Smith     for (i=0; i<m; i++) y[i] = 0.0;
11685ac36cfcSBarry Smith   } else {
11698b83055fSJed Brown     PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DZero,y,&_One));
11709566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->rmap->n));
11715ac36cfcSBarry Smith   }
11729566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx,&x));
11739566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayWrite(yy,&y));
11743a40ed3dSBarry Smith   PetscFunctionReturn(0);
1175289bc588SBarry Smith }
11766ee01492SSatish Balay 
1177ca15aa20SStefano Zampini PetscErrorCode MatMultAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
1178289bc588SBarry Smith {
1179c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1180d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
1181d9ca1df4SBarry Smith   PetscScalar       *y,_DOne=1.0;
11820805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
11833a40ed3dSBarry Smith 
11843a40ed3dSBarry Smith   PetscFunctionBegin;
11859566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
11869566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
11879566063dSJacob Faibussowitsch   PetscCall(VecCopy(zz,yy));
1188d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
11899566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx,&x));
11909566063dSJacob Faibussowitsch   PetscCall(VecGetArray(yy,&y));
11918b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
11929566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx,&x));
11939566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(yy,&y));
11949566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0*A->rmap->n*A->cmap->n));
11953a40ed3dSBarry Smith   PetscFunctionReturn(0);
1196289bc588SBarry Smith }
11976ee01492SSatish Balay 
1198ca15aa20SStefano Zampini PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy)
1199289bc588SBarry Smith {
1200c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1201d9ca1df4SBarry Smith   const PetscScalar *v = mat->v,*x;
1202d9ca1df4SBarry Smith   PetscScalar       *y;
12030805154bSBarry Smith   PetscBLASInt      m, n, _One=1;
120487828ca2SBarry Smith   PetscScalar       _DOne=1.0;
12053a40ed3dSBarry Smith 
12063a40ed3dSBarry Smith   PetscFunctionBegin;
12079566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&m));
12089566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&n));
12099566063dSJacob Faibussowitsch   PetscCall(VecCopy(zz,yy));
1210d0f46423SBarry Smith   if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0);
12119566063dSJacob Faibussowitsch   PetscCall(VecGetArrayRead(xx,&x));
12129566063dSJacob Faibussowitsch   PetscCall(VecGetArray(yy,&y));
12138b83055fSJed Brown   PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One));
12149566063dSJacob Faibussowitsch   PetscCall(VecRestoreArrayRead(xx,&x));
12159566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(yy,&y));
12169566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(2.0*A->rmap->n*A->cmap->n));
12173a40ed3dSBarry Smith   PetscFunctionReturn(0);
1218289bc588SBarry Smith }
1219289bc588SBarry Smith 
1220289bc588SBarry Smith /* -----------------------------------------------------------------*/
1221e0877f53SBarry Smith static PetscErrorCode MatGetRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
1222289bc588SBarry Smith {
1223c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
122413f74950SBarry Smith   PetscInt       i;
122567e560aaSBarry Smith 
12263a40ed3dSBarry Smith   PetscFunctionBegin;
1227d0f46423SBarry Smith   *ncols = A->cmap->n;
1228289bc588SBarry Smith   if (cols) {
12299566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(A->cmap->n,cols));
1230d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) (*cols)[i] = i;
1231289bc588SBarry Smith   }
1232289bc588SBarry Smith   if (vals) {
1233ca15aa20SStefano Zampini     const PetscScalar *v;
1234ca15aa20SStefano Zampini 
12359566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A,&v));
12369566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(A->cmap->n,vals));
1237ca15aa20SStefano Zampini     v   += row;
1238d0f46423SBarry Smith     for (i=0; i<A->cmap->n; i++) {(*vals)[i] = *v; v += mat->lda;}
12399566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A,&v));
1240289bc588SBarry Smith   }
12413a40ed3dSBarry Smith   PetscFunctionReturn(0);
1242289bc588SBarry Smith }
12436ee01492SSatish Balay 
1244e0877f53SBarry Smith static PetscErrorCode MatRestoreRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals)
1245289bc588SBarry Smith {
1246606d414cSSatish Balay   PetscFunctionBegin;
1247cb4a9cd9SHong Zhang   if (ncols) *ncols = 0;
12489566063dSJacob Faibussowitsch   if (cols) PetscCall(PetscFree(*cols));
12499566063dSJacob Faibussowitsch   if (vals) PetscCall(PetscFree(*vals));
12503a40ed3dSBarry Smith   PetscFunctionReturn(0);
1251289bc588SBarry Smith }
1252289bc588SBarry Smith /* ----------------------------------------------------------------*/
1253e0877f53SBarry Smith static PetscErrorCode MatSetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],const PetscScalar v[],InsertMode addv)
1254289bc588SBarry Smith {
1255c0bbcb79SLois Curfman McInnes   Mat_SeqDense     *mat = (Mat_SeqDense*)A->data;
1256ca15aa20SStefano Zampini   PetscScalar      *av;
125713f74950SBarry Smith   PetscInt         i,j,idx=0;
1258ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1259c70f7ee4SJunchao Zhang   PetscOffloadMask oldf;
1260ca15aa20SStefano Zampini #endif
1261d6dfbf8fSBarry Smith 
12623a40ed3dSBarry Smith   PetscFunctionBegin;
12639566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&av));
1264289bc588SBarry Smith   if (!mat->roworiented) {
1265dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1266289bc588SBarry Smith       for (j=0; j<n; j++) {
1267cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
12686bdcaf15SBarry 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);
1269289bc588SBarry Smith         for (i=0; i<m; i++) {
1270cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
12716bdcaf15SBarry 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);
1272ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
1273289bc588SBarry Smith         }
1274289bc588SBarry Smith       }
12753a40ed3dSBarry Smith     } else {
1276289bc588SBarry Smith       for (j=0; j<n; j++) {
1277cddbea37SSatish Balay         if (indexn[j] < 0) {idx += m; continue;}
12786bdcaf15SBarry 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);
1279289bc588SBarry Smith         for (i=0; i<m; i++) {
1280cddbea37SSatish Balay           if (indexm[i] < 0) {idx++; continue;}
12816bdcaf15SBarry Smith           PetscCheck(indexm[i] < A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %" PetscInt_FMT " max %" PetscInt_FMT,indexm[i],A->rmap->n-1);
1282ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
1283289bc588SBarry Smith         }
1284289bc588SBarry Smith       }
1285289bc588SBarry Smith     }
12863a40ed3dSBarry Smith   } else {
1287dbb450caSBarry Smith     if (addv == INSERT_VALUES) {
1288e8d4e0b9SBarry Smith       for (i=0; i<m; i++) {
1289cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
12906bdcaf15SBarry 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);
1291e8d4e0b9SBarry Smith         for (j=0; j<n; j++) {
1292cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
12936bdcaf15SBarry 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);
1294ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] = v[idx++];
1295e8d4e0b9SBarry Smith         }
1296e8d4e0b9SBarry Smith       }
12973a40ed3dSBarry Smith     } else {
1298289bc588SBarry Smith       for (i=0; i<m; i++) {
1299cddbea37SSatish Balay         if (indexm[i] < 0) { idx += n; continue;}
13006bdcaf15SBarry 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);
1301289bc588SBarry Smith         for (j=0; j<n; j++) {
1302cddbea37SSatish Balay           if (indexn[j] < 0) { idx++; continue;}
13036bdcaf15SBarry Smith           PetscCheck(indexn[j] < A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %" PetscInt_FMT " max %" PetscInt_FMT,indexn[j],A->cmap->n-1);
1304ca15aa20SStefano Zampini           av[indexn[j]*mat->lda + indexm[i]] += v[idx++];
1305289bc588SBarry Smith         }
1306289bc588SBarry Smith       }
1307289bc588SBarry Smith     }
1308e8d4e0b9SBarry Smith   }
1309ca15aa20SStefano Zampini   /* hack to prevent unneeded copy to the GPU while returning the array */
1310ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1311c70f7ee4SJunchao Zhang   oldf = A->offloadmask;
1312c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_GPU;
1313ca15aa20SStefano Zampini #endif
13149566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&av));
1315ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1316c70f7ee4SJunchao Zhang   A->offloadmask = (oldf == PETSC_OFFLOAD_UNALLOCATED ? PETSC_OFFLOAD_UNALLOCATED : PETSC_OFFLOAD_CPU);
1317ca15aa20SStefano Zampini #endif
13183a40ed3dSBarry Smith   PetscFunctionReturn(0);
1319289bc588SBarry Smith }
1320e8d4e0b9SBarry Smith 
1321e0877f53SBarry Smith static PetscErrorCode MatGetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],PetscScalar v[])
1322ae80bb75SLois Curfman McInnes {
1323ae80bb75SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1324ca15aa20SStefano Zampini   const PetscScalar *vv;
132513f74950SBarry Smith   PetscInt          i,j;
1326ae80bb75SLois Curfman McInnes 
13273a40ed3dSBarry Smith   PetscFunctionBegin;
13289566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&vv));
1329ae80bb75SLois Curfman McInnes   /* row-oriented output */
1330ae80bb75SLois Curfman McInnes   for (i=0; i<m; i++) {
133197e567efSBarry Smith     if (indexm[i] < 0) {v += n;continue;}
133208401ef6SPierre 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);
1333ae80bb75SLois Curfman McInnes     for (j=0; j<n; j++) {
13346f31f424SBarry Smith       if (indexn[j] < 0) {v++; continue;}
133508401ef6SPierre 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);
1336ca15aa20SStefano Zampini       *v++ = vv[indexn[j]*mat->lda + indexm[i]];
1337ae80bb75SLois Curfman McInnes     }
1338ae80bb75SLois Curfman McInnes   }
13399566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&vv));
13403a40ed3dSBarry Smith   PetscFunctionReturn(0);
1341ae80bb75SLois Curfman McInnes }
1342ae80bb75SLois Curfman McInnes 
1343289bc588SBarry Smith /* -----------------------------------------------------------------*/
1344289bc588SBarry Smith 
13458491ab44SLisandro Dalcin PetscErrorCode MatView_Dense_Binary(Mat mat,PetscViewer viewer)
1346aabbc4fbSShri Abhyankar {
13478491ab44SLisandro Dalcin   PetscBool         skipHeader;
13488491ab44SLisandro Dalcin   PetscViewerFormat format;
13498491ab44SLisandro Dalcin   PetscInt          header[4],M,N,m,lda,i,j,k;
13508491ab44SLisandro Dalcin   const PetscScalar *v;
13518491ab44SLisandro Dalcin   PetscScalar       *vwork;
1352aabbc4fbSShri Abhyankar 
1353aabbc4fbSShri Abhyankar   PetscFunctionBegin;
13549566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
13559566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryGetSkipHeader(viewer,&skipHeader));
13569566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer,&format));
13578491ab44SLisandro Dalcin   if (skipHeader) format = PETSC_VIEWER_NATIVE;
1358aabbc4fbSShri Abhyankar 
13599566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat,&M,&N));
13608491ab44SLisandro Dalcin 
13618491ab44SLisandro Dalcin   /* write matrix header */
13628491ab44SLisandro Dalcin   header[0] = MAT_FILE_CLASSID; header[1] = M; header[2] = N;
13638491ab44SLisandro Dalcin   header[3] = (format == PETSC_VIEWER_NATIVE) ? MATRIX_BINARY_FORMAT_DENSE : M*N;
13649566063dSJacob Faibussowitsch   if (!skipHeader) PetscCall(PetscViewerBinaryWrite(viewer,header,4,PETSC_INT));
13658491ab44SLisandro Dalcin 
13669566063dSJacob Faibussowitsch   PetscCall(MatGetLocalSize(mat,&m,NULL));
13678491ab44SLisandro Dalcin   if (format != PETSC_VIEWER_NATIVE) {
13688491ab44SLisandro Dalcin     PetscInt nnz = m*N, *iwork;
13698491ab44SLisandro Dalcin     /* store row lengths for each row */
13709566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nnz,&iwork));
13718491ab44SLisandro Dalcin     for (i=0; i<m; i++) iwork[i] = N;
13729566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWriteAll(viewer,iwork,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT));
13738491ab44SLisandro Dalcin     /* store column indices (zero start index) */
13748491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
13758491ab44SLisandro Dalcin       for (j=0; j<N; j++, k++)
13768491ab44SLisandro Dalcin         iwork[k] = j;
13779566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryWriteAll(viewer,iwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT));
13789566063dSJacob Faibussowitsch     PetscCall(PetscFree(iwork));
13798491ab44SLisandro Dalcin   }
13808491ab44SLisandro Dalcin   /* store matrix values as a dense matrix in row major order */
13819566063dSJacob Faibussowitsch   PetscCall(PetscMalloc1(m*N,&vwork));
13829566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(mat,&v));
13839566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(mat,&lda));
13848491ab44SLisandro Dalcin   for (k=0, i=0; i<m; i++)
13858491ab44SLisandro Dalcin     for (j=0; j<N; j++, k++)
13868491ab44SLisandro Dalcin       vwork[k] = v[i+lda*j];
13879566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(mat,&v));
13889566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryWriteAll(viewer,vwork,m*N,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR));
13899566063dSJacob Faibussowitsch   PetscCall(PetscFree(vwork));
13908491ab44SLisandro Dalcin   PetscFunctionReturn(0);
13918491ab44SLisandro Dalcin }
13928491ab44SLisandro Dalcin 
13938491ab44SLisandro Dalcin PetscErrorCode MatLoad_Dense_Binary(Mat mat,PetscViewer viewer)
13948491ab44SLisandro Dalcin {
13958491ab44SLisandro Dalcin   PetscBool      skipHeader;
13968491ab44SLisandro Dalcin   PetscInt       header[4],M,N,m,nz,lda,i,j,k;
13978491ab44SLisandro Dalcin   PetscInt       rows,cols;
13988491ab44SLisandro Dalcin   PetscScalar    *v,*vwork;
13998491ab44SLisandro Dalcin 
14008491ab44SLisandro Dalcin   PetscFunctionBegin;
14019566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
14029566063dSJacob Faibussowitsch   PetscCall(PetscViewerBinaryGetSkipHeader(viewer,&skipHeader));
14038491ab44SLisandro Dalcin 
14048491ab44SLisandro Dalcin   if (!skipHeader) {
14059566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryRead(viewer,header,4,NULL,PETSC_INT));
140608401ef6SPierre Jolivet     PetscCheck(header[0] == MAT_FILE_CLASSID,PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Not a matrix object in file");
14078491ab44SLisandro Dalcin     M = header[1]; N = header[2];
140808401ef6SPierre Jolivet     PetscCheck(M >= 0,PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix row size (%" PetscInt_FMT ") in file is negative",M);
140908401ef6SPierre Jolivet     PetscCheck(N >= 0,PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Matrix column size (%" PetscInt_FMT ") in file is negative",N);
14108491ab44SLisandro Dalcin     nz = header[3];
1411aed4548fSBarry Smith     PetscCheck(nz == MATRIX_BINARY_FORMAT_DENSE || nz >= 0,PetscObjectComm((PetscObject)viewer),PETSC_ERR_FILE_UNEXPECTED,"Unknown matrix format %" PetscInt_FMT " in file",nz);
1412aabbc4fbSShri Abhyankar   } else {
14139566063dSJacob Faibussowitsch     PetscCall(MatGetSize(mat,&M,&N));
1414aed4548fSBarry 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");
14158491ab44SLisandro Dalcin     nz = MATRIX_BINARY_FORMAT_DENSE;
1416e6324fbbSBarry Smith   }
1417aabbc4fbSShri Abhyankar 
14188491ab44SLisandro Dalcin   /* setup global sizes if not set */
14198491ab44SLisandro Dalcin   if (mat->rmap->N < 0) mat->rmap->N = M;
14208491ab44SLisandro Dalcin   if (mat->cmap->N < 0) mat->cmap->N = N;
14219566063dSJacob Faibussowitsch   PetscCall(MatSetUp(mat));
14228491ab44SLisandro Dalcin   /* check if global sizes are correct */
14239566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat,&rows,&cols));
1424aed4548fSBarry 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);
1425aabbc4fbSShri Abhyankar 
14269566063dSJacob Faibussowitsch   PetscCall(MatGetSize(mat,NULL,&N));
14279566063dSJacob Faibussowitsch   PetscCall(MatGetLocalSize(mat,&m,NULL));
14289566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(mat,&v));
14299566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(mat,&lda));
14308491ab44SLisandro Dalcin   if (nz == MATRIX_BINARY_FORMAT_DENSE) {  /* matrix in file is dense format */
14318491ab44SLisandro Dalcin     PetscInt nnz = m*N;
14328491ab44SLisandro Dalcin     /* read in matrix values */
14339566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(nnz,&vwork));
14349566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR));
14358491ab44SLisandro Dalcin     /* store values in column major order */
14368491ab44SLisandro Dalcin     for (j=0; j<N; j++)
14378491ab44SLisandro Dalcin       for (i=0; i<m; i++)
14388491ab44SLisandro Dalcin         v[i+lda*j] = vwork[i*N+j];
14399566063dSJacob Faibussowitsch     PetscCall(PetscFree(vwork));
14408491ab44SLisandro Dalcin   } else { /* matrix in file is sparse format */
14418491ab44SLisandro Dalcin     PetscInt nnz = 0, *rlens, *icols;
14428491ab44SLisandro Dalcin     /* read in row lengths */
14439566063dSJacob Faibussowitsch     PetscCall(PetscMalloc1(m,&rlens));
14449566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer,rlens,m,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT));
14458491ab44SLisandro Dalcin     for (i=0; i<m; i++) nnz += rlens[i];
14468491ab44SLisandro Dalcin     /* read in column indices and values */
14479566063dSJacob Faibussowitsch     PetscCall(PetscMalloc2(nnz,&icols,nnz,&vwork));
14489566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer,icols,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_INT));
14499566063dSJacob Faibussowitsch     PetscCall(PetscViewerBinaryReadAll(viewer,vwork,nnz,PETSC_DETERMINE,PETSC_DETERMINE,PETSC_SCALAR));
14508491ab44SLisandro Dalcin     /* store values in column major order */
14518491ab44SLisandro Dalcin     for (k=0, i=0; i<m; i++)
14528491ab44SLisandro Dalcin       for (j=0; j<rlens[i]; j++, k++)
14538491ab44SLisandro Dalcin         v[i+lda*icols[k]] = vwork[k];
14549566063dSJacob Faibussowitsch     PetscCall(PetscFree(rlens));
14559566063dSJacob Faibussowitsch     PetscCall(PetscFree2(icols,vwork));
1456aabbc4fbSShri Abhyankar   }
14579566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(mat,&v));
14589566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(mat,MAT_FINAL_ASSEMBLY));
14599566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(mat,MAT_FINAL_ASSEMBLY));
1460aabbc4fbSShri Abhyankar   PetscFunctionReturn(0);
1461aabbc4fbSShri Abhyankar }
1462aabbc4fbSShri Abhyankar 
1463eb91f321SVaclav Hapla PetscErrorCode MatLoad_SeqDense(Mat newMat, PetscViewer viewer)
1464eb91f321SVaclav Hapla {
1465eb91f321SVaclav Hapla   PetscBool      isbinary, ishdf5;
1466eb91f321SVaclav Hapla 
1467eb91f321SVaclav Hapla   PetscFunctionBegin;
1468eb91f321SVaclav Hapla   PetscValidHeaderSpecific(newMat,MAT_CLASSID,1);
1469eb91f321SVaclav Hapla   PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2);
1470eb91f321SVaclav Hapla   /* force binary viewer to load .info file if it has not yet done so */
14719566063dSJacob Faibussowitsch   PetscCall(PetscViewerSetUp(viewer));
14729566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary));
14739566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERHDF5,  &ishdf5));
1474eb91f321SVaclav Hapla   if (isbinary) {
14759566063dSJacob Faibussowitsch     PetscCall(MatLoad_Dense_Binary(newMat,viewer));
1476eb91f321SVaclav Hapla   } else if (ishdf5) {
1477eb91f321SVaclav Hapla #if defined(PETSC_HAVE_HDF5)
14789566063dSJacob Faibussowitsch     PetscCall(MatLoad_Dense_HDF5(newMat,viewer));
1479eb91f321SVaclav Hapla #else
1480eb91f321SVaclav Hapla     SETERRQ(PetscObjectComm((PetscObject)newMat),PETSC_ERR_SUP,"HDF5 not supported in this build.\nPlease reconfigure using --download-hdf5");
1481eb91f321SVaclav Hapla #endif
1482eb91f321SVaclav Hapla   } else {
148398921bdaSJacob 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);
1484eb91f321SVaclav Hapla   }
1485eb91f321SVaclav Hapla   PetscFunctionReturn(0);
1486eb91f321SVaclav Hapla }
1487eb91f321SVaclav Hapla 
14886849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_ASCII(Mat A,PetscViewer viewer)
1489289bc588SBarry Smith {
1490932b0c3eSLois Curfman McInnes   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
149113f74950SBarry Smith   PetscInt          i,j;
14922dcb1b2aSMatthew Knepley   const char        *name;
1493ca15aa20SStefano Zampini   PetscScalar       *v,*av;
1494f3ef73ceSBarry Smith   PetscViewerFormat format;
14955f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX)
1496ace3abfcSBarry Smith   PetscBool         allreal = PETSC_TRUE;
14975f481a85SSatish Balay #endif
1498932b0c3eSLois Curfman McInnes 
14993a40ed3dSBarry Smith   PetscFunctionBegin;
15009566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,(const PetscScalar**)&av));
15019566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer,&format));
1502456192e2SBarry Smith   if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) {
15033a40ed3dSBarry Smith     PetscFunctionReturn(0);  /* do nothing for now */
1504fb9695e5SSatish Balay   } else if (format == PETSC_VIEWER_ASCII_COMMON) {
15059566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE));
1506d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1507ca15aa20SStefano Zampini       v    = av + i;
15089566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"row %" PetscInt_FMT ":",i));
1509d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1510aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
1511329f5518SBarry Smith         if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) {
15129566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g + %g i) ",j,(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v)));
1513329f5518SBarry Smith         } else if (PetscRealPart(*v)) {
15149566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g) ",j,(double)PetscRealPart(*v)));
15156831982aSBarry Smith         }
151680cd9d93SLois Curfman McInnes #else
15176831982aSBarry Smith         if (*v) {
15189566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer," (%" PetscInt_FMT ", %g) ",j,(double)*v));
15196831982aSBarry Smith         }
152080cd9d93SLois Curfman McInnes #endif
15211b807ce4Svictorle         v += a->lda;
152280cd9d93SLois Curfman McInnes       }
15239566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"\n"));
152480cd9d93SLois Curfman McInnes     }
15259566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE));
15263a40ed3dSBarry Smith   } else {
15279566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_FALSE));
1528aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
152947989497SBarry Smith     /* determine if matrix has all real values */
1530ca15aa20SStefano Zampini     v = av;
1531d0f46423SBarry Smith     for (i=0; i<A->rmap->n*A->cmap->n; i++) {
1532ffac6cdbSBarry Smith       if (PetscImaginaryPart(v[i])) { allreal = PETSC_FALSE; break;}
153347989497SBarry Smith     }
153447989497SBarry Smith #endif
1535fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
15369566063dSJacob Faibussowitsch       PetscCall(PetscObjectGetName((PetscObject)A,&name));
15379566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"%% Size = %" PetscInt_FMT " %" PetscInt_FMT " \n",A->rmap->n,A->cmap->n));
15389566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"%s = zeros(%" PetscInt_FMT ",%" PetscInt_FMT ");\n",name,A->rmap->n,A->cmap->n));
15399566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"%s = [\n",name));
1540ffac6cdbSBarry Smith     }
1541ffac6cdbSBarry Smith 
1542d0f46423SBarry Smith     for (i=0; i<A->rmap->n; i++) {
1543ca15aa20SStefano Zampini       v = av + i;
1544d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1545aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX)
154647989497SBarry Smith         if (allreal) {
15479566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)PetscRealPart(*v)));
154847989497SBarry Smith         } else {
15499566063dSJacob Faibussowitsch           PetscCall(PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ei ",(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v)));
155047989497SBarry Smith         }
1551289bc588SBarry Smith #else
15529566063dSJacob Faibussowitsch         PetscCall(PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)*v));
1553289bc588SBarry Smith #endif
15541b807ce4Svictorle         v += a->lda;
1555289bc588SBarry Smith       }
15569566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"\n"));
1557289bc588SBarry Smith     }
1558fb9695e5SSatish Balay     if (format == PETSC_VIEWER_ASCII_MATLAB) {
15599566063dSJacob Faibussowitsch       PetscCall(PetscViewerASCIIPrintf(viewer,"];\n"));
1560ffac6cdbSBarry Smith     }
15619566063dSJacob Faibussowitsch     PetscCall(PetscViewerASCIIUseTabs(viewer,PETSC_TRUE));
1562da3a660dSBarry Smith   }
15639566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,(const PetscScalar**)&av));
15649566063dSJacob Faibussowitsch   PetscCall(PetscViewerFlush(viewer));
15653a40ed3dSBarry Smith   PetscFunctionReturn(0);
1566289bc588SBarry Smith }
1567289bc588SBarry Smith 
15689804daf3SBarry Smith #include <petscdraw.h>
1569e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw,void *Aa)
1570f1af5d2fSBarry Smith {
1571f1af5d2fSBarry Smith   Mat               A  = (Mat) Aa;
1572383922c3SLisandro Dalcin   PetscInt          m  = A->rmap->n,n = A->cmap->n,i,j;
1573383922c3SLisandro Dalcin   int               color = PETSC_DRAW_WHITE;
1574ca15aa20SStefano Zampini   const PetscScalar *v;
1575b0a32e0cSBarry Smith   PetscViewer       viewer;
1576b05fc000SLisandro Dalcin   PetscReal         xl,yl,xr,yr,x_l,x_r,y_l,y_r;
1577f3ef73ceSBarry Smith   PetscViewerFormat format;
1578f1af5d2fSBarry Smith 
1579f1af5d2fSBarry Smith   PetscFunctionBegin;
15809566063dSJacob Faibussowitsch   PetscCall(PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer));
15819566063dSJacob Faibussowitsch   PetscCall(PetscViewerGetFormat(viewer,&format));
15829566063dSJacob Faibussowitsch   PetscCall(PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr));
1583f1af5d2fSBarry Smith 
1584f1af5d2fSBarry Smith   /* Loop over matrix elements drawing boxes */
15859566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&v));
1586fb9695e5SSatish Balay   if (format != PETSC_VIEWER_DRAW_CONTOUR) {
1587d0609cedSBarry Smith     PetscDrawCollectiveBegin(draw);
1588f1af5d2fSBarry Smith     /* Blue for negative and Red for positive */
1589f1af5d2fSBarry Smith     for (j = 0; j < n; j++) {
1590383922c3SLisandro Dalcin       x_l = j; x_r = x_l + 1.0;
1591f1af5d2fSBarry Smith       for (i = 0; i < m; i++) {
1592f1af5d2fSBarry Smith         y_l = m - i - 1.0;
1593f1af5d2fSBarry Smith         y_r = y_l + 1.0;
1594ca15aa20SStefano Zampini         if (PetscRealPart(v[j*m+i]) >  0.) color = PETSC_DRAW_RED;
1595ca15aa20SStefano Zampini         else if (PetscRealPart(v[j*m+i]) <  0.) color = PETSC_DRAW_BLUE;
1596ca15aa20SStefano Zampini         else continue;
15979566063dSJacob Faibussowitsch         PetscCall(PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color));
1598f1af5d2fSBarry Smith       }
1599f1af5d2fSBarry Smith     }
1600d0609cedSBarry Smith     PetscDrawCollectiveEnd(draw);
1601f1af5d2fSBarry Smith   } else {
1602f1af5d2fSBarry Smith     /* use contour shading to indicate magnitude of values */
1603f1af5d2fSBarry Smith     /* first determine max of all nonzero values */
1604b05fc000SLisandro Dalcin     PetscReal minv = 0.0, maxv = 0.0;
1605b05fc000SLisandro Dalcin     PetscDraw popup;
1606b05fc000SLisandro Dalcin 
1607f1af5d2fSBarry Smith     for (i=0; i < m*n; i++) {
1608f1af5d2fSBarry Smith       if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]);
1609f1af5d2fSBarry Smith     }
1610383922c3SLisandro Dalcin     if (minv >= maxv) maxv = minv + PETSC_SMALL;
16119566063dSJacob Faibussowitsch     PetscCall(PetscDrawGetPopup(draw,&popup));
16129566063dSJacob Faibussowitsch     PetscCall(PetscDrawScalePopup(popup,minv,maxv));
1613383922c3SLisandro Dalcin 
1614d0609cedSBarry Smith     PetscDrawCollectiveBegin(draw);
1615f1af5d2fSBarry Smith     for (j=0; j<n; j++) {
1616f1af5d2fSBarry Smith       x_l = j;
1617f1af5d2fSBarry Smith       x_r = x_l + 1.0;
1618f1af5d2fSBarry Smith       for (i=0; i<m; i++) {
1619f1af5d2fSBarry Smith         y_l   = m - i - 1.0;
1620f1af5d2fSBarry Smith         y_r   = y_l + 1.0;
1621b05fc000SLisandro Dalcin         color = PetscDrawRealToColor(PetscAbsScalar(v[j*m+i]),minv,maxv);
16229566063dSJacob Faibussowitsch         PetscCall(PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color));
1623f1af5d2fSBarry Smith       }
1624f1af5d2fSBarry Smith     }
1625d0609cedSBarry Smith     PetscDrawCollectiveEnd(draw);
1626f1af5d2fSBarry Smith   }
16279566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&v));
1628f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1629f1af5d2fSBarry Smith }
1630f1af5d2fSBarry Smith 
1631e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw(Mat A,PetscViewer viewer)
1632f1af5d2fSBarry Smith {
1633b0a32e0cSBarry Smith   PetscDraw      draw;
1634ace3abfcSBarry Smith   PetscBool      isnull;
1635329f5518SBarry Smith   PetscReal      xr,yr,xl,yl,h,w;
1636f1af5d2fSBarry Smith 
1637f1af5d2fSBarry Smith   PetscFunctionBegin;
16389566063dSJacob Faibussowitsch   PetscCall(PetscViewerDrawGetDraw(viewer,0,&draw));
16399566063dSJacob Faibussowitsch   PetscCall(PetscDrawIsNull(draw,&isnull));
1640abc0a331SBarry Smith   if (isnull) PetscFunctionReturn(0);
1641f1af5d2fSBarry Smith 
1642d0f46423SBarry Smith   xr   = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0;
1643f1af5d2fSBarry Smith   xr  += w;          yr += h;        xl = -w;     yl = -h;
16449566063dSJacob Faibussowitsch   PetscCall(PetscDrawSetCoordinates(draw,xl,yl,xr,yr));
16459566063dSJacob Faibussowitsch   PetscCall(PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer));
16469566063dSJacob Faibussowitsch   PetscCall(PetscDrawZoom(draw,MatView_SeqDense_Draw_Zoom,A));
16479566063dSJacob Faibussowitsch   PetscCall(PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL));
16489566063dSJacob Faibussowitsch   PetscCall(PetscDrawSave(draw));
1649f1af5d2fSBarry Smith   PetscFunctionReturn(0);
1650f1af5d2fSBarry Smith }
1651f1af5d2fSBarry Smith 
1652dfbe8321SBarry Smith PetscErrorCode MatView_SeqDense(Mat A,PetscViewer viewer)
1653932b0c3eSLois Curfman McInnes {
1654ace3abfcSBarry Smith   PetscBool      iascii,isbinary,isdraw;
1655932b0c3eSLois Curfman McInnes 
16563a40ed3dSBarry Smith   PetscFunctionBegin;
16579566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii));
16589566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary));
16599566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw));
1660c45a1595SBarry Smith   if (iascii) {
16619566063dSJacob Faibussowitsch     PetscCall(MatView_SeqDense_ASCII(A,viewer));
16620f5bd95cSBarry Smith   } else if (isbinary) {
16639566063dSJacob Faibussowitsch     PetscCall(MatView_Dense_Binary(A,viewer));
1664f1af5d2fSBarry Smith   } else if (isdraw) {
16659566063dSJacob Faibussowitsch     PetscCall(MatView_SeqDense_Draw(A,viewer));
1666932b0c3eSLois Curfman McInnes   }
16673a40ed3dSBarry Smith   PetscFunctionReturn(0);
1668932b0c3eSLois Curfman McInnes }
1669289bc588SBarry Smith 
1670637a0070SStefano Zampini static PetscErrorCode MatDensePlaceArray_SeqDense(Mat A,const PetscScalar *array)
1671d3042a70SBarry Smith {
1672d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1673d3042a70SBarry Smith 
1674d3042a70SBarry Smith   PetscFunctionBegin;
167528b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
167628b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
167728b400f6SJacob Faibussowitsch   PetscCheck(!a->unplacedarray,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreArray() first");
1678d3042a70SBarry Smith   a->unplacedarray       = a->v;
1679d3042a70SBarry Smith   a->unplaced_user_alloc = a->user_alloc;
1680d3042a70SBarry Smith   a->v                   = (PetscScalar*) array;
1681637a0070SStefano Zampini   a->user_alloc          = PETSC_TRUE;
1682ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1683c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1684ca15aa20SStefano Zampini #endif
1685d3042a70SBarry Smith   PetscFunctionReturn(0);
1686d3042a70SBarry Smith }
1687d3042a70SBarry Smith 
1688d3042a70SBarry Smith static PetscErrorCode MatDenseResetArray_SeqDense(Mat A)
1689d3042a70SBarry Smith {
1690d3042a70SBarry Smith   Mat_SeqDense *a = (Mat_SeqDense*)A->data;
1691d3042a70SBarry Smith 
1692d3042a70SBarry Smith   PetscFunctionBegin;
169328b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
169428b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
1695d3042a70SBarry Smith   a->v             = a->unplacedarray;
1696d3042a70SBarry Smith   a->user_alloc    = a->unplaced_user_alloc;
1697d3042a70SBarry Smith   a->unplacedarray = NULL;
1698ca15aa20SStefano Zampini #if defined(PETSC_HAVE_CUDA)
1699c70f7ee4SJunchao Zhang   A->offloadmask = PETSC_OFFLOAD_CPU;
1700ca15aa20SStefano Zampini #endif
1701d3042a70SBarry Smith   PetscFunctionReturn(0);
1702d3042a70SBarry Smith }
1703d3042a70SBarry Smith 
1704d5ea218eSStefano Zampini static PetscErrorCode MatDenseReplaceArray_SeqDense(Mat A,const PetscScalar *array)
1705d5ea218eSStefano Zampini {
1706d5ea218eSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
1707d5ea218eSStefano Zampini 
1708d5ea218eSStefano Zampini   PetscFunctionBegin;
170928b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
171028b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
17119566063dSJacob Faibussowitsch   if (!a->user_alloc) PetscCall(PetscFree(a->v));
1712d5ea218eSStefano Zampini   a->v           = (PetscScalar*) array;
1713d5ea218eSStefano Zampini   a->user_alloc  = PETSC_FALSE;
1714d5ea218eSStefano Zampini #if defined(PETSC_HAVE_CUDA)
1715d5ea218eSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
1716d5ea218eSStefano Zampini #endif
1717d5ea218eSStefano Zampini   PetscFunctionReturn(0);
1718d5ea218eSStefano Zampini }
1719d5ea218eSStefano Zampini 
1720ca15aa20SStefano Zampini PetscErrorCode MatDestroy_SeqDense(Mat mat)
1721289bc588SBarry Smith {
1722ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)mat->data;
172390f02eecSBarry Smith 
17243a40ed3dSBarry Smith   PetscFunctionBegin;
1725aa482453SBarry Smith #if defined(PETSC_USE_LOG)
1726c0aa6a63SJacob Faibussowitsch   PetscLogObjectState((PetscObject)mat,"Rows %" PetscInt_FMT " Cols %" PetscInt_FMT,mat->rmap->n,mat->cmap->n);
1727a5a9c739SBarry Smith #endif
17289566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&(l->qrrhs)));
17299566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->tau));
17309566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->pivots));
17319566063dSJacob Faibussowitsch   PetscCall(PetscFree(l->fwork));
17329566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&l->ptapwork));
17339566063dSJacob Faibussowitsch   if (!l->user_alloc) PetscCall(PetscFree(l->v));
17349566063dSJacob Faibussowitsch   if (!l->unplaced_user_alloc) PetscCall(PetscFree(l->unplacedarray));
173528b400f6SJacob Faibussowitsch   PetscCheck(!l->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
173628b400f6SJacob Faibussowitsch   PetscCheck(!l->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
17379566063dSJacob Faibussowitsch   PetscCall(VecDestroy(&l->cvec));
17389566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&l->cmat));
17399566063dSJacob Faibussowitsch   PetscCall(PetscFree(mat->data));
1740dbd8c25aSHong Zhang 
17419566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)mat,NULL));
17429566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatQRFactor_C",NULL));
17439566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetLDA_C",NULL));
17449566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseSetLDA_C",NULL));
17459566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArray_C",NULL));
17469566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArray_C",NULL));
17479566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDensePlaceArray_C",NULL));
17489566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseResetArray_C",NULL));
17499566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseReplaceArray_C",NULL));
17509566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArrayRead_C",NULL));
17519566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArrayRead_C",NULL));
17529566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArrayWrite_C",NULL));
17539566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArrayWrite_C",NULL));
17549566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqaij_C",NULL));
17558baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
17569566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_elemental_C",NULL));
17578baccfbdSHong Zhang #endif
1758d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
17599566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_scalapack_C",NULL));
1760d24d4204SJose E. Roman #endif
17612bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
17629566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqdensecuda_C",NULL));
17639566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",NULL));
17649566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdensecuda_seqdense_C",NULL));
17652bf066beSStefano Zampini #endif
17669566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatSeqDenseSetPreallocation_C",NULL));
17679566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqaij_seqdense_C",NULL));
17689566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqdense_seqdense_C",NULL));
17699566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqbaij_seqdense_C",NULL));
17709566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatProductSetFromOptions_seqsbaij_seqdense_C",NULL));
177152c5f739Sprj- 
17729566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumn_C",NULL));
17739566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumn_C",NULL));
17749566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVec_C",NULL));
17759566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVec_C",NULL));
17769566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVecRead_C",NULL));
17779566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVecRead_C",NULL));
17789566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetColumnVecWrite_C",NULL));
17799566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreColumnVecWrite_C",NULL));
17809566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetSubMatrix_C",NULL));
17819566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreSubMatrix_C",NULL));
17823a40ed3dSBarry Smith   PetscFunctionReturn(0);
1783289bc588SBarry Smith }
1784289bc588SBarry Smith 
1785e0877f53SBarry Smith static PetscErrorCode MatTranspose_SeqDense(Mat A,MatReuse reuse,Mat *matout)
1786289bc588SBarry Smith {
1787c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
17886536e3caSStefano Zampini   PetscInt       k,j,m = A->rmap->n, M = mat->lda, n = A->cmap->n;
178987828ca2SBarry Smith   PetscScalar    *v,tmp;
179048b35521SBarry Smith 
17913a40ed3dSBarry Smith   PetscFunctionBegin;
17926536e3caSStefano Zampini   if (reuse == MAT_INPLACE_MATRIX) {
17936536e3caSStefano Zampini     if (m == n) { /* in place transpose */
17949566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(A,&v));
1795d3e5ee88SLois Curfman McInnes       for (j=0; j<m; j++) {
1796289bc588SBarry Smith         for (k=0; k<j; k++) {
17971b807ce4Svictorle           tmp        = v[j + k*M];
17981b807ce4Svictorle           v[j + k*M] = v[k + j*M];
17991b807ce4Svictorle           v[k + j*M] = tmp;
1800289bc588SBarry Smith         }
1801289bc588SBarry Smith       }
18029566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArray(A,&v));
18036536e3caSStefano Zampini     } else { /* reuse memory, temporary allocates new memory */
18046536e3caSStefano Zampini       PetscScalar *v2;
18056536e3caSStefano Zampini       PetscLayout tmplayout;
18066536e3caSStefano Zampini 
18079566063dSJacob Faibussowitsch       PetscCall(PetscMalloc1((size_t)m*n,&v2));
18089566063dSJacob Faibussowitsch       PetscCall(MatDenseGetArray(A,&v));
18096536e3caSStefano Zampini       for (j=0; j<n; j++) {
18106536e3caSStefano Zampini         for (k=0; k<m; k++) v2[j + (size_t)k*n] = v[k + (size_t)j*M];
18116536e3caSStefano Zampini       }
18129566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(v,v2,(size_t)m*n));
18139566063dSJacob Faibussowitsch       PetscCall(PetscFree(v2));
18149566063dSJacob Faibussowitsch       PetscCall(MatDenseRestoreArray(A,&v));
18156536e3caSStefano Zampini       /* cleanup size dependent quantities */
18169566063dSJacob Faibussowitsch       PetscCall(VecDestroy(&mat->cvec));
18179566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&mat->cmat));
18189566063dSJacob Faibussowitsch       PetscCall(PetscFree(mat->pivots));
18199566063dSJacob Faibussowitsch       PetscCall(PetscFree(mat->fwork));
18209566063dSJacob Faibussowitsch       PetscCall(MatDestroy(&mat->ptapwork));
18216536e3caSStefano Zampini       /* swap row/col layouts */
18226536e3caSStefano Zampini       mat->lda  = n;
18236536e3caSStefano Zampini       tmplayout = A->rmap;
18246536e3caSStefano Zampini       A->rmap   = A->cmap;
18256536e3caSStefano Zampini       A->cmap   = tmplayout;
18266536e3caSStefano Zampini     }
18273a40ed3dSBarry Smith   } else { /* out-of-place transpose */
1828d3e5ee88SLois Curfman McInnes     Mat          tmat;
1829ec8511deSBarry Smith     Mat_SeqDense *tmatd;
183087828ca2SBarry Smith     PetscScalar  *v2;
1831af36a384SStefano Zampini     PetscInt     M2;
1832ea709b57SSatish Balay 
18336536e3caSStefano Zampini     if (reuse == MAT_INITIAL_MATRIX) {
18349566063dSJacob Faibussowitsch       PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&tmat));
18359566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(tmat,A->cmap->n,A->rmap->n,A->cmap->n,A->rmap->n));
18369566063dSJacob Faibussowitsch       PetscCall(MatSetType(tmat,((PetscObject)A)->type_name));
18379566063dSJacob Faibussowitsch       PetscCall(MatSeqDenseSetPreallocation(tmat,NULL));
1838ca15aa20SStefano Zampini     } else tmat = *matout;
1839ca15aa20SStefano Zampini 
18409566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArrayRead(A,(const PetscScalar**)&v));
18419566063dSJacob Faibussowitsch     PetscCall(MatDenseGetArray(tmat,&v2));
1842ec8511deSBarry Smith     tmatd = (Mat_SeqDense*)tmat->data;
1843ca15aa20SStefano Zampini     M2    = tmatd->lda;
1844d3e5ee88SLois Curfman McInnes     for (j=0; j<n; j++) {
1845af36a384SStefano Zampini       for (k=0; k<m; k++) v2[j + k*M2] = v[k + j*M];
1846d3e5ee88SLois Curfman McInnes     }
18479566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArray(tmat,&v2));
18489566063dSJacob Faibussowitsch     PetscCall(MatDenseRestoreArrayRead(A,(const PetscScalar**)&v));
18499566063dSJacob Faibussowitsch     PetscCall(MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY));
18509566063dSJacob Faibussowitsch     PetscCall(MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY));
18516536e3caSStefano Zampini     *matout = tmat;
185248b35521SBarry Smith   }
18533a40ed3dSBarry Smith   PetscFunctionReturn(0);
1854289bc588SBarry Smith }
1855289bc588SBarry Smith 
1856e0877f53SBarry Smith static PetscErrorCode MatEqual_SeqDense(Mat A1,Mat A2,PetscBool  *flg)
1857289bc588SBarry Smith {
1858c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat1 = (Mat_SeqDense*)A1->data;
1859c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat2 = (Mat_SeqDense*)A2->data;
1860ca15aa20SStefano Zampini   PetscInt          i;
1861ca15aa20SStefano Zampini   const PetscScalar *v1,*v2;
18629ea5d5aeSSatish Balay 
18633a40ed3dSBarry Smith   PetscFunctionBegin;
1864d0f46423SBarry Smith   if (A1->rmap->n != A2->rmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
1865d0f46423SBarry Smith   if (A1->cmap->n != A2->cmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);}
18669566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A1,&v1));
18679566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A2,&v2));
1868ca15aa20SStefano Zampini   for (i=0; i<A1->cmap->n; i++) {
18699566063dSJacob Faibussowitsch     PetscCall(PetscArraycmp(v1,v2,A1->rmap->n,flg));
1870ca15aa20SStefano Zampini     if (*flg == PETSC_FALSE) PetscFunctionReturn(0);
1871ca15aa20SStefano Zampini     v1 += mat1->lda;
1872ca15aa20SStefano Zampini     v2 += mat2->lda;
18731b807ce4Svictorle   }
18749566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A1,&v1));
18759566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A2,&v2));
187677c4ece6SBarry Smith   *flg = PETSC_TRUE;
18773a40ed3dSBarry Smith   PetscFunctionReturn(0);
1878289bc588SBarry Smith }
1879289bc588SBarry Smith 
1880e0877f53SBarry Smith static PetscErrorCode MatGetDiagonal_SeqDense(Mat A,Vec v)
1881289bc588SBarry Smith {
1882c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
188313f74950SBarry Smith   PetscInt          i,n,len;
1884ca15aa20SStefano Zampini   PetscScalar       *x;
1885ca15aa20SStefano Zampini   const PetscScalar *vv;
188644cd7ae7SLois Curfman McInnes 
18873a40ed3dSBarry Smith   PetscFunctionBegin;
18889566063dSJacob Faibussowitsch   PetscCall(VecGetSize(v,&n));
18899566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v,&x));
1890d0f46423SBarry Smith   len  = PetscMin(A->rmap->n,A->cmap->n);
18919566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&vv));
189208401ef6SPierre Jolivet   PetscCheck(n == A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming mat and vec");
189344cd7ae7SLois Curfman McInnes   for (i=0; i<len; i++) {
1894ca15aa20SStefano Zampini     x[i] = vv[i*mat->lda + i];
1895289bc588SBarry Smith   }
18969566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&vv));
18979566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v,&x));
18983a40ed3dSBarry Smith   PetscFunctionReturn(0);
1899289bc588SBarry Smith }
1900289bc588SBarry Smith 
1901e0877f53SBarry Smith static PetscErrorCode MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr)
1902289bc588SBarry Smith {
1903c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1904f1ceaac6SMatthew G. Knepley   const PetscScalar *l,*r;
1905ca15aa20SStefano Zampini   PetscScalar       x,*v,*vv;
1906d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n;
190755659b69SBarry Smith 
19083a40ed3dSBarry Smith   PetscFunctionBegin;
19099566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&vv));
191028988994SBarry Smith   if (ll) {
19119566063dSJacob Faibussowitsch     PetscCall(VecGetSize(ll,&m));
19129566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(ll,&l));
191308401ef6SPierre Jolivet     PetscCheck(m == A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vec wrong size");
1914da3a660dSBarry Smith     for (i=0; i<m; i++) {
1915da3a660dSBarry Smith       x = l[i];
1916ca15aa20SStefano Zampini       v = vv + i;
1917b43bac26SStefano Zampini       for (j=0; j<n; j++) { (*v) *= x; v+= mat->lda;}
1918da3a660dSBarry Smith     }
19199566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(ll,&l));
19209566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0*n*m));
1921da3a660dSBarry Smith   }
192228988994SBarry Smith   if (rr) {
19239566063dSJacob Faibussowitsch     PetscCall(VecGetSize(rr,&n));
19249566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(rr,&r));
192508401ef6SPierre Jolivet     PetscCheck(n == A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vec wrong size");
1926da3a660dSBarry Smith     for (i=0; i<n; i++) {
1927da3a660dSBarry Smith       x = r[i];
1928ca15aa20SStefano Zampini       v = vv + i*mat->lda;
19292205254eSKarl Rupp       for (j=0; j<m; j++) (*v++) *= x;
1930da3a660dSBarry Smith     }
19319566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(rr,&r));
19329566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0*n*m));
1933da3a660dSBarry Smith   }
19349566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&vv));
19353a40ed3dSBarry Smith   PetscFunctionReturn(0);
1936289bc588SBarry Smith }
1937289bc588SBarry Smith 
1938ca15aa20SStefano Zampini PetscErrorCode MatNorm_SeqDense(Mat A,NormType type,PetscReal *nrm)
1939289bc588SBarry Smith {
1940c0bbcb79SLois Curfman McInnes   Mat_SeqDense      *mat = (Mat_SeqDense*)A->data;
1941ca15aa20SStefano Zampini   PetscScalar       *v,*vv;
1942329f5518SBarry Smith   PetscReal         sum = 0.0;
194375f6d85dSStefano Zampini   PetscInt          lda, m=A->rmap->n,i,j;
194455659b69SBarry Smith 
19453a40ed3dSBarry Smith   PetscFunctionBegin;
19469566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,(const PetscScalar**)&vv));
19479566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(A,&lda));
1948ca15aa20SStefano Zampini   v    = vv;
1949289bc588SBarry Smith   if (type == NORM_FROBENIUS) {
1950a5ce6ee0Svictorle     if (lda>m) {
1951d0f46423SBarry Smith       for (j=0; j<A->cmap->n; j++) {
1952ca15aa20SStefano Zampini         v = vv+j*lda;
1953a5ce6ee0Svictorle         for (i=0; i<m; i++) {
1954a5ce6ee0Svictorle           sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1955a5ce6ee0Svictorle         }
1956a5ce6ee0Svictorle       }
1957a5ce6ee0Svictorle     } else {
1958570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16)
1959570b7f6dSBarry Smith       PetscBLASInt one = 1,cnt = A->cmap->n*A->rmap->n;
196073cf7048SBarry Smith       PetscStackCallBLAS("BLASnrm2",*nrm = BLASnrm2_(&cnt,v,&one));
1961570b7f6dSBarry Smith     }
1962570b7f6dSBarry Smith #else
1963d0f46423SBarry Smith       for (i=0; i<A->cmap->n*A->rmap->n; i++) {
1964329f5518SBarry Smith         sum += PetscRealPart(PetscConj(*v)*(*v)); v++;
1965289bc588SBarry Smith       }
1966a5ce6ee0Svictorle     }
19678f1a2a5eSBarry Smith     *nrm = PetscSqrtReal(sum);
1968570b7f6dSBarry Smith #endif
19699566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(2.0*A->cmap->n*A->rmap->n));
19703a40ed3dSBarry Smith   } else if (type == NORM_1) {
1971064f8208SBarry Smith     *nrm = 0.0;
1972d0f46423SBarry Smith     for (j=0; j<A->cmap->n; j++) {
1973ca15aa20SStefano Zampini       v   = vv + j*mat->lda;
1974289bc588SBarry Smith       sum = 0.0;
1975d0f46423SBarry Smith       for (i=0; i<A->rmap->n; i++) {
197633a8263dSBarry Smith         sum += PetscAbsScalar(*v);  v++;
1977289bc588SBarry Smith       }
1978064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1979289bc588SBarry Smith     }
19809566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0*A->cmap->n*A->rmap->n));
19813a40ed3dSBarry Smith   } else if (type == NORM_INFINITY) {
1982064f8208SBarry Smith     *nrm = 0.0;
1983d0f46423SBarry Smith     for (j=0; j<A->rmap->n; j++) {
1984ca15aa20SStefano Zampini       v   = vv + j;
1985289bc588SBarry Smith       sum = 0.0;
1986d0f46423SBarry Smith       for (i=0; i<A->cmap->n; i++) {
19871b807ce4Svictorle         sum += PetscAbsScalar(*v); v += mat->lda;
1988289bc588SBarry Smith       }
1989064f8208SBarry Smith       if (sum > *nrm) *nrm = sum;
1990289bc588SBarry Smith     }
19919566063dSJacob Faibussowitsch     PetscCall(PetscLogFlops(1.0*A->cmap->n*A->rmap->n));
1992e7e72b3dSBarry Smith   } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No two norm");
19939566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,(const PetscScalar**)&vv));
19943a40ed3dSBarry Smith   PetscFunctionReturn(0);
1995289bc588SBarry Smith }
1996289bc588SBarry Smith 
1997e0877f53SBarry Smith static PetscErrorCode MatSetOption_SeqDense(Mat A,MatOption op,PetscBool flg)
1998289bc588SBarry Smith {
1999c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *aij = (Mat_SeqDense*)A->data;
200067e560aaSBarry Smith 
20013a40ed3dSBarry Smith   PetscFunctionBegin;
2002b5a2b587SKris Buschelman   switch (op) {
2003b5a2b587SKris Buschelman   case MAT_ROW_ORIENTED:
20044e0d8c25SBarry Smith     aij->roworiented = flg;
2005b5a2b587SKris Buschelman     break;
2006512a5fc5SBarry Smith   case MAT_NEW_NONZERO_LOCATIONS:
2007b5a2b587SKris Buschelman   case MAT_NEW_NONZERO_LOCATION_ERR:
20083971808eSMatthew Knepley   case MAT_NEW_NONZERO_ALLOCATION_ERR:
20098c78258cSHong Zhang   case MAT_FORCE_DIAGONAL_ENTRIES:
201013fa8e87SLisandro Dalcin   case MAT_KEEP_NONZERO_PATTERN:
2011b5a2b587SKris Buschelman   case MAT_IGNORE_OFF_PROC_ENTRIES:
2012b5a2b587SKris Buschelman   case MAT_USE_HASH_TABLE:
20130f8fb01aSBarry Smith   case MAT_IGNORE_ZERO_ENTRIES:
20145021d80fSJed Brown   case MAT_IGNORE_LOWER_TRIANGULAR:
2015071fcb05SBarry Smith   case MAT_SORTED_FULL:
20169566063dSJacob Faibussowitsch     PetscCall(PetscInfo(A,"Option %s ignored\n",MatOptions[op]));
20175021d80fSJed Brown     break;
20185021d80fSJed Brown   case MAT_SPD:
201977e54ba9SKris Buschelman   case MAT_SYMMETRIC:
202077e54ba9SKris Buschelman   case MAT_STRUCTURALLY_SYMMETRIC:
20219a4540c5SBarry Smith   case MAT_HERMITIAN:
20229a4540c5SBarry Smith   case MAT_SYMMETRY_ETERNAL:
20235021d80fSJed Brown     /* These options are handled directly by MatSetOption() */
202477e54ba9SKris Buschelman     break;
2025b5a2b587SKris Buschelman   default:
202698921bdaSJacob Faibussowitsch     SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %s",MatOptions[op]);
20273a40ed3dSBarry Smith   }
20283a40ed3dSBarry Smith   PetscFunctionReturn(0);
2029289bc588SBarry Smith }
2030289bc588SBarry Smith 
20313d8925e7SStefano Zampini PetscErrorCode MatZeroEntries_SeqDense(Mat A)
20326f0a148fSBarry Smith {
2033ec8511deSBarry Smith   Mat_SeqDense   *l = (Mat_SeqDense*)A->data;
20343d8925e7SStefano Zampini   PetscInt       lda=l->lda,m=A->rmap->n,n=A->cmap->n,j;
2035ca15aa20SStefano Zampini   PetscScalar    *v;
20363a40ed3dSBarry Smith 
20373a40ed3dSBarry Smith   PetscFunctionBegin;
20389566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(A,&v));
2039a5ce6ee0Svictorle   if (lda>m) {
20403d8925e7SStefano Zampini     for (j=0; j<n; j++) {
20419566063dSJacob Faibussowitsch       PetscCall(PetscArrayzero(v+j*lda,m));
2042a5ce6ee0Svictorle     }
2043a5ce6ee0Svictorle   } else {
20449566063dSJacob Faibussowitsch     PetscCall(PetscArrayzero(v,PetscInt64Mult(m,n)));
2045a5ce6ee0Svictorle   }
20469566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(A,&v));
20473a40ed3dSBarry Smith   PetscFunctionReturn(0);
20486f0a148fSBarry Smith }
20496f0a148fSBarry Smith 
2050e0877f53SBarry Smith static PetscErrorCode MatZeroRows_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b)
20516f0a148fSBarry Smith {
2052ec8511deSBarry Smith   Mat_SeqDense      *l = (Mat_SeqDense*)A->data;
2053b9679d65SBarry Smith   PetscInt          m  = l->lda, n = A->cmap->n, i,j;
2054ca15aa20SStefano Zampini   PetscScalar       *slot,*bb,*v;
205597b48c8fSBarry Smith   const PetscScalar *xx;
205655659b69SBarry Smith 
20573a40ed3dSBarry Smith   PetscFunctionBegin;
205876bd3646SJed Brown   if (PetscDefined(USE_DEBUG)) {
2059b9679d65SBarry Smith     for (i=0; i<N; i++) {
206008401ef6SPierre Jolivet       PetscCheck(rows[i] >= 0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed");
206108401ef6SPierre 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);
2062b9679d65SBarry Smith     }
206376bd3646SJed Brown   }
2064ca15aa20SStefano Zampini   if (!N) PetscFunctionReturn(0);
2065b9679d65SBarry Smith 
206697b48c8fSBarry Smith   /* fix right hand side if needed */
206797b48c8fSBarry Smith   if (x && b) {
20689566063dSJacob Faibussowitsch     PetscCall(VecGetArrayRead(x,&xx));
20699566063dSJacob Faibussowitsch     PetscCall(VecGetArray(b,&bb));
20702205254eSKarl Rupp     for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]];
20719566063dSJacob Faibussowitsch     PetscCall(VecRestoreArrayRead(x,&xx));
20729566063dSJacob Faibussowitsch     PetscCall(VecRestoreArray(b,&bb));
207397b48c8fSBarry Smith   }
207497b48c8fSBarry Smith 
20759566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&v));
20766f0a148fSBarry Smith   for (i=0; i<N; i++) {
2077ca15aa20SStefano Zampini     slot = v + rows[i];
2078b9679d65SBarry Smith     for (j=0; j<n; j++) { *slot = 0.0; slot += m;}
20796f0a148fSBarry Smith   }
2080f4df32b1SMatthew Knepley   if (diag != 0.0) {
208108401ef6SPierre Jolivet     PetscCheck(A->rmap->n == A->cmap->n,PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices");
20826f0a148fSBarry Smith     for (i=0; i<N; i++) {
2083ca15aa20SStefano Zampini       slot  = v + (m+1)*rows[i];
2084f4df32b1SMatthew Knepley       *slot = diag;
20856f0a148fSBarry Smith     }
20866f0a148fSBarry Smith   }
20879566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&v));
20883a40ed3dSBarry Smith   PetscFunctionReturn(0);
20896f0a148fSBarry Smith }
2090557bce09SLois Curfman McInnes 
209149a6ff4bSBarry Smith static PetscErrorCode MatDenseGetLDA_SeqDense(Mat A,PetscInt *lda)
209249a6ff4bSBarry Smith {
209349a6ff4bSBarry Smith   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
209449a6ff4bSBarry Smith 
209549a6ff4bSBarry Smith   PetscFunctionBegin;
209649a6ff4bSBarry Smith   *lda = mat->lda;
209749a6ff4bSBarry Smith   PetscFunctionReturn(0);
209849a6ff4bSBarry Smith }
209949a6ff4bSBarry Smith 
2100637a0070SStefano Zampini PetscErrorCode MatDenseGetArray_SeqDense(Mat A,PetscScalar **array)
210164e87e97SBarry Smith {
2102c0bbcb79SLois Curfman McInnes   Mat_SeqDense *mat = (Mat_SeqDense*)A->data;
21033a40ed3dSBarry Smith 
21043a40ed3dSBarry Smith   PetscFunctionBegin;
210528b400f6SJacob Faibussowitsch   PetscCheck(!mat->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
210664e87e97SBarry Smith   *array = mat->v;
21073a40ed3dSBarry Smith   PetscFunctionReturn(0);
210864e87e97SBarry Smith }
21090754003eSLois Curfman McInnes 
2110637a0070SStefano Zampini PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A,PetscScalar **array)
2111ff14e315SSatish Balay {
21123a40ed3dSBarry Smith   PetscFunctionBegin;
211375f6d85dSStefano Zampini   if (array) *array = NULL;
21143a40ed3dSBarry Smith   PetscFunctionReturn(0);
2115ff14e315SSatish Balay }
21160754003eSLois Curfman McInnes 
21170f74d2c1SSatish Balay /*@
211849a6ff4bSBarry Smith    MatDenseGetLDA - gets the leading dimension of the array returned from MatDenseGetArray()
211949a6ff4bSBarry Smith 
2120ad16ce7aSStefano Zampini    Not collective
212149a6ff4bSBarry Smith 
212249a6ff4bSBarry Smith    Input Parameter:
212349a6ff4bSBarry Smith .  mat - a MATSEQDENSE or MATMPIDENSE matrix
212449a6ff4bSBarry Smith 
212549a6ff4bSBarry Smith    Output Parameter:
212649a6ff4bSBarry Smith .   lda - the leading dimension
212749a6ff4bSBarry Smith 
212849a6ff4bSBarry Smith    Level: intermediate
212949a6ff4bSBarry Smith 
2130db781477SPatrick Sanan .seealso: `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseSetLDA()`
213149a6ff4bSBarry Smith @*/
213249a6ff4bSBarry Smith PetscErrorCode  MatDenseGetLDA(Mat A,PetscInt *lda)
213349a6ff4bSBarry Smith {
213449a6ff4bSBarry Smith   PetscFunctionBegin;
2135d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2136dadcf809SJacob Faibussowitsch   PetscValidIntPointer(lda,2);
213775f6d85dSStefano Zampini   MatCheckPreallocated(A,1);
2138cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetLDA_C",(Mat,PetscInt*),(A,lda));
213949a6ff4bSBarry Smith   PetscFunctionReturn(0);
214049a6ff4bSBarry Smith }
214149a6ff4bSBarry Smith 
21420f74d2c1SSatish Balay /*@
2143ad16ce7aSStefano Zampini    MatDenseSetLDA - Sets the leading dimension of the array used by the dense matrix
2144ad16ce7aSStefano Zampini 
2145ad16ce7aSStefano Zampini    Not collective
2146ad16ce7aSStefano Zampini 
2147d8d19677SJose E. Roman    Input Parameters:
2148ad16ce7aSStefano Zampini +  mat - a MATSEQDENSE or MATMPIDENSE matrix
2149ad16ce7aSStefano Zampini -  lda - the leading dimension
2150ad16ce7aSStefano Zampini 
2151ad16ce7aSStefano Zampini    Level: intermediate
2152ad16ce7aSStefano Zampini 
2153db781477SPatrick Sanan .seealso: `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetLDA()`
2154ad16ce7aSStefano Zampini @*/
2155ad16ce7aSStefano Zampini PetscErrorCode  MatDenseSetLDA(Mat A,PetscInt lda)
2156ad16ce7aSStefano Zampini {
2157ad16ce7aSStefano Zampini   PetscFunctionBegin;
2158ad16ce7aSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2159cac4c232SBarry Smith   PetscTryMethod(A,"MatDenseSetLDA_C",(Mat,PetscInt),(A,lda));
2160ad16ce7aSStefano Zampini   PetscFunctionReturn(0);
2161ad16ce7aSStefano Zampini }
2162ad16ce7aSStefano Zampini 
2163ad16ce7aSStefano Zampini /*@C
21646947451fSStefano Zampini    MatDenseGetArray - gives read-write access to the array where the data for a dense matrix is stored
216573a71a0fSBarry Smith 
21668572280aSBarry Smith    Logically Collective on Mat
216773a71a0fSBarry Smith 
216873a71a0fSBarry Smith    Input Parameter:
21696947451fSStefano Zampini .  mat - a dense matrix
217073a71a0fSBarry Smith 
217173a71a0fSBarry Smith    Output Parameter:
217273a71a0fSBarry Smith .   array - pointer to the data
217373a71a0fSBarry Smith 
217473a71a0fSBarry Smith    Level: intermediate
217573a71a0fSBarry Smith 
2176db781477SPatrick Sanan .seealso: `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
217773a71a0fSBarry Smith @*/
21788c778c55SBarry Smith PetscErrorCode  MatDenseGetArray(Mat A,PetscScalar **array)
217973a71a0fSBarry Smith {
218073a71a0fSBarry Smith   PetscFunctionBegin;
2181d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2182d5ea218eSStefano Zampini   PetscValidPointer(array,2);
2183cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetArray_C",(Mat,PetscScalar**),(A,array));
218473a71a0fSBarry Smith   PetscFunctionReturn(0);
218573a71a0fSBarry Smith }
218673a71a0fSBarry Smith 
2187dec5eb66SMatthew G Knepley /*@C
2188579dbff0SBarry Smith    MatDenseRestoreArray - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray()
218973a71a0fSBarry Smith 
21908572280aSBarry Smith    Logically Collective on Mat
21918572280aSBarry Smith 
21928572280aSBarry Smith    Input Parameters:
21936947451fSStefano Zampini +  mat - a dense matrix
2194a2b725a8SWilliam Gropp -  array - pointer to the data
21958572280aSBarry Smith 
21968572280aSBarry Smith    Level: intermediate
21978572280aSBarry Smith 
2198db781477SPatrick Sanan .seealso: `MatDenseGetArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
21998572280aSBarry Smith @*/
22008572280aSBarry Smith PetscErrorCode  MatDenseRestoreArray(Mat A,PetscScalar **array)
22018572280aSBarry Smith {
22028572280aSBarry Smith   PetscFunctionBegin;
2203d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2204d5ea218eSStefano Zampini   PetscValidPointer(array,2);
2205cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreArray_C",(Mat,PetscScalar**),(A,array));
22069566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)A));
2207637a0070SStefano Zampini #if defined(PETSC_HAVE_CUDA)
2208637a0070SStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
2209637a0070SStefano Zampini #endif
22108572280aSBarry Smith   PetscFunctionReturn(0);
22118572280aSBarry Smith }
22128572280aSBarry Smith 
22138572280aSBarry Smith /*@C
22146947451fSStefano Zampini    MatDenseGetArrayRead - gives read-only access to the array where the data for a dense matrix is stored
22158572280aSBarry Smith 
22168572280aSBarry Smith    Not Collective
22178572280aSBarry Smith 
22188572280aSBarry Smith    Input Parameter:
22196947451fSStefano Zampini .  mat - a dense matrix
22208572280aSBarry Smith 
22218572280aSBarry Smith    Output Parameter:
22228572280aSBarry Smith .   array - pointer to the data
22238572280aSBarry Smith 
22248572280aSBarry Smith    Level: intermediate
22258572280aSBarry Smith 
2226db781477SPatrick Sanan .seealso: `MatDenseRestoreArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
22278572280aSBarry Smith @*/
22288572280aSBarry Smith PetscErrorCode  MatDenseGetArrayRead(Mat A,const PetscScalar **array)
22298572280aSBarry Smith {
22308572280aSBarry Smith   PetscFunctionBegin;
2231d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2232d5ea218eSStefano Zampini   PetscValidPointer(array,2);
2233cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetArrayRead_C",(Mat,const PetscScalar**),(A,array));
22348572280aSBarry Smith   PetscFunctionReturn(0);
22358572280aSBarry Smith }
22368572280aSBarry Smith 
22378572280aSBarry Smith /*@C
22386947451fSStefano Zampini    MatDenseRestoreArrayRead - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArrayRead()
22398572280aSBarry Smith 
224073a71a0fSBarry Smith    Not Collective
224173a71a0fSBarry Smith 
224273a71a0fSBarry Smith    Input Parameters:
22436947451fSStefano Zampini +  mat - a dense matrix
2244a2b725a8SWilliam Gropp -  array - pointer to the data
224573a71a0fSBarry Smith 
224673a71a0fSBarry Smith    Level: intermediate
224773a71a0fSBarry Smith 
2248db781477SPatrick Sanan .seealso: `MatDenseGetArrayRead()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayWrite()`, `MatDenseRestoreArrayWrite()`
224973a71a0fSBarry Smith @*/
22508572280aSBarry Smith PetscErrorCode  MatDenseRestoreArrayRead(Mat A,const PetscScalar **array)
225173a71a0fSBarry Smith {
225273a71a0fSBarry Smith   PetscFunctionBegin;
2253d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2254d5ea218eSStefano Zampini   PetscValidPointer(array,2);
2255cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreArrayRead_C",(Mat,const PetscScalar**),(A,array));
225673a71a0fSBarry Smith   PetscFunctionReturn(0);
225773a71a0fSBarry Smith }
225873a71a0fSBarry Smith 
22596947451fSStefano Zampini /*@C
22606947451fSStefano Zampini    MatDenseGetArrayWrite - gives write-only access to the array where the data for a dense matrix is stored
22616947451fSStefano Zampini 
22626947451fSStefano Zampini    Not Collective
22636947451fSStefano Zampini 
22646947451fSStefano Zampini    Input Parameter:
22656947451fSStefano Zampini .  mat - a dense matrix
22666947451fSStefano Zampini 
22676947451fSStefano Zampini    Output Parameter:
22686947451fSStefano Zampini .   array - pointer to the data
22696947451fSStefano Zampini 
22706947451fSStefano Zampini    Level: intermediate
22716947451fSStefano Zampini 
2272db781477SPatrick Sanan .seealso: `MatDenseRestoreArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`
22736947451fSStefano Zampini @*/
22746947451fSStefano Zampini PetscErrorCode  MatDenseGetArrayWrite(Mat A,PetscScalar **array)
22756947451fSStefano Zampini {
22766947451fSStefano Zampini   PetscFunctionBegin;
2277d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2278d5ea218eSStefano Zampini   PetscValidPointer(array,2);
2279cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetArrayWrite_C",(Mat,PetscScalar**),(A,array));
22806947451fSStefano Zampini   PetscFunctionReturn(0);
22816947451fSStefano Zampini }
22826947451fSStefano Zampini 
22836947451fSStefano Zampini /*@C
22846947451fSStefano Zampini    MatDenseRestoreArrayWrite - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArrayWrite()
22856947451fSStefano Zampini 
22866947451fSStefano Zampini    Not Collective
22876947451fSStefano Zampini 
22886947451fSStefano Zampini    Input Parameters:
22896947451fSStefano Zampini +  mat - a dense matrix
22906947451fSStefano Zampini -  array - pointer to the data
22916947451fSStefano Zampini 
22926947451fSStefano Zampini    Level: intermediate
22936947451fSStefano Zampini 
2294db781477SPatrick Sanan .seealso: `MatDenseGetArrayWrite()`, `MatDenseGetArray()`, `MatDenseRestoreArray()`, `MatDenseGetArrayRead()`, `MatDenseRestoreArrayRead()`
22956947451fSStefano Zampini @*/
22966947451fSStefano Zampini PetscErrorCode  MatDenseRestoreArrayWrite(Mat A,PetscScalar **array)
22976947451fSStefano Zampini {
22986947451fSStefano Zampini   PetscFunctionBegin;
2299d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
2300d5ea218eSStefano Zampini   PetscValidPointer(array,2);
2301cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreArrayWrite_C",(Mat,PetscScalar**),(A,array));
23029566063dSJacob Faibussowitsch   PetscCall(PetscObjectStateIncrease((PetscObject)A));
23036947451fSStefano Zampini #if defined(PETSC_HAVE_CUDA)
23046947451fSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
23056947451fSStefano Zampini #endif
23066947451fSStefano Zampini   PetscFunctionReturn(0);
23076947451fSStefano Zampini }
23086947451fSStefano Zampini 
2309023c16fcSToby Isaac static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,MatReuse scall,Mat *B)
23100754003eSLois Curfman McInnes {
2311c0bbcb79SLois Curfman McInnes   Mat_SeqDense   *mat = (Mat_SeqDense*)A->data;
2312bf5a80bcSToby Isaac   PetscInt       i,j,nrows,ncols,ldb;
23135d0c19d7SBarry Smith   const PetscInt *irow,*icol;
231487828ca2SBarry Smith   PetscScalar    *av,*bv,*v = mat->v;
23150754003eSLois Curfman McInnes   Mat            newmat;
23160754003eSLois Curfman McInnes 
23173a40ed3dSBarry Smith   PetscFunctionBegin;
23189566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(isrow,&irow));
23199566063dSJacob Faibussowitsch   PetscCall(ISGetIndices(iscol,&icol));
23209566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(isrow,&nrows));
23219566063dSJacob Faibussowitsch   PetscCall(ISGetLocalSize(iscol,&ncols));
23220754003eSLois Curfman McInnes 
2323182d2002SSatish Balay   /* Check submatrixcall */
2324182d2002SSatish Balay   if (scall == MAT_REUSE_MATRIX) {
232513f74950SBarry Smith     PetscInt n_cols,n_rows;
23269566063dSJacob Faibussowitsch     PetscCall(MatGetSize(*B,&n_rows,&n_cols));
232721a2c019SBarry Smith     if (n_rows != nrows || n_cols != ncols) {
2328f746d493SDmitry Karpeev       /* resize the result matrix to match number of requested rows/columns */
23299566063dSJacob Faibussowitsch       PetscCall(MatSetSizes(*B,nrows,ncols,nrows,ncols));
233021a2c019SBarry Smith     }
2331182d2002SSatish Balay     newmat = *B;
2332182d2002SSatish Balay   } else {
23330754003eSLois Curfman McInnes     /* Create and fill new matrix */
23349566063dSJacob Faibussowitsch     PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&newmat));
23359566063dSJacob Faibussowitsch     PetscCall(MatSetSizes(newmat,nrows,ncols,nrows,ncols));
23369566063dSJacob Faibussowitsch     PetscCall(MatSetType(newmat,((PetscObject)A)->type_name));
23379566063dSJacob Faibussowitsch     PetscCall(MatSeqDenseSetPreallocation(newmat,NULL));
2338182d2002SSatish Balay   }
2339182d2002SSatish Balay 
2340182d2002SSatish Balay   /* Now extract the data pointers and do the copy,column at a time */
23419566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(newmat,&bv));
23429566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(newmat,&ldb));
2343182d2002SSatish Balay   for (i=0; i<ncols; i++) {
23446de62eeeSBarry Smith     av = v + mat->lda*icol[i];
2345ca15aa20SStefano Zampini     for (j=0; j<nrows; j++) bv[j] = av[irow[j]];
2346bf5a80bcSToby Isaac     bv += ldb;
23470754003eSLois Curfman McInnes   }
23489566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(newmat,&bv));
2349182d2002SSatish Balay 
2350182d2002SSatish Balay   /* Assemble the matrices so that the correct flags are set */
23519566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY));
23529566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY));
23530754003eSLois Curfman McInnes 
23540754003eSLois Curfman McInnes   /* Free work space */
23559566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(isrow,&irow));
23569566063dSJacob Faibussowitsch   PetscCall(ISRestoreIndices(iscol,&icol));
2357182d2002SSatish Balay   *B   = newmat;
23583a40ed3dSBarry Smith   PetscFunctionReturn(0);
23590754003eSLois Curfman McInnes }
23600754003eSLois Curfman McInnes 
23617dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[])
2362905e6a2fSBarry Smith {
236313f74950SBarry Smith   PetscInt       i;
2364905e6a2fSBarry Smith 
23653a40ed3dSBarry Smith   PetscFunctionBegin;
2366905e6a2fSBarry Smith   if (scall == MAT_INITIAL_MATRIX) {
23679566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1(n,B));
2368905e6a2fSBarry Smith   }
2369905e6a2fSBarry Smith 
2370905e6a2fSBarry Smith   for (i=0; i<n; i++) {
23719566063dSJacob Faibussowitsch     PetscCall(MatCreateSubMatrix_SeqDense(A,irow[i],icol[i],scall,&(*B)[i]));
2372905e6a2fSBarry Smith   }
23733a40ed3dSBarry Smith   PetscFunctionReturn(0);
2374905e6a2fSBarry Smith }
2375905e6a2fSBarry Smith 
2376e0877f53SBarry Smith static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat,MatAssemblyType mode)
2377c0aa2d19SHong Zhang {
2378c0aa2d19SHong Zhang   PetscFunctionBegin;
2379c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2380c0aa2d19SHong Zhang }
2381c0aa2d19SHong Zhang 
2382e0877f53SBarry Smith static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat,MatAssemblyType mode)
2383c0aa2d19SHong Zhang {
2384c0aa2d19SHong Zhang   PetscFunctionBegin;
2385c0aa2d19SHong Zhang   PetscFunctionReturn(0);
2386c0aa2d19SHong Zhang }
2387c0aa2d19SHong Zhang 
2388a76f77c3SStefano Zampini PetscErrorCode MatCopy_SeqDense(Mat A,Mat B,MatStructure str)
23894b0e389bSBarry Smith {
23904b0e389bSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data,*b = (Mat_SeqDense*)B->data;
2391ca15aa20SStefano Zampini   const PetscScalar *va;
2392ca15aa20SStefano Zampini   PetscScalar       *vb;
2393d0f46423SBarry Smith   PetscInt          lda1=a->lda,lda2=b->lda, m=A->rmap->n,n=A->cmap->n, j;
23943a40ed3dSBarry Smith 
23953a40ed3dSBarry Smith   PetscFunctionBegin;
239633f4a19fSKris Buschelman   /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */
239733f4a19fSKris Buschelman   if (A->ops->copy != B->ops->copy) {
23989566063dSJacob Faibussowitsch     PetscCall(MatCopy_Basic(A,B,str));
23993a40ed3dSBarry Smith     PetscFunctionReturn(0);
24003a40ed3dSBarry Smith   }
2401aed4548fSBarry Smith   PetscCheck(m == B->rmap->n && n == B->cmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"size(B) != size(A)");
24029566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&va));
24039566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(B,&vb));
2404a5ce6ee0Svictorle   if (lda1>m || lda2>m) {
24050dbb7854Svictorle     for (j=0; j<n; j++) {
24069566063dSJacob Faibussowitsch       PetscCall(PetscArraycpy(vb+j*lda2,va+j*lda1,m));
2407a5ce6ee0Svictorle     }
2408a5ce6ee0Svictorle   } else {
24099566063dSJacob Faibussowitsch     PetscCall(PetscArraycpy(vb,va,A->rmap->n*A->cmap->n));
2410a5ce6ee0Svictorle   }
24119566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(B,&vb));
24129566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&va));
24139566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY));
24149566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY));
2415273d9f13SBarry Smith   PetscFunctionReturn(0);
2416273d9f13SBarry Smith }
2417273d9f13SBarry Smith 
241875f6d85dSStefano Zampini PetscErrorCode MatSetUp_SeqDense(Mat A)
2419273d9f13SBarry Smith {
2420273d9f13SBarry Smith   PetscFunctionBegin;
24219566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(A->rmap));
24229566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(A->cmap));
242318992e5dSStefano Zampini   if (!A->preallocated) {
24249566063dSJacob Faibussowitsch     PetscCall(MatSeqDenseSetPreallocation(A,NULL));
242518992e5dSStefano Zampini   }
24263a40ed3dSBarry Smith   PetscFunctionReturn(0);
24274b0e389bSBarry Smith }
24284b0e389bSBarry Smith 
2429ba337c44SJed Brown static PetscErrorCode MatConjugate_SeqDense(Mat A)
2430ba337c44SJed Brown {
24314396437dSToby Isaac   Mat_SeqDense   *mat = (Mat_SeqDense *) A->data;
2432ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
24334396437dSToby Isaac   PetscInt       min = PetscMin(A->rmap->n,A->cmap->n);
2434ca15aa20SStefano Zampini   PetscScalar    *aa;
2435ba337c44SJed Brown 
2436ba337c44SJed Brown   PetscFunctionBegin;
24379566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&aa));
2438ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscConj(aa[i]);
24399566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&aa));
24404396437dSToby Isaac   if (mat->tau) for (i = 0; i < min; i++) mat->tau[i] = PetscConj(mat->tau[i]);
2441ba337c44SJed Brown   PetscFunctionReturn(0);
2442ba337c44SJed Brown }
2443ba337c44SJed Brown 
2444ba337c44SJed Brown static PetscErrorCode MatRealPart_SeqDense(Mat A)
2445ba337c44SJed Brown {
2446ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2447ca15aa20SStefano Zampini   PetscScalar    *aa;
2448ba337c44SJed Brown 
2449ba337c44SJed Brown   PetscFunctionBegin;
24509566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&aa));
2451ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]);
24529566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&aa));
2453ba337c44SJed Brown   PetscFunctionReturn(0);
2454ba337c44SJed Brown }
2455ba337c44SJed Brown 
2456ba337c44SJed Brown static PetscErrorCode MatImaginaryPart_SeqDense(Mat A)
2457ba337c44SJed Brown {
2458ba337c44SJed Brown   PetscInt       i,nz = A->rmap->n*A->cmap->n;
2459ca15aa20SStefano Zampini   PetscScalar    *aa;
2460ba337c44SJed Brown 
2461ba337c44SJed Brown   PetscFunctionBegin;
24629566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&aa));
2463ba337c44SJed Brown   for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]);
24649566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&aa));
2465ba337c44SJed Brown   PetscFunctionReturn(0);
2466ba337c44SJed Brown }
2467284134d9SBarry Smith 
2468a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/
24694222ddf1SHong Zhang PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
2470a9fe9ddaSSatish Balay {
2471d0f46423SBarry Smith   PetscInt       m=A->rmap->n,n=B->cmap->n;
24727a3c3d58SStefano Zampini   PetscBool      cisdense;
2473a9fe9ddaSSatish Balay 
2474ee16a9a1SHong Zhang   PetscFunctionBegin;
24759566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C,m,n,m,n));
24769566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,""));
24777a3c3d58SStefano Zampini   if (!cisdense) {
24787a3c3d58SStefano Zampini     PetscBool flg;
24797a3c3d58SStefano Zampini 
24809566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg));
24819566063dSJacob Faibussowitsch     PetscCall(MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE));
24827a3c3d58SStefano Zampini   }
24839566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
2484ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2485ee16a9a1SHong Zhang }
2486a9fe9ddaSSatish Balay 
2487a9fe9ddaSSatish Balay PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2488a9fe9ddaSSatish Balay {
24896718818eSStefano Zampini   Mat_SeqDense       *a=(Mat_SeqDense*)A->data,*b=(Mat_SeqDense*)B->data,*c=(Mat_SeqDense*)C->data;
24900805154bSBarry Smith   PetscBLASInt       m,n,k;
2491ca15aa20SStefano Zampini   const PetscScalar *av,*bv;
2492ca15aa20SStefano Zampini   PetscScalar       *cv;
2493a9fe9ddaSSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
2494a9fe9ddaSSatish Balay 
2495a9fe9ddaSSatish Balay   PetscFunctionBegin;
24969566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n,&m));
24979566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n,&n));
24989566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&k));
249949d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
25009566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&av));
25019566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B,&bv));
25029566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C,&cv));
2503ca15aa20SStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
25049566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1)));
25059566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&av));
25069566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B,&bv));
25079566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C,&cv));
2508a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2509a9fe9ddaSSatish Balay }
2510a9fe9ddaSSatish Balay 
25114222ddf1SHong Zhang PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
251269f65d41SStefano Zampini {
251369f65d41SStefano Zampini   PetscInt       m=A->rmap->n,n=B->rmap->n;
25147a3c3d58SStefano Zampini   PetscBool      cisdense;
251569f65d41SStefano Zampini 
251669f65d41SStefano Zampini   PetscFunctionBegin;
25179566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C,m,n,m,n));
25189566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,""));
25197a3c3d58SStefano Zampini   if (!cisdense) {
25207a3c3d58SStefano Zampini     PetscBool flg;
25217a3c3d58SStefano Zampini 
25229566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg));
25239566063dSJacob Faibussowitsch     PetscCall(MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE));
25247a3c3d58SStefano Zampini   }
25259566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
252669f65d41SStefano Zampini   PetscFunctionReturn(0);
252769f65d41SStefano Zampini }
252869f65d41SStefano Zampini 
252969f65d41SStefano Zampini PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
253069f65d41SStefano Zampini {
253169f65d41SStefano Zampini   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
253269f65d41SStefano Zampini   Mat_SeqDense      *b = (Mat_SeqDense*)B->data;
253369f65d41SStefano Zampini   Mat_SeqDense      *c = (Mat_SeqDense*)C->data;
25346718818eSStefano Zampini   const PetscScalar *av,*bv;
25356718818eSStefano Zampini   PetscScalar       *cv;
253669f65d41SStefano Zampini   PetscBLASInt      m,n,k;
253769f65d41SStefano Zampini   PetscScalar       _DOne=1.0,_DZero=0.0;
253869f65d41SStefano Zampini 
253969f65d41SStefano Zampini   PetscFunctionBegin;
25409566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n,&m));
25419566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n,&n));
25429566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->cmap->n,&k));
254349d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
25449566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&av));
25459566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B,&bv));
25469566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C,&cv));
25476718818eSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("N","T",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
25489566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&av));
25499566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B,&bv));
25509566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C,&cv));
25519566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1)));
255269f65d41SStefano Zampini   PetscFunctionReturn(0);
255369f65d41SStefano Zampini }
255469f65d41SStefano Zampini 
25554222ddf1SHong Zhang PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
2556a9fe9ddaSSatish Balay {
2557d0f46423SBarry Smith   PetscInt       m=A->cmap->n,n=B->cmap->n;
25587a3c3d58SStefano Zampini   PetscBool      cisdense;
2559a9fe9ddaSSatish Balay 
2560ee16a9a1SHong Zhang   PetscFunctionBegin;
25619566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(C,m,n,m,n));
25629566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,""));
25637a3c3d58SStefano Zampini   if (!cisdense) {
25647a3c3d58SStefano Zampini     PetscBool flg;
25657a3c3d58SStefano Zampini 
25669566063dSJacob Faibussowitsch     PetscCall(PetscObjectTypeCompare((PetscObject)B,((PetscObject)A)->type_name,&flg));
25679566063dSJacob Faibussowitsch     PetscCall(MatSetType(C,flg ? ((PetscObject)A)->type_name : MATDENSE));
25687a3c3d58SStefano Zampini   }
25699566063dSJacob Faibussowitsch   PetscCall(MatSetUp(C));
2570ee16a9a1SHong Zhang   PetscFunctionReturn(0);
2571ee16a9a1SHong Zhang }
2572a9fe9ddaSSatish Balay 
257375648e8dSHong Zhang PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C)
2574a9fe9ddaSSatish Balay {
2575a9fe9ddaSSatish Balay   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2576a9fe9ddaSSatish Balay   Mat_SeqDense      *b = (Mat_SeqDense*)B->data;
2577a9fe9ddaSSatish Balay   Mat_SeqDense      *c = (Mat_SeqDense*)C->data;
25786718818eSStefano Zampini   const PetscScalar *av,*bv;
25796718818eSStefano Zampini   PetscScalar       *cv;
25800805154bSBarry Smith   PetscBLASInt      m,n,k;
2581a9fe9ddaSSatish Balay   PetscScalar       _DOne=1.0,_DZero=0.0;
2582a9fe9ddaSSatish Balay 
2583a9fe9ddaSSatish Balay   PetscFunctionBegin;
25849566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->rmap->n,&m));
25859566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(C->cmap->n,&n));
25869566063dSJacob Faibussowitsch   PetscCall(PetscBLASIntCast(A->rmap->n,&k));
258749d0e964SStefano Zampini   if (!m || !n || !k) PetscFunctionReturn(0);
25889566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&av));
25899566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(B,&bv));
25909566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(C,&cv));
25916718818eSStefano Zampini   PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&m,&n,&k,&_DOne,av,&a->lda,bv,&b->lda,&_DZero,cv,&c->lda));
25929566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&av));
25939566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(B,&bv));
25949566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(C,&cv));
25959566063dSJacob Faibussowitsch   PetscCall(PetscLogFlops(1.0*m*n*k + 1.0*m*n*(k-1)));
2596a9fe9ddaSSatish Balay   PetscFunctionReturn(0);
2597a9fe9ddaSSatish Balay }
2598985db425SBarry Smith 
25994222ddf1SHong Zhang /* ----------------------------------------------- */
26004222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AB(Mat C)
26014222ddf1SHong Zhang {
26024222ddf1SHong Zhang   PetscFunctionBegin;
26034222ddf1SHong Zhang   C->ops->matmultsymbolic = MatMatMultSymbolic_SeqDense_SeqDense;
26044222ddf1SHong Zhang   C->ops->productsymbolic = MatProductSymbolic_AB;
26054222ddf1SHong Zhang   PetscFunctionReturn(0);
26064222ddf1SHong Zhang }
26074222ddf1SHong Zhang 
26084222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_AtB(Mat C)
26094222ddf1SHong Zhang {
26104222ddf1SHong Zhang   PetscFunctionBegin;
26114222ddf1SHong Zhang   C->ops->transposematmultsymbolic = MatTransposeMatMultSymbolic_SeqDense_SeqDense;
26124222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_AtB;
26134222ddf1SHong Zhang   PetscFunctionReturn(0);
26144222ddf1SHong Zhang }
26154222ddf1SHong Zhang 
26164222ddf1SHong Zhang static PetscErrorCode MatProductSetFromOptions_SeqDense_ABt(Mat C)
26174222ddf1SHong Zhang {
26184222ddf1SHong Zhang   PetscFunctionBegin;
26194222ddf1SHong Zhang   C->ops->mattransposemultsymbolic = MatMatTransposeMultSymbolic_SeqDense_SeqDense;
26204222ddf1SHong Zhang   C->ops->productsymbolic          = MatProductSymbolic_ABt;
26214222ddf1SHong Zhang   PetscFunctionReturn(0);
26224222ddf1SHong Zhang }
26234222ddf1SHong Zhang 
26244222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_SeqDense(Mat C)
26254222ddf1SHong Zhang {
26264222ddf1SHong Zhang   Mat_Product    *product = C->product;
26274222ddf1SHong Zhang 
26284222ddf1SHong Zhang   PetscFunctionBegin;
26294222ddf1SHong Zhang   switch (product->type) {
26304222ddf1SHong Zhang   case MATPRODUCT_AB:
26319566063dSJacob Faibussowitsch     PetscCall(MatProductSetFromOptions_SeqDense_AB(C));
26324222ddf1SHong Zhang     break;
26334222ddf1SHong Zhang   case MATPRODUCT_AtB:
26349566063dSJacob Faibussowitsch     PetscCall(MatProductSetFromOptions_SeqDense_AtB(C));
26354222ddf1SHong Zhang     break;
26364222ddf1SHong Zhang   case MATPRODUCT_ABt:
26379566063dSJacob Faibussowitsch     PetscCall(MatProductSetFromOptions_SeqDense_ABt(C));
26384222ddf1SHong Zhang     break;
26396718818eSStefano Zampini   default:
26404222ddf1SHong Zhang     break;
26414222ddf1SHong Zhang   }
26424222ddf1SHong Zhang   PetscFunctionReturn(0);
26434222ddf1SHong Zhang }
26444222ddf1SHong Zhang /* ----------------------------------------------- */
26454222ddf1SHong Zhang 
2646e0877f53SBarry Smith static PetscErrorCode MatGetRowMax_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;
2651ca15aa20SStefano Zampini   const PetscScalar *aa;
2652985db425SBarry Smith 
2653985db425SBarry Smith   PetscFunctionBegin;
265428b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
26559566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v,&x));
26569566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v,&p));
26579566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&aa));
265808401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2659985db425SBarry Smith   for (i=0; i<m; i++) {
2660985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2661985db425SBarry Smith     for (j=1; j<n; j++) {
2662ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) < PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2663985db425SBarry Smith     }
2664985db425SBarry Smith   }
26659566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&aa));
26669566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v,&x));
2667985db425SBarry Smith   PetscFunctionReturn(0);
2668985db425SBarry Smith }
2669985db425SBarry Smith 
2670e0877f53SBarry Smith static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A,Vec v,PetscInt idx[])
2671985db425SBarry Smith {
2672985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2673d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2674985db425SBarry Smith   PetscScalar       *x;
2675985db425SBarry Smith   PetscReal         atmp;
2676ca15aa20SStefano Zampini   const PetscScalar *aa;
2677985db425SBarry Smith 
2678985db425SBarry Smith   PetscFunctionBegin;
267928b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
26809566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v,&x));
26819566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v,&p));
26829566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&aa));
268308401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2684985db425SBarry Smith   for (i=0; i<m; i++) {
26859189402eSHong Zhang     x[i] = PetscAbsScalar(aa[i]);
2686985db425SBarry Smith     for (j=1; j<n; j++) {
2687ca15aa20SStefano Zampini       atmp = PetscAbsScalar(aa[i+a->lda*j]);
2688985db425SBarry Smith       if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = j;}
2689985db425SBarry Smith     }
2690985db425SBarry Smith   }
26919566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&aa));
26929566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v,&x));
2693985db425SBarry Smith   PetscFunctionReturn(0);
2694985db425SBarry Smith }
2695985db425SBarry Smith 
2696e0877f53SBarry Smith static PetscErrorCode MatGetRowMin_SeqDense(Mat A,Vec v,PetscInt idx[])
2697985db425SBarry Smith {
2698985db425SBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
2699d0f46423SBarry Smith   PetscInt          i,j,m = A->rmap->n,n = A->cmap->n,p;
2700985db425SBarry Smith   PetscScalar       *x;
2701ca15aa20SStefano Zampini   const PetscScalar *aa;
2702985db425SBarry Smith 
2703985db425SBarry Smith   PetscFunctionBegin;
270428b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
27059566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&aa));
27069566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v,&x));
27079566063dSJacob Faibussowitsch   PetscCall(VecGetLocalSize(v,&p));
270808401ef6SPierre Jolivet   PetscCheck(p == A->rmap->n,PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector");
2709985db425SBarry Smith   for (i=0; i<m; i++) {
2710985db425SBarry Smith     x[i] = aa[i]; if (idx) idx[i] = 0;
2711985db425SBarry Smith     for (j=1; j<n; j++) {
2712ca15aa20SStefano Zampini       if (PetscRealPart(x[i]) > PetscRealPart(aa[i+a->lda*j])) {x[i] = aa[i + a->lda*j]; if (idx) idx[i] = j;}
2713985db425SBarry Smith     }
2714985db425SBarry Smith   }
27159566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v,&x));
27169566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&aa));
2717985db425SBarry Smith   PetscFunctionReturn(0);
2718985db425SBarry Smith }
2719985db425SBarry Smith 
2720637a0070SStefano Zampini PetscErrorCode MatGetColumnVector_SeqDense(Mat A,Vec v,PetscInt col)
27218d0534beSBarry Smith {
27228d0534beSBarry Smith   Mat_SeqDense      *a = (Mat_SeqDense*)A->data;
27238d0534beSBarry Smith   PetscScalar       *x;
2724ca15aa20SStefano Zampini   const PetscScalar *aa;
27258d0534beSBarry Smith 
27268d0534beSBarry Smith   PetscFunctionBegin;
272728b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
27289566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&aa));
27299566063dSJacob Faibussowitsch   PetscCall(VecGetArray(v,&x));
27309566063dSJacob Faibussowitsch   PetscCall(PetscArraycpy(x,aa+col*a->lda,A->rmap->n));
27319566063dSJacob Faibussowitsch   PetscCall(VecRestoreArray(v,&x));
27329566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&aa));
27338d0534beSBarry Smith   PetscFunctionReturn(0);
27348d0534beSBarry Smith }
27358d0534beSBarry Smith 
2736857cbf51SRichard Tran Mills PETSC_INTERN PetscErrorCode MatGetColumnReductions_SeqDense(Mat A,PetscInt type,PetscReal *reductions)
27370716a85fSBarry Smith {
27380716a85fSBarry Smith   PetscInt          i,j,m,n;
27391683a169SBarry Smith   const PetscScalar *a;
27400716a85fSBarry Smith 
27410716a85fSBarry Smith   PetscFunctionBegin;
27429566063dSJacob Faibussowitsch   PetscCall(MatGetSize(A,&m,&n));
27439566063dSJacob Faibussowitsch   PetscCall(PetscArrayzero(reductions,n));
27449566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&a));
2745857cbf51SRichard Tran Mills   if (type == NORM_2) {
27460716a85fSBarry Smith     for (i=0; i<n; i++) {
27470716a85fSBarry Smith       for (j=0; j<m; j++) {
2748a873a8cdSSam Reynolds         reductions[i] += PetscAbsScalar(a[j]*a[j]);
27490716a85fSBarry Smith       }
27500716a85fSBarry Smith       a += m;
27510716a85fSBarry Smith     }
2752857cbf51SRichard Tran Mills   } else if (type == NORM_1) {
27530716a85fSBarry Smith     for (i=0; i<n; i++) {
27540716a85fSBarry Smith       for (j=0; j<m; j++) {
2755a873a8cdSSam Reynolds         reductions[i] += PetscAbsScalar(a[j]);
27560716a85fSBarry Smith       }
27570716a85fSBarry Smith       a += m;
27580716a85fSBarry Smith     }
2759857cbf51SRichard Tran Mills   } else if (type == NORM_INFINITY) {
27600716a85fSBarry Smith     for (i=0; i<n; i++) {
27610716a85fSBarry Smith       for (j=0; j<m; j++) {
2762a873a8cdSSam Reynolds         reductions[i] = PetscMax(PetscAbsScalar(a[j]),reductions[i]);
27630716a85fSBarry Smith       }
27640716a85fSBarry Smith       a += m;
27650716a85fSBarry Smith     }
2766857cbf51SRichard Tran Mills   } else if (type == REDUCTION_SUM_REALPART || type == REDUCTION_MEAN_REALPART) {
2767a873a8cdSSam Reynolds     for (i=0; i<n; i++) {
2768a873a8cdSSam Reynolds       for (j=0; j<m; j++) {
2769857cbf51SRichard Tran Mills         reductions[i] += PetscRealPart(a[j]);
2770a873a8cdSSam Reynolds       }
2771a873a8cdSSam Reynolds       a += m;
2772a873a8cdSSam Reynolds     }
2773857cbf51SRichard Tran Mills   } else if (type == REDUCTION_SUM_IMAGINARYPART || type == REDUCTION_MEAN_IMAGINARYPART) {
2774857cbf51SRichard Tran Mills     for (i=0; i<n; i++) {
2775857cbf51SRichard Tran Mills       for (j=0; j<m; j++) {
2776857cbf51SRichard Tran Mills         reductions[i] += PetscImaginaryPart(a[j]);
2777857cbf51SRichard Tran Mills       }
2778857cbf51SRichard Tran Mills       a += m;
2779857cbf51SRichard Tran Mills     }
2780857cbf51SRichard Tran Mills   } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Unknown reduction type");
27819566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&a));
2782857cbf51SRichard Tran Mills   if (type == NORM_2) {
2783a873a8cdSSam Reynolds     for (i=0; i<n; i++) reductions[i] = PetscSqrtReal(reductions[i]);
2784857cbf51SRichard Tran Mills   } else if (type == REDUCTION_MEAN_REALPART || type == REDUCTION_MEAN_IMAGINARYPART) {
2785a873a8cdSSam Reynolds     for (i=0; i<n; i++) reductions[i] /= m;
27860716a85fSBarry Smith   }
27870716a85fSBarry Smith   PetscFunctionReturn(0);
27880716a85fSBarry Smith }
27890716a85fSBarry Smith 
279073a71a0fSBarry Smith static PetscErrorCode  MatSetRandom_SeqDense(Mat x,PetscRandom rctx)
279173a71a0fSBarry Smith {
279273a71a0fSBarry Smith   PetscScalar    *a;
2793637a0070SStefano Zampini   PetscInt       lda,m,n,i,j;
279473a71a0fSBarry Smith 
279573a71a0fSBarry Smith   PetscFunctionBegin;
27969566063dSJacob Faibussowitsch   PetscCall(MatGetSize(x,&m,&n));
27979566063dSJacob Faibussowitsch   PetscCall(MatDenseGetLDA(x,&lda));
27989566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(x,&a));
2799637a0070SStefano Zampini   for (j=0; j<n; j++) {
2800637a0070SStefano Zampini     for (i=0; i<m; i++) {
28019566063dSJacob Faibussowitsch       PetscCall(PetscRandomGetValue(rctx,a+j*lda+i));
2802637a0070SStefano Zampini     }
280373a71a0fSBarry Smith   }
28049566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(x,&a));
280573a71a0fSBarry Smith   PetscFunctionReturn(0);
280673a71a0fSBarry Smith }
280773a71a0fSBarry Smith 
28083b49f96aSBarry Smith static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A,PetscBool  *missing,PetscInt *d)
28093b49f96aSBarry Smith {
28103b49f96aSBarry Smith   PetscFunctionBegin;
28113b49f96aSBarry Smith   *missing = PETSC_FALSE;
28123b49f96aSBarry Smith   PetscFunctionReturn(0);
28133b49f96aSBarry Smith }
281473a71a0fSBarry Smith 
2815ca15aa20SStefano Zampini /* vals is not const */
2816af53bab2SHong Zhang static PetscErrorCode MatDenseGetColumn_SeqDense(Mat A,PetscInt col,PetscScalar **vals)
281786aefd0dSHong Zhang {
281886aefd0dSHong Zhang   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
2819ca15aa20SStefano Zampini   PetscScalar    *v;
282086aefd0dSHong Zhang 
282186aefd0dSHong Zhang   PetscFunctionBegin;
282228b400f6SJacob Faibussowitsch   PetscCheck(!A->factortype,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix");
28239566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,&v));
2824ca15aa20SStefano Zampini   *vals = v+col*a->lda;
28259566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,&v));
282686aefd0dSHong Zhang   PetscFunctionReturn(0);
282786aefd0dSHong Zhang }
282886aefd0dSHong Zhang 
2829af53bab2SHong Zhang static PetscErrorCode MatDenseRestoreColumn_SeqDense(Mat A,PetscScalar **vals)
283086aefd0dSHong Zhang {
283186aefd0dSHong Zhang   PetscFunctionBegin;
2832a5b23f4aSJose E. Roman   *vals = NULL; /* user cannot accidentally use the array later */
283386aefd0dSHong Zhang   PetscFunctionReturn(0);
283486aefd0dSHong Zhang }
2835abc3b08eSStefano Zampini 
2836289bc588SBarry Smith /* -------------------------------------------------------------------*/
2837a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqDense,
2838905e6a2fSBarry Smith                                         MatGetRow_SeqDense,
2839905e6a2fSBarry Smith                                         MatRestoreRow_SeqDense,
2840905e6a2fSBarry Smith                                         MatMult_SeqDense,
284197304618SKris Buschelman                                 /*  4*/ MatMultAdd_SeqDense,
28427c922b88SBarry Smith                                         MatMultTranspose_SeqDense,
28437c922b88SBarry Smith                                         MatMultTransposeAdd_SeqDense,
2844f4259b30SLisandro Dalcin                                         NULL,
2845f4259b30SLisandro Dalcin                                         NULL,
2846f4259b30SLisandro Dalcin                                         NULL,
2847f4259b30SLisandro Dalcin                                 /* 10*/ NULL,
2848905e6a2fSBarry Smith                                         MatLUFactor_SeqDense,
2849905e6a2fSBarry Smith                                         MatCholeskyFactor_SeqDense,
285041f059aeSBarry Smith                                         MatSOR_SeqDense,
2851ec8511deSBarry Smith                                         MatTranspose_SeqDense,
285297304618SKris Buschelman                                 /* 15*/ MatGetInfo_SeqDense,
2853905e6a2fSBarry Smith                                         MatEqual_SeqDense,
2854905e6a2fSBarry Smith                                         MatGetDiagonal_SeqDense,
2855905e6a2fSBarry Smith                                         MatDiagonalScale_SeqDense,
2856905e6a2fSBarry Smith                                         MatNorm_SeqDense,
2857c0aa2d19SHong Zhang                                 /* 20*/ MatAssemblyBegin_SeqDense,
2858c0aa2d19SHong Zhang                                         MatAssemblyEnd_SeqDense,
2859905e6a2fSBarry Smith                                         MatSetOption_SeqDense,
2860905e6a2fSBarry Smith                                         MatZeroEntries_SeqDense,
2861d519adbfSMatthew Knepley                                 /* 24*/ MatZeroRows_SeqDense,
2862f4259b30SLisandro Dalcin                                         NULL,
2863f4259b30SLisandro Dalcin                                         NULL,
2864f4259b30SLisandro Dalcin                                         NULL,
2865f4259b30SLisandro Dalcin                                         NULL,
28664994cf47SJed Brown                                 /* 29*/ MatSetUp_SeqDense,
2867f4259b30SLisandro Dalcin                                         NULL,
2868f4259b30SLisandro Dalcin                                         NULL,
2869f4259b30SLisandro Dalcin                                         NULL,
2870f4259b30SLisandro Dalcin                                         NULL,
2871d519adbfSMatthew Knepley                                 /* 34*/ MatDuplicate_SeqDense,
2872f4259b30SLisandro Dalcin                                         NULL,
2873f4259b30SLisandro Dalcin                                         NULL,
2874f4259b30SLisandro Dalcin                                         NULL,
2875f4259b30SLisandro Dalcin                                         NULL,
2876d519adbfSMatthew Knepley                                 /* 39*/ MatAXPY_SeqDense,
28777dae84e0SHong Zhang                                         MatCreateSubMatrices_SeqDense,
2878f4259b30SLisandro Dalcin                                         NULL,
28794b0e389bSBarry Smith                                         MatGetValues_SeqDense,
2880a5ae1ecdSBarry Smith                                         MatCopy_SeqDense,
2881d519adbfSMatthew Knepley                                 /* 44*/ MatGetRowMax_SeqDense,
2882a5ae1ecdSBarry Smith                                         MatScale_SeqDense,
28832f605a99SJose E. Roman                                         MatShift_SeqDense,
2884f4259b30SLisandro Dalcin                                         NULL,
28853f49a652SStefano Zampini                                         MatZeroRowsColumns_SeqDense,
288673a71a0fSBarry Smith                                 /* 49*/ MatSetRandom_SeqDense,
2887f4259b30SLisandro Dalcin                                         NULL,
2888f4259b30SLisandro Dalcin                                         NULL,
2889f4259b30SLisandro Dalcin                                         NULL,
2890f4259b30SLisandro Dalcin                                         NULL,
2891f4259b30SLisandro Dalcin                                 /* 54*/ NULL,
2892f4259b30SLisandro Dalcin                                         NULL,
2893f4259b30SLisandro Dalcin                                         NULL,
2894f4259b30SLisandro Dalcin                                         NULL,
2895f4259b30SLisandro Dalcin                                         NULL,
2896023c16fcSToby Isaac                                 /* 59*/ MatCreateSubMatrix_SeqDense,
2897e03a110bSBarry Smith                                         MatDestroy_SeqDense,
2898e03a110bSBarry Smith                                         MatView_SeqDense,
2899f4259b30SLisandro Dalcin                                         NULL,
2900f4259b30SLisandro Dalcin                                         NULL,
2901f4259b30SLisandro Dalcin                                 /* 64*/ NULL,
2902f4259b30SLisandro Dalcin                                         NULL,
2903f4259b30SLisandro Dalcin                                         NULL,
2904f4259b30SLisandro Dalcin                                         NULL,
2905f4259b30SLisandro Dalcin                                         NULL,
2906d519adbfSMatthew Knepley                                 /* 69*/ MatGetRowMaxAbs_SeqDense,
2907f4259b30SLisandro Dalcin                                         NULL,
2908f4259b30SLisandro Dalcin                                         NULL,
2909f4259b30SLisandro Dalcin                                         NULL,
2910f4259b30SLisandro Dalcin                                         NULL,
2911f4259b30SLisandro Dalcin                                 /* 74*/ NULL,
2912f4259b30SLisandro Dalcin                                         NULL,
2913f4259b30SLisandro Dalcin                                         NULL,
2914f4259b30SLisandro Dalcin                                         NULL,
2915f4259b30SLisandro Dalcin                                         NULL,
2916f4259b30SLisandro Dalcin                                 /* 79*/ NULL,
2917f4259b30SLisandro Dalcin                                         NULL,
2918f4259b30SLisandro Dalcin                                         NULL,
2919f4259b30SLisandro Dalcin                                         NULL,
29205bba2384SShri Abhyankar                                 /* 83*/ MatLoad_SeqDense,
2921637a0070SStefano Zampini                                         MatIsSymmetric_SeqDense,
29221cbb95d3SBarry Smith                                         MatIsHermitian_SeqDense,
2923f4259b30SLisandro Dalcin                                         NULL,
2924f4259b30SLisandro Dalcin                                         NULL,
2925f4259b30SLisandro Dalcin                                         NULL,
2926f4259b30SLisandro Dalcin                                 /* 89*/ NULL,
2927f4259b30SLisandro Dalcin                                         NULL,
2928a9fe9ddaSSatish Balay                                         MatMatMultNumeric_SeqDense_SeqDense,
2929f4259b30SLisandro Dalcin                                         NULL,
2930f4259b30SLisandro Dalcin                                         NULL,
2931f4259b30SLisandro Dalcin                                 /* 94*/ NULL,
2932f4259b30SLisandro Dalcin                                         NULL,
2933f4259b30SLisandro Dalcin                                         NULL,
293469f65d41SStefano Zampini                                         MatMatTransposeMultNumeric_SeqDense_SeqDense,
2935f4259b30SLisandro Dalcin                                         NULL,
29364222ddf1SHong Zhang                                 /* 99*/ MatProductSetFromOptions_SeqDense,
2937f4259b30SLisandro Dalcin                                         NULL,
2938f4259b30SLisandro Dalcin                                         NULL,
2939ba337c44SJed Brown                                         MatConjugate_SeqDense,
2940f4259b30SLisandro Dalcin                                         NULL,
2941f4259b30SLisandro Dalcin                                 /*104*/ NULL,
2942ba337c44SJed Brown                                         MatRealPart_SeqDense,
2943ba337c44SJed Brown                                         MatImaginaryPart_SeqDense,
2944f4259b30SLisandro Dalcin                                         NULL,
2945f4259b30SLisandro Dalcin                                         NULL,
2946f4259b30SLisandro Dalcin                                 /*109*/ NULL,
2947f4259b30SLisandro Dalcin                                         NULL,
29488d0534beSBarry Smith                                         MatGetRowMin_SeqDense,
2949aabbc4fbSShri Abhyankar                                         MatGetColumnVector_SeqDense,
29503b49f96aSBarry Smith                                         MatMissingDiagonal_SeqDense,
2951f4259b30SLisandro Dalcin                                 /*114*/ NULL,
2952f4259b30SLisandro Dalcin                                         NULL,
2953f4259b30SLisandro Dalcin                                         NULL,
2954f4259b30SLisandro Dalcin                                         NULL,
2955f4259b30SLisandro Dalcin                                         NULL,
2956f4259b30SLisandro Dalcin                                 /*119*/ NULL,
2957f4259b30SLisandro Dalcin                                         NULL,
2958f4259b30SLisandro Dalcin                                         NULL,
2959f4259b30SLisandro Dalcin                                         NULL,
2960f4259b30SLisandro Dalcin                                         NULL,
2961f4259b30SLisandro Dalcin                                 /*124*/ NULL,
2962a873a8cdSSam Reynolds                                         MatGetColumnReductions_SeqDense,
2963f4259b30SLisandro Dalcin                                         NULL,
2964f4259b30SLisandro Dalcin                                         NULL,
2965f4259b30SLisandro Dalcin                                         NULL,
2966f4259b30SLisandro Dalcin                                 /*129*/ NULL,
2967f4259b30SLisandro Dalcin                                         NULL,
2968f4259b30SLisandro Dalcin                                         NULL,
296975648e8dSHong Zhang                                         MatTransposeMatMultNumeric_SeqDense_SeqDense,
2970f4259b30SLisandro Dalcin                                         NULL,
2971f4259b30SLisandro Dalcin                                 /*134*/ NULL,
2972f4259b30SLisandro Dalcin                                         NULL,
2973f4259b30SLisandro Dalcin                                         NULL,
2974f4259b30SLisandro Dalcin                                         NULL,
2975f4259b30SLisandro Dalcin                                         NULL,
2976f4259b30SLisandro Dalcin                                 /*139*/ NULL,
2977f4259b30SLisandro Dalcin                                         NULL,
2978f4259b30SLisandro Dalcin                                         NULL,
2979f4259b30SLisandro Dalcin                                         NULL,
2980f4259b30SLisandro Dalcin                                         NULL,
29814222ddf1SHong Zhang                                         MatCreateMPIMatConcatenateSeqMat_SeqDense,
2982f4259b30SLisandro Dalcin                                 /*145*/ NULL,
2983f4259b30SLisandro Dalcin                                         NULL,
2984f4259b30SLisandro Dalcin                                         NULL
2985985db425SBarry Smith };
298690ace30eSBarry Smith 
29874b828684SBarry Smith /*@C
2988fafbff53SBarry Smith    MatCreateSeqDense - Creates a sequential dense matrix that
2989d65003e9SLois Curfman McInnes    is stored in column major order (the usual Fortran 77 manner). Many
2990d65003e9SLois Curfman McInnes    of the matrix operations use the BLAS and LAPACK routines.
2991289bc588SBarry Smith 
2992d083f849SBarry Smith    Collective
2993db81eaa0SLois Curfman McInnes 
299420563c6bSBarry Smith    Input Parameters:
2995db81eaa0SLois Curfman McInnes +  comm - MPI communicator, set to PETSC_COMM_SELF
29960c775827SLois Curfman McInnes .  m - number of rows
299718f449edSLois Curfman McInnes .  n - number of columns
29980298fd71SBarry Smith -  data - optional location of matrix data in column major order.  Set data=NULL for PETSc
2999dfc5480cSLois Curfman McInnes    to control all matrix memory allocation.
300020563c6bSBarry Smith 
300120563c6bSBarry Smith    Output Parameter:
300244cd7ae7SLois Curfman McInnes .  A - the matrix
300320563c6bSBarry Smith 
3004b259b22eSLois Curfman McInnes    Notes:
300518f449edSLois Curfman McInnes    The data input variable is intended primarily for Fortran programmers
300618f449edSLois Curfman McInnes    who wish to allocate their own matrix memory space.  Most users should
30070298fd71SBarry Smith    set data=NULL.
300818f449edSLois Curfman McInnes 
3009027ccd11SLois Curfman McInnes    Level: intermediate
3010027ccd11SLois Curfman McInnes 
3011db781477SPatrick Sanan .seealso: `MatCreate()`, `MatCreateDense()`, `MatSetValues()`
301220563c6bSBarry Smith @*/
30137087cfbeSBarry Smith PetscErrorCode  MatCreateSeqDense(MPI_Comm comm,PetscInt m,PetscInt n,PetscScalar *data,Mat *A)
3014289bc588SBarry Smith {
30153a40ed3dSBarry Smith   PetscFunctionBegin;
30169566063dSJacob Faibussowitsch   PetscCall(MatCreate(comm,A));
30179566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(*A,m,n,m,n));
30189566063dSJacob Faibussowitsch   PetscCall(MatSetType(*A,MATSEQDENSE));
30199566063dSJacob Faibussowitsch   PetscCall(MatSeqDenseSetPreallocation(*A,data));
3020273d9f13SBarry Smith   PetscFunctionReturn(0);
3021273d9f13SBarry Smith }
3022273d9f13SBarry Smith 
3023273d9f13SBarry Smith /*@C
3024273d9f13SBarry Smith    MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements
3025273d9f13SBarry Smith 
3026d083f849SBarry Smith    Collective
3027273d9f13SBarry Smith 
3028273d9f13SBarry Smith    Input Parameters:
30291c4f3114SJed Brown +  B - the matrix
30300298fd71SBarry Smith -  data - the array (or NULL)
3031273d9f13SBarry Smith 
3032273d9f13SBarry Smith    Notes:
3033273d9f13SBarry Smith    The data input variable is intended primarily for Fortran programmers
3034273d9f13SBarry Smith    who wish to allocate their own matrix memory space.  Most users should
3035284134d9SBarry Smith    need not call this routine.
3036273d9f13SBarry Smith 
3037273d9f13SBarry Smith    Level: intermediate
3038273d9f13SBarry Smith 
3039db781477SPatrick Sanan .seealso: `MatCreate()`, `MatCreateDense()`, `MatSetValues()`, `MatDenseSetLDA()`
3040867c911aSBarry Smith 
3041273d9f13SBarry Smith @*/
30427087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation(Mat B,PetscScalar data[])
3043273d9f13SBarry Smith {
3044a23d5eceSKris Buschelman   PetscFunctionBegin;
3045d5ea218eSStefano Zampini   PetscValidHeaderSpecific(B,MAT_CLASSID,1);
3046cac4c232SBarry Smith   PetscTryMethod(B,"MatSeqDenseSetPreallocation_C",(Mat,PetscScalar[]),(B,data));
3047a23d5eceSKris Buschelman   PetscFunctionReturn(0);
3048a23d5eceSKris Buschelman }
3049a23d5eceSKris Buschelman 
30507087cfbeSBarry Smith PetscErrorCode  MatSeqDenseSetPreallocation_SeqDense(Mat B,PetscScalar *data)
3051a23d5eceSKris Buschelman {
3052ad16ce7aSStefano Zampini   Mat_SeqDense   *b = (Mat_SeqDense*)B->data;
3053273d9f13SBarry Smith 
3054273d9f13SBarry Smith   PetscFunctionBegin;
305528b400f6SJacob Faibussowitsch   PetscCheck(!b->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
3056273d9f13SBarry Smith   B->preallocated = PETSC_TRUE;
3057a868139aSShri Abhyankar 
30589566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(B->rmap));
30599566063dSJacob Faibussowitsch   PetscCall(PetscLayoutSetUp(B->cmap));
306034ef9618SShri Abhyankar 
3061ad16ce7aSStefano Zampini   if (b->lda <= 0) b->lda = B->rmap->n;
306286d161a7SShri Abhyankar 
30639e8f95c4SLisandro Dalcin   if (!data) { /* petsc-allocated storage */
30649566063dSJacob Faibussowitsch     if (!b->user_alloc) PetscCall(PetscFree(b->v));
30659566063dSJacob Faibussowitsch     PetscCall(PetscCalloc1((size_t)b->lda*B->cmap->n,&b->v));
30669566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectMemory((PetscObject)B,b->lda*B->cmap->n*sizeof(PetscScalar)));
30672205254eSKarl Rupp 
30689e8f95c4SLisandro Dalcin     b->user_alloc = PETSC_FALSE;
3069273d9f13SBarry Smith   } else { /* user-allocated storage */
30709566063dSJacob Faibussowitsch     if (!b->user_alloc) PetscCall(PetscFree(b->v));
3071273d9f13SBarry Smith     b->v          = data;
3072273d9f13SBarry Smith     b->user_alloc = PETSC_TRUE;
3073273d9f13SBarry Smith   }
30740450473dSBarry Smith   B->assembled = PETSC_TRUE;
3075273d9f13SBarry Smith   PetscFunctionReturn(0);
3076273d9f13SBarry Smith }
3077273d9f13SBarry Smith 
307865b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
3079cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat)
30808baccfbdSHong Zhang {
3081d77f618aSHong Zhang   Mat               mat_elemental;
30821683a169SBarry Smith   const PetscScalar *array;
30831683a169SBarry Smith   PetscScalar       *v_colwise;
3084d77f618aSHong Zhang   PetscInt          M=A->rmap->N,N=A->cmap->N,i,j,k,*rows,*cols;
3085d77f618aSHong Zhang 
30868baccfbdSHong Zhang   PetscFunctionBegin;
30879566063dSJacob Faibussowitsch   PetscCall(PetscMalloc3(M*N,&v_colwise,M,&rows,N,&cols));
30889566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&array));
3089d77f618aSHong Zhang   /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */
3090d77f618aSHong Zhang   k = 0;
3091d77f618aSHong Zhang   for (j=0; j<N; j++) {
3092d77f618aSHong Zhang     cols[j] = j;
3093d77f618aSHong Zhang     for (i=0; i<M; i++) {
3094d77f618aSHong Zhang       v_colwise[j*M+i] = array[k++];
3095d77f618aSHong Zhang     }
3096d77f618aSHong Zhang   }
3097d77f618aSHong Zhang   for (i=0; i<M; i++) {
3098d77f618aSHong Zhang     rows[i] = i;
3099d77f618aSHong Zhang   }
31009566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&array));
3101d77f618aSHong Zhang 
31029566063dSJacob Faibussowitsch   PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental));
31039566063dSJacob Faibussowitsch   PetscCall(MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N));
31049566063dSJacob Faibussowitsch   PetscCall(MatSetType(mat_elemental,MATELEMENTAL));
31059566063dSJacob Faibussowitsch   PetscCall(MatSetUp(mat_elemental));
3106d77f618aSHong Zhang 
3107d77f618aSHong Zhang   /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */
31089566063dSJacob Faibussowitsch   PetscCall(MatSetValues(mat_elemental,M,rows,N,cols,v_colwise,ADD_VALUES));
31099566063dSJacob Faibussowitsch   PetscCall(MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY));
31109566063dSJacob Faibussowitsch   PetscCall(MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY));
31119566063dSJacob Faibussowitsch   PetscCall(PetscFree3(v_colwise,rows,cols));
3112d77f618aSHong Zhang 
3113511c6705SHong Zhang   if (reuse == MAT_INPLACE_MATRIX) {
31149566063dSJacob Faibussowitsch     PetscCall(MatHeaderReplace(A,&mat_elemental));
3115d77f618aSHong Zhang   } else {
3116d77f618aSHong Zhang     *newmat = mat_elemental;
3117d77f618aSHong Zhang   }
31188baccfbdSHong Zhang   PetscFunctionReturn(0);
31198baccfbdSHong Zhang }
312065b80a83SHong Zhang #endif
31218baccfbdSHong Zhang 
312217359960SJose E. Roman PetscErrorCode  MatDenseSetLDA_SeqDense(Mat B,PetscInt lda)
31231b807ce4Svictorle {
31241b807ce4Svictorle   Mat_SeqDense *b = (Mat_SeqDense*)B->data;
31257422da62SJose E. Roman   PetscBool    data;
312621a2c019SBarry Smith 
31271b807ce4Svictorle   PetscFunctionBegin;
31287422da62SJose E. Roman   data = (PetscBool)((B->rmap->n > 0 && B->cmap->n > 0) ? (b->v ? PETSC_TRUE : PETSC_FALSE) : PETSC_FALSE);
3129aed4548fSBarry Smith   PetscCheck(b->user_alloc || !data || b->lda == lda,PETSC_COMM_SELF,PETSC_ERR_ORDER,"LDA cannot be changed after allocation of internal storage");
313008401ef6SPierre 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);
31311b807ce4Svictorle   b->lda = lda;
31321b807ce4Svictorle   PetscFunctionReturn(0);
31331b807ce4Svictorle }
31341b807ce4Svictorle 
3135d528f656SJakub Kruzik PetscErrorCode MatCreateMPIMatConcatenateSeqMat_SeqDense(MPI_Comm comm,Mat inmat,PetscInt n,MatReuse scall,Mat *outmat)
3136d528f656SJakub Kruzik {
3137d528f656SJakub Kruzik   PetscMPIInt    size;
3138d528f656SJakub Kruzik 
3139d528f656SJakub Kruzik   PetscFunctionBegin;
31409566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(comm,&size));
3141d528f656SJakub Kruzik   if (size == 1) {
3142d528f656SJakub Kruzik     if (scall == MAT_INITIAL_MATRIX) {
31439566063dSJacob Faibussowitsch       PetscCall(MatDuplicate(inmat,MAT_COPY_VALUES,outmat));
3144d528f656SJakub Kruzik     } else {
31459566063dSJacob Faibussowitsch       PetscCall(MatCopy(inmat,*outmat,SAME_NONZERO_PATTERN));
3146d528f656SJakub Kruzik     }
3147d528f656SJakub Kruzik   } else {
31489566063dSJacob Faibussowitsch     PetscCall(MatCreateMPIMatConcatenateSeqMat_MPIDense(comm,inmat,n,scall,outmat));
3149d528f656SJakub Kruzik   }
3150d528f656SJakub Kruzik   PetscFunctionReturn(0);
3151d528f656SJakub Kruzik }
3152d528f656SJakub Kruzik 
31536947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVec_SeqDense(Mat A,PetscInt col,Vec *v)
31546947451fSStefano Zampini {
31556947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
31566947451fSStefano Zampini 
31576947451fSStefano Zampini   PetscFunctionBegin;
315828b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
315928b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
31606947451fSStefano Zampini   if (!a->cvec) {
31619566063dSJacob Faibussowitsch     PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec));
31629566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec));
31636947451fSStefano Zampini   }
31646947451fSStefano Zampini   a->vecinuse = col + 1;
31659566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArray(A,(PetscScalar**)&a->ptrinuse));
31669566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda));
31676947451fSStefano Zampini   *v   = a->cvec;
31686947451fSStefano Zampini   PetscFunctionReturn(0);
31696947451fSStefano Zampini }
31706947451fSStefano Zampini 
31716947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVec_SeqDense(Mat A,PetscInt col,Vec *v)
31726947451fSStefano Zampini {
31736947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
31746947451fSStefano Zampini 
31756947451fSStefano Zampini   PetscFunctionBegin;
317628b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first");
317728b400f6SJacob Faibussowitsch   PetscCheck(a->cvec,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
31786947451fSStefano Zampini   a->vecinuse = 0;
31799566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArray(A,(PetscScalar**)&a->ptrinuse));
31809566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
318175f6d85dSStefano Zampini   if (v) *v = NULL;
31826947451fSStefano Zampini   PetscFunctionReturn(0);
31836947451fSStefano Zampini }
31846947451fSStefano Zampini 
31856947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecRead_SeqDense(Mat A,PetscInt col,Vec *v)
31866947451fSStefano Zampini {
31876947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
31886947451fSStefano Zampini 
31896947451fSStefano Zampini   PetscFunctionBegin;
319028b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
319128b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
31926947451fSStefano Zampini   if (!a->cvec) {
31939566063dSJacob Faibussowitsch     PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec));
31949566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec));
31956947451fSStefano Zampini   }
31966947451fSStefano Zampini   a->vecinuse = col + 1;
31979566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayRead(A,&a->ptrinuse));
31989566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda));
31999566063dSJacob Faibussowitsch   PetscCall(VecLockReadPush(a->cvec));
32006947451fSStefano Zampini   *v   = a->cvec;
32016947451fSStefano Zampini   PetscFunctionReturn(0);
32026947451fSStefano Zampini }
32036947451fSStefano Zampini 
32046947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecRead_SeqDense(Mat A,PetscInt col,Vec *v)
32056947451fSStefano Zampini {
32066947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32076947451fSStefano Zampini 
32086947451fSStefano Zampini   PetscFunctionBegin;
320928b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first");
321028b400f6SJacob Faibussowitsch   PetscCheck(a->cvec,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
32116947451fSStefano Zampini   a->vecinuse = 0;
32129566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayRead(A,&a->ptrinuse));
32139566063dSJacob Faibussowitsch   PetscCall(VecLockReadPop(a->cvec));
32149566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
321575f6d85dSStefano Zampini   if (v) *v = NULL;
32166947451fSStefano Zampini   PetscFunctionReturn(0);
32176947451fSStefano Zampini }
32186947451fSStefano Zampini 
32196947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecWrite_SeqDense(Mat A,PetscInt col,Vec *v)
32206947451fSStefano Zampini {
32216947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32226947451fSStefano Zampini 
32236947451fSStefano Zampini   PetscFunctionBegin;
322428b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
322528b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
32266947451fSStefano Zampini   if (!a->cvec) {
32279566063dSJacob Faibussowitsch     PetscCall(VecCreateSeqWithArray(PetscObjectComm((PetscObject)A),A->rmap->bs,A->rmap->n,NULL,&a->cvec));
32289566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)A,(PetscObject)a->cvec));
32296947451fSStefano Zampini   }
32306947451fSStefano Zampini   a->vecinuse = col + 1;
32319566063dSJacob Faibussowitsch   PetscCall(MatDenseGetArrayWrite(A,(PetscScalar**)&a->ptrinuse));
32329566063dSJacob Faibussowitsch   PetscCall(VecPlaceArray(a->cvec,a->ptrinuse + (size_t)col * (size_t)a->lda));
32336947451fSStefano Zampini   *v   = a->cvec;
32346947451fSStefano Zampini   PetscFunctionReturn(0);
32356947451fSStefano Zampini }
32366947451fSStefano Zampini 
32376947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecWrite_SeqDense(Mat A,PetscInt col,Vec *v)
32386947451fSStefano Zampini {
32396947451fSStefano Zampini   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32406947451fSStefano Zampini 
32416947451fSStefano Zampini   PetscFunctionBegin;
324228b400f6SJacob Faibussowitsch   PetscCheck(a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetColumnVec() first");
324328b400f6SJacob Faibussowitsch   PetscCheck(a->cvec,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column vector");
32446947451fSStefano Zampini   a->vecinuse = 0;
32459566063dSJacob Faibussowitsch   PetscCall(MatDenseRestoreArrayWrite(A,(PetscScalar**)&a->ptrinuse));
32469566063dSJacob Faibussowitsch   PetscCall(VecResetArray(a->cvec));
324775f6d85dSStefano Zampini   if (v) *v = NULL;
32486947451fSStefano Zampini   PetscFunctionReturn(0);
32496947451fSStefano Zampini }
32506947451fSStefano Zampini 
32515ea7661aSPierre Jolivet PetscErrorCode MatDenseGetSubMatrix_SeqDense(Mat A,PetscInt cbegin,PetscInt cend,Mat *v)
32525ea7661aSPierre Jolivet {
32535ea7661aSPierre Jolivet   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32545ea7661aSPierre Jolivet 
32555ea7661aSPierre Jolivet   PetscFunctionBegin;
325628b400f6SJacob Faibussowitsch   PetscCheck(!a->vecinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreColumnVec() first");
325728b400f6SJacob Faibussowitsch   PetscCheck(!a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseRestoreSubMatrix() first");
32585ea7661aSPierre Jolivet   if (a->cmat && cend-cbegin != a->cmat->cmap->N) {
32599566063dSJacob Faibussowitsch     PetscCall(MatDestroy(&a->cmat));
32605ea7661aSPierre Jolivet   }
32615ea7661aSPierre Jolivet   if (!a->cmat) {
32629566063dSJacob 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));
32639566063dSJacob Faibussowitsch     PetscCall(PetscLogObjectParent((PetscObject)A,(PetscObject)a->cmat));
32645ea7661aSPierre Jolivet   } else {
32659566063dSJacob Faibussowitsch     PetscCall(MatDensePlaceArray(a->cmat,a->v+(size_t)cbegin*a->lda));
32665ea7661aSPierre Jolivet   }
32679566063dSJacob Faibussowitsch   PetscCall(MatDenseSetLDA(a->cmat,a->lda));
32685ea7661aSPierre Jolivet   a->matinuse = cbegin + 1;
32695ea7661aSPierre Jolivet   *v = a->cmat;
327075f6d85dSStefano Zampini #if defined(PETSC_HAVE_CUDA)
327175f6d85dSStefano Zampini   A->offloadmask = PETSC_OFFLOAD_CPU;
327275f6d85dSStefano Zampini #endif
32735ea7661aSPierre Jolivet   PetscFunctionReturn(0);
32745ea7661aSPierre Jolivet }
32755ea7661aSPierre Jolivet 
32765ea7661aSPierre Jolivet PetscErrorCode MatDenseRestoreSubMatrix_SeqDense(Mat A,Mat *v)
32775ea7661aSPierre Jolivet {
32785ea7661aSPierre Jolivet   Mat_SeqDense   *a = (Mat_SeqDense*)A->data;
32795ea7661aSPierre Jolivet 
32805ea7661aSPierre Jolivet   PetscFunctionBegin;
328128b400f6SJacob Faibussowitsch   PetscCheck(a->matinuse,PETSC_COMM_SELF,PETSC_ERR_ORDER,"Need to call MatDenseGetSubMatrix() first");
328228b400f6SJacob Faibussowitsch   PetscCheck(a->cmat,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Missing internal column matrix");
328308401ef6SPierre Jolivet   PetscCheck(*v == a->cmat,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Not the matrix obtained from MatDenseGetSubMatrix()");
32845ea7661aSPierre Jolivet   a->matinuse = 0;
32859566063dSJacob Faibussowitsch   PetscCall(MatDenseResetArray(a->cmat));
32865ea7661aSPierre Jolivet   *v   = NULL;
32875ea7661aSPierre Jolivet   PetscFunctionReturn(0);
32885ea7661aSPierre Jolivet }
32895ea7661aSPierre Jolivet 
32900bad9183SKris Buschelman /*MC
3291fafad747SKris Buschelman    MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices.
32920bad9183SKris Buschelman 
32930bad9183SKris Buschelman    Options Database Keys:
32940bad9183SKris Buschelman . -mat_type seqdense - sets the matrix type to "seqdense" during a call to MatSetFromOptions()
32950bad9183SKris Buschelman 
32960bad9183SKris Buschelman   Level: beginner
32970bad9183SKris Buschelman 
3298db781477SPatrick Sanan .seealso: `MatCreateSeqDense()`
329989665df3SBarry Smith 
33000bad9183SKris Buschelman M*/
3301ca15aa20SStefano Zampini PetscErrorCode MatCreate_SeqDense(Mat B)
3302273d9f13SBarry Smith {
3303273d9f13SBarry Smith   Mat_SeqDense   *b;
33047c334f02SBarry Smith   PetscMPIInt    size;
3305273d9f13SBarry Smith 
3306273d9f13SBarry Smith   PetscFunctionBegin;
33079566063dSJacob Faibussowitsch   PetscCallMPI(MPI_Comm_size(PetscObjectComm((PetscObject)B),&size));
330808401ef6SPierre Jolivet   PetscCheck(size <= 1,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Comm must be of size 1");
330955659b69SBarry Smith 
33109566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(B,&b));
33119566063dSJacob Faibussowitsch   PetscCall(PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps)));
331244cd7ae7SLois Curfman McInnes   B->data = (void*)b;
331318f449edSLois Curfman McInnes 
3314273d9f13SBarry Smith   b->roworiented = PETSC_TRUE;
33154e220ebcSLois Curfman McInnes 
33169566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatQRFactor_C",MatQRFactor_SeqDense));
33179566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetLDA_C",MatDenseGetLDA_SeqDense));
33189566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseSetLDA_C",MatDenseSetLDA_SeqDense));
33199566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArray_C",MatDenseGetArray_SeqDense));
33209566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArray_C",MatDenseRestoreArray_SeqDense));
33219566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDensePlaceArray_C",MatDensePlaceArray_SeqDense));
33229566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseResetArray_C",MatDenseResetArray_SeqDense));
33239566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseReplaceArray_C",MatDenseReplaceArray_SeqDense));
33249566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayRead_C",MatDenseGetArray_SeqDense));
33259566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayRead_C",MatDenseRestoreArray_SeqDense));
33269566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArrayWrite_C",MatDenseGetArray_SeqDense));
33279566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArrayWrite_C",MatDenseRestoreArray_SeqDense));
33289566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqaij_C",MatConvert_SeqDense_SeqAIJ));
33298baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL)
33309566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_elemental_C",MatConvert_SeqDense_Elemental));
33318baccfbdSHong Zhang #endif
3332d24d4204SJose E. Roman #if defined(PETSC_HAVE_SCALAPACK)
33339566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_scalapack_C",MatConvert_Dense_ScaLAPACK));
3334d24d4204SJose E. Roman #endif
33352bf066beSStefano Zampini #if defined(PETSC_HAVE_CUDA)
33369566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqdensecuda_C",MatConvert_SeqDense_SeqDenseCUDA));
33379566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdensecuda_C",MatProductSetFromOptions_SeqDense));
33389566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdensecuda_seqdense_C",MatProductSetFromOptions_SeqDense));
33399566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqdensecuda_C",MatProductSetFromOptions_SeqDense));
33402bf066beSStefano Zampini #endif
33419566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatSeqDenseSetPreallocation_C",MatSeqDenseSetPreallocation_SeqDense));
33429566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqaij_seqdense_C",MatProductSetFromOptions_SeqAIJ_SeqDense));
33439566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqdense_seqdense_C",MatProductSetFromOptions_SeqDense));
33449566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense));
33459566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatProductSetFromOptions_seqsbaij_seqdense_C",MatProductSetFromOptions_SeqXBAIJ_SeqDense));
334696e6d5c4SRichard Tran Mills 
33479566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumn_C",MatDenseGetColumn_SeqDense));
33489566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumn_C",MatDenseRestoreColumn_SeqDense));
33499566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVec_C",MatDenseGetColumnVec_SeqDense));
33509566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVec_C",MatDenseRestoreColumnVec_SeqDense));
33519566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVecRead_C",MatDenseGetColumnVecRead_SeqDense));
33529566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVecRead_C",MatDenseRestoreColumnVecRead_SeqDense));
33539566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetColumnVecWrite_C",MatDenseGetColumnVecWrite_SeqDense));
33549566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreColumnVecWrite_C",MatDenseRestoreColumnVecWrite_SeqDense));
33559566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseGetSubMatrix_C",MatDenseGetSubMatrix_SeqDense));
33569566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreSubMatrix_C",MatDenseRestoreSubMatrix_SeqDense));
33579566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)B,MATSEQDENSE));
33583a40ed3dSBarry Smith   PetscFunctionReturn(0);
3359289bc588SBarry Smith }
336086aefd0dSHong Zhang 
336186aefd0dSHong Zhang /*@C
3362af53bab2SHong 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.
336386aefd0dSHong Zhang 
336486aefd0dSHong Zhang    Not Collective
336586aefd0dSHong Zhang 
33665ea7661aSPierre Jolivet    Input Parameters:
336786aefd0dSHong Zhang +  mat - a MATSEQDENSE or MATMPIDENSE matrix
336886aefd0dSHong Zhang -  col - column index
336986aefd0dSHong Zhang 
337086aefd0dSHong Zhang    Output Parameter:
337186aefd0dSHong Zhang .  vals - pointer to the data
337286aefd0dSHong Zhang 
337386aefd0dSHong Zhang    Level: intermediate
337486aefd0dSHong Zhang 
3375db781477SPatrick Sanan .seealso: `MatDenseRestoreColumn()`
337686aefd0dSHong Zhang @*/
337786aefd0dSHong Zhang PetscErrorCode MatDenseGetColumn(Mat A,PetscInt col,PetscScalar **vals)
337886aefd0dSHong Zhang {
337986aefd0dSHong Zhang   PetscFunctionBegin;
3380d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3381d5ea218eSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
3382d5ea218eSStefano Zampini   PetscValidPointer(vals,3);
3383cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetColumn_C",(Mat,PetscInt,PetscScalar**),(A,col,vals));
338486aefd0dSHong Zhang   PetscFunctionReturn(0);
338586aefd0dSHong Zhang }
338686aefd0dSHong Zhang 
338786aefd0dSHong Zhang /*@C
338886aefd0dSHong Zhang    MatDenseRestoreColumn - returns access to a column of a dense matrix which is returned by MatDenseGetColumn().
338986aefd0dSHong Zhang 
339086aefd0dSHong Zhang    Not Collective
339186aefd0dSHong Zhang 
339286aefd0dSHong Zhang    Input Parameter:
339386aefd0dSHong Zhang .  mat - a MATSEQDENSE or MATMPIDENSE matrix
339486aefd0dSHong Zhang 
339586aefd0dSHong Zhang    Output Parameter:
339686aefd0dSHong Zhang .  vals - pointer to the data
339786aefd0dSHong Zhang 
339886aefd0dSHong Zhang    Level: intermediate
339986aefd0dSHong Zhang 
3400db781477SPatrick Sanan .seealso: `MatDenseGetColumn()`
340186aefd0dSHong Zhang @*/
340286aefd0dSHong Zhang PetscErrorCode MatDenseRestoreColumn(Mat A,PetscScalar **vals)
340386aefd0dSHong Zhang {
340486aefd0dSHong Zhang   PetscFunctionBegin;
3405d5ea218eSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
3406d5ea218eSStefano Zampini   PetscValidPointer(vals,2);
3407cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreColumn_C",(Mat,PetscScalar**),(A,vals));
340886aefd0dSHong Zhang   PetscFunctionReturn(0);
340986aefd0dSHong Zhang }
34106947451fSStefano Zampini 
34110f74d2c1SSatish Balay /*@
34126947451fSStefano Zampini    MatDenseGetColumnVec - Gives read-write access to a column of a dense matrix, represented as a Vec.
34136947451fSStefano Zampini 
34146947451fSStefano Zampini    Collective
34156947451fSStefano Zampini 
34165ea7661aSPierre Jolivet    Input Parameters:
34176947451fSStefano Zampini +  mat - the Mat object
34186947451fSStefano Zampini -  col - the column index
34196947451fSStefano Zampini 
34206947451fSStefano Zampini    Output Parameter:
34216947451fSStefano Zampini .  v - the vector
34226947451fSStefano Zampini 
34236947451fSStefano Zampini    Notes:
34246947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVec() when the vector is no longer needed.
34256947451fSStefano Zampini      Use MatDenseGetColumnVecRead() to obtain read-only access or MatDenseGetColumnVecWrite() for write-only access.
34266947451fSStefano Zampini 
34276947451fSStefano Zampini    Level: intermediate
34286947451fSStefano Zampini 
3429db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
34306947451fSStefano Zampini @*/
34316947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVec(Mat A,PetscInt col,Vec *v)
34326947451fSStefano Zampini {
34336947451fSStefano Zampini   PetscFunctionBegin;
34346947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
34356947451fSStefano Zampini   PetscValidType(A,1);
34366947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
34376947451fSStefano Zampini   PetscValidPointer(v,3);
343828b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
34392cf15c64SPierre 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);
3440cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetColumnVec_C",(Mat,PetscInt,Vec*),(A,col,v));
34416947451fSStefano Zampini   PetscFunctionReturn(0);
34426947451fSStefano Zampini }
34436947451fSStefano Zampini 
34440f74d2c1SSatish Balay /*@
34456947451fSStefano Zampini    MatDenseRestoreColumnVec - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVec().
34466947451fSStefano Zampini 
34476947451fSStefano Zampini    Collective
34486947451fSStefano Zampini 
34495ea7661aSPierre Jolivet    Input Parameters:
34506947451fSStefano Zampini +  mat - the Mat object
34516947451fSStefano Zampini .  col - the column index
34526947451fSStefano Zampini -  v - the Vec object
34536947451fSStefano Zampini 
34546947451fSStefano Zampini    Level: intermediate
34556947451fSStefano Zampini 
3456db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
34576947451fSStefano Zampini @*/
34586947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVec(Mat A,PetscInt col,Vec *v)
34596947451fSStefano Zampini {
34606947451fSStefano Zampini   PetscFunctionBegin;
34616947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
34626947451fSStefano Zampini   PetscValidType(A,1);
34636947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
346408401ef6SPierre Jolivet   PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
34652cf15c64SPierre 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);
3466cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreColumnVec_C",(Mat,PetscInt,Vec*),(A,col,v));
34676947451fSStefano Zampini   PetscFunctionReturn(0);
34686947451fSStefano Zampini }
34696947451fSStefano Zampini 
34700f74d2c1SSatish Balay /*@
34716947451fSStefano Zampini    MatDenseGetColumnVecRead - Gives read-only access to a column of a dense matrix, represented as a Vec.
34726947451fSStefano Zampini 
34736947451fSStefano Zampini    Collective
34746947451fSStefano Zampini 
34755ea7661aSPierre Jolivet    Input Parameters:
34766947451fSStefano Zampini +  mat - the Mat object
34776947451fSStefano Zampini -  col - the column index
34786947451fSStefano Zampini 
34796947451fSStefano Zampini    Output Parameter:
34806947451fSStefano Zampini .  v - the vector
34816947451fSStefano Zampini 
34826947451fSStefano Zampini    Notes:
34836947451fSStefano Zampini      The vector is owned by PETSc and users cannot modify it.
34846947451fSStefano Zampini      Users need to call MatDenseRestoreColumnVecRead() when the vector is no longer needed.
34856947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecWrite() for write-only access.
34866947451fSStefano Zampini 
34876947451fSStefano Zampini    Level: intermediate
34886947451fSStefano Zampini 
3489db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
34906947451fSStefano Zampini @*/
34916947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecRead(Mat A,PetscInt col,Vec *v)
34926947451fSStefano Zampini {
34936947451fSStefano Zampini   PetscFunctionBegin;
34946947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
34956947451fSStefano Zampini   PetscValidType(A,1);
34966947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
34976947451fSStefano Zampini   PetscValidPointer(v,3);
349828b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
34992cf15c64SPierre 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);
3500cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetColumnVecRead_C",(Mat,PetscInt,Vec*),(A,col,v));
35016947451fSStefano Zampini   PetscFunctionReturn(0);
35026947451fSStefano Zampini }
35036947451fSStefano Zampini 
35040f74d2c1SSatish Balay /*@
35056947451fSStefano Zampini    MatDenseRestoreColumnVecRead - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecRead().
35066947451fSStefano Zampini 
35076947451fSStefano Zampini    Collective
35086947451fSStefano Zampini 
35095ea7661aSPierre Jolivet    Input Parameters:
35106947451fSStefano Zampini +  mat - the Mat object
35116947451fSStefano Zampini .  col - the column index
35126947451fSStefano Zampini -  v - the Vec object
35136947451fSStefano Zampini 
35146947451fSStefano Zampini    Level: intermediate
35156947451fSStefano Zampini 
3516db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecWrite()`
35176947451fSStefano Zampini @*/
35186947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecRead(Mat A,PetscInt col,Vec *v)
35196947451fSStefano Zampini {
35206947451fSStefano Zampini   PetscFunctionBegin;
35216947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
35226947451fSStefano Zampini   PetscValidType(A,1);
35236947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
352408401ef6SPierre Jolivet   PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
35252cf15c64SPierre 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);
3526cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreColumnVecRead_C",(Mat,PetscInt,Vec*),(A,col,v));
35276947451fSStefano Zampini   PetscFunctionReturn(0);
35286947451fSStefano Zampini }
35296947451fSStefano Zampini 
35300f74d2c1SSatish Balay /*@
35316947451fSStefano Zampini    MatDenseGetColumnVecWrite - Gives write-only access to a column of a dense matrix, represented as a Vec.
35326947451fSStefano Zampini 
35336947451fSStefano Zampini    Collective
35346947451fSStefano Zampini 
35355ea7661aSPierre Jolivet    Input Parameters:
35366947451fSStefano Zampini +  mat - the Mat object
35376947451fSStefano Zampini -  col - the column index
35386947451fSStefano Zampini 
35396947451fSStefano Zampini    Output Parameter:
35406947451fSStefano Zampini .  v - the vector
35416947451fSStefano Zampini 
35426947451fSStefano Zampini    Notes:
35436947451fSStefano Zampini      The vector is owned by PETSc. Users need to call MatDenseRestoreColumnVecWrite() when the vector is no longer needed.
35446947451fSStefano Zampini      Use MatDenseGetColumnVec() to obtain read-write access or MatDenseGetColumnVecRead() for read-only access.
35456947451fSStefano Zampini 
35466947451fSStefano Zampini    Level: intermediate
35476947451fSStefano Zampini 
3548db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`, `MatDenseRestoreColumnVecWrite()`
35496947451fSStefano Zampini @*/
35506947451fSStefano Zampini PetscErrorCode MatDenseGetColumnVecWrite(Mat A,PetscInt col,Vec *v)
35516947451fSStefano Zampini {
35526947451fSStefano Zampini   PetscFunctionBegin;
35536947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
35546947451fSStefano Zampini   PetscValidType(A,1);
35556947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
35566947451fSStefano Zampini   PetscValidPointer(v,3);
355728b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
3558aed4548fSBarry 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);
3559cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetColumnVecWrite_C",(Mat,PetscInt,Vec*),(A,col,v));
35606947451fSStefano Zampini   PetscFunctionReturn(0);
35616947451fSStefano Zampini }
35626947451fSStefano Zampini 
35630f74d2c1SSatish Balay /*@
35646947451fSStefano Zampini    MatDenseRestoreColumnVecWrite - Returns access to a column of a dense matrix obtained from MatDenseGetColumnVecWrite().
35656947451fSStefano Zampini 
35666947451fSStefano Zampini    Collective
35676947451fSStefano Zampini 
35685ea7661aSPierre Jolivet    Input Parameters:
35696947451fSStefano Zampini +  mat - the Mat object
35706947451fSStefano Zampini .  col - the column index
35716947451fSStefano Zampini -  v - the Vec object
35726947451fSStefano Zampini 
35736947451fSStefano Zampini    Level: intermediate
35746947451fSStefano Zampini 
3575db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseGetColumnVecRead()`, `MatDenseGetColumnVecWrite()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreColumnVecRead()`
35766947451fSStefano Zampini @*/
35776947451fSStefano Zampini PetscErrorCode MatDenseRestoreColumnVecWrite(Mat A,PetscInt col,Vec *v)
35786947451fSStefano Zampini {
35796947451fSStefano Zampini   PetscFunctionBegin;
35806947451fSStefano Zampini   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
35816947451fSStefano Zampini   PetscValidType(A,1);
35826947451fSStefano Zampini   PetscValidLogicalCollectiveInt(A,col,2);
358308401ef6SPierre Jolivet   PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
3584aed4548fSBarry 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);
3585cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreColumnVecWrite_C",(Mat,PetscInt,Vec*),(A,col,v));
35866947451fSStefano Zampini   PetscFunctionReturn(0);
35876947451fSStefano Zampini }
35885ea7661aSPierre Jolivet 
35890f74d2c1SSatish Balay /*@
35905ea7661aSPierre Jolivet    MatDenseGetSubMatrix - Gives access to a block of columns of a dense matrix, represented as a Mat.
35915ea7661aSPierre Jolivet 
35925ea7661aSPierre Jolivet    Collective
35935ea7661aSPierre Jolivet 
35945ea7661aSPierre Jolivet    Input Parameters:
35955ea7661aSPierre Jolivet +  mat - the Mat object
35965ea7661aSPierre Jolivet .  cbegin - the first index in the block
35972cf15c64SPierre Jolivet -  cend - the index past the last one in the block
35985ea7661aSPierre Jolivet 
35995ea7661aSPierre Jolivet    Output Parameter:
36005ea7661aSPierre Jolivet .  v - the matrix
36015ea7661aSPierre Jolivet 
36025ea7661aSPierre Jolivet    Notes:
36035ea7661aSPierre Jolivet      The matrix is owned by PETSc. Users need to call MatDenseRestoreSubMatrix() when the matrix is no longer needed.
36045ea7661aSPierre Jolivet 
36055ea7661aSPierre Jolivet    Level: intermediate
36065ea7661aSPierre Jolivet 
3607db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseRestoreSubMatrix()`
36085ea7661aSPierre Jolivet @*/
36095ea7661aSPierre Jolivet PetscErrorCode MatDenseGetSubMatrix(Mat A,PetscInt cbegin,PetscInt cend,Mat *v)
36105ea7661aSPierre Jolivet {
36115ea7661aSPierre Jolivet   PetscFunctionBegin;
36125ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
36135ea7661aSPierre Jolivet   PetscValidType(A,1);
36145ea7661aSPierre Jolivet   PetscValidLogicalCollectiveInt(A,cbegin,2);
36155ea7661aSPierre Jolivet   PetscValidLogicalCollectiveInt(A,cend,3);
36165ea7661aSPierre Jolivet   PetscValidPointer(v,4);
361728b400f6SJacob Faibussowitsch   PetscCheck(A->preallocated,PetscObjectComm((PetscObject)A),PETSC_ERR_ORDER,"Matrix not preallocated");
36182cf15c64SPierre 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);
36192cf15c64SPierre 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);
3620cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseGetSubMatrix_C",(Mat,PetscInt,PetscInt,Mat*),(A,cbegin,cend,v));
36215ea7661aSPierre Jolivet   PetscFunctionReturn(0);
36225ea7661aSPierre Jolivet }
36235ea7661aSPierre Jolivet 
36240f74d2c1SSatish Balay /*@
36255ea7661aSPierre Jolivet    MatDenseRestoreSubMatrix - Returns access to a block of columns of a dense matrix obtained from MatDenseGetSubMatrix().
36265ea7661aSPierre Jolivet 
36275ea7661aSPierre Jolivet    Collective
36285ea7661aSPierre Jolivet 
36295ea7661aSPierre Jolivet    Input Parameters:
36305ea7661aSPierre Jolivet +  mat - the Mat object
36315ea7661aSPierre Jolivet -  v - the Mat object
36325ea7661aSPierre Jolivet 
36335ea7661aSPierre Jolivet    Level: intermediate
36345ea7661aSPierre Jolivet 
3635db781477SPatrick Sanan .seealso: `MATDENSE`, `MATDENSECUDA`, `MatDenseGetColumnVec()`, `MatDenseRestoreColumnVec()`, `MatDenseGetSubMatrix()`
36365ea7661aSPierre Jolivet @*/
36375ea7661aSPierre Jolivet PetscErrorCode MatDenseRestoreSubMatrix(Mat A,Mat *v)
36385ea7661aSPierre Jolivet {
36395ea7661aSPierre Jolivet   PetscFunctionBegin;
36405ea7661aSPierre Jolivet   PetscValidHeaderSpecific(A,MAT_CLASSID,1);
36415ea7661aSPierre Jolivet   PetscValidType(A,1);
36425ea7661aSPierre Jolivet   PetscValidPointer(v,2);
3643cac4c232SBarry Smith   PetscUseMethod(A,"MatDenseRestoreSubMatrix_C",(Mat,Mat*),(A,v));
36445ea7661aSPierre Jolivet   PetscFunctionReturn(0);
36455ea7661aSPierre Jolivet }
36468a9c020eSBarry Smith 
36478a9c020eSBarry Smith #include <petscblaslapack.h>
36488a9c020eSBarry Smith #include <petsc/private/kernels/blockinvert.h>
36498a9c020eSBarry Smith 
36508a9c020eSBarry Smith PetscErrorCode MatSeqDenseInvert(Mat A)
36518a9c020eSBarry Smith {
36528a9c020eSBarry Smith   Mat_SeqDense    *a = (Mat_SeqDense*) A->data;
36538a9c020eSBarry Smith   PetscInt        bs = A->rmap->n;
36548a9c020eSBarry Smith   MatScalar       *values = a->v;
36558a9c020eSBarry Smith   const PetscReal shift = 0.0;
36568a9c020eSBarry Smith   PetscBool       allowzeropivot = PetscNot(A->erroriffailure),zeropivotdetected=PETSC_FALSE;
36578a9c020eSBarry Smith 
36588a9c020eSBarry Smith   PetscFunctionBegin;
36598a9c020eSBarry Smith   /* factor and invert each block */
36608a9c020eSBarry Smith   switch (bs) {
36618a9c020eSBarry Smith   case 1:
36628a9c020eSBarry Smith     values[0] = (PetscScalar)1.0 / (values[0] + shift);
36638a9c020eSBarry Smith     break;
36648a9c020eSBarry Smith   case 2:
36658a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_2(values,shift,allowzeropivot,&zeropivotdetected));
36668a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
36678a9c020eSBarry Smith     break;
36688a9c020eSBarry Smith   case 3:
36698a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_3(values,shift,allowzeropivot,&zeropivotdetected));
36708a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
36718a9c020eSBarry Smith     break;
36728a9c020eSBarry Smith   case 4:
36738a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_4(values,shift,allowzeropivot,&zeropivotdetected));
36748a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
36758a9c020eSBarry Smith     break;
36768a9c020eSBarry Smith   case 5:
36778a9c020eSBarry Smith   {
36788a9c020eSBarry Smith     PetscScalar work[25];
36798a9c020eSBarry Smith     PetscInt    ipvt[5];
36808a9c020eSBarry Smith 
36818a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_5(values,ipvt,work,shift,allowzeropivot,&zeropivotdetected));
36828a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
36838a9c020eSBarry Smith   }
36848a9c020eSBarry Smith     break;
36858a9c020eSBarry Smith   case 6:
36868a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_6(values,shift,allowzeropivot,&zeropivotdetected));
36878a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
36888a9c020eSBarry Smith     break;
36898a9c020eSBarry Smith   case 7:
36908a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A_7(values,shift,allowzeropivot,&zeropivotdetected));
36918a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
36928a9c020eSBarry Smith     break;
36938a9c020eSBarry Smith   default:
36948a9c020eSBarry Smith   {
36958a9c020eSBarry Smith     PetscInt    *v_pivots,*IJ,j;
36968a9c020eSBarry Smith     PetscScalar *v_work;
36978a9c020eSBarry Smith 
36988a9c020eSBarry Smith     PetscCall(PetscMalloc3(bs,&v_work,bs,&v_pivots,bs,&IJ));
36998a9c020eSBarry Smith     for (j=0; j<bs; j++) {
37008a9c020eSBarry Smith       IJ[j] = j;
37018a9c020eSBarry Smith     }
37028a9c020eSBarry Smith     PetscCall(PetscKernel_A_gets_inverse_A(bs,values,v_pivots,v_work,allowzeropivot,&zeropivotdetected));
37038a9c020eSBarry Smith     if (zeropivotdetected) A->factorerrortype = MAT_FACTOR_NUMERIC_ZEROPIVOT;
37048a9c020eSBarry Smith     PetscCall(PetscFree3(v_work,v_pivots,IJ));
37058a9c020eSBarry Smith   }
37068a9c020eSBarry Smith   }
37078a9c020eSBarry Smith   PetscFunctionReturn(0);
37088a9c020eSBarry Smith }
3709