xref: /petsc/src/mat/impls/aij/mpi/mpimatmatmatmult.c (revision b7e612beb08fd2c90fb14a40c5ac3a1dae7b02ad)
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 
338a9b8717SHong Zhang PetscErrorCode MatFreeIntermediateDataStructures_MPIAIJ_BC(Mat ABC)
34f996eeb8SHong Zhang {
358a9b8717SHong Zhang   Mat_MPIAIJ        *a = (Mat_MPIAIJ*)ABC->data;
36f996eeb8SHong Zhang   Mat_MatMatMatMult *matmatmatmult = a->matmatmatmult;
37f996eeb8SHong Zhang   PetscErrorCode    ierr;
38f996eeb8SHong Zhang 
39f996eeb8SHong Zhang   PetscFunctionBegin;
408a9b8717SHong Zhang   if (!matmatmatmult) PetscFunctionReturn(0);
418a9b8717SHong Zhang 
42f996eeb8SHong Zhang   ierr = MatDestroy(&matmatmatmult->BC);CHKERRQ(ierr);
438a9b8717SHong Zhang   ABC->ops->destroy = matmatmatmult->destroy;
448a9b8717SHong Zhang   ierr = PetscFree(a->matmatmatmult);CHKERRQ(ierr);
458a9b8717SHong Zhang   PetscFunctionReturn(0);
468a9b8717SHong Zhang }
478a9b8717SHong Zhang 
488a9b8717SHong Zhang PetscErrorCode MatDestroy_MPIAIJ_MatMatMatMult(Mat A)
498a9b8717SHong Zhang {
508a9b8717SHong Zhang   PetscErrorCode    ierr;
518a9b8717SHong Zhang 
528a9b8717SHong Zhang   PetscFunctionBegin;
538a9b8717SHong Zhang   ierr = (*A->ops->freeintermediatedatastructures)(A);CHKERRQ(ierr);
548a9b8717SHong 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;
808a9b8717SHong Zhang   PetscBool         flg;
818a9b8717SHong Zhang   const char        *algTypes[2] = {"scalable","nonscalable"};
828a9b8717SHong Zhang   PetscInt          nalg=2,alg=0; /* set default algorithm */
83f996eeb8SHong Zhang 
84f996eeb8SHong Zhang   PetscFunctionBegin;
85715a5346SHong Zhang   ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)B),((PetscObject)B)->prefix,"MatMatMatMult","Mat");CHKERRQ(ierr);
868a9b8717SHong Zhang   ierr = PetscOptionsEList("-matmatmatmult_via","Algorithmic approach","MatMatMatMult",algTypes,nalg,algTypes[alg],&alg,&flg);CHKERRQ(ierr);
87f996eeb8SHong Zhang   ierr = PetscOptionsEnd();CHKERRQ(ierr);
888a9b8717SHong Zhang 
898a9b8717SHong Zhang   switch (alg) {
908a9b8717SHong Zhang   case 0: /* scalable */
91b2405163SHong Zhang     ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ(B,C,fill,&BC);CHKERRQ(ierr);
92*b7e612beSHong Zhang     ierr = MatZeroEntries(BC);CHKERRQ(ierr); /* initialize value entries of BC */
93b2405163SHong Zhang     ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ(A,BC,fill,D);CHKERRQ(ierr);
948a9b8717SHong Zhang     break;
958a9b8717SHong Zhang   case 1:
960fc8cf34SHong Zhang     ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ_nonscalable(B,C,fill,&BC);CHKERRQ(ierr);
97*b7e612beSHong Zhang     ierr = MatZeroEntries(BC);CHKERRQ(ierr); /* initialize value entries of BC */
980fc8cf34SHong Zhang     ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ_nonscalable(A,BC,fill,D);CHKERRQ(ierr);
998a9b8717SHong Zhang     break;
1008a9b8717SHong Zhang   default:
1018a9b8717SHong Zhang     SETERRQ(PetscObjectComm((PetscObject)B),PETSC_ERR_SUP,"Not supported");
102f996eeb8SHong Zhang   }
103f996eeb8SHong Zhang 
104f996eeb8SHong Zhang   /* create struct Mat_MatMatMatMult and attached it to *D */
105b00a9115SJed Brown   ierr = PetscNew(&matmatmatmult);CHKERRQ(ierr);
1062205254eSKarl Rupp 
107f996eeb8SHong Zhang   matmatmatmult->BC      = BC;
108f996eeb8SHong Zhang   matmatmatmult->destroy = (*D)->ops->destroy;
109f996eeb8SHong Zhang   d                      = (Mat_MPIAIJ*)(*D)->data;
110f996eeb8SHong Zhang   d->matmatmatmult       = matmatmatmult;
111f996eeb8SHong Zhang 
112f996eeb8SHong Zhang   (*D)->ops->matmatmultnumeric = MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ;
113f996eeb8SHong Zhang   (*D)->ops->destroy           = MatDestroy_MPIAIJ_MatMatMatMult;
1148a9b8717SHong Zhang   (*D)->ops->freeintermediatedatastructures = MatFreeIntermediateDataStructures_MPIAIJ_BC;
115f996eeb8SHong Zhang   PetscFunctionReturn(0);
116f996eeb8SHong Zhang }
117f996eeb8SHong Zhang 
118f996eeb8SHong Zhang PetscErrorCode MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ(Mat A,Mat B,Mat C,Mat D)
119f996eeb8SHong Zhang {
120f996eeb8SHong Zhang   PetscErrorCode    ierr;
121f996eeb8SHong Zhang   Mat_MPIAIJ        *d             = (Mat_MPIAIJ*)D->data;
122f996eeb8SHong Zhang   Mat_MatMatMatMult *matmatmatmult = d->matmatmatmult;
123f996eeb8SHong Zhang   Mat               BC             = matmatmatmult->BC;
124f996eeb8SHong Zhang 
125f996eeb8SHong Zhang   PetscFunctionBegin;
126f996eeb8SHong Zhang   ierr = (BC->ops->matmultnumeric)(B,C,BC);CHKERRQ(ierr);
127f996eeb8SHong Zhang   ierr = (D->ops->matmultnumeric)(A,BC,D);CHKERRQ(ierr);
128f996eeb8SHong Zhang   PetscFunctionReturn(0);
129f996eeb8SHong Zhang }
1308d45306eSHong Zhang 
1318d45306eSHong Zhang PetscErrorCode MatRARt_MPIAIJ_MPIAIJ(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C)
1328d45306eSHong Zhang {
1338d45306eSHong Zhang   PetscErrorCode ierr;
1348d45306eSHong Zhang   Mat            Rt;
1358d45306eSHong Zhang 
1368d45306eSHong Zhang   PetscFunctionBegin;
1378d45306eSHong Zhang   ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr);
1388d45306eSHong Zhang   if (scall == MAT_INITIAL_MATRIX) {
1398d45306eSHong Zhang     ierr = MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ(R,A,Rt,fill,C);CHKERRQ(ierr);
1408d45306eSHong Zhang   }
1418d45306eSHong Zhang   ierr = MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ(R,A,Rt,*C);CHKERRQ(ierr);
1428d45306eSHong Zhang   ierr = MatDestroy(&Rt);CHKERRQ(ierr);
1438d45306eSHong Zhang   PetscFunctionReturn(0);
1448d45306eSHong Zhang }
145