xref: /petsc/src/mat/impls/aij/mpi/mpimatmatmatmult.c (revision 390e1bf27627d887df99a9f4d0d0ad68037f55ec)
1 /*
2   Defines matrix-matrix-matrix product routines for MPIAIJ matrices
3           D = A * B * C
4 */
5 #include <../src/mat/impls/aij/mpi/mpiaij.h> /*I "petscmat.h" I*/
6 
7 #if defined(PETSC_HAVE_HYPRE)
8 PETSC_INTERN PetscErrorCode MatTransposeMatMatMultSymbolic_AIJ_AIJ_AIJ_wHYPRE(Mat,Mat,Mat,PetscReal,Mat*);
9 PETSC_INTERN PetscErrorCode MatTransposeMatMatMultNumeric_AIJ_AIJ_AIJ_wHYPRE(Mat,Mat,Mat,Mat);
10 
11 #undef __FUNCT__
12 #define __FUNCT__ "MatMatMatMult_Transpose_AIJ_AIJ"
13 PETSC_INTERN PetscErrorCode MatMatMatMult_Transpose_AIJ_AIJ(Mat R,Mat A,Mat P,MatReuse scall, PetscReal fill, Mat *RAP)
14 {
15   Mat            Rt;
16   PetscBool      flg;
17   PetscErrorCode ierr;
18 
19   PetscFunctionBegin;
20   ierr = MatTransposeGetMat(R,&Rt);CHKERRQ(ierr);
21   ierr = PetscObjectTypeCompareAny((PetscObject)Rt,&flg,MATSEQAIJ,MATMPIAIJ,NULL);CHKERRQ(ierr);
22   if (!flg) SETERRQ1(PetscObjectComm((PetscObject)Rt),PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)Rt)->type_name);
23   if (scall == MAT_INITIAL_MATRIX) {
24     ierr = PetscLogEventBegin(MAT_MatMatMultSymbolic,R,A,P,0);CHKERRQ(ierr);
25     ierr = MatTransposeMatMatMultSymbolic_AIJ_AIJ_AIJ_wHYPRE(Rt,A,P,fill,RAP);CHKERRQ(ierr);
26     ierr = PetscLogEventEnd(MAT_MatMatMultSymbolic,R,A,P,0);CHKERRQ(ierr);
27   }
28   ierr = PetscLogEventBegin(MAT_MatMatMultNumeric,R,A,P,0);CHKERRQ(ierr);
29   ierr = MatTransposeMatMatMultNumeric_AIJ_AIJ_AIJ_wHYPRE(Rt,A,P,*RAP);CHKERRQ(ierr);
30   ierr = PetscLogEventEnd(MAT_MatMatMultNumeric,R,A,P,0);CHKERRQ(ierr);
31   PetscFunctionReturn(0);
32 }
33 #endif
34 
35 #undef __FUNCT__
36 #define __FUNCT__ "MatDestroy_MPIAIJ_MatMatMatMult"
37 PetscErrorCode MatDestroy_MPIAIJ_MatMatMatMult(Mat A)
38 {
39   Mat_MPIAIJ        *a            = (Mat_MPIAIJ*)A->data;
40   Mat_MatMatMatMult *matmatmatmult=a->matmatmatmult;
41   PetscErrorCode    ierr;
42 
43   PetscFunctionBegin;
44   ierr = MatDestroy(&matmatmatmult->BC);CHKERRQ(ierr);
45   ierr = matmatmatmult->destroy(A);CHKERRQ(ierr);
46   ierr = PetscFree(matmatmatmult);CHKERRQ(ierr);
47   PetscFunctionReturn(0);
48 }
49 
50 PETSC_INTERN PetscErrorCode MatMatMatMult_MPIAIJ_MPIAIJ_MPIAIJ(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
51 {
52   PetscErrorCode ierr;
53 
54   PetscFunctionBegin;
55   if (scall == MAT_INITIAL_MATRIX) {
56     ierr = PetscLogEventBegin(MAT_MatMatMultSymbolic,A,B,C,0);CHKERRQ(ierr);
57     ierr = MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ(A,B,C,fill,D);CHKERRQ(ierr);
58     ierr = PetscLogEventEnd(MAT_MatMatMultSymbolic,A,B,C,0);CHKERRQ(ierr);
59   }
60   ierr = PetscLogEventBegin(MAT_MatMatMultNumeric,A,B,C,0);CHKERRQ(ierr);
61   ierr = ((*D)->ops->matmatmultnumeric)(A,B,C,*D);CHKERRQ(ierr);
62   ierr = PetscLogEventEnd(MAT_MatMatMultNumeric,A,B,C,0);CHKERRQ(ierr);
63   PetscFunctionReturn(0);
64 }
65 
66 PetscErrorCode MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ(Mat A,Mat B,Mat C,PetscReal fill,Mat *D)
67 {
68   PetscErrorCode    ierr;
69   Mat               BC;
70   Mat_MatMatMatMult *matmatmatmult;
71   Mat_MPIAIJ        *d;
72   PetscBool         scalable=PETSC_TRUE;
73 
74   PetscFunctionBegin;
75   ierr = PetscObjectOptionsBegin((PetscObject)B);CHKERRQ(ierr);
76   ierr = PetscOptionsBool("-matmatmatmult_scalable","Use a scalable but slower D=A*B*C","",scalable,&scalable,NULL);CHKERRQ(ierr);
77   ierr = PetscOptionsEnd();CHKERRQ(ierr);
78   if (scalable) {
79     ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ(B,C,fill,&BC);CHKERRQ(ierr);
80     ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ(A,BC,fill,D);CHKERRQ(ierr);
81   } else {
82     ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ_nonscalable(B,C,fill,&BC);CHKERRQ(ierr);
83     ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ_nonscalable(A,BC,fill,D);CHKERRQ(ierr);
84   }
85 
86   /* create struct Mat_MatMatMatMult and attached it to *D */
87   ierr = PetscNew(&matmatmatmult);CHKERRQ(ierr);
88 
89   matmatmatmult->BC      = BC;
90   matmatmatmult->destroy = (*D)->ops->destroy;
91   d                      = (Mat_MPIAIJ*)(*D)->data;
92   d->matmatmatmult       = matmatmatmult;
93 
94   (*D)->ops->matmatmultnumeric = MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ;
95   (*D)->ops->destroy           = MatDestroy_MPIAIJ_MatMatMatMult;
96   PetscFunctionReturn(0);
97 }
98 
99 PetscErrorCode MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ(Mat A,Mat B,Mat C,Mat D)
100 {
101   PetscErrorCode    ierr;
102   Mat_MPIAIJ        *d             = (Mat_MPIAIJ*)D->data;
103   Mat_MatMatMatMult *matmatmatmult = d->matmatmatmult;
104   Mat               BC             = matmatmatmult->BC;
105 
106   PetscFunctionBegin;
107   ierr = (BC->ops->matmultnumeric)(B,C,BC);CHKERRQ(ierr);
108   ierr = (D->ops->matmultnumeric)(A,BC,D);CHKERRQ(ierr);
109   PetscFunctionReturn(0);
110 }
111