-
Notifications
You must be signed in to change notification settings - Fork 11
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
Replace multi-variable connections with functions #518
Conversation
This is going to be too complex for me to review again, especially since it's touches on the msmi which I'm not into at all.. However, I'm concerned that this will make the API much more difficult to use. IMO, there should still be an "easy" way of doing simple stuff like using/creating functions* (both global and connection specific) like or similar to *General functions, not a cse::function. |
I agree that the current API is easier to use, and that the proposed API will slightly increase the amount of code required for simple use cases. (Though it's worth noting that it reduces the amount of code required for the simplest use case, a direct scalar connection, making it a one-liner.) The However, once you have cases where the inputs and outputs need to be identified and grouped, like vector sums and coordinate transformations, then the current API is no longer sufficient. I started out trying to find some way of simply extending the
From the perspective of client code, I'd say it's now roughly on the same complexity level as adding and connecting a simulator to do the same job. Example: const auto s1 = execution.add_slave(make_slave_somehow());
const auto s2 = execution.add_slave(make_slave_somehow());
const auto fn= execution.add_function(std::make_shared<linear_transformation_function>(32.0, 1.8));
execution.connect_variables({s1, variable_type::real, s1Out}, {fn, variable_type::real, fnIn});
execution.connect_variables({fn, variable_type::real, fnOut}, {s2, variable_type::real, s2In}); |
This PR follows our discussion on handling functions as proper function structures in cse-core. I like it, and believe we're moving in the right direction. Not able to build on windows as warnings are treated as errors:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool beans!
The function parameterization part seems a bit complex, but I guess there is a reason for having it general.
Thanks for the feedback so far, it's very helpful. To summarise, I will:
|
Since nobody has commented on the proposed class and struct names, should I assume that you're all fine with them? In particular, I'm thinking about the use of the word EDIT: Also, if we're thinking of these as functions in the mathematical sense, then I suppose "inputs" and "outputs" are more appropriate terms than "variables" anyway. |
Then |
I reverted it to the old evaluation order (but kept the cleaned-up code). |
This fixes issue #538, "`mock_slave` violates assumptions, causing tests to be ill-defined". Basically, what I've done is to make the user-supplied functions act on the outputs rather than on the internal states. This had quite substantial effects on some of the tests, which depended on the wrong behaviour. To compensate and, to some extent, restore the old behaviour in a "correct" way, I've had to add some new functionality to `mock_slave`, namely: - The possibility to have outputs depend on time as well as inputs. - The possibility to have a custom function called at each time step. Finally, I've taken this opportunity to make some of the tests slightly more readable by replacing magic numbers with named variables/constants. This includes: - Simulator indexes, which were assumed to be sequential in some tests - Variable references, which were assumed to be 0 and 1 for `mock_slave`'s variables The magic numbers were making the tests hard to read, and therefore also to fix. Besides, while the above assumptions are correct at the moment, that need not be the case in the future.
Sorry for the last-minute changes while you are apparently in the middle of reviewing this, Levi. (The new commits don't add functionality, it's just some minor cleanup.) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice job on introducing functions as first class citizens!
Great work on the documentation 👍
I've retargeted this on |
…ion-introspection
I've fixed the conflicts now, but I'll wait for Jenkins to come back online and check the code before merging anything. |
Jenkins is back up and has built this branch successfully 👍 |
Here is my current attempt at fixing #464 and providing an API for the new "functions" feature.
It's not entirely done yet – see "to do" below – but since it's a rather big change, I figured I'd start getting some feedback now in case any big issues or change requests come up (but not a formal review).Main changes
connection
and related classesfunction
and related classesvector_sum_function
andlinear_transformation_function
To do
The following remains to be done before this PR is complete:
Reorganise headers slightly(I'll do this as a separate pull request rather than complicate this one even further.)What's the difference?
Basically, a
function
is a lot more like asimulator
than aconnection
. You add it to an execution withexecution::add_function()
, and then you make (scalar) connections between simulator and function variables usingexecution::connect_variables()
. Currently, three types of connections are allowed:Notably, function-function connections are not allowed. API- and implementation-wise it shouldn't pose too many problems, but there are some simulation-technical subtleties I'd like us to think some more about before adding it (in particular, how to deal with algebraic loops in function chains).
Like simulators/FMUs, functions also support introspection and dynamic instantiation by means of the
function_type
andfunction_type_description
classes. (These correspond tomodel
andmodel_description
for simulators, respectively.) This will be crucial for completing the other thing I've been working on, namely #114 (system_structure
).