-
Notifications
You must be signed in to change notification settings - Fork 51
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
Improving the attribute system #61
Comments
As an initial idea, the attributes could be implemented by using two different levels of pointers. Every class that should hold attributes would have a member variable that stores a shared pointer to an attribute instance. At the same time, the underlying When doing calculations involving the attributes, is should be possible to directly use the involved class' member variables (which would then be pointers to attributes with pointers to values). To make this as easy as possible (regarding syntax and computation effort), the dereference operator As a more advanced step, we might want to look at how the Task schedule is computed from the attributes' relations to each other. It might be possible to move the dependency information into the attributes themselves, specifying what other attributes an attribute depends on and how its value can be computed from its dependencies. While this is quite a large shift in how the scheduler manages dependencies, it might result in a simpler dependency graph and easier to understand scheduler code. |
dpsim/models/Include/cps/Attribute.h Lines 256 to 267 in ad491cc
For the new attribute system, we might also want to look at how to implement these kinds of derived attributes in a different way. Currently, these create new attributes that reference the old attribute and compute their own values using Getter and Setter functions. In this example, this behavior is inconsistent as the generated setter is never used (instead |
The main application of the getters is to process data before sending it to VILLASweb and for logging. Often we send amplitude and phase to VILLASweb instead of real and imaginary value of a complex voltage. Setters were introduced to preprocess incoming data but eventually we never used them and just made sure that the incoming data is already compliant. Since we built the attribute system, VILLASnode introduced hooks to transform relayed data. This covers many use cases already. For logging purposes, the getters are still convenient. I could imagine that having a clean solution for the getters would be sufficient since we can use VILLASnode for other use cases. |
All commits related to this issue will now be collected in PR #62. In the coming days I will post an overview on the (highly experimental) changes currently contained in the PR. |
Here are some thoughts on the current state of the attribute system as well as an explanation of the new system currently included in PR #62 :
Additionally, dependencies can be defined for all of these attributes using the The system introduced in PR #62 aims to unify these different types of attributes and dependencies, while allowing for full generality with regard to which attributes can be combined in which relationships. To do this, the new system provides two kinds of attributes which now have their own classes:
Using the dynamic attributes, the "derived" and "referencing" attributes from the old model can be recreated in a more general form: "Referencing" attributes are implemented using a dynamic attribute with a task which updates not the cached data value, but the cache pointer address. When referencing a static attribute, it would suffice to update the cache pointer once at the beginning of the simulation. When referencing a dynamic attribute, this update has to be performed on every To allow for this scope of generality, the resulting attribute code gets quite complicated and template-heavy. To prevent the user from having to deal with these generic types, multiple Lastly, I want to stress that most of these concepts currently just exist on paper and are therefore subject to change. For example, the high amount of templates might lead to an unacceptable increase in compiled code size. Or the additional function calls for management of the actor functions might cause too much of a performance overhead to actually be useful. The system might also be too general for the use case of DPsim, in which the special cases this new system allows for might never be needed. |
Since reworking the attributes entails reading through a lot of DPsim's current code, here are some random things I noticed that might be turned into new Issues later on:
|
Most points mentioned above are now marked in the code for PR #62 using the keywords |
This PR introduces a new attribute system to DPsim. Attributes are variable properties that can hold some numerical value, which can then be accessed from the outside by the simulation scheduler or by other components. Attributes can be computed from other attributes, therefore forming a dependency graph which is used in the scheduler to determine the execution order of tasks. With this PR, every attribute can either be static or dynamic. Static attributes do not have any immediate dependencies, while dynamic attributes can be entirely derived from other attributes. For more details on the distinction between dynamic and static attributes, see this comment in issue #61 The usage of attributes in the component code remains roughly the same, however there are some differences: - Attributes are public member variables of the components they belong to and they usually have type const Attribute<T>::Ptr. - Attributes are created in the constructors initialization list. A new attribute can be created with the Attribute<T>::create and Attribute<T>::createDynamic methods. - To acquire a (mutable) reference to an attribute's underlying data, the dereference operator has to be used twice on the attribute member variable, resulting in **mAttribute. - Derived attributes can be created using the various derive-functions on the attribute object.
Attributes should be declared as member variables of the component class to avoid something like
attribute<Complex>("V_ref")->get()
during the simulation. This is not efficient and the attributes of a component class are not easily deduced from looking at the component class declaration.mInductance = addAttribute<Real>("L", Flags::read | Flags::write);
Each attribute should include
Accordingly, the python print should include more columns for this information.
To make the work with the attributes more comfortable in the component classes, some operators like cast () and assignment operator might be overwritten but this should be limited as much as possible.
We also need to improve the mechanism for describing the output - input relation between two components.
Currently, it is possible to change the map value for a key calling something like this:
voltageSource->setAttributeRef("V_ref", attribute<Real>("V_ref"));
If you store are reference to an attribute inside a component like below, the stored reference might be invalid after calling the function above.
voltageRef = attribute<Complex>("V_ref");
We could add one member variable to the Attribute class that points to referenced Attributes, which describes an input output relation. Still, the value pointer address should be overwritten for the input Attribute to minimize the overhead when reading the value during simulation time.
The text was updated successfully, but these errors were encountered: