xref: /petsc/src/mat/impls/aij/mpi/mpimatmatmatmult.c (revision 8f83a4d96e6432e9a06bd6cd8c5929cf0bb638f8)
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 
119371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatProductNumeric_ABC_Transpose_AIJ_AIJ(Mat RAP) {
124222ddf1SHong Zhang   Mat_Product *product = RAP->product;
134222ddf1SHong Zhang   Mat          Rt, R = product->A, A = product->B, P = product->C;
143dad0653Sstefano_zampini 
153dad0653Sstefano_zampini   PetscFunctionBegin;
169566063dSJacob Faibussowitsch   PetscCall(MatTransposeGetMat(R, &Rt));
179566063dSJacob Faibussowitsch   PetscCall(MatTransposeMatMatMultNumeric_AIJ_AIJ_AIJ_wHYPRE(Rt, A, P, RAP));
184222ddf1SHong Zhang   PetscFunctionReturn(0);
194222ddf1SHong Zhang }
204222ddf1SHong Zhang 
219371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatProductSymbolic_ABC_Transpose_AIJ_AIJ(Mat RAP) {
224222ddf1SHong Zhang   Mat_Product *product = RAP->product;
234222ddf1SHong Zhang   Mat          Rt, R = product->A, A = product->B, P = product->C;
244222ddf1SHong Zhang   PetscBool    flg;
254222ddf1SHong Zhang 
264222ddf1SHong Zhang   PetscFunctionBegin;
274222ddf1SHong Zhang   /* local sizes of matrices will be checked by the calling subroutines */
289566063dSJacob Faibussowitsch   PetscCall(MatTransposeGetMat(R, &Rt));
299566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompareAny((PetscObject)Rt, &flg, MATSEQAIJ, MATSEQAIJMKL, MATMPIAIJ, NULL));
3028b400f6SJacob Faibussowitsch   PetscCheck(flg, PetscObjectComm((PetscObject)Rt), PETSC_ERR_SUP, "Not for matrix type %s", ((PetscObject)Rt)->type_name);
319566063dSJacob Faibussowitsch   PetscCall(MatTransposeMatMatMultSymbolic_AIJ_AIJ_AIJ_wHYPRE(Rt, A, P, product->fill, RAP));
324222ddf1SHong Zhang   RAP->ops->productnumeric = MatProductNumeric_ABC_Transpose_AIJ_AIJ;
334222ddf1SHong Zhang   PetscFunctionReturn(0);
343dad0653Sstefano_zampini }
354222ddf1SHong Zhang 
369371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatProductSetFromOptions_Transpose_AIJ_AIJ(Mat C) {
374222ddf1SHong Zhang   Mat_Product *product = C->product;
384222ddf1SHong Zhang 
394222ddf1SHong Zhang   PetscFunctionBegin;
404222ddf1SHong Zhang   if (product->type == MATPRODUCT_ABC) {
414222ddf1SHong Zhang     C->ops->productsymbolic = MatProductSymbolic_ABC_Transpose_AIJ_AIJ;
4298921bdaSJacob Faibussowitsch   } else SETERRQ(PetscObjectComm((PetscObject)C), PETSC_ERR_SUP, "MatProduct type %s is not supported for Transpose, AIJ and AIJ matrices", MatProductTypes[product->type]);
433dad0653Sstefano_zampini   PetscFunctionReturn(0);
443dad0653Sstefano_zampini }
453dad0653Sstefano_zampini #endif
463dad0653Sstefano_zampini 
479371c9d4SSatish Balay PetscErrorCode MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ(Mat A, Mat B, Mat C, PetscReal fill, Mat D) {
48f996eeb8SHong Zhang   Mat          BC;
494222ddf1SHong Zhang   PetscBool    scalable;
506718818eSStefano Zampini   Mat_Product *product;
51f996eeb8SHong Zhang 
52f996eeb8SHong Zhang   PetscFunctionBegin;
53*8f83a4d9SJacob Faibussowitsch   MatCheckProduct(D, 5);
5428b400f6SJacob Faibussowitsch   PetscCheck(!D->product->data, PetscObjectComm((PetscObject)D), PETSC_ERR_PLIB, "Product data not empty");
556718818eSStefano Zampini   product = D->product;
569566063dSJacob Faibussowitsch   PetscCall(MatProductCreate(B, C, NULL, &BC));
579566063dSJacob Faibussowitsch   PetscCall(MatProductSetType(BC, MATPRODUCT_AB));
589566063dSJacob Faibussowitsch   PetscCall(PetscStrcmp(product->alg, "scalable", &scalable));
594222ddf1SHong Zhang   if (scalable) {
609566063dSJacob Faibussowitsch     PetscCall(MatMatMultSymbolic_MPIAIJ_MPIAIJ(B, C, fill, BC));
619566063dSJacob Faibussowitsch     PetscCall(MatZeroEntries(BC)); /* initialize value entries of BC */
629566063dSJacob Faibussowitsch     PetscCall(MatMatMultSymbolic_MPIAIJ_MPIAIJ(A, BC, fill, D));
634222ddf1SHong Zhang   } else {
649566063dSJacob Faibussowitsch     PetscCall(MatMatMultSymbolic_MPIAIJ_MPIAIJ_nonscalable(B, C, fill, BC));
659566063dSJacob Faibussowitsch     PetscCall(MatZeroEntries(BC)); /* initialize value entries of BC */
669566063dSJacob Faibussowitsch     PetscCall(MatMatMultSymbolic_MPIAIJ_MPIAIJ_nonscalable(A, BC, fill, D));
67f996eeb8SHong Zhang   }
689566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&product->Dwork));
694222ddf1SHong Zhang   product->Dwork = BC;
70f996eeb8SHong Zhang 
714222ddf1SHong Zhang   D->ops->matmatmultnumeric = MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ;
72f996eeb8SHong Zhang   PetscFunctionReturn(0);
73f996eeb8SHong Zhang }
74f996eeb8SHong Zhang 
759371c9d4SSatish Balay PetscErrorCode MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ(Mat A, Mat B, Mat C, Mat D) {
766718818eSStefano Zampini   Mat_Product *product;
776718818eSStefano Zampini   Mat          BC;
78f996eeb8SHong Zhang 
79f996eeb8SHong Zhang   PetscFunctionBegin;
806718818eSStefano Zampini   MatCheckProduct(D, 4);
8128b400f6SJacob Faibussowitsch   PetscCheck(D->product->data, PetscObjectComm((PetscObject)D), PETSC_ERR_PLIB, "Product data empty");
826718818eSStefano Zampini   product = D->product;
836718818eSStefano Zampini   BC      = product->Dwork;
849566063dSJacob Faibussowitsch   PetscCall((*BC->ops->matmultnumeric)(B, C, BC));
859566063dSJacob Faibussowitsch   PetscCall((*D->ops->matmultnumeric)(A, BC, D));
86f996eeb8SHong Zhang   PetscFunctionReturn(0);
87f996eeb8SHong Zhang }
888d45306eSHong Zhang 
894222ddf1SHong Zhang /* ----------------------------------------------------- */
909371c9d4SSatish Balay PetscErrorCode MatDestroy_MPIAIJ_RARt(void *data) {
916718818eSStefano Zampini   Mat_RARt *rart = (Mat_RARt *)data;
924222ddf1SHong Zhang 
934222ddf1SHong Zhang   PetscFunctionBegin;
949566063dSJacob Faibussowitsch   PetscCall(MatDestroy(&rart->Rt));
951baa6e33SBarry Smith   if (rart->destroy) PetscCall((*rart->destroy)(rart->data));
969566063dSJacob Faibussowitsch   PetscCall(PetscFree(rart));
974222ddf1SHong Zhang   PetscFunctionReturn(0);
984222ddf1SHong Zhang }
994222ddf1SHong Zhang 
1009371c9d4SSatish Balay PetscErrorCode MatProductNumeric_RARt_MPIAIJ_MPIAIJ(Mat C) {
1016718818eSStefano Zampini   Mat_RARt *rart;
1026718818eSStefano Zampini   Mat       A, R, Rt;
1034222ddf1SHong Zhang 
1044222ddf1SHong Zhang   PetscFunctionBegin;
1056718818eSStefano Zampini   MatCheckProduct(C, 1);
10628b400f6SJacob Faibussowitsch   PetscCheck(C->product->data, PetscObjectComm((PetscObject)C), PETSC_ERR_PLIB, "Product data empty");
1076718818eSStefano Zampini   rart = (Mat_RARt *)C->product->data;
1086718818eSStefano Zampini   A    = C->product->A;
1096718818eSStefano Zampini   R    = C->product->B;
1106718818eSStefano Zampini   Rt   = rart->Rt;
1119566063dSJacob Faibussowitsch   PetscCall(MatTranspose(R, MAT_REUSE_MATRIX, &Rt));
1126718818eSStefano Zampini   if (rart->data) C->product->data = rart->data;
1139566063dSJacob Faibussowitsch   PetscCall((*C->ops->matmatmultnumeric)(R, A, Rt, C));
1146718818eSStefano Zampini   C->product->data = rart;
1154222ddf1SHong Zhang   PetscFunctionReturn(0);
1164222ddf1SHong Zhang }
1174222ddf1SHong Zhang 
1189371c9d4SSatish Balay PetscErrorCode MatProductSymbolic_RARt_MPIAIJ_MPIAIJ(Mat C) {
1196718818eSStefano Zampini   Mat       A, R, Rt;
1204222ddf1SHong Zhang   Mat_RARt *rart;
1218d45306eSHong Zhang 
1228d45306eSHong Zhang   PetscFunctionBegin;
1236718818eSStefano Zampini   MatCheckProduct(C, 1);
12428b400f6SJacob Faibussowitsch   PetscCheck(!C->product->data, PetscObjectComm((PetscObject)C), PETSC_ERR_PLIB, "Product data not empty");
1256718818eSStefano Zampini   A = C->product->A;
1266718818eSStefano Zampini   R = C->product->B;
1279566063dSJacob Faibussowitsch   PetscCall(MatTranspose(R, MAT_INITIAL_MATRIX, &Rt));
1284222ddf1SHong Zhang   /* product->Dwork is used to store A*Rt in MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ() */
1299566063dSJacob Faibussowitsch   PetscCall(MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ(R, A, Rt, C->product->fill, C));
1304222ddf1SHong Zhang   C->ops->productnumeric = MatProductNumeric_RARt_MPIAIJ_MPIAIJ;
1314222ddf1SHong Zhang 
1324222ddf1SHong Zhang   /* create a supporting struct */
1339566063dSJacob Faibussowitsch   PetscCall(PetscNew(&rart));
1344222ddf1SHong Zhang   rart->Rt            = Rt;
1356718818eSStefano Zampini   rart->data          = C->product->data;
1366718818eSStefano Zampini   rart->destroy       = C->product->destroy;
1376718818eSStefano Zampini   C->product->data    = rart;
1386718818eSStefano Zampini   C->product->destroy = MatDestroy_MPIAIJ_RARt;
1398d45306eSHong Zhang   PetscFunctionReturn(0);
1408d45306eSHong Zhang }
141