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 7*3dad0653Sstefano_zampini #if defined(PETSC_HAVE_HYPRE) 8*3dad0653Sstefano_zampini PETSC_INTERN PetscErrorCode MatTransposeMatMatMultSymbolic_AIJ_AIJ_AIJ_wHYPRE(Mat,Mat,Mat,PetscReal,Mat*); 9*3dad0653Sstefano_zampini PETSC_INTERN PetscErrorCode MatTransposeMatMatMultNumeric_AIJ_AIJ_AIJ_wHYPRE(Mat,Mat,Mat,Mat); 10*3dad0653Sstefano_zampini 11*3dad0653Sstefano_zampini #undef __FUNCT__ 12*3dad0653Sstefano_zampini #define __FUNCT__ "MatMatMatMult_Transpose_AIJ_AIJ" 13*3dad0653Sstefano_zampini PETSC_INTERN PetscErrorCode MatMatMatMult_Transpose_AIJ_AIJ(Mat R,Mat A,Mat P,MatReuse scall, PetscReal fill, Mat *RAP) 14*3dad0653Sstefano_zampini { 15*3dad0653Sstefano_zampini Mat Rt; 16*3dad0653Sstefano_zampini PetscBool flg; 17*3dad0653Sstefano_zampini PetscErrorCode ierr; 18*3dad0653Sstefano_zampini 19*3dad0653Sstefano_zampini PetscFunctionBegin; 20*3dad0653Sstefano_zampini ierr = MatTransposeGetMat(R,&Rt);CHKERRQ(ierr); 21*3dad0653Sstefano_zampini ierr = PetscObjectTypeCompareAny((PetscObject)Rt,&flg,MATSEQAIJ,MATMPIAIJ,NULL);CHKERRQ(ierr); 22*3dad0653Sstefano_zampini if (!flg) SETERRQ1(PetscObjectComm((PetscObject)Rt),PETSC_ERR_SUP,"Not for matrix type %s\n",((PetscObject)Rt)->type_name); 23*3dad0653Sstefano_zampini if (scall == MAT_INITIAL_MATRIX) { 24*3dad0653Sstefano_zampini ierr = PetscLogEventBegin(MAT_MatMatMultSymbolic,R,A,P,0);CHKERRQ(ierr); 25*3dad0653Sstefano_zampini ierr = MatTransposeMatMatMultSymbolic_AIJ_AIJ_AIJ_wHYPRE(Rt,A,P,fill,RAP);CHKERRQ(ierr); 26*3dad0653Sstefano_zampini ierr = PetscLogEventEnd(MAT_MatMatMultSymbolic,R,A,P,0);CHKERRQ(ierr); 27*3dad0653Sstefano_zampini } 28*3dad0653Sstefano_zampini ierr = PetscLogEventBegin(MAT_MatMatMultNumeric,R,A,P,0);CHKERRQ(ierr); 29*3dad0653Sstefano_zampini ierr = MatTransposeMatMatMultNumeric_AIJ_AIJ_AIJ_wHYPRE(Rt,A,P,*RAP);CHKERRQ(ierr); 30*3dad0653Sstefano_zampini ierr = PetscLogEventEnd(MAT_MatMatMultNumeric,R,A,P,0);CHKERRQ(ierr); 31*3dad0653Sstefano_zampini PetscFunctionReturn(0); 32*3dad0653Sstefano_zampini } 33*3dad0653Sstefano_zampini #endif 34*3dad0653Sstefano_zampini 35f996eeb8SHong Zhang #undef __FUNCT__ 36f996eeb8SHong Zhang #define __FUNCT__ "MatDestroy_MPIAIJ_MatMatMatMult" 37f996eeb8SHong Zhang PetscErrorCode MatDestroy_MPIAIJ_MatMatMatMult(Mat A) 38f996eeb8SHong Zhang { 39f996eeb8SHong Zhang Mat_MPIAIJ *a = (Mat_MPIAIJ*)A->data; 40f996eeb8SHong Zhang Mat_MatMatMatMult *matmatmatmult=a->matmatmatmult; 41f996eeb8SHong Zhang PetscErrorCode ierr; 42f996eeb8SHong Zhang 43f996eeb8SHong Zhang PetscFunctionBegin; 44f996eeb8SHong Zhang ierr = MatDestroy(&matmatmatmult->BC);CHKERRQ(ierr); 45f996eeb8SHong Zhang ierr = matmatmatmult->destroy(A);CHKERRQ(ierr); 46f996eeb8SHong Zhang ierr = PetscFree(matmatmatmult);CHKERRQ(ierr); 47f996eeb8SHong Zhang PetscFunctionReturn(0); 48f996eeb8SHong Zhang } 49f996eeb8SHong Zhang 50f996eeb8SHong Zhang #undef __FUNCT__ 51f996eeb8SHong Zhang #define __FUNCT__ "MatMatMatMult_MPIAIJ_MPIAIJ_MPIAIJ" 52150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatMatMatMult_MPIAIJ_MPIAIJ_MPIAIJ(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D) 53f996eeb8SHong Zhang { 54f996eeb8SHong Zhang PetscErrorCode ierr; 55f996eeb8SHong Zhang 56f996eeb8SHong Zhang PetscFunctionBegin; 57f996eeb8SHong Zhang if (scall == MAT_INITIAL_MATRIX) { 58f996eeb8SHong Zhang ierr = PetscLogEventBegin(MAT_MatMatMultSymbolic,A,B,C,0);CHKERRQ(ierr); 59f996eeb8SHong Zhang ierr = MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ(A,B,C,fill,D);CHKERRQ(ierr); 60f996eeb8SHong Zhang ierr = PetscLogEventEnd(MAT_MatMatMultSymbolic,A,B,C,0);CHKERRQ(ierr); 61f996eeb8SHong Zhang } 62f996eeb8SHong Zhang ierr = PetscLogEventBegin(MAT_MatMatMultNumeric,A,B,C,0);CHKERRQ(ierr); 6320e1dc0dSstefano_zampini ierr = ((*D)->ops->matmatmultnumeric)(A,B,C,*D);CHKERRQ(ierr); 64f996eeb8SHong Zhang ierr = PetscLogEventEnd(MAT_MatMatMultNumeric,A,B,C,0);CHKERRQ(ierr); 65f996eeb8SHong Zhang PetscFunctionReturn(0); 66f996eeb8SHong Zhang } 67f996eeb8SHong Zhang 68f996eeb8SHong Zhang #undef __FUNCT__ 69f996eeb8SHong Zhang #define __FUNCT__ "MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ" 70f996eeb8SHong Zhang PetscErrorCode MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ(Mat A,Mat B,Mat C,PetscReal fill,Mat *D) 71f996eeb8SHong Zhang { 72f996eeb8SHong Zhang PetscErrorCode ierr; 73f996eeb8SHong Zhang Mat BC; 74f996eeb8SHong Zhang Mat_MatMatMatMult *matmatmatmult; 75f996eeb8SHong Zhang Mat_MPIAIJ *d; 76f996eeb8SHong Zhang PetscBool scalable=PETSC_TRUE; 77f996eeb8SHong Zhang 78f996eeb8SHong Zhang PetscFunctionBegin; 79f996eeb8SHong Zhang ierr = PetscObjectOptionsBegin((PetscObject)B);CHKERRQ(ierr); 800298fd71SBarry Smith ierr = PetscOptionsBool("-matmatmatmult_scalable","Use a scalable but slower D=A*B*C","",scalable,&scalable,NULL);CHKERRQ(ierr); 81f996eeb8SHong Zhang ierr = PetscOptionsEnd();CHKERRQ(ierr); 82f996eeb8SHong Zhang if (scalable) { 83b2405163SHong Zhang ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ(B,C,fill,&BC);CHKERRQ(ierr); 84b2405163SHong Zhang ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ(A,BC,fill,D);CHKERRQ(ierr); 85f996eeb8SHong Zhang } else { 860fc8cf34SHong Zhang ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ_nonscalable(B,C,fill,&BC);CHKERRQ(ierr); 870fc8cf34SHong Zhang ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ_nonscalable(A,BC,fill,D);CHKERRQ(ierr); 88f996eeb8SHong Zhang } 89f996eeb8SHong Zhang 90f996eeb8SHong Zhang /* create struct Mat_MatMatMatMult and attached it to *D */ 91b00a9115SJed Brown ierr = PetscNew(&matmatmatmult);CHKERRQ(ierr); 922205254eSKarl Rupp 93f996eeb8SHong Zhang matmatmatmult->BC = BC; 94f996eeb8SHong Zhang matmatmatmult->destroy = (*D)->ops->destroy; 95f996eeb8SHong Zhang d = (Mat_MPIAIJ*)(*D)->data; 96f996eeb8SHong Zhang d->matmatmatmult = matmatmatmult; 97f996eeb8SHong Zhang 98f996eeb8SHong Zhang (*D)->ops->matmatmultnumeric = MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ; 99f996eeb8SHong Zhang (*D)->ops->destroy = MatDestroy_MPIAIJ_MatMatMatMult; 100f996eeb8SHong Zhang PetscFunctionReturn(0); 101f996eeb8SHong Zhang } 102f996eeb8SHong Zhang 103f996eeb8SHong Zhang #undef __FUNCT__ 104f996eeb8SHong Zhang #define __FUNCT__ "MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ" 105f996eeb8SHong Zhang PetscErrorCode MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ(Mat A,Mat B,Mat C,Mat D) 106f996eeb8SHong Zhang { 107f996eeb8SHong Zhang PetscErrorCode ierr; 108f996eeb8SHong Zhang Mat_MPIAIJ *d = (Mat_MPIAIJ*)D->data; 109f996eeb8SHong Zhang Mat_MatMatMatMult *matmatmatmult = d->matmatmatmult; 110f996eeb8SHong Zhang Mat BC = matmatmatmult->BC; 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 } 117