<div dir="ltr"><div>From the current master, in MatMatTransposeMult we have</div><div><br></div><div>  fA = A->ops->mattransposemult;</div><div>  if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for A of type %s",((PetscObject)A)->type_name);</div><div>  fB = B->ops->mattransposemult;</div><div>  if (!fB) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatMatTransposeMult not supported for B of type %s",((PetscObject)B)->type_name);</div><div>  if (fB!=fA) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatMatTransposeMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);</div><div><br></div><div>  ierr = PetscLogEventBegin(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);</div><div>  if (scall == MAT_INITIAL_MATRIX) {</div><div>    ierr = PetscLogEventBegin(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);</div><div>    ierr = (*A->ops->mattransposemultsymbolic)(A,B,fill,C);CHKERRQ(ierr);</div><div>    ierr = PetscLogEventEnd(MAT_MatTransposeMultSymbolic,A,B,0,0);CHKERRQ(ierr);</div><div>  }</div><div>  ierr = PetscLogEventBegin(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);</div><div>  ierr = (*A->ops->mattransposemultnumeric)(A,B,*C);CHKERRQ(ierr);</div><div>  ierr = PetscLogEventEnd(MAT_MatTransposeMultNumeric,A,B,0,0);CHKERRQ(ierr);</div><div>  ierr = PetscLogEventEnd(MAT_MatTransposeMult,A,B,0,0);CHKERRQ(ierr);</div><div><br></div><div>Note that  neither A->ops->mattransposemult or B->ops->mattransposemult are used.</div><div><br></div><div>Instead, in MatTransposeMatMult we have </div><div><br></div><div><div>  fA = A->ops->transposematmult;</div><div>  fB = B->ops->transposematmult;</div><div>  if (fB==fA) {</div><div>    if (!fA) SETERRQ1(PetscObjectComm((PetscObject)A),PETSC_ERR_SUP,"MatTransposeMatMult not supported for A of type %s",((PetscObject)A)->type_name);</div><div>    transposematmult = fA;</div><div>  } else {</div><div>    /* dispatch based on the type of A and B from their PetscObject's PetscFunctionLists. */</div><div>    char multname[256];</div><div>    ierr = PetscStrcpy(multname,"MatTransposeMatMult_");CHKERRQ(ierr);</div><div>    ierr = PetscStrcat(multname,((PetscObject)A)->type_name);CHKERRQ(ierr);</div><div>    ierr = PetscStrcat(multname,"_");CHKERRQ(ierr);</div><div>    ierr = PetscStrcat(multname,((PetscObject)B)->type_name);CHKERRQ(ierr);</div><div>    ierr = PetscStrcat(multname,"_C");CHKERRQ(ierr); /* e.g., multname = "MatMatMult_seqdense_seqaij_C" */</div><div>    ierr = PetscObjectQueryFunction((PetscObject)B,multname,&transposematmult);CHKERRQ(ierr);</div><div>    if (!transposematmult) SETERRQ2(PetscObjectComm((PetscObject)A),PETSC_ERR_ARG_INCOMP,"MatTransposeMatMult requires A, %s, to be compatible with B, %s",((PetscObject)A)->type_name,((PetscObject)B)->type_name);</div><div>  }</div><div>  ierr = PetscLogEventBegin(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);</div><div>  ierr = (*transposematmult)(A,B,scall,fill,C);CHKERRQ(ierr);</div><div>  ierr = PetscLogEventEnd(MAT_TransposeMatMult,A,B,0,0);CHKERRQ(ierr);</div></div><div><br></div><div>I would be inclined to have MatMatTransposeMult to dispatch the same way MatTransposeMatMult does. Comments?</div><div><br></div><div> </div>--<div><div class="gmail_signature">Stefano</div>
</div></div>