xref: /petsc/src/mat/impls/aij/mpi/mpimatmatmatmult.c (revision 8a9b871730310674d6b577d3422209ebfdc8ff84)
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)
83dad0653Sstefano_zampini 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 
113dad0653Sstefano_zampini PETSC_INTERN PetscErrorCode MatMatMatMult_Transpose_AIJ_AIJ(Mat R,Mat A,Mat P,MatReuse scall, PetscReal fill, Mat *RAP)
123dad0653Sstefano_zampini {
133dad0653Sstefano_zampini   Mat            Rt;
143dad0653Sstefano_zampini   PetscBool      flg;
153dad0653Sstefano_zampini   PetscErrorCode ierr;
163dad0653Sstefano_zampini 
173dad0653Sstefano_zampini   PetscFunctionBegin;
183dad0653Sstefano_zampini   ierr = MatTransposeGetMat(R,&Rt);CHKERRQ(ierr);
193dad0653Sstefano_zampini   ierr = PetscObjectTypeCompareAny((PetscObject)Rt,&flg,MATSEQAIJ,MATMPIAIJ,NULL);CHKERRQ(ierr);
2083976f8eSstefano_zampini   if (!flg) SETERRQ1(PetscObjectComm((PetscObject)Rt),PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)Rt)->type_name);
213dad0653Sstefano_zampini   if (scall == MAT_INITIAL_MATRIX) {
223dad0653Sstefano_zampini     ierr = PetscLogEventBegin(MAT_MatMatMultSymbolic,R,A,P,0);CHKERRQ(ierr);
233dad0653Sstefano_zampini     ierr = MatTransposeMatMatMultSymbolic_AIJ_AIJ_AIJ_wHYPRE(Rt,A,P,fill,RAP);CHKERRQ(ierr);
243dad0653Sstefano_zampini     ierr = PetscLogEventEnd(MAT_MatMatMultSymbolic,R,A,P,0);CHKERRQ(ierr);
253dad0653Sstefano_zampini   }
263dad0653Sstefano_zampini   ierr = PetscLogEventBegin(MAT_MatMatMultNumeric,R,A,P,0);CHKERRQ(ierr);
273dad0653Sstefano_zampini   ierr = MatTransposeMatMatMultNumeric_AIJ_AIJ_AIJ_wHYPRE(Rt,A,P,*RAP);CHKERRQ(ierr);
283dad0653Sstefano_zampini   ierr = PetscLogEventEnd(MAT_MatMatMultNumeric,R,A,P,0);CHKERRQ(ierr);
293dad0653Sstefano_zampini   PetscFunctionReturn(0);
303dad0653Sstefano_zampini }
313dad0653Sstefano_zampini #endif
323dad0653Sstefano_zampini 
33*8a9b8717SHong Zhang PetscErrorCode MatFreeIntermediateDataStructures_MPIAIJ_BC(Mat ABC)
34f996eeb8SHong Zhang {
35*8a9b8717SHong Zhang   Mat_MPIAIJ        *a = (Mat_MPIAIJ*)ABC->data;
36f996eeb8SHong Zhang   Mat_MatMatMatMult *matmatmatmult = a->matmatmatmult;
37f996eeb8SHong Zhang   PetscErrorCode    ierr;
38f996eeb8SHong Zhang 
39f996eeb8SHong Zhang   PetscFunctionBegin;
40*8a9b8717SHong Zhang   if (!matmatmatmult) PetscFunctionReturn(0);
41*8a9b8717SHong Zhang 
42f996eeb8SHong Zhang   ierr = MatDestroy(&matmatmatmult->BC);CHKERRQ(ierr);
43*8a9b8717SHong Zhang   ABC->ops->destroy = matmatmatmult->destroy;
44*8a9b8717SHong Zhang   ierr = PetscFree(a->matmatmatmult);CHKERRQ(ierr);
45*8a9b8717SHong Zhang   PetscFunctionReturn(0);
46*8a9b8717SHong Zhang }
47*8a9b8717SHong Zhang 
48*8a9b8717SHong Zhang PetscErrorCode MatDestroy_MPIAIJ_MatMatMatMult(Mat A)
49*8a9b8717SHong Zhang {
50*8a9b8717SHong Zhang   PetscErrorCode    ierr;
51*8a9b8717SHong Zhang 
52*8a9b8717SHong Zhang   PetscFunctionBegin;
53*8a9b8717SHong Zhang   ierr = (*A->ops->freeintermediatedatastructures)(A);CHKERRQ(ierr);
54*8a9b8717SHong Zhang   ierr = (*A->ops->destroy)(A);CHKERRQ(ierr);
55f996eeb8SHong Zhang   PetscFunctionReturn(0);
56f996eeb8SHong Zhang }
57f996eeb8SHong Zhang 
58150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatMatMatMult_MPIAIJ_MPIAIJ_MPIAIJ(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
59f996eeb8SHong Zhang {
60f996eeb8SHong Zhang   PetscErrorCode ierr;
61f996eeb8SHong Zhang 
62f996eeb8SHong Zhang   PetscFunctionBegin;
63f996eeb8SHong Zhang   if (scall == MAT_INITIAL_MATRIX) {
64f996eeb8SHong Zhang     ierr = PetscLogEventBegin(MAT_MatMatMultSymbolic,A,B,C,0);CHKERRQ(ierr);
65f996eeb8SHong Zhang     ierr = MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ(A,B,C,fill,D);CHKERRQ(ierr);
66f996eeb8SHong Zhang     ierr = PetscLogEventEnd(MAT_MatMatMultSymbolic,A,B,C,0);CHKERRQ(ierr);
67f996eeb8SHong Zhang   }
68f996eeb8SHong Zhang   ierr = PetscLogEventBegin(MAT_MatMatMultNumeric,A,B,C,0);CHKERRQ(ierr);
6920e1dc0dSstefano_zampini   ierr = ((*D)->ops->matmatmultnumeric)(A,B,C,*D);CHKERRQ(ierr);
70f996eeb8SHong Zhang   ierr = PetscLogEventEnd(MAT_MatMatMultNumeric,A,B,C,0);CHKERRQ(ierr);
71f996eeb8SHong Zhang   PetscFunctionReturn(0);
72f996eeb8SHong Zhang }
73f996eeb8SHong Zhang 
74f996eeb8SHong Zhang PetscErrorCode MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ(Mat A,Mat B,Mat C,PetscReal fill,Mat *D)
75f996eeb8SHong Zhang {
76f996eeb8SHong Zhang   PetscErrorCode    ierr;
77f996eeb8SHong Zhang   Mat               BC;
78f996eeb8SHong Zhang   Mat_MatMatMatMult *matmatmatmult;
79f996eeb8SHong Zhang   Mat_MPIAIJ        *d;
80*8a9b8717SHong Zhang   PetscBool         flg;
81*8a9b8717SHong Zhang   const char        *algTypes[2] = {"scalable","nonscalable"};
82*8a9b8717SHong Zhang   PetscInt          nalg=2,alg=0; /* set default algorithm */
83f996eeb8SHong Zhang 
84f996eeb8SHong Zhang   PetscFunctionBegin;
85f996eeb8SHong Zhang   ierr = PetscObjectOptionsBegin((PetscObject)B);CHKERRQ(ierr);
86*8a9b8717SHong Zhang   PetscOptionsObject->alreadyprinted = PETSC_FALSE; /* a hack to ensure the option shows in '-help' */
87*8a9b8717SHong Zhang   ierr = PetscOptionsEList("-matmatmatmult_via","Algorithmic approach","MatMatMatMult",algTypes,nalg,algTypes[alg],&alg,&flg);CHKERRQ(ierr);
88f996eeb8SHong Zhang   ierr = PetscOptionsEnd();CHKERRQ(ierr);
89*8a9b8717SHong Zhang 
90*8a9b8717SHong Zhang   switch (alg) {
91*8a9b8717SHong Zhang   case 0: /* scalable */
92b2405163SHong Zhang     ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ(B,C,fill,&BC);CHKERRQ(ierr);
93b2405163SHong Zhang     ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ(A,BC,fill,D);CHKERRQ(ierr);
94*8a9b8717SHong Zhang     break;
95*8a9b8717SHong Zhang   case 1:
960fc8cf34SHong Zhang     ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ_nonscalable(B,C,fill,&BC);CHKERRQ(ierr);
970fc8cf34SHong Zhang     ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ_nonscalable(A,BC,fill,D);CHKERRQ(ierr);
98*8a9b8717SHong Zhang     break;
99*8a9b8717SHong Zhang   default:
100*8a9b8717SHong Zhang     SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"Not supported");
101f996eeb8SHong Zhang   }
102f996eeb8SHong Zhang 
103f996eeb8SHong Zhang   /* create struct Mat_MatMatMatMult and attached it to *D */
104b00a9115SJed Brown   ierr = PetscNew(&matmatmatmult);CHKERRQ(ierr);
1052205254eSKarl Rupp 
106f996eeb8SHong Zhang   matmatmatmult->BC      = BC;
107f996eeb8SHong Zhang   matmatmatmult->destroy = (*D)->ops->destroy;
108f996eeb8SHong Zhang   d                      = (Mat_MPIAIJ*)(*D)->data;
109f996eeb8SHong Zhang   d->matmatmatmult       = matmatmatmult;
110f996eeb8SHong Zhang 
111f996eeb8SHong Zhang   (*D)->ops->matmatmultnumeric = MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ;
112f996eeb8SHong Zhang   (*D)->ops->destroy           = MatDestroy_MPIAIJ_MatMatMatMult;
113*8a9b8717SHong Zhang   (*D)->ops->freeintermediatedatastructures = MatFreeIntermediateDataStructures_MPIAIJ_BC;
114f996eeb8SHong Zhang   PetscFunctionReturn(0);
115f996eeb8SHong Zhang }
116f996eeb8SHong Zhang 
117f996eeb8SHong Zhang PetscErrorCode MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ(Mat A,Mat B,Mat C,Mat D)
118f996eeb8SHong Zhang {
119f996eeb8SHong Zhang   PetscErrorCode    ierr;
120f996eeb8SHong Zhang   Mat_MPIAIJ        *d             = (Mat_MPIAIJ*)D->data;
121f996eeb8SHong Zhang   Mat_MatMatMatMult *matmatmatmult = d->matmatmatmult;
122f996eeb8SHong Zhang   Mat               BC             = matmatmatmult->BC;
123f996eeb8SHong Zhang 
124f996eeb8SHong Zhang   PetscFunctionBegin;
125f996eeb8SHong Zhang   ierr = (BC->ops->matmultnumeric)(B,C,BC);CHKERRQ(ierr);
126f996eeb8SHong Zhang   ierr = (D->ops->matmultnumeric)(A,BC,D);CHKERRQ(ierr);
127f996eeb8SHong Zhang   PetscFunctionReturn(0);
128f996eeb8SHong Zhang }
1298d45306eSHong Zhang 
1308d45306eSHong Zhang PetscErrorCode MatRARt_MPIAIJ_MPIAIJ(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
1318d45306eSHong Zhang {
1328d45306eSHong Zhang   PetscErrorCode ierr;
1338d45306eSHong Zhang   Mat            Rt;
1348d45306eSHong Zhang 
1358d45306eSHong Zhang   PetscFunctionBegin;
1368d45306eSHong Zhang   ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr);
1378d45306eSHong Zhang   if (scall == MAT_INITIAL_MATRIX) {
1388d45306eSHong Zhang     ierr = MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ(R,A,Rt,fill,C);CHKERRQ(ierr);
1398d45306eSHong Zhang   }
1408d45306eSHong Zhang   ierr = MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ(R,A,Rt,*C);CHKERRQ(ierr);
1418d45306eSHong Zhang   ierr = MatDestroy(&Rt);CHKERRQ(ierr);
1428d45306eSHong Zhang   PetscFunctionReturn(0);
1438d45306eSHong Zhang }
144