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

AnyParameterProperties tests #4414

Closed
wants to merge 18 commits into from

Conversation

gf712
Copy link
Member

@gf712 gf712 commented Nov 15, 2018

Added tests to check binary logic of AnyParameterProperties.m_attribute_mask.

Gil added 10 commits October 15, 2018 15:48
Refactored all the opeations tests.
* Decreased tolerance for float type tests to work with `float32_t`, `float64_t` and `floatmax_t`
* Changed tests where `int` types are required to work with both `int` and `float`
* Did not add `complex128_t`, `bool` or `char` tests
I added the SE test whilst there is no fix for the typed test for this case (see my PR description)
* get_epsilon is called inside each test case to determine the tolerance
* tested these values with my own machine
* solver tests will have a lower threshold, as these seem to change quite a bit depending on machine and lapack/blas installations
* if typed testing is rolled out for all unit tests should move this to its own header file
* solvers have a fixed threshold
* also fixed indentation
* avoids using several getters
@gf712
Copy link
Member Author

gf712 commented Nov 15, 2018

Sorry for the commit spam, not sure what happened, but they don't affect the diff.

@karlnapf
Copy link
Member

you need to rebase against the develop branch

@gf712
Copy link
Member Author

gf712 commented Nov 15, 2018

yup, I tried it earlier and it didn't work. Might be fine now though, if you want I can start a fresh PR to avoid having all those old commits?

Copy link
Member

@karlnapf karlnapf left a comment

Choose a reason for hiding this comment

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

great, these sanity checks are definitely useful!
Some minor comments only and then we can merge it

