-
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
Check variadic pattern arguments at compile time #356
Conversation
… mixed size/distribution specification)
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.
Looks good, I'll leave some comments inline
@@ -122,71 +105,91 @@ class PatternArguments { | |||
|
|||
private: | |||
/// BlockPattern matching for extent value of type IndexType. | |||
template<int count> | |||
void check(SizeType extent) { | |||
template<int argc_size, int argc_dist, int has_team, typename ... Args> |
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.
Some documentation would be nice for those parameters.
_teamspec = teamSpec; | ||
check<argc_size, argc_dist, -1>(std::forward<Args>(args)...); |
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.
No Team is set in this case, it was probably broken before as well...
_teamspec = TeamSpec_t(_distspec, team); | ||
} | ||
_team = &team; | ||
check<argc_size, argc_dist, 1>(std::forward<Args>(args)...); |
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.
No TeamSpec is created in this case,
as it is dependend on _distspec
it probably has to go in the final check()
call.
template<int count> | ||
void check(const SizeSpec_t & sizeSpec) { | ||
template<int argc_size, int argc_dist, int has_team, typename ... Args> | ||
void check(const SizeSpec_t & sizeSpec, Args && ... args) { |
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.
Perhaps it makes sense to move this function up,
so that the it is grouped with the function taking individual extents.
_argc_size++; | ||
_sizespec.resize(count, extent); | ||
_sizespec.resize(argc_size, extent); | ||
check<argc_size+1, argc_dist, has_team>(std::forward<Args>(args)...); | ||
} | ||
/// BlockPattern matching for up to \c NumDimensions optional | ||
/// parameters specifying the distribution pattern. |
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.
This comment seems to be shifted.
@@ -18,14 +18,16 @@ TEST_F(BlockPatternTest, SimpleConstructor) | |||
int extent_x = 21; | |||
int extent_y = 37; | |||
int extent_z = 41; | |||
int size = extent_x * extent_y * extent_z; | |||
int size = extent_x * extent_x * extent_z; |
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.
This change was probably uninteded, as it is currently breaking the tests.
dash::Team::All()); | ||
EXPECT_EQ(ds_blocked_z, pat_ds_t.distspec()); | ||
EXPECT_EQ(size, pat_ds_t.capacity()); | ||
EXPECT_EQ(dash::Team::All().size(), pat_ds_t.num_units()); |
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.
The wrong patterns are checked in those EXPECT
s.
// Should default to distribution BLOCKED, NONE, NONE: | ||
dash::BlockPattern<3> pat_default(extent_x, extent_y, extent_z); | ||
EXPECT_EQ(dash::DistributionSpec<3>(), pat_default.distspec()); | ||
EXPECT_EQ(dash::Team::All(), pat_default.team()); | ||
EXPECT_EQ(dash::Team::All().size(), pat_default.num_units()); | ||
EXPECT_EQ(size, pat_default.capacity()); | ||
|
||
dash::SizeSpec<3> sspec( | ||
extent_x, extent_x, extent_z); |
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.
Probably the wrong y-extent here, too.
void check(const TeamSpec_t & teamSpec, Args && ... args) { | ||
static_assert(has_team == 0, | ||
"Cannot mix Team and TeamSpec definition in variadic " | ||
"pattern constructor!"); |
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.
This limitation seems a little bit odd,
but I think this is depended on TeamSpec.
"expected " << NumDimensions << ", got " << _argc_dist); | ||
} | ||
check_tile_constraints(); | ||
check<0, 0, 0>(std::forward<Args>(args)...); |
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.
Meanwhile it is probably more a parse than a check.
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.
It looks good now and should be ready to merge.
I found one more minor thing that is TeamSpec related,
but I think TeamSpec needs its own issue/pull request, so it shouldn't be important for now.
_teamspec = TeamSpec_t(_distspec, team); | ||
} | ||
_team = &team; | ||
_teamspec = TeamSpec_t(team); |
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.
Possibly overwrites previously set TeamSpec.
Should already be handled by check in line 255.
*/ | ||
if (ArgcTeam && !ArgcTeamSpec) { | ||
_teamspec = TeamSpec_t(_distspec, *_team); | ||
} |
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.
I think it is possible to return without _team
set, how about:
if(!ArgcTeam) {
_team = &dash::Team::All()
}
if(!ArgcTeamSpec) {
_teamspec = TeamSpec_t(_distspec, *_team);
}
I'm not sure about the use cases of this constructor,
so perhaps it is also fine to return without a team.
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.
The dash::Team::All
is used by default if no team has been set, see team()
. The assumption here is that it only makes sense to overwrite the default TeamSpec
if a team was set. However, I realized that I am not sure about the relation between DistSpec
and TeamSpec
and whether we have to create the latter if the former was explicitely given bu the user. Is it even valid to specify both at the same time? @fuchsto can you shed some light?
_distspec = ds; | ||
_distspec = ds; | ||
parse<ArgcSize, -1, ArgcTeam, | ||
ArgcTeam>(std::forward<Args>(args)...); |
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.
Is the use of ArgcTeam
instead of ArgcTeamSpec
intended here?
} | ||
_distspec[ArgcDist] = ds; | ||
parse<ArgcSize, ArgcDist+1, ArgcTeam, | ||
ArgcTeam>(std::forward<Args>(args)...); |
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.
Here too.
@@ -25,7 +27,7 @@ template< | |||
dim_t NumDimensions, | |||
typename IndexType = dash::default_index_t> | |||
class PatternArguments { | |||
private: | |||
public: |
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.
Why public?
Thanks for the reviews, they should be addressed. |
This PR changes
dash::internal::PatternArguments
such that variadic pattern argument integrity is checked at compile-time (except for tile-correctness). It also enables arbitrary mixing ofSizeType
,Distribution
, andTeam|TeamSpec
arguments, as long as the argument list starts with aSizeType
. Most notably, it catches mixed usage ofTeam
andTeamSpec
,Distribution
andDistributionSpec
, as well asSizeType
andSizeSpec
specifications at compile-time.My attempt to add some
constexpr
magic (as proposed in #354) failed since this style of parsing does not seem to be possible that way as it would require overloading constructor templates.As an addition, this PR also introduces
DASH_ASSERT_ALWAYS
, which always asserts even if assertions are disabled. This is required to ensure pattern validity (replaced plainassert
).