xref: /petsc/src/mat/impls/aij/mpi/mpimatmatmatmult.c (revision 98921bda46e76d7aaed9e0138c5ff9d0ce93f355)
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);
34*98921bdaSJacob Faibussowitsch   if (!flg) SETERRQ(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*98921bdaSJacob Faibussowitsch   } else SETERRQ(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 
524222ddf1SHong Zhang PetscErrorCode MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ(Mat A,Mat B,Mat C,PetscReal fill,Mat D)
53f996eeb8SHong Zhang {
54f996eeb8SHong Zhang   PetscErrorCode ierr;
55f996eeb8SHong Zhang   Mat            BC;
564222ddf1SHong Zhang   PetscBool      scalable;
576718818eSStefano Zampini   Mat_Product    *product;
58f996eeb8SHong Zhang 
59f996eeb8SHong Zhang   PetscFunctionBegin;
606718818eSStefano Zampini   MatCheckProduct(D,4);
616718818eSStefano Zampini   if (D->product->data) SETERRQ(PetscObjectComm((PetscObject)D),PETSC_ERR_PLIB,"Product data not empty");
626718818eSStefano Zampini   product = D->product;
636718818eSStefano Zampini   ierr = MatProductCreate(B,C,NULL,&BC);CHKERRQ(ierr);
646718818eSStefano Zampini   ierr = MatProductSetType(BC,MATPRODUCT_AB);CHKERRQ(ierr);
654222ddf1SHong Zhang   ierr = PetscStrcmp(product->alg,"scalable",&scalable);CHKERRQ(ierr);
664222ddf1SHong Zhang   if (scalable) {
674222ddf1SHong Zhang     ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ(B,C,fill,BC);CHKERRQ(ierr);
68b7e612beSHong Zhang     ierr = MatZeroEntries(BC);CHKERRQ(ierr); /* initialize value entries of BC */
69b2405163SHong Zhang     ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ(A,BC,fill,D);CHKERRQ(ierr);
704222ddf1SHong Zhang   } else {
714222ddf1SHong Zhang     ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ_nonscalable(B,C,fill,BC);CHKERRQ(ierr);
72b7e612beSHong Zhang     ierr = MatZeroEntries(BC);CHKERRQ(ierr); /* initialize value entries of BC */
730fc8cf34SHong Zhang     ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ_nonscalable(A,BC,fill,D);CHKERRQ(ierr);
74f996eeb8SHong Zhang   }
756718818eSStefano Zampini   ierr = MatDestroy(&product->Dwork);CHKERRQ(ierr);
764222ddf1SHong Zhang   product->Dwork = BC;
77f996eeb8SHong Zhang 
784222ddf1SHong Zhang   D->ops->matmatmultnumeric = MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ;
79f996eeb8SHong Zhang   PetscFunctionReturn(0);
80f996eeb8SHong Zhang }
81f996eeb8SHong Zhang 
82f996eeb8SHong Zhang PetscErrorCode MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ(Mat A,Mat B,Mat C,Mat D)
83f996eeb8SHong Zhang {
84f996eeb8SHong Zhang   PetscErrorCode ierr;
856718818eSStefano Zampini   Mat_Product    *product;
866718818eSStefano Zampini   Mat            BC;
87f996eeb8SHong Zhang 
88f996eeb8SHong Zhang   PetscFunctionBegin;
896718818eSStefano Zampini   MatCheckProduct(D,4);
906718818eSStefano Zampini   if (!D->product->data) SETERRQ(PetscObjectComm((PetscObject)D),PETSC_ERR_PLIB,"Product data empty");
916718818eSStefano Zampini   product = D->product;
926718818eSStefano Zampini   BC = product->Dwork;
936718818eSStefano Zampini   if (!BC->ops->matmultnumeric) SETERRQ(PetscObjectComm((PetscObject)D),PETSC_ERR_PLIB,"Missing numeric operation");
946718818eSStefano Zampini   ierr = (*BC->ops->matmultnumeric)(B,C,BC);CHKERRQ(ierr);
956718818eSStefano Zampini   if (!D->ops->matmultnumeric) SETERRQ(PetscObjectComm((PetscObject)D),PETSC_ERR_PLIB,"Missing numeric operation");
966718818eSStefano Zampini   ierr = (*D->ops->matmultnumeric)(A,BC,D);CHKERRQ(ierr);
97f996eeb8SHong Zhang   PetscFunctionReturn(0);
98f996eeb8SHong Zhang }
998d45306eSHong Zhang 
1004222ddf1SHong Zhang /* ----------------------------------------------------- */
1016718818eSStefano Zampini PetscErrorCode MatDestroy_MPIAIJ_RARt(void *data)
1028d45306eSHong Zhang {
1038d45306eSHong Zhang   PetscErrorCode ierr;
1046718818eSStefano Zampini   Mat_RARt       *rart = (Mat_RARt*)data;
1054222ddf1SHong Zhang 
1064222ddf1SHong Zhang   PetscFunctionBegin;
1074222ddf1SHong Zhang   ierr = MatDestroy(&rart->Rt);CHKERRQ(ierr);
1086718818eSStefano Zampini   if (rart->destroy) {
1096718818eSStefano Zampini     ierr = (*rart->destroy)(rart->data);CHKERRQ(ierr);
1104222ddf1SHong Zhang   }
1114222ddf1SHong Zhang   ierr = PetscFree(rart);CHKERRQ(ierr);
1124222ddf1SHong Zhang   PetscFunctionReturn(0);
1134222ddf1SHong Zhang }
1144222ddf1SHong Zhang 
1154222ddf1SHong Zhang PetscErrorCode MatProductNumeric_RARt_MPIAIJ_MPIAIJ(Mat C)
1164222ddf1SHong Zhang {
1174222ddf1SHong Zhang   PetscErrorCode ierr;
1186718818eSStefano Zampini   Mat_RARt       *rart;
1196718818eSStefano Zampini   Mat            A,R,Rt;
1204222ddf1SHong Zhang 
1214222ddf1SHong Zhang   PetscFunctionBegin;
1226718818eSStefano Zampini   MatCheckProduct(C,1);
1236718818eSStefano Zampini   if (!C->product->data) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_PLIB,"Product data empty");
1246718818eSStefano Zampini   rart = (Mat_RARt*)C->product->data;
1256718818eSStefano Zampini   A    = C->product->A;
1266718818eSStefano Zampini   R    = C->product->B;
1276718818eSStefano Zampini   Rt   = rart->Rt;
1284222ddf1SHong Zhang   ierr = MatTranspose(R,MAT_REUSE_MATRIX,&Rt);CHKERRQ(ierr);
1296718818eSStefano Zampini   if (rart->data) C->product->data = rart->data;
1306718818eSStefano Zampini   ierr = (*C->ops->matmatmultnumeric)(R,A,Rt,C);CHKERRQ(ierr);
1316718818eSStefano Zampini   C->product->data = rart;
1324222ddf1SHong Zhang   PetscFunctionReturn(0);
1334222ddf1SHong Zhang }
1344222ddf1SHong Zhang 
1354222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_RARt_MPIAIJ_MPIAIJ(Mat C)
1364222ddf1SHong Zhang {
1374222ddf1SHong Zhang   PetscErrorCode ierr;
1386718818eSStefano Zampini   Mat            A,R,Rt;
1394222ddf1SHong Zhang   Mat_RARt       *rart;
1408d45306eSHong Zhang 
1418d45306eSHong Zhang   PetscFunctionBegin;
1426718818eSStefano Zampini   MatCheckProduct(C,1);
1436718818eSStefano Zampini   if (C->product->data) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_PLIB,"Product data not empty");
1446718818eSStefano Zampini   A    = C->product->A;
1456718818eSStefano Zampini   R    = C->product->B;
1468d45306eSHong Zhang   ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr);
1474222ddf1SHong Zhang   /* product->Dwork is used to store A*Rt in MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ() */
1486718818eSStefano Zampini   ierr = MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ(R,A,Rt,C->product->fill,C);CHKERRQ(ierr);
1494222ddf1SHong Zhang   C->ops->productnumeric = MatProductNumeric_RARt_MPIAIJ_MPIAIJ;
1504222ddf1SHong Zhang 
1514222ddf1SHong Zhang   /* create a supporting struct */
1524222ddf1SHong Zhang   ierr = PetscNew(&rart);CHKERRQ(ierr);
1534222ddf1SHong Zhang   rart->Rt      = Rt;
1546718818eSStefano Zampini   rart->data    = C->product->data;
1556718818eSStefano Zampini   rart->destroy = C->product->destroy;
1566718818eSStefano Zampini   C->product->data    = rart;
1576718818eSStefano Zampini   C->product->destroy = MatDestroy_MPIAIJ_RARt;
1588d45306eSHong Zhang   PetscFunctionReturn(0);
1598d45306eSHong Zhang }
160