18949adfdSHong Zhang 28949adfdSHong Zhang /* 38949adfdSHong Zhang Defines matrix-matrix product routines for pairs of MPIAIJ matrices 48949adfdSHong Zhang C = A^T * B 58949adfdSHong Zhang The routines are slightly modified from MatTransposeMatMultxxx_SeqAIJ_SeqDense(). 68949adfdSHong Zhang */ 78949adfdSHong Zhang #include <../src/mat/impls/aij/seq/aij.h> /*I "petscmat.h" I*/ 88949adfdSHong Zhang #include <../src/mat/impls/aij/mpi/mpiaij.h> 98949adfdSHong Zhang #include <../src/mat/impls/dense/mpi/mpidense.h> 108949adfdSHong Zhang 118949adfdSHong Zhang PetscErrorCode MatDestroy_MPIDense_MatTransMatMult(Mat A) 128949adfdSHong Zhang { 138949adfdSHong Zhang PetscErrorCode ierr; 148949adfdSHong Zhang Mat_MPIDense *a = (Mat_MPIDense*)A->data; 158949adfdSHong Zhang Mat_MatTransMatMult *atb = a->atb; 168949adfdSHong Zhang 178949adfdSHong Zhang PetscFunctionBegin; 188949adfdSHong Zhang ierr = MatDestroy(&atb->mA);CHKERRQ(ierr); 198949adfdSHong Zhang ierr = VecDestroy(&atb->bt);CHKERRQ(ierr); 208949adfdSHong Zhang ierr = VecDestroy(&atb->ct);CHKERRQ(ierr); 218949adfdSHong Zhang ierr = (atb->destroy)(A);CHKERRQ(ierr); 228949adfdSHong Zhang ierr = PetscFree(atb);CHKERRQ(ierr); 238949adfdSHong Zhang PetscFunctionReturn(0); 248949adfdSHong Zhang } 258949adfdSHong Zhang 264222ddf1SHong Zhang PetscErrorCode MatTransposeMatMultSymbolic_MPIAIJ_MPIDense(Mat A,Mat B,PetscReal fill,Mat C) 278949adfdSHong Zhang { 288949adfdSHong Zhang PetscErrorCode ierr; 298949adfdSHong Zhang PetscInt m=A->rmap->n,n=A->cmap->n,BN=B->cmap->N; 308949adfdSHong Zhang Mat_MatTransMatMult *atb; 318949adfdSHong Zhang Vec bt,ct; 328949adfdSHong Zhang Mat_MPIDense *c; 338949adfdSHong Zhang 348949adfdSHong Zhang PetscFunctionBegin; 35b00a9115SJed Brown ierr = PetscNew(&atb);CHKERRQ(ierr); 368949adfdSHong Zhang 378949adfdSHong Zhang /* create output dense matrix C = A^T*B */ 38*4eeee6adSStefano Zampini ierr = MatSetSizes(C,n,B->cmap->n,A->cmap->N,BN);CHKERRQ(ierr); 394222ddf1SHong Zhang ierr = MatSetType(C,MATMPIDENSE);CHKERRQ(ierr); 40*4eeee6adSStefano Zampini ierr = MatSetUp(C);CHKERRQ(ierr); 418949adfdSHong Zhang 428949adfdSHong Zhang /* create vectors bt and ct to hold locally transposed arrays of B and C */ 438949adfdSHong Zhang ierr = VecCreate(PetscObjectComm((PetscObject)A),&bt);CHKERRQ(ierr); 448949adfdSHong Zhang ierr = VecSetSizes(bt,m*BN,PETSC_DECIDE);CHKERRQ(ierr); 45c0dedaeaSBarry Smith ierr = VecSetType(bt,VECSTANDARD);CHKERRQ(ierr); 468949adfdSHong Zhang ierr = VecCreate(PetscObjectComm((PetscObject)A),&ct);CHKERRQ(ierr); 478949adfdSHong Zhang ierr = VecSetSizes(ct,n*BN,PETSC_DECIDE);CHKERRQ(ierr); 48c0dedaeaSBarry Smith ierr = VecSetType(ct,VECSTANDARD);CHKERRQ(ierr); 498949adfdSHong Zhang atb->bt = bt; 508949adfdSHong Zhang atb->ct = ct; 518949adfdSHong Zhang 524222ddf1SHong Zhang c = (Mat_MPIDense*)C->data; 538949adfdSHong Zhang c->atb = atb; 544222ddf1SHong Zhang atb->destroy = C->ops->destroy; 554222ddf1SHong Zhang C->ops->destroy = MatDestroy_MPIDense_MatTransMatMult; 564222ddf1SHong Zhang C->ops->transposematmultnumeric = MatTransposeMatMultNumeric_MPIAIJ_MPIDense; 578949adfdSHong Zhang PetscFunctionReturn(0); 588949adfdSHong Zhang } 598949adfdSHong Zhang 608949adfdSHong Zhang PetscErrorCode MatTransposeMatMultNumeric_MPIAIJ_MPIDense(Mat A,Mat B,Mat C) 618949adfdSHong Zhang { 628949adfdSHong Zhang PetscErrorCode ierr; 631683a169SBarry Smith const PetscScalar *Barray,*ctarray; 641683a169SBarry Smith PetscScalar *Carray,*btarray; 65905b3b74SHong Zhang Mat_MPIDense *b=(Mat_MPIDense*)B->data,*c=(Mat_MPIDense*)C->data; 66905b3b74SHong Zhang Mat_SeqDense *bseq=(Mat_SeqDense*)(b->A)->data,*cseq=(Mat_SeqDense*)(c->A)->data; 67905b3b74SHong Zhang PetscInt i,j,m=A->rmap->n,n=A->cmap->n,ldb=bseq->lda,BN=B->cmap->N,ldc=cseq->lda; 688949adfdSHong Zhang Mat_MatTransMatMult *atb=c->atb; 698949adfdSHong Zhang Vec bt=atb->bt,ct=atb->ct; 708949adfdSHong Zhang 718949adfdSHong Zhang PetscFunctionBegin; 728949adfdSHong Zhang /* create MAIJ matrix mA from A -- should be done in symbolic phase */ 738949adfdSHong Zhang ierr = MatDestroy(&atb->mA);CHKERRQ(ierr); 748949adfdSHong Zhang ierr = MatCreateMAIJ(A,BN,&atb->mA);CHKERRQ(ierr); 758949adfdSHong Zhang 768949adfdSHong Zhang /* transpose local arry of B, then copy it to vector bt */ 771683a169SBarry Smith ierr = MatDenseGetArrayRead(B,&Barray);CHKERRQ(ierr); 788949adfdSHong Zhang ierr = VecGetArray(bt,&btarray);CHKERRQ(ierr); 798949adfdSHong Zhang 808949adfdSHong Zhang for (j=0; j<BN; j++) { 81905b3b74SHong Zhang for (i=0; i<m; i++) btarray[i*BN + j] = Barray[j*ldb + i]; 828949adfdSHong Zhang } 838949adfdSHong Zhang ierr = VecRestoreArray(bt,&btarray);CHKERRQ(ierr); 841683a169SBarry Smith ierr = MatDenseRestoreArrayRead(B,&Barray);CHKERRQ(ierr); 858949adfdSHong Zhang 868949adfdSHong Zhang /* compute ct = mA^T * cb */ 878949adfdSHong Zhang ierr = MatMultTranspose(atb->mA,bt,ct);CHKERRQ(ierr); 888949adfdSHong Zhang 89905b3b74SHong Zhang /* transpose local array of ct to matrix C */ 908949adfdSHong Zhang ierr = MatDenseGetArray(C,&Carray);CHKERRQ(ierr); 911683a169SBarry Smith ierr = VecGetArrayRead(ct,&ctarray);CHKERRQ(ierr); 92905b3b74SHong Zhang 938949adfdSHong Zhang for (j=0; j<BN; j++) { 94905b3b74SHong Zhang for (i=0; i<n; i++) Carray[j*ldc + i] = ctarray[i*BN + j]; 958949adfdSHong Zhang } 961683a169SBarry Smith ierr = VecRestoreArrayRead(ct,&ctarray);CHKERRQ(ierr); 978949adfdSHong Zhang ierr = MatDenseRestoreArray(C,&Carray);CHKERRQ(ierr); 988949adfdSHong Zhang ierr = MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 998949adfdSHong Zhang ierr = MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1008949adfdSHong Zhang PetscFunctionReturn(0); 1018949adfdSHong Zhang } 102