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 { 133dad0653Sstefano_zampini PetscErrorCode ierr; 144222ddf1SHong Zhang Mat_Product *product = RAP->product; 154222ddf1SHong Zhang Mat Rt,R=product->A,A=product->B,P=product->C; 163dad0653Sstefano_zampini 173dad0653Sstefano_zampini PetscFunctionBegin; 183dad0653Sstefano_zampini ierr = MatTransposeGetMat(R,&Rt);CHKERRQ(ierr); 194222ddf1SHong Zhang ierr = MatTransposeMatMatMultNumeric_AIJ_AIJ_AIJ_wHYPRE(Rt,A,P,RAP);CHKERRQ(ierr); 204222ddf1SHong Zhang PetscFunctionReturn(0); 214222ddf1SHong Zhang } 224222ddf1SHong Zhang 234222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSymbolic_ABC_Transpose_AIJ_AIJ(Mat RAP) 244222ddf1SHong Zhang { 254222ddf1SHong Zhang PetscErrorCode ierr; 264222ddf1SHong Zhang Mat_Product *product = RAP->product; 274222ddf1SHong Zhang Mat Rt,R=product->A,A=product->B,P=product->C; 284222ddf1SHong Zhang PetscBool flg; 294222ddf1SHong Zhang 304222ddf1SHong Zhang PetscFunctionBegin; 314222ddf1SHong Zhang /* local sizes of matrices will be checked by the calling subroutines */ 324222ddf1SHong Zhang ierr = MatTransposeGetMat(R,&Rt);CHKERRQ(ierr); 33d248a85cSRichard Tran Mills ierr = PetscObjectTypeCompareAny((PetscObject)Rt,&flg,MATSEQAIJ,MATSEQAIJMKL,MATMPIAIJ,NULL);CHKERRQ(ierr); 34*98921bdaSJacob Faibussowitsch if (!flg) SETERRQ(PetscObjectComm((PetscObject)Rt),PETSC_ERR_SUP,"Not for matrix type %s",((PetscObject)Rt)->type_name); 354222ddf1SHong Zhang ierr = MatTransposeMatMatMultSymbolic_AIJ_AIJ_AIJ_wHYPRE(Rt,A,P,product->fill,RAP);CHKERRQ(ierr); 364222ddf1SHong Zhang RAP->ops->productnumeric = MatProductNumeric_ABC_Transpose_AIJ_AIJ; 374222ddf1SHong Zhang PetscFunctionReturn(0); 383dad0653Sstefano_zampini } 394222ddf1SHong Zhang 404222ddf1SHong Zhang PETSC_INTERN PetscErrorCode MatProductSetFromOptions_Transpose_AIJ_AIJ(Mat C) 414222ddf1SHong Zhang { 424222ddf1SHong Zhang Mat_Product *product = C->product; 434222ddf1SHong Zhang 444222ddf1SHong Zhang PetscFunctionBegin; 454222ddf1SHong Zhang if (product->type == MATPRODUCT_ABC) { 464222ddf1SHong Zhang C->ops->productsymbolic = MatProductSymbolic_ABC_Transpose_AIJ_AIJ; 47*98921bdaSJacob Faibussowitsch } else SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_SUP,"MatProduct type %s is not supported for Transpose, AIJ and AIJ matrices",MatProductTypes[product->type]); 483dad0653Sstefano_zampini PetscFunctionReturn(0); 493dad0653Sstefano_zampini } 503dad0653Sstefano_zampini #endif 513dad0653Sstefano_zampini 524222ddf1SHong Zhang PetscErrorCode MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ(Mat A,Mat B,Mat C,PetscReal fill,Mat D) 53f996eeb8SHong Zhang { 54f996eeb8SHong Zhang PetscErrorCode ierr; 55f996eeb8SHong Zhang Mat BC; 564222ddf1SHong Zhang PetscBool scalable; 576718818eSStefano Zampini Mat_Product *product; 58f996eeb8SHong Zhang 59f996eeb8SHong Zhang PetscFunctionBegin; 606718818eSStefano Zampini MatCheckProduct(D,4); 616718818eSStefano Zampini if (D->product->data) SETERRQ(PetscObjectComm((PetscObject)D),PETSC_ERR_PLIB,"Product data not empty"); 626718818eSStefano Zampini product = D->product; 636718818eSStefano Zampini ierr = MatProductCreate(B,C,NULL,&BC);CHKERRQ(ierr); 646718818eSStefano Zampini ierr = MatProductSetType(BC,MATPRODUCT_AB);CHKERRQ(ierr); 654222ddf1SHong Zhang ierr = PetscStrcmp(product->alg,"scalable",&scalable);CHKERRQ(ierr); 664222ddf1SHong Zhang if (scalable) { 674222ddf1SHong Zhang ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ(B,C,fill,BC);CHKERRQ(ierr); 68b7e612beSHong Zhang ierr = MatZeroEntries(BC);CHKERRQ(ierr); /* initialize value entries of BC */ 69b2405163SHong Zhang ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ(A,BC,fill,D);CHKERRQ(ierr); 704222ddf1SHong Zhang } else { 714222ddf1SHong Zhang ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ_nonscalable(B,C,fill,BC);CHKERRQ(ierr); 72b7e612beSHong Zhang ierr = MatZeroEntries(BC);CHKERRQ(ierr); /* initialize value entries of BC */ 730fc8cf34SHong Zhang ierr = MatMatMultSymbolic_MPIAIJ_MPIAIJ_nonscalable(A,BC,fill,D);CHKERRQ(ierr); 74f996eeb8SHong Zhang } 756718818eSStefano Zampini ierr = MatDestroy(&product->Dwork);CHKERRQ(ierr); 764222ddf1SHong Zhang product->Dwork = BC; 77f996eeb8SHong Zhang 784222ddf1SHong Zhang D->ops->matmatmultnumeric = MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ; 79f996eeb8SHong Zhang PetscFunctionReturn(0); 80f996eeb8SHong Zhang } 81f996eeb8SHong Zhang 82f996eeb8SHong Zhang PetscErrorCode MatMatMatMultNumeric_MPIAIJ_MPIAIJ_MPIAIJ(Mat A,Mat B,Mat C,Mat D) 83f996eeb8SHong Zhang { 84f996eeb8SHong Zhang PetscErrorCode ierr; 856718818eSStefano Zampini Mat_Product *product; 866718818eSStefano Zampini Mat BC; 87f996eeb8SHong Zhang 88f996eeb8SHong Zhang PetscFunctionBegin; 896718818eSStefano Zampini MatCheckProduct(D,4); 906718818eSStefano Zampini if (!D->product->data) SETERRQ(PetscObjectComm((PetscObject)D),PETSC_ERR_PLIB,"Product data empty"); 916718818eSStefano Zampini product = D->product; 926718818eSStefano Zampini BC = product->Dwork; 936718818eSStefano Zampini if (!BC->ops->matmultnumeric) SETERRQ(PetscObjectComm((PetscObject)D),PETSC_ERR_PLIB,"Missing numeric operation"); 946718818eSStefano Zampini ierr = (*BC->ops->matmultnumeric)(B,C,BC);CHKERRQ(ierr); 956718818eSStefano Zampini if (!D->ops->matmultnumeric) SETERRQ(PetscObjectComm((PetscObject)D),PETSC_ERR_PLIB,"Missing numeric operation"); 966718818eSStefano Zampini ierr = (*D->ops->matmultnumeric)(A,BC,D);CHKERRQ(ierr); 97f996eeb8SHong Zhang PetscFunctionReturn(0); 98f996eeb8SHong Zhang } 998d45306eSHong Zhang 1004222ddf1SHong Zhang /* ----------------------------------------------------- */ 1016718818eSStefano Zampini PetscErrorCode MatDestroy_MPIAIJ_RARt(void *data) 1028d45306eSHong Zhang { 1038d45306eSHong Zhang PetscErrorCode ierr; 1046718818eSStefano Zampini Mat_RARt *rart = (Mat_RARt*)data; 1054222ddf1SHong Zhang 1064222ddf1SHong Zhang PetscFunctionBegin; 1074222ddf1SHong Zhang ierr = MatDestroy(&rart->Rt);CHKERRQ(ierr); 1086718818eSStefano Zampini if (rart->destroy) { 1096718818eSStefano Zampini ierr = (*rart->destroy)(rart->data);CHKERRQ(ierr); 1104222ddf1SHong Zhang } 1114222ddf1SHong Zhang ierr = PetscFree(rart);CHKERRQ(ierr); 1124222ddf1SHong Zhang PetscFunctionReturn(0); 1134222ddf1SHong Zhang } 1144222ddf1SHong Zhang 1154222ddf1SHong Zhang PetscErrorCode MatProductNumeric_RARt_MPIAIJ_MPIAIJ(Mat C) 1164222ddf1SHong Zhang { 1174222ddf1SHong Zhang PetscErrorCode ierr; 1186718818eSStefano Zampini Mat_RARt *rart; 1196718818eSStefano Zampini Mat A,R,Rt; 1204222ddf1SHong Zhang 1214222ddf1SHong Zhang PetscFunctionBegin; 1226718818eSStefano Zampini MatCheckProduct(C,1); 1236718818eSStefano Zampini if (!C->product->data) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_PLIB,"Product data empty"); 1246718818eSStefano Zampini rart = (Mat_RARt*)C->product->data; 1256718818eSStefano Zampini A = C->product->A; 1266718818eSStefano Zampini R = C->product->B; 1276718818eSStefano Zampini Rt = rart->Rt; 1284222ddf1SHong Zhang ierr = MatTranspose(R,MAT_REUSE_MATRIX,&Rt);CHKERRQ(ierr); 1296718818eSStefano Zampini if (rart->data) C->product->data = rart->data; 1306718818eSStefano Zampini ierr = (*C->ops->matmatmultnumeric)(R,A,Rt,C);CHKERRQ(ierr); 1316718818eSStefano Zampini C->product->data = rart; 1324222ddf1SHong Zhang PetscFunctionReturn(0); 1334222ddf1SHong Zhang } 1344222ddf1SHong Zhang 1354222ddf1SHong Zhang PetscErrorCode MatProductSymbolic_RARt_MPIAIJ_MPIAIJ(Mat C) 1364222ddf1SHong Zhang { 1374222ddf1SHong Zhang PetscErrorCode ierr; 1386718818eSStefano Zampini Mat A,R,Rt; 1394222ddf1SHong Zhang Mat_RARt *rart; 1408d45306eSHong Zhang 1418d45306eSHong Zhang PetscFunctionBegin; 1426718818eSStefano Zampini MatCheckProduct(C,1); 1436718818eSStefano Zampini if (C->product->data) SETERRQ(PetscObjectComm((PetscObject)C),PETSC_ERR_PLIB,"Product data not empty"); 1446718818eSStefano Zampini A = C->product->A; 1456718818eSStefano Zampini R = C->product->B; 1468d45306eSHong Zhang ierr = MatTranspose(R,MAT_INITIAL_MATRIX,&Rt);CHKERRQ(ierr); 1474222ddf1SHong Zhang /* product->Dwork is used to store A*Rt in MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ() */ 1486718818eSStefano Zampini ierr = MatMatMatMultSymbolic_MPIAIJ_MPIAIJ_MPIAIJ(R,A,Rt,C->product->fill,C);CHKERRQ(ierr); 1494222ddf1SHong Zhang C->ops->productnumeric = MatProductNumeric_RARt_MPIAIJ_MPIAIJ; 1504222ddf1SHong Zhang 1514222ddf1SHong Zhang /* create a supporting struct */ 1524222ddf1SHong Zhang ierr = PetscNew(&rart);CHKERRQ(ierr); 1534222ddf1SHong Zhang rart->Rt = Rt; 1546718818eSStefano Zampini rart->data = C->product->data; 1556718818eSStefano Zampini rart->destroy = C->product->destroy; 1566718818eSStefano Zampini C->product->data = rart; 1576718818eSStefano Zampini C->product->destroy = MatDestroy_MPIAIJ_RARt; 1588d45306eSHong Zhang PetscFunctionReturn(0); 1598d45306eSHong Zhang } 160