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) 84222ddf1SHong 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 114222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductNumeric_ABC_Transpose_AIJ_AIJ(Mat RAP) 123dad0653Sstefano_zampini { 133dad0653Sstefano_zampini PetscErrorCode ierr; 144222ddf1SHong Zhang Mat_Product *product = RAP->product; 154222ddf1SHong 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); 194222ddf1SHong Zhang ierr = MatTransposeMatMatMultNumeric_AIJ_AIJ_AIJ_wHYPRE(Rt,A,P,RAP);CHKERRQ(ierr); 204222ddf1SHong Zhang PetscFunctionReturn(0); 214222ddf1SHong Zhang } 224222ddf1SHong Zhang 234222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSymbolic_ABC_Transpose_AIJ_AIJ(Mat RAP) 244222ddf1SHong Zhang { 254222ddf1SHong Zhang PetscErrorCode ierr; 264222ddf1SHong Zhang Mat_Product *product = RAP->product; 274222ddf1SHong Zhang Mat Rt,R=product->A,A=product->B,P=product->C; 284222ddf1SHong Zhang PetscBool flg; 294222ddf1SHong Zhang 304222ddf1SHong Zhang PetscFunctionBegin; 314222ddf1SHong Zhang /* local sizes of matrices will be checked by the calling subroutines */ 324222ddf1SHong 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); 354222ddf1SHong Zhang ierr = MatTransposeMatMatMultSymbolic_AIJ_AIJ_AIJ_wHYPRE(Rt,A,P,product->fill,RAP);CHKERRQ(ierr); 364222ddf1SHong Zhang RAP->ops->productnumeric = MatProductNumeric_ABC_Transpose_AIJ_AIJ; 374222ddf1SHong Zhang PetscFunctionReturn(0); 383dad0653Sstefano_zampini } 394222ddf1SHong Zhang 404222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_Transpose_AIJ_AIJ(Mat C) 414222ddf1SHong Zhang { 424222ddf1SHong Zhang Mat_Product *product = C->product; 434222ddf1SHong Zhang 444222ddf1SHong Zhang PetscFunctionBegin; 454222ddf1SHong Zhang if (product->type == MATPRODUCT_ABC) { 464222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_ABC_Transpose_AIJ_AIJ; 47*544a5e07SHong Zhang } else SETERRQ1(PetscObjectComm((PetscObject)C),PETSC_ERR_SUP,"MatProduct type %s is not supported for Transpose, AIJ and AIJ matrices",MatProductTypes[product->type]); 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 774222ddf1SHong 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; 814222ddf1SHong Zhang PetscBool scalable; 824222ddf1SHong Zhang Mat_Product *product = D->product; 83f996eeb8SHong Zhang 84f996eeb8SHong Zhang PetscFunctionBegin; 854222ddf1SHong Zhang ierr = MatCreate(PetscObjectComm((PetscObject)A),&BC);CHKERRQ(ierr); 864222ddf1SHong Zhang if (product) { 874222ddf1SHong Zhang ierr = PetscStrcmp(product->alg,"scalable",&scalable);CHKERRQ(ierr); 884222ddf1SHong Zhang } else SETERRQ(PetscObjectComm((PetscObject)D),PETSC_ERR_ARG_NULL,"Call MatProductCreate() first"); 898a9b8717SHong Zhang 904222ddf1SHong Zhang if (scalable) { 914222ddf1SHong 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); 944222ddf1SHong Zhang } else { 954222ddf1SHong 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 } 994222ddf1SHong Zhang product->Dwork = BC; 100f996eeb8SHong Zhang 1014222ddf1SHong Zhang D->ops->matmatmultnumeric = MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ; 1024222ddf1SHong 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; 1094222ddf1SHong Zhang Mat_Product *product = D->product; 1104222ddf1SHong 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 1184222ddf1SHong Zhang /* ----------------------------------------------------- */ 1194222ddf1SHong Zhang PetscErrorCode MatDestroy_MPIAIJ_RARt(Mat C) 1208d45306eSHong Zhang { 1218d45306eSHong Zhang PetscErrorCode ierr; 1224222ddf1SHong Zhang Mat_MPIAIJ *c = (Mat_MPIAIJ*)C->data; 1234222ddf1SHong Zhang Mat_RARt *rart = c->rart; 1244222ddf1SHong Zhang 1254222ddf1SHong Zhang PetscFunctionBegin; 1264222ddf1SHong Zhang ierr = MatDestroy(&rart->Rt);CHKERRQ(ierr); 1274222ddf1SHong Zhang 1284222ddf1SHong Zhang C->ops->destroy = rart->destroy; 1294222ddf1SHong Zhang if (C->ops->destroy) { 1304222ddf1SHong Zhang ierr = (*C->ops->destroy)(C);CHKERRQ(ierr); 1314222ddf1SHong Zhang } 1324222ddf1SHong Zhang ierr = PetscFree(rart);CHKERRQ(ierr); 1334222ddf1SHong Zhang PetscFunctionReturn(0); 1344222ddf1SHong Zhang } 1354222ddf1SHong Zhang 1364222ddf1SHong Zhang PetscErrorCode MatProductNumeric_RARt_MPIAIJ_MPIAIJ(Mat C) 1374222ddf1SHong Zhang { 1384222ddf1SHong Zhang PetscErrorCode ierr; 1394222ddf1SHong Zhang Mat_MPIAIJ *c = (Mat_MPIAIJ*)C->data; 1404222ddf1SHong Zhang Mat_RARt *rart = c->rart; 1414222ddf1SHong Zhang Mat_Product *product = C->product; 1424222ddf1SHong Zhang Mat A=product->A,R=product->B,Rt=rart->Rt; 1434222ddf1SHong Zhang 1444222ddf1SHong Zhang PetscFunctionBegin; 1454222ddf1SHong Zhang ierr = MatTranspose(R,MAT_REUSE_MATRIX,&Rt);CHKERRQ(ierr); 1464222ddf1SHong Zhang ierr = (C->ops->matmatmultnumeric)(R,A,Rt,C);CHKERRQ(ierr); 1474222ddf1SHong Zhang PetscFunctionReturn(0); 1484222ddf1SHong Zhang } 1494222ddf1SHong Zhang 1504222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_RARt_MPIAIJ_MPIAIJ(Mat C) 1514222ddf1SHong Zhang { 1524222ddf1SHong Zhang PetscErrorCode ierr; 1534222ddf1SHong Zhang Mat_Product *product = C->product; 1544222ddf1SHong Zhang Mat A=product->A,R=product->B,Rt; 1554222ddf1SHong Zhang PetscReal fill=product->fill; 1564222ddf1SHong Zhang Mat_RARt *rart; 1574222ddf1SHong Zhang Mat_MPIAIJ *c; 1588d45306eSHong Zhang 1598d45306eSHong Zhang PetscFunctionBegin; 1608d45306eSHong Zhang ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr); 1614222ddf1SHong 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); 1634222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_RARt_MPIAIJ_MPIAIJ; 1644222ddf1SHong Zhang 1654222ddf1SHong Zhang /* create a supporting struct */ 1664222ddf1SHong Zhang ierr = PetscNew(&rart);CHKERRQ(ierr); 1674222ddf1SHong Zhang c = (Mat_MPIAIJ*)C->data; 1684222ddf1SHong Zhang c->rart = rart; 1694222ddf1SHong Zhang rart->Rt = Rt; 1704222ddf1SHong Zhang rart->destroy = C->ops->destroy; 1714222ddf1SHong Zhang C->ops->destroy = MatDestroy_MPIAIJ_RARt; 1728d45306eSHong Zhang PetscFunctionReturn(0); 1738d45306eSHong Zhang } 174