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 11d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatProductNumeric_ABC_Transpose_AIJ_AIJ(Mat RAP) 12d71ae5a4SJacob Faibussowitsch { 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; 179566063dSJacob Faibussowitsch PetscCall(MatTransposeGetMat(R, &Rt)); 189566063dSJacob Faibussowitsch PetscCall(MatTransposeMatMatMultNumeric_AIJ_AIJ_AIJ_wHYPRE(Rt, A, P, RAP)); 19*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 204222ddf1SHong Zhang } 214222ddf1SHong Zhang 22d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatProductSymbolic_ABC_Transpose_AIJ_AIJ(Mat RAP) 23d71ae5a4SJacob Faibussowitsch { 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 */ 309566063dSJacob Faibussowitsch PetscCall(MatTransposeGetMat(R, &Rt)); 319566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)Rt, &flg, MATSEQAIJ, MATSEQAIJMKL, MATMPIAIJ, NULL)); 3228b400f6SJacob Faibussowitsch PetscCheck(flg, PetscObjectComm((PetscObject)Rt), PETSC_ERR_SUP, "Not for matrix type %s", ((PetscObject)Rt)->type_name); 339566063dSJacob Faibussowitsch PetscCall(MatTransposeMatMatMultSymbolic_AIJ_AIJ_AIJ_wHYPRE(Rt, A, P, product->fill, RAP)); 344222ddf1SHong Zhang RAP->ops->productnumeric = MatProductNumeric_ABC_Transpose_AIJ_AIJ; 35*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 363dad0653Sstefano_zampini } 374222ddf1SHong Zhang 38d71ae5a4SJacob Faibussowitsch PETSC_INTERN PetscErrorCode MatProductSetFromOptions_Transpose_AIJ_AIJ(Mat C) 39d71ae5a4SJacob Faibussowitsch { 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]); 46*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 473dad0653Sstefano_zampini } 483dad0653Sstefano_zampini #endif 493dad0653Sstefano_zampini 50d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ(Mat A, Mat B, Mat C, PetscReal fill, Mat D) 51d71ae5a4SJacob Faibussowitsch { 52f996eeb8SHong Zhang Mat BC; 534222ddf1SHong Zhang PetscBool scalable; 546718818eSStefano Zampini Mat_Product *product; 55f996eeb8SHong Zhang 56f996eeb8SHong Zhang PetscFunctionBegin; 578f83a4d9SJacob Faibussowitsch MatCheckProduct(D, 5); 5828b400f6SJacob Faibussowitsch PetscCheck(!D->product->data, PetscObjectComm((PetscObject)D), PETSC_ERR_PLIB, "Product data not empty"); 596718818eSStefano Zampini product = D->product; 609566063dSJacob Faibussowitsch PetscCall(MatProductCreate(B, C, NULL, &BC)); 619566063dSJacob Faibussowitsch PetscCall(MatProductSetType(BC, MATPRODUCT_AB)); 629566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(product->alg, "scalable", &scalable)); 634222ddf1SHong Zhang if (scalable) { 649566063dSJacob Faibussowitsch PetscCall(MatMatMultSymbolic_MPIAIJ_MPIAIJ(B, C, fill, BC)); 659566063dSJacob Faibussowitsch PetscCall(MatZeroEntries(BC)); /* initialize value entries of BC */ 669566063dSJacob Faibussowitsch PetscCall(MatMatMultSymbolic_MPIAIJ_MPIAIJ(A, BC, fill, D)); 674222ddf1SHong Zhang } else { 689566063dSJacob Faibussowitsch PetscCall(MatMatMultSymbolic_MPIAIJ_MPIAIJ_nonscalable(B, C, fill, BC)); 699566063dSJacob Faibussowitsch PetscCall(MatZeroEntries(BC)); /* initialize value entries of BC */ 709566063dSJacob Faibussowitsch PetscCall(MatMatMultSymbolic_MPIAIJ_MPIAIJ_nonscalable(A, BC, fill, D)); 71f996eeb8SHong Zhang } 729566063dSJacob Faibussowitsch PetscCall(MatDestroy(&product->Dwork)); 734222ddf1SHong Zhang product->Dwork = BC; 74f996eeb8SHong Zhang 754222ddf1SHong Zhang D->ops->matmatmultnumeric = MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ; 76*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 77f996eeb8SHong Zhang } 78f996eeb8SHong Zhang 79d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ(Mat A, Mat B, Mat C, Mat D) 80d71ae5a4SJacob Faibussowitsch { 816718818eSStefano Zampini Mat_Product *product; 826718818eSStefano Zampini Mat BC; 83f996eeb8SHong Zhang 84f996eeb8SHong Zhang PetscFunctionBegin; 856718818eSStefano Zampini MatCheckProduct(D, 4); 8628b400f6SJacob Faibussowitsch PetscCheck(D->product->data, PetscObjectComm((PetscObject)D), PETSC_ERR_PLIB, "Product data empty"); 876718818eSStefano Zampini product = D->product; 886718818eSStefano Zampini BC = product->Dwork; 899566063dSJacob Faibussowitsch PetscCall((*BC->ops->matmultnumeric)(B, C, BC)); 909566063dSJacob Faibussowitsch PetscCall((*D->ops->matmultnumeric)(A, BC, D)); 91*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 92f996eeb8SHong Zhang } 938d45306eSHong Zhang 944222ddf1SHong Zhang /* ----------------------------------------------------- */ 95d71ae5a4SJacob Faibussowitsch PetscErrorCode MatDestroy_MPIAIJ_RARt(void *data) 96d71ae5a4SJacob Faibussowitsch { 976718818eSStefano Zampini Mat_RARt *rart = (Mat_RARt *)data; 984222ddf1SHong Zhang 994222ddf1SHong Zhang PetscFunctionBegin; 1009566063dSJacob Faibussowitsch PetscCall(MatDestroy(&rart->Rt)); 1011baa6e33SBarry Smith if (rart->destroy) PetscCall((*rart->destroy)(rart->data)); 1029566063dSJacob Faibussowitsch PetscCall(PetscFree(rart)); 103*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1044222ddf1SHong Zhang } 1054222ddf1SHong Zhang 106d71ae5a4SJacob Faibussowitsch PetscErrorCode MatProductNumeric_RARt_MPIAIJ_MPIAIJ(Mat C) 107d71ae5a4SJacob Faibussowitsch { 1086718818eSStefano Zampini Mat_RARt *rart; 1096718818eSStefano Zampini Mat A, R, Rt; 1104222ddf1SHong Zhang 1114222ddf1SHong Zhang PetscFunctionBegin; 1126718818eSStefano Zampini MatCheckProduct(C, 1); 11328b400f6SJacob Faibussowitsch PetscCheck(C->product->data, PetscObjectComm((PetscObject)C), PETSC_ERR_PLIB, "Product data empty"); 1146718818eSStefano Zampini rart = (Mat_RARt *)C->product->data; 1156718818eSStefano Zampini A = C->product->A; 1166718818eSStefano Zampini R = C->product->B; 1176718818eSStefano Zampini Rt = rart->Rt; 1189566063dSJacob Faibussowitsch PetscCall(MatTranspose(R, MAT_REUSE_MATRIX, &Rt)); 1196718818eSStefano Zampini if (rart->data) C->product->data = rart->data; 1209566063dSJacob Faibussowitsch PetscCall((*C->ops->matmatmultnumeric)(R, A, Rt, C)); 1216718818eSStefano Zampini C->product->data = rart; 122*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1234222ddf1SHong Zhang } 1244222ddf1SHong Zhang 125d71ae5a4SJacob Faibussowitsch PetscErrorCode MatProductSymbolic_RARt_MPIAIJ_MPIAIJ(Mat C) 126d71ae5a4SJacob Faibussowitsch { 1276718818eSStefano Zampini Mat A, R, Rt; 1284222ddf1SHong Zhang Mat_RARt *rart; 1298d45306eSHong Zhang 1308d45306eSHong Zhang PetscFunctionBegin; 1316718818eSStefano Zampini MatCheckProduct(C, 1); 13228b400f6SJacob Faibussowitsch PetscCheck(!C->product->data, PetscObjectComm((PetscObject)C), PETSC_ERR_PLIB, "Product data not empty"); 1336718818eSStefano Zampini A = C->product->A; 1346718818eSStefano Zampini R = C->product->B; 1359566063dSJacob Faibussowitsch PetscCall(MatTranspose(R, MAT_INITIAL_MATRIX, &Rt)); 1364222ddf1SHong Zhang /* product->Dwork is used to store A*Rt in MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ() */ 1379566063dSJacob Faibussowitsch PetscCall(MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ(R, A, Rt, C->product->fill, C)); 1384222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_RARt_MPIAIJ_MPIAIJ; 1394222ddf1SHong Zhang 1404222ddf1SHong Zhang /* create a supporting struct */ 1419566063dSJacob Faibussowitsch PetscCall(PetscNew(&rart)); 1424222ddf1SHong Zhang rart->Rt = Rt; 1436718818eSStefano Zampini rart->data = C->product->data; 1446718818eSStefano Zampini rart->destroy = C->product->destroy; 1456718818eSStefano Zampini C->product->data = rart; 1466718818eSStefano Zampini C->product->destroy = MatDestroy_MPIAIJ_RARt; 147*3ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1488d45306eSHong Zhang } 149