xref: /petsc/src/mat/impls/aij/seq/mattransposematmult.c (revision 7a3c3d58f0dc30013810dc66cc68344148a68c77)
17a94429cSHong Zhang 
27a94429cSHong Zhang /*
32cff0574SHong Zhang   Defines matrix-matrix product routines
47a94429cSHong Zhang           C = A^T * B
57a94429cSHong Zhang */
67a94429cSHong Zhang 
77a94429cSHong Zhang #include <../src/mat/impls/aij/seq/aij.h> /*I "petscmat.h" I*/
8afea5027SHong Zhang #include <../src/mat/impls/dense/seq/dense.h>
9afea5027SHong Zhang 
10afea5027SHong Zhang PetscErrorCode MatDestroy_SeqDense_MatTransMatMult(Mat A)
11afea5027SHong Zhang {
12afea5027SHong Zhang   PetscErrorCode      ierr;
13afea5027SHong Zhang   Mat_SeqDense        *a = (Mat_SeqDense*)A->data;
14afea5027SHong Zhang   Mat_MatTransMatMult *atb = a->atb;
15afea5027SHong Zhang 
16afea5027SHong Zhang   PetscFunctionBegin;
17afea5027SHong Zhang   ierr = MatDestroy(&atb->mA);CHKERRQ(ierr);
18afea5027SHong Zhang   ierr = VecDestroy(&atb->bt);CHKERRQ(ierr);
19afea5027SHong Zhang   ierr = VecDestroy(&atb->ct);CHKERRQ(ierr);
20afea5027SHong Zhang   ierr = (atb->destroy)(A);CHKERRQ(ierr);
21afea5027SHong Zhang   ierr = PetscFree(atb);CHKERRQ(ierr);
22afea5027SHong Zhang   PetscFunctionReturn(0);
23afea5027SHong Zhang }
247a94429cSHong Zhang 
254222ddf1SHong Zhang PetscErrorCode MatTransposeMatMultSymbolic_SeqAIJ_SeqDense(Mat A,Mat B,PetscReal fill,Mat C)
26c608a817SHong Zhang {
27c608a817SHong Zhang   PetscErrorCode      ierr;
288949adfdSHong Zhang   PetscInt            m=A->rmap->n,n=A->cmap->n,BN=B->cmap->N;
297a94429cSHong Zhang   Mat_MatTransMatMult *atb;
307a94429cSHong Zhang   Vec                 bt,ct;
31afea5027SHong Zhang   Mat_SeqDense        *c;
32*7a3c3d58SStefano Zampini   PetscBool           cisdense;
337a94429cSHong Zhang 
347a94429cSHong Zhang   PetscFunctionBegin;
35b00a9115SJed Brown   ierr = PetscNew(&atb);CHKERRQ(ierr);
367a94429cSHong Zhang 
377a94429cSHong Zhang   /* create output dense matrix C = A^T*B */
384222ddf1SHong Zhang   ierr = MatSetSizes(C,n,BN,n,BN);CHKERRQ(ierr);
39*7a3c3d58SStefano Zampini   ierr = PetscObjectTypeCompareAny((PetscObject)C,&cisdense,MATSEQDENSE,MATSEQDENSECUDA,"");CHKERRQ(ierr);
40*7a3c3d58SStefano Zampini   if (!cisdense) {
41*7a3c3d58SStefano Zampini     ierr = MatSetType(C,((PetscObject)B)->type_name);CHKERRQ(ierr);
42*7a3c3d58SStefano Zampini   }
4318992e5dSStefano Zampini   ierr = MatSetUp(C);CHKERRQ(ierr);
447a94429cSHong Zhang 
457a94429cSHong Zhang   /* create vectors bt and ct to hold locally transposed arrays of B and C */
467a94429cSHong Zhang   ierr = VecCreate(PETSC_COMM_SELF,&bt);CHKERRQ(ierr);
47afea5027SHong Zhang   ierr = VecSetSizes(bt,m*BN,m*BN);CHKERRQ(ierr);
48*7a3c3d58SStefano Zampini   ierr = VecSetType(bt,A->defaultvectype);CHKERRQ(ierr);
497a94429cSHong Zhang   ierr = VecCreate(PETSC_COMM_SELF,&ct);CHKERRQ(ierr);
50afea5027SHong Zhang   ierr = VecSetSizes(ct,n*BN,n*BN);CHKERRQ(ierr);
51*7a3c3d58SStefano Zampini   ierr = VecSetType(ct,A->defaultvectype);CHKERRQ(ierr);
527a94429cSHong Zhang   atb->bt = bt;
537a94429cSHong Zhang   atb->ct = ct;
547a94429cSHong Zhang 
554222ddf1SHong Zhang   c                               = (Mat_SeqDense*)C->data;
56c608a817SHong Zhang   c->atb                          = atb;
574222ddf1SHong Zhang   atb->destroy                    = C->ops->destroy;
584222ddf1SHong Zhang   C->ops->destroy                 = MatDestroy_SeqDense_MatTransMatMult;
594222ddf1SHong Zhang   C->ops->transposematmultnumeric = MatTransposeMatMultNumeric_SeqAIJ_SeqDense;
60c608a817SHong Zhang   PetscFunctionReturn(0);
61c608a817SHong Zhang }
62c608a817SHong Zhang 
63c608a817SHong Zhang PetscErrorCode MatTransposeMatMultNumeric_SeqAIJ_SeqDense(Mat A,Mat B,Mat C)
64c608a817SHong Zhang {
65c608a817SHong Zhang   PetscErrorCode      ierr;
66c608a817SHong Zhang   PetscInt            i,j,k,m=A->rmap->n,n=A->cmap->n,BN=B->cmap->N;
671683a169SBarry Smith   const PetscScalar   *Barray,*ctarray;
681683a169SBarry Smith   PetscScalar         *Carray,*btarray;
69c608a817SHong Zhang   Mat_SeqDense        *c=(Mat_SeqDense*)C->data;
70c608a817SHong Zhang   Mat_MatTransMatMult *atb=c->atb;
71c608a817SHong Zhang   Vec                 bt=atb->bt,ct=atb->ct;
72c608a817SHong Zhang 
73c608a817SHong Zhang   PetscFunctionBegin;
74c608a817SHong Zhang   /* create MAIJ matrix mA from A -- should be done in symbolic phase */
75c608a817SHong Zhang   ierr = MatDestroy(&atb->mA);CHKERRQ(ierr);
76c608a817SHong Zhang   ierr = MatCreateMAIJ(A,BN,&atb->mA);CHKERRQ(ierr);
77c608a817SHong Zhang 
78*7a3c3d58SStefano Zampini   /* transpose local array of B, then copy it to vector bt */
791683a169SBarry Smith   ierr = MatDenseGetArrayRead(B,&Barray);CHKERRQ(ierr);
807a94429cSHong Zhang   ierr = VecGetArray(bt,&btarray);CHKERRQ(ierr);
817a94429cSHong Zhang 
827a94429cSHong Zhang   k=0;
83afea5027SHong Zhang   for (j=0; j<BN; j++) {
84afea5027SHong Zhang     for (i=0; i<m; i++) btarray[i*BN + j] = Barray[k++];
857a94429cSHong Zhang   }
867a94429cSHong Zhang   ierr = VecRestoreArray(bt,&btarray);CHKERRQ(ierr);
871683a169SBarry Smith   ierr = MatDenseRestoreArrayRead(B,&Barray);CHKERRQ(ierr);
887a94429cSHong Zhang 
897a94429cSHong Zhang   /* compute ct = mA^T * cb */
907a94429cSHong Zhang   ierr = MatMultTranspose(atb->mA,bt,ct);CHKERRQ(ierr);
917a94429cSHong Zhang 
92*7a3c3d58SStefano Zampini   /* transpose local array of ct to matrix C */
93c608a817SHong Zhang   ierr = MatDenseGetArray(C,&Carray);CHKERRQ(ierr);
941683a169SBarry Smith   ierr = VecGetArrayRead(ct,&ctarray);CHKERRQ(ierr);
957a94429cSHong Zhang   k = 0;
96afea5027SHong Zhang   for (j=0; j<BN; j++) {
97afea5027SHong Zhang     for (i=0; i<n; i++) Carray[k++] = ctarray[i*BN + j];
987a94429cSHong Zhang   }
991683a169SBarry Smith   ierr = VecRestoreArrayRead(ct,&ctarray);CHKERRQ(ierr);
100c608a817SHong Zhang   ierr = MatDenseRestoreArray(C,&Carray);CHKERRQ(ierr);
1017a94429cSHong Zhang   PetscFunctionReturn(0);
1027a94429cSHong Zhang }
103