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) 84222ddf1SHong 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 114222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductNumeric_ABC_Transpose_AIJ_AIJ(Mat RAP) 123dad0653Sstefano_zampini { 134222ddf1SHong Zhang Mat_Product *product = RAP->product; 144222ddf1SHong Zhang Mat Rt,R=product->A,A=product->B,P=product->C; 153dad0653Sstefano_zampini 163dad0653Sstefano_zampini PetscFunctionBegin; 175f80ce2aSJacob Faibussowitsch CHKERRQ(MatTransposeGetMat(R,&Rt)); 185f80ce2aSJacob Faibussowitsch CHKERRQ(MatTransposeMatMatMultNumeric_AIJ_AIJ_AIJ_wHYPRE(Rt,A,P,RAP)); 194222ddf1SHong Zhang PetscFunctionReturn(0); 204222ddf1SHong Zhang } 214222ddf1SHong Zhang 224222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSymbolic_ABC_Transpose_AIJ_AIJ(Mat RAP) 234222ddf1SHong Zhang { 244222ddf1SHong Zhang Mat_Product *product = RAP->product; 254222ddf1SHong Zhang Mat Rt,R=product->A,A=product->B,P=product->C; 264222ddf1SHong Zhang PetscBool flg; 274222ddf1SHong Zhang 284222ddf1SHong Zhang PetscFunctionBegin; 294222ddf1SHong Zhang /* local sizes of matrices will be checked by the calling subroutines */ 305f80ce2aSJacob Faibussowitsch CHKERRQ(MatTransposeGetMat(R,&Rt)); 315f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectTypeCompareAny((PetscObject)Rt,&flg,MATSEQAIJ,MATSEQAIJMKL,MATMPIAIJ,NULL)); 32*28b400f6SJacob Faibussowitsch PetscCheck(flg,PetscObjectComm((PetscObject)Rt),PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)Rt)->type_name); 335f80ce2aSJacob Faibussowitsch CHKERRQ(MatTransposeMatMatMultSymbolic_AIJ_AIJ_AIJ_wHYPRE(Rt,A,P,product->fill,RAP)); 344222ddf1SHong Zhang RAP->ops->productnumeric = MatProductNumeric_ABC_Transpose_AIJ_AIJ; 354222ddf1SHong Zhang PetscFunctionReturn(0); 363dad0653Sstefano_zampini } 374222ddf1SHong Zhang 384222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_Transpose_AIJ_AIJ(Mat C) 394222ddf1SHong Zhang { 404222ddf1SHong Zhang Mat_Product *product = C->product; 414222ddf1SHong Zhang 424222ddf1SHong Zhang PetscFunctionBegin; 434222ddf1SHong Zhang if (product->type == MATPRODUCT_ABC) { 444222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_ABC_Transpose_AIJ_AIJ; 4598921bdaSJacob Faibussowitsch } else SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_SUP,"MatProduct type %s is not supported for Transpose, AIJ and AIJ matrices",MatProductTypes[product->type]); 463dad0653Sstefano_zampini PetscFunctionReturn(0); 473dad0653Sstefano_zampini } 483dad0653Sstefano_zampini #endif 493dad0653Sstefano_zampini 504222ddf1SHong Zhang PetscErrorCode MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ(Mat A,Mat B,Mat C,PetscReal fill,Mat D) 51f996eeb8SHong Zhang { 52f996eeb8SHong Zhang Mat BC; 534222ddf1SHong Zhang PetscBool scalable; 546718818eSStefano Zampini Mat_Product *product; 55f996eeb8SHong Zhang 56f996eeb8SHong Zhang PetscFunctionBegin; 576718818eSStefano Zampini MatCheckProduct(D,4); 58*28b400f6SJacob Faibussowitsch PetscCheck(!D->product->data,PetscObjectComm((PetscObject)D),PETSC_ERR_PLIB,"Product data not empty"); 596718818eSStefano Zampini product = D->product; 605f80ce2aSJacob Faibussowitsch CHKERRQ(MatProductCreate(B,C,NULL,&BC)); 615f80ce2aSJacob Faibussowitsch CHKERRQ(MatProductSetType(BC,MATPRODUCT_AB)); 625f80ce2aSJacob Faibussowitsch CHKERRQ(PetscStrcmp(product->alg,"scalable",&scalable)); 634222ddf1SHong Zhang if (scalable) { 645f80ce2aSJacob Faibussowitsch CHKERRQ(MatMatMultSymbolic_MPIAIJ_MPIAIJ(B,C,fill,BC)); 655f80ce2aSJacob Faibussowitsch CHKERRQ(MatZeroEntries(BC)); /* initialize value entries of BC */ 665f80ce2aSJacob Faibussowitsch CHKERRQ(MatMatMultSymbolic_MPIAIJ_MPIAIJ(A,BC,fill,D)); 674222ddf1SHong Zhang } else { 685f80ce2aSJacob Faibussowitsch CHKERRQ(MatMatMultSymbolic_MPIAIJ_MPIAIJ_nonscalable(B,C,fill,BC)); 695f80ce2aSJacob Faibussowitsch CHKERRQ(MatZeroEntries(BC)); /* initialize value entries of BC */ 705f80ce2aSJacob Faibussowitsch CHKERRQ(MatMatMultSymbolic_MPIAIJ_MPIAIJ_nonscalable(A,BC,fill,D)); 71f996eeb8SHong Zhang } 725f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&product->Dwork)); 734222ddf1SHong Zhang product->Dwork = BC; 74f996eeb8SHong Zhang 754222ddf1SHong Zhang D->ops->matmatmultnumeric = MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ; 76f996eeb8SHong Zhang PetscFunctionReturn(0); 77f996eeb8SHong Zhang } 78f996eeb8SHong Zhang 79f996eeb8SHong Zhang PetscErrorCode MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ(Mat A,Mat B,Mat C,Mat D) 80f996eeb8SHong Zhang { 816718818eSStefano Zampini Mat_Product *product; 826718818eSStefano Zampini Mat BC; 83f996eeb8SHong Zhang 84f996eeb8SHong Zhang PetscFunctionBegin; 856718818eSStefano Zampini MatCheckProduct(D,4); 86*28b400f6SJacob Faibussowitsch PetscCheck(D->product->data,PetscObjectComm((PetscObject)D),PETSC_ERR_PLIB,"Product data empty"); 876718818eSStefano Zampini product = D->product; 886718818eSStefano Zampini BC = product->Dwork; 89*28b400f6SJacob Faibussowitsch PetscCheck(BC->ops->matmultnumeric,PetscObjectComm((PetscObject)D),PETSC_ERR_PLIB,"Missing numeric operation"); 905f80ce2aSJacob Faibussowitsch CHKERRQ((*BC->ops->matmultnumeric)(B,C,BC)); 91*28b400f6SJacob Faibussowitsch PetscCheck(D->ops->matmultnumeric,PetscObjectComm((PetscObject)D),PETSC_ERR_PLIB,"Missing numeric operation"); 925f80ce2aSJacob Faibussowitsch CHKERRQ((*D->ops->matmultnumeric)(A,BC,D)); 93f996eeb8SHong Zhang PetscFunctionReturn(0); 94f996eeb8SHong Zhang } 958d45306eSHong Zhang 964222ddf1SHong Zhang /* ----------------------------------------------------- */ 976718818eSStefano Zampini PetscErrorCode MatDestroy_MPIAIJ_RARt(void *data) 988d45306eSHong Zhang { 996718818eSStefano Zampini Mat_RARt *rart = (Mat_RARt*)data; 1004222ddf1SHong Zhang 1014222ddf1SHong Zhang PetscFunctionBegin; 1025f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&rart->Rt)); 1036718818eSStefano Zampini if (rart->destroy) { 1045f80ce2aSJacob Faibussowitsch CHKERRQ((*rart->destroy)(rart->data)); 1054222ddf1SHong Zhang } 1065f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(rart)); 1074222ddf1SHong Zhang PetscFunctionReturn(0); 1084222ddf1SHong Zhang } 1094222ddf1SHong Zhang 1104222ddf1SHong Zhang PetscErrorCode MatProductNumeric_RARt_MPIAIJ_MPIAIJ(Mat C) 1114222ddf1SHong Zhang { 1126718818eSStefano Zampini Mat_RARt *rart; 1136718818eSStefano Zampini Mat A,R,Rt; 1144222ddf1SHong Zhang 1154222ddf1SHong Zhang PetscFunctionBegin; 1166718818eSStefano Zampini MatCheckProduct(C,1); 117*28b400f6SJacob Faibussowitsch PetscCheck(C->product->data,PetscObjectComm((PetscObject)C),PETSC_ERR_PLIB,"Product data empty"); 1186718818eSStefano Zampini rart = (Mat_RARt*)C->product->data; 1196718818eSStefano Zampini A = C->product->A; 1206718818eSStefano Zampini R = C->product->B; 1216718818eSStefano Zampini Rt = rart->Rt; 1225f80ce2aSJacob Faibussowitsch CHKERRQ(MatTranspose(R,MAT_REUSE_MATRIX,&Rt)); 1236718818eSStefano Zampini if (rart->data) C->product->data = rart->data; 1245f80ce2aSJacob Faibussowitsch CHKERRQ((*C->ops->matmatmultnumeric)(R,A,Rt,C)); 1256718818eSStefano Zampini C->product->data = rart; 1264222ddf1SHong Zhang PetscFunctionReturn(0); 1274222ddf1SHong Zhang } 1284222ddf1SHong Zhang 1294222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_RARt_MPIAIJ_MPIAIJ(Mat C) 1304222ddf1SHong Zhang { 1316718818eSStefano Zampini Mat A,R,Rt; 1324222ddf1SHong Zhang Mat_RARt *rart; 1338d45306eSHong Zhang 1348d45306eSHong Zhang PetscFunctionBegin; 1356718818eSStefano Zampini MatCheckProduct(C,1); 136*28b400f6SJacob Faibussowitsch PetscCheck(!C->product->data,PetscObjectComm((PetscObject)C),PETSC_ERR_PLIB,"Product data not empty"); 1376718818eSStefano Zampini A = C->product->A; 1386718818eSStefano Zampini R = C->product->B; 1395f80ce2aSJacob Faibussowitsch CHKERRQ(MatTranspose(R,MAT_INITIAL_MATRIX,&Rt)); 1404222ddf1SHong Zhang /* product->Dwork is used to store A*Rt in MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ() */ 1415f80ce2aSJacob Faibussowitsch CHKERRQ(MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ(R,A,Rt,C->product->fill,C)); 1424222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_RARt_MPIAIJ_MPIAIJ; 1434222ddf1SHong Zhang 1444222ddf1SHong Zhang /* create a supporting struct */ 1455f80ce2aSJacob Faibussowitsch CHKERRQ(PetscNew(&rart)); 1464222ddf1SHong Zhang rart->Rt = Rt; 1476718818eSStefano Zampini rart->data = C->product->data; 1486718818eSStefano Zampini rart->destroy = C->product->destroy; 1496718818eSStefano Zampini C->product->data = rart; 1506718818eSStefano Zampini C->product->destroy = MatDestroy_MPIAIJ_RARt; 1518d45306eSHong Zhang PetscFunctionReturn(0); 1528d45306eSHong Zhang } 153