xref: /petsc/src/mat/impls/aij/mpi/mpimatmatmatmult.c (revision 28b400f66ebc7ae0049166a2294dfcd3df27e64b)
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 {
134222ddf1SHong Zhang   Mat_Product    *product = RAP->product;
144222ddf1SHong Zhang   Mat            Rt,R=product->A,A=product->B,P=product->C;
153dad0653Sstefano_zampini 
163dad0653Sstefano_zampini   PetscFunctionBegin;
175f80ce2aSJacob Faibussowitsch   CHKERRQ(MatTransposeGetMat(R,&Rt));
185f80ce2aSJacob Faibussowitsch   CHKERRQ(MatTransposeMatMatMultNumeric_AIJ_AIJ_AIJ_wHYPRE(Rt,A,P,RAP));
194222ddf1SHong Zhang   PetscFunctionReturn(0);
204222ddf1SHong Zhang }
214222ddf1SHong Zhang 
224222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSymbolic_ABC_Transpose_AIJ_AIJ(Mat RAP)
234222ddf1SHong Zhang {
244222ddf1SHong Zhang   Mat_Product    *product = RAP->product;
254222ddf1SHong Zhang   Mat            Rt,R=product->A,A=product->B,P=product->C;
264222ddf1SHong Zhang   PetscBool      flg;
274222ddf1SHong Zhang 
284222ddf1SHong Zhang   PetscFunctionBegin;
294222ddf1SHong Zhang   /* local sizes of matrices will be checked by the calling subroutines */
305f80ce2aSJacob Faibussowitsch   CHKERRQ(MatTransposeGetMat(R,&Rt));
315f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscObjectTypeCompareAny((PetscObject)Rt,&flg,MATSEQAIJ,MATSEQAIJMKL,MATMPIAIJ,NULL));
32*28b400f6SJacob Faibussowitsch   PetscCheck(flg,PetscObjectComm((PetscObject)Rt),PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)Rt)->type_name);
335f80ce2aSJacob Faibussowitsch   CHKERRQ(MatTransposeMatMatMultSymbolic_AIJ_AIJ_AIJ_wHYPRE(Rt,A,P,product->fill,RAP));
344222ddf1SHong Zhang   RAP->ops->productnumeric = MatProductNumeric_ABC_Transpose_AIJ_AIJ;
354222ddf1SHong Zhang   PetscFunctionReturn(0);
363dad0653Sstefano_zampini }
374222ddf1SHong Zhang 
384222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_Transpose_AIJ_AIJ(Mat C)
394222ddf1SHong Zhang {
404222ddf1SHong Zhang   Mat_Product *product = C->product;
414222ddf1SHong Zhang 
424222ddf1SHong Zhang   PetscFunctionBegin;
434222ddf1SHong Zhang   if (product->type == MATPRODUCT_ABC) {
444222ddf1SHong Zhang     C->ops->productsymbolic = MatProductSymbolic_ABC_Transpose_AIJ_AIJ;
4598921bdaSJacob Faibussowitsch   } else SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_SUP,"MatProduct type %s is not supported for Transpose, AIJ and AIJ matrices",MatProductTypes[product->type]);
463dad0653Sstefano_zampini   PetscFunctionReturn(0);
473dad0653Sstefano_zampini }
483dad0653Sstefano_zampini #endif
493dad0653Sstefano_zampini 
504222ddf1SHong Zhang PetscErrorCode MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ(Mat A,Mat B,Mat C,PetscReal fill,Mat D)
51f996eeb8SHong Zhang {
52f996eeb8SHong Zhang   Mat            BC;
534222ddf1SHong Zhang   PetscBool      scalable;
546718818eSStefano Zampini   Mat_Product    *product;
55f996eeb8SHong Zhang 
56f996eeb8SHong Zhang   PetscFunctionBegin;
576718818eSStefano Zampini   MatCheckProduct(D,4);
58*28b400f6SJacob Faibussowitsch   PetscCheck(!D->product->data,PetscObjectComm((PetscObject)D),PETSC_ERR_PLIB,"Product data not empty");
596718818eSStefano Zampini   product = D->product;
605f80ce2aSJacob Faibussowitsch   CHKERRQ(MatProductCreate(B,C,NULL,&BC));
615f80ce2aSJacob Faibussowitsch   CHKERRQ(MatProductSetType(BC,MATPRODUCT_AB));
625f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscStrcmp(product->alg,"scalable",&scalable));
634222ddf1SHong Zhang   if (scalable) {
645f80ce2aSJacob Faibussowitsch     CHKERRQ(MatMatMultSymbolic_MPIAIJ_MPIAIJ(B,C,fill,BC));
655f80ce2aSJacob Faibussowitsch     CHKERRQ(MatZeroEntries(BC)); /* initialize value entries of BC */
665f80ce2aSJacob Faibussowitsch     CHKERRQ(MatMatMultSymbolic_MPIAIJ_MPIAIJ(A,BC,fill,D));
674222ddf1SHong Zhang   } else {
685f80ce2aSJacob Faibussowitsch     CHKERRQ(MatMatMultSymbolic_MPIAIJ_MPIAIJ_nonscalable(B,C,fill,BC));
695f80ce2aSJacob Faibussowitsch     CHKERRQ(MatZeroEntries(BC)); /* initialize value entries of BC */
705f80ce2aSJacob Faibussowitsch     CHKERRQ(MatMatMultSymbolic_MPIAIJ_MPIAIJ_nonscalable(A,BC,fill,D));
71f996eeb8SHong Zhang   }
725f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&product->Dwork));
734222ddf1SHong Zhang   product->Dwork = BC;
74f996eeb8SHong Zhang 
754222ddf1SHong Zhang   D->ops->matmatmultnumeric = MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ;
76f996eeb8SHong Zhang   PetscFunctionReturn(0);
77f996eeb8SHong Zhang }
78f996eeb8SHong Zhang 
79f996eeb8SHong Zhang PetscErrorCode MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ(Mat A,Mat B,Mat C,Mat D)
80f996eeb8SHong Zhang {
816718818eSStefano Zampini   Mat_Product    *product;
826718818eSStefano Zampini   Mat            BC;
83f996eeb8SHong Zhang 
84f996eeb8SHong Zhang   PetscFunctionBegin;
856718818eSStefano Zampini   MatCheckProduct(D,4);
86*28b400f6SJacob Faibussowitsch   PetscCheck(D->product->data,PetscObjectComm((PetscObject)D),PETSC_ERR_PLIB,"Product data empty");
876718818eSStefano Zampini   product = D->product;
886718818eSStefano Zampini   BC = product->Dwork;
89*28b400f6SJacob Faibussowitsch   PetscCheck(BC->ops->matmultnumeric,PetscObjectComm((PetscObject)D),PETSC_ERR_PLIB,"Missing numeric operation");
905f80ce2aSJacob Faibussowitsch   CHKERRQ((*BC->ops->matmultnumeric)(B,C,BC));
91*28b400f6SJacob Faibussowitsch   PetscCheck(D->ops->matmultnumeric,PetscObjectComm((PetscObject)D),PETSC_ERR_PLIB,"Missing numeric operation");
925f80ce2aSJacob Faibussowitsch   CHKERRQ((*D->ops->matmultnumeric)(A,BC,D));
93f996eeb8SHong Zhang   PetscFunctionReturn(0);
94f996eeb8SHong Zhang }
958d45306eSHong Zhang 
964222ddf1SHong Zhang /* ----------------------------------------------------- */
976718818eSStefano Zampini PetscErrorCode MatDestroy_MPIAIJ_RARt(void *data)
988d45306eSHong Zhang {
996718818eSStefano Zampini   Mat_RARt       *rart = (Mat_RARt*)data;
1004222ddf1SHong Zhang 
1014222ddf1SHong Zhang   PetscFunctionBegin;
1025f80ce2aSJacob Faibussowitsch   CHKERRQ(MatDestroy(&rart->Rt));
1036718818eSStefano Zampini   if (rart->destroy) {
1045f80ce2aSJacob Faibussowitsch     CHKERRQ((*rart->destroy)(rart->data));
1054222ddf1SHong Zhang   }
1065f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscFree(rart));
1074222ddf1SHong Zhang   PetscFunctionReturn(0);
1084222ddf1SHong Zhang }
1094222ddf1SHong Zhang 
1104222ddf1SHong Zhang PetscErrorCode MatProductNumeric_RARt_MPIAIJ_MPIAIJ(Mat C)
1114222ddf1SHong Zhang {
1126718818eSStefano Zampini   Mat_RARt       *rart;
1136718818eSStefano Zampini   Mat            A,R,Rt;
1144222ddf1SHong Zhang 
1154222ddf1SHong Zhang   PetscFunctionBegin;
1166718818eSStefano Zampini   MatCheckProduct(C,1);
117*28b400f6SJacob Faibussowitsch   PetscCheck(C->product->data,PetscObjectComm((PetscObject)C),PETSC_ERR_PLIB,"Product data empty");
1186718818eSStefano Zampini   rart = (Mat_RARt*)C->product->data;
1196718818eSStefano Zampini   A    = C->product->A;
1206718818eSStefano Zampini   R    = C->product->B;
1216718818eSStefano Zampini   Rt   = rart->Rt;
1225f80ce2aSJacob Faibussowitsch   CHKERRQ(MatTranspose(R,MAT_REUSE_MATRIX,&Rt));
1236718818eSStefano Zampini   if (rart->data) C->product->data = rart->data;
1245f80ce2aSJacob Faibussowitsch   CHKERRQ((*C->ops->matmatmultnumeric)(R,A,Rt,C));
1256718818eSStefano Zampini   C->product->data = rart;
1264222ddf1SHong Zhang   PetscFunctionReturn(0);
1274222ddf1SHong Zhang }
1284222ddf1SHong Zhang 
1294222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_RARt_MPIAIJ_MPIAIJ(Mat C)
1304222ddf1SHong Zhang {
1316718818eSStefano Zampini   Mat            A,R,Rt;
1324222ddf1SHong Zhang   Mat_RARt       *rart;
1338d45306eSHong Zhang 
1348d45306eSHong Zhang   PetscFunctionBegin;
1356718818eSStefano Zampini   MatCheckProduct(C,1);
136*28b400f6SJacob Faibussowitsch   PetscCheck(!C->product->data,PetscObjectComm((PetscObject)C),PETSC_ERR_PLIB,"Product data not empty");
1376718818eSStefano Zampini   A    = C->product->A;
1386718818eSStefano Zampini   R    = C->product->B;
1395f80ce2aSJacob Faibussowitsch   CHKERRQ(MatTranspose(R,MAT_INITIAL_MATRIX,&Rt));
1404222ddf1SHong Zhang   /* product->Dwork is used to store A*Rt in MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ() */
1415f80ce2aSJacob Faibussowitsch   CHKERRQ(MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ(R,A,Rt,C->product->fill,C));
1424222ddf1SHong Zhang   C->ops->productnumeric = MatProductNumeric_RARt_MPIAIJ_MPIAIJ;
1434222ddf1SHong Zhang 
1444222ddf1SHong Zhang   /* create a supporting struct */
1455f80ce2aSJacob Faibussowitsch   CHKERRQ(PetscNew(&rart));
1464222ddf1SHong Zhang   rart->Rt      = Rt;
1476718818eSStefano Zampini   rart->data    = C->product->data;
1486718818eSStefano Zampini   rart->destroy = C->product->destroy;
1496718818eSStefano Zampini   C->product->data    = rart;
1506718818eSStefano Zampini   C->product->destroy = MatDestroy_MPIAIJ_RARt;
1518d45306eSHong Zhang   PetscFunctionReturn(0);
1528d45306eSHong Zhang }
153