18949adfdSHong Zhang 28949adfdSHong Zhang /* 38949adfdSHong Zhang Defines matrix-matrix product routines for pairs of MPIAIJ matrices 48949adfdSHong Zhang C = A^T * B 58949adfdSHong Zhang The routines are slightly modified from MatTransposeMatMultxxx_SeqAIJ_SeqDense(). 68949adfdSHong Zhang */ 78949adfdSHong Zhang #include <../src/mat/impls/aij/seq/aij.h> /*I "petscmat.h" I*/ 88949adfdSHong Zhang #include <../src/mat/impls/aij/mpi/mpiaij.h> 98949adfdSHong Zhang #include <../src/mat/impls/dense/mpi/mpidense.h> 108949adfdSHong Zhang 119371c9d4SSatish Balay PetscErrorCode MatDestroy_MPIDense_MatTransMatMult(void *data) { 126718818eSStefano Zampini Mat_MatTransMatMult *atb = (Mat_MatTransMatMult *)data; 138949adfdSHong Zhang 148949adfdSHong Zhang PetscFunctionBegin; 159566063dSJacob Faibussowitsch PetscCall(MatDestroy(&atb->mA)); 169566063dSJacob Faibussowitsch PetscCall(VecDestroy(&atb->bt)); 179566063dSJacob Faibussowitsch PetscCall(VecDestroy(&atb->ct)); 189566063dSJacob Faibussowitsch PetscCall(PetscFree(atb)); 198949adfdSHong Zhang PetscFunctionReturn(0); 208949adfdSHong Zhang } 218949adfdSHong Zhang 226718818eSStefano Zampini static PetscErrorCode MatTransposeMatMultNumeric_MPIAIJ_MPIDense(Mat, Mat, Mat); 236718818eSStefano Zampini 249371c9d4SSatish Balay PETSC_INTERN PetscErrorCode MatTransposeMatMultSymbolic_MPIAIJ_MPIDense(Mat A, Mat B, PetscReal fill, Mat C) { 258949adfdSHong Zhang Mat_MatTransMatMult *atb; 266718818eSStefano Zampini PetscBool cisdense; 278949adfdSHong Zhang 288949adfdSHong Zhang PetscFunctionBegin; 296718818eSStefano Zampini MatCheckProduct(C, 4); 3028b400f6SJacob Faibussowitsch PetscCheck(!C->product->data, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Extra product struct not empty"); 318949adfdSHong Zhang 328949adfdSHong Zhang /* create output dense matrix C = A^T*B */ 339566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, A->cmap->n, B->cmap->n, A->cmap->N, B->cmap->N)); 349566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)C, &cisdense, MATMPIDENSE, MATMPIDENSECUDA, "")); 35*48a46eb9SPierre Jolivet if (!cisdense) PetscCall(MatSetType(C, ((PetscObject)B)->type_name)); 369566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 378949adfdSHong Zhang 386718818eSStefano Zampini /* create additional data structure for the product */ 399566063dSJacob Faibussowitsch PetscCall(PetscNew(&atb)); 406718818eSStefano Zampini if (B->cmap->N) { 419566063dSJacob Faibussowitsch PetscCall(MatCreateMAIJ(A, B->cmap->N, &atb->mA)); 42445ca090SPierre Jolivet if (!atb->mA->assembled) { 439566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(atb->mA, MAT_FINAL_ASSEMBLY)); 449566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(atb->mA, MAT_FINAL_ASSEMBLY)); 45445ca090SPierre Jolivet } 469566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(atb->mA, &atb->ct, &atb->bt)); 476718818eSStefano Zampini } 486718818eSStefano Zampini C->product->data = atb; 496718818eSStefano Zampini C->product->destroy = MatDestroy_MPIDense_MatTransMatMult; 508949adfdSHong Zhang 514222ddf1SHong Zhang C->ops->transposematmultnumeric = MatTransposeMatMultNumeric_MPIAIJ_MPIDense; 528949adfdSHong Zhang PetscFunctionReturn(0); 538949adfdSHong Zhang } 548949adfdSHong Zhang 559371c9d4SSatish Balay static PetscErrorCode MatTransposeMatMultNumeric_MPIAIJ_MPIDense(Mat A, Mat B, Mat C) { 561683a169SBarry Smith const PetscScalar *Barray, *ctarray; 571683a169SBarry Smith PetscScalar *Carray, *btarray; 58b45e3bf4SStefano Zampini PetscInt i, j, m = A->rmap->n, n = A->cmap->n, ldb, BN = B->cmap->N, ldc; 596718818eSStefano Zampini Mat_MatTransMatMult *atb; 606718818eSStefano Zampini Vec bt, ct; 618949adfdSHong Zhang 628949adfdSHong Zhang PetscFunctionBegin; 636718818eSStefano Zampini MatCheckProduct(C, 3); 646718818eSStefano Zampini atb = (Mat_MatTransMatMult *)C->product->data; 6508401ef6SPierre Jolivet PetscCheck(atb, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Missing product struct"); 666718818eSStefano Zampini if (!BN) { 679566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(C, MAT_FINAL_ASSEMBLY)); 689566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(C, MAT_FINAL_ASSEMBLY)); 696718818eSStefano Zampini PetscFunctionReturn(0); 706718818eSStefano Zampini } 716718818eSStefano Zampini bt = atb->bt; 726718818eSStefano Zampini ct = atb->ct; 738949adfdSHong Zhang 74b45e3bf4SStefano Zampini /* transpose local array of B, then copy it to vector bt */ 759566063dSJacob Faibussowitsch PetscCall(MatDenseGetArrayRead(B, &Barray)); 769566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(B, &ldb)); 779566063dSJacob Faibussowitsch PetscCall(VecGetArray(bt, &btarray)); 78b45e3bf4SStefano Zampini for (j = 0; j < BN; j++) 799371c9d4SSatish Balay for (i = 0; i < m; i++) btarray[i * BN + j] = Barray[j * ldb + i]; 809566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(bt, &btarray)); 819566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArrayRead(B, &Barray)); 828949adfdSHong Zhang 838949adfdSHong Zhang /* compute ct = mA^T * cb */ 849566063dSJacob Faibussowitsch PetscCall(MatMultTranspose(atb->mA, bt, ct)); 858949adfdSHong Zhang 86905b3b74SHong Zhang /* transpose local array of ct to matrix C */ 879566063dSJacob Faibussowitsch PetscCall(MatDenseGetArray(C, &Carray)); 889566063dSJacob Faibussowitsch PetscCall(MatDenseGetLDA(C, &ldc)); 899566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(ct, &ctarray)); 90b45e3bf4SStefano Zampini for (j = 0; j < BN; j++) 919371c9d4SSatish Balay for (i = 0; i < n; i++) Carray[j * ldc + i] = ctarray[i * BN + j]; 929566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(ct, &ctarray)); 939566063dSJacob Faibussowitsch PetscCall(MatDenseRestoreArray(C, &Carray)); 949566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(C, MAT_FINAL_ASSEMBLY)); 959566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(C, MAT_FINAL_ASSEMBLY)); 968949adfdSHong Zhang PetscFunctionReturn(0); 978949adfdSHong Zhang } 98