1f996eeb8SHong Zhang /* 2f996eeb8SHong Zhang Defines matrix-matrix-matrix product routines for MPIAIJ matrices 3f996eeb8SHong Zhang D = A * B * C 4f996eeb8SHong Zhang */ 5f996eeb8SHong Zhang #include <../src/mat/impls/aij/mpi/mpiaij.h> /*I "petscmat.h" I*/ 6f996eeb8SHong Zhang 73dad0653Sstefano_zampini #if defined(PETSC_HAVE_HYPRE) 8*4222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatTransposeMatMatMultSymbolic_AIJ_AIJ_AIJ_wHYPRE(Mat,Mat,Mat,PetscReal,Mat); 93dad0653Sstefano_zampini PETSC_INTERN PetscErrorCode MatTransposeMatMatMultNumeric_AIJ_AIJ_AIJ_wHYPRE(Mat,Mat,Mat,Mat); 103dad0653Sstefano_zampini 11*4222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductNumeric_ABC_Transpose_AIJ_AIJ(Mat RAP) 123dad0653Sstefano_zampini { 133dad0653Sstefano_zampini PetscErrorCode ierr; 14*4222ddf1SHong Zhang Mat_Product *product = RAP->product; 15*4222ddf1SHong Zhang Mat Rt,R=product->A,A=product->B,P=product->C; 163dad0653Sstefano_zampini 173dad0653Sstefano_zampini PetscFunctionBegin; 183dad0653Sstefano_zampini ierr = MatTransposeGetMat(R,&Rt);CHKERRQ(ierr); 19*4222ddf1SHong Zhang ierr = MatTransposeMatMatMultNumeric_AIJ_AIJ_AIJ_wHYPRE(Rt,A,P,RAP);CHKERRQ(ierr); 20*4222ddf1SHong Zhang PetscFunctionReturn(0); 21*4222ddf1SHong Zhang } 22*4222ddf1SHong Zhang 23*4222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSymbolic_ABC_Transpose_AIJ_AIJ(Mat RAP) 24*4222ddf1SHong Zhang { 25*4222ddf1SHong Zhang PetscErrorCode ierr; 26*4222ddf1SHong Zhang Mat_Product *product = RAP->product; 27*4222ddf1SHong Zhang Mat Rt,R=product->A,A=product->B,P=product->C; 28*4222ddf1SHong Zhang PetscBool flg; 29*4222ddf1SHong Zhang 30*4222ddf1SHong Zhang PetscFunctionBegin; 31*4222ddf1SHong Zhang /* local sizes of matrices will be checked by the calling subroutines */ 32*4222ddf1SHong Zhang ierr = MatTransposeGetMat(R,&Rt);CHKERRQ(ierr); 33d248a85cSRichard Tran Mills ierr = PetscObjectTypeCompareAny((PetscObject)Rt,&flg,MATSEQAIJ,MATSEQAIJMKL,MATMPIAIJ,NULL);CHKERRQ(ierr); 3483976f8eSstefano_zampini if (!flg) SETERRQ1(PetscObjectComm((PetscObject)Rt),PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)Rt)->type_name); 35*4222ddf1SHong Zhang ierr = MatTransposeMatMatMultSymbolic_AIJ_AIJ_AIJ_wHYPRE(Rt,A,P,product->fill,RAP);CHKERRQ(ierr); 36*4222ddf1SHong Zhang RAP->ops->productnumeric = MatProductNumeric_ABC_Transpose_AIJ_AIJ; 37*4222ddf1SHong Zhang PetscFunctionReturn(0); 383dad0653Sstefano_zampini } 39*4222ddf1SHong Zhang 40*4222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_Transpose_AIJ_AIJ(Mat C) 41*4222ddf1SHong Zhang { 42*4222ddf1SHong Zhang Mat_Product *product = C->product; 43*4222ddf1SHong Zhang 44*4222ddf1SHong Zhang PetscFunctionBegin; 45*4222ddf1SHong Zhang if (product->type == MATPRODUCT_ABC) { 46*4222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_ABC_Transpose_AIJ_AIJ; 47*4222ddf1SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_SUP,"MatProduct type is not supported"); 483dad0653Sstefano_zampini PetscFunctionReturn(0); 493dad0653Sstefano_zampini } 503dad0653Sstefano_zampini #endif 513dad0653Sstefano_zampini 528a9b8717SHong Zhang PetscErrorCode MatFreeIntermediateDataStructures_MPIAIJ_BC(Mat ABC) 53f996eeb8SHong Zhang { 548a9b8717SHong Zhang Mat_MPIAIJ *a = (Mat_MPIAIJ*)ABC->data; 55f996eeb8SHong Zhang Mat_MatMatMatMult *matmatmatmult = a->matmatmatmult; 56f996eeb8SHong Zhang PetscErrorCode ierr; 57f996eeb8SHong Zhang 58f996eeb8SHong Zhang PetscFunctionBegin; 598a9b8717SHong Zhang if (!matmatmatmult) PetscFunctionReturn(0); 608a9b8717SHong Zhang 61f996eeb8SHong Zhang ierr = MatDestroy(&matmatmatmult->BC);CHKERRQ(ierr); 628a9b8717SHong Zhang ABC->ops->destroy = matmatmatmult->destroy; 638a9b8717SHong Zhang ierr = PetscFree(a->matmatmatmult);CHKERRQ(ierr); 648a9b8717SHong Zhang PetscFunctionReturn(0); 658a9b8717SHong Zhang } 668a9b8717SHong Zhang 678a9b8717SHong Zhang PetscErrorCode MatDestroy_MPIAIJ_MatMatMatMult(Mat A) 688a9b8717SHong Zhang { 698a9b8717SHong Zhang PetscErrorCode ierr; 708a9b8717SHong Zhang 718a9b8717SHong Zhang PetscFunctionBegin; 728a9b8717SHong Zhang ierr = (*A->ops->freeintermediatedatastructures)(A);CHKERRQ(ierr); 738a9b8717SHong Zhang ierr = (*A->ops->destroy)(A);CHKERRQ(ierr); 74f996eeb8SHong Zhang PetscFunctionReturn(0); 75f996eeb8SHong Zhang } 76f996eeb8SHong Zhang 77*4222ddf1SHong Zhang PetscErrorCode MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ(Mat A,Mat B,Mat C,PetscReal fill,Mat D) 78f996eeb8SHong Zhang { 79f996eeb8SHong Zhang PetscErrorCode ierr; 80f996eeb8SHong Zhang Mat BC; 81*4222ddf1SHong Zhang PetscBool scalable; 82*4222ddf1SHong Zhang Mat_Product *product = D->product; 83f996eeb8SHong Zhang 84f996eeb8SHong Zhang PetscFunctionBegin; 85*4222ddf1SHong Zhang ierr = MatCreate(PetscObjectComm((PetscObject)A),&BC);CHKERRQ(ierr); 86*4222ddf1SHong Zhang if (product) { 87*4222ddf1SHong Zhang ierr = PetscStrcmp(product->alg,"scalable",&scalable);CHKERRQ(ierr); 88*4222ddf1SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)D),PETSC_ERR_ARG_NULL,"Call MatProductCreate() first"); 898a9b8717SHong Zhang 90*4222ddf1SHong Zhang if (scalable) { 91*4222ddf1SHong Zhang ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ(B,C,fill,BC);CHKERRQ(ierr); 92b7e612beSHong Zhang ierr = MatZeroEntries(BC);CHKERRQ(ierr); /* initialize value entries of BC */ 93b2405163SHong Zhang ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ(A,BC,fill,D);CHKERRQ(ierr); 94*4222ddf1SHong Zhang } else { 95*4222ddf1SHong Zhang ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ_nonscalable(B,C,fill,BC);CHKERRQ(ierr); 96b7e612beSHong Zhang ierr = MatZeroEntries(BC);CHKERRQ(ierr); /* initialize value entries of BC */ 970fc8cf34SHong Zhang ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ_nonscalable(A,BC,fill,D);CHKERRQ(ierr); 98f996eeb8SHong Zhang } 99*4222ddf1SHong Zhang product->Dwork = BC; 100f996eeb8SHong Zhang 101*4222ddf1SHong Zhang D->ops->matmatmultnumeric = MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ; 102*4222ddf1SHong Zhang D->ops->freeintermediatedatastructures = MatFreeIntermediateDataStructures_MPIAIJ_BC; 103f996eeb8SHong Zhang PetscFunctionReturn(0); 104f996eeb8SHong Zhang } 105f996eeb8SHong Zhang 106f996eeb8SHong Zhang PetscErrorCode MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ(Mat A,Mat B,Mat C,Mat D) 107f996eeb8SHong Zhang { 108f996eeb8SHong Zhang PetscErrorCode ierr; 109*4222ddf1SHong Zhang Mat_Product *product = D->product; 110*4222ddf1SHong Zhang Mat BC = product->Dwork; 111f996eeb8SHong Zhang 112f996eeb8SHong Zhang PetscFunctionBegin; 113f996eeb8SHong Zhang ierr = (BC->ops->matmultnumeric)(B,C,BC);CHKERRQ(ierr); 114f996eeb8SHong Zhang ierr = (D->ops->matmultnumeric)(A,BC,D);CHKERRQ(ierr); 115f996eeb8SHong Zhang PetscFunctionReturn(0); 116f996eeb8SHong Zhang } 1178d45306eSHong Zhang 118*4222ddf1SHong Zhang /* ----------------------------------------------------- */ 119*4222ddf1SHong Zhang PetscErrorCode MatDestroy_MPIAIJ_RARt(Mat C) 1208d45306eSHong Zhang { 1218d45306eSHong Zhang PetscErrorCode ierr; 122*4222ddf1SHong Zhang Mat_MPIAIJ *c = (Mat_MPIAIJ*)C->data; 123*4222ddf1SHong Zhang Mat_RARt *rart = c->rart; 124*4222ddf1SHong Zhang 125*4222ddf1SHong Zhang PetscFunctionBegin; 126*4222ddf1SHong Zhang ierr = MatDestroy(&rart->Rt);CHKERRQ(ierr); 127*4222ddf1SHong Zhang 128*4222ddf1SHong Zhang C->ops->destroy = rart->destroy; 129*4222ddf1SHong Zhang if (C->ops->destroy) { 130*4222ddf1SHong Zhang ierr = (*C->ops->destroy)(C);CHKERRQ(ierr); 131*4222ddf1SHong Zhang } 132*4222ddf1SHong Zhang ierr = PetscFree(rart);CHKERRQ(ierr); 133*4222ddf1SHong Zhang PetscFunctionReturn(0); 134*4222ddf1SHong Zhang } 135*4222ddf1SHong Zhang 136*4222ddf1SHong Zhang PetscErrorCode MatProductNumeric_RARt_MPIAIJ_MPIAIJ(Mat C) 137*4222ddf1SHong Zhang { 138*4222ddf1SHong Zhang PetscErrorCode ierr; 139*4222ddf1SHong Zhang Mat_MPIAIJ *c = (Mat_MPIAIJ*)C->data; 140*4222ddf1SHong Zhang Mat_RARt *rart = c->rart; 141*4222ddf1SHong Zhang Mat_Product *product = C->product; 142*4222ddf1SHong Zhang Mat A=product->A,R=product->B,Rt=rart->Rt; 143*4222ddf1SHong Zhang 144*4222ddf1SHong Zhang PetscFunctionBegin; 145*4222ddf1SHong Zhang ierr = MatTranspose(R,MAT_REUSE_MATRIX,&Rt);CHKERRQ(ierr); 146*4222ddf1SHong Zhang ierr = (C->ops->matmatmultnumeric)(R,A,Rt,C);CHKERRQ(ierr); 147*4222ddf1SHong Zhang PetscFunctionReturn(0); 148*4222ddf1SHong Zhang } 149*4222ddf1SHong Zhang 150*4222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_RARt_MPIAIJ_MPIAIJ(Mat C) 151*4222ddf1SHong Zhang { 152*4222ddf1SHong Zhang PetscErrorCode ierr; 153*4222ddf1SHong Zhang Mat_Product *product = C->product; 154*4222ddf1SHong Zhang Mat A=product->A,R=product->B,Rt; 155*4222ddf1SHong Zhang PetscReal fill=product->fill; 156*4222ddf1SHong Zhang Mat_RARt *rart; 157*4222ddf1SHong Zhang Mat_MPIAIJ *c; 1588d45306eSHong Zhang 1598d45306eSHong Zhang PetscFunctionBegin; 1608d45306eSHong Zhang ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr); 161*4222ddf1SHong Zhang /* product->Dwork is used to store A*Rt in MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ() */ 1628d45306eSHong Zhang ierr = MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ(R,A,Rt,fill,C);CHKERRQ(ierr); 163*4222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_RARt_MPIAIJ_MPIAIJ; 164*4222ddf1SHong Zhang 165*4222ddf1SHong Zhang /* create a supporting struct */ 166*4222ddf1SHong Zhang ierr = PetscNew(&rart);CHKERRQ(ierr); 167*4222ddf1SHong Zhang c = (Mat_MPIAIJ*)C->data; 168*4222ddf1SHong Zhang c->rart = rart; 169*4222ddf1SHong Zhang rart->Rt = Rt; 170*4222ddf1SHong Zhang rart->destroy = C->ops->destroy; 171*4222ddf1SHong Zhang C->ops->destroy = MatDestroy_MPIAIJ_RARt; 1728d45306eSHong Zhang PetscFunctionReturn(0); 1738d45306eSHong Zhang } 174