Skip to content
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

Merged
merged 10 commits into from
May 30, 2017

Conversation

devreal
Copy link
Member

@devreal devreal commented Apr 3, 2017

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 of SizeType, Distribution, and Team|TeamSpec arguments, as long as the argument list starts with a SizeType. Most notably, it catches mixed usage of Team and TeamSpec, Distribution and DistributionSpec, as well as SizeType and SizeSpec 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 plain assert).

@devreal devreal added this to the dash-0.3.0 milestone Apr 3, 2017
@devreal devreal requested a review from fuchsto April 3, 2017 15:51
Copy link
Contributor

@ddiefenthaler ddiefenthaler left a 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>
Copy link
Contributor

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)...);
Copy link
Contributor

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)...);
Copy link
Contributor

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) {
Copy link
Contributor

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.
Copy link
Contributor

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;
Copy link
Contributor

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());
Copy link
Contributor

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 EXPECTs.

// 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);
Copy link
Contributor

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!");
Copy link
Contributor

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)...);
Copy link
Contributor

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.

Copy link
Contributor

@ddiefenthaler ddiefenthaler left a 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);
Copy link
Contributor

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);
}
Copy link
Contributor

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.

Copy link
Member Author

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)...);
Copy link
Contributor

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)...);
Copy link
Contributor

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:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why public?

@devreal
Copy link
Member Author

devreal commented Apr 18, 2017

Thanks for the reviews, they should be addressed.

@fuchsto fuchsto merged commit 59238d3 into development May 30, 2017
@fuchsto fuchsto deleted the dash-patternargs-comptime branch May 30, 2017 01:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants