xref: /petsc/src/mat/impls/aij/mpi/mpimatmatmatmult.c (revision 2bf68e3e0f2a61f71e7c65bee250bfa1c8ce0cdb)
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 #undef __FUNCT__
51 #define __FUNCT__ "MatMatMatMult_MPIAIJ_MPIAIJ_MPIAIJ"
52 PETSC_INTERN PetscErrorCode MatMatMatMult_MPIAIJ_MPIAIJ_MPIAIJ(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D)
53 {
54   PetscErrorCode ierr;
55 
56   PetscFunctionBegin;
57   if (scall == MAT_INITIAL_MATRIX) {
58     ierr = PetscLogEventBegin(MAT_MatMatMultSymbolic,A,B,C,0);CHKERRQ(ierr);
59     ierr = MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ(A,B,C,fill,D);CHKERRQ(ierr);
60     ierr = PetscLogEventEnd(MAT_MatMatMultSymbolic,A,B,C,0);CHKERRQ(ierr);
61   }
62   ierr = PetscLogEventBegin(MAT_MatMatMultNumeric,A,B,C,0);CHKERRQ(ierr);
63   ierr = ((*D)->ops->matmatmultnumeric)(A,B,C,*D);CHKERRQ(ierr);
64   ierr = PetscLogEventEnd(MAT_MatMatMultNumeric,A,B,C,0);CHKERRQ(ierr);
65   PetscFunctionReturn(0);
66 }
67 
68 #undef __FUNCT__
69 #define __FUNCT__ "MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ"
70 PetscErrorCode MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ(Mat A,Mat B,Mat C,PetscReal fill,Mat *D)
71 {
72   PetscErrorCode    ierr;
73   Mat               BC;
74   Mat_MatMatMatMult *matmatmatmult;
75   Mat_MPIAIJ        *d;
76   PetscBool         scalable=PETSC_TRUE;
77 
78   PetscFunctionBegin;
79   ierr = PetscObjectOptionsBegin((PetscObject)B);CHKERRQ(ierr);
80   ierr = PetscOptionsBool("-matmatmatmult_scalable","Use a scalable but slower D=A*B*C","",scalable,&scalable,NULL);CHKERRQ(ierr);
81   ierr = PetscOptionsEnd();CHKERRQ(ierr);
82   if (scalable) {
83     ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ(B,C,fill,&BC);CHKERRQ(ierr);
84     ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ(A,BC,fill,D);CHKERRQ(ierr);
85   } else {
86     ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ_nonscalable(B,C,fill,&BC);CHKERRQ(ierr);
87     ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ_nonscalable(A,BC,fill,D);CHKERRQ(ierr);
88   }
89 
90   /* create struct Mat_MatMatMatMult and attached it to *D */
91   ierr = PetscNew(&matmatmatmult);CHKERRQ(ierr);
92 
93   matmatmatmult->BC      = BC;
94   matmatmatmult->destroy = (*D)->ops->destroy;
95   d                      = (Mat_MPIAIJ*)(*D)->data;
96   d->matmatmatmult       = matmatmatmult;
97 
98   (*D)->ops->matmatmultnumeric = MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ;
99   (*D)->ops->destroy           = MatDestroy_MPIAIJ_MatMatMatMult;
100   PetscFunctionReturn(0);
101 }
102 
103 #undef __FUNCT__
104 #define __FUNCT__ "MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ"
105 PetscErrorCode MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ(Mat A,Mat B,Mat C,Mat D)
106 {
107   PetscErrorCode    ierr;
108   Mat_MPIAIJ        *d             = (Mat_MPIAIJ*)D->data;
109   Mat_MatMatMatMult *matmatmatmult = d->matmatmatmult;
110   Mat               BC             = matmatmatmult->BC;
111 
112   PetscFunctionBegin;
113   ierr = (BC->ops->matmultnumeric)(B,C,BC);CHKERRQ(ierr);
114   ierr = (D->ops->matmultnumeric)(A,BC,D);CHKERRQ(ierr);
115   PetscFunctionReturn(0);
116 }
117