xref: /petsc/src/mat/impls/aij/mpi/mpimatmatmatmult.c (revision 1baa6e3354bfe224b33a0c158f482508792a8a6e)
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;
179566063dSJacob Faibussowitsch   PetscCall(MatTransposeGetMat(R,&Rt));
189566063dSJacob Faibussowitsch   PetscCall(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 */
309566063dSJacob Faibussowitsch   PetscCall(MatTransposeGetMat(R,&Rt));
319566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)Rt,&flg,MATSEQAIJ,MATSEQAIJMKL,MATMPIAIJ,NULL));
3228b400f6SJacob Faibussowitsch   PetscCheck(flg,PetscObjectComm((PetscObject)Rt),PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)Rt)->type_name);
339566063dSJacob Faibussowitsch   PetscCall(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);
5828b400f6SJacob Faibussowitsch   PetscCheck(!D->product->data,PetscObjectComm((PetscObject)D),PETSC_ERR_PLIB,"Product data not empty");
596718818eSStefano Zampini   product = D->product;
609566063dSJacob Faibussowitsch   PetscCall(MatProductCreate(B,C,NULL,&BC));
619566063dSJacob Faibussowitsch   PetscCall(MatProductSetType(BC,MATPRODUCT_AB));
629566063dSJacob Faibussowitsch   PetscCall(PetscStrcmp(product->alg,"scalable",&scalable));
634222ddf1SHong Zhang   if (scalable) {
649566063dSJacob Faibussowitsch     PetscCall(MatMatMultSymbolic_MPIAIJ_MPIAIJ(B,C,fill,BC));
659566063dSJacob Faibussowitsch     PetscCall(MatZeroEntries(BC)); /* initialize value entries of BC */
669566063dSJacob Faibussowitsch     PetscCall(MatMatMultSymbolic_MPIAIJ_MPIAIJ(A,BC,fill,D));
674222ddf1SHong Zhang   } else {
689566063dSJacob Faibussowitsch     PetscCall(MatMatMultSymbolic_MPIAIJ_MPIAIJ_nonscalable(B,C,fill,BC));
699566063dSJacob Faibussowitsch     PetscCall(MatZeroEntries(BC)); /* initialize value entries of BC */
709566063dSJacob Faibussowitsch     PetscCall(MatMatMultSymbolic_MPIAIJ_MPIAIJ_nonscalable(A,BC,fill,D));
71f996eeb8SHong Zhang   }
729566063dSJacob Faibussowitsch   PetscCall(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);
8628b400f6SJacob Faibussowitsch   PetscCheck(D->product->data,PetscObjectComm((PetscObject)D),PETSC_ERR_PLIB,"Product data empty");
876718818eSStefano Zampini   product = D->product;
886718818eSStefano Zampini   BC = product->Dwork;
8928b400f6SJacob Faibussowitsch   PetscCheck(BC->ops->matmultnumeric,PetscObjectComm((PetscObject)D),PETSC_ERR_PLIB,"Missing numeric operation");
909566063dSJacob Faibussowitsch   PetscCall((*BC->ops->matmultnumeric)(B,C,BC));
9128b400f6SJacob Faibussowitsch   PetscCheck(D->ops->matmultnumeric,PetscObjectComm((PetscObject)D),PETSC_ERR_PLIB,"Missing numeric operation");
929566063dSJacob Faibussowitsch   PetscCall((*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;
1029566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&rart->Rt));
103*1baa6e33SBarry Smith   if (rart->destroy) PetscCall((*rart->destroy)(rart->data));
1049566063dSJacob Faibussowitsch   PetscCall(PetscFree(rart));
1054222ddf1SHong Zhang   PetscFunctionReturn(0);
1064222ddf1SHong Zhang }
1074222ddf1SHong Zhang 
1084222ddf1SHong Zhang PetscErrorCode MatProductNumeric_RARt_MPIAIJ_MPIAIJ(Mat C)
1094222ddf1SHong Zhang {
1106718818eSStefano Zampini   Mat_RARt       *rart;
1116718818eSStefano Zampini   Mat            A,R,Rt;
1124222ddf1SHong Zhang 
1134222ddf1SHong Zhang   PetscFunctionBegin;
1146718818eSStefano Zampini   MatCheckProduct(C,1);
11528b400f6SJacob Faibussowitsch   PetscCheck(C->product->data,PetscObjectComm((PetscObject)C),PETSC_ERR_PLIB,"Product data empty");
1166718818eSStefano Zampini   rart = (Mat_RARt*)C->product->data;
1176718818eSStefano Zampini   A    = C->product->A;
1186718818eSStefano Zampini   R    = C->product->B;
1196718818eSStefano Zampini   Rt   = rart->Rt;
1209566063dSJacob Faibussowitsch   PetscCall(MatTranspose(R,MAT_REUSE_MATRIX,&Rt));
1216718818eSStefano Zampini   if (rart->data) C->product->data = rart->data;
1229566063dSJacob Faibussowitsch   PetscCall((*C->ops->matmatmultnumeric)(R,A,Rt,C));
1236718818eSStefano Zampini   C->product->data = rart;
1244222ddf1SHong Zhang   PetscFunctionReturn(0);
1254222ddf1SHong Zhang }
1264222ddf1SHong Zhang 
1274222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_RARt_MPIAIJ_MPIAIJ(Mat C)
1284222ddf1SHong Zhang {
1296718818eSStefano Zampini   Mat            A,R,Rt;
1304222ddf1SHong Zhang   Mat_RARt       *rart;
1318d45306eSHong Zhang 
1328d45306eSHong Zhang   PetscFunctionBegin;
1336718818eSStefano Zampini   MatCheckProduct(C,1);
13428b400f6SJacob Faibussowitsch   PetscCheck(!C->product->data,PetscObjectComm((PetscObject)C),PETSC_ERR_PLIB,"Product data not empty");
1356718818eSStefano Zampini   A    = C->product->A;
1366718818eSStefano Zampini   R    = C->product->B;
1379566063dSJacob Faibussowitsch   PetscCall(MatTranspose(R,MAT_INITIAL_MATRIX,&Rt));
1384222ddf1SHong Zhang   /* product->Dwork is used to store A*Rt in MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ() */
1399566063dSJacob Faibussowitsch   PetscCall(MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ(R,A,Rt,C->product->fill,C));
1404222ddf1SHong Zhang   C->ops->productnumeric = MatProductNumeric_RARt_MPIAIJ_MPIAIJ;
1414222ddf1SHong Zhang 
1424222ddf1SHong Zhang   /* create a supporting struct */
1439566063dSJacob Faibussowitsch   PetscCall(PetscNew(&rart));
1444222ddf1SHong Zhang   rart->Rt      = Rt;
1456718818eSStefano Zampini   rart->data    = C->product->data;
1466718818eSStefano Zampini   rart->destroy = C->product->destroy;
1476718818eSStefano Zampini   C->product->data    = rart;
1486718818eSStefano Zampini   C->product->destroy = MatDestroy_MPIAIJ_RARt;
1498d45306eSHong Zhang   PetscFunctionReturn(0);
1508d45306eSHong Zhang }
151