@@ -118,6 +118,9 @@ namespace shogun
return static_cast<bool>(
m_attribute_mask & ParameterProperties::MODEL);
}
bool is_property(ParameterProperties mask) const {
Copy link
Member

Choose a reason for hiding this comment

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

I would name it has_property

tests/unit/lib/Any_unittest.cc Outdated Show resolved Hide resolved
AnyParameterProperties params = AnyParameterProperties();

EXPECT_EQ(params.get_description(), "No description given");
EXPECT_FALSE(params.is_property(
Copy link
Member

Choose a reason for hiding this comment

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

imagine we get more properties ... this test then needs to be touched which makes maintenance noisy.
What about just asserting that no parameters are set. i.e. the mask is zero everywhere

Copy link
Member Author

Choose a reason for hiding this comment

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

OK! So you mean have three tests, one for each parameter? The only thing that feels like is missing is an enum for zero, since we can't compare the enum class to an int, i.e. 0.

Copy link
Member Author

Choose a reason for hiding this comment

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

well I guess 0 and ParameterProperties() are the same, so never mind!

Copy link
Member

Choose a reason for hiding this comment

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

I would just write a test that ensures that the default parameter properties are 0

"test", EModelSelectionAvailability::MS_NOT_AVAILABLE,
EGradientAvailability::GRADIENT_AVAILABLE, true);

EXPECT_EQ(params.get_description(), "test");
Copy link
Member

Choose a reason for hiding this comment

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

yep here we can/should test

@karlnapf
Copy link
Member

yup, I tried it earlier and it didn't work. Might be fine now though, if you want I can start a fresh PR to avoid having all those old commits?

you can just checkout the develop branch and then git cherry-pick your local commit hash, then force push to your PR

{
AnyParameterProperties params = AnyParameterProperties();

EXPECT_FALSE(params.has_property(ParameterProperties::MODEL));
Copy link
Member

Choose a reason for hiding this comment

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

As said, putting them explicitly means we have to update the test when new properties arrive.
Why not define ParameterProperties::DEFAULT = 0x0 and then assert the default value is that?

Copy link
Member

Choose a reason for hiding this comment

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

For that we would need a method equals which returns true iff the masks exactly match

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 issue is that if you do params.has_property(ParameterProperties::DEFAULT) you end up with 0 & 0 which is 0/false.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, I can add a method with something like:

bool equals(ParameterProperties other) {
    return static_cast<int32_t>(m_attribute_mask) == static_cast<int32_t>(other);
}

EXPECT_FALSE(params.has_property(
ParameterProperties::HYPER & ParameterProperties::GRADIENT));
EXPECT_TRUE(params.has_property(
~ParameterProperties::HYPER & ParameterProperties::GRADIENT));
Copy link
Member

Choose a reason for hiding this comment

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

this doesnt make sense. You cannot check that a property is not set using has_property -- it is AND'ed with the given properties so if both are zero the and is still zero. Need the mentioned is_property (or something similar)

Copy link
Member Author

Choose a reason for hiding this comment

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

yup, I found it a bit odd when I wrote it. It seems unnecessarily convoluted...

EXPECT_FALSE(params.has_property(
ParameterProperties::HYPER & ParameterProperties::GRADIENT));
EXPECT_TRUE(params.has_property(
~ParameterProperties::HYPER & ParameterProperties::GRADIENT));
Copy link
Member

Choose a reason for hiding this comment

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

as above

Copy link
Member

@karlnapf karlnapf left a comment

Choose a reason for hiding this comment

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

almost there :)

EModelSelectionAvailability::MS_NOT_AVAILABLE);
EXPECT_EQ(
params.get_gradient(), EGradientAvailability::GRADIENT_NOT_AVAILABLE);
EXPECT_FALSE(params.get_model());
Copy link
Member

Choose a reason for hiding this comment

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

get model is not part of the old API or? Just realising this

Copy link
Member Author

Choose a reason for hiding this comment

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

It isn't, but the constructor of the old API still sets the ParameterProperties::MODEL bit, so I just thought it would be appropriate to add this check?

Copy link
Member

Choose a reason for hiding this comment

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

I think this would be covered in the test below where we check that nothing is set after construction.
The old api test is more to make sure we didnt change the behaviour of the code, so remove it here.

{
AnyParameterProperties params = AnyParameterProperties();

EXPECT_TRUE(params.equals(ParameterProperties()));
Copy link
Member

Choose a reason for hiding this comment

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

yes, this does it.
And then the next 3 checks can go

Copy link
Member

Choose a reason for hiding this comment

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

oh, and also, actually it could be operator== instead of equals, or?

Copy link
Member

Choose a reason for hiding this comment

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

mmh couldnt this even be added to bitmask_operators so that == is available for all bitmasks that are defined using this?

Copy link
Member Author

@gf712 gf712 Nov 16, 2018

Choose a reason for hiding this comment

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

but wouldn't that imply that all attributes would be equal, i.e. matching descriptions?

Copy link
Member

Choose a reason for hiding this comment

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

No I mean put an operator= in the enum class, the one defined via enableEnumClassBitmask(ParameterProperties);, not the AnyParameterProperties. Or doesnt that make sense?

Copy link
Member Author

Choose a reason for hiding this comment

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

but should still have the equals method in AnyParameterProperties that then uses the operator==, no?

Copy link
Member

Choose a reason for hiding this comment

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

Not sure ... Why would we want to have that?

Copy link
Member Author

Choose a reason for hiding this comment

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

Because you still need a method to access it no? Unless you want to have a getter for m_attribute_mask in AnyParameterProperties and then compare the returned value in the code to something. Wouldn't the equals method be cleaner?

Copy link
Member

Choose a reason for hiding this comment

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

see my other comment

Copy link
Member

Choose a reason for hiding this comment

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

(I agree we need a method), but equals not maybe not the best name.
What about a getter instead? Then the caller can just use ==

EXPECT_EQ(params.get_gradient(), EGradientAvailability::GRADIENT_AVAILABLE);
EXPECT_TRUE(params.get_model());

EXPECT_TRUE(params.has_property(ParameterProperties::MODEL));
Copy link
Member

Choose a reason for hiding this comment

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

I think here we should check that the mask only has exactly the two (mode, gradient) set, but nothing else (without saying what the "else" is)
Rather than explicitly testing that bits are not set (again think about adding properties and we would have to extend the test)

Copy link
Member Author

Choose a reason for hiding this comment

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

So just check:

EXPECT_TRUE(params.equals(
    ParameterProperties::MODEL | ParameterProperties::GRADIENT));

Copy link
Member

Choose a reason for hiding this comment

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

Yes, that would do it.

@gf712
Copy link
Member Author

gf712 commented Nov 16, 2018

Somewhat unrelated but should I also update the license in this file to the new short version?

@karlnapf
Copy link
Member

Somewhat unrelated but should I also update the license in this file to the new short version?

yes good idea.

this ensures that the underlying type is used to cast and make the comparisson
@gf712
Copy link
Member Author

gf712 commented Nov 22, 2018

Closing this and opened a new PR with the same commits (without the old irrelevant commits).

@gf712 gf712 closed this Nov 22, 2018
@karlnapf
Copy link
Member

force push didnt work? Because you could have done that definitely.

@gf712
Copy link
Member Author

gf712 commented Nov 26, 2018

Yes, I tried https://stackoverflow.com/questions/44958129/git-new-pull-request-from-the-same-branch-still-shows-previous-commits, but then when I forced pushed it didn't work, must have messed something up somewhere..

@karlnapf
Copy link
Member

next time ping me on irc and we can do it together :)

@gf712 gf712 deleted the anyparameters_tests branch December 13, 2018 15:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants