<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Tue, Oct 17, 2017 at 8:16 AM, Jed Brown <span dir="ltr"><<a href="mailto:jed@jedbrown.org" target="_blank">jed@jedbrown.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">Stefano Zampini <<a href="mailto:stefano.zampini@gmail.com">stefano.zampini@gmail.com</a>> writes:<br>
<br>
>> ><br>
>> ><br>
>> >> In case of multiple objectives, there may be a performance reason to<br>
>> >> amortize evaluation of several at once, though the list interface is<br>
>> >> convenient. Consider common objectives being quantities like lift and<br>
>> >> drag on different surfaces of a fluids simulation or stress/strain at<br>
>> >> certain critical joints in a structure. Although these have some<br>
>> >> locality, it's reasonable to assume that state dependence will have<br>
>> >> quickly become global, thus make no attempt to handle sparse<br>
>> >> representations of the adjoint vectors lambda.<br>
>> >><br>
>> >><br>
>> > I don't get this comment. Is it related with multi-objective optimization<br>
>> > (e.g. Pareto)?<br>
>><br>
>> Adjoints are usually preferred any time you are differentiating a small<br>
>> number of output variables with respect to a large number of inputs. It<br>
>> could be for multi-objective optimization, but it's every bit as<br>
>> relevant for physical sensitivities.<br>
>><br>
>><br>
> If we are not talking about Pareto optimization, and thus we don't need a<br>
> separate output from each function, then users can pass a single function<br>
> that computes all the quantities they need at the same time. Anyway, I<br>
> don't mind having a single callback for multiple functions.<br>
<br>
</span>I don't follow why multi-objective optimization would be any different.<br>
Are you supposing that the different objective functions would be<br>
implemented by different software packages?<br>
<span class=""><br>
>> >> How are parameters accessed in TSComputeRHSFunction? It looks like<br>
>> >> they're coming out of the context. Why should this be different? (If<br>
>> >> parameters need to go into a Vec, we could do that, but it comes at a<br>
>> >> readability and possibly parallel cost if the global Vec needs to be<br>
>> >> communicated to local vectors.)<br>
>> >><br>
>> >><br>
>> > design paramaters are fixed troughout an adjoint/tlm run. They can be<br>
>> > communicated locally once at the beginning of the run.<br>
>> > This is what TSSetUpFromDesign and TSSetSetUpFromDesign are supposed to<br>
>> > handle, if I get your comment.<br>
>><br>
>> My point is that users currently get design parameters out of the<br>
>> context when evaluating their RHSFunction and friends. If that is the<br>
>> endorsed way to access design variables, then your new function doesn't<br>
>> need to pass the vector. If you need to pass the parameter vector in<br>
>> that one function, instead of obtaining them from the context, then<br>
>> you'd need to pass the parameter vector everywhere and discourage using<br>
>> the context for active design variables. I think there are merits to<br>
>> both approaches, but it absolutely needs to be consistent.<br>
>><br>
><br>
> So, to be consistent, we have to force users to perform an operation in a<br>
> single way?<br>
> Yes, TSSetUpFromDesign is among the last things I have added, and allows to<br>
> update the application context (among other things, as it is very general).<br>
> I can remove the parameter vector from TSEvalGradientDAE and<br>
> TSEvalGradientIC; however, having these vectors there makes it clear that<br>
> we allow non-linear dependency on the parameters too.<br>
<br>
</span>There are a bunch of other places that allow nonlinear dependence on<br>
parameters yet don't pass that parameter Vec, including<br>
TSSetRHSFunction. If it is passed explicitly in one such function, it<br>
needs to be passed explicitly in all.<br>
<span class=""><br>
> I can add a comment on the man pages that the vectors are guaranteed<br>
> to be the same one passed in my TSSetUpFromDesign, or remove<br>
> them. Your call.<br>
<br>
</span>It's a recipe for confusion. Either the parameters are never passed<br>
explicitly or they are always passed explicitly and should not be stored<br>
redundantly in the context, thus perhaps enabling some sort of higher<br>
level analysis that dynamically changes parameter values. I would go<br>
with the former for now.</blockquote><div><br></div><div>I want to say again how much I dislike ad hoc memory layouts through contexts</div><div>and the like. We have a perfectly good layout descriptor (DM) that should be used</div><div>to describe data layout.</div><div><br></div><div> Matt</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class=""><br>
> Users can do anything they want with the forward model context, but they<br>
> are not free to change the application context of the adjoints TS. Maybe<br>
> this should be improved by adding and extra slot to AdjointTSCtx to carry<br>
> over the user context (for the adjoint I mean)?<br>
<br>
</span>Why do you need to own the application context for the adjoint TS,<br>
versus using the context parameters to TSSetRHSJacobian, etc.<br>
<br>
>> > <a href="https://bitbucket.org/petsc/petsc/src/c2e9112e7fdfd89985f9ffc4d68b0d" rel="noreferrer" target="_blank">https://bitbucket.org/petsc/<wbr>petsc/src/<wbr>c2e9112e7fdfd89985f9ffc4d68b0d</a><br>
>> 46cf7cad52/src/ts/interface/<wbr>tspdeconstrainedutils.c?at=<br>
>> stefano_zampini%2Ffeature-<wbr>continuousadjoint&fileviewer=<wbr>file-view-default#<br>
<span class="">>> tspdeconstrainedutils.c-579<br>
>> ><br>
>> > Here is how ex23.c uses it<br>
>> ><br>
>> > <a href="https://bitbucket.org/petsc/petsc/src/c2e9112e7fdfd89985f9ffc4d68b0d" rel="noreferrer" target="_blank">https://bitbucket.org/petsc/<wbr>petsc/src/<wbr>c2e9112e7fdfd89985f9ffc4d68b0d</a><br>
>> 46cf7cad52/src/ts/examples/<wbr>tutorials/ex23.c?at=stefano_<wbr>zampini%2Ffeature-<br>
>> continuousadjoint&fileviewer=<wbr>file-view-default#ex23.c-677<br>
>><br>
>> And yet you redo the scatter here instead of using what you stuffed into<br>
>> the context. If you needed to redo it for correctness, you'd also need<br>
>> to in every other function that accesses design parameters.<br>
>><br>
> <a href="https://bitbucket.org/petsc/petsc/src/c2e9112e7fdfd89985f9ffc4d68b0d" rel="noreferrer" target="_blank">https://bitbucket.org/petsc/<wbr>petsc/src/<wbr>c2e9112e7fdfd89985f9ffc4d68b0d</a><br>
>> 46cf7cad52/src/ts/examples/<wbr>tutorials/ex23.c?at=stefano_<wbr>zampini%2Ffeature-<br>
>> continuousadjoint&fileviewer=<wbr>file-view-default#ex23.c-274<br>
>><br>
>><br>
> This is a leftover from a previous version of the code (there's also a<br>
> comment) that was not using TSSetSetUpFromDesign and it's definitely not<br>
> needed.<br>
<br>
</span>Comments that some lines of code can be deleted is a good sign that they<br>
should be deleted.<br>
<span class=""><br>
>> >> > Both methods need the Jacobian of the DAE wrt the parameters: H<br>
>> >> > TSAdjointSetRHSJacobian(), S TSSetGradientDAE()<br>
>> >> ><br>
>> >> > Initial condition dependence on the parameters is implicitly computed<br>
>> in<br>
>> >> > Hong's code (limited to linear dependence on all the variables);<br>
>> >><br>
>> >> How so? Once the user gets \lambda(time=0), they can apply the chain<br>
>> >> rule to produce any dependency on the parameter vector?<br>
>> >><br>
>> >> Yes, the chain rule is implemented here<br>
>> ><br>
>> > <a href="https://bitbucket.org/petsc/petsc/src/c2e9112e7fdfd89985f9ffc4d68b0d" rel="noreferrer" target="_blank">https://bitbucket.org/petsc/<wbr>petsc/src/<wbr>c2e9112e7fdfd89985f9ffc4d68b0d</a><br>
>> 46cf7cad52/src/ts/interface/<wbr>tspdeconstrainedutils.c?at=<br>
>> stefano_zampini%2Ffeature-<wbr>continuousadjoint&fileviewer=<wbr>file-view-default#<br>
>> tspdeconstrainedutils.c-254<br>
>><br>
>> I know you have a callback for it, but Hong's interface is plenty<br>
>> functional for such systems, they just call that derivative instead of<br>
>> writing and registering a function to do that.<br>
>><br>
><br>
> I'm not saying HOng's interface is not functional.<br>
<br>
</span>I was responding to your statement that "Initial condition dependence on<br>
the parameters is limited to linear dependence on all the variables" in<br>
his approach. General dependence is supported, the user is just<br>
expected to call it themselves rather than registering a callback that<br>
TS calls.<br>
<span class=""><br>
> The initial condition gradients allow to automatize the process in<br>
> TSComputeObjectiveAndGradient(<wbr>), TSComputeHessian(), and<br>
> MatMult_Propagator(). Anyway, the lambda variables are not modified by<br>
> AdjointTSComputeFinalGradient(<wbr>) (that adds the IC dependency) and<br>
> users can do whatever they want with them.<br>
><br>
> I know you don't like TSComputeObjectiveAndGradient(<wbr>),<br>
<br>
</span>I don't have a problem with the concept but don't want to rely on it.<br>
I'd rather discuss how to unify interfaces for discrete and continuous<br>
adjoints and get a PR for it merged before adding higher level<br>
interfaces.<br>
<span class=""><br>
> but it's a code that anyway users have to write to compute a gradient<br>
> of the DAE not arising from a PDAE. How can this be automatized for<br>
> PDAEs? Should we store the AdjointTS inside the model TS and use<br>
> TSGetAdjointTS(ts,&ts->adjts) with<br>
<br>
</span>I see reasons for the adjoint TS to hold a reference to the forward TS,<br>
but not vice-versa. What is the use case for your proposal below?<br>
<div class="HOEnZb"><div class="h5"><br>
> TSGetAdjointTS(TS f,TS* a) {<br>
> if (!f->adjtts) TSCreateAdjointsTS(f,&f-><wbr>adjts);<br>
> *a = f->adjts:<br>
> }<br>
><br>
> and the corresponding Setter to allow users to do<br>
><br>
> TSCreateAdjointTS(ts,&atts)<br>
> TSSetRHSJacobian(ats,...)<br>
> TSSetAdjointTS(ts,ats)<br>
><br>
> or<br>
><br>
> TSGetAdjointTS(ts,&atts)<br>
> TSSetRHSJacobian(ats,...)<br>
><br>
><br>
> --<br>
> Stefano<br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div>What most experimenters take for granted before they begin their experiments is infinitely more interesting than any results to which their experiments lead.<br>-- Norbert Wiener</div><div><br></div><div><a href="http://www.caam.rice.edu/~mk51/" target="_blank">https://www.cse.buffalo.edu/~knepley/</a><br></div></div></div></div></div>
</div></div>