-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add support for capturing data for any variable at runtime #355
Conversation
…mension and variable info
…ces buffer in model run loop
…ted by SDE in the generated model
…arIndex since these can't be saved as outputs like other variables
…o use the same var index used at code gen time (only for accessible variables)
Cool new change. I can definitely see how this will be useful for unit tests. |
I haven't reviewed the code, but I will comment on your description. This is not something I would use in my own work, but it's a big step toward duplicating the full functionality of Vensim. Having the giant switch statement off by default is important for me, since our models are so large. I would like to keep the text listing output. That's something I use a lot. I think the JSON output could replace YAML. I have some model analysis tools that use YAML, but they could use JSON instead. I agree that JSON is a better choice than YAML for model listings. |
Not a problem. Let me know if you mean "haven't reviewed yet" (in which case I'll await your review) or if you mean "unlikely to review".
Yes, same here. FWIW, I think I could get rid of the "giant switch statement" approach entirely if the code generator had support for pluggable/custom allocators (which I alluded to in a comment on the WebGPU feature). But that's a separate topic. For now, with the switch off, there's no impact on build or runtime performance.
Fair enough, all three are still available. Later (separate from this) we can drop the YAML output in favor of JSON, and we can keep the TXT output. |
Sounds good — I am unlikely to review the code itself. |
Fixes #105
@ToddFincannonEI: I'm finally getting around to submitting a PR for this feature that I started over 2 years ago. We've been using this branch in production (for En-ROADS and C-ROADS) for the past 6 months, so I think it's stable enough to merge into
main
.There are currently two use cases at CI where this feature comes in handy:
I realize this is a large PR, and there's no rush on reviewing it. We could wait to go through it together when we meet in person soon. I probably could've split the JSON listing part into its own PR, but it all kind of goes together so decided to leave it in.
I'll try to succinctly explain how it all fits together:
sde generate --list
now produces a JSON file in addition to the existing YAML and TXT outputs. I know we had talked about removing the YAML and TXT variants but I figure it's better to do that as a separate change since this one is already big enough.In that JSON file, for each variable, there is a
varIndex
field. ThisvarIndex
corresponds to the value that code gen emits in the newstoreOutput
function in the generated C code. For example, variableX
might have avarIndex
of 1. At runtime, the code that runs the model can request data for variableX
by using that index value of 1.The code gen outputs a giant switch statement in the generated C code that handles the mapping of
varIndex
values to the appropriate internal C variable (and handles access to subscripted variables as well). ThestoreOutput
function body is gated by a preprocessor flag that is off by default (it needs to be enabled at build time). Therefore, even though the generated C code is larger, there is no impact on the compiled code size or performance when the switch is off.Likewise, there's a new
outputIndexBuffer
argument to therunModelWithBuffers
function, but in the common case where this parameter is left asNULL
, then that code is completely unused and there is no impact on runtime performance or behavior.The JS-level
runtime
andruntime-async
packages have been updated to support this new functionality, but I decided to apply@hidden
tags for most of the new APIs so that they don't yet appear in the public API documentation. This is because a) I'm not ready to call this new API "done", as I've got some changes in mind to make it better and b) we (CI) are probably going to be the only users of this API in the beginning. Once this initial work gets merged in, I can look at the API again with fresh eyes (and ideally align it with how we incorporate your proposal for changes to how inputs are passed in).I added an automated E2E test of the new functionality in
tests/integration/impl-var-access
to make sure it all works together.