xref: /petsc/src/mat/impls/aij/mpi/mpimatmatmatmult.c (revision 4222ddf1d74c63827c599361b3bb0b06ad3944a0)
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)
8*4222ddf1SHong 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 
11*4222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductNumeric_ABC_Transpose_AIJ_AIJ(Mat RAP)
123dad0653Sstefano_zampini {
133dad0653Sstefano_zampini   PetscErrorCode ierr;
14*4222ddf1SHong Zhang   Mat_Product    *product = RAP->product;
15*4222ddf1SHong 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);
19*4222ddf1SHong Zhang   ierr = MatTransposeMatMatMultNumeric_AIJ_AIJ_AIJ_wHYPRE(Rt,A,P,RAP);CHKERRQ(ierr);
20*4222ddf1SHong Zhang   PetscFunctionReturn(0);
21*4222ddf1SHong Zhang }
22*4222ddf1SHong Zhang 
23*4222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSymbolic_ABC_Transpose_AIJ_AIJ(Mat RAP)
24*4222ddf1SHong Zhang {
25*4222ddf1SHong Zhang   PetscErrorCode ierr;
26*4222ddf1SHong Zhang   Mat_Product    *product = RAP->product;
27*4222ddf1SHong Zhang   Mat            Rt,R=product->A,A=product->B,P=product->C;
28*4222ddf1SHong Zhang   PetscBool      flg;
29*4222ddf1SHong Zhang 
30*4222ddf1SHong Zhang   PetscFunctionBegin;
31*4222ddf1SHong Zhang   /* local sizes of matrices will be checked by the calling subroutines */
32*4222ddf1SHong Zhang   ierr = MatTransposeGetMat(R,&Rt);CHKERRQ(ierr);
33d248a85cSRichard Tran Mills   ierr = PetscObjectTypeCompareAny((PetscObject)Rt,&flg,MATSEQAIJ,MATSEQAIJMKL,MATMPIAIJ,NULL);CHKERRQ(ierr);
3483976f8eSstefano_zampini   if (!flg) SETERRQ1(PetscObjectComm((PetscObject)Rt),PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)Rt)->type_name);
35*4222ddf1SHong Zhang   ierr = MatTransposeMatMatMultSymbolic_AIJ_AIJ_AIJ_wHYPRE(Rt,A,P,product->fill,RAP);CHKERRQ(ierr);
36*4222ddf1SHong Zhang   RAP->ops->productnumeric = MatProductNumeric_ABC_Transpose_AIJ_AIJ;
37*4222ddf1SHong Zhang   PetscFunctionReturn(0);
383dad0653Sstefano_zampini }
39*4222ddf1SHong Zhang 
40*4222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_Transpose_AIJ_AIJ(Mat C)
41*4222ddf1SHong Zhang {
42*4222ddf1SHong Zhang   Mat_Product *product = C->product;
43*4222ddf1SHong Zhang 
44*4222ddf1SHong Zhang   PetscFunctionBegin;
45*4222ddf1SHong Zhang   if (product->type == MATPRODUCT_ABC) {
46*4222ddf1SHong Zhang     C->ops->productsymbolic = MatProductSymbolic_ABC_Transpose_AIJ_AIJ;
47*4222ddf1SHong Zhang   } else SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_SUP,"MatProduct type is not supported");
483dad0653Sstefano_zampini   PetscFunctionReturn(0);
493dad0653Sstefano_zampini }
503dad0653Sstefano_zampini #endif
513dad0653Sstefano_zampini 
528a9b8717SHong Zhang PetscErrorCode MatFreeIntermediateDataStructures_MPIAIJ_BC(Mat ABC)
53f996eeb8SHong Zhang {
548a9b8717SHong Zhang   Mat_MPIAIJ        *a = (Mat_MPIAIJ*)ABC->data;
55f996eeb8SHong Zhang   Mat_MatMatMatMult *matmatmatmult = a->matmatmatmult;
56f996eeb8SHong Zhang   PetscErrorCode    ierr;
57f996eeb8SHong Zhang 
58f996eeb8SHong Zhang   PetscFunctionBegin;
598a9b8717SHong Zhang   if (!matmatmatmult) PetscFunctionReturn(0);
608a9b8717SHong Zhang 
61f996eeb8SHong Zhang   ierr = MatDestroy(&matmatmatmult->BC);CHKERRQ(ierr);
628a9b8717SHong Zhang   ABC->ops->destroy = matmatmatmult->destroy;
638a9b8717SHong Zhang   ierr = PetscFree(a->matmatmatmult);CHKERRQ(ierr);
648a9b8717SHong Zhang   PetscFunctionReturn(0);
658a9b8717SHong Zhang }
668a9b8717SHong Zhang 
678a9b8717SHong Zhang PetscErrorCode MatDestroy_MPIAIJ_MatMatMatMult(Mat A)
688a9b8717SHong Zhang {
698a9b8717SHong Zhang   PetscErrorCode    ierr;
708a9b8717SHong Zhang 
718a9b8717SHong Zhang   PetscFunctionBegin;
728a9b8717SHong Zhang   ierr = (*A->ops->freeintermediatedatastructures)(A);CHKERRQ(ierr);
738a9b8717SHong Zhang   ierr = (*A->ops->destroy)(A);CHKERRQ(ierr);
74f996eeb8SHong Zhang   PetscFunctionReturn(0);
75f996eeb8SHong Zhang }
76f996eeb8SHong Zhang 
77*4222ddf1SHong Zhang PetscErrorCode MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ(Mat A,Mat B,Mat C,PetscReal fill,Mat D)
78f996eeb8SHong Zhang {
79f996eeb8SHong Zhang   PetscErrorCode ierr;
80f996eeb8SHong Zhang   Mat            BC;
81*4222ddf1SHong Zhang   PetscBool      scalable;
82*4222ddf1SHong Zhang   Mat_Product    *product = D->product;
83f996eeb8SHong Zhang 
84f996eeb8SHong Zhang   PetscFunctionBegin;
85*4222ddf1SHong Zhang   ierr = MatCreate(PetscObjectComm((PetscObject)A),&BC);CHKERRQ(ierr);
86*4222ddf1SHong Zhang   if (product) {
87*4222ddf1SHong Zhang     ierr = PetscStrcmp(product->alg,"scalable",&scalable);CHKERRQ(ierr);
88*4222ddf1SHong Zhang   } else SETERRQ(PetscObjectComm((PetscObject)D),PETSC_ERR_ARG_NULL,"Call MatProductCreate() first");
898a9b8717SHong Zhang 
90*4222ddf1SHong Zhang   if (scalable) {
91*4222ddf1SHong Zhang     ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ(B,C,fill,BC);CHKERRQ(ierr);
92b7e612beSHong Zhang     ierr = MatZeroEntries(BC);CHKERRQ(ierr); /* initialize value entries of BC */
93b2405163SHong Zhang     ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ(A,BC,fill,D);CHKERRQ(ierr);
94*4222ddf1SHong Zhang   } else {
95*4222ddf1SHong Zhang     ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ_nonscalable(B,C,fill,BC);CHKERRQ(ierr);
96b7e612beSHong Zhang     ierr = MatZeroEntries(BC);CHKERRQ(ierr); /* initialize value entries of BC */
970fc8cf34SHong Zhang     ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ_nonscalable(A,BC,fill,D);CHKERRQ(ierr);
98f996eeb8SHong Zhang   }
99*4222ddf1SHong Zhang   product->Dwork = BC;
100f996eeb8SHong Zhang 
101*4222ddf1SHong Zhang   D->ops->matmatmultnumeric = MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ;
102*4222ddf1SHong Zhang   D->ops->freeintermediatedatastructures = MatFreeIntermediateDataStructures_MPIAIJ_BC;
103f996eeb8SHong Zhang   PetscFunctionReturn(0);
104f996eeb8SHong Zhang }
105f996eeb8SHong Zhang 
106f996eeb8SHong Zhang PetscErrorCode MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ(Mat A,Mat B,Mat C,Mat D)
107f996eeb8SHong Zhang {
108f996eeb8SHong Zhang   PetscErrorCode ierr;
109*4222ddf1SHong Zhang   Mat_Product    *product = D->product;
110*4222ddf1SHong Zhang   Mat            BC = product->Dwork;
111f996eeb8SHong Zhang 
112f996eeb8SHong Zhang   PetscFunctionBegin;
113f996eeb8SHong Zhang   ierr = (BC->ops->matmultnumeric)(B,C,BC);CHKERRQ(ierr);
114f996eeb8SHong Zhang   ierr = (D->ops->matmultnumeric)(A,BC,D);CHKERRQ(ierr);
115f996eeb8SHong Zhang   PetscFunctionReturn(0);
116f996eeb8SHong Zhang }
1178d45306eSHong Zhang 
118*4222ddf1SHong Zhang /* ----------------------------------------------------- */
119*4222ddf1SHong Zhang PetscErrorCode MatDestroy_MPIAIJ_RARt(Mat C)
1208d45306eSHong Zhang {
1218d45306eSHong Zhang   PetscErrorCode ierr;
122*4222ddf1SHong Zhang   Mat_MPIAIJ     *c    = (Mat_MPIAIJ*)C->data;
123*4222ddf1SHong Zhang   Mat_RARt       *rart = c->rart;
124*4222ddf1SHong Zhang 
125*4222ddf1SHong Zhang   PetscFunctionBegin;
126*4222ddf1SHong Zhang   ierr = MatDestroy(&rart->Rt);CHKERRQ(ierr);
127*4222ddf1SHong Zhang 
128*4222ddf1SHong Zhang   C->ops->destroy = rart->destroy;
129*4222ddf1SHong Zhang   if (C->ops->destroy) {
130*4222ddf1SHong Zhang     ierr = (*C->ops->destroy)(C);CHKERRQ(ierr);
131*4222ddf1SHong Zhang   }
132*4222ddf1SHong Zhang   ierr = PetscFree(rart);CHKERRQ(ierr);
133*4222ddf1SHong Zhang   PetscFunctionReturn(0);
134*4222ddf1SHong Zhang }
135*4222ddf1SHong Zhang 
136*4222ddf1SHong Zhang PetscErrorCode MatProductNumeric_RARt_MPIAIJ_MPIAIJ(Mat C)
137*4222ddf1SHong Zhang {
138*4222ddf1SHong Zhang   PetscErrorCode ierr;
139*4222ddf1SHong Zhang   Mat_MPIAIJ     *c = (Mat_MPIAIJ*)C->data;
140*4222ddf1SHong Zhang   Mat_RARt       *rart = c->rart;
141*4222ddf1SHong Zhang   Mat_Product    *product = C->product;
142*4222ddf1SHong Zhang   Mat            A=product->A,R=product->B,Rt=rart->Rt;
143*4222ddf1SHong Zhang 
144*4222ddf1SHong Zhang   PetscFunctionBegin;
145*4222ddf1SHong Zhang   ierr = MatTranspose(R,MAT_REUSE_MATRIX,&Rt);CHKERRQ(ierr);
146*4222ddf1SHong Zhang   ierr = (C->ops->matmatmultnumeric)(R,A,Rt,C);CHKERRQ(ierr);
147*4222ddf1SHong Zhang   PetscFunctionReturn(0);
148*4222ddf1SHong Zhang }
149*4222ddf1SHong Zhang 
150*4222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_RARt_MPIAIJ_MPIAIJ(Mat C)
151*4222ddf1SHong Zhang {
152*4222ddf1SHong Zhang   PetscErrorCode      ierr;
153*4222ddf1SHong Zhang   Mat_Product         *product = C->product;
154*4222ddf1SHong Zhang   Mat                 A=product->A,R=product->B,Rt;
155*4222ddf1SHong Zhang   PetscReal           fill=product->fill;
156*4222ddf1SHong Zhang   Mat_RARt            *rart;
157*4222ddf1SHong Zhang   Mat_MPIAIJ          *c;
1588d45306eSHong Zhang 
1598d45306eSHong Zhang   PetscFunctionBegin;
1608d45306eSHong Zhang   ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr);
161*4222ddf1SHong Zhang   /* product->Dwork is used to store A*Rt in MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ() */
1628d45306eSHong Zhang   ierr = MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ(R,A,Rt,fill,C);CHKERRQ(ierr);
163*4222ddf1SHong Zhang   C->ops->productnumeric = MatProductNumeric_RARt_MPIAIJ_MPIAIJ;
164*4222ddf1SHong Zhang 
165*4222ddf1SHong Zhang   /* create a supporting struct */
166*4222ddf1SHong Zhang   ierr     = PetscNew(&rart);CHKERRQ(ierr);
167*4222ddf1SHong Zhang   c        = (Mat_MPIAIJ*)C->data;
168*4222ddf1SHong Zhang   c->rart  = rart;
169*4222ddf1SHong Zhang   rart->Rt = Rt;
170*4222ddf1SHong Zhang   rart->destroy   = C->ops->destroy;
171*4222ddf1SHong Zhang   C->ops->destroy = MatDestroy_MPIAIJ_RARt;
1728d45306eSHong Zhang   PetscFunctionReturn(0);
1738d45306eSHong Zhang }
174