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
Conversation
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
Sorry for the commit spam, not sure what happened, but they don't affect the diff. |
you need to rebase against the develop branch |
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? |
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.
great, these sanity checks are definitely useful!
Some minor comments only and then we can merge it
src/shogun/base/AnyParameter.h
Outdated
@@ -118,6 +118,9 @@ namespace shogun | |||
return static_cast<bool>( | |||
m_attribute_mask & ParameterProperties::MODEL); | |||
} | |||
bool is_property(ParameterProperties mask) const { |
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 would name it has_property
tests/unit/lib/Any_unittest.cc
Outdated
AnyParameterProperties params = AnyParameterProperties(); | ||
|
||
EXPECT_EQ(params.get_description(), "No description given"); | ||
EXPECT_FALSE(params.is_property( |
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.
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
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.
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.
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.
well I guess 0 and ParameterProperties()
are the same, so never mind!
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 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"); |
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.
yep here we can/should test
you can just checkout the develop branch and then |
{ | ||
AnyParameterProperties params = AnyParameterProperties(); | ||
|
||
EXPECT_FALSE(params.has_property(ParameterProperties::MODEL)); |
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.
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?
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.
For that we would need a method equals
which returns true iff the masks exactly match
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 issue is that if you do params.has_property(ParameterProperties::DEFAULT)
you end up with 0 & 0
which is 0
/false
.
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.
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);
}
tests/unit/lib/Any_unittest.cc
Outdated
EXPECT_FALSE(params.has_property( | ||
ParameterProperties::HYPER & ParameterProperties::GRADIENT)); | ||
EXPECT_TRUE(params.has_property( | ||
~ParameterProperties::HYPER & ParameterProperties::GRADIENT)); |
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 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)
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.
yup, I found it a bit odd when I wrote it. It seems unnecessarily convoluted...
tests/unit/lib/Any_unittest.cc
Outdated
EXPECT_FALSE(params.has_property( | ||
ParameterProperties::HYPER & ParameterProperties::GRADIENT)); | ||
EXPECT_TRUE(params.has_property( | ||
~ParameterProperties::HYPER & ParameterProperties::GRADIENT)); |
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.
as above
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.
almost there :)
EModelSelectionAvailability::MS_NOT_AVAILABLE); | ||
EXPECT_EQ( | ||
params.get_gradient(), EGradientAvailability::GRADIENT_NOT_AVAILABLE); | ||
EXPECT_FALSE(params.get_model()); |
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.
get model is not part of the old API or? Just realising this
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 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?
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 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())); |
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.
yes, this does it.
And then the next 3 checks can go
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.
oh, and also, actually it could be operator==
instead of equals, or?
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.
mmh couldnt this even be added to bitmask_operators
so that ==
is available for all bitmasks that are defined using this?
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.
but wouldn't that imply that all attributes would be equal, i.e. matching descriptions?
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 I mean put an operator=
in the enum class, the one defined via enableEnumClassBitmask(ParameterProperties);
, not the AnyParameterProperties. Or doesnt that make sense?
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.
but should still have the equals
method in AnyParameterProperties
that then uses the operator==
, no?
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.
Not sure ... Why would we want to have that?
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.
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?
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.
see my other comment
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 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)); |
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 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)
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.
So just check:
EXPECT_TRUE(params.equals(
ParameterProperties::MODEL | ParameterProperties::GRADIENT));
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.
Yes, that would do it.
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
Closing this and opened a new PR with the same commits (without the old irrelevant commits). |
force push didnt work? Because you could have done that definitely. |
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.. |
next time ping me on irc and we can do it together :) |
Added tests to check binary logic of
AnyParameterProperties.m_attribute_mask
.