-
Notifications
You must be signed in to change notification settings - Fork 44
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
Strong typing for local and global IDs #143
Comments
Can you give an example for which IDs this is problematic? |
This is required, as I know you have changed it in PR #133, however that was not a good one, as then the unit test failed. In fact, the bug was in the Array implementation and not in GlobMem. I stumbled upon this curiosity too. |
@fmoessbauer Disregard that, I got it myself, can't quite remember why I implemented it this way, though. EDIT: deleted my comment, you were too quick to answer and I can't seem to undelete it |
@dash-project/developers After all, I think @clemensmanert is right. I would introduce types in DART like: typedef struct {
dart_unit_t id;
} dart_global_unit_t;
typedef struct {
dart_unit_t id;
} dart_local_unit_t; ... with some union-magic for convenient strong typing. This would work for DART (C99). This would solve the situation in pointer lbegin(dart_global_unit_t gunit) {
// ...
}
pointer lbegin(dart_local_unit_t lunit) {
// convert to global unit id and pass to dart_global_unit_t overload
} |
To me it looks like this is only some (though maybe more prominent) form of documentation as well as long as we do not make sure that |
You might: My intention is the opposite: the strong typing adds semantic information that I don't want to lose. dart_ret_t dart_group_addmember(dart_group_t *g, dart_unit_t unitid); As a user, I would be unsure whether With strong typing, it would look like this: dart_ret_t dart_group_addmember(dart_group_t *g, dart_global_unit_t unitid); Passing Also, the compiler error would be really, really nice. Something along the lines of DASH users won't see these changes but DART is a library on its own with a public interface. |
Got it, thanks. I'm fine with changing the interface like that and not have implicit conversion (not possible in C anyway but could be possible in C++), even though it's a bit more coding effort (manually creating the struct from a dart_unit_t or using a macro to do it). |
Right, but in C++ we can do even better and use phantom types like: namespace dash {
template <typename IdScope> struct unit_id { dart_unit_t id; }
typedef unit_id<dash::scope::local> local_unit_id;
typedef unit_id<dash::scope::global> global_unit_id;
} ... and provide constructors or use brace initializers for convenient instantiation: local_unit_id lu { 42 }; Ah yes, and conversion operators must be |
Thinking about this a little more it seems that it is only important to be able to differentiate global and local unit IDs based on the type. To make the change less intrusive, we could as well simply typedef |
Then we would have another interface / behavior the user has to learn and keep in mind. |
Out of curiosity, I started implementing typed unit IDs for the DASH part. Please see https://github.com/dash-project/dash/compare/feat-143-unitids Some things I noticed:
but has to be:
Overall, I think this is a viable route to go. Once the conversion in DASH is done, it will be much easier to introduce typed unit IDs in DART as it only requires adaptation of the |
Hi, at a first glance, I noticed the following points:
The rest of your changes looks great to me. |
The implementation of
Not sure I understand this part. Do mean |
I think what Felix means is that in DASH library code |
In the cases where I replaced The question is whether teams should provide the global ID of the current unit. IMO, this is not a clean solution as teams should only be concerned with team-local IDs (and the translation to and from global IDs). |
Agreed, providing separate global IDs seems redundant to me. The global ID is simply the ID in |
The point ist that I am not happy with To the |
This seems to be a discussion about our programming conventions. What @fmoessbauer and @fuerlinger meant is that we should not use short-hand statements in our library. While An additional comment to the code changes. We explicitly loose the context information if one extracts the native dart_id. However, for this purpose we still have to add type safety for dart_unit_t with some union magic as @fuchsto already mentioned. |
So just to make sure I understand this right: your argument is that I should use As soon as DASH is fully aware of the typed unit IDs a user cannot pass |
Come to think about it, the return type of I would also propose to implement |
I am not sure how you are going to implement that. |
@devreal Thank you so much for putting your time into this. |
@fmoessbauer I was a bit too fast on that, it's not easily possible to implement this using a template (since dash::Team::* would become dash::Team<>::* across the code base). However, I still think that If we still want to encapsulate the accessor for the global unit ID inside dash::Team we could have a static function along with the other accessors for invariants like
Not sure whether this provides any benefit over the |
@devreal I aggree, for several reasons. Briefly put, from the perspective of a specific team, there is no "global". You have to "step outside" of the team's reference frame to view the global scope. A static method looks very intuitive to me to express this because developers simply cannot obtain the global position from a team instance, they have to consolidate the type |
Ok, you convinced me. I did not even thought about a static method. IMO the static method is the best solution. Thanks for putting time into this and the enlightening discussion. |
I just finished converting most of the places where The usage of Overall, the conversion was rather tedious (changing things here breaks things there, changing things there breaks things somewhere else and always having to rebuild most of the code) and a bigger effort than expected originally so I hope I didn't change any semantics. Please check and let me know what you think, I'm happy to adjust the details. There are about 60 places left where left where |
@devreal Need to clarify semantics for myself first, but apart from that, the PR should include documentation. |
See my comments in PR #186: Currently there is a conversion operator to In effect, this allows use cases we intended to prohibit in the first place: dash::local_unit_t l_uid { 12 };
dash::global_unit_t g_uid { 12 };
l_uid = g_uid; // works, but shouldn't even compile Added test suite |
I added documentation and deleted mixed-type comparison and assignment operators. |
As the usage of local vs. global unit ids is discussed repeatedly for several use cases, I propose the following rules:
Example: dash::Confabulation<int> cfb(1024, team);
// confabulation: \kən-ˌfa-byə-ˈlā-shən\
// noun: disturbance of memory (psych.)
auto disturbance = cfb.at_unit(dash::local_unit_t { 3 });
auto mmap = dash::MemoryMap::AtUnit(dash::global_unit_t { 3 });
dart_ret_t ret = dart_confabulation_at(cfb, team, dart_local_unit_t { 3 });
dart_ret_t ret = dart_memory_map_at(dart_global_unit_t { 3 }); Ceterum censeo: I still don't like the term "local" for teams. In the DART topology module, I use Any objections? @dash-project/developers let's decide this now as long as the bulk-redesign is not completed, yet. |
I agree that the term For the |
A unit id that is relative to Using Also, Eclipse?! Oh boy, you are just too lazy to invest half a year in a vim configuration! |
I am back from China and managed to implement typed unit IDs in DART during the conference breaks. This change was even more invasive since we cannot define operations on structs in C. The DASH unit types are now derived from the DART unit types, hence we could get rid of the scope enum entirely. Please note that there are a handfull todos for @fuchsto (see I have not applied the renaming discussed earlier, yet. |
@devreal Naahiiice, thank you, much appreciated! Updated branch |
@devreal On second and third thoughts, I follow your suggestion to rename relative unit ID types to
You're right, |
Fixed in #186 |
Create a new own type for each kind of id, so they can not be mixed up any more.
The text was updated successfully, but these errors were encountered: