xref: /petsc/src/mat/impls/aij/mpi/mpimattransposematmult.c (revision 48a46eb9bd028bec07ec0f396b1a3abb43f14558)
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