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 119371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatProductNumeric_ABC_Transpose_AIJ_AIJ(Mat RAP) { 124222ddf1SHong Zhang Mat_Product *product = RAP->product; 134222ddf1SHong Zhang Mat Rt, R = product->A, A = product->B, P = product->C; 143dad0653Sstefano_zampini 153dad0653Sstefano_zampini PetscFunctionBegin; 169566063dSJacob Faibussowitsch PetscCall(MatTransposeGetMat(R, &Rt)); 179566063dSJacob Faibussowitsch PetscCall(MatTransposeMatMatMultNumeric_AIJ_AIJ_AIJ_wHYPRE(Rt, A, P, RAP)); 184222ddf1SHong Zhang PetscFunctionReturn(0); 194222ddf1SHong Zhang } 204222ddf1SHong Zhang 219371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatProductSymbolic_ABC_Transpose_AIJ_AIJ(Mat RAP) { 224222ddf1SHong Zhang Mat_Product *product = RAP->product; 234222ddf1SHong Zhang Mat Rt, R = product->A, A = product->B, P = product->C; 244222ddf1SHong Zhang PetscBool flg; 254222ddf1SHong Zhang 264222ddf1SHong Zhang PetscFunctionBegin; 274222ddf1SHong Zhang /* local sizes of matrices will be checked by the calling subroutines */ 289566063dSJacob Faibussowitsch PetscCall(MatTransposeGetMat(R, &Rt)); 299566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)Rt, &flg, MATSEQAIJ, MATSEQAIJMKL, MATMPIAIJ, NULL)); 3028b400f6SJacob Faibussowitsch PetscCheck(flg, PetscObjectComm((PetscObject)Rt), PETSC_ERR_SUP, "Not for matrix type %s", ((PetscObject)Rt)->type_name); 319566063dSJacob Faibussowitsch PetscCall(MatTransposeMatMatMultSymbolic_AIJ_AIJ_AIJ_wHYPRE(Rt, A, P, product->fill, RAP)); 324222ddf1SHong Zhang RAP->ops->productnumeric = MatProductNumeric_ABC_Transpose_AIJ_AIJ; 334222ddf1SHong Zhang PetscFunctionReturn(0); 343dad0653Sstefano_zampini } 354222ddf1SHong Zhang 369371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatProductSetFromOptions_Transpose_AIJ_AIJ(Mat C) { 374222ddf1SHong Zhang Mat_Product *product = C->product; 384222ddf1SHong Zhang 394222ddf1SHong Zhang PetscFunctionBegin; 404222ddf1SHong Zhang if (product->type == MATPRODUCT_ABC) { 414222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_ABC_Transpose_AIJ_AIJ; 4298921bdaSJacob Faibussowitsch } else SETERRQ(PetscObjectComm((PetscObject)C), PETSC_ERR_SUP, "MatProduct type %s is not supported for Transpose, AIJ and AIJ matrices", MatProductTypes[product->type]); 433dad0653Sstefano_zampini PetscFunctionReturn(0); 443dad0653Sstefano_zampini } 453dad0653Sstefano_zampini #endif 463dad0653Sstefano_zampini 479371c9d4SSatish Balay PetscErrorCode MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ(Mat A, Mat B, Mat C, PetscReal fill, Mat D) { 48f996eeb8SHong Zhang Mat BC; 494222ddf1SHong Zhang PetscBool scalable; 506718818eSStefano Zampini Mat_Product *product; 51f996eeb8SHong Zhang 52f996eeb8SHong Zhang PetscFunctionBegin; 53*8f83a4d9SJacob Faibussowitsch MatCheckProduct(D, 5); 5428b400f6SJacob Faibussowitsch PetscCheck(!D->product->data, PetscObjectComm((PetscObject)D), PETSC_ERR_PLIB, "Product data not empty"); 556718818eSStefano Zampini product = D->product; 569566063dSJacob Faibussowitsch PetscCall(MatProductCreate(B, C, NULL, &BC)); 579566063dSJacob Faibussowitsch PetscCall(MatProductSetType(BC, MATPRODUCT_AB)); 589566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(product->alg, "scalable", &scalable)); 594222ddf1SHong Zhang if (scalable) { 609566063dSJacob Faibussowitsch PetscCall(MatMatMultSymbolic_MPIAIJ_MPIAIJ(B, C, fill, BC)); 619566063dSJacob Faibussowitsch PetscCall(MatZeroEntries(BC)); /* initialize value entries of BC */ 629566063dSJacob Faibussowitsch PetscCall(MatMatMultSymbolic_MPIAIJ_MPIAIJ(A, BC, fill, D)); 634222ddf1SHong Zhang } else { 649566063dSJacob Faibussowitsch PetscCall(MatMatMultSymbolic_MPIAIJ_MPIAIJ_nonscalable(B, C, fill, BC)); 659566063dSJacob Faibussowitsch PetscCall(MatZeroEntries(BC)); /* initialize value entries of BC */ 669566063dSJacob Faibussowitsch PetscCall(MatMatMultSymbolic_MPIAIJ_MPIAIJ_nonscalable(A, BC, fill, D)); 67f996eeb8SHong Zhang } 689566063dSJacob Faibussowitsch PetscCall(MatDestroy(&product->Dwork)); 694222ddf1SHong Zhang product->Dwork = BC; 70f996eeb8SHong Zhang 714222ddf1SHong Zhang D->ops->matmatmultnumeric = MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ; 72f996eeb8SHong Zhang PetscFunctionReturn(0); 73f996eeb8SHong Zhang } 74f996eeb8SHong Zhang 759371c9d4SSatish Balay PetscErrorCode MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ(Mat A, Mat B, Mat C, Mat D) { 766718818eSStefano Zampini Mat_Product *product; 776718818eSStefano Zampini Mat BC; 78f996eeb8SHong Zhang 79f996eeb8SHong Zhang PetscFunctionBegin; 806718818eSStefano Zampini MatCheckProduct(D, 4); 8128b400f6SJacob Faibussowitsch PetscCheck(D->product->data, PetscObjectComm((PetscObject)D), PETSC_ERR_PLIB, "Product data empty"); 826718818eSStefano Zampini product = D->product; 836718818eSStefano Zampini BC = product->Dwork; 849566063dSJacob Faibussowitsch PetscCall((*BC->ops->matmultnumeric)(B, C, BC)); 859566063dSJacob Faibussowitsch PetscCall((*D->ops->matmultnumeric)(A, BC, D)); 86f996eeb8SHong Zhang PetscFunctionReturn(0); 87f996eeb8SHong Zhang } 888d45306eSHong Zhang 894222ddf1SHong Zhang /* ----------------------------------------------------- */ 909371c9d4SSatish Balay PetscErrorCode MatDestroy_MPIAIJ_RARt(void *data) { 916718818eSStefano Zampini Mat_RARt *rart = (Mat_RARt *)data; 924222ddf1SHong Zhang 934222ddf1SHong Zhang PetscFunctionBegin; 949566063dSJacob Faibussowitsch PetscCall(MatDestroy(&rart->Rt)); 951baa6e33SBarry Smith if (rart->destroy) PetscCall((*rart->destroy)(rart->data)); 969566063dSJacob Faibussowitsch PetscCall(PetscFree(rart)); 974222ddf1SHong Zhang PetscFunctionReturn(0); 984222ddf1SHong Zhang } 994222ddf1SHong Zhang 1009371c9d4SSatish Balay PetscErrorCode MatProductNumeric_RARt_MPIAIJ_MPIAIJ(Mat C) { 1016718818eSStefano Zampini Mat_RARt *rart; 1026718818eSStefano Zampini Mat A, R, Rt; 1034222ddf1SHong Zhang 1044222ddf1SHong Zhang PetscFunctionBegin; 1056718818eSStefano Zampini MatCheckProduct(C, 1); 10628b400f6SJacob Faibussowitsch PetscCheck(C->product->data, PetscObjectComm((PetscObject)C), PETSC_ERR_PLIB, "Product data empty"); 1076718818eSStefano Zampini rart = (Mat_RARt *)C->product->data; 1086718818eSStefano Zampini A = C->product->A; 1096718818eSStefano Zampini R = C->product->B; 1106718818eSStefano Zampini Rt = rart->Rt; 1119566063dSJacob Faibussowitsch PetscCall(MatTranspose(R, MAT_REUSE_MATRIX, &Rt)); 1126718818eSStefano Zampini if (rart->data) C->product->data = rart->data; 1139566063dSJacob Faibussowitsch PetscCall((*C->ops->matmatmultnumeric)(R, A, Rt, C)); 1146718818eSStefano Zampini C->product->data = rart; 1154222ddf1SHong Zhang PetscFunctionReturn(0); 1164222ddf1SHong Zhang } 1174222ddf1SHong Zhang 1189371c9d4SSatish Balay PetscErrorCode MatProductSymbolic_RARt_MPIAIJ_MPIAIJ(Mat C) { 1196718818eSStefano Zampini Mat A, R, Rt; 1204222ddf1SHong Zhang Mat_RARt *rart; 1218d45306eSHong Zhang 1228d45306eSHong Zhang PetscFunctionBegin; 1236718818eSStefano Zampini MatCheckProduct(C, 1); 12428b400f6SJacob Faibussowitsch PetscCheck(!C->product->data, PetscObjectComm((PetscObject)C), PETSC_ERR_PLIB, "Product data not empty"); 1256718818eSStefano Zampini A = C->product->A; 1266718818eSStefano Zampini R = C->product->B; 1279566063dSJacob Faibussowitsch PetscCall(MatTranspose(R, MAT_INITIAL_MATRIX, &Rt)); 1284222ddf1SHong Zhang /* product->Dwork is used to store A*Rt in MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ() */ 1299566063dSJacob Faibussowitsch PetscCall(MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ(R, A, Rt, C->product->fill, C)); 1304222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_RARt_MPIAIJ_MPIAIJ; 1314222ddf1SHong Zhang 1324222ddf1SHong Zhang /* create a supporting struct */ 1339566063dSJacob Faibussowitsch PetscCall(PetscNew(&rart)); 1344222ddf1SHong Zhang rart->Rt = Rt; 1356718818eSStefano Zampini rart->data = C->product->data; 1366718818eSStefano Zampini rart->destroy = C->product->destroy; 1376718818eSStefano Zampini C->product->data = rart; 1386718818eSStefano Zampini C->product->destroy = MatDestroy_MPIAIJ_RARt; 1398d45306eSHong Zhang PetscFunctionReturn(0); 1408d45306eSHong Zhang } 141