Actual source code: mattransposematmult.c

petsc-3.12.5 2020-03-29
Report Typos and Errors

  2: /*
  3:   Defines matrix-matrix product routines 
  4:           C = A^T * B
  5: */

  7:  #include <../src/mat/impls/aij/seq/aij.h>
  8:  #include <../src/mat/impls/dense/seq/dense.h>

 10: PetscErrorCode MatDestroy_SeqDense_MatTransMatMult(Mat A)
 11: {
 12:   PetscErrorCode      ierr;
 13:   Mat_SeqDense        *a = (Mat_SeqDense*)A->data;
 14:   Mat_MatTransMatMult *atb = a->atb;

 17:   MatDestroy(&atb->mA);
 18:   VecDestroy(&atb->bt);
 19:   VecDestroy(&atb->ct);
 20:   (atb->destroy)(A);
 21:   PetscFree(atb);
 22:   return(0);
 23: }

 25: PetscErrorCode MatTransposeMatMult_SeqAIJ_SeqDense(Mat A,Mat B,MatReuse scall,PetscReal fill,Mat *C)
 26: {
 28: 
 30:   if (scall == MAT_INITIAL_MATRIX) {
 31:     PetscLogEventBegin(MAT_TransposeMatMultSymbolic,A,B,0,0);
 32:     MatTransposeMatMultSymbolic_SeqAIJ_SeqDense(A,B,fill,C);
 33:     PetscLogEventEnd(MAT_TransposeMatMultSymbolic,A,B,0,0);
 34:   }
 35:   PetscLogEventBegin(MAT_TransposeMatMultNumeric,A,B,0,0);
 36:   MatTransposeMatMultNumeric_SeqAIJ_SeqDense(A,B,*C);
 37:   PetscLogEventEnd(MAT_TransposeMatMultNumeric,A,B,0,0);
 38:   return(0);
 39: }

 41: PetscErrorCode MatTransposeMatMultSymbolic_SeqAIJ_SeqDense(Mat A,Mat B,PetscReal fill,Mat *C)
 42: {
 43:   PetscErrorCode      ierr;
 44:   PetscInt            m=A->rmap->n,n=A->cmap->n,BN=B->cmap->N;
 45:   Mat_MatTransMatMult *atb;
 46:   Mat                 Cdense;
 47:   Vec                 bt,ct;
 48:   Mat_SeqDense        *c;

 51:   PetscNew(&atb);

 53:   /* create output dense matrix C = A^T*B */
 54:   MatCreate(PETSC_COMM_SELF,&Cdense);
 55:   MatSetSizes(Cdense,n,BN,n,BN);
 56:   MatSetType(Cdense,MATSEQDENSE);
 57:   MatSeqDenseSetPreallocation(Cdense,NULL);

 59:   /* create vectors bt and ct to hold locally transposed arrays of B and C */
 60:   VecCreate(PETSC_COMM_SELF,&bt);
 61:   VecSetSizes(bt,m*BN,m*BN);
 62:   VecSetType(bt,VECSTANDARD);
 63:   VecCreate(PETSC_COMM_SELF,&ct);
 64:   VecSetSizes(ct,n*BN,n*BN);
 65:   VecSetType(ct,VECSTANDARD);
 66:   atb->bt = bt;
 67:   atb->ct = ct;

 69:   *C                   = Cdense;
 70:   c                    = (Mat_SeqDense*)Cdense->data;
 71:   c->atb               = atb;
 72:   atb->destroy         = Cdense->ops->destroy;
 73:   Cdense->ops->destroy = MatDestroy_SeqDense_MatTransMatMult;
 74:   return(0);
 75: }

 77: PetscErrorCode MatTransposeMatMultNumeric_SeqAIJ_SeqDense(Mat A,Mat B,Mat C)
 78: {
 79:   PetscErrorCode      ierr;
 80:   PetscInt            i,j,k,m=A->rmap->n,n=A->cmap->n,BN=B->cmap->N;
 81:   const PetscScalar   *Barray,*ctarray;
 82:   PetscScalar         *Carray,*btarray;
 83:   Mat_SeqDense        *c=(Mat_SeqDense*)C->data;
 84:   Mat_MatTransMatMult *atb=c->atb;
 85:   Vec                 bt=atb->bt,ct=atb->ct;

 88:   /* create MAIJ matrix mA from A -- should be done in symbolic phase */
 89:   MatDestroy(&atb->mA);
 90:   MatCreateMAIJ(A,BN,&atb->mA);

 92:   /* transpose local arry of B, then copy it to vector bt */
 93:   MatDenseGetArrayRead(B,&Barray);
 94:   VecGetArray(bt,&btarray);

 96:   k=0;
 97:   for (j=0; j<BN; j++) {
 98:     for (i=0; i<m; i++) btarray[i*BN + j] = Barray[k++];
 99:   }
100:   VecRestoreArray(bt,&btarray);
101:   MatDenseRestoreArrayRead(B,&Barray);
102: 
103:   /* compute ct = mA^T * cb */
104:   MatMultTranspose(atb->mA,bt,ct);

106:   /* transpose local arry of ct to matrix C */
107:   MatDenseGetArray(C,&Carray);
108:   VecGetArrayRead(ct,&ctarray);
109:   k = 0;
110:   for (j=0; j<BN; j++) {
111:     for (i=0; i<n; i++) Carray[k++] = ctarray[i*BN + j];
112:   }
113:   VecRestoreArrayRead(ct,&ctarray);
114:   MatDenseRestoreArray(C,&Carray);
115:   return(0);
116: }