update ad-level so it uses a circular flowgraph - #1079
Conversation
|
@WardBrian fyi the plan is to merge this, then |
|
@rybern fyi I set you as the reviewer since a lot of this is actually your code I just modified |
|
Great, I'll have a look tomorrow |
rybern
left a comment
There was a problem hiding this comment.
Looks good to me as long as those tests results are right, I didn't double check those.
One thing you could consider adding is an expect test showing that name collisions can happen with this approach. Maybe a program like
parameters {
real x;
real y;
}
model {
if (x > 1) {
int a = x;
y ~ normal(a, 1);
} else {
int a = 1; // a is AD but doesn't need to be
y ~ normal(a, 1);
}
}
so we can see the progress when we/if we fix that
| let rev_flowgraph, flowgraph_to_mir = | ||
| Monotone_framework.inverse_flowgraph_of_stmt stmt in | ||
| let fwd_flowgraph = Monotone_framework.reverse rev_flowgraph in | ||
| let (module Fwd_Flowgraph) = |
There was a problem hiding this comment.
Tiny nit: I'd call this Circular_Fwd_Flowgraph to distinguish it
| Eigen::Matrix<local_scalar_t__, -1, -1> X_tp1; | ||
| current_statement__ = 2; | ||
| assign(X_tp1, X_d, "assigning variable X_tp1"); | ||
| Eigen::Matrix<double, -1, -1> X_tp2; |
There was a problem hiding this comment.
Just to double check, looks like X_p is AD and X_tp1-X_tp7 are non-AD, is that right?
There was a problem hiding this comment.
X_tp1 is ad but the rest are not which, with lcm, is what we expect
Let's leave that till @VMatthijs puts in that PR |
|
Aight think we are good! @rybern Once test passes and you approve feel free to merge |
Summary
This is a fix for the ad-level optimization. There was a bug where the monotone framework was not continuously iterating in the minimum fixed point algorithm to find the set of variables that can be made into data. This led to the algorithm stopping too early and possibly producing non-compilable C++ such as for the following model
In the current impl the ad level optimization will think
X_tp1is an autodiff type butX_tp2is data. Since we can't assign autodiff variables to data variables this would throw a C++ compiler error.By connecting the end nodes to the initial nodes the minimum fixed point algorithm will continously run until no changes to the program are made. Now the above program deduces that since
X_tp1must be an autodiff typeX_tp2must be as well.In the test model you'll see that lazy code motion actually allows
X_tp2to still be data, but that's becauseexp(X_data)is stored in a local variable and the code becomes the equivalent ofSubmission Checklist
Release notes
bug fix for ad-level optimization
Copyright and Licensing
By submitting this pull request, the copyright holder is agreeing to
license the submitted work under the BSD 3-clause license (https://opensource.org/licenses/BSD-3-Clause)