<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, 27 Mar 2020 at 05:09, <a href="mailto:hong@aspiritech.org">hong@aspiritech.org</a> <<a href="mailto:hong@aspiritech.org">hong@aspiritech.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Lisandro,<br></div><div dir="ltr"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_quote"><div>As I said in previous emails, I'm not complaining about the API, I said it was a welcome adition. All I'm asking is:</div><div><br></div><div>1)  Fix the handling of reference counting. This is an implementation detail, not really an API change.</div></div></div></blockquote><div>I'm creating a branch from master and patch it with your suggestions on reference counting.</div></div></div></div></div></blockquote><div><br></div><div>OK, thanks!</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_quote"><div dir="ltr"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_quote"><div><br></div><div>2) Add a simple new routine to the API, MatProductReset(D)  [or maybe name it MatProductClear(D) ], that should throw away all of the D->product stuff to release memory related to the product algorithm implementation. After calling MatProductReset(D), you cannot call anymore MatProductNumeric().</div></div></div></blockquote><div>Do you mean adding a public function MatProductClear(D) to clear internal data structure 'product' attached to D? </div><div>For example, after destroy A and B, user should call  MatProductClear(D), i.e.,</div><div>MatDestroy(&A) ;</div><div>MatDestroy(&B) ;<br></div><div>MatProductClear(D); // throw away all of the D->product stuff, thus D becomes a standard matrix<br></div><div><br></div></div></div></div></div></blockquote><div><br></div><div>Exactly. MatProductClear(D) should make D a standard matrix and discard all of the internal product stuff.</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_quote"><div dir="ltr"><div class="gmail_quote"><div></div><div>I understand that you are concerned about the dangling pointers. However, most users compute D =A*B, then destroy A, B and D separately in random order. Do we require user to call MatProductClear(D) after A or B is destroyed? </div></div></div></div></div></blockquote><div><br></div><div>No, MatProductClear() should not be required. I would code MatProductClear(D) to be a non-op if D does not have the internal product stuff. Then I would always call MatProductClear(D) in MatDestroy(&D) .</div><div><br></div><div>Of course, all that assuming that MatProductCreate() makes D take ownership (increment refcount) of A and B (and C if given). This way it does not really matter the order in which users destroy A,B, and D.</div><div><br></div><div>As I said before, look at PCReset() and PCDestroy(). MatProcuctClear() should work similarly as the Reset() routine.</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_quote"><div dir="ltr"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><br></div><div>3) For MatProduct, I consider</div><div>MatProductSetFromOptions() is logically equivalent to MatSetFromOptions(), <br></div><div>MatProductSymbolic() is logically equivalent to MatSetUp(),</div><div>and</div><div>MatProductNumeric() assembles the matproduct  D repeatedly when A or B are updated.</div><div><br></div></div></blockquote><div><br></div><div>OK, so... your point it that what looks like "setup" code in MatProductSetFromOptions() is just some minimal stuff required to actually dispatch the SetFromOptions_typeA_typeB routine, right? In that case, you are right, no changes/refactors needed here.</div></div></div></blockquote><div>Yes,  MatProductSetFromOptions() only dispatches SetFromOptions_typeA_typeB_producttype() which handles local options and polymorphism. The organization of new API is described at the top of petsc/src/mat/interface/matproduct.c.</div><div><br></div></div></div></div></div></blockquote><div><br></div><div>OK, all good with that one.</div><div><br></div><div>Regards,</div><div><br></div></div>-- <br><div dir="ltr" class="gmail_signature"><div dir="ltr"><div>Lisandro Dalcin<br>============<br>Research Scientist<br>Extreme Computing Research Center (ECRC)<br>King Abdullah University of Science and Technology (KAUST)<br><a href="http://ecrc.kaust.edu.sa/" target="_blank">http://ecrc.kaust.edu.sa/</a><br></div></div></div></div>