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 118c178816SStefano Zampini static 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; 158c178816SStefano Zampini 168c178816SStefano Zampini PetscFunctionBegin; 178c178816SStefano Zampini if (A->rmap->n != A->cmap->n) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"Cannot symmetrize a rectangular matrix"); 188c178816SStefano Zampini if (!hermitian) { 198c178816SStefano Zampini for (k=0;k<n;k++) { 208c178816SStefano Zampini for (j=k;j<n;j++) { 218c178816SStefano Zampini mat->v[j*mat->lda + k] = mat->v[k*mat->lda + j]; 228c178816SStefano Zampini } 238c178816SStefano Zampini } 248c178816SStefano Zampini } else { 258c178816SStefano Zampini for (k=0;k<n;k++) { 268c178816SStefano Zampini for (j=k;j<n;j++) { 278c178816SStefano Zampini mat->v[j*mat->lda + k] = PetscConj(mat->v[k*mat->lda + j]); 288c178816SStefano Zampini } 298c178816SStefano Zampini } 308c178816SStefano Zampini } 318c178816SStefano Zampini PetscFunctionReturn(0); 328c178816SStefano Zampini } 338c178816SStefano Zampini 3405709791SSatish Balay PETSC_EXTERN PetscErrorCode MatSeqDenseInvertFactors_Private(Mat A) 358c178816SStefano Zampini { 368c178816SStefano Zampini #if defined(PETSC_MISSING_LAPACK_POTRF) 378c178816SStefano Zampini PetscFunctionBegin; 388c178816SStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRF - Lapack routine is unavailable."); 398c178816SStefano Zampini #else 408c178816SStefano Zampini Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 418c178816SStefano Zampini PetscErrorCode ierr; 428c178816SStefano Zampini PetscBLASInt info,n; 438c178816SStefano Zampini 448c178816SStefano Zampini PetscFunctionBegin; 458c178816SStefano Zampini if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 468c178816SStefano Zampini ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr); 478c178816SStefano Zampini if (A->factortype == MAT_FACTOR_LU) { 488c178816SStefano Zampini if (!mat->pivots) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present"); 498c178816SStefano Zampini if (!mat->fwork) { 508c178816SStefano Zampini mat->lfwork = n; 518c178816SStefano Zampini ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr); 528c178816SStefano Zampini ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr); 538c178816SStefano Zampini } 548c178816SStefano Zampini PetscStackCallBLAS("LAPACKgetri",LAPACKgetri_(&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info)); 558c178816SStefano Zampini ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr); /* TODO CHECK FLOPS */ 568c178816SStefano Zampini } else if (A->factortype == MAT_FACTOR_CHOLESKY) { 578c178816SStefano Zampini if (A->spd) { 588c178816SStefano Zampini PetscStackCallBLAS("LAPACKpotri",LAPACKpotri_("L",&n,mat->v,&mat->lda,&info)); 598c178816SStefano Zampini ierr = MatSeqDenseSymmetrize_Private(A,PETSC_TRUE);CHKERRQ(ierr); 608c178816SStefano Zampini #if defined (PETSC_USE_COMPLEX) 618c178816SStefano Zampini } else if (A->hermitian) { 628c178816SStefano Zampini if (!mat->pivots) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present"); 638c178816SStefano Zampini if (!mat->fwork) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Fwork not present"); 648c178816SStefano Zampini PetscStackCallBLAS("LAPACKhetri",LAPACKhetri_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&info)); 658c178816SStefano Zampini ierr = MatSeqDenseSymmetrize_Private(A,PETSC_TRUE);CHKERRQ(ierr); 668c178816SStefano Zampini #endif 678c178816SStefano Zampini } else { /* symmetric case */ 688c178816SStefano Zampini if (!mat->pivots) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Pivots not present"); 698c178816SStefano Zampini if (!mat->fwork) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Fwork not present"); 708c178816SStefano Zampini PetscStackCallBLAS("LAPACKsytri",LAPACKsytri_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&info)); 718c178816SStefano Zampini ierr = MatSeqDenseSymmetrize_Private(A,PETSC_FALSE);CHKERRQ(ierr); 728c178816SStefano Zampini } 738c178816SStefano Zampini if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad Inversion: zero pivot in row %D",(PetscInt)info-1); 748c178816SStefano Zampini ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr); /* TODO CHECK FLOPS */ 758c178816SStefano Zampini } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve"); 768c178816SStefano Zampini #endif 778c178816SStefano Zampini 788c178816SStefano Zampini A->ops->solve = NULL; 798c178816SStefano Zampini A->ops->matsolve = NULL; 808c178816SStefano Zampini A->ops->solvetranspose = NULL; 818c178816SStefano Zampini A->ops->matsolvetranspose = NULL; 828c178816SStefano Zampini A->ops->solveadd = NULL; 838c178816SStefano Zampini A->ops->solvetransposeadd = NULL; 848c178816SStefano Zampini A->factortype = MAT_FACTOR_NONE; 858c178816SStefano Zampini ierr = PetscFree(A->solvertype);CHKERRQ(ierr); 868c178816SStefano Zampini PetscFunctionReturn(0); 878c178816SStefano Zampini } 888c178816SStefano Zampini 893f49a652SStefano Zampini PetscErrorCode MatZeroRowsColumns_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 903f49a652SStefano Zampini { 913f49a652SStefano Zampini PetscErrorCode ierr; 923f49a652SStefano Zampini Mat_SeqDense *l = (Mat_SeqDense*)A->data; 933f49a652SStefano Zampini PetscInt m = l->lda, n = A->cmap->n,r = A->rmap->n, i,j; 943f49a652SStefano Zampini PetscScalar *slot,*bb; 953f49a652SStefano Zampini const PetscScalar *xx; 963f49a652SStefano Zampini 973f49a652SStefano Zampini PetscFunctionBegin; 983f49a652SStefano Zampini #if defined(PETSC_USE_DEBUG) 993f49a652SStefano Zampini for (i=0; i<N; i++) { 1003f49a652SStefano Zampini if (rows[i] < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed"); 1013f49a652SStefano Zampini if (rows[i] >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D requested to be zeroed greater than or equal number of rows %D",rows[i],A->rmap->n); 1023f49a652SStefano Zampini if (rows[i] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Col %D requested to be zeroed greater than or equal number of cols %D",rows[i],A->cmap->n); 1033f49a652SStefano Zampini } 1043f49a652SStefano Zampini #endif 1053f49a652SStefano Zampini 1063f49a652SStefano Zampini /* fix right hand side if needed */ 1073f49a652SStefano Zampini if (x && b) { 1083f49a652SStefano Zampini ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 1093f49a652SStefano Zampini ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 1103f49a652SStefano Zampini for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]]; 1113f49a652SStefano Zampini ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 1123f49a652SStefano Zampini ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 1133f49a652SStefano Zampini } 1143f49a652SStefano Zampini 1153f49a652SStefano Zampini for (i=0; i<N; i++) { 1163f49a652SStefano Zampini slot = l->v + rows[i]*m; 1173f49a652SStefano Zampini ierr = PetscMemzero(slot,r*sizeof(PetscScalar));CHKERRQ(ierr); 1183f49a652SStefano Zampini } 1193f49a652SStefano Zampini for (i=0; i<N; i++) { 1203f49a652SStefano Zampini slot = l->v + rows[i]; 1213f49a652SStefano Zampini for (j=0; j<n; j++) { *slot = 0.0; slot += m;} 1223f49a652SStefano Zampini } 1233f49a652SStefano Zampini if (diag != 0.0) { 1243f49a652SStefano Zampini if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices"); 1253f49a652SStefano Zampini for (i=0; i<N; i++) { 1263f49a652SStefano Zampini slot = l->v + (m+1)*rows[i]; 1273f49a652SStefano Zampini *slot = diag; 1283f49a652SStefano Zampini } 1293f49a652SStefano Zampini } 1303f49a652SStefano Zampini PetscFunctionReturn(0); 1313f49a652SStefano Zampini } 1323f49a652SStefano Zampini 133abc3b08eSStefano Zampini PetscErrorCode MatPtAPNumeric_SeqDense_SeqDense(Mat A,Mat P,Mat C) 134abc3b08eSStefano Zampini { 135abc3b08eSStefano Zampini Mat_SeqDense *c = (Mat_SeqDense*)(C->data); 136abc3b08eSStefano Zampini PetscErrorCode ierr; 137abc3b08eSStefano Zampini 138abc3b08eSStefano Zampini PetscFunctionBegin; 139abc3b08eSStefano Zampini ierr = MatMatMultNumeric_SeqDense_SeqDense(A,P,c->ptapwork);CHKERRQ(ierr); 140abc3b08eSStefano Zampini ierr = MatTransposeMatMultNumeric_SeqDense_SeqDense(P,c->ptapwork,C);CHKERRQ(ierr); 141abc3b08eSStefano Zampini PetscFunctionReturn(0); 142abc3b08eSStefano Zampini } 143abc3b08eSStefano Zampini 144abc3b08eSStefano Zampini PetscErrorCode MatPtAPSymbolic_SeqDense_SeqDense(Mat A,Mat P,PetscReal fill,Mat *C) 145abc3b08eSStefano Zampini { 146abc3b08eSStefano Zampini Mat_SeqDense *c; 147abc3b08eSStefano Zampini PetscErrorCode ierr; 148abc3b08eSStefano Zampini 149abc3b08eSStefano Zampini PetscFunctionBegin; 150abc3b08eSStefano Zampini ierr = MatCreateSeqDense(PetscObjectComm((PetscObject)A),P->cmap->N,P->cmap->N,NULL,C);CHKERRQ(ierr); 151abc3b08eSStefano Zampini c = (Mat_SeqDense*)((*C)->data); 152abc3b08eSStefano Zampini ierr = MatCreateSeqDense(PetscObjectComm((PetscObject)A),A->rmap->N,P->cmap->N,NULL,&c->ptapwork);CHKERRQ(ierr); 153abc3b08eSStefano Zampini PetscFunctionReturn(0); 154abc3b08eSStefano Zampini } 155abc3b08eSStefano Zampini 156150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatPtAP_SeqDense_SeqDense(Mat A,Mat P,MatReuse reuse,PetscReal fill,Mat *C) 157abc3b08eSStefano Zampini { 158abc3b08eSStefano Zampini PetscErrorCode ierr; 159abc3b08eSStefano Zampini 160abc3b08eSStefano Zampini PetscFunctionBegin; 161abc3b08eSStefano Zampini if (reuse == MAT_INITIAL_MATRIX) { 162abc3b08eSStefano Zampini ierr = MatPtAPSymbolic_SeqDense_SeqDense(A,P,fill,C);CHKERRQ(ierr); 163abc3b08eSStefano Zampini } 164abc3b08eSStefano Zampini ierr = PetscLogEventBegin(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 165abc3b08eSStefano Zampini ierr = (*(*C)->ops->ptapnumeric)(A,P,*C);CHKERRQ(ierr); 166abc3b08eSStefano Zampini ierr = PetscLogEventEnd(MAT_PtAPNumeric,A,P,0,0);CHKERRQ(ierr); 167abc3b08eSStefano Zampini PetscFunctionReturn(0); 168abc3b08eSStefano Zampini } 169abc3b08eSStefano Zampini 170cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqAIJ_SeqDense(Mat A,MatType newtype,MatReuse reuse,Mat *newmat) 171b49cda9fSStefano Zampini { 172a13144ffSStefano Zampini Mat B = NULL; 173b49cda9fSStefano Zampini Mat_SeqAIJ *a = (Mat_SeqAIJ*)A->data; 174b49cda9fSStefano Zampini Mat_SeqDense *b; 175b49cda9fSStefano Zampini PetscErrorCode ierr; 176b49cda9fSStefano Zampini PetscInt *ai=a->i,*aj=a->j,m=A->rmap->N,n=A->cmap->N,i; 177b49cda9fSStefano Zampini MatScalar *av=a->a; 178a13144ffSStefano Zampini PetscBool isseqdense; 179b49cda9fSStefano Zampini 180b49cda9fSStefano Zampini PetscFunctionBegin; 181a13144ffSStefano Zampini if (reuse == MAT_REUSE_MATRIX) { 182a13144ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*newmat,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 183a13144ffSStefano Zampini if (!isseqdense) SETERRQ1(PetscObjectComm((PetscObject)*newmat),PETSC_ERR_USER,"Cannot reuse matrix of type %s",((PetscObject)(*newmat))->type); 184a13144ffSStefano Zampini } 185a13144ffSStefano Zampini if (reuse != MAT_REUSE_MATRIX) { 186b49cda9fSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr); 187b49cda9fSStefano Zampini ierr = MatSetSizes(B,m,n,m,n);CHKERRQ(ierr); 188b49cda9fSStefano Zampini ierr = MatSetType(B,MATSEQDENSE);CHKERRQ(ierr); 189b49cda9fSStefano Zampini ierr = MatSeqDenseSetPreallocation(B,NULL);CHKERRQ(ierr); 190b49cda9fSStefano Zampini b = (Mat_SeqDense*)(B->data); 191a13144ffSStefano Zampini } else { 192a13144ffSStefano Zampini b = (Mat_SeqDense*)((*newmat)->data); 193a13144ffSStefano Zampini ierr = PetscMemzero(b->v,m*n*sizeof(PetscScalar));CHKERRQ(ierr); 194a13144ffSStefano Zampini } 195b49cda9fSStefano Zampini for (i=0; i<m; i++) { 196b49cda9fSStefano Zampini PetscInt j; 197b49cda9fSStefano Zampini for (j=0;j<ai[1]-ai[0];j++) { 198b49cda9fSStefano Zampini b->v[*aj*m+i] = *av; 199b49cda9fSStefano Zampini aj++; 200b49cda9fSStefano Zampini av++; 201b49cda9fSStefano Zampini } 202b49cda9fSStefano Zampini ai++; 203b49cda9fSStefano Zampini } 204b49cda9fSStefano Zampini 205511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 206a13144ffSStefano Zampini ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 207a13144ffSStefano Zampini ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 20828be2f97SBarry Smith ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); 209b49cda9fSStefano Zampini } else { 210a13144ffSStefano Zampini if (B) *newmat = B; 211a13144ffSStefano Zampini ierr = MatAssemblyBegin(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 212a13144ffSStefano Zampini ierr = MatAssemblyEnd(*newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 213b49cda9fSStefano Zampini } 214b49cda9fSStefano Zampini PetscFunctionReturn(0); 215b49cda9fSStefano Zampini } 216b49cda9fSStefano Zampini 217cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_SeqAIJ(Mat A, MatType newtype,MatReuse reuse,Mat *newmat) 2186a63e612SBarry Smith { 2196a63e612SBarry Smith Mat B; 2206a63e612SBarry Smith Mat_SeqDense *a = (Mat_SeqDense*)A->data; 2216a63e612SBarry Smith PetscErrorCode ierr; 2229399e1b8SMatthew G. Knepley PetscInt i, j; 2239399e1b8SMatthew G. Knepley PetscInt *rows, *nnz; 2249399e1b8SMatthew G. Knepley MatScalar *aa = a->v, *vals; 2256a63e612SBarry Smith 2266a63e612SBarry Smith PetscFunctionBegin; 227ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&B);CHKERRQ(ierr); 2286a63e612SBarry Smith ierr = MatSetSizes(B,A->rmap->n,A->cmap->n,A->rmap->N,A->cmap->N);CHKERRQ(ierr); 2296a63e612SBarry Smith ierr = MatSetType(B,MATSEQAIJ);CHKERRQ(ierr); 2309399e1b8SMatthew G. Knepley ierr = PetscCalloc3(A->rmap->n,&rows,A->rmap->n,&nnz,A->rmap->n,&vals);CHKERRQ(ierr); 2319399e1b8SMatthew G. Knepley for (j=0; j<A->cmap->n; j++) { 2329399e1b8SMatthew G. Knepley for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || i == j) ++nnz[i]; 2336a63e612SBarry Smith aa += a->lda; 2346a63e612SBarry Smith } 2359399e1b8SMatthew G. Knepley ierr = MatSeqAIJSetPreallocation(B,PETSC_DETERMINE,nnz);CHKERRQ(ierr); 2369399e1b8SMatthew G. Knepley aa = a->v; 2379399e1b8SMatthew G. Knepley for (j=0; j<A->cmap->n; j++) { 2389399e1b8SMatthew G. Knepley PetscInt numRows = 0; 2399399e1b8SMatthew G. Knepley for (i=0; i<A->rmap->n; i++) if (aa[i] != 0.0 || i == j) {rows[numRows] = i; vals[numRows++] = aa[i];} 2409399e1b8SMatthew G. Knepley ierr = MatSetValues(B,numRows,rows,1,&j,vals,INSERT_VALUES);CHKERRQ(ierr); 2419399e1b8SMatthew G. Knepley aa += a->lda; 2429399e1b8SMatthew G. Knepley } 2439399e1b8SMatthew G. Knepley ierr = PetscFree3(rows,nnz,vals);CHKERRQ(ierr); 2446a63e612SBarry Smith ierr = MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2456a63e612SBarry Smith ierr = MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2466a63e612SBarry Smith 247511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 24828be2f97SBarry Smith ierr = MatHeaderReplace(A,&B);CHKERRQ(ierr); 2496a63e612SBarry Smith } else { 2506a63e612SBarry Smith *newmat = B; 2516a63e612SBarry Smith } 2526a63e612SBarry Smith PetscFunctionReturn(0); 2536a63e612SBarry Smith } 2546a63e612SBarry Smith 255e0877f53SBarry Smith static PetscErrorCode MatAXPY_SeqDense(Mat Y,PetscScalar alpha,Mat X,MatStructure str) 2561987afe7SBarry Smith { 2571987afe7SBarry Smith Mat_SeqDense *x = (Mat_SeqDense*)X->data,*y = (Mat_SeqDense*)Y->data; 258f4df32b1SMatthew Knepley PetscScalar oalpha = alpha; 25913f74950SBarry Smith PetscInt j; 2600805154bSBarry Smith PetscBLASInt N,m,ldax,lday,one = 1; 261efee365bSSatish Balay PetscErrorCode ierr; 2623a40ed3dSBarry Smith 2633a40ed3dSBarry Smith PetscFunctionBegin; 264c5df96a5SBarry Smith ierr = PetscBLASIntCast(X->rmap->n*X->cmap->n,&N);CHKERRQ(ierr); 265c5df96a5SBarry Smith ierr = PetscBLASIntCast(X->rmap->n,&m);CHKERRQ(ierr); 266c5df96a5SBarry Smith ierr = PetscBLASIntCast(x->lda,&ldax);CHKERRQ(ierr); 267c5df96a5SBarry Smith ierr = PetscBLASIntCast(y->lda,&lday);CHKERRQ(ierr); 268a5ce6ee0Svictorle if (ldax>m || lday>m) { 269d0f46423SBarry Smith for (j=0; j<X->cmap->n; j++) { 2708b83055fSJed Brown PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&m,&oalpha,x->v+j*ldax,&one,y->v+j*lday,&one)); 271a5ce6ee0Svictorle } 272a5ce6ee0Svictorle } else { 2738b83055fSJed Brown PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&N,&oalpha,x->v,&one,y->v,&one)); 274a5ce6ee0Svictorle } 275a3fa217bSJose E. Roman ierr = PetscObjectStateIncrease((PetscObject)Y);CHKERRQ(ierr); 2760450473dSBarry Smith ierr = PetscLogFlops(PetscMax(2*N-1,0));CHKERRQ(ierr); 2773a40ed3dSBarry Smith PetscFunctionReturn(0); 2781987afe7SBarry Smith } 2791987afe7SBarry Smith 280e0877f53SBarry Smith static PetscErrorCode MatGetInfo_SeqDense(Mat A,MatInfoType flag,MatInfo *info) 281289bc588SBarry Smith { 282d0f46423SBarry Smith PetscInt N = A->rmap->n*A->cmap->n; 2833a40ed3dSBarry Smith 2843a40ed3dSBarry Smith PetscFunctionBegin; 2854e220ebcSLois Curfman McInnes info->block_size = 1.0; 2864e220ebcSLois Curfman McInnes info->nz_allocated = (double)N; 2876de62eeeSBarry Smith info->nz_used = (double)N; 2886de62eeeSBarry Smith info->nz_unneeded = (double)0; 2894e220ebcSLois Curfman McInnes info->assemblies = (double)A->num_ass; 2904e220ebcSLois Curfman McInnes info->mallocs = 0; 2917adad957SLisandro Dalcin info->memory = ((PetscObject)A)->mem; 2924e220ebcSLois Curfman McInnes info->fill_ratio_given = 0; 2934e220ebcSLois Curfman McInnes info->fill_ratio_needed = 0; 2944e220ebcSLois Curfman McInnes info->factor_mallocs = 0; 2953a40ed3dSBarry Smith PetscFunctionReturn(0); 296289bc588SBarry Smith } 297289bc588SBarry Smith 298e0877f53SBarry Smith static PetscErrorCode MatScale_SeqDense(Mat A,PetscScalar alpha) 29980cd9d93SLois Curfman McInnes { 300273d9f13SBarry Smith Mat_SeqDense *a = (Mat_SeqDense*)A->data; 301f4df32b1SMatthew Knepley PetscScalar oalpha = alpha; 302efee365bSSatish Balay PetscErrorCode ierr; 303c5df96a5SBarry Smith PetscBLASInt one = 1,j,nz,lda; 30480cd9d93SLois Curfman McInnes 3053a40ed3dSBarry Smith PetscFunctionBegin; 306c5df96a5SBarry Smith ierr = PetscBLASIntCast(a->lda,&lda);CHKERRQ(ierr); 307d0f46423SBarry Smith if (lda>A->rmap->n) { 308c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->rmap->n,&nz);CHKERRQ(ierr); 309d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 3108b83055fSJed Brown PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&oalpha,a->v+j*lda,&one)); 311a5ce6ee0Svictorle } 312a5ce6ee0Svictorle } else { 313c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->rmap->n*A->cmap->n,&nz);CHKERRQ(ierr); 3148b83055fSJed Brown PetscStackCallBLAS("BLASscal",BLASscal_(&nz,&oalpha,a->v,&one)); 315a5ce6ee0Svictorle } 316efee365bSSatish Balay ierr = PetscLogFlops(nz);CHKERRQ(ierr); 3173a40ed3dSBarry Smith PetscFunctionReturn(0); 31880cd9d93SLois Curfman McInnes } 31980cd9d93SLois Curfman McInnes 320e0877f53SBarry Smith static PetscErrorCode MatIsHermitian_SeqDense(Mat A,PetscReal rtol,PetscBool *fl) 3211cbb95d3SBarry Smith { 3221cbb95d3SBarry Smith Mat_SeqDense *a = (Mat_SeqDense*)A->data; 323d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,N; 3241cbb95d3SBarry Smith PetscScalar *v = a->v; 3251cbb95d3SBarry Smith 3261cbb95d3SBarry Smith PetscFunctionBegin; 3271cbb95d3SBarry Smith *fl = PETSC_FALSE; 328d0f46423SBarry Smith if (A->rmap->n != A->cmap->n) PetscFunctionReturn(0); 3291cbb95d3SBarry Smith N = a->lda; 3301cbb95d3SBarry Smith 3311cbb95d3SBarry Smith for (i=0; i<m; i++) { 3321cbb95d3SBarry Smith for (j=i+1; j<m; j++) { 3331cbb95d3SBarry Smith if (PetscAbsScalar(v[i+j*N] - PetscConj(v[j+i*N])) > rtol) PetscFunctionReturn(0); 3341cbb95d3SBarry Smith } 3351cbb95d3SBarry Smith } 3361cbb95d3SBarry Smith *fl = PETSC_TRUE; 3371cbb95d3SBarry Smith PetscFunctionReturn(0); 3381cbb95d3SBarry Smith } 3391cbb95d3SBarry Smith 340e0877f53SBarry Smith static PetscErrorCode MatDuplicateNoCreate_SeqDense(Mat newi,Mat A,MatDuplicateOption cpvalues) 341b24902e0SBarry Smith { 342b24902e0SBarry Smith Mat_SeqDense *mat = (Mat_SeqDense*)A->data,*l; 343b24902e0SBarry Smith PetscErrorCode ierr; 344b24902e0SBarry Smith PetscInt lda = (PetscInt)mat->lda,j,m; 345b24902e0SBarry Smith 346b24902e0SBarry Smith PetscFunctionBegin; 347aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->rmap,&newi->rmap);CHKERRQ(ierr); 348aa5ea44dSBarry Smith ierr = PetscLayoutReference(A->cmap,&newi->cmap);CHKERRQ(ierr); 3490298fd71SBarry Smith ierr = MatSeqDenseSetPreallocation(newi,NULL);CHKERRQ(ierr); 350b24902e0SBarry Smith if (cpvalues == MAT_COPY_VALUES) { 351b24902e0SBarry Smith l = (Mat_SeqDense*)newi->data; 352d0f46423SBarry Smith if (lda>A->rmap->n) { 353d0f46423SBarry Smith m = A->rmap->n; 354d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 355b24902e0SBarry Smith ierr = PetscMemcpy(l->v+j*m,mat->v+j*lda,m*sizeof(PetscScalar));CHKERRQ(ierr); 356b24902e0SBarry Smith } 357b24902e0SBarry Smith } else { 358d0f46423SBarry Smith ierr = PetscMemcpy(l->v,mat->v,A->rmap->n*A->cmap->n*sizeof(PetscScalar));CHKERRQ(ierr); 359b24902e0SBarry Smith } 360b24902e0SBarry Smith } 361b24902e0SBarry Smith newi->assembled = PETSC_TRUE; 362b24902e0SBarry Smith PetscFunctionReturn(0); 363b24902e0SBarry Smith } 364b24902e0SBarry Smith 365e0877f53SBarry Smith static PetscErrorCode MatDuplicate_SeqDense(Mat A,MatDuplicateOption cpvalues,Mat *newmat) 36602cad45dSBarry Smith { 3676849ba73SBarry Smith PetscErrorCode ierr; 36802cad45dSBarry Smith 3693a40ed3dSBarry Smith PetscFunctionBegin; 370ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),newmat);CHKERRQ(ierr); 371d0f46423SBarry Smith ierr = MatSetSizes(*newmat,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 3725c9eb25fSBarry Smith ierr = MatSetType(*newmat,((PetscObject)A)->type_name);CHKERRQ(ierr); 373719d5645SBarry Smith ierr = MatDuplicateNoCreate_SeqDense(*newmat,A,cpvalues);CHKERRQ(ierr); 374b24902e0SBarry Smith PetscFunctionReturn(0); 375b24902e0SBarry Smith } 376b24902e0SBarry Smith 3776ee01492SSatish Balay 378e0877f53SBarry Smith static PetscErrorCode MatLUFactor_SeqDense(Mat,IS,IS,const MatFactorInfo*); 379719d5645SBarry Smith 380e0877f53SBarry Smith static PetscErrorCode MatLUFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy) 381289bc588SBarry Smith { 3824482741eSBarry Smith MatFactorInfo info; 383a093e273SMatthew Knepley PetscErrorCode ierr; 3843a40ed3dSBarry Smith 3853a40ed3dSBarry Smith PetscFunctionBegin; 386c3ef05f6SHong Zhang ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr); 387719d5645SBarry Smith ierr = MatLUFactor_SeqDense(fact,0,0,&info);CHKERRQ(ierr); 3883a40ed3dSBarry Smith PetscFunctionReturn(0); 389289bc588SBarry Smith } 3906ee01492SSatish Balay 391e0877f53SBarry Smith static PetscErrorCode MatSolve_SeqDense(Mat A,Vec xx,Vec yy) 392289bc588SBarry Smith { 393c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 3946849ba73SBarry Smith PetscErrorCode ierr; 395f1ceaac6SMatthew G. Knepley const PetscScalar *x; 396f1ceaac6SMatthew G. Knepley PetscScalar *y; 397c5df96a5SBarry Smith PetscBLASInt one = 1,info,m; 39867e560aaSBarry Smith 3993a40ed3dSBarry Smith PetscFunctionBegin; 400c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr); 401f1ceaac6SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 4021ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 403d0f46423SBarry Smith ierr = PetscMemcpy(y,x,A->rmap->n*sizeof(PetscScalar));CHKERRQ(ierr); 404d5f3da31SBarry Smith if (A->factortype == MAT_FACTOR_LU) { 405ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_GETRS) 406e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRS - Lapack routine is unavailable."); 407ae7cfcebSSatish Balay #else 4088b83055fSJed Brown PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("N",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info)); 409e32f2f54SBarry Smith if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve"); 410ae7cfcebSSatish Balay #endif 411d5f3da31SBarry Smith } else if (A->factortype == MAT_FACTOR_CHOLESKY) { 412ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_POTRS) 413e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRS - Lapack routine is unavailable."); 414ae7cfcebSSatish Balay #else 415a49dc2a2SStefano Zampini if (A->spd) { 4168b83055fSJed Brown PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info)); 417e32f2f54SBarry Smith if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve"); 418a49dc2a2SStefano Zampini #if defined (PETSC_USE_COMPLEX) 419a49dc2a2SStefano Zampini } else if (A->hermitian) { 420a49dc2a2SStefano Zampini PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info)); 421a49dc2a2SStefano Zampini if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve"); 422a49dc2a2SStefano Zampini #endif 423a49dc2a2SStefano Zampini } else { /* symmetric case */ 424a49dc2a2SStefano Zampini PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info)); 425a49dc2a2SStefano Zampini if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve"); 426a49dc2a2SStefano Zampini } 427ae7cfcebSSatish Balay #endif 4282205254eSKarl Rupp } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve"); 429f1ceaac6SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 4301ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 431dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*A->cmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr); 4323a40ed3dSBarry Smith PetscFunctionReturn(0); 433289bc588SBarry Smith } 4346ee01492SSatish Balay 435e0877f53SBarry Smith static PetscErrorCode MatMatSolve_SeqDense(Mat A,Mat B,Mat X) 43685e2c93fSHong Zhang { 43785e2c93fSHong Zhang Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 43885e2c93fSHong Zhang PetscErrorCode ierr; 43985e2c93fSHong Zhang PetscScalar *b,*x; 440efb80c78SLisandro Dalcin PetscInt n; 441783b601eSJed Brown PetscBLASInt nrhs,info,m; 442bda8bf91SBarry Smith PetscBool flg; 44385e2c93fSHong Zhang 44485e2c93fSHong Zhang PetscFunctionBegin; 445c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr); 4460298fd71SBarry Smith ierr = PetscObjectTypeCompareAny((PetscObject)B,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr); 447ce94432eSBarry Smith if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix B must be MATDENSE matrix"); 4480298fd71SBarry Smith ierr = PetscObjectTypeCompareAny((PetscObject)X,&flg,MATSEQDENSE,MATMPIDENSE,NULL);CHKERRQ(ierr); 449ce94432eSBarry Smith if (!flg) SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Matrix X must be MATDENSE matrix"); 450bda8bf91SBarry Smith 4510298fd71SBarry Smith ierr = MatGetSize(B,NULL,&n);CHKERRQ(ierr); 452c5df96a5SBarry Smith ierr = PetscBLASIntCast(n,&nrhs);CHKERRQ(ierr); 4538c778c55SBarry Smith ierr = MatDenseGetArray(B,&b);CHKERRQ(ierr); 4548c778c55SBarry Smith ierr = MatDenseGetArray(X,&x);CHKERRQ(ierr); 45585e2c93fSHong Zhang 456f272c775SHong Zhang ierr = PetscMemcpy(x,b,m*nrhs*sizeof(PetscScalar));CHKERRQ(ierr); 45785e2c93fSHong Zhang 45885e2c93fSHong Zhang if (A->factortype == MAT_FACTOR_LU) { 45985e2c93fSHong Zhang #if defined(PETSC_MISSING_LAPACK_GETRS) 46085e2c93fSHong Zhang SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRS - Lapack routine is unavailable."); 46185e2c93fSHong Zhang #else 4628b83055fSJed Brown PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("N",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info)); 46385e2c93fSHong Zhang if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"GETRS - Bad solve"); 46485e2c93fSHong Zhang #endif 46585e2c93fSHong Zhang } else if (A->factortype == MAT_FACTOR_CHOLESKY) { 46685e2c93fSHong Zhang #if defined(PETSC_MISSING_LAPACK_POTRS) 46785e2c93fSHong Zhang SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRS - Lapack routine is unavailable."); 46885e2c93fSHong Zhang #else 469a49dc2a2SStefano Zampini if (A->spd) { 4708b83055fSJed Brown PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&nrhs,mat->v,&mat->lda,x,&m,&info)); 47185e2c93fSHong Zhang if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve"); 472a49dc2a2SStefano Zampini #if defined (PETSC_USE_COMPLEX) 473a49dc2a2SStefano Zampini } else if (A->hermitian) { 474a49dc2a2SStefano Zampini PetscStackCallBLAS("LAPACKhetrs",LAPACKhetrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info)); 475a49dc2a2SStefano Zampini if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"HETRS Bad solve"); 476a49dc2a2SStefano Zampini #endif 477a49dc2a2SStefano Zampini } else { /* symmetric case */ 478a49dc2a2SStefano Zampini PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&nrhs,mat->v,&mat->lda,mat->pivots,x,&m,&info)); 479a49dc2a2SStefano Zampini if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve"); 480a49dc2a2SStefano Zampini } 48185e2c93fSHong Zhang #endif 4822205254eSKarl Rupp } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve"); 48385e2c93fSHong Zhang 4848c778c55SBarry Smith ierr = MatDenseRestoreArray(B,&b);CHKERRQ(ierr); 4858c778c55SBarry Smith ierr = MatDenseRestoreArray(X,&x);CHKERRQ(ierr); 48685e2c93fSHong Zhang ierr = PetscLogFlops(nrhs*(2.0*m*m - m));CHKERRQ(ierr); 48785e2c93fSHong Zhang PetscFunctionReturn(0); 48885e2c93fSHong Zhang } 48985e2c93fSHong Zhang 490e0877f53SBarry Smith static PetscErrorCode MatSolveTranspose_SeqDense(Mat A,Vec xx,Vec yy) 491da3a660dSBarry Smith { 492c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 493dfbe8321SBarry Smith PetscErrorCode ierr; 494f1ceaac6SMatthew G. Knepley const PetscScalar *x; 495f1ceaac6SMatthew G. Knepley PetscScalar *y; 496c5df96a5SBarry Smith PetscBLASInt one = 1,info,m; 49767e560aaSBarry Smith 4983a40ed3dSBarry Smith PetscFunctionBegin; 499c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr); 500f1ceaac6SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 5011ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 502d0f46423SBarry Smith ierr = PetscMemcpy(y,x,A->rmap->n*sizeof(PetscScalar));CHKERRQ(ierr); 5038208b9aeSStefano Zampini if (A->factortype == MAT_FACTOR_LU) { 504ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_GETRS) 505e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRS - Lapack routine is unavailable."); 506ae7cfcebSSatish Balay #else 5078b83055fSJed Brown PetscStackCallBLAS("LAPACKgetrs",LAPACKgetrs_("T",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info)); 508e32f2f54SBarry Smith if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS - Bad solve"); 509ae7cfcebSSatish Balay #endif 5108208b9aeSStefano Zampini } else if (A->factortype == MAT_FACTOR_CHOLESKY) { 511ae7cfcebSSatish Balay #if defined(PETSC_MISSING_LAPACK_POTRS) 512e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRS - Lapack routine is unavailable."); 513ae7cfcebSSatish Balay #else 514a49dc2a2SStefano Zampini if (A->spd) { 5158b83055fSJed Brown PetscStackCallBLAS("LAPACKpotrs",LAPACKpotrs_("L",&m,&one,mat->v,&mat->lda,y,&m,&info)); 516a49dc2a2SStefano Zampini if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"POTRS Bad solve"); 517a49dc2a2SStefano Zampini #if defined (PETSC_USE_COMPLEX) 518a49dc2a2SStefano Zampini } else if (A->hermitian) { 519a49dc2a2SStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"MatSolveTranspose with Cholesky/Hermitian not available"); 520ae7cfcebSSatish Balay #endif 521a49dc2a2SStefano Zampini } else { /* symmetric case */ 522a49dc2a2SStefano Zampini PetscStackCallBLAS("LAPACKsytrs",LAPACKsytrs_("L",&m,&one,mat->v,&mat->lda,mat->pivots,y,&m,&info)); 523a49dc2a2SStefano Zampini if (info) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"SYTRS Bad solve"); 524da3a660dSBarry Smith } 525a49dc2a2SStefano Zampini #endif 526a49dc2a2SStefano Zampini } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Matrix must be factored to solve"); 527f1ceaac6SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 5281ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 529dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*A->cmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr); 5303a40ed3dSBarry Smith PetscFunctionReturn(0); 531da3a660dSBarry Smith } 5326ee01492SSatish Balay 533e0877f53SBarry Smith static PetscErrorCode MatSolveAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy) 534da3a660dSBarry Smith { 535dfbe8321SBarry Smith PetscErrorCode ierr; 536f1ceaac6SMatthew G. Knepley const PetscScalar *x; 537f1ceaac6SMatthew G. Knepley PetscScalar *y,sone = 1.0; 538da3a660dSBarry Smith Vec tmp = 0; 53967e560aaSBarry Smith 5403a40ed3dSBarry Smith PetscFunctionBegin; 541f1ceaac6SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 5421ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 543d0f46423SBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 544da3a660dSBarry Smith if (yy == zz) { 54578b31e54SBarry Smith ierr = VecDuplicate(yy,&tmp);CHKERRQ(ierr); 5463bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)tmp);CHKERRQ(ierr); 54778b31e54SBarry Smith ierr = VecCopy(yy,tmp);CHKERRQ(ierr); 548da3a660dSBarry Smith } 5498208b9aeSStefano Zampini ierr = MatSolve_SeqDense(A,xx,yy);CHKERRQ(ierr); 5506bf464f9SBarry Smith if (tmp) { 5516bf464f9SBarry Smith ierr = VecAXPY(yy,sone,tmp);CHKERRQ(ierr); 5526bf464f9SBarry Smith ierr = VecDestroy(&tmp);CHKERRQ(ierr); 5536bf464f9SBarry Smith } else { 5546bf464f9SBarry Smith ierr = VecAXPY(yy,sone,zz);CHKERRQ(ierr); 5556bf464f9SBarry Smith } 556f1ceaac6SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 5571ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 5588208b9aeSStefano Zampini ierr = PetscLogFlops(A->cmap->n);CHKERRQ(ierr); 5593a40ed3dSBarry Smith PetscFunctionReturn(0); 560da3a660dSBarry Smith } 56167e560aaSBarry Smith 562e0877f53SBarry Smith static PetscErrorCode MatSolveTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy) 563da3a660dSBarry Smith { 5646849ba73SBarry Smith PetscErrorCode ierr; 565f1ceaac6SMatthew G. Knepley const PetscScalar *x; 566f1ceaac6SMatthew G. Knepley PetscScalar *y,sone = 1.0; 56789ae1891SBarry Smith Vec tmp = NULL; 56867e560aaSBarry Smith 5693a40ed3dSBarry Smith PetscFunctionBegin; 570d0f46423SBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 571f1ceaac6SMatthew G. Knepley ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 5721ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 573da3a660dSBarry Smith if (yy == zz) { 57478b31e54SBarry Smith ierr = VecDuplicate(yy,&tmp);CHKERRQ(ierr); 5753bb1ff40SBarry Smith ierr = PetscLogObjectParent((PetscObject)A,(PetscObject)tmp);CHKERRQ(ierr); 57678b31e54SBarry Smith ierr = VecCopy(yy,tmp);CHKERRQ(ierr); 577da3a660dSBarry Smith } 5788208b9aeSStefano Zampini ierr = MatSolveTranspose_SeqDense(A,xx,yy);CHKERRQ(ierr); 57990f02eecSBarry Smith if (tmp) { 5802dcb1b2aSMatthew Knepley ierr = VecAXPY(yy,sone,tmp);CHKERRQ(ierr); 5816bf464f9SBarry Smith ierr = VecDestroy(&tmp);CHKERRQ(ierr); 5823a40ed3dSBarry Smith } else { 5832dcb1b2aSMatthew Knepley ierr = VecAXPY(yy,sone,zz);CHKERRQ(ierr); 58490f02eecSBarry Smith } 585f1ceaac6SMatthew G. Knepley ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 5861ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 5878208b9aeSStefano Zampini ierr = PetscLogFlops(A->cmap->n);CHKERRQ(ierr); 5883a40ed3dSBarry Smith PetscFunctionReturn(0); 589da3a660dSBarry Smith } 590db4efbfdSBarry Smith 591db4efbfdSBarry Smith /* ---------------------------------------------------------------*/ 592db4efbfdSBarry Smith /* COMMENT: I have chosen to hide row permutation in the pivots, 593db4efbfdSBarry Smith rather than put it in the Mat->row slot.*/ 594e0877f53SBarry Smith static PetscErrorCode MatLUFactor_SeqDense(Mat A,IS row,IS col,const MatFactorInfo *minfo) 595db4efbfdSBarry Smith { 596db4efbfdSBarry Smith #if defined(PETSC_MISSING_LAPACK_GETRF) 597db4efbfdSBarry Smith PetscFunctionBegin; 598e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"GETRF - Lapack routine is unavailable."); 599db4efbfdSBarry Smith #else 600db4efbfdSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 601db4efbfdSBarry Smith PetscErrorCode ierr; 602db4efbfdSBarry Smith PetscBLASInt n,m,info; 603db4efbfdSBarry Smith 604db4efbfdSBarry Smith PetscFunctionBegin; 605c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr); 606c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr); 607db4efbfdSBarry Smith if (!mat->pivots) { 6088208b9aeSStefano Zampini ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr); 6093bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr); 610db4efbfdSBarry Smith } 611db4efbfdSBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 6128e57ea43SSatish Balay ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 6138b83055fSJed Brown PetscStackCallBLAS("LAPACKgetrf",LAPACKgetrf_(&m,&n,mat->v,&mat->lda,mat->pivots,&info)); 6148e57ea43SSatish Balay ierr = PetscFPTrapPop();CHKERRQ(ierr); 6158e57ea43SSatish Balay 616e32f2f54SBarry Smith if (info<0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_LIB,"Bad argument to LU factorization"); 617e32f2f54SBarry Smith if (info>0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_MAT_LU_ZRPVT,"Bad LU factorization"); 6188208b9aeSStefano Zampini 619db4efbfdSBarry Smith A->ops->solve = MatSolve_SeqDense; 6208208b9aeSStefano Zampini A->ops->matsolve = MatMatSolve_SeqDense; 621db4efbfdSBarry Smith A->ops->solvetranspose = MatSolveTranspose_SeqDense; 622db4efbfdSBarry Smith A->ops->solveadd = MatSolveAdd_SeqDense; 623db4efbfdSBarry Smith A->ops->solvetransposeadd = MatSolveTransposeAdd_SeqDense; 624d5f3da31SBarry Smith A->factortype = MAT_FACTOR_LU; 625db4efbfdSBarry Smith 626f6224b95SHong Zhang ierr = PetscFree(A->solvertype);CHKERRQ(ierr); 627f6224b95SHong Zhang ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr); 628f6224b95SHong Zhang 629dc0b31edSSatish Balay ierr = PetscLogFlops((2.0*A->cmap->n*A->cmap->n*A->cmap->n)/3);CHKERRQ(ierr); 630db4efbfdSBarry Smith #endif 631db4efbfdSBarry Smith PetscFunctionReturn(0); 632db4efbfdSBarry Smith } 633db4efbfdSBarry Smith 634a49dc2a2SStefano Zampini /* Cholesky as L*L^T or L*D*L^T and the symmetric/hermitian complex variants */ 635e0877f53SBarry Smith static PetscErrorCode MatCholeskyFactor_SeqDense(Mat A,IS perm,const MatFactorInfo *factinfo) 636db4efbfdSBarry Smith { 637db4efbfdSBarry Smith #if defined(PETSC_MISSING_LAPACK_POTRF) 638db4efbfdSBarry Smith PetscFunctionBegin; 639e32f2f54SBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"POTRF - Lapack routine is unavailable."); 640db4efbfdSBarry Smith #else 641db4efbfdSBarry Smith Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 642db4efbfdSBarry Smith PetscErrorCode ierr; 643c5df96a5SBarry Smith PetscBLASInt info,n; 644db4efbfdSBarry Smith 645db4efbfdSBarry Smith PetscFunctionBegin; 646c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr); 647db4efbfdSBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 648a49dc2a2SStefano Zampini if (A->spd) { 6498b83055fSJed Brown PetscStackCallBLAS("LAPACKpotrf",LAPACKpotrf_("L",&n,mat->v,&mat->lda,&info)); 650a49dc2a2SStefano Zampini #if defined (PETSC_USE_COMPLEX) 651a49dc2a2SStefano Zampini } else if (A->hermitian) { 652a49dc2a2SStefano Zampini if (!mat->pivots) { 653a49dc2a2SStefano Zampini ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr); 654a49dc2a2SStefano Zampini ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr); 655a49dc2a2SStefano Zampini } 656a49dc2a2SStefano Zampini if (!mat->fwork) { 657a49dc2a2SStefano Zampini PetscScalar dummy; 658a49dc2a2SStefano Zampini 659a49dc2a2SStefano Zampini mat->lfwork = -1; 660a49dc2a2SStefano Zampini PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info)); 661a49dc2a2SStefano Zampini mat->lfwork = (PetscInt)PetscRealPart(dummy); 662a49dc2a2SStefano Zampini ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr); 663a49dc2a2SStefano Zampini ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr); 664a49dc2a2SStefano Zampini } 665a49dc2a2SStefano Zampini PetscStackCallBLAS("LAPACKhetrf",LAPACKhetrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info)); 666a49dc2a2SStefano Zampini #endif 667a49dc2a2SStefano Zampini } else { /* symmetric case */ 668a49dc2a2SStefano Zampini if (!mat->pivots) { 669a49dc2a2SStefano Zampini ierr = PetscMalloc1(A->rmap->n,&mat->pivots);CHKERRQ(ierr); 670a49dc2a2SStefano Zampini ierr = PetscLogObjectMemory((PetscObject)A,A->rmap->n*sizeof(PetscBLASInt));CHKERRQ(ierr); 671a49dc2a2SStefano Zampini } 672a49dc2a2SStefano Zampini if (!mat->fwork) { 673a49dc2a2SStefano Zampini PetscScalar dummy; 674a49dc2a2SStefano Zampini 675a49dc2a2SStefano Zampini mat->lfwork = -1; 676a49dc2a2SStefano Zampini PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,&dummy,&mat->lfwork,&info)); 677a49dc2a2SStefano Zampini mat->lfwork = (PetscInt)PetscRealPart(dummy); 678a49dc2a2SStefano Zampini ierr = PetscMalloc1(mat->lfwork,&mat->fwork);CHKERRQ(ierr); 679a49dc2a2SStefano Zampini ierr = PetscLogObjectMemory((PetscObject)A,mat->lfwork*sizeof(PetscBLASInt));CHKERRQ(ierr); 680a49dc2a2SStefano Zampini } 681a49dc2a2SStefano Zampini PetscStackCallBLAS("LAPACKsytrf",LAPACKsytrf_("L",&n,mat->v,&mat->lda,mat->pivots,mat->fwork,&mat->lfwork,&info)); 682a49dc2a2SStefano Zampini } 683e32f2f54SBarry Smith if (info) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_MAT_CH_ZRPVT,"Bad factorization: zero pivot in row %D",(PetscInt)info-1); 6848208b9aeSStefano Zampini 685db4efbfdSBarry Smith A->ops->solve = MatSolve_SeqDense; 6868208b9aeSStefano Zampini A->ops->matsolve = MatMatSolve_SeqDense; 687db4efbfdSBarry Smith A->ops->solvetranspose = MatSolveTranspose_SeqDense; 688db4efbfdSBarry Smith A->ops->solveadd = MatSolveAdd_SeqDense; 689db4efbfdSBarry Smith A->ops->solvetransposeadd = MatSolveTransposeAdd_SeqDense; 690d5f3da31SBarry Smith A->factortype = MAT_FACTOR_CHOLESKY; 6912205254eSKarl Rupp 692f6224b95SHong Zhang ierr = PetscFree(A->solvertype);CHKERRQ(ierr); 693f6224b95SHong Zhang ierr = PetscStrallocpy(MATSOLVERPETSC,&A->solvertype);CHKERRQ(ierr); 694f6224b95SHong Zhang 695eb3f19e4SBarry Smith ierr = PetscLogFlops((1.0*A->cmap->n*A->cmap->n*A->cmap->n)/3.0);CHKERRQ(ierr); 696db4efbfdSBarry Smith #endif 697db4efbfdSBarry Smith PetscFunctionReturn(0); 698db4efbfdSBarry Smith } 699db4efbfdSBarry Smith 700db4efbfdSBarry Smith 7010481f469SBarry Smith PetscErrorCode MatCholeskyFactorNumeric_SeqDense(Mat fact,Mat A,const MatFactorInfo *info_dummy) 702db4efbfdSBarry Smith { 703db4efbfdSBarry Smith PetscErrorCode ierr; 704db4efbfdSBarry Smith MatFactorInfo info; 705db4efbfdSBarry Smith 706db4efbfdSBarry Smith PetscFunctionBegin; 707db4efbfdSBarry Smith info.fill = 1.0; 7082205254eSKarl Rupp 709c3ef05f6SHong Zhang ierr = MatDuplicateNoCreate_SeqDense(fact,A,MAT_COPY_VALUES);CHKERRQ(ierr); 710719d5645SBarry Smith ierr = MatCholeskyFactor_SeqDense(fact,0,&info);CHKERRQ(ierr); 711db4efbfdSBarry Smith PetscFunctionReturn(0); 712db4efbfdSBarry Smith } 713db4efbfdSBarry Smith 714e0877f53SBarry Smith static PetscErrorCode MatCholeskyFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,const MatFactorInfo *info) 715db4efbfdSBarry Smith { 716db4efbfdSBarry Smith PetscFunctionBegin; 717c3ef05f6SHong Zhang fact->assembled = PETSC_TRUE; 7181bbcc794SSatish Balay fact->preallocated = PETSC_TRUE; 719719d5645SBarry Smith fact->ops->choleskyfactornumeric = MatCholeskyFactorNumeric_SeqDense; 720bd443b22SStefano Zampini fact->ops->solve = MatSolve_SeqDense; 721bd443b22SStefano Zampini fact->ops->matsolve = MatMatSolve_SeqDense; 722bd443b22SStefano Zampini fact->ops->solvetranspose = MatSolveTranspose_SeqDense; 723bd443b22SStefano Zampini fact->ops->solveadd = MatSolveAdd_SeqDense; 724bd443b22SStefano Zampini fact->ops->solvetransposeadd = MatSolveTransposeAdd_SeqDense; 725db4efbfdSBarry Smith PetscFunctionReturn(0); 726db4efbfdSBarry Smith } 727db4efbfdSBarry Smith 728e0877f53SBarry Smith static PetscErrorCode MatLUFactorSymbolic_SeqDense(Mat fact,Mat A,IS row,IS col,const MatFactorInfo *info) 729db4efbfdSBarry Smith { 730db4efbfdSBarry Smith PetscFunctionBegin; 731b66fe19dSMatthew G Knepley fact->preallocated = PETSC_TRUE; 732c3ef05f6SHong Zhang fact->assembled = PETSC_TRUE; 733719d5645SBarry Smith fact->ops->lufactornumeric = MatLUFactorNumeric_SeqDense; 734bd443b22SStefano Zampini fact->ops->solve = MatSolve_SeqDense; 735bd443b22SStefano Zampini fact->ops->matsolve = MatMatSolve_SeqDense; 736bd443b22SStefano Zampini fact->ops->solvetranspose = MatSolveTranspose_SeqDense; 737bd443b22SStefano Zampini fact->ops->solveadd = MatSolveAdd_SeqDense; 738bd443b22SStefano Zampini fact->ops->solvetransposeadd = MatSolveTransposeAdd_SeqDense; 739db4efbfdSBarry Smith PetscFunctionReturn(0); 740db4efbfdSBarry Smith } 741db4efbfdSBarry Smith 742cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatGetFactor_seqdense_petsc(Mat A,MatFactorType ftype,Mat *fact) 743db4efbfdSBarry Smith { 744db4efbfdSBarry Smith PetscErrorCode ierr; 745db4efbfdSBarry Smith 746db4efbfdSBarry Smith PetscFunctionBegin; 747ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),fact);CHKERRQ(ierr); 748db4efbfdSBarry Smith ierr = MatSetSizes(*fact,A->rmap->n,A->cmap->n,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 749db4efbfdSBarry Smith ierr = MatSetType(*fact,((PetscObject)A)->type_name);CHKERRQ(ierr); 750db4efbfdSBarry Smith if (ftype == MAT_FACTOR_LU) { 751db4efbfdSBarry Smith (*fact)->ops->lufactorsymbolic = MatLUFactorSymbolic_SeqDense; 752db4efbfdSBarry Smith } else { 753db4efbfdSBarry Smith (*fact)->ops->choleskyfactorsymbolic = MatCholeskyFactorSymbolic_SeqDense; 754db4efbfdSBarry Smith } 755d5f3da31SBarry Smith (*fact)->factortype = ftype; 75600c67f3bSHong Zhang 75700c67f3bSHong Zhang ierr = PetscFree((*fact)->solvertype);CHKERRQ(ierr); 75800c67f3bSHong Zhang ierr = PetscStrallocpy(MATSOLVERPETSC,&(*fact)->solvertype);CHKERRQ(ierr); 759db4efbfdSBarry Smith PetscFunctionReturn(0); 760db4efbfdSBarry Smith } 761db4efbfdSBarry Smith 762289bc588SBarry Smith /* ------------------------------------------------------------------*/ 763e0877f53SBarry Smith static PetscErrorCode MatSOR_SeqDense(Mat A,Vec bb,PetscReal omega,MatSORType flag,PetscReal shift,PetscInt its,PetscInt lits,Vec xx) 764289bc588SBarry Smith { 765c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 766d9ca1df4SBarry Smith PetscScalar *x,*v = mat->v,zero = 0.0,xt; 767d9ca1df4SBarry Smith const PetscScalar *b; 768dfbe8321SBarry Smith PetscErrorCode ierr; 769d0f46423SBarry Smith PetscInt m = A->rmap->n,i; 770c5df96a5SBarry Smith PetscBLASInt o = 1,bm; 771289bc588SBarry Smith 7723a40ed3dSBarry Smith PetscFunctionBegin; 773422a814eSBarry Smith if (shift == -1) shift = 0.0; /* negative shift indicates do not error on zero diagonal; this code never zeros on zero diagonal */ 774c5df96a5SBarry Smith ierr = PetscBLASIntCast(m,&bm);CHKERRQ(ierr); 775289bc588SBarry Smith if (flag & SOR_ZERO_INITIAL_GUESS) { 77671044d3cSBarry Smith /* this is a hack fix, should have another version without the second BLASdot */ 7772dcb1b2aSMatthew Knepley ierr = VecSet(xx,zero);CHKERRQ(ierr); 778289bc588SBarry Smith } 7791ebc52fbSHong Zhang ierr = VecGetArray(xx,&x);CHKERRQ(ierr); 780d9ca1df4SBarry Smith ierr = VecGetArrayRead(bb,&b);CHKERRQ(ierr); 781b965ef7fSBarry Smith its = its*lits; 782e32f2f54SBarry Smith if (its <= 0) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Relaxation requires global its %D and local its %D both positive",its,lits); 783289bc588SBarry Smith while (its--) { 784fccaa45eSBarry Smith if (flag & SOR_FORWARD_SWEEP || flag & SOR_LOCAL_FORWARD_SWEEP) { 785289bc588SBarry Smith for (i=0; i<m; i++) { 7868b83055fSJed Brown PetscStackCallBLAS("BLASdot",xt = b[i] - BLASdot_(&bm,v+i,&bm,x,&o)); 78755a1b374SBarry Smith x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift); 788289bc588SBarry Smith } 789289bc588SBarry Smith } 790fccaa45eSBarry Smith if (flag & SOR_BACKWARD_SWEEP || flag & SOR_LOCAL_BACKWARD_SWEEP) { 791289bc588SBarry Smith for (i=m-1; i>=0; i--) { 7928b83055fSJed Brown PetscStackCallBLAS("BLASdot",xt = b[i] - BLASdot_(&bm,v+i,&bm,x,&o)); 79355a1b374SBarry Smith x[i] = (1. - omega)*x[i] + omega*(xt+v[i + i*m]*x[i])/(v[i + i*m]+shift); 794289bc588SBarry Smith } 795289bc588SBarry Smith } 796289bc588SBarry Smith } 797d9ca1df4SBarry Smith ierr = VecRestoreArrayRead(bb,&b);CHKERRQ(ierr); 7981ebc52fbSHong Zhang ierr = VecRestoreArray(xx,&x);CHKERRQ(ierr); 7993a40ed3dSBarry Smith PetscFunctionReturn(0); 800289bc588SBarry Smith } 801289bc588SBarry Smith 802289bc588SBarry Smith /* -----------------------------------------------------------------*/ 803cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatMultTranspose_SeqDense(Mat A,Vec xx,Vec yy) 804289bc588SBarry Smith { 805c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 806d9ca1df4SBarry Smith const PetscScalar *v = mat->v,*x; 807d9ca1df4SBarry Smith PetscScalar *y; 808dfbe8321SBarry Smith PetscErrorCode ierr; 8090805154bSBarry Smith PetscBLASInt m, n,_One=1; 810ea709b57SSatish Balay PetscScalar _DOne=1.0,_DZero=0.0; 8113a40ed3dSBarry Smith 8123a40ed3dSBarry Smith PetscFunctionBegin; 813c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr); 814c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr); 815d0f46423SBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 816d9ca1df4SBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 8171ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 8188b83055fSJed Brown PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&mat->lda,x,&_One,&_DZero,y,&_One)); 819d9ca1df4SBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 8201ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 821dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->cmap->n);CHKERRQ(ierr); 8223a40ed3dSBarry Smith PetscFunctionReturn(0); 823289bc588SBarry Smith } 824800995b7SMatthew Knepley 825cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatMult_SeqDense(Mat A,Vec xx,Vec yy) 826289bc588SBarry Smith { 827c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 828d9ca1df4SBarry Smith PetscScalar *y,_DOne=1.0,_DZero=0.0; 829dfbe8321SBarry Smith PetscErrorCode ierr; 8300805154bSBarry Smith PetscBLASInt m, n, _One=1; 831d9ca1df4SBarry Smith const PetscScalar *v = mat->v,*x; 8323a40ed3dSBarry Smith 8333a40ed3dSBarry Smith PetscFunctionBegin; 834c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr); 835c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr); 836d0f46423SBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 837d9ca1df4SBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 8381ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 8398b83055fSJed Brown PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DZero,y,&_One)); 840d9ca1df4SBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 8411ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 842dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n - A->rmap->n);CHKERRQ(ierr); 8433a40ed3dSBarry Smith PetscFunctionReturn(0); 844289bc588SBarry Smith } 8456ee01492SSatish Balay 846cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatMultAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy) 847289bc588SBarry Smith { 848c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 849d9ca1df4SBarry Smith const PetscScalar *v = mat->v,*x; 850d9ca1df4SBarry Smith PetscScalar *y,_DOne=1.0; 851dfbe8321SBarry Smith PetscErrorCode ierr; 8520805154bSBarry Smith PetscBLASInt m, n, _One=1; 8533a40ed3dSBarry Smith 8543a40ed3dSBarry Smith PetscFunctionBegin; 855c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr); 856c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr); 857d0f46423SBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 858600d6d0bSBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 859d9ca1df4SBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 8601ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 8618b83055fSJed Brown PetscStackCallBLAS("BLASgemv",BLASgemv_("N",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One)); 862d9ca1df4SBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 8631ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 864dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr); 8653a40ed3dSBarry Smith PetscFunctionReturn(0); 866289bc588SBarry Smith } 8676ee01492SSatish Balay 868e0877f53SBarry Smith static PetscErrorCode MatMultTransposeAdd_SeqDense(Mat A,Vec xx,Vec zz,Vec yy) 869289bc588SBarry Smith { 870c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 871d9ca1df4SBarry Smith const PetscScalar *v = mat->v,*x; 872d9ca1df4SBarry Smith PetscScalar *y; 873dfbe8321SBarry Smith PetscErrorCode ierr; 8740805154bSBarry Smith PetscBLASInt m, n, _One=1; 87587828ca2SBarry Smith PetscScalar _DOne=1.0; 8763a40ed3dSBarry Smith 8773a40ed3dSBarry Smith PetscFunctionBegin; 878c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr); 879c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->cmap->n,&n);CHKERRQ(ierr); 880d0f46423SBarry Smith if (!A->rmap->n || !A->cmap->n) PetscFunctionReturn(0); 881600d6d0bSBarry Smith if (zz != yy) {ierr = VecCopy(zz,yy);CHKERRQ(ierr);} 882d9ca1df4SBarry Smith ierr = VecGetArrayRead(xx,&x);CHKERRQ(ierr); 8831ebc52fbSHong Zhang ierr = VecGetArray(yy,&y);CHKERRQ(ierr); 8848b83055fSJed Brown PetscStackCallBLAS("BLASgemv",BLASgemv_("T",&m,&n,&_DOne,v,&(mat->lda),x,&_One,&_DOne,y,&_One)); 885d9ca1df4SBarry Smith ierr = VecRestoreArrayRead(xx,&x);CHKERRQ(ierr); 8861ebc52fbSHong Zhang ierr = VecRestoreArray(yy,&y);CHKERRQ(ierr); 887dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*A->rmap->n*A->cmap->n);CHKERRQ(ierr); 8883a40ed3dSBarry Smith PetscFunctionReturn(0); 889289bc588SBarry Smith } 890289bc588SBarry Smith 891289bc588SBarry Smith /* -----------------------------------------------------------------*/ 892e0877f53SBarry Smith static PetscErrorCode MatGetRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals) 893289bc588SBarry Smith { 894c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 89587828ca2SBarry Smith PetscScalar *v; 8966849ba73SBarry Smith PetscErrorCode ierr; 89713f74950SBarry Smith PetscInt i; 89867e560aaSBarry Smith 8993a40ed3dSBarry Smith PetscFunctionBegin; 900d0f46423SBarry Smith *ncols = A->cmap->n; 901289bc588SBarry Smith if (cols) { 902854ce69bSBarry Smith ierr = PetscMalloc1(A->cmap->n+1,cols);CHKERRQ(ierr); 903d0f46423SBarry Smith for (i=0; i<A->cmap->n; i++) (*cols)[i] = i; 904289bc588SBarry Smith } 905289bc588SBarry Smith if (vals) { 906854ce69bSBarry Smith ierr = PetscMalloc1(A->cmap->n+1,vals);CHKERRQ(ierr); 907289bc588SBarry Smith v = mat->v + row; 908d0f46423SBarry Smith for (i=0; i<A->cmap->n; i++) {(*vals)[i] = *v; v += mat->lda;} 909289bc588SBarry Smith } 9103a40ed3dSBarry Smith PetscFunctionReturn(0); 911289bc588SBarry Smith } 9126ee01492SSatish Balay 913e0877f53SBarry Smith static PetscErrorCode MatRestoreRow_SeqDense(Mat A,PetscInt row,PetscInt *ncols,PetscInt **cols,PetscScalar **vals) 914289bc588SBarry Smith { 915dfbe8321SBarry Smith PetscErrorCode ierr; 9166e111a19SKarl Rupp 917606d414cSSatish Balay PetscFunctionBegin; 918606d414cSSatish Balay if (cols) {ierr = PetscFree(*cols);CHKERRQ(ierr);} 919606d414cSSatish Balay if (vals) {ierr = PetscFree(*vals);CHKERRQ(ierr); } 9203a40ed3dSBarry Smith PetscFunctionReturn(0); 921289bc588SBarry Smith } 922289bc588SBarry Smith /* ----------------------------------------------------------------*/ 923e0877f53SBarry Smith static PetscErrorCode MatSetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],const PetscScalar v[],InsertMode addv) 924289bc588SBarry Smith { 925c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 92613f74950SBarry Smith PetscInt i,j,idx=0; 927d6dfbf8fSBarry Smith 9283a40ed3dSBarry Smith PetscFunctionBegin; 929289bc588SBarry Smith if (!mat->roworiented) { 930dbb450caSBarry Smith if (addv == INSERT_VALUES) { 931289bc588SBarry Smith for (j=0; j<n; j++) { 932cddbea37SSatish Balay if (indexn[j] < 0) {idx += m; continue;} 9332515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 934e32f2f54SBarry Smith if (indexn[j] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",indexn[j],A->cmap->n-1); 93558804f6dSBarry Smith #endif 936289bc588SBarry Smith for (i=0; i<m; i++) { 937cddbea37SSatish Balay if (indexm[i] < 0) {idx++; continue;} 9382515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 939e32f2f54SBarry Smith if (indexm[i] >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",indexm[i],A->rmap->n-1); 94058804f6dSBarry Smith #endif 941cddbea37SSatish Balay mat->v[indexn[j]*mat->lda + indexm[i]] = v[idx++]; 942289bc588SBarry Smith } 943289bc588SBarry Smith } 9443a40ed3dSBarry Smith } else { 945289bc588SBarry Smith for (j=0; j<n; j++) { 946cddbea37SSatish Balay if (indexn[j] < 0) {idx += m; continue;} 9472515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 948e32f2f54SBarry Smith if (indexn[j] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",indexn[j],A->cmap->n-1); 94958804f6dSBarry Smith #endif 950289bc588SBarry Smith for (i=0; i<m; i++) { 951cddbea37SSatish Balay if (indexm[i] < 0) {idx++; continue;} 9522515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 953e32f2f54SBarry Smith if (indexm[i] >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",indexm[i],A->rmap->n-1); 95458804f6dSBarry Smith #endif 955cddbea37SSatish Balay mat->v[indexn[j]*mat->lda + indexm[i]] += v[idx++]; 956289bc588SBarry Smith } 957289bc588SBarry Smith } 958289bc588SBarry Smith } 9593a40ed3dSBarry Smith } else { 960dbb450caSBarry Smith if (addv == INSERT_VALUES) { 961e8d4e0b9SBarry Smith for (i=0; i<m; i++) { 962cddbea37SSatish Balay if (indexm[i] < 0) { idx += n; continue;} 9632515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 964e32f2f54SBarry Smith if (indexm[i] >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",indexm[i],A->rmap->n-1); 96558804f6dSBarry Smith #endif 966e8d4e0b9SBarry Smith for (j=0; j<n; j++) { 967cddbea37SSatish Balay if (indexn[j] < 0) { idx++; continue;} 9682515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 969e32f2f54SBarry Smith if (indexn[j] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",indexn[j],A->cmap->n-1); 97058804f6dSBarry Smith #endif 971cddbea37SSatish Balay mat->v[indexn[j]*mat->lda + indexm[i]] = v[idx++]; 972e8d4e0b9SBarry Smith } 973e8d4e0b9SBarry Smith } 9743a40ed3dSBarry Smith } else { 975289bc588SBarry Smith for (i=0; i<m; i++) { 976cddbea37SSatish Balay if (indexm[i] < 0) { idx += n; continue;} 9772515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 978e32f2f54SBarry Smith if (indexm[i] >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row too large: row %D max %D",indexm[i],A->rmap->n-1); 97958804f6dSBarry Smith #endif 980289bc588SBarry Smith for (j=0; j<n; j++) { 981cddbea37SSatish Balay if (indexn[j] < 0) { idx++; continue;} 9822515c552SBarry Smith #if defined(PETSC_USE_DEBUG) 983e32f2f54SBarry Smith if (indexn[j] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column too large: col %D max %D",indexn[j],A->cmap->n-1); 98458804f6dSBarry Smith #endif 985cddbea37SSatish Balay mat->v[indexn[j]*mat->lda + indexm[i]] += v[idx++]; 986289bc588SBarry Smith } 987289bc588SBarry Smith } 988289bc588SBarry Smith } 989e8d4e0b9SBarry Smith } 9903a40ed3dSBarry Smith PetscFunctionReturn(0); 991289bc588SBarry Smith } 992e8d4e0b9SBarry Smith 993e0877f53SBarry Smith static PetscErrorCode MatGetValues_SeqDense(Mat A,PetscInt m,const PetscInt indexm[],PetscInt n,const PetscInt indexn[],PetscScalar v[]) 994ae80bb75SLois Curfman McInnes { 995ae80bb75SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 99613f74950SBarry Smith PetscInt i,j; 997ae80bb75SLois Curfman McInnes 9983a40ed3dSBarry Smith PetscFunctionBegin; 999ae80bb75SLois Curfman McInnes /* row-oriented output */ 1000ae80bb75SLois Curfman McInnes for (i=0; i<m; i++) { 100197e567efSBarry Smith if (indexm[i] < 0) {v += n;continue;} 1002e32f2f54SBarry Smith if (indexm[i] >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D requested larger than number rows %D",indexm[i],A->rmap->n); 1003ae80bb75SLois Curfman McInnes for (j=0; j<n; j++) { 10046f31f424SBarry Smith if (indexn[j] < 0) {v++; continue;} 1005e32f2f54SBarry Smith if (indexn[j] >= A->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Column %D requested larger than number columns %D",indexn[j],A->cmap->n); 100697e567efSBarry Smith *v++ = mat->v[indexn[j]*mat->lda + indexm[i]]; 1007ae80bb75SLois Curfman McInnes } 1008ae80bb75SLois Curfman McInnes } 10093a40ed3dSBarry Smith PetscFunctionReturn(0); 1010ae80bb75SLois Curfman McInnes } 1011ae80bb75SLois Curfman McInnes 1012289bc588SBarry Smith /* -----------------------------------------------------------------*/ 1013289bc588SBarry Smith 1014e0877f53SBarry Smith static PetscErrorCode MatLoad_SeqDense(Mat newmat,PetscViewer viewer) 1015aabbc4fbSShri Abhyankar { 1016aabbc4fbSShri Abhyankar Mat_SeqDense *a; 1017aabbc4fbSShri Abhyankar PetscErrorCode ierr; 1018aabbc4fbSShri Abhyankar PetscInt *scols,i,j,nz,header[4]; 1019aabbc4fbSShri Abhyankar int fd; 1020aabbc4fbSShri Abhyankar PetscMPIInt size; 1021aabbc4fbSShri Abhyankar PetscInt *rowlengths = 0,M,N,*cols,grows,gcols; 1022aabbc4fbSShri Abhyankar PetscScalar *vals,*svals,*v,*w; 1023ce94432eSBarry Smith MPI_Comm comm; 1024aabbc4fbSShri Abhyankar 1025aabbc4fbSShri Abhyankar PetscFunctionBegin; 1026c98fd787SBarry Smith /* force binary viewer to load .info file if it has not yet done so */ 1027c98fd787SBarry Smith ierr = PetscViewerSetUp(viewer);CHKERRQ(ierr); 1028ce94432eSBarry Smith ierr = PetscObjectGetComm((PetscObject)viewer,&comm);CHKERRQ(ierr); 1029aabbc4fbSShri Abhyankar ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 1030aabbc4fbSShri Abhyankar if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"view must have one processor"); 1031aabbc4fbSShri Abhyankar ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 1032aabbc4fbSShri Abhyankar ierr = PetscBinaryRead(fd,header,4,PETSC_INT);CHKERRQ(ierr); 1033aabbc4fbSShri Abhyankar if (header[0] != MAT_FILE_CLASSID) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED,"Not matrix object"); 1034aabbc4fbSShri Abhyankar M = header[1]; N = header[2]; nz = header[3]; 1035aabbc4fbSShri Abhyankar 1036aabbc4fbSShri Abhyankar /* set global size if not set already*/ 1037aabbc4fbSShri Abhyankar if (newmat->rmap->n < 0 && newmat->rmap->N < 0 && newmat->cmap->n < 0 && newmat->cmap->N < 0) { 1038aabbc4fbSShri Abhyankar ierr = MatSetSizes(newmat,M,N,M,N);CHKERRQ(ierr); 1039aabbc4fbSShri Abhyankar } else { 1040aabbc4fbSShri Abhyankar /* if sizes and type are already set, check if the vector global sizes are correct */ 1041aabbc4fbSShri Abhyankar ierr = MatGetSize(newmat,&grows,&gcols);CHKERRQ(ierr); 1042aabbc4fbSShri Abhyankar if (M != grows || N != gcols) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_FILE_UNEXPECTED, "Matrix in file of different length (%d, %d) than the input matrix (%d, %d)",M,N,grows,gcols); 1043aabbc4fbSShri Abhyankar } 1044e6324fbbSBarry Smith a = (Mat_SeqDense*)newmat->data; 1045e6324fbbSBarry Smith if (!a->user_alloc) { 10460298fd71SBarry Smith ierr = MatSeqDenseSetPreallocation(newmat,NULL);CHKERRQ(ierr); 1047e6324fbbSBarry Smith } 1048aabbc4fbSShri Abhyankar 1049aabbc4fbSShri Abhyankar if (nz == MATRIX_BINARY_FORMAT_DENSE) { /* matrix in file is dense */ 1050aabbc4fbSShri Abhyankar a = (Mat_SeqDense*)newmat->data; 1051aabbc4fbSShri Abhyankar v = a->v; 1052aabbc4fbSShri Abhyankar /* Allocate some temp space to read in the values and then flip them 1053aabbc4fbSShri Abhyankar from row major to column major */ 1054854ce69bSBarry Smith ierr = PetscMalloc1(M*N > 0 ? M*N : 1,&w);CHKERRQ(ierr); 1055aabbc4fbSShri Abhyankar /* read in nonzero values */ 1056aabbc4fbSShri Abhyankar ierr = PetscBinaryRead(fd,w,M*N,PETSC_SCALAR);CHKERRQ(ierr); 1057aabbc4fbSShri Abhyankar /* now flip the values and store them in the matrix*/ 1058aabbc4fbSShri Abhyankar for (j=0; j<N; j++) { 1059aabbc4fbSShri Abhyankar for (i=0; i<M; i++) { 1060aabbc4fbSShri Abhyankar *v++ =w[i*N+j]; 1061aabbc4fbSShri Abhyankar } 1062aabbc4fbSShri Abhyankar } 1063aabbc4fbSShri Abhyankar ierr = PetscFree(w);CHKERRQ(ierr); 1064aabbc4fbSShri Abhyankar } else { 1065aabbc4fbSShri Abhyankar /* read row lengths */ 1066854ce69bSBarry Smith ierr = PetscMalloc1(M+1,&rowlengths);CHKERRQ(ierr); 1067aabbc4fbSShri Abhyankar ierr = PetscBinaryRead(fd,rowlengths,M,PETSC_INT);CHKERRQ(ierr); 1068aabbc4fbSShri Abhyankar 1069aabbc4fbSShri Abhyankar a = (Mat_SeqDense*)newmat->data; 1070aabbc4fbSShri Abhyankar v = a->v; 1071aabbc4fbSShri Abhyankar 1072aabbc4fbSShri Abhyankar /* read column indices and nonzeros */ 1073854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&scols);CHKERRQ(ierr); 1074aabbc4fbSShri Abhyankar cols = scols; 1075aabbc4fbSShri Abhyankar ierr = PetscBinaryRead(fd,cols,nz,PETSC_INT);CHKERRQ(ierr); 1076854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&svals);CHKERRQ(ierr); 1077aabbc4fbSShri Abhyankar vals = svals; 1078aabbc4fbSShri Abhyankar ierr = PetscBinaryRead(fd,vals,nz,PETSC_SCALAR);CHKERRQ(ierr); 1079aabbc4fbSShri Abhyankar 1080aabbc4fbSShri Abhyankar /* insert into matrix */ 1081aabbc4fbSShri Abhyankar for (i=0; i<M; i++) { 1082aabbc4fbSShri Abhyankar for (j=0; j<rowlengths[i]; j++) v[i+M*scols[j]] = svals[j]; 1083aabbc4fbSShri Abhyankar svals += rowlengths[i]; scols += rowlengths[i]; 1084aabbc4fbSShri Abhyankar } 1085aabbc4fbSShri Abhyankar ierr = PetscFree(vals);CHKERRQ(ierr); 1086aabbc4fbSShri Abhyankar ierr = PetscFree(cols);CHKERRQ(ierr); 1087aabbc4fbSShri Abhyankar ierr = PetscFree(rowlengths);CHKERRQ(ierr); 1088aabbc4fbSShri Abhyankar } 1089aabbc4fbSShri Abhyankar ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1090aabbc4fbSShri Abhyankar ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1091aabbc4fbSShri Abhyankar PetscFunctionReturn(0); 1092aabbc4fbSShri Abhyankar } 1093aabbc4fbSShri Abhyankar 10946849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_ASCII(Mat A,PetscViewer viewer) 1095289bc588SBarry Smith { 1096932b0c3eSLois Curfman McInnes Mat_SeqDense *a = (Mat_SeqDense*)A->data; 1097dfbe8321SBarry Smith PetscErrorCode ierr; 109813f74950SBarry Smith PetscInt i,j; 10992dcb1b2aSMatthew Knepley const char *name; 110087828ca2SBarry Smith PetscScalar *v; 1101f3ef73ceSBarry Smith PetscViewerFormat format; 11025f481a85SSatish Balay #if defined(PETSC_USE_COMPLEX) 1103ace3abfcSBarry Smith PetscBool allreal = PETSC_TRUE; 11045f481a85SSatish Balay #endif 1105932b0c3eSLois Curfman McInnes 11063a40ed3dSBarry Smith PetscFunctionBegin; 1107b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 1108456192e2SBarry Smith if (format == PETSC_VIEWER_ASCII_INFO || format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 11093a40ed3dSBarry Smith PetscFunctionReturn(0); /* do nothing for now */ 1110fb9695e5SSatish Balay } else if (format == PETSC_VIEWER_ASCII_COMMON) { 1111d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 1112d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 111344cd7ae7SLois Curfman McInnes v = a->v + i; 111477431f27SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"row %D:",i);CHKERRQ(ierr); 1115d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 1116aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 1117329f5518SBarry Smith if (PetscRealPart(*v) != 0.0 && PetscImaginaryPart(*v) != 0.0) { 111857622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g + %g i) ",j,(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr); 1119329f5518SBarry Smith } else if (PetscRealPart(*v)) { 112057622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)PetscRealPart(*v));CHKERRQ(ierr); 11216831982aSBarry Smith } 112280cd9d93SLois Curfman McInnes #else 11236831982aSBarry Smith if (*v) { 112457622a8eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," (%D, %g) ",j,(double)*v);CHKERRQ(ierr); 11256831982aSBarry Smith } 112680cd9d93SLois Curfman McInnes #endif 11271b807ce4Svictorle v += a->lda; 112880cd9d93SLois Curfman McInnes } 1129b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 113080cd9d93SLois Curfman McInnes } 1131d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 11323a40ed3dSBarry Smith } else { 1133d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_FALSE);CHKERRQ(ierr); 1134aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 113547989497SBarry Smith /* determine if matrix has all real values */ 113647989497SBarry Smith v = a->v; 1137d0f46423SBarry Smith for (i=0; i<A->rmap->n*A->cmap->n; i++) { 1138ffac6cdbSBarry Smith if (PetscImaginaryPart(v[i])) { allreal = PETSC_FALSE; break;} 113947989497SBarry Smith } 114047989497SBarry Smith #endif 1141fb9695e5SSatish Balay if (format == PETSC_VIEWER_ASCII_MATLAB) { 11423a7fca6bSBarry Smith ierr = PetscObjectGetName((PetscObject)A,&name);CHKERRQ(ierr); 1143d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%% Size = %D %D \n",A->rmap->n,A->cmap->n);CHKERRQ(ierr); 1144d0f46423SBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"%s = zeros(%D,%D);\n",name,A->rmap->n,A->cmap->n);CHKERRQ(ierr); 1145fb9695e5SSatish Balay ierr = PetscViewerASCIIPrintf(viewer,"%s = [\n",name);CHKERRQ(ierr); 1146ffac6cdbSBarry Smith } 1147ffac6cdbSBarry Smith 1148d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 1149932b0c3eSLois Curfman McInnes v = a->v + i; 1150d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 1151aa482453SBarry Smith #if defined(PETSC_USE_COMPLEX) 115247989497SBarry Smith if (allreal) { 1153c61cd2faSJed Brown ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)PetscRealPart(*v));CHKERRQ(ierr); 115447989497SBarry Smith } else { 1155c61cd2faSJed Brown ierr = PetscViewerASCIIPrintf(viewer,"%18.16e + %18.16ei ",(double)PetscRealPart(*v),(double)PetscImaginaryPart(*v));CHKERRQ(ierr); 115647989497SBarry Smith } 1157289bc588SBarry Smith #else 1158c61cd2faSJed Brown ierr = PetscViewerASCIIPrintf(viewer,"%18.16e ",(double)*v);CHKERRQ(ierr); 1159289bc588SBarry Smith #endif 11601b807ce4Svictorle v += a->lda; 1161289bc588SBarry Smith } 1162b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"\n");CHKERRQ(ierr); 1163289bc588SBarry Smith } 1164fb9695e5SSatish Balay if (format == PETSC_VIEWER_ASCII_MATLAB) { 1165b0a32e0cSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"];\n");CHKERRQ(ierr); 1166ffac6cdbSBarry Smith } 1167d00279f6SBarry Smith ierr = PetscViewerASCIIUseTabs(viewer,PETSC_TRUE);CHKERRQ(ierr); 1168da3a660dSBarry Smith } 1169b0a32e0cSBarry Smith ierr = PetscViewerFlush(viewer);CHKERRQ(ierr); 11703a40ed3dSBarry Smith PetscFunctionReturn(0); 1171289bc588SBarry Smith } 1172289bc588SBarry Smith 11736849ba73SBarry Smith static PetscErrorCode MatView_SeqDense_Binary(Mat A,PetscViewer viewer) 1174932b0c3eSLois Curfman McInnes { 1175932b0c3eSLois Curfman McInnes Mat_SeqDense *a = (Mat_SeqDense*)A->data; 11766849ba73SBarry Smith PetscErrorCode ierr; 117713f74950SBarry Smith int fd; 1178d0f46423SBarry Smith PetscInt ict,j,n = A->cmap->n,m = A->rmap->n,i,*col_lens,nz = m*n; 1179f4403165SShri Abhyankar PetscScalar *v,*anonz,*vals; 1180f4403165SShri Abhyankar PetscViewerFormat format; 1181932b0c3eSLois Curfman McInnes 11823a40ed3dSBarry Smith PetscFunctionBegin; 1183b0a32e0cSBarry Smith ierr = PetscViewerBinaryGetDescriptor(viewer,&fd);CHKERRQ(ierr); 118490ace30eSBarry Smith 1185f4403165SShri Abhyankar ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 1186f4403165SShri Abhyankar if (format == PETSC_VIEWER_NATIVE) { 1187f4403165SShri Abhyankar /* store the matrix as a dense matrix */ 1188785e854fSJed Brown ierr = PetscMalloc1(4,&col_lens);CHKERRQ(ierr); 11892205254eSKarl Rupp 1190f4403165SShri Abhyankar col_lens[0] = MAT_FILE_CLASSID; 1191f4403165SShri Abhyankar col_lens[1] = m; 1192f4403165SShri Abhyankar col_lens[2] = n; 1193f4403165SShri Abhyankar col_lens[3] = MATRIX_BINARY_FORMAT_DENSE; 11942205254eSKarl Rupp 1195f4403165SShri Abhyankar ierr = PetscBinaryWrite(fd,col_lens,4,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr); 1196f4403165SShri Abhyankar ierr = PetscFree(col_lens);CHKERRQ(ierr); 1197f4403165SShri Abhyankar 1198f4403165SShri Abhyankar /* write out matrix, by rows */ 1199854ce69bSBarry Smith ierr = PetscMalloc1(m*n+1,&vals);CHKERRQ(ierr); 1200f4403165SShri Abhyankar v = a->v; 1201f4403165SShri Abhyankar for (j=0; j<n; j++) { 1202f4403165SShri Abhyankar for (i=0; i<m; i++) { 1203f4403165SShri Abhyankar vals[j + i*n] = *v++; 1204f4403165SShri Abhyankar } 1205f4403165SShri Abhyankar } 1206f4403165SShri Abhyankar ierr = PetscBinaryWrite(fd,vals,n*m,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr); 1207f4403165SShri Abhyankar ierr = PetscFree(vals);CHKERRQ(ierr); 1208f4403165SShri Abhyankar } else { 1209854ce69bSBarry Smith ierr = PetscMalloc1(4+nz,&col_lens);CHKERRQ(ierr); 12102205254eSKarl Rupp 12110700a824SBarry Smith col_lens[0] = MAT_FILE_CLASSID; 1212932b0c3eSLois Curfman McInnes col_lens[1] = m; 1213932b0c3eSLois Curfman McInnes col_lens[2] = n; 1214932b0c3eSLois Curfman McInnes col_lens[3] = nz; 1215932b0c3eSLois Curfman McInnes 1216932b0c3eSLois Curfman McInnes /* store lengths of each row and write (including header) to file */ 1217932b0c3eSLois Curfman McInnes for (i=0; i<m; i++) col_lens[4+i] = n; 12186f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,col_lens,4+m,PETSC_INT,PETSC_TRUE);CHKERRQ(ierr); 1219932b0c3eSLois Curfman McInnes 1220932b0c3eSLois Curfman McInnes /* Possibly should write in smaller increments, not whole matrix at once? */ 1221932b0c3eSLois Curfman McInnes /* store column indices (zero start index) */ 1222932b0c3eSLois Curfman McInnes ict = 0; 1223932b0c3eSLois Curfman McInnes for (i=0; i<m; i++) { 1224932b0c3eSLois Curfman McInnes for (j=0; j<n; j++) col_lens[ict++] = j; 1225932b0c3eSLois Curfman McInnes } 12266f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,col_lens,nz,PETSC_INT,PETSC_FALSE);CHKERRQ(ierr); 1227606d414cSSatish Balay ierr = PetscFree(col_lens);CHKERRQ(ierr); 1228932b0c3eSLois Curfman McInnes 1229932b0c3eSLois Curfman McInnes /* store nonzero values */ 1230854ce69bSBarry Smith ierr = PetscMalloc1(nz+1,&anonz);CHKERRQ(ierr); 1231932b0c3eSLois Curfman McInnes ict = 0; 1232932b0c3eSLois Curfman McInnes for (i=0; i<m; i++) { 1233932b0c3eSLois Curfman McInnes v = a->v + i; 1234932b0c3eSLois Curfman McInnes for (j=0; j<n; j++) { 12351b807ce4Svictorle anonz[ict++] = *v; v += a->lda; 1236932b0c3eSLois Curfman McInnes } 1237932b0c3eSLois Curfman McInnes } 12386f69ff64SBarry Smith ierr = PetscBinaryWrite(fd,anonz,nz,PETSC_SCALAR,PETSC_FALSE);CHKERRQ(ierr); 1239606d414cSSatish Balay ierr = PetscFree(anonz);CHKERRQ(ierr); 1240f4403165SShri Abhyankar } 12413a40ed3dSBarry Smith PetscFunctionReturn(0); 1242932b0c3eSLois Curfman McInnes } 1243932b0c3eSLois Curfman McInnes 12449804daf3SBarry Smith #include <petscdraw.h> 1245e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw_Zoom(PetscDraw draw,void *Aa) 1246f1af5d2fSBarry Smith { 1247f1af5d2fSBarry Smith Mat A = (Mat) Aa; 1248f1af5d2fSBarry Smith Mat_SeqDense *a = (Mat_SeqDense*)A->data; 12496849ba73SBarry Smith PetscErrorCode ierr; 1250383922c3SLisandro Dalcin PetscInt m = A->rmap->n,n = A->cmap->n,i,j; 1251383922c3SLisandro Dalcin int color = PETSC_DRAW_WHITE; 125287828ca2SBarry Smith PetscScalar *v = a->v; 1253b0a32e0cSBarry Smith PetscViewer viewer; 1254b05fc000SLisandro Dalcin PetscReal xl,yl,xr,yr,x_l,x_r,y_l,y_r; 1255f3ef73ceSBarry Smith PetscViewerFormat format; 1256f1af5d2fSBarry Smith 1257f1af5d2fSBarry Smith PetscFunctionBegin; 1258f1af5d2fSBarry Smith ierr = PetscObjectQuery((PetscObject)A,"Zoomviewer",(PetscObject*)&viewer);CHKERRQ(ierr); 1259b0a32e0cSBarry Smith ierr = PetscViewerGetFormat(viewer,&format);CHKERRQ(ierr); 1260b0a32e0cSBarry Smith ierr = PetscDrawGetCoordinates(draw,&xl,&yl,&xr,&yr);CHKERRQ(ierr); 1261f1af5d2fSBarry Smith 1262f1af5d2fSBarry Smith /* Loop over matrix elements drawing boxes */ 1263383922c3SLisandro Dalcin 1264fb9695e5SSatish Balay if (format != PETSC_VIEWER_DRAW_CONTOUR) { 1265383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 1266f1af5d2fSBarry Smith /* Blue for negative and Red for positive */ 1267f1af5d2fSBarry Smith for (j = 0; j < n; j++) { 1268383922c3SLisandro Dalcin x_l = j; x_r = x_l + 1.0; 1269f1af5d2fSBarry Smith for (i = 0; i < m; i++) { 1270f1af5d2fSBarry Smith y_l = m - i - 1.0; 1271f1af5d2fSBarry Smith y_r = y_l + 1.0; 1272329f5518SBarry Smith if (PetscRealPart(v[j*m+i]) > 0.) { 1273b0a32e0cSBarry Smith color = PETSC_DRAW_RED; 1274329f5518SBarry Smith } else if (PetscRealPart(v[j*m+i]) < 0.) { 1275b0a32e0cSBarry Smith color = PETSC_DRAW_BLUE; 1276f1af5d2fSBarry Smith } else { 1277f1af5d2fSBarry Smith continue; 1278f1af5d2fSBarry Smith } 1279b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 1280f1af5d2fSBarry Smith } 1281f1af5d2fSBarry Smith } 1282383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 1283f1af5d2fSBarry Smith } else { 1284f1af5d2fSBarry Smith /* use contour shading to indicate magnitude of values */ 1285f1af5d2fSBarry Smith /* first determine max of all nonzero values */ 1286b05fc000SLisandro Dalcin PetscReal minv = 0.0, maxv = 0.0; 1287b05fc000SLisandro Dalcin PetscDraw popup; 1288b05fc000SLisandro Dalcin 1289f1af5d2fSBarry Smith for (i=0; i < m*n; i++) { 1290f1af5d2fSBarry Smith if (PetscAbsScalar(v[i]) > maxv) maxv = PetscAbsScalar(v[i]); 1291f1af5d2fSBarry Smith } 1292383922c3SLisandro Dalcin if (minv >= maxv) maxv = minv + PETSC_SMALL; 1293b0a32e0cSBarry Smith ierr = PetscDrawGetPopup(draw,&popup);CHKERRQ(ierr); 129445f3bb6eSLisandro Dalcin ierr = PetscDrawScalePopup(popup,minv,maxv);CHKERRQ(ierr); 1295383922c3SLisandro Dalcin 1296383922c3SLisandro Dalcin ierr = PetscDrawCollectiveBegin(draw);CHKERRQ(ierr); 1297f1af5d2fSBarry Smith for (j=0; j<n; j++) { 1298f1af5d2fSBarry Smith x_l = j; 1299f1af5d2fSBarry Smith x_r = x_l + 1.0; 1300f1af5d2fSBarry Smith for (i=0; i<m; i++) { 1301f1af5d2fSBarry Smith y_l = m - i - 1.0; 1302f1af5d2fSBarry Smith y_r = y_l + 1.0; 1303b05fc000SLisandro Dalcin color = PetscDrawRealToColor(PetscAbsScalar(v[j*m+i]),minv,maxv); 1304b0a32e0cSBarry Smith ierr = PetscDrawRectangle(draw,x_l,y_l,x_r,y_r,color,color,color,color);CHKERRQ(ierr); 1305f1af5d2fSBarry Smith } 1306f1af5d2fSBarry Smith } 1307383922c3SLisandro Dalcin ierr = PetscDrawCollectiveEnd(draw);CHKERRQ(ierr); 1308f1af5d2fSBarry Smith } 1309f1af5d2fSBarry Smith PetscFunctionReturn(0); 1310f1af5d2fSBarry Smith } 1311f1af5d2fSBarry Smith 1312e0877f53SBarry Smith static PetscErrorCode MatView_SeqDense_Draw(Mat A,PetscViewer viewer) 1313f1af5d2fSBarry Smith { 1314b0a32e0cSBarry Smith PetscDraw draw; 1315ace3abfcSBarry Smith PetscBool isnull; 1316329f5518SBarry Smith PetscReal xr,yr,xl,yl,h,w; 1317dfbe8321SBarry Smith PetscErrorCode ierr; 1318f1af5d2fSBarry Smith 1319f1af5d2fSBarry Smith PetscFunctionBegin; 1320b0a32e0cSBarry Smith ierr = PetscViewerDrawGetDraw(viewer,0,&draw);CHKERRQ(ierr); 1321b0a32e0cSBarry Smith ierr = PetscDrawIsNull(draw,&isnull);CHKERRQ(ierr); 1322abc0a331SBarry Smith if (isnull) PetscFunctionReturn(0); 1323f1af5d2fSBarry Smith 1324d0f46423SBarry Smith xr = A->cmap->n; yr = A->rmap->n; h = yr/10.0; w = xr/10.0; 1325f1af5d2fSBarry Smith xr += w; yr += h; xl = -w; yl = -h; 1326b0a32e0cSBarry Smith ierr = PetscDrawSetCoordinates(draw,xl,yl,xr,yr);CHKERRQ(ierr); 1327832b7cebSLisandro Dalcin ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",(PetscObject)viewer);CHKERRQ(ierr); 1328b0a32e0cSBarry Smith ierr = PetscDrawZoom(draw,MatView_SeqDense_Draw_Zoom,A);CHKERRQ(ierr); 13290298fd71SBarry Smith ierr = PetscObjectCompose((PetscObject)A,"Zoomviewer",NULL);CHKERRQ(ierr); 1330832b7cebSLisandro Dalcin ierr = PetscDrawSave(draw);CHKERRQ(ierr); 1331f1af5d2fSBarry Smith PetscFunctionReturn(0); 1332f1af5d2fSBarry Smith } 1333f1af5d2fSBarry Smith 1334dfbe8321SBarry Smith PetscErrorCode MatView_SeqDense(Mat A,PetscViewer viewer) 1335932b0c3eSLois Curfman McInnes { 1336dfbe8321SBarry Smith PetscErrorCode ierr; 1337ace3abfcSBarry Smith PetscBool iascii,isbinary,isdraw; 1338932b0c3eSLois Curfman McInnes 13393a40ed3dSBarry Smith PetscFunctionBegin; 1340251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1341251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary);CHKERRQ(ierr); 1342251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw);CHKERRQ(ierr); 13430f5bd95cSBarry Smith 1344c45a1595SBarry Smith if (iascii) { 1345c45a1595SBarry Smith ierr = MatView_SeqDense_ASCII(A,viewer);CHKERRQ(ierr); 13460f5bd95cSBarry Smith } else if (isbinary) { 13473a40ed3dSBarry Smith ierr = MatView_SeqDense_Binary(A,viewer);CHKERRQ(ierr); 1348f1af5d2fSBarry Smith } else if (isdraw) { 1349f1af5d2fSBarry Smith ierr = MatView_SeqDense_Draw(A,viewer);CHKERRQ(ierr); 1350932b0c3eSLois Curfman McInnes } 13513a40ed3dSBarry Smith PetscFunctionReturn(0); 1352932b0c3eSLois Curfman McInnes } 1353289bc588SBarry Smith 1354e0877f53SBarry Smith static PetscErrorCode MatDestroy_SeqDense(Mat mat) 1355289bc588SBarry Smith { 1356ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense*)mat->data; 1357dfbe8321SBarry Smith PetscErrorCode ierr; 135890f02eecSBarry Smith 13593a40ed3dSBarry Smith PetscFunctionBegin; 1360aa482453SBarry Smith #if defined(PETSC_USE_LOG) 1361d0f46423SBarry Smith PetscLogObjectState((PetscObject)mat,"Rows %D Cols %D",mat->rmap->n,mat->cmap->n); 1362a5a9c739SBarry Smith #endif 136305b42c5fSBarry Smith ierr = PetscFree(l->pivots);CHKERRQ(ierr); 1364a49dc2a2SStefano Zampini ierr = PetscFree(l->fwork);CHKERRQ(ierr); 1365abc3b08eSStefano Zampini ierr = MatDestroy(&l->ptapwork);CHKERRQ(ierr); 13666857c123SSatish Balay if (!l->user_alloc) {ierr = PetscFree(l->v);CHKERRQ(ierr);} 1367bf0cc555SLisandro Dalcin ierr = PetscFree(mat->data);CHKERRQ(ierr); 1368dbd8c25aSHong Zhang 1369dbd8c25aSHong Zhang ierr = PetscObjectChangeTypeName((PetscObject)mat,0);CHKERRQ(ierr); 1370bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseGetArray_C",NULL);CHKERRQ(ierr); 1371bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)mat,"MatDenseRestoreArray_C",NULL);CHKERRQ(ierr); 13728baccfbdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_seqaij_C",NULL);CHKERRQ(ierr); 13738baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 13748baccfbdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)mat,"MatConvert_seqdense_elemental_C",NULL);CHKERRQ(ierr); 13758baccfbdSHong Zhang #endif 1376bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)mat,"MatSeqDenseSetPreallocation_C",NULL);CHKERRQ(ierr); 1377bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMult_seqaij_seqdense_C",NULL);CHKERRQ(ierr); 1378bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultSymbolic_seqaij_seqdense_C",NULL);CHKERRQ(ierr); 1379bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)mat,"MatMatMultNumeric_seqaij_seqdense_C",NULL);CHKERRQ(ierr); 1380abc3b08eSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)mat,"MatPtAP_seqaij_seqdense_C",NULL);CHKERRQ(ierr); 13813bf78175SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMult_seqaij_seqdense_C",NULL);CHKERRQ(ierr); 13823bf78175SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultSymbolic_seqaij_seqdense_C",NULL);CHKERRQ(ierr); 13833bf78175SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)mat,"MatTransposeMatMultNumeric_seqaij_seqdense_C",NULL);CHKERRQ(ierr); 13843a40ed3dSBarry Smith PetscFunctionReturn(0); 1385289bc588SBarry Smith } 1386289bc588SBarry Smith 1387e0877f53SBarry Smith static PetscErrorCode MatTranspose_SeqDense(Mat A,MatReuse reuse,Mat *matout) 1388289bc588SBarry Smith { 1389c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 13906849ba73SBarry Smith PetscErrorCode ierr; 139113f74950SBarry Smith PetscInt k,j,m,n,M; 139287828ca2SBarry Smith PetscScalar *v,tmp; 139348b35521SBarry Smith 13943a40ed3dSBarry Smith PetscFunctionBegin; 1395d0f46423SBarry Smith v = mat->v; m = A->rmap->n; M = mat->lda; n = A->cmap->n; 1396cf37664fSBarry Smith if (reuse == MAT_INPLACE_MATRIX) { /* in place transpose */ 1397e7e72b3dSBarry Smith if (m != n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Can not transpose non-square matrix in place"); 1398e7e72b3dSBarry Smith else { 1399d3e5ee88SLois Curfman McInnes for (j=0; j<m; j++) { 1400289bc588SBarry Smith for (k=0; k<j; k++) { 14011b807ce4Svictorle tmp = v[j + k*M]; 14021b807ce4Svictorle v[j + k*M] = v[k + j*M]; 14031b807ce4Svictorle v[k + j*M] = tmp; 1404289bc588SBarry Smith } 1405289bc588SBarry Smith } 1406d64ed03dSBarry Smith } 14073a40ed3dSBarry Smith } else { /* out-of-place transpose */ 1408d3e5ee88SLois Curfman McInnes Mat tmat; 1409ec8511deSBarry Smith Mat_SeqDense *tmatd; 141087828ca2SBarry Smith PetscScalar *v2; 1411af36a384SStefano Zampini PetscInt M2; 1412ea709b57SSatish Balay 1413fc4dec0aSBarry Smith if (reuse == MAT_INITIAL_MATRIX) { 1414ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&tmat);CHKERRQ(ierr); 1415d0f46423SBarry Smith ierr = MatSetSizes(tmat,A->cmap->n,A->rmap->n,A->cmap->n,A->rmap->n);CHKERRQ(ierr); 14167adad957SLisandro Dalcin ierr = MatSetType(tmat,((PetscObject)A)->type_name);CHKERRQ(ierr); 14170298fd71SBarry Smith ierr = MatSeqDenseSetPreallocation(tmat,NULL);CHKERRQ(ierr); 1418fc4dec0aSBarry Smith } else { 1419fc4dec0aSBarry Smith tmat = *matout; 1420fc4dec0aSBarry Smith } 1421ec8511deSBarry Smith tmatd = (Mat_SeqDense*)tmat->data; 1422af36a384SStefano Zampini v = mat->v; v2 = tmatd->v; M2 = tmatd->lda; 1423d3e5ee88SLois Curfman McInnes for (j=0; j<n; j++) { 1424af36a384SStefano Zampini for (k=0; k<m; k++) v2[j + k*M2] = v[k + j*M]; 1425d3e5ee88SLois Curfman McInnes } 14266d4a8577SBarry Smith ierr = MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14276d4a8577SBarry Smith ierr = MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1428d3e5ee88SLois Curfman McInnes *matout = tmat; 142948b35521SBarry Smith } 14303a40ed3dSBarry Smith PetscFunctionReturn(0); 1431289bc588SBarry Smith } 1432289bc588SBarry Smith 1433e0877f53SBarry Smith static PetscErrorCode MatEqual_SeqDense(Mat A1,Mat A2,PetscBool *flg) 1434289bc588SBarry Smith { 1435c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat1 = (Mat_SeqDense*)A1->data; 1436c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat2 = (Mat_SeqDense*)A2->data; 143713f74950SBarry Smith PetscInt i,j; 1438a2ea699eSBarry Smith PetscScalar *v1,*v2; 14399ea5d5aeSSatish Balay 14403a40ed3dSBarry Smith PetscFunctionBegin; 1441d0f46423SBarry Smith if (A1->rmap->n != A2->rmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);} 1442d0f46423SBarry Smith if (A1->cmap->n != A2->cmap->n) {*flg = PETSC_FALSE; PetscFunctionReturn(0);} 1443d0f46423SBarry Smith for (i=0; i<A1->rmap->n; i++) { 14441b807ce4Svictorle v1 = mat1->v+i; v2 = mat2->v+i; 1445d0f46423SBarry Smith for (j=0; j<A1->cmap->n; j++) { 14463a40ed3dSBarry Smith if (*v1 != *v2) {*flg = PETSC_FALSE; PetscFunctionReturn(0);} 14471b807ce4Svictorle v1 += mat1->lda; v2 += mat2->lda; 14481b807ce4Svictorle } 1449289bc588SBarry Smith } 145077c4ece6SBarry Smith *flg = PETSC_TRUE; 14513a40ed3dSBarry Smith PetscFunctionReturn(0); 1452289bc588SBarry Smith } 1453289bc588SBarry Smith 1454e0877f53SBarry Smith static PetscErrorCode MatGetDiagonal_SeqDense(Mat A,Vec v) 1455289bc588SBarry Smith { 1456c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 1457dfbe8321SBarry Smith PetscErrorCode ierr; 145813f74950SBarry Smith PetscInt i,n,len; 145987828ca2SBarry Smith PetscScalar *x,zero = 0.0; 146044cd7ae7SLois Curfman McInnes 14613a40ed3dSBarry Smith PetscFunctionBegin; 14622dcb1b2aSMatthew Knepley ierr = VecSet(v,zero);CHKERRQ(ierr); 14637a97a34bSBarry Smith ierr = VecGetSize(v,&n);CHKERRQ(ierr); 14641ebc52fbSHong Zhang ierr = VecGetArray(v,&x);CHKERRQ(ierr); 1465d0f46423SBarry Smith len = PetscMin(A->rmap->n,A->cmap->n); 1466e32f2f54SBarry Smith if (n != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming mat and vec"); 146744cd7ae7SLois Curfman McInnes for (i=0; i<len; i++) { 14681b807ce4Svictorle x[i] = mat->v[i*mat->lda + i]; 1469289bc588SBarry Smith } 14701ebc52fbSHong Zhang ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 14713a40ed3dSBarry Smith PetscFunctionReturn(0); 1472289bc588SBarry Smith } 1473289bc588SBarry Smith 1474e0877f53SBarry Smith static PetscErrorCode MatDiagonalScale_SeqDense(Mat A,Vec ll,Vec rr) 1475289bc588SBarry Smith { 1476c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 1477f1ceaac6SMatthew G. Knepley const PetscScalar *l,*r; 1478f1ceaac6SMatthew G. Knepley PetscScalar x,*v; 1479dfbe8321SBarry Smith PetscErrorCode ierr; 1480d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n; 148155659b69SBarry Smith 14823a40ed3dSBarry Smith PetscFunctionBegin; 148328988994SBarry Smith if (ll) { 14847a97a34bSBarry Smith ierr = VecGetSize(ll,&m);CHKERRQ(ierr); 1485f1ceaac6SMatthew G. Knepley ierr = VecGetArrayRead(ll,&l);CHKERRQ(ierr); 1486e32f2f54SBarry Smith if (m != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Left scaling vec wrong size"); 1487da3a660dSBarry Smith for (i=0; i<m; i++) { 1488da3a660dSBarry Smith x = l[i]; 1489da3a660dSBarry Smith v = mat->v + i; 1490b43bac26SStefano Zampini for (j=0; j<n; j++) { (*v) *= x; v+= mat->lda;} 1491da3a660dSBarry Smith } 1492f1ceaac6SMatthew G. Knepley ierr = VecRestoreArrayRead(ll,&l);CHKERRQ(ierr); 1493eb3f19e4SBarry Smith ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr); 1494da3a660dSBarry Smith } 149528988994SBarry Smith if (rr) { 14967a97a34bSBarry Smith ierr = VecGetSize(rr,&n);CHKERRQ(ierr); 1497f1ceaac6SMatthew G. Knepley ierr = VecGetArrayRead(rr,&r);CHKERRQ(ierr); 1498e32f2f54SBarry Smith if (n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Right scaling vec wrong size"); 1499da3a660dSBarry Smith for (i=0; i<n; i++) { 1500da3a660dSBarry Smith x = r[i]; 1501b43bac26SStefano Zampini v = mat->v + i*mat->lda; 15022205254eSKarl Rupp for (j=0; j<m; j++) (*v++) *= x; 1503da3a660dSBarry Smith } 1504f1ceaac6SMatthew G. Knepley ierr = VecRestoreArrayRead(rr,&r);CHKERRQ(ierr); 1505eb3f19e4SBarry Smith ierr = PetscLogFlops(1.0*n*m);CHKERRQ(ierr); 1506da3a660dSBarry Smith } 15073a40ed3dSBarry Smith PetscFunctionReturn(0); 1508289bc588SBarry Smith } 1509289bc588SBarry Smith 1510e0877f53SBarry Smith static PetscErrorCode MatNorm_SeqDense(Mat A,NormType type,PetscReal *nrm) 1511289bc588SBarry Smith { 1512c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 151387828ca2SBarry Smith PetscScalar *v = mat->v; 1514329f5518SBarry Smith PetscReal sum = 0.0; 1515d0f46423SBarry Smith PetscInt lda =mat->lda,m=A->rmap->n,i,j; 1516efee365bSSatish Balay PetscErrorCode ierr; 151755659b69SBarry Smith 15183a40ed3dSBarry Smith PetscFunctionBegin; 1519289bc588SBarry Smith if (type == NORM_FROBENIUS) { 1520a5ce6ee0Svictorle if (lda>m) { 1521d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 1522a5ce6ee0Svictorle v = mat->v+j*lda; 1523a5ce6ee0Svictorle for (i=0; i<m; i++) { 1524a5ce6ee0Svictorle sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 1525a5ce6ee0Svictorle } 1526a5ce6ee0Svictorle } 1527a5ce6ee0Svictorle } else { 1528570b7f6dSBarry Smith #if defined(PETSC_USE_REAL___FP16) 1529570b7f6dSBarry Smith PetscBLASInt one = 1,cnt = A->cmap->n*A->rmap->n; 1530570b7f6dSBarry Smith *nrm = BLASnrm2_(&cnt,v,&one); 1531570b7f6dSBarry Smith } 1532570b7f6dSBarry Smith #else 1533d0f46423SBarry Smith for (i=0; i<A->cmap->n*A->rmap->n; i++) { 1534329f5518SBarry Smith sum += PetscRealPart(PetscConj(*v)*(*v)); v++; 1535289bc588SBarry Smith } 1536a5ce6ee0Svictorle } 15378f1a2a5eSBarry Smith *nrm = PetscSqrtReal(sum); 1538570b7f6dSBarry Smith #endif 1539dc0b31edSSatish Balay ierr = PetscLogFlops(2.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr); 15403a40ed3dSBarry Smith } else if (type == NORM_1) { 1541064f8208SBarry Smith *nrm = 0.0; 1542d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 15431b807ce4Svictorle v = mat->v + j*mat->lda; 1544289bc588SBarry Smith sum = 0.0; 1545d0f46423SBarry Smith for (i=0; i<A->rmap->n; i++) { 154633a8263dSBarry Smith sum += PetscAbsScalar(*v); v++; 1547289bc588SBarry Smith } 1548064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 1549289bc588SBarry Smith } 1550eb3f19e4SBarry Smith ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr); 15513a40ed3dSBarry Smith } else if (type == NORM_INFINITY) { 1552064f8208SBarry Smith *nrm = 0.0; 1553d0f46423SBarry Smith for (j=0; j<A->rmap->n; j++) { 1554289bc588SBarry Smith v = mat->v + j; 1555289bc588SBarry Smith sum = 0.0; 1556d0f46423SBarry Smith for (i=0; i<A->cmap->n; i++) { 15571b807ce4Svictorle sum += PetscAbsScalar(*v); v += mat->lda; 1558289bc588SBarry Smith } 1559064f8208SBarry Smith if (sum > *nrm) *nrm = sum; 1560289bc588SBarry Smith } 1561eb3f19e4SBarry Smith ierr = PetscLogFlops(1.0*A->cmap->n*A->rmap->n);CHKERRQ(ierr); 1562e7e72b3dSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No two norm"); 15633a40ed3dSBarry Smith PetscFunctionReturn(0); 1564289bc588SBarry Smith } 1565289bc588SBarry Smith 1566e0877f53SBarry Smith static PetscErrorCode MatSetOption_SeqDense(Mat A,MatOption op,PetscBool flg) 1567289bc588SBarry Smith { 1568c0bbcb79SLois Curfman McInnes Mat_SeqDense *aij = (Mat_SeqDense*)A->data; 156963ba0a88SBarry Smith PetscErrorCode ierr; 157067e560aaSBarry Smith 15713a40ed3dSBarry Smith PetscFunctionBegin; 1572b5a2b587SKris Buschelman switch (op) { 1573b5a2b587SKris Buschelman case MAT_ROW_ORIENTED: 15744e0d8c25SBarry Smith aij->roworiented = flg; 1575b5a2b587SKris Buschelman break; 1576512a5fc5SBarry Smith case MAT_NEW_NONZERO_LOCATIONS: 1577b5a2b587SKris Buschelman case MAT_NEW_NONZERO_LOCATION_ERR: 15783971808eSMatthew Knepley case MAT_NEW_NONZERO_ALLOCATION_ERR: 15794e0d8c25SBarry Smith case MAT_NEW_DIAGONALS: 158013fa8e87SLisandro Dalcin case MAT_KEEP_NONZERO_PATTERN: 1581b5a2b587SKris Buschelman case MAT_IGNORE_OFF_PROC_ENTRIES: 1582b5a2b587SKris Buschelman case MAT_USE_HASH_TABLE: 15835021d80fSJed Brown case MAT_IGNORE_LOWER_TRIANGULAR: 15845021d80fSJed Brown ierr = PetscInfo1(A,"Option %s ignored\n",MatOptions[op]);CHKERRQ(ierr); 15855021d80fSJed Brown break; 15865021d80fSJed Brown case MAT_SPD: 158777e54ba9SKris Buschelman case MAT_SYMMETRIC: 158877e54ba9SKris Buschelman case MAT_STRUCTURALLY_SYMMETRIC: 15899a4540c5SBarry Smith case MAT_HERMITIAN: 15909a4540c5SBarry Smith case MAT_SYMMETRY_ETERNAL: 15915021d80fSJed Brown /* These options are handled directly by MatSetOption() */ 159277e54ba9SKris Buschelman break; 1593b5a2b587SKris Buschelman default: 1594e32f2f54SBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"unknown option %s",MatOptions[op]); 15953a40ed3dSBarry Smith } 15963a40ed3dSBarry Smith PetscFunctionReturn(0); 1597289bc588SBarry Smith } 1598289bc588SBarry Smith 1599e0877f53SBarry Smith static PetscErrorCode MatZeroEntries_SeqDense(Mat A) 16006f0a148fSBarry Smith { 1601ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense*)A->data; 16026849ba73SBarry Smith PetscErrorCode ierr; 1603d0f46423SBarry Smith PetscInt lda=l->lda,m=A->rmap->n,j; 16043a40ed3dSBarry Smith 16053a40ed3dSBarry Smith PetscFunctionBegin; 1606a5ce6ee0Svictorle if (lda>m) { 1607d0f46423SBarry Smith for (j=0; j<A->cmap->n; j++) { 1608a5ce6ee0Svictorle ierr = PetscMemzero(l->v+j*lda,m*sizeof(PetscScalar));CHKERRQ(ierr); 1609a5ce6ee0Svictorle } 1610a5ce6ee0Svictorle } else { 1611d0f46423SBarry Smith ierr = PetscMemzero(l->v,A->rmap->n*A->cmap->n*sizeof(PetscScalar));CHKERRQ(ierr); 1612a5ce6ee0Svictorle } 16133a40ed3dSBarry Smith PetscFunctionReturn(0); 16146f0a148fSBarry Smith } 16156f0a148fSBarry Smith 1616e0877f53SBarry Smith static PetscErrorCode MatZeroRows_SeqDense(Mat A,PetscInt N,const PetscInt rows[],PetscScalar diag,Vec x,Vec b) 16176f0a148fSBarry Smith { 161897b48c8fSBarry Smith PetscErrorCode ierr; 1619ec8511deSBarry Smith Mat_SeqDense *l = (Mat_SeqDense*)A->data; 1620b9679d65SBarry Smith PetscInt m = l->lda, n = A->cmap->n, i,j; 162197b48c8fSBarry Smith PetscScalar *slot,*bb; 162297b48c8fSBarry Smith const PetscScalar *xx; 162355659b69SBarry Smith 16243a40ed3dSBarry Smith PetscFunctionBegin; 1625b9679d65SBarry Smith #if defined(PETSC_USE_DEBUG) 1626b9679d65SBarry Smith for (i=0; i<N; i++) { 1627b9679d65SBarry Smith if (rows[i] < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Negative row requested to be zeroed"); 1628b9679d65SBarry Smith if (rows[i] >= A->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Row %D requested to be zeroed greater than or equal number of rows %D",rows[i],A->rmap->n); 1629b9679d65SBarry Smith } 1630b9679d65SBarry Smith #endif 1631b9679d65SBarry Smith 163297b48c8fSBarry Smith /* fix right hand side if needed */ 163397b48c8fSBarry Smith if (x && b) { 163497b48c8fSBarry Smith ierr = VecGetArrayRead(x,&xx);CHKERRQ(ierr); 163597b48c8fSBarry Smith ierr = VecGetArray(b,&bb);CHKERRQ(ierr); 16362205254eSKarl Rupp for (i=0; i<N; i++) bb[rows[i]] = diag*xx[rows[i]]; 163797b48c8fSBarry Smith ierr = VecRestoreArrayRead(x,&xx);CHKERRQ(ierr); 163897b48c8fSBarry Smith ierr = VecRestoreArray(b,&bb);CHKERRQ(ierr); 163997b48c8fSBarry Smith } 164097b48c8fSBarry Smith 16416f0a148fSBarry Smith for (i=0; i<N; i++) { 16426f0a148fSBarry Smith slot = l->v + rows[i]; 1643b9679d65SBarry Smith for (j=0; j<n; j++) { *slot = 0.0; slot += m;} 16446f0a148fSBarry Smith } 1645f4df32b1SMatthew Knepley if (diag != 0.0) { 1646b9679d65SBarry Smith if (A->rmap->n != A->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Only coded for square matrices"); 16476f0a148fSBarry Smith for (i=0; i<N; i++) { 1648b9679d65SBarry Smith slot = l->v + (m+1)*rows[i]; 1649f4df32b1SMatthew Knepley *slot = diag; 16506f0a148fSBarry Smith } 16516f0a148fSBarry Smith } 16523a40ed3dSBarry Smith PetscFunctionReturn(0); 16536f0a148fSBarry Smith } 1654557bce09SLois Curfman McInnes 1655e0877f53SBarry Smith static PetscErrorCode MatDenseGetArray_SeqDense(Mat A,PetscScalar *array[]) 165664e87e97SBarry Smith { 1657c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 16583a40ed3dSBarry Smith 16593a40ed3dSBarry Smith PetscFunctionBegin; 1660e32f2f54SBarry Smith if (mat->lda != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot get array for Dense matrices with LDA different from number of rows"); 166164e87e97SBarry Smith *array = mat->v; 16623a40ed3dSBarry Smith PetscFunctionReturn(0); 166364e87e97SBarry Smith } 16640754003eSLois Curfman McInnes 1665e0877f53SBarry Smith static PetscErrorCode MatDenseRestoreArray_SeqDense(Mat A,PetscScalar *array[]) 1666ff14e315SSatish Balay { 16673a40ed3dSBarry Smith PetscFunctionBegin; 166809b544d4SBarry Smith *array = 0; /* user cannot accidently use the array later */ 16693a40ed3dSBarry Smith PetscFunctionReturn(0); 1670ff14e315SSatish Balay } 16710754003eSLois Curfman McInnes 1672dec5eb66SMatthew G Knepley /*@C 16738c778c55SBarry Smith MatDenseGetArray - gives access to the array where the data for a SeqDense matrix is stored 167473a71a0fSBarry Smith 167573a71a0fSBarry Smith Not Collective 167673a71a0fSBarry Smith 167773a71a0fSBarry Smith Input Parameter: 1678579dbff0SBarry Smith . mat - a MATSEQDENSE or MATMPIDENSE matrix 167973a71a0fSBarry Smith 168073a71a0fSBarry Smith Output Parameter: 168173a71a0fSBarry Smith . array - pointer to the data 168273a71a0fSBarry Smith 168373a71a0fSBarry Smith Level: intermediate 168473a71a0fSBarry Smith 16858c778c55SBarry Smith .seealso: MatDenseRestoreArray() 168673a71a0fSBarry Smith @*/ 16878c778c55SBarry Smith PetscErrorCode MatDenseGetArray(Mat A,PetscScalar **array) 168873a71a0fSBarry Smith { 168973a71a0fSBarry Smith PetscErrorCode ierr; 169073a71a0fSBarry Smith 169173a71a0fSBarry Smith PetscFunctionBegin; 16928c778c55SBarry Smith ierr = PetscUseMethod(A,"MatDenseGetArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 169373a71a0fSBarry Smith PetscFunctionReturn(0); 169473a71a0fSBarry Smith } 169573a71a0fSBarry Smith 1696dec5eb66SMatthew G Knepley /*@C 1697579dbff0SBarry Smith MatDenseRestoreArray - returns access to the array where the data for a dense matrix is stored obtained by MatDenseGetArray() 169873a71a0fSBarry Smith 169973a71a0fSBarry Smith Not Collective 170073a71a0fSBarry Smith 170173a71a0fSBarry Smith Input Parameters: 1702579dbff0SBarry Smith . mat - a MATSEQDENSE or MATMPIDENSE matrix 170373a71a0fSBarry Smith . array - pointer to the data 170473a71a0fSBarry Smith 170573a71a0fSBarry Smith Level: intermediate 170673a71a0fSBarry Smith 17078c778c55SBarry Smith .seealso: MatDenseGetArray() 170873a71a0fSBarry Smith @*/ 17098c778c55SBarry Smith PetscErrorCode MatDenseRestoreArray(Mat A,PetscScalar **array) 171073a71a0fSBarry Smith { 171173a71a0fSBarry Smith PetscErrorCode ierr; 171273a71a0fSBarry Smith 171373a71a0fSBarry Smith PetscFunctionBegin; 17148c778c55SBarry Smith ierr = PetscUseMethod(A,"MatDenseRestoreArray_C",(Mat,PetscScalar**),(A,array));CHKERRQ(ierr); 171573a71a0fSBarry Smith PetscFunctionReturn(0); 171673a71a0fSBarry Smith } 171773a71a0fSBarry Smith 17187dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrix_SeqDense(Mat A,IS isrow,IS iscol,PetscInt cs,MatReuse scall,Mat *B) 17190754003eSLois Curfman McInnes { 1720c0bbcb79SLois Curfman McInnes Mat_SeqDense *mat = (Mat_SeqDense*)A->data; 17216849ba73SBarry Smith PetscErrorCode ierr; 17225d0c19d7SBarry Smith PetscInt i,j,nrows,ncols; 17235d0c19d7SBarry Smith const PetscInt *irow,*icol; 172487828ca2SBarry Smith PetscScalar *av,*bv,*v = mat->v; 17250754003eSLois Curfman McInnes Mat newmat; 17260754003eSLois Curfman McInnes 17273a40ed3dSBarry Smith PetscFunctionBegin; 172878b31e54SBarry Smith ierr = ISGetIndices(isrow,&irow);CHKERRQ(ierr); 172978b31e54SBarry Smith ierr = ISGetIndices(iscol,&icol);CHKERRQ(ierr); 1730e03a110bSBarry Smith ierr = ISGetLocalSize(isrow,&nrows);CHKERRQ(ierr); 1731e03a110bSBarry Smith ierr = ISGetLocalSize(iscol,&ncols);CHKERRQ(ierr); 17320754003eSLois Curfman McInnes 1733182d2002SSatish Balay /* Check submatrixcall */ 1734182d2002SSatish Balay if (scall == MAT_REUSE_MATRIX) { 173513f74950SBarry Smith PetscInt n_cols,n_rows; 1736182d2002SSatish Balay ierr = MatGetSize(*B,&n_rows,&n_cols);CHKERRQ(ierr); 173721a2c019SBarry Smith if (n_rows != nrows || n_cols != ncols) { 1738f746d493SDmitry Karpeev /* resize the result matrix to match number of requested rows/columns */ 1739c61587bbSBarry Smith ierr = MatSetSizes(*B,nrows,ncols,nrows,ncols);CHKERRQ(ierr); 174021a2c019SBarry Smith } 1741182d2002SSatish Balay newmat = *B; 1742182d2002SSatish Balay } else { 17430754003eSLois Curfman McInnes /* Create and fill new matrix */ 1744ce94432eSBarry Smith ierr = MatCreate(PetscObjectComm((PetscObject)A),&newmat);CHKERRQ(ierr); 1745f69a0ea3SMatthew Knepley ierr = MatSetSizes(newmat,nrows,ncols,nrows,ncols);CHKERRQ(ierr); 17467adad957SLisandro Dalcin ierr = MatSetType(newmat,((PetscObject)A)->type_name);CHKERRQ(ierr); 17470298fd71SBarry Smith ierr = MatSeqDenseSetPreallocation(newmat,NULL);CHKERRQ(ierr); 1748182d2002SSatish Balay } 1749182d2002SSatish Balay 1750182d2002SSatish Balay /* Now extract the data pointers and do the copy,column at a time */ 1751182d2002SSatish Balay bv = ((Mat_SeqDense*)newmat->data)->v; 1752182d2002SSatish Balay 1753182d2002SSatish Balay for (i=0; i<ncols; i++) { 17546de62eeeSBarry Smith av = v + mat->lda*icol[i]; 17552205254eSKarl Rupp for (j=0; j<nrows; j++) *bv++ = av[irow[j]]; 17560754003eSLois Curfman McInnes } 1757182d2002SSatish Balay 1758182d2002SSatish Balay /* Assemble the matrices so that the correct flags are set */ 17596d4a8577SBarry Smith ierr = MatAssemblyBegin(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 17606d4a8577SBarry Smith ierr = MatAssemblyEnd(newmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 17610754003eSLois Curfman McInnes 17620754003eSLois Curfman McInnes /* Free work space */ 176378b31e54SBarry Smith ierr = ISRestoreIndices(isrow,&irow);CHKERRQ(ierr); 176478b31e54SBarry Smith ierr = ISRestoreIndices(iscol,&icol);CHKERRQ(ierr); 1765182d2002SSatish Balay *B = newmat; 17663a40ed3dSBarry Smith PetscFunctionReturn(0); 17670754003eSLois Curfman McInnes } 17680754003eSLois Curfman McInnes 17697dae84e0SHong Zhang static PetscErrorCode MatCreateSubMatrices_SeqDense(Mat A,PetscInt n,const IS irow[],const IS icol[],MatReuse scall,Mat *B[]) 1770905e6a2fSBarry Smith { 17716849ba73SBarry Smith PetscErrorCode ierr; 177213f74950SBarry Smith PetscInt i; 1773905e6a2fSBarry Smith 17743a40ed3dSBarry Smith PetscFunctionBegin; 1775905e6a2fSBarry Smith if (scall == MAT_INITIAL_MATRIX) { 1776df750dc8SHong Zhang ierr = PetscCalloc1(n+1,B);CHKERRQ(ierr); 1777905e6a2fSBarry Smith } 1778905e6a2fSBarry Smith 1779905e6a2fSBarry Smith for (i=0; i<n; i++) { 17807dae84e0SHong Zhang ierr = MatCreateSubMatrix_SeqDense(A,irow[i],icol[i],PETSC_DECIDE,scall,&(*B)[i]);CHKERRQ(ierr); 1781905e6a2fSBarry Smith } 17823a40ed3dSBarry Smith PetscFunctionReturn(0); 1783905e6a2fSBarry Smith } 1784905e6a2fSBarry Smith 1785e0877f53SBarry Smith static PetscErrorCode MatAssemblyBegin_SeqDense(Mat mat,MatAssemblyType mode) 1786c0aa2d19SHong Zhang { 1787c0aa2d19SHong Zhang PetscFunctionBegin; 1788c0aa2d19SHong Zhang PetscFunctionReturn(0); 1789c0aa2d19SHong Zhang } 1790c0aa2d19SHong Zhang 1791e0877f53SBarry Smith static PetscErrorCode MatAssemblyEnd_SeqDense(Mat mat,MatAssemblyType mode) 1792c0aa2d19SHong Zhang { 1793c0aa2d19SHong Zhang PetscFunctionBegin; 1794c0aa2d19SHong Zhang PetscFunctionReturn(0); 1795c0aa2d19SHong Zhang } 1796c0aa2d19SHong Zhang 1797e0877f53SBarry Smith static PetscErrorCode MatCopy_SeqDense(Mat A,Mat B,MatStructure str) 17984b0e389bSBarry Smith { 17994b0e389bSBarry Smith Mat_SeqDense *a = (Mat_SeqDense*)A->data,*b = (Mat_SeqDense*)B->data; 18006849ba73SBarry Smith PetscErrorCode ierr; 1801d0f46423SBarry Smith PetscInt lda1=a->lda,lda2=b->lda, m=A->rmap->n,n=A->cmap->n, j; 18023a40ed3dSBarry Smith 18033a40ed3dSBarry Smith PetscFunctionBegin; 180433f4a19fSKris Buschelman /* If the two matrices don't have the same copy implementation, they aren't compatible for fast copy. */ 180533f4a19fSKris Buschelman if (A->ops->copy != B->ops->copy) { 1806cb5b572fSBarry Smith ierr = MatCopy_Basic(A,B,str);CHKERRQ(ierr); 18073a40ed3dSBarry Smith PetscFunctionReturn(0); 18083a40ed3dSBarry Smith } 1809e32f2f54SBarry Smith if (m != B->rmap->n || n != B->cmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"size(B) != size(A)"); 1810a5ce6ee0Svictorle if (lda1>m || lda2>m) { 18110dbb7854Svictorle for (j=0; j<n; j++) { 1812a5ce6ee0Svictorle ierr = PetscMemcpy(b->v+j*lda2,a->v+j*lda1,m*sizeof(PetscScalar));CHKERRQ(ierr); 1813a5ce6ee0Svictorle } 1814a5ce6ee0Svictorle } else { 1815d0f46423SBarry Smith ierr = PetscMemcpy(b->v,a->v,A->rmap->n*A->cmap->n*sizeof(PetscScalar));CHKERRQ(ierr); 1816a5ce6ee0Svictorle } 1817273d9f13SBarry Smith PetscFunctionReturn(0); 1818273d9f13SBarry Smith } 1819273d9f13SBarry Smith 1820e0877f53SBarry Smith static PetscErrorCode MatSetUp_SeqDense(Mat A) 1821273d9f13SBarry Smith { 1822dfbe8321SBarry Smith PetscErrorCode ierr; 1823273d9f13SBarry Smith 1824273d9f13SBarry Smith PetscFunctionBegin; 1825273d9f13SBarry Smith ierr = MatSeqDenseSetPreallocation(A,0);CHKERRQ(ierr); 18263a40ed3dSBarry Smith PetscFunctionReturn(0); 18274b0e389bSBarry Smith } 18284b0e389bSBarry Smith 1829ba337c44SJed Brown static PetscErrorCode MatConjugate_SeqDense(Mat A) 1830ba337c44SJed Brown { 1831ba337c44SJed Brown Mat_SeqDense *a = (Mat_SeqDense*)A->data; 1832ba337c44SJed Brown PetscInt i,nz = A->rmap->n*A->cmap->n; 1833ba337c44SJed Brown PetscScalar *aa = a->v; 1834ba337c44SJed Brown 1835ba337c44SJed Brown PetscFunctionBegin; 1836ba337c44SJed Brown for (i=0; i<nz; i++) aa[i] = PetscConj(aa[i]); 1837ba337c44SJed Brown PetscFunctionReturn(0); 1838ba337c44SJed Brown } 1839ba337c44SJed Brown 1840ba337c44SJed Brown static PetscErrorCode MatRealPart_SeqDense(Mat A) 1841ba337c44SJed Brown { 1842ba337c44SJed Brown Mat_SeqDense *a = (Mat_SeqDense*)A->data; 1843ba337c44SJed Brown PetscInt i,nz = A->rmap->n*A->cmap->n; 1844ba337c44SJed Brown PetscScalar *aa = a->v; 1845ba337c44SJed Brown 1846ba337c44SJed Brown PetscFunctionBegin; 1847ba337c44SJed Brown for (i=0; i<nz; i++) aa[i] = PetscRealPart(aa[i]); 1848ba337c44SJed Brown PetscFunctionReturn(0); 1849ba337c44SJed Brown } 1850ba337c44SJed Brown 1851ba337c44SJed Brown static PetscErrorCode MatImaginaryPart_SeqDense(Mat A) 1852ba337c44SJed Brown { 1853ba337c44SJed Brown Mat_SeqDense *a = (Mat_SeqDense*)A->data; 1854ba337c44SJed Brown PetscInt i,nz = A->rmap->n*A->cmap->n; 1855ba337c44SJed Brown PetscScalar *aa = a->v; 1856ba337c44SJed Brown 1857ba337c44SJed Brown PetscFunctionBegin; 1858ba337c44SJed Brown for (i=0; i<nz; i++) aa[i] = PetscImaginaryPart(aa[i]); 1859ba337c44SJed Brown PetscFunctionReturn(0); 1860ba337c44SJed Brown } 1861284134d9SBarry Smith 1862a9fe9ddaSSatish Balay /* ----------------------------------------------------------------*/ 1863150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatMatMult_SeqDense_SeqDense(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 1864a9fe9ddaSSatish Balay { 1865a9fe9ddaSSatish Balay PetscErrorCode ierr; 1866a9fe9ddaSSatish Balay 1867a9fe9ddaSSatish Balay PetscFunctionBegin; 1868a9fe9ddaSSatish Balay if (scall == MAT_INITIAL_MATRIX) { 18693ff4c91cSHong Zhang ierr = PetscLogEventBegin(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 1870a9fe9ddaSSatish Balay ierr = MatMatMultSymbolic_SeqDense_SeqDense(A,B,fill,C);CHKERRQ(ierr); 18713ff4c91cSHong Zhang ierr = PetscLogEventEnd(MAT_MatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 1872a9fe9ddaSSatish Balay } 18733ff4c91cSHong Zhang ierr = PetscLogEventBegin(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 1874a9fe9ddaSSatish Balay ierr = MatMatMultNumeric_SeqDense_SeqDense(A,B,*C);CHKERRQ(ierr); 18753ff4c91cSHong Zhang ierr = PetscLogEventEnd(MAT_MatMultNumeric,A,B,0,0);CHKERRQ(ierr); 1876a9fe9ddaSSatish Balay PetscFunctionReturn(0); 1877a9fe9ddaSSatish Balay } 1878a9fe9ddaSSatish Balay 1879a9fe9ddaSSatish Balay PetscErrorCode MatMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat *C) 1880a9fe9ddaSSatish Balay { 1881ee16a9a1SHong Zhang PetscErrorCode ierr; 1882d0f46423SBarry Smith PetscInt m=A->rmap->n,n=B->cmap->n; 1883ee16a9a1SHong Zhang Mat Cmat; 1884a9fe9ddaSSatish Balay 1885ee16a9a1SHong Zhang PetscFunctionBegin; 1886e32f2f54SBarry Smith if (A->cmap->n != B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"A->cmap->n %d != B->rmap->n %d\n",A->cmap->n,B->rmap->n); 1887ee16a9a1SHong Zhang ierr = MatCreate(PETSC_COMM_SELF,&Cmat);CHKERRQ(ierr); 1888ee16a9a1SHong Zhang ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr); 1889ee16a9a1SHong Zhang ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr); 18900298fd71SBarry Smith ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr); 1891d73949e8SHong Zhang 1892ee16a9a1SHong Zhang *C = Cmat; 1893ee16a9a1SHong Zhang PetscFunctionReturn(0); 1894ee16a9a1SHong Zhang } 1895a9fe9ddaSSatish Balay 1896a9fe9ddaSSatish Balay PetscErrorCode MatMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C) 1897a9fe9ddaSSatish Balay { 1898a9fe9ddaSSatish Balay Mat_SeqDense *a = (Mat_SeqDense*)A->data; 1899a9fe9ddaSSatish Balay Mat_SeqDense *b = (Mat_SeqDense*)B->data; 1900a9fe9ddaSSatish Balay Mat_SeqDense *c = (Mat_SeqDense*)C->data; 19010805154bSBarry Smith PetscBLASInt m,n,k; 1902a9fe9ddaSSatish Balay PetscScalar _DOne=1.0,_DZero=0.0; 1903c5df96a5SBarry Smith PetscErrorCode ierr; 1904fd4e9aacSBarry Smith PetscBool flg; 1905a9fe9ddaSSatish Balay 1906a9fe9ddaSSatish Balay PetscFunctionBegin; 1907fd4e9aacSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)B,MATSEQDENSE,&flg);CHKERRQ(ierr); 1908fd4e9aacSBarry Smith if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Second matrix must be dense"); 1909fd4e9aacSBarry Smith 1910fd4e9aacSBarry Smith /* Handle case where where user provided the final C matrix rather than calling MatMatMult() with MAT_INITIAL_MATRIX*/ 1911fd4e9aacSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&flg);CHKERRQ(ierr); 1912fd4e9aacSBarry Smith if (flg) { 1913fd4e9aacSBarry Smith C->ops->matmultnumeric = MatMatMultNumeric_SeqAIJ_SeqDense; 1914fd4e9aacSBarry Smith ierr = (*C->ops->matmultnumeric)(A,B,C);CHKERRQ(ierr); 1915fd4e9aacSBarry Smith PetscFunctionReturn(0); 1916fd4e9aacSBarry Smith } 1917fd4e9aacSBarry Smith 1918fd4e9aacSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQDENSE,&flg);CHKERRQ(ierr); 1919fd4e9aacSBarry Smith if (!flg) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"First matrix must be dense"); 19208208b9aeSStefano Zampini ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr); 19218208b9aeSStefano Zampini ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr); 1922c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr); 19235ca1cc5dSStefano Zampini PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda)); 1924a9fe9ddaSSatish Balay PetscFunctionReturn(0); 1925a9fe9ddaSSatish Balay } 1926a9fe9ddaSSatish Balay 1927*69f65d41SStefano Zampini PetscErrorCode MatMatTransposeMult_SeqDense_SeqDense(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 1928*69f65d41SStefano Zampini { 1929*69f65d41SStefano Zampini PetscErrorCode ierr; 1930*69f65d41SStefano Zampini 1931*69f65d41SStefano Zampini PetscFunctionBegin; 1932*69f65d41SStefano Zampini if (scall == MAT_INITIAL_MATRIX) { 1933*69f65d41SStefano Zampini ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 1934*69f65d41SStefano Zampini ierr = MatMatTransposeMultSymbolic_SeqDense_SeqDense(A,B,fill,C);CHKERRQ(ierr); 1935*69f65d41SStefano Zampini ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr); 1936*69f65d41SStefano Zampini } 1937*69f65d41SStefano Zampini ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 1938*69f65d41SStefano Zampini ierr = MatMatTransposeMultNumeric_SeqDense_SeqDense(A,B,*C);CHKERRQ(ierr); 1939*69f65d41SStefano Zampini ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr); 1940*69f65d41SStefano Zampini PetscFunctionReturn(0); 1941*69f65d41SStefano Zampini } 1942*69f65d41SStefano Zampini 1943*69f65d41SStefano Zampini PetscErrorCode MatMatTransposeMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat *C) 1944*69f65d41SStefano Zampini { 1945*69f65d41SStefano Zampini PetscErrorCode ierr; 1946*69f65d41SStefano Zampini PetscInt m=A->rmap->n,n=B->rmap->n; 1947*69f65d41SStefano Zampini Mat Cmat; 1948*69f65d41SStefano Zampini 1949*69f65d41SStefano Zampini PetscFunctionBegin; 1950*69f65d41SStefano Zampini if (A->cmap->n != B->cmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"A->cmap->n %d != B->cmap->n %d\n",A->cmap->n,B->cmap->n); 1951*69f65d41SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&Cmat);CHKERRQ(ierr); 1952*69f65d41SStefano Zampini ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr); 1953*69f65d41SStefano Zampini ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr); 1954*69f65d41SStefano Zampini ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr); 1955*69f65d41SStefano Zampini 1956*69f65d41SStefano Zampini Cmat->assembled = PETSC_TRUE; 1957*69f65d41SStefano Zampini 1958*69f65d41SStefano Zampini *C = Cmat; 1959*69f65d41SStefano Zampini PetscFunctionReturn(0); 1960*69f65d41SStefano Zampini } 1961*69f65d41SStefano Zampini 1962*69f65d41SStefano Zampini PetscErrorCode MatMatTransposeMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C) 1963*69f65d41SStefano Zampini { 1964*69f65d41SStefano Zampini Mat_SeqDense *a = (Mat_SeqDense*)A->data; 1965*69f65d41SStefano Zampini Mat_SeqDense *b = (Mat_SeqDense*)B->data; 1966*69f65d41SStefano Zampini Mat_SeqDense *c = (Mat_SeqDense*)C->data; 1967*69f65d41SStefano Zampini PetscBLASInt m,n,k; 1968*69f65d41SStefano Zampini PetscScalar _DOne=1.0,_DZero=0.0; 1969*69f65d41SStefano Zampini PetscErrorCode ierr; 1970*69f65d41SStefano Zampini 1971*69f65d41SStefano Zampini PetscFunctionBegin; 1972*69f65d41SStefano Zampini ierr = PetscBLASIntCast(A->rmap->n,&m);CHKERRQ(ierr); 1973*69f65d41SStefano Zampini ierr = PetscBLASIntCast(B->rmap->n,&n);CHKERRQ(ierr); 1974*69f65d41SStefano Zampini ierr = PetscBLASIntCast(A->cmap->n,&k);CHKERRQ(ierr); 1975*69f65d41SStefano Zampini PetscStackCallBLAS("BLASgemm",BLASgemm_("N","T",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda)); 1976*69f65d41SStefano Zampini PetscFunctionReturn(0); 1977*69f65d41SStefano Zampini } 1978*69f65d41SStefano Zampini 197975648e8dSHong Zhang PetscErrorCode MatTransposeMatMult_SeqDense_SeqDense(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C) 1980a9fe9ddaSSatish Balay { 1981a9fe9ddaSSatish Balay PetscErrorCode ierr; 1982a9fe9ddaSSatish Balay 1983a9fe9ddaSSatish Balay PetscFunctionBegin; 1984a9fe9ddaSSatish Balay if (scall == MAT_INITIAL_MATRIX) { 19853ff4c91cSHong Zhang ierr = PetscLogEventBegin(MAT_TransposeMatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 198675648e8dSHong Zhang ierr = MatTransposeMatMultSymbolic_SeqDense_SeqDense(A,B,fill,C);CHKERRQ(ierr); 19873ff4c91cSHong Zhang ierr = PetscLogEventEnd(MAT_TransposeMatMultSymbolic,A,B,0,0);CHKERRQ(ierr); 1988a9fe9ddaSSatish Balay } 19893ff4c91cSHong Zhang ierr = PetscLogEventBegin(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr); 199075648e8dSHong Zhang ierr = MatTransposeMatMultNumeric_SeqDense_SeqDense(A,B,*C);CHKERRQ(ierr); 19913ff4c91cSHong Zhang ierr = PetscLogEventEnd(MAT_TransposeMatMultNumeric,A,B,0,0);CHKERRQ(ierr); 1992a9fe9ddaSSatish Balay PetscFunctionReturn(0); 1993a9fe9ddaSSatish Balay } 1994a9fe9ddaSSatish Balay 199575648e8dSHong Zhang PetscErrorCode MatTransposeMatMultSymbolic_SeqDense_SeqDense(Mat A,Mat B,PetscReal fill,Mat *C) 1996a9fe9ddaSSatish Balay { 1997ee16a9a1SHong Zhang PetscErrorCode ierr; 1998d0f46423SBarry Smith PetscInt m=A->cmap->n,n=B->cmap->n; 1999ee16a9a1SHong Zhang Mat Cmat; 2000a9fe9ddaSSatish Balay 2001ee16a9a1SHong Zhang PetscFunctionBegin; 2002e32f2f54SBarry Smith if (A->rmap->n != B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"A->rmap->n %d != B->rmap->n %d\n",A->rmap->n,B->rmap->n); 2003ee16a9a1SHong Zhang ierr = MatCreate(PETSC_COMM_SELF,&Cmat);CHKERRQ(ierr); 2004ee16a9a1SHong Zhang ierr = MatSetSizes(Cmat,m,n,m,n);CHKERRQ(ierr); 2005ee16a9a1SHong Zhang ierr = MatSetType(Cmat,MATSEQDENSE);CHKERRQ(ierr); 20060298fd71SBarry Smith ierr = MatSeqDenseSetPreallocation(Cmat,NULL);CHKERRQ(ierr); 20072205254eSKarl Rupp 2008ee16a9a1SHong Zhang Cmat->assembled = PETSC_TRUE; 20092205254eSKarl Rupp 2010ee16a9a1SHong Zhang *C = Cmat; 2011ee16a9a1SHong Zhang PetscFunctionReturn(0); 2012ee16a9a1SHong Zhang } 2013a9fe9ddaSSatish Balay 201475648e8dSHong Zhang PetscErrorCode MatTransposeMatMultNumeric_SeqDense_SeqDense(Mat A,Mat B,Mat C) 2015a9fe9ddaSSatish Balay { 2016a9fe9ddaSSatish Balay Mat_SeqDense *a = (Mat_SeqDense*)A->data; 2017a9fe9ddaSSatish Balay Mat_SeqDense *b = (Mat_SeqDense*)B->data; 2018a9fe9ddaSSatish Balay Mat_SeqDense *c = (Mat_SeqDense*)C->data; 20190805154bSBarry Smith PetscBLASInt m,n,k; 2020a9fe9ddaSSatish Balay PetscScalar _DOne=1.0,_DZero=0.0; 2021c5df96a5SBarry Smith PetscErrorCode ierr; 2022a9fe9ddaSSatish Balay 2023a9fe9ddaSSatish Balay PetscFunctionBegin; 20248208b9aeSStefano Zampini ierr = PetscBLASIntCast(C->rmap->n,&m);CHKERRQ(ierr); 20258208b9aeSStefano Zampini ierr = PetscBLASIntCast(C->cmap->n,&n);CHKERRQ(ierr); 2026c5df96a5SBarry Smith ierr = PetscBLASIntCast(A->rmap->n,&k);CHKERRQ(ierr); 20275ca1cc5dSStefano Zampini PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&m,&n,&k,&_DOne,a->v,&a->lda,b->v,&b->lda,&_DZero,c->v,&c->lda)); 2028a9fe9ddaSSatish Balay PetscFunctionReturn(0); 2029a9fe9ddaSSatish Balay } 2030985db425SBarry Smith 2031e0877f53SBarry Smith static PetscErrorCode MatGetRowMax_SeqDense(Mat A,Vec v,PetscInt idx[]) 2032985db425SBarry Smith { 2033985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense*)A->data; 2034985db425SBarry Smith PetscErrorCode ierr; 2035d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n,p; 2036985db425SBarry Smith PetscScalar *x; 2037985db425SBarry Smith MatScalar *aa = a->v; 2038985db425SBarry Smith 2039985db425SBarry Smith PetscFunctionBegin; 2040e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2041985db425SBarry Smith 2042985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2043985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2044985db425SBarry Smith ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr); 2045e32f2f54SBarry Smith if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2046985db425SBarry Smith for (i=0; i<m; i++) { 2047985db425SBarry Smith x[i] = aa[i]; if (idx) idx[i] = 0; 2048985db425SBarry Smith for (j=1; j<n; j++) { 2049985db425SBarry Smith if (PetscRealPart(x[i]) < PetscRealPart(aa[i+m*j])) {x[i] = aa[i + m*j]; if (idx) idx[i] = j;} 2050985db425SBarry Smith } 2051985db425SBarry Smith } 2052985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2053985db425SBarry Smith PetscFunctionReturn(0); 2054985db425SBarry Smith } 2055985db425SBarry Smith 2056e0877f53SBarry Smith static PetscErrorCode MatGetRowMaxAbs_SeqDense(Mat A,Vec v,PetscInt idx[]) 2057985db425SBarry Smith { 2058985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense*)A->data; 2059985db425SBarry Smith PetscErrorCode ierr; 2060d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n,p; 2061985db425SBarry Smith PetscScalar *x; 2062985db425SBarry Smith PetscReal atmp; 2063985db425SBarry Smith MatScalar *aa = a->v; 2064985db425SBarry Smith 2065985db425SBarry Smith PetscFunctionBegin; 2066e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2067985db425SBarry Smith 2068985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2069985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2070985db425SBarry Smith ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr); 2071e32f2f54SBarry Smith if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2072985db425SBarry Smith for (i=0; i<m; i++) { 20739189402eSHong Zhang x[i] = PetscAbsScalar(aa[i]); 2074985db425SBarry Smith for (j=1; j<n; j++) { 2075985db425SBarry Smith atmp = PetscAbsScalar(aa[i+m*j]); 2076985db425SBarry Smith if (PetscAbsScalar(x[i]) < atmp) {x[i] = atmp; if (idx) idx[i] = j;} 2077985db425SBarry Smith } 2078985db425SBarry Smith } 2079985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2080985db425SBarry Smith PetscFunctionReturn(0); 2081985db425SBarry Smith } 2082985db425SBarry Smith 2083e0877f53SBarry Smith static PetscErrorCode MatGetRowMin_SeqDense(Mat A,Vec v,PetscInt idx[]) 2084985db425SBarry Smith { 2085985db425SBarry Smith Mat_SeqDense *a = (Mat_SeqDense*)A->data; 2086985db425SBarry Smith PetscErrorCode ierr; 2087d0f46423SBarry Smith PetscInt i,j,m = A->rmap->n,n = A->cmap->n,p; 2088985db425SBarry Smith PetscScalar *x; 2089985db425SBarry Smith MatScalar *aa = a->v; 2090985db425SBarry Smith 2091985db425SBarry Smith PetscFunctionBegin; 2092e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 2093985db425SBarry Smith 2094985db425SBarry Smith ierr = VecSet(v,0.0);CHKERRQ(ierr); 2095985db425SBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2096985db425SBarry Smith ierr = VecGetLocalSize(v,&p);CHKERRQ(ierr); 2097e32f2f54SBarry Smith if (p != A->rmap->n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"Nonconforming matrix and vector"); 2098985db425SBarry Smith for (i=0; i<m; i++) { 2099985db425SBarry Smith x[i] = aa[i]; if (idx) idx[i] = 0; 2100985db425SBarry Smith for (j=1; j<n; j++) { 2101985db425SBarry Smith if (PetscRealPart(x[i]) > PetscRealPart(aa[i+m*j])) {x[i] = aa[i + m*j]; if (idx) idx[i] = j;} 2102985db425SBarry Smith } 2103985db425SBarry Smith } 2104985db425SBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 2105985db425SBarry Smith PetscFunctionReturn(0); 2106985db425SBarry Smith } 2107985db425SBarry Smith 2108e0877f53SBarry Smith static PetscErrorCode MatGetColumnVector_SeqDense(Mat A,Vec v,PetscInt col) 21098d0534beSBarry Smith { 21108d0534beSBarry Smith Mat_SeqDense *a = (Mat_SeqDense*)A->data; 21118d0534beSBarry Smith PetscErrorCode ierr; 21128d0534beSBarry Smith PetscScalar *x; 21138d0534beSBarry Smith 21148d0534beSBarry Smith PetscFunctionBegin; 2115e32f2f54SBarry Smith if (A->factortype) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"Not for factored matrix"); 21168d0534beSBarry Smith 21178d0534beSBarry Smith ierr = VecGetArray(v,&x);CHKERRQ(ierr); 2118d0f46423SBarry Smith ierr = PetscMemcpy(x,a->v+col*a->lda,A->rmap->n*sizeof(PetscScalar));CHKERRQ(ierr); 21198d0534beSBarry Smith ierr = VecRestoreArray(v,&x);CHKERRQ(ierr); 21208d0534beSBarry Smith PetscFunctionReturn(0); 21218d0534beSBarry Smith } 21228d0534beSBarry Smith 21230716a85fSBarry Smith 21240716a85fSBarry Smith PetscErrorCode MatGetColumnNorms_SeqDense(Mat A,NormType type,PetscReal *norms) 21250716a85fSBarry Smith { 21260716a85fSBarry Smith PetscErrorCode ierr; 21270716a85fSBarry Smith PetscInt i,j,m,n; 21280716a85fSBarry Smith PetscScalar *a; 21290716a85fSBarry Smith 21300716a85fSBarry Smith PetscFunctionBegin; 21310716a85fSBarry Smith ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr); 21320716a85fSBarry Smith ierr = PetscMemzero(norms,n*sizeof(PetscReal));CHKERRQ(ierr); 21338c778c55SBarry Smith ierr = MatDenseGetArray(A,&a);CHKERRQ(ierr); 21340716a85fSBarry Smith if (type == NORM_2) { 21350716a85fSBarry Smith for (i=0; i<n; i++) { 21360716a85fSBarry Smith for (j=0; j<m; j++) { 21370716a85fSBarry Smith norms[i] += PetscAbsScalar(a[j]*a[j]); 21380716a85fSBarry Smith } 21390716a85fSBarry Smith a += m; 21400716a85fSBarry Smith } 21410716a85fSBarry Smith } else if (type == NORM_1) { 21420716a85fSBarry Smith for (i=0; i<n; i++) { 21430716a85fSBarry Smith for (j=0; j<m; j++) { 21440716a85fSBarry Smith norms[i] += PetscAbsScalar(a[j]); 21450716a85fSBarry Smith } 21460716a85fSBarry Smith a += m; 21470716a85fSBarry Smith } 21480716a85fSBarry Smith } else if (type == NORM_INFINITY) { 21490716a85fSBarry Smith for (i=0; i<n; i++) { 21500716a85fSBarry Smith for (j=0; j<m; j++) { 21510716a85fSBarry Smith norms[i] = PetscMax(PetscAbsScalar(a[j]),norms[i]); 21520716a85fSBarry Smith } 21530716a85fSBarry Smith a += m; 21540716a85fSBarry Smith } 2155ce94432eSBarry Smith } else SETERRQ(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_WRONG,"Unknown NormType"); 21568c778c55SBarry Smith ierr = MatDenseRestoreArray(A,&a);CHKERRQ(ierr); 21570716a85fSBarry Smith if (type == NORM_2) { 21588f1a2a5eSBarry Smith for (i=0; i<n; i++) norms[i] = PetscSqrtReal(norms[i]); 21590716a85fSBarry Smith } 21600716a85fSBarry Smith PetscFunctionReturn(0); 21610716a85fSBarry Smith } 21620716a85fSBarry Smith 216373a71a0fSBarry Smith static PetscErrorCode MatSetRandom_SeqDense(Mat x,PetscRandom rctx) 216473a71a0fSBarry Smith { 216573a71a0fSBarry Smith PetscErrorCode ierr; 216673a71a0fSBarry Smith PetscScalar *a; 216773a71a0fSBarry Smith PetscInt m,n,i; 216873a71a0fSBarry Smith 216973a71a0fSBarry Smith PetscFunctionBegin; 217073a71a0fSBarry Smith ierr = MatGetSize(x,&m,&n);CHKERRQ(ierr); 21718c778c55SBarry Smith ierr = MatDenseGetArray(x,&a);CHKERRQ(ierr); 217273a71a0fSBarry Smith for (i=0; i<m*n; i++) { 217373a71a0fSBarry Smith ierr = PetscRandomGetValue(rctx,a+i);CHKERRQ(ierr); 217473a71a0fSBarry Smith } 21758c778c55SBarry Smith ierr = MatDenseRestoreArray(x,&a);CHKERRQ(ierr); 217673a71a0fSBarry Smith PetscFunctionReturn(0); 217773a71a0fSBarry Smith } 217873a71a0fSBarry Smith 21793b49f96aSBarry Smith static PetscErrorCode MatMissingDiagonal_SeqDense(Mat A,PetscBool *missing,PetscInt *d) 21803b49f96aSBarry Smith { 21813b49f96aSBarry Smith PetscFunctionBegin; 21823b49f96aSBarry Smith *missing = PETSC_FALSE; 21833b49f96aSBarry Smith PetscFunctionReturn(0); 21843b49f96aSBarry Smith } 218573a71a0fSBarry Smith 2186abc3b08eSStefano Zampini 2187289bc588SBarry Smith /* -------------------------------------------------------------------*/ 2188a5ae1ecdSBarry Smith static struct _MatOps MatOps_Values = { MatSetValues_SeqDense, 2189905e6a2fSBarry Smith MatGetRow_SeqDense, 2190905e6a2fSBarry Smith MatRestoreRow_SeqDense, 2191905e6a2fSBarry Smith MatMult_SeqDense, 219297304618SKris Buschelman /* 4*/ MatMultAdd_SeqDense, 21937c922b88SBarry Smith MatMultTranspose_SeqDense, 21947c922b88SBarry Smith MatMultTransposeAdd_SeqDense, 2195db4efbfdSBarry Smith 0, 2196db4efbfdSBarry Smith 0, 2197db4efbfdSBarry Smith 0, 2198db4efbfdSBarry Smith /* 10*/ 0, 2199905e6a2fSBarry Smith MatLUFactor_SeqDense, 2200905e6a2fSBarry Smith MatCholeskyFactor_SeqDense, 220141f059aeSBarry Smith MatSOR_SeqDense, 2202ec8511deSBarry Smith MatTranspose_SeqDense, 220397304618SKris Buschelman /* 15*/ MatGetInfo_SeqDense, 2204905e6a2fSBarry Smith MatEqual_SeqDense, 2205905e6a2fSBarry Smith MatGetDiagonal_SeqDense, 2206905e6a2fSBarry Smith MatDiagonalScale_SeqDense, 2207905e6a2fSBarry Smith MatNorm_SeqDense, 2208c0aa2d19SHong Zhang /* 20*/ MatAssemblyBegin_SeqDense, 2209c0aa2d19SHong Zhang MatAssemblyEnd_SeqDense, 2210905e6a2fSBarry Smith MatSetOption_SeqDense, 2211905e6a2fSBarry Smith MatZeroEntries_SeqDense, 2212d519adbfSMatthew Knepley /* 24*/ MatZeroRows_SeqDense, 2213db4efbfdSBarry Smith 0, 2214db4efbfdSBarry Smith 0, 2215db4efbfdSBarry Smith 0, 2216db4efbfdSBarry Smith 0, 22174994cf47SJed Brown /* 29*/ MatSetUp_SeqDense, 2218273d9f13SBarry Smith 0, 2219905e6a2fSBarry Smith 0, 222073a71a0fSBarry Smith 0, 222173a71a0fSBarry Smith 0, 2222d519adbfSMatthew Knepley /* 34*/ MatDuplicate_SeqDense, 2223a5ae1ecdSBarry Smith 0, 2224a5ae1ecdSBarry Smith 0, 2225a5ae1ecdSBarry Smith 0, 2226a5ae1ecdSBarry Smith 0, 2227d519adbfSMatthew Knepley /* 39*/ MatAXPY_SeqDense, 22287dae84e0SHong Zhang MatCreateSubMatrices_SeqDense, 2229a5ae1ecdSBarry Smith 0, 22304b0e389bSBarry Smith MatGetValues_SeqDense, 2231a5ae1ecdSBarry Smith MatCopy_SeqDense, 2232d519adbfSMatthew Knepley /* 44*/ MatGetRowMax_SeqDense, 2233a5ae1ecdSBarry Smith MatScale_SeqDense, 22347d68702bSBarry Smith MatShift_Basic, 2235a5ae1ecdSBarry Smith 0, 22363f49a652SStefano Zampini MatZeroRowsColumns_SeqDense, 223773a71a0fSBarry Smith /* 49*/ MatSetRandom_SeqDense, 2238a5ae1ecdSBarry Smith 0, 2239a5ae1ecdSBarry Smith 0, 2240a5ae1ecdSBarry Smith 0, 2241a5ae1ecdSBarry Smith 0, 2242d519adbfSMatthew Knepley /* 54*/ 0, 2243a5ae1ecdSBarry Smith 0, 2244a5ae1ecdSBarry Smith 0, 2245a5ae1ecdSBarry Smith 0, 2246a5ae1ecdSBarry Smith 0, 2247d519adbfSMatthew Knepley /* 59*/ 0, 2248e03a110bSBarry Smith MatDestroy_SeqDense, 2249e03a110bSBarry Smith MatView_SeqDense, 2250357abbc8SBarry Smith 0, 225197304618SKris Buschelman 0, 2252d519adbfSMatthew Knepley /* 64*/ 0, 225397304618SKris Buschelman 0, 225497304618SKris Buschelman 0, 225597304618SKris Buschelman 0, 225697304618SKris Buschelman 0, 2257d519adbfSMatthew Knepley /* 69*/ MatGetRowMaxAbs_SeqDense, 225897304618SKris Buschelman 0, 225997304618SKris Buschelman 0, 226097304618SKris Buschelman 0, 226197304618SKris Buschelman 0, 2262d519adbfSMatthew Knepley /* 74*/ 0, 226397304618SKris Buschelman 0, 226497304618SKris Buschelman 0, 226597304618SKris Buschelman 0, 226697304618SKris Buschelman 0, 2267d519adbfSMatthew Knepley /* 79*/ 0, 226897304618SKris Buschelman 0, 226997304618SKris Buschelman 0, 227097304618SKris Buschelman 0, 22715bba2384SShri Abhyankar /* 83*/ MatLoad_SeqDense, 2272865e5f61SKris Buschelman 0, 22731cbb95d3SBarry Smith MatIsHermitian_SeqDense, 2274865e5f61SKris Buschelman 0, 2275865e5f61SKris Buschelman 0, 2276865e5f61SKris Buschelman 0, 2277d519adbfSMatthew Knepley /* 89*/ MatMatMult_SeqDense_SeqDense, 2278a9fe9ddaSSatish Balay MatMatMultSymbolic_SeqDense_SeqDense, 2279a9fe9ddaSSatish Balay MatMatMultNumeric_SeqDense_SeqDense, 2280abc3b08eSStefano Zampini MatPtAP_SeqDense_SeqDense, 2281abc3b08eSStefano Zampini MatPtAPSymbolic_SeqDense_SeqDense, 2282abc3b08eSStefano Zampini /* 94*/ MatPtAPNumeric_SeqDense_SeqDense, 2283*69f65d41SStefano Zampini MatMatTransposeMult_SeqDense_SeqDense, 2284*69f65d41SStefano Zampini MatMatTransposeMultSymbolic_SeqDense_SeqDense, 2285*69f65d41SStefano Zampini MatMatTransposeMultNumeric_SeqDense_SeqDense, 2286284134d9SBarry Smith 0, 2287d519adbfSMatthew Knepley /* 99*/ 0, 2288284134d9SBarry Smith 0, 2289284134d9SBarry Smith 0, 2290ba337c44SJed Brown MatConjugate_SeqDense, 2291f73d5cc4SBarry Smith 0, 2292ba337c44SJed Brown /*104*/ 0, 2293ba337c44SJed Brown MatRealPart_SeqDense, 2294ba337c44SJed Brown MatImaginaryPart_SeqDense, 2295985db425SBarry Smith 0, 2296985db425SBarry Smith 0, 22978208b9aeSStefano Zampini /*109*/ 0, 2298985db425SBarry Smith 0, 22998d0534beSBarry Smith MatGetRowMin_SeqDense, 2300aabbc4fbSShri Abhyankar MatGetColumnVector_SeqDense, 23013b49f96aSBarry Smith MatMissingDiagonal_SeqDense, 2302aabbc4fbSShri Abhyankar /*114*/ 0, 2303aabbc4fbSShri Abhyankar 0, 2304aabbc4fbSShri Abhyankar 0, 2305aabbc4fbSShri Abhyankar 0, 2306aabbc4fbSShri Abhyankar 0, 2307aabbc4fbSShri Abhyankar /*119*/ 0, 2308aabbc4fbSShri Abhyankar 0, 2309aabbc4fbSShri Abhyankar 0, 23100716a85fSBarry Smith 0, 23110716a85fSBarry Smith 0, 23120716a85fSBarry Smith /*124*/ 0, 23135df89d91SHong Zhang MatGetColumnNorms_SeqDense, 23145df89d91SHong Zhang 0, 23155df89d91SHong Zhang 0, 23165df89d91SHong Zhang 0, 23175df89d91SHong Zhang /*129*/ 0, 231875648e8dSHong Zhang MatTransposeMatMult_SeqDense_SeqDense, 231975648e8dSHong Zhang MatTransposeMatMultSymbolic_SeqDense_SeqDense, 232075648e8dSHong Zhang MatTransposeMatMultNumeric_SeqDense_SeqDense, 23213964eb88SJed Brown 0, 23223964eb88SJed Brown /*134*/ 0, 23233964eb88SJed Brown 0, 23243964eb88SJed Brown 0, 23253964eb88SJed Brown 0, 23263964eb88SJed Brown 0, 23273964eb88SJed Brown /*139*/ 0, 2328f9426fe0SMark Adams 0, 23293964eb88SJed Brown 0 2330985db425SBarry Smith }; 233190ace30eSBarry Smith 23324b828684SBarry Smith /*@C 2333fafbff53SBarry Smith MatCreateSeqDense - Creates a sequential dense matrix that 2334d65003e9SLois Curfman McInnes is stored in column major order (the usual Fortran 77 manner). Many 2335d65003e9SLois Curfman McInnes of the matrix operations use the BLAS and LAPACK routines. 2336289bc588SBarry Smith 2337db81eaa0SLois Curfman McInnes Collective on MPI_Comm 2338db81eaa0SLois Curfman McInnes 233920563c6bSBarry Smith Input Parameters: 2340db81eaa0SLois Curfman McInnes + comm - MPI communicator, set to PETSC_COMM_SELF 23410c775827SLois Curfman McInnes . m - number of rows 234218f449edSLois Curfman McInnes . n - number of columns 23430298fd71SBarry Smith - data - optional location of matrix data in column major order. Set data=NULL for PETSc 2344dfc5480cSLois Curfman McInnes to control all matrix memory allocation. 234520563c6bSBarry Smith 234620563c6bSBarry Smith Output Parameter: 234744cd7ae7SLois Curfman McInnes . A - the matrix 234820563c6bSBarry Smith 2349b259b22eSLois Curfman McInnes Notes: 235018f449edSLois Curfman McInnes The data input variable is intended primarily for Fortran programmers 235118f449edSLois Curfman McInnes who wish to allocate their own matrix memory space. Most users should 23520298fd71SBarry Smith set data=NULL. 235318f449edSLois Curfman McInnes 2354027ccd11SLois Curfman McInnes Level: intermediate 2355027ccd11SLois Curfman McInnes 2356dbd7a890SLois Curfman McInnes .keywords: dense, matrix, LAPACK, BLAS 2357d65003e9SLois Curfman McInnes 235869b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues() 235920563c6bSBarry Smith @*/ 23607087cfbeSBarry Smith PetscErrorCode MatCreateSeqDense(MPI_Comm comm,PetscInt m,PetscInt n,PetscScalar *data,Mat *A) 2361289bc588SBarry Smith { 2362dfbe8321SBarry Smith PetscErrorCode ierr; 23633b2fbd54SBarry Smith 23643a40ed3dSBarry Smith PetscFunctionBegin; 2365f69a0ea3SMatthew Knepley ierr = MatCreate(comm,A);CHKERRQ(ierr); 2366f69a0ea3SMatthew Knepley ierr = MatSetSizes(*A,m,n,m,n);CHKERRQ(ierr); 2367273d9f13SBarry Smith ierr = MatSetType(*A,MATSEQDENSE);CHKERRQ(ierr); 2368273d9f13SBarry Smith ierr = MatSeqDenseSetPreallocation(*A,data);CHKERRQ(ierr); 2369273d9f13SBarry Smith PetscFunctionReturn(0); 2370273d9f13SBarry Smith } 2371273d9f13SBarry Smith 2372273d9f13SBarry Smith /*@C 2373273d9f13SBarry Smith MatSeqDenseSetPreallocation - Sets the array used for storing the matrix elements 2374273d9f13SBarry Smith 2375273d9f13SBarry Smith Collective on MPI_Comm 2376273d9f13SBarry Smith 2377273d9f13SBarry Smith Input Parameters: 23781c4f3114SJed Brown + B - the matrix 23790298fd71SBarry Smith - data - the array (or NULL) 2380273d9f13SBarry Smith 2381273d9f13SBarry Smith Notes: 2382273d9f13SBarry Smith The data input variable is intended primarily for Fortran programmers 2383273d9f13SBarry Smith who wish to allocate their own matrix memory space. Most users should 2384284134d9SBarry Smith need not call this routine. 2385273d9f13SBarry Smith 2386273d9f13SBarry Smith Level: intermediate 2387273d9f13SBarry Smith 2388273d9f13SBarry Smith .keywords: dense, matrix, LAPACK, BLAS 2389273d9f13SBarry Smith 239069b1f4b7SBarry Smith .seealso: MatCreate(), MatCreateDense(), MatSetValues(), MatSeqDenseSetLDA() 2391867c911aSBarry Smith 2392273d9f13SBarry Smith @*/ 23937087cfbeSBarry Smith PetscErrorCode MatSeqDenseSetPreallocation(Mat B,PetscScalar data[]) 2394273d9f13SBarry Smith { 23954ac538c5SBarry Smith PetscErrorCode ierr; 2396a23d5eceSKris Buschelman 2397a23d5eceSKris Buschelman PetscFunctionBegin; 23984ac538c5SBarry Smith ierr = PetscTryMethod(B,"MatSeqDenseSetPreallocation_C",(Mat,PetscScalar[]),(B,data));CHKERRQ(ierr); 2399a23d5eceSKris Buschelman PetscFunctionReturn(0); 2400a23d5eceSKris Buschelman } 2401a23d5eceSKris Buschelman 24027087cfbeSBarry Smith PetscErrorCode MatSeqDenseSetPreallocation_SeqDense(Mat B,PetscScalar *data) 2403a23d5eceSKris Buschelman { 2404273d9f13SBarry Smith Mat_SeqDense *b; 2405dfbe8321SBarry Smith PetscErrorCode ierr; 2406273d9f13SBarry Smith 2407273d9f13SBarry Smith PetscFunctionBegin; 2408273d9f13SBarry Smith B->preallocated = PETSC_TRUE; 2409a868139aSShri Abhyankar 241034ef9618SShri Abhyankar ierr = PetscLayoutSetUp(B->rmap);CHKERRQ(ierr); 241134ef9618SShri Abhyankar ierr = PetscLayoutSetUp(B->cmap);CHKERRQ(ierr); 241234ef9618SShri Abhyankar 2413273d9f13SBarry Smith b = (Mat_SeqDense*)B->data; 241486d161a7SShri Abhyankar b->Mmax = B->rmap->n; 241586d161a7SShri Abhyankar b->Nmax = B->cmap->n; 241686d161a7SShri Abhyankar if (b->lda <= 0 || b->changelda) b->lda = B->rmap->n; 241786d161a7SShri Abhyankar 2418220afb94SBarry Smith ierr = PetscIntMultError(b->lda,b->Nmax,NULL);CHKERRQ(ierr); 24199e8f95c4SLisandro Dalcin if (!data) { /* petsc-allocated storage */ 24209e8f95c4SLisandro Dalcin if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); } 2421e92229d0SSatish Balay ierr = PetscCalloc1((size_t)b->lda*b->Nmax,&b->v);CHKERRQ(ierr); 24223bb1ff40SBarry Smith ierr = PetscLogObjectMemory((PetscObject)B,b->lda*b->Nmax*sizeof(PetscScalar));CHKERRQ(ierr); 24232205254eSKarl Rupp 24249e8f95c4SLisandro Dalcin b->user_alloc = PETSC_FALSE; 2425273d9f13SBarry Smith } else { /* user-allocated storage */ 24269e8f95c4SLisandro Dalcin if (!b->user_alloc) { ierr = PetscFree(b->v);CHKERRQ(ierr); } 2427273d9f13SBarry Smith b->v = data; 2428273d9f13SBarry Smith b->user_alloc = PETSC_TRUE; 2429273d9f13SBarry Smith } 24300450473dSBarry Smith B->assembled = PETSC_TRUE; 2431273d9f13SBarry Smith PetscFunctionReturn(0); 2432273d9f13SBarry Smith } 2433273d9f13SBarry Smith 243465b80a83SHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 2435cc2e6a90SBarry Smith PETSC_INTERN PetscErrorCode MatConvert_SeqDense_Elemental(Mat A, MatType newtype,MatReuse reuse,Mat *newmat) 24368baccfbdSHong Zhang { 2437d77f618aSHong Zhang Mat mat_elemental; 2438d77f618aSHong Zhang PetscErrorCode ierr; 2439d77f618aSHong Zhang PetscScalar *array,*v_colwise; 2440d77f618aSHong Zhang PetscInt M=A->rmap->N,N=A->cmap->N,i,j,k,*rows,*cols; 2441d77f618aSHong Zhang 24428baccfbdSHong Zhang PetscFunctionBegin; 2443d77f618aSHong Zhang ierr = PetscMalloc3(M*N,&v_colwise,M,&rows,N,&cols);CHKERRQ(ierr); 2444d77f618aSHong Zhang ierr = MatDenseGetArray(A,&array);CHKERRQ(ierr); 2445d77f618aSHong Zhang /* convert column-wise array into row-wise v_colwise, see MatSetValues_Elemental() */ 2446d77f618aSHong Zhang k = 0; 2447d77f618aSHong Zhang for (j=0; j<N; j++) { 2448d77f618aSHong Zhang cols[j] = j; 2449d77f618aSHong Zhang for (i=0; i<M; i++) { 2450d77f618aSHong Zhang v_colwise[j*M+i] = array[k++]; 2451d77f618aSHong Zhang } 2452d77f618aSHong Zhang } 2453d77f618aSHong Zhang for (i=0; i<M; i++) { 2454d77f618aSHong Zhang rows[i] = i; 2455d77f618aSHong Zhang } 2456d77f618aSHong Zhang ierr = MatDenseRestoreArray(A,&array);CHKERRQ(ierr); 2457d77f618aSHong Zhang 2458d77f618aSHong Zhang ierr = MatCreate(PetscObjectComm((PetscObject)A), &mat_elemental);CHKERRQ(ierr); 2459d77f618aSHong Zhang ierr = MatSetSizes(mat_elemental,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 2460d77f618aSHong Zhang ierr = MatSetType(mat_elemental,MATELEMENTAL);CHKERRQ(ierr); 2461d77f618aSHong Zhang ierr = MatSetUp(mat_elemental);CHKERRQ(ierr); 2462d77f618aSHong Zhang 2463d77f618aSHong Zhang /* PETSc-Elemental interaface uses axpy for setting off-processor entries, only ADD_VALUES is allowed */ 2464d77f618aSHong Zhang ierr = MatSetValues(mat_elemental,M,rows,N,cols,v_colwise,ADD_VALUES);CHKERRQ(ierr); 2465d77f618aSHong Zhang ierr = MatAssemblyBegin(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2466d77f618aSHong Zhang ierr = MatAssemblyEnd(mat_elemental, MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2467d77f618aSHong Zhang ierr = PetscFree3(v_colwise,rows,cols);CHKERRQ(ierr); 2468d77f618aSHong Zhang 2469511c6705SHong Zhang if (reuse == MAT_INPLACE_MATRIX) { 247028be2f97SBarry Smith ierr = MatHeaderReplace(A,&mat_elemental);CHKERRQ(ierr); 2471d77f618aSHong Zhang } else { 2472d77f618aSHong Zhang *newmat = mat_elemental; 2473d77f618aSHong Zhang } 24748baccfbdSHong Zhang PetscFunctionReturn(0); 24758baccfbdSHong Zhang } 247665b80a83SHong Zhang #endif 24778baccfbdSHong Zhang 24781b807ce4Svictorle /*@C 24791b807ce4Svictorle MatSeqDenseSetLDA - Declare the leading dimension of the user-provided array 24801b807ce4Svictorle 24811b807ce4Svictorle Input parameter: 24821b807ce4Svictorle + A - the matrix 24831b807ce4Svictorle - lda - the leading dimension 24841b807ce4Svictorle 24851b807ce4Svictorle Notes: 2486867c911aSBarry Smith This routine is to be used in conjunction with MatSeqDenseSetPreallocation(); 24871b807ce4Svictorle it asserts that the preallocation has a leading dimension (the LDA parameter 24881b807ce4Svictorle of Blas and Lapack fame) larger than M, the first dimension of the matrix. 24891b807ce4Svictorle 24901b807ce4Svictorle Level: intermediate 24911b807ce4Svictorle 24921b807ce4Svictorle .keywords: dense, matrix, LAPACK, BLAS 24931b807ce4Svictorle 2494284134d9SBarry Smith .seealso: MatCreate(), MatCreateSeqDense(), MatSeqDenseSetPreallocation(), MatSetMaximumSize() 2495867c911aSBarry Smith 24961b807ce4Svictorle @*/ 24977087cfbeSBarry Smith PetscErrorCode MatSeqDenseSetLDA(Mat B,PetscInt lda) 24981b807ce4Svictorle { 24991b807ce4Svictorle Mat_SeqDense *b = (Mat_SeqDense*)B->data; 250021a2c019SBarry Smith 25011b807ce4Svictorle PetscFunctionBegin; 2502e32f2f54SBarry Smith if (lda < B->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_SIZ,"LDA %D must be at least matrix dimension %D",lda,B->rmap->n); 25031b807ce4Svictorle b->lda = lda; 250421a2c019SBarry Smith b->changelda = PETSC_FALSE; 250521a2c019SBarry Smith b->Mmax = PetscMax(b->Mmax,lda); 25061b807ce4Svictorle PetscFunctionReturn(0); 25071b807ce4Svictorle } 25081b807ce4Svictorle 25090bad9183SKris Buschelman /*MC 2510fafad747SKris Buschelman MATSEQDENSE - MATSEQDENSE = "seqdense" - A matrix type to be used for sequential dense matrices. 25110bad9183SKris Buschelman 25120bad9183SKris Buschelman Options Database Keys: 25130bad9183SKris Buschelman . -mat_type seqdense - sets the matrix type to "seqdense" during a call to MatSetFromOptions() 25140bad9183SKris Buschelman 25150bad9183SKris Buschelman Level: beginner 25160bad9183SKris Buschelman 251789665df3SBarry Smith .seealso: MatCreateSeqDense() 251889665df3SBarry Smith 25190bad9183SKris Buschelman M*/ 25200bad9183SKris Buschelman 25218cc058d9SJed Brown PETSC_EXTERN PetscErrorCode MatCreate_SeqDense(Mat B) 2522273d9f13SBarry Smith { 2523273d9f13SBarry Smith Mat_SeqDense *b; 2524dfbe8321SBarry Smith PetscErrorCode ierr; 25257c334f02SBarry Smith PetscMPIInt size; 2526273d9f13SBarry Smith 2527273d9f13SBarry Smith PetscFunctionBegin; 2528ce94432eSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)B),&size);CHKERRQ(ierr); 2529e32f2f54SBarry Smith if (size > 1) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Comm must be of size 1"); 253055659b69SBarry Smith 2531b00a9115SJed Brown ierr = PetscNewLog(B,&b);CHKERRQ(ierr); 2532549d3d68SSatish Balay ierr = PetscMemcpy(B->ops,&MatOps_Values,sizeof(struct _MatOps));CHKERRQ(ierr); 253344cd7ae7SLois Curfman McInnes B->data = (void*)b; 253418f449edSLois Curfman McInnes 2535273d9f13SBarry Smith b->roworiented = PETSC_TRUE; 25364e220ebcSLois Curfman McInnes 2537bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseGetArray_C",MatDenseGetArray_SeqDense);CHKERRQ(ierr); 2538bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatDenseRestoreArray_C",MatDenseRestoreArray_SeqDense);CHKERRQ(ierr); 2539bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_seqaij_C",MatConvert_SeqDense_SeqAIJ);CHKERRQ(ierr); 25408baccfbdSHong Zhang #if defined(PETSC_HAVE_ELEMENTAL) 25418baccfbdSHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatConvert_seqdense_elemental_C",MatConvert_SeqDense_Elemental);CHKERRQ(ierr); 25428baccfbdSHong Zhang #endif 2543bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatSeqDenseSetPreallocation_C",MatSeqDenseSetPreallocation_SeqDense);CHKERRQ(ierr); 2544bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMult_seqaij_seqdense_C",MatMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr); 2545bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultSymbolic_seqaij_seqdense_C",MatMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr); 2546bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)B,"MatMatMultNumeric_seqaij_seqdense_C",MatMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr); 2547abc3b08eSStefano Zampini ierr = PetscObjectComposeFunction((PetscObject)B,"MatPtAP_seqaij_seqdense_C",MatPtAP_SeqDense_SeqDense);CHKERRQ(ierr); 25483bf78175SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMult_seqaij_seqdense_C",MatTransposeMatMult_SeqAIJ_SeqDense);CHKERRQ(ierr); 25493bf78175SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultSymbolic_seqaij_seqdense_C",MatTransposeMatMultSymbolic_SeqAIJ_SeqDense);CHKERRQ(ierr); 25503bf78175SHong Zhang ierr = PetscObjectComposeFunction((PetscObject)B,"MatTransposeMatMultNumeric_seqaij_seqdense_C",MatTransposeMatMultNumeric_SeqAIJ_SeqDense);CHKERRQ(ierr); 255117667f90SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)B,MATSEQDENSE);CHKERRQ(ierr); 25523a40ed3dSBarry Smith PetscFunctionReturn(0); 2553289bc588SBarry Smith } 2554