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)); 193ba16761SJacob 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; 353ba16761SJacob 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; 43966bd95aSPierre Jolivet PetscCheck(product->type == MATPRODUCT_ABC, PetscObjectComm((PetscObject)C), PETSC_ERR_SUP, "MatProduct type %s is not supported for Transpose, AIJ and AIJ matrices", MatProductTypes[product->type]); 444222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_ABC_Transpose_AIJ_AIJ; 453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 463dad0653Sstefano_zampini } 473dad0653Sstefano_zampini #endif 483dad0653Sstefano_zampini 49d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ(Mat A, Mat B, Mat C, PetscReal fill, Mat D) 50d71ae5a4SJacob Faibussowitsch { 51f996eeb8SHong Zhang Mat BC; 524222ddf1SHong Zhang PetscBool scalable; 536718818eSStefano Zampini Mat_Product *product; 54f996eeb8SHong Zhang 55f996eeb8SHong Zhang PetscFunctionBegin; 568f83a4d9SJacob Faibussowitsch MatCheckProduct(D, 5); 5728b400f6SJacob Faibussowitsch PetscCheck(!D->product->data, PetscObjectComm((PetscObject)D), PETSC_ERR_PLIB, "Product data not empty"); 586718818eSStefano Zampini product = D->product; 599566063dSJacob Faibussowitsch PetscCall(MatProductCreate(B, C, NULL, &BC)); 609566063dSJacob Faibussowitsch PetscCall(MatProductSetType(BC, MATPRODUCT_AB)); 619566063dSJacob Faibussowitsch PetscCall(PetscStrcmp(product->alg, "scalable", &scalable)); 624222ddf1SHong Zhang if (scalable) { 639566063dSJacob Faibussowitsch PetscCall(MatMatMultSymbolic_MPIAIJ_MPIAIJ(B, C, fill, BC)); 649566063dSJacob Faibussowitsch PetscCall(MatZeroEntries(BC)); /* initialize value entries of BC */ 659566063dSJacob Faibussowitsch PetscCall(MatMatMultSymbolic_MPIAIJ_MPIAIJ(A, BC, fill, D)); 664222ddf1SHong Zhang } else { 679566063dSJacob Faibussowitsch PetscCall(MatMatMultSymbolic_MPIAIJ_MPIAIJ_nonscalable(B, C, fill, BC)); 689566063dSJacob Faibussowitsch PetscCall(MatZeroEntries(BC)); /* initialize value entries of BC */ 699566063dSJacob Faibussowitsch PetscCall(MatMatMultSymbolic_MPIAIJ_MPIAIJ_nonscalable(A, BC, fill, D)); 70f996eeb8SHong Zhang } 719566063dSJacob Faibussowitsch PetscCall(MatDestroy(&product->Dwork)); 724222ddf1SHong Zhang product->Dwork = BC; 73f996eeb8SHong Zhang 744222ddf1SHong Zhang D->ops->matmatmultnumeric = MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ; 753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 76f996eeb8SHong Zhang } 77f996eeb8SHong Zhang 78d71ae5a4SJacob Faibussowitsch PetscErrorCode MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ(Mat A, Mat B, Mat C, Mat D) 79d71ae5a4SJacob Faibussowitsch { 806718818eSStefano Zampini Mat_Product *product; 816718818eSStefano Zampini Mat BC; 82f996eeb8SHong Zhang 83f996eeb8SHong Zhang PetscFunctionBegin; 846718818eSStefano Zampini MatCheckProduct(D, 4); 8528b400f6SJacob Faibussowitsch PetscCheck(D->product->data, PetscObjectComm((PetscObject)D), PETSC_ERR_PLIB, "Product data empty"); 866718818eSStefano Zampini product = D->product; 876718818eSStefano Zampini BC = product->Dwork; 889566063dSJacob Faibussowitsch PetscCall((*BC->ops->matmultnumeric)(B, C, BC)); 899566063dSJacob Faibussowitsch PetscCall((*D->ops->matmultnumeric)(A, BC, D)); 903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 91f996eeb8SHong Zhang } 928d45306eSHong Zhang 93*cc1eb50dSBarry Smith static PetscErrorCode MatProductCtxDestroy_MPIAIJ_RARt(void **data) 94d71ae5a4SJacob Faibussowitsch { 95*cc1eb50dSBarry Smith MatProductCtx_RARt *rart = *(MatProductCtx_RARt **)data; 964222ddf1SHong Zhang 974222ddf1SHong Zhang PetscFunctionBegin; 989566063dSJacob Faibussowitsch PetscCall(MatDestroy(&rart->Rt)); 99*cc1eb50dSBarry Smith if (rart->destroy) PetscCall((*rart->destroy)(&rart->data)); 1009566063dSJacob Faibussowitsch PetscCall(PetscFree(rart)); 1013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1024222ddf1SHong Zhang } 1034222ddf1SHong Zhang 104d71ae5a4SJacob Faibussowitsch PetscErrorCode MatProductNumeric_RARt_MPIAIJ_MPIAIJ(Mat C) 105d71ae5a4SJacob Faibussowitsch { 106*cc1eb50dSBarry Smith MatProductCtx_RARt *rart; 1076718818eSStefano Zampini Mat A, R, Rt; 1084222ddf1SHong Zhang 1094222ddf1SHong Zhang PetscFunctionBegin; 1106718818eSStefano Zampini MatCheckProduct(C, 1); 11128b400f6SJacob Faibussowitsch PetscCheck(C->product->data, PetscObjectComm((PetscObject)C), PETSC_ERR_PLIB, "Product data empty"); 112*cc1eb50dSBarry Smith rart = (MatProductCtx_RARt *)C->product->data; 1136718818eSStefano Zampini A = C->product->A; 1146718818eSStefano Zampini R = C->product->B; 1156718818eSStefano Zampini Rt = rart->Rt; 1169566063dSJacob Faibussowitsch PetscCall(MatTranspose(R, MAT_REUSE_MATRIX, &Rt)); 1176718818eSStefano Zampini if (rart->data) C->product->data = rart->data; 1189566063dSJacob Faibussowitsch PetscCall((*C->ops->matmatmultnumeric)(R, A, Rt, C)); 1196718818eSStefano Zampini C->product->data = rart; 1203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1214222ddf1SHong Zhang } 1224222ddf1SHong Zhang 123d71ae5a4SJacob Faibussowitsch PetscErrorCode MatProductSymbolic_RARt_MPIAIJ_MPIAIJ(Mat C) 124d71ae5a4SJacob Faibussowitsch { 1256718818eSStefano Zampini Mat A, R, Rt; 126*cc1eb50dSBarry Smith MatProductCtx_RARt *rart; 1278d45306eSHong Zhang 1288d45306eSHong Zhang PetscFunctionBegin; 1296718818eSStefano Zampini MatCheckProduct(C, 1); 13028b400f6SJacob Faibussowitsch PetscCheck(!C->product->data, PetscObjectComm((PetscObject)C), PETSC_ERR_PLIB, "Product data not empty"); 1316718818eSStefano Zampini A = C->product->A; 1326718818eSStefano Zampini R = C->product->B; 1339566063dSJacob Faibussowitsch PetscCall(MatTranspose(R, MAT_INITIAL_MATRIX, &Rt)); 1344222ddf1SHong Zhang /* product->Dwork is used to store A*Rt in MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ() */ 1359566063dSJacob Faibussowitsch PetscCall(MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ(R, A, Rt, C->product->fill, C)); 1364222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_RARt_MPIAIJ_MPIAIJ; 1374222ddf1SHong Zhang 1384222ddf1SHong Zhang /* create a supporting struct */ 1399566063dSJacob Faibussowitsch PetscCall(PetscNew(&rart)); 1404222ddf1SHong Zhang rart->Rt = Rt; 1416718818eSStefano Zampini rart->data = C->product->data; 1426718818eSStefano Zampini rart->destroy = C->product->destroy; 1436718818eSStefano Zampini C->product->data = rart; 144*cc1eb50dSBarry Smith C->product->destroy = MatProductCtxDestroy_MPIAIJ_RARt; 1453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1468d45306eSHong Zhang } 147