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 33f996eeb8SHong Zhang PetscErrorCode MatDestroy_MPIAIJ_MatMatMatMult(Mat A) 34f996eeb8SHong Zhang { 35f996eeb8SHong Zhang Mat_MPIAIJ *a = (Mat_MPIAIJ*)A->data; 36f996eeb8SHong Zhang Mat_MatMatMatMult *matmatmatmult=a->matmatmatmult; 37f996eeb8SHong Zhang PetscErrorCode ierr; 38f996eeb8SHong Zhang 39f996eeb8SHong Zhang PetscFunctionBegin; 40f996eeb8SHong Zhang ierr = MatDestroy(&matmatmatmult->BC);CHKERRQ(ierr); 41f996eeb8SHong Zhang ierr = matmatmatmult->destroy(A);CHKERRQ(ierr); 42f996eeb8SHong Zhang ierr = PetscFree(matmatmatmult);CHKERRQ(ierr); 43f996eeb8SHong Zhang PetscFunctionReturn(0); 44f996eeb8SHong Zhang } 45f996eeb8SHong Zhang 46150d2497SBarry Smith PETSC_INTERN PetscErrorCode MatMatMatMult_MPIAIJ_MPIAIJ_MPIAIJ(Mat A,Mat B,Mat C,MatReuse scall,PetscReal fill,Mat *D) 47f996eeb8SHong Zhang { 48f996eeb8SHong Zhang PetscErrorCode ierr; 49f996eeb8SHong Zhang 50f996eeb8SHong Zhang PetscFunctionBegin; 51f996eeb8SHong Zhang if (scall == MAT_INITIAL_MATRIX) { 52f996eeb8SHong Zhang ierr = PetscLogEventBegin(MAT_MatMatMultSymbolic,A,B,C,0);CHKERRQ(ierr); 53f996eeb8SHong Zhang ierr = MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ(A,B,C,fill,D);CHKERRQ(ierr); 54f996eeb8SHong Zhang ierr = PetscLogEventEnd(MAT_MatMatMultSymbolic,A,B,C,0);CHKERRQ(ierr); 55f996eeb8SHong Zhang } 56f996eeb8SHong Zhang ierr = PetscLogEventBegin(MAT_MatMatMultNumeric,A,B,C,0);CHKERRQ(ierr); 5720e1dc0dSstefano_zampini ierr = ((*D)->ops->matmatmultnumeric)(A,B,C,*D);CHKERRQ(ierr); 58f996eeb8SHong Zhang ierr = PetscLogEventEnd(MAT_MatMatMultNumeric,A,B,C,0);CHKERRQ(ierr); 59f996eeb8SHong Zhang PetscFunctionReturn(0); 60f996eeb8SHong Zhang } 61f996eeb8SHong Zhang 62f996eeb8SHong Zhang PetscErrorCode MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ(Mat A,Mat B,Mat C,PetscReal fill,Mat *D) 63f996eeb8SHong Zhang { 64f996eeb8SHong Zhang PetscErrorCode ierr; 65f996eeb8SHong Zhang Mat BC; 66f996eeb8SHong Zhang Mat_MatMatMatMult *matmatmatmult; 67f996eeb8SHong Zhang Mat_MPIAIJ *d; 68f996eeb8SHong Zhang PetscBool scalable=PETSC_TRUE; 69f996eeb8SHong Zhang 70f996eeb8SHong Zhang PetscFunctionBegin; 71f996eeb8SHong Zhang ierr = PetscObjectOptionsBegin((PetscObject)B);CHKERRQ(ierr); 720298fd71SBarry Smith ierr = PetscOptionsBool("-matmatmatmult_scalable","Use a scalable but slower D=A*B*C","",scalable,&scalable,NULL);CHKERRQ(ierr); 73f996eeb8SHong Zhang ierr = PetscOptionsEnd();CHKERRQ(ierr); 74f996eeb8SHong Zhang if (scalable) { 75b2405163SHong Zhang ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ(B,C,fill,&BC);CHKERRQ(ierr); 76b2405163SHong Zhang ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ(A,BC,fill,D);CHKERRQ(ierr); 77f996eeb8SHong Zhang } else { 780fc8cf34SHong Zhang ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ_nonscalable(B,C,fill,&BC);CHKERRQ(ierr); 790fc8cf34SHong Zhang ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ_nonscalable(A,BC,fill,D);CHKERRQ(ierr); 80f996eeb8SHong Zhang } 81f996eeb8SHong Zhang 82f996eeb8SHong Zhang /* create struct Mat_MatMatMatMult and attached it to *D */ 83b00a9115SJed Brown ierr = PetscNew(&matmatmatmult);CHKERRQ(ierr); 842205254eSKarl Rupp 85f996eeb8SHong Zhang matmatmatmult->BC = BC; 86f996eeb8SHong Zhang matmatmatmult->destroy = (*D)->ops->destroy; 87f996eeb8SHong Zhang d = (Mat_MPIAIJ*)(*D)->data; 88f996eeb8SHong Zhang d->matmatmatmult = matmatmatmult; 89f996eeb8SHong Zhang 90f996eeb8SHong Zhang (*D)->ops->matmatmultnumeric = MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ; 91f996eeb8SHong Zhang (*D)->ops->destroy = MatDestroy_MPIAIJ_MatMatMatMult; 92f996eeb8SHong Zhang PetscFunctionReturn(0); 93f996eeb8SHong Zhang } 94f996eeb8SHong Zhang 95f996eeb8SHong Zhang PetscErrorCode MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ(Mat A,Mat B,Mat C,Mat D) 96f996eeb8SHong Zhang { 97f996eeb8SHong Zhang PetscErrorCode ierr; 98f996eeb8SHong Zhang Mat_MPIAIJ *d = (Mat_MPIAIJ*)D->data; 99f996eeb8SHong Zhang Mat_MatMatMatMult *matmatmatmult = d->matmatmatmult; 100f996eeb8SHong Zhang Mat BC = matmatmatmult->BC; 101f996eeb8SHong Zhang 102f996eeb8SHong Zhang PetscFunctionBegin; 103f996eeb8SHong Zhang ierr = (BC->ops->matmultnumeric)(B,C,BC);CHKERRQ(ierr); 104f996eeb8SHong Zhang ierr = (D->ops->matmultnumeric)(A,BC,D);CHKERRQ(ierr); 105f996eeb8SHong Zhang PetscFunctionReturn(0); 106f996eeb8SHong Zhang } 107*8d45306eSHong Zhang 108*8d45306eSHong Zhang PetscErrorCode MatRARt_MPIAIJ_MPIAIJ(Mat A,Mat R,MatReuse scall,PetscReal fill,Mat *C) 109*8d45306eSHong Zhang { 110*8d45306eSHong Zhang PetscErrorCode ierr; 111*8d45306eSHong Zhang Mat Rt; 112*8d45306eSHong Zhang 113*8d45306eSHong Zhang PetscFunctionBegin; 114*8d45306eSHong Zhang ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr); 115*8d45306eSHong Zhang if (scall == MAT_INITIAL_MATRIX) { 116*8d45306eSHong Zhang ierr = MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ(R,A,Rt,fill,C);CHKERRQ(ierr); 117*8d45306eSHong Zhang } 118*8d45306eSHong Zhang ierr = MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ(R,A,Rt,*C);CHKERRQ(ierr); 119*8d45306eSHong Zhang ierr = MatDestroy(&Rt);CHKERRQ(ierr); 120*8d45306eSHong Zhang PetscFunctionReturn(0); 121*8d45306eSHong Zhang } 122