Dear Barry:<br><br>Thank you for your reply. Generally, for security, after I do some matrix operations by calling some functions in PETSc, I should call the assembly functions based on your advice. Whether is there a mechanism/method that the users should always call assembly functions but the code will judge whether it&nbsp;should&nbsp;do&nbsp;the&nbsp;assembly?&nbsp;If&nbsp;there&nbsp;is,&nbsp;I&nbsp;think&nbsp;that&nbsp;it&nbsp;should&nbsp;save&nbsp;some&nbsp;time&nbsp;:).<br>
 <br>Regards,<br>Yujie<br><br><div><span class="gmail_quote">On 3/3/08, <b class="gmail_sendername">Barry Smith</b> &lt;<a href="mailto:bsmith@mcs.anl.gov">bsmith@mcs.anl.gov</a>&gt; wrote:</span><blockquote class="gmail_quote" style="margin-top: 0; margin-right: 0; margin-bottom: 0; margin-left: 0; margin-left: 0.80ex; border-left-color: #cccccc; border-left-width: 1px; border-left-style: solid; padding-left: 1ex">
<div><div><br></div>&nbsp;&nbsp;Based on your comments I have simplified and improved the code slightly it is now<div><span class="q"><div>PetscErrorCode MatMatMultNumeric_MPIDense_MPIAIJ(Mat A,Mat B,Mat C)</div></span><div>{</div>
<div>&nbsp;&nbsp;PetscErrorCode &nbsp; &nbsp; ierr;</div><div>&nbsp;&nbsp;Mat &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;At,Bt,Ct;</div><div><br></div><div>&nbsp;&nbsp;PetscFunctionBegin;</div><span class="q"><div>&nbsp;&nbsp;ierr = MatTranspose(A,MAT_INITIAL_MATRIX,&amp;At);CHKERRQ(ierr);</div></span><span class="q"><div>
&nbsp;&nbsp;ierr = MatTranspose(B,MAT_INITIAL_MATRIX,&amp;Bt);CHKERRQ(ierr);</div></span><span class="q"><div>&nbsp;&nbsp;ierr = MatMatMult(Bt,At,MAT_INITIAL_MATRIX,1.0,&amp;Ct);CHKERRQ(ierr);</div></span><span class="q"><div>&nbsp;&nbsp;ierr = MatDestroy(At);CHKERRQ(ierr);</div>
</span><span class="q"><div>&nbsp;&nbsp;ierr = MatDestroy(Bt);CHKERRQ(ierr);</div></span><span class="q"><div>&nbsp;&nbsp;ierr = MatTranspose(Ct,MAT_REUSE_MATRIX,&amp;C);CHKERRQ(ierr);</div></span><span class="q"><div>&nbsp;&nbsp;ierr = MatDestroy(Ct);CHKERRQ(ierr);</div>
</span><div>&nbsp;&nbsp;PetscFunctionReturn(0);</div><div>}</div><div><br></div><div>#undef __FUNCT__</div><div>#define __FUNCT__ &quot;MatMatMultSymbolic_MPIDense_MPIAIJ&quot;</div><div>PetscErrorCode MatMatMultSymbolic_MPIDense_MPIAIJ(Mat A,Mat B,PetscReal fill,Mat *C)</div>
<div>{</div><div>&nbsp;&nbsp;PetscErrorCode ierr;</div><div>&nbsp;&nbsp;PetscInt &nbsp; &nbsp; &nbsp; m=A-&gt;rmap.n,n=B-&gt;cmap.n;</div><div>&nbsp;&nbsp;Mat &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Cmat;</div><div><br></div><div>&nbsp;&nbsp;PetscFunctionBegin;</div><div>&nbsp;&nbsp;if (A-&gt;cmap.n != B-&gt;rmap.n) SETERRQ2(PETSC_ERR_ARG_SIZ,&quot;A-&gt;cmap.n %d != B-&gt;rmap.n %d\n&quot;,A-&gt;cmap.n,B-&gt;rmap.n);</div>
<div>&nbsp;&nbsp;ierr = MatCreate(A-&gt;hdr.comm,&amp;Cmat);CHKERRQ(ierr);</div><div>&nbsp;&nbsp;ierr = MatSetSizes(Cmat,m,n,PETSC_DETERMINE,PETSC_DETERMINE);CHKERRQ(ierr);</div><div>&nbsp;&nbsp;ierr = MatSetType(Cmat,MATMPIDENSE);CHKERRQ(ierr);</div>
<div>&nbsp;&nbsp;ierr = MatMPIDenseSetPreallocation(Cmat,PETSC_NULL);CHKERRQ(ierr);</div><div>&nbsp;&nbsp;ierr = MatAssemblyBegin(Cmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);</div><div>&nbsp;&nbsp;ierr = MatAssemblyEnd(Cmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);</div>
<div>&nbsp;&nbsp;*C &nbsp; = Cmat;</div><div>&nbsp;&nbsp;PetscFunctionReturn(0);</div><div>}</div><div><br></div><div>As you note there was no need to call the assembly after the transpose. It is, needed, in general where I put it</div><div>in the symbolic portion of the code. (You could avoid it by directly setting some flags in the Cmat object</div>
<div>but it is better to do the right thing and call the assembly (which is free in terms of time anyways compare to the</div><div>numerical calculations).</div><div><br></div><span class="sg"><div>&nbsp;&nbsp; Barry</div></span><div>
<span class="e" id="q_11875a469d88cd5b_12"><div><br></div><div><div>On Mar 3, 2008, at 10:59 AM, Yujie wrote:</div><br><blockquote type="cite">Dear Barry:<br><br>Why do you call these two functions in your code? Because I have realized the same method with yours to calculate MPIDENSE_MPIAIJ. However, I didn&#39;t call&nbsp;MatAssemblyBegin and MatAssemblyEnd&nbsp;after&nbsp;I&nbsp;call&nbsp;MatTranspose&nbsp;for&nbsp;matrix&nbsp;C. <br>
 In application, sometimes  I don&#39;t know what do the functions&nbsp;I&nbsp;call in PETSc do? So,&nbsp;I&nbsp;don&#39;t&nbsp;know&nbsp;whether&nbsp;I should call&nbsp;these&nbsp;two&nbsp;functions&nbsp;although&nbsp;you&nbsp;give&nbsp;me&nbsp;these&nbsp;conditions.&nbsp;Regarding&nbsp;this&nbsp;example,&nbsp;which&nbsp;condition&nbsp;should&nbsp;it&nbsp;belong&nbsp;to?&nbsp;thanks&nbsp;a&nbsp;lot.<br>
<br>Regards,<br>Yujie&nbsp;&nbsp;<br><br><div><span class="gmail_quote">On 3/3/08, <b class="gmail_sendername">Barry Smith</b> &lt;<a href="mailto:bsmith@mcs.anl.gov" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">bsmith@mcs.anl.gov</a>&gt; wrote:</span><blockquote class="gmail_quote" style="margin-top: 0; margin-right: 0; margin-bottom: 0; margin-left: 0; margin-left: 0.80ex; border-left-color: #cccccc; border-left-width: 1px; border-left-style: solid; padding-left: 1ex">
<br>&nbsp;&nbsp;&nbsp;&nbsp;MatAssembly does<br> 1) moves any values set on one process that belongs on another<br> 2) finalizes the sparse matrix data structure (for example takes any<br> holes out of the CSR format)<br>&nbsp;&nbsp;&nbsp;&nbsp; doesn&#39;t need to do this for dense matrices<br>
 3) sets up whatever VecScatters that are need to do matrix vector<br> products<br> 4) marks the matrix as assembled and ready to be used<br><br><br>&nbsp;&nbsp;&nbsp;&nbsp;Barry<br><br><br> On Mar 2, 2008, at 11:47 PM, Yujie wrote:<br><br> &gt; Hi, everyone<br>
 &gt;<br> &gt; I just check the codes added by Barry for MPIDENSE_MPIAIJ. The codes<br> &gt; is as follows. I am wondering what context one may call<br> &gt; MatAssemblyBegin and MatAssemblyEnd?<br> &gt; From the webpage, I can find some information about two functions:<br>
 &gt; &quot;Begins assembling the matrix. This routine should be called after<br> &gt; completing all calls to MatSetValues().&quot;<br> &gt; I mean that I don&#39;t know how to judge whether I should call two<br> &gt; functions. Could you give me some advice? thanks a lot.<br>
 &gt;<br> &gt; 4723 */<br> &gt; 4724 PetscErrorCode MatMatMultNumeric_MPIDense_MPIAIJ(Mat A,Mat<br> &gt; B,Mat C)<br> &gt; 4725 {<br> &gt; 4726 PetscErrorCode ierr;<br> &gt; 4727 Mat_MPIDense *sub_c = (Mat_MPIDense*)C-&gt;data;<br>
 &gt; 4728 Mat At,Bt,Ct;<br> &gt; 4729<br> &gt; 4730 PetscFunctionBegin;<br> &gt; 4731 ierr = MatTranspose(A,MAT_INITIAL_MATRIX,&amp;At);CHKERRQ(ierr);<br> &gt; 4732 ierr = MatTranspose(B,MAT_INITIAL_MATRIX,&amp;Bt);CHKERRQ(ierr);<br>
 &gt; 4733 ierr = MatMatMult(Bt,At,MAT_INITIAL_MATRIX,<br> &gt; 1.0,&amp;Ct);CHKERRQ(ierr);<br> &gt; 4734 ierr = MatDestroy(At);CHKERRQ(ierr);<br> &gt; 4735 ierr = MatDestroy(Bt);CHKERRQ(ierr);<br> &gt; 4736 ierr = MatTranspose(Ct,MAT_REUSE_MATRIX,&amp;C);CHKERRQ(ierr);<br>
 &gt; 4737 ierr = MatDestroy(Ct);CHKERRQ(ierr);<br> &gt; 4738<br> &gt; 4739 C-&gt;assembled = PETSC_TRUE;<br> &gt; 4740 ierr = MatAssemblyBegin(sub_c-<br> &gt; &gt;A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);<br> &gt; 4741 ierr = MatAssemblyEnd(sub_c-&gt;A,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr);<br>
 &gt; 4742 if (!C-&gt;was_assembled) {<br> &gt; 4743 ierr = MatSetUpMultiply_MPIDense(C);CHKERRQ(ierr);<br> &gt; 4744 }<br> &gt; 4745 PetscFunctionReturn(0);<br> &gt; 4746 }<br> &gt;<br> &gt;<br> &gt;<br> &gt; Regards,<br>
 &gt; Yujie<br><br></blockquote></div><br></blockquote></div><br></span></div></div></div></blockquote></div><br>