From 0a8628d923924d4c13ce402beae704f82d4f362e Mon Sep 17 00:00:00 2001 From: Gil Date: Wed, 7 Nov 2018 14:20:29 +0000 Subject: [PATCH 1/7] combined parameter flags in a single mask * added mask_attribute to keep track of parameter availabilities * updated constructors and getters * added some documentation --- src/shogun/base/AnyParameter.h | 73 +++++++++++++++++++++++++++++----- 1 file changed, 63 insertions(+), 10 deletions(-) diff --git a/src/shogun/base/AnyParameter.h b/src/shogun/base/AnyParameter.h index 23a1ba44457..219460dba12 100644 --- a/src/shogun/base/AnyParameter.h +++ b/src/shogun/base/AnyParameter.h @@ -21,49 +21,102 @@ namespace shogun GRADIENT_NOT_AVAILABLE = 0, GRADIENT_AVAILABLE = 1 }; - + /** @brief Class AnyParameterProperties keeps track of parameter properties. + * + * Currently there are three types of parameters: + * -# HYPERPARAMETER: the parameter determines how the training is + * performed, e.g. regularisation + * -# GRADIENT_PARAM: the parameter is used in gradient updates + * -# MODELSELECTION_PARAM: model parameter that is trained, e.g. weight + * vectors and bias + */ class AnyParameterProperties { public: - AnyParameterProperties() - : m_description(), m_model_selection(MS_NOT_AVAILABLE), - m_gradient(GRADIENT_NOT_AVAILABLE) + static const int32_t HYPERPARAMETER = 0x00000001; + static const int32_t GRADIENT_PARAM = 0x00000010; + static const int32_t MODELSELECTION_PARAM = 0x00000100; + + /** default constructor where all parameter types are switched to false + */ + AnyParameterProperties() : m_description(), m_mask_attribute(0x00000000) { } + /** legacy constructor */ AnyParameterProperties( std::string description, EModelSelectionAvailability model_selection = MS_NOT_AVAILABLE, - EGradientAvailability gradient = GRADIENT_NOT_AVAILABLE) + EGradientAvailability gradient = GRADIENT_NOT_AVAILABLE, + bool hyperparameter = false) : m_description(description), m_model_selection(model_selection), m_gradient(gradient) { + m_mask_attribute = 0x00000000; + if (model_selection) + m_mask_attribute |= MODELSELECTION_PARAM; + if (gradient) + m_mask_attribute |= GRADIENT_PARAM; + if (hyperparameter) + m_mask_attribute |= HYPERPARAMETER; } + /** mask constructor */ + AnyParameterProperties(std::string description, int32_t mask_attribute) + : m_description(description) + { + m_mask_attribute = mask_attribute; + } + /** copy contructor */ AnyParameterProperties(const AnyParameterProperties& other) : m_description(other.m_description), m_model_selection(other.m_model_selection), - m_gradient(other.m_gradient) + m_gradient(other.m_gradient), + m_mask_attribute(other.m_mask_attribute) { } - + /** description getter */ std::string get_description() const { return m_description; } - + /** model selection flag getter */ EModelSelectionAvailability get_model_selection() const { - return m_model_selection; + EModelSelectionAvailability return_val; + if (m_mask_attribute & MODELSELECTION_PARAM) + return_val = EModelSelectionAvailability::MS_AVAILABLE; + else + return_val = EModelSelectionAvailability::MS_NOT_AVAILABLE; + return return_val; } + /** gradient flag getter */ EGradientAvailability get_gradient() const { - return m_gradient; + EGradientAvailability return_val; + if (m_mask_attribute & GRADIENT_PARAM) + return_val = EGradientAvailability::GRADIENT_AVAILABLE; + else + return_val = EGradientAvailability::GRADIENT_NOT_AVAILABLE; + return return_val; + } + + /** hyperparameter flag getter */ + bool get_hyperparameter() const + { + bool return_val; + if (m_mask_attribute & HYPERPARAMETER) + return_val = true; + else + return_val = false; + return return_val; } private: std::string m_description; EModelSelectionAvailability m_model_selection; EGradientAvailability m_gradient; + /** mask to store all param flags*/ + int32_t m_mask_attribute; }; class AnyParameter From c505c2a6408fa5a522e7364a61393ec29253a151 Mon Sep 17 00:00:00 2001 From: Gil Date: Wed, 7 Nov 2018 14:56:23 +0000 Subject: [PATCH 2/7] changed properties default `AnyParameterProperties::HYPERPARAMETER | AnyParameterProperties::GRADIENT_PARAM | AnyParameterProperties::MODELSELECTION_PARAM` is equivalent to all parameter property flags being false (`0x00000000`) --- src/shogun/base/SGObject.h | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/shogun/base/SGObject.h b/src/shogun/base/SGObject.h index 8464880e781..46d1d6e1b19 100644 --- a/src/shogun/base/SGObject.h +++ b/src/shogun/base/SGObject.h @@ -676,7 +676,10 @@ class CSGObject void watch_param( const std::string& name, T* value, AnyParameterProperties properties = AnyParameterProperties( - "Unknown parameter", MS_NOT_AVAILABLE, GRADIENT_NOT_AVAILABLE)) + "Unknown parameter", + AnyParameterProperties::HYPERPARAMETER | + AnyParameterProperties::GRADIENT_PARAM | + AnyParameterProperties::MODELSELECTION_PARAM)) { BaseTag tag(name); create_parameter(tag, AnyParameter(make_any_ref(value), properties)); @@ -694,7 +697,10 @@ class CSGObject void watch_param( const std::string& name, T** value, S* len, AnyParameterProperties properties = AnyParameterProperties( - "Unknown parameter", MS_NOT_AVAILABLE, GRADIENT_NOT_AVAILABLE)) + "Unknown parameter", + AnyParameterProperties::HYPERPARAMETER | + AnyParameterProperties::GRADIENT_PARAM | + AnyParameterProperties::MODELSELECTION_PARAM)) { BaseTag tag(name); create_parameter( @@ -715,7 +721,10 @@ class CSGObject void watch_param( const std::string& name, T** value, S* rows, S* cols, AnyParameterProperties properties = AnyParameterProperties( - "Unknown parameter", MS_NOT_AVAILABLE, GRADIENT_NOT_AVAILABLE)) + "Unknown parameter", + AnyParameterProperties::HYPERPARAMETER | + AnyParameterProperties::GRADIENT_PARAM | + AnyParameterProperties::MODELSELECTION_PARAM)) { BaseTag tag(name); create_parameter( @@ -733,7 +742,10 @@ class CSGObject { BaseTag tag(name); AnyParameterProperties properties( - "Dynamic parameter", MS_NOT_AVAILABLE, GRADIENT_NOT_AVAILABLE); + "Dynamic parameter", + AnyParameterProperties::HYPERPARAMETER | + AnyParameterProperties::GRADIENT_PARAM | + AnyParameterProperties::MODELSELECTION_PARAM); std::function bind_method = std::bind(method, dynamic_cast(this)); create_parameter(tag, AnyParameter(make_any(bind_method), properties)); From 3aba0953e2ed00eebc4f09749b63b0272feb00a1 Mon Sep 17 00:00:00 2001 From: Gil Date: Wed, 7 Nov 2018 15:01:32 +0000 Subject: [PATCH 3/7] changed modelselection_param to model_param modelselection_param is actually hyperparameter now and model_param is a seperate definition, e.g. bias and weights --- src/shogun/base/AnyParameter.h | 16 +++++++++++----- src/shogun/base/SGObject.h | 8 ++++---- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/shogun/base/AnyParameter.h b/src/shogun/base/AnyParameter.h index 219460dba12..e7e71ccaa02 100644 --- a/src/shogun/base/AnyParameter.h +++ b/src/shogun/base/AnyParameter.h @@ -1,3 +1,9 @@ +/* + * This software is distributed under BSD 3-clause license (see LICENSE file). + * + * Authors: Heiko Strathmann, Gil Hoben + */ + #ifndef __ANYPARAMETER_H__ #define __ANYPARAMETER_H__ @@ -27,7 +33,7 @@ namespace shogun * -# HYPERPARAMETER: the parameter determines how the training is * performed, e.g. regularisation * -# GRADIENT_PARAM: the parameter is used in gradient updates - * -# MODELSELECTION_PARAM: model parameter that is trained, e.g. weight + * -# MODEL_PARAM: model parameter that is trained, e.g. weight and bias * vectors and bias */ class AnyParameterProperties @@ -35,7 +41,7 @@ namespace shogun public: static const int32_t HYPERPARAMETER = 0x00000001; static const int32_t GRADIENT_PARAM = 0x00000010; - static const int32_t MODELSELECTION_PARAM = 0x00000100; + static const int32_t MODEL_PARAM = 0x00000100; /** default constructor where all parameter types are switched to false */ @@ -53,7 +59,7 @@ namespace shogun { m_mask_attribute = 0x00000000; if (model_selection) - m_mask_attribute |= MODELSELECTION_PARAM; + m_mask_attribute |= MODEL_PARAM; if (gradient) m_mask_attribute |= GRADIENT_PARAM; if (hyperparameter) @@ -82,7 +88,7 @@ namespace shogun EModelSelectionAvailability get_model_selection() const { EModelSelectionAvailability return_val; - if (m_mask_attribute & MODELSELECTION_PARAM) + if (m_mask_attribute & HYPERPARAMETER) return_val = EModelSelectionAvailability::MS_AVAILABLE; else return_val = EModelSelectionAvailability::MS_NOT_AVAILABLE; @@ -169,6 +175,6 @@ namespace shogun Any m_value; AnyParameterProperties m_properties; }; -} +} // namespace shogun #endif diff --git a/src/shogun/base/SGObject.h b/src/shogun/base/SGObject.h index 46d1d6e1b19..e9909a595e4 100644 --- a/src/shogun/base/SGObject.h +++ b/src/shogun/base/SGObject.h @@ -679,7 +679,7 @@ class CSGObject "Unknown parameter", AnyParameterProperties::HYPERPARAMETER | AnyParameterProperties::GRADIENT_PARAM | - AnyParameterProperties::MODELSELECTION_PARAM)) + AnyParameterProperties::MODEL_PARAM)) { BaseTag tag(name); create_parameter(tag, AnyParameter(make_any_ref(value), properties)); @@ -700,7 +700,7 @@ class CSGObject "Unknown parameter", AnyParameterProperties::HYPERPARAMETER | AnyParameterProperties::GRADIENT_PARAM | - AnyParameterProperties::MODELSELECTION_PARAM)) + AnyParameterProperties::MODEL_PARAM)) { BaseTag tag(name); create_parameter( @@ -724,7 +724,7 @@ class CSGObject "Unknown parameter", AnyParameterProperties::HYPERPARAMETER | AnyParameterProperties::GRADIENT_PARAM | - AnyParameterProperties::MODELSELECTION_PARAM)) + AnyParameterProperties::MODEL_PARAM)) { BaseTag tag(name); create_parameter( @@ -745,7 +745,7 @@ class CSGObject "Dynamic parameter", AnyParameterProperties::HYPERPARAMETER | AnyParameterProperties::GRADIENT_PARAM | - AnyParameterProperties::MODELSELECTION_PARAM); + AnyParameterProperties::MODEL_PARAM); std::function bind_method = std::bind(method, dynamic_cast(this)); create_parameter(tag, AnyParameter(make_any(bind_method), properties)); From 476d2a9ad0eba65149a209244ad851ff88b3385a Mon Sep 17 00:00:00 2001 From: Gil Date: Fri, 9 Nov 2018 10:56:29 +0000 Subject: [PATCH 4/7] fixed docs --- src/shogun/base/AnyParameter.h | 37 ++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/src/shogun/base/AnyParameter.h b/src/shogun/base/AnyParameter.h index e7e71ccaa02..8b81e7ba6be 100644 --- a/src/shogun/base/AnyParameter.h +++ b/src/shogun/base/AnyParameter.h @@ -28,13 +28,9 @@ namespace shogun GRADIENT_AVAILABLE = 1 }; /** @brief Class AnyParameterProperties keeps track of parameter properties. - * - * Currently there are three types of parameters: - * -# HYPERPARAMETER: the parameter determines how the training is - * performed, e.g. regularisation - * -# GRADIENT_PARAM: the parameter is used in gradient updates - * -# MODEL_PARAM: model parameter that is trained, e.g. weight and bias - * vectors and bias + * The parameter properties can be either true or false. + * These properties describe if a parameter is for example a hyperparameter + * or if it has a gradient. */ class AnyParameterProperties { @@ -43,12 +39,20 @@ namespace shogun static const int32_t GRADIENT_PARAM = 0x00000010; static const int32_t MODEL_PARAM = 0x00000100; - /** default constructor where all parameter types are switched to false + /** Default constructor where all parameter properties are false */ AnyParameterProperties() : m_description(), m_mask_attribute(0x00000000) { } - /** legacy constructor */ + /** Constructor + * @param description parameter description + * @param hyperparameter set to true for parameters that determine + * how training is performed, e.g. regularisation parameters + * @param gradient set to true for parameters required for gradient + * updates + * @param model set to true for parameters used in inference, e.g. + * weights and bias + * */ AnyParameterProperties( std::string description, EModelSelectionAvailability model_selection = MS_NOT_AVAILABLE, @@ -65,13 +69,15 @@ namespace shogun if (hyperparameter) m_mask_attribute |= HYPERPARAMETER; } - /** mask constructor */ - AnyParameterProperties(std::string description, int32_t mask_attribute) + /** Mask constructor + * @param description parameter description + * @param attribute_mask mask encoding parameter properties + * */ : m_description(description) { m_mask_attribute = mask_attribute; } - /** copy contructor */ + /** Copy contructor */ AnyParameterProperties(const AnyParameterProperties& other) : m_description(other.m_description), m_model_selection(other.m_model_selection), @@ -79,12 +85,11 @@ namespace shogun m_mask_attribute(other.m_mask_attribute) { } - /** description getter */ + const std::string& get_description() const std::string get_description() const { return m_description; } - /** model selection flag getter */ EModelSelectionAvailability get_model_selection() const { EModelSelectionAvailability return_val; @@ -95,7 +100,6 @@ namespace shogun return return_val; } - /** gradient flag getter */ EGradientAvailability get_gradient() const { EGradientAvailability return_val; @@ -106,7 +110,6 @@ namespace shogun return return_val; } - /** hyperparameter flag getter */ bool get_hyperparameter() const { bool return_val; @@ -121,7 +124,7 @@ namespace shogun std::string m_description; EModelSelectionAvailability m_model_selection; EGradientAvailability m_gradient; - /** mask to store all param flags*/ + int32_t m_attribute_mask; int32_t m_mask_attribute; }; From 3e32f1cf8b5501ba570d01654cc4eb5428c24777 Mon Sep 17 00:00:00 2001 From: Gil Date: Fri, 9 Nov 2018 10:58:19 +0000 Subject: [PATCH 5/7] switched to bitshifts instead of hexadecimals * also shorted class member names * changed default constructor to give default description --- src/shogun/base/AnyParameter.h | 59 ++++++++++++---------------------- src/shogun/base/SGObject.h | 24 +++++--------- 2 files changed, 28 insertions(+), 55 deletions(-) diff --git a/src/shogun/base/AnyParameter.h b/src/shogun/base/AnyParameter.h index 8b81e7ba6be..81d819d9f88 100644 --- a/src/shogun/base/AnyParameter.h +++ b/src/shogun/base/AnyParameter.h @@ -35,13 +35,14 @@ namespace shogun class AnyParameterProperties { public: - static const int32_t HYPERPARAMETER = 0x00000001; - static const int32_t GRADIENT_PARAM = 0x00000010; - static const int32_t MODEL_PARAM = 0x00000100; + static const int32_t HYPER = 1u << 0; + static const int32_t GRADIENT = 1u << 1; + static const int32_t MODEL = 1u << 2; /** Default constructor where all parameter properties are false */ - AnyParameterProperties() : m_description(), m_mask_attribute(0x00000000) + AnyParameterProperties() + : m_description("No description given"), m_attribute_mask(0) { } /** Constructor @@ -55,69 +56,50 @@ namespace shogun * */ AnyParameterProperties( std::string description, - EModelSelectionAvailability model_selection = MS_NOT_AVAILABLE, + EModelSelectionAvailability hyperparameter = MS_NOT_AVAILABLE, EGradientAvailability gradient = GRADIENT_NOT_AVAILABLE, - bool hyperparameter = false) - : m_description(description), m_model_selection(model_selection), + bool model = false) + : m_description(description), m_model_selection(hyperparameter), m_gradient(gradient) { - m_mask_attribute = 0x00000000; - if (model_selection) - m_mask_attribute |= MODEL_PARAM; - if (gradient) - m_mask_attribute |= GRADIENT_PARAM; - if (hyperparameter) - m_mask_attribute |= HYPERPARAMETER; + m_attribute_mask = (hyperparameter << 0 & HYPER) | + (gradient << 1 & GRADIENT) | + (model << 2 & MODEL); } /** Mask constructor * @param description parameter description * @param attribute_mask mask encoding parameter properties * */ + AnyParameterProperties(std::string description, int32_t attribute_mask) : m_description(description) { - m_mask_attribute = mask_attribute; + m_attribute_mask = attribute_mask; } /** Copy contructor */ AnyParameterProperties(const AnyParameterProperties& other) : m_description(other.m_description), m_model_selection(other.m_model_selection), m_gradient(other.m_gradient), - m_mask_attribute(other.m_mask_attribute) + m_attribute_mask(other.m_attribute_mask) { } const std::string& get_description() const - std::string get_description() const { return m_description; } EModelSelectionAvailability get_model_selection() const { - EModelSelectionAvailability return_val; - if (m_mask_attribute & HYPERPARAMETER) - return_val = EModelSelectionAvailability::MS_AVAILABLE; - else - return_val = EModelSelectionAvailability::MS_NOT_AVAILABLE; - return return_val; + return static_cast( + (m_attribute_mask & HYPER) > 0); } - EGradientAvailability get_gradient() const { - EGradientAvailability return_val; - if (m_mask_attribute & GRADIENT_PARAM) - return_val = EGradientAvailability::GRADIENT_AVAILABLE; - else - return_val = EGradientAvailability::GRADIENT_NOT_AVAILABLE; - return return_val; + return static_cast( + (m_attribute_mask & GRADIENT) > 0); } - - bool get_hyperparameter() const + bool get_model() const { - bool return_val; - if (m_mask_attribute & HYPERPARAMETER) - return_val = true; - else - return_val = false; - return return_val; + return static_cast(m_attribute_mask & MODEL); } private: @@ -125,7 +107,6 @@ namespace shogun EModelSelectionAvailability m_model_selection; EGradientAvailability m_gradient; int32_t m_attribute_mask; - int32_t m_mask_attribute; }; class AnyParameter diff --git a/src/shogun/base/SGObject.h b/src/shogun/base/SGObject.h index e9909a595e4..19b606f5cd4 100644 --- a/src/shogun/base/SGObject.h +++ b/src/shogun/base/SGObject.h @@ -677,9 +677,9 @@ class CSGObject const std::string& name, T* value, AnyParameterProperties properties = AnyParameterProperties( "Unknown parameter", - AnyParameterProperties::HYPERPARAMETER | - AnyParameterProperties::GRADIENT_PARAM | - AnyParameterProperties::MODEL_PARAM)) + AnyParameterProperties::HYPER | + AnyParameterProperties::GRADIENT | + AnyParameterProperties::MODEL)) { BaseTag tag(name); create_parameter(tag, AnyParameter(make_any_ref(value), properties)); @@ -696,11 +696,7 @@ class CSGObject template void watch_param( const std::string& name, T** value, S* len, - AnyParameterProperties properties = AnyParameterProperties( - "Unknown parameter", - AnyParameterProperties::HYPERPARAMETER | - AnyParameterProperties::GRADIENT_PARAM | - AnyParameterProperties::MODEL_PARAM)) + AnyParameterProperties properties = AnyParameterProperties()) { BaseTag tag(name); create_parameter( @@ -720,11 +716,7 @@ class CSGObject template void watch_param( const std::string& name, T** value, S* rows, S* cols, - AnyParameterProperties properties = AnyParameterProperties( - "Unknown parameter", - AnyParameterProperties::HYPERPARAMETER | - AnyParameterProperties::GRADIENT_PARAM | - AnyParameterProperties::MODEL_PARAM)) + AnyParameterProperties properties = AnyParameterProperties()) { BaseTag tag(name); create_parameter( @@ -743,9 +735,9 @@ class CSGObject BaseTag tag(name); AnyParameterProperties properties( "Dynamic parameter", - AnyParameterProperties::HYPERPARAMETER | - AnyParameterProperties::GRADIENT_PARAM | - AnyParameterProperties::MODEL_PARAM); + !AnyParameterProperties::HYPER | + !AnyParameterProperties::GRADIENT | + !AnyParameterProperties::MODEL); std::function bind_method = std::bind(method, dynamic_cast(this)); create_parameter(tag, AnyParameter(make_any(bind_method), properties)); From dfb5aea94159c028cfe81893b862660b15724693 Mon Sep 17 00:00:00 2001 From: Gil Date: Wed, 14 Nov 2018 08:46:48 +0000 Subject: [PATCH 6/7] typesafe bitmasking --- src/shogun/base/AnyParameter.h | 20 ++++-- src/shogun/lib/bitmask_operators.h | 110 +++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+), 4 deletions(-) create mode 100644 src/shogun/lib/bitmask_operators.h diff --git a/src/shogun/base/AnyParameter.h b/src/shogun/base/AnyParameter.h index 81d819d9f88..7eaeafb9cab 100644 --- a/src/shogun/base/AnyParameter.h +++ b/src/shogun/base/AnyParameter.h @@ -8,6 +8,7 @@ #define __ANYPARAMETER_H__ #include +#include #include @@ -27,10 +28,21 @@ namespace shogun GRADIENT_NOT_AVAILABLE = 0, GRADIENT_AVAILABLE = 1 }; - /** @brief Class AnyParameterProperties keeps track of parameter properties. - * The parameter properties can be either true or false. - * These properties describe if a parameter is for example a hyperparameter - * or if it has a gradient. + + /** parameter properties */ + enum class ParameterProperties + { + HYPER = 1u << 0, + GRADIENT = 1u << 1, + MODEL = 1u << 2 + }; + + enableEnumClassBitmask(ParameterProperties); + + /** @brief Class AnyParameterProperties keeps track of of parameter meta + * information, such as properties and descriptions The parameter properties + * can be either true or false. These properties describe if a parameter is + * for example a hyperparameter or if it has a gradient. */ class AnyParameterProperties { diff --git a/src/shogun/lib/bitmask_operators.h b/src/shogun/lib/bitmask_operators.h new file mode 100644 index 00000000000..5417dea17cb --- /dev/null +++ b/src/shogun/lib/bitmask_operators.h @@ -0,0 +1,110 @@ +#ifndef JSS_BITMASK_HPP +#define JSS_BITMASK_HPP + +// (C) Copyright 2015 Just Software Solutions Ltd +// +// Distributed under the Boost Software License, Version 1.0. +// +// Boost Software License - Version 1.0 - August 17th, 2003 +// +// Permission is hereby granted, free of charge, to any person or +// organization obtaining a copy of the software and accompanying +// documentation covered by this license (the "Software") to use, +// reproduce, display, distribute, execute, and transmit the +// Software, and to prepare derivative works of the Software, and +// to permit third-parties to whom the Software is furnished to +// do so, all subject to the following: +// +// The copyright notices in the Software and this entire +// statement, including the above license grant, this restriction +// and the following disclaimer, must be included in all copies +// of the Software, in whole or in part, and all derivative works +// of the Software, unless such copies or derivative works are +// solely in the form of machine-executable object code generated +// by a source language processor. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +// KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +// WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR +// PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +// COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE +// LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN +// CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#include + +namespace shogun { + + template + struct enable_bitmask_operators { + static constexpr bool enable = false; + }; + + #define enableEnumClassBitmask(T) template<> \ + struct enable_bitmask_operators \ + { \ + static constexpr bool enable = true; \ + } + + template + typename std::enable_if::enable, E>::type + operator|(E lhs, E rhs) { + typedef typename std::underlying_type::type underlying; + return static_cast( + static_cast(lhs) | static_cast(rhs)); + } + + template + typename std::enable_if::enable, E>::type + operator&(E lhs, E rhs) { + typedef typename std::underlying_type::type underlying; + return static_cast( + static_cast(lhs) & static_cast(rhs)); + } + + template + typename std::enable_if::enable, E>::type + operator^(E lhs, E rhs) { + typedef typename std::underlying_type::type underlying; + return static_cast( + static_cast(lhs) ^ static_cast(rhs)); + } + + template + typename std::enable_if::enable, E>::type + operator~(E lhs) { + typedef typename std::underlying_type::type underlying; + return static_cast( + ~static_cast(lhs)); + } + + template + typename std::enable_if::enable, E &>::type + operator|=(E &lhs, E rhs) { + typedef typename std::underlying_type::type underlying; + lhs = static_cast( + static_cast(lhs) | static_cast(rhs)); + return lhs; + } + + template + typename std::enable_if::enable, E &>::type + operator&=(E &lhs, E rhs) { + typedef typename std::underlying_type::type underlying; + lhs = static_cast( + static_cast(lhs) & static_cast(rhs)); + return lhs; + } + + template + typename std::enable_if::enable, E &>::type + operator^=(E &lhs, E rhs) { + typedef typename std::underlying_type::type underlying; + lhs = static_cast( + static_cast(lhs) ^ static_cast(rhs)); + return lhs; + } +} +#endif \ No newline at end of file From 2bf79c4a72896810f9f53d9a5ee0621808946803 Mon Sep 17 00:00:00 2001 From: Gil Date: Wed, 14 Nov 2018 09:09:19 +0000 Subject: [PATCH 7/7] refactored code to use enum class and bitmask operators --- src/shogun/base/AnyParameter.h | 31 ++++++++++++++++++------------- src/shogun/base/SGObject.h | 12 ++++-------- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/shogun/base/AnyParameter.h b/src/shogun/base/AnyParameter.h index 7eaeafb9cab..4cc8f80db66 100644 --- a/src/shogun/base/AnyParameter.h +++ b/src/shogun/base/AnyParameter.h @@ -47,14 +47,11 @@ namespace shogun class AnyParameterProperties { public: - static const int32_t HYPER = 1u << 0; - static const int32_t GRADIENT = 1u << 1; - static const int32_t MODEL = 1u << 2; - /** Default constructor where all parameter properties are false */ AnyParameterProperties() - : m_description("No description given"), m_attribute_mask(0) + : m_description("No description given"), + m_attribute_mask(ParameterProperties()) { } /** Constructor @@ -74,15 +71,20 @@ namespace shogun : m_description(description), m_model_selection(hyperparameter), m_gradient(gradient) { - m_attribute_mask = (hyperparameter << 0 & HYPER) | - (gradient << 1 & GRADIENT) | - (model << 2 & MODEL); + m_attribute_mask = ParameterProperties(); + if (hyperparameter) + m_attribute_mask |= ParameterProperties::HYPER; + if (gradient) + m_attribute_mask |= ParameterProperties::GRADIENT; + if (model) + m_attribute_mask |= ParameterProperties::MODEL; } /** Mask constructor * @param description parameter description * @param attribute_mask mask encoding parameter properties * */ - AnyParameterProperties(std::string description, int32_t attribute_mask) + AnyParameterProperties( + std::string description, ParameterProperties attribute_mask) : m_description(description) { m_attribute_mask = attribute_mask; @@ -102,23 +104,26 @@ namespace shogun EModelSelectionAvailability get_model_selection() const { return static_cast( - (m_attribute_mask & HYPER) > 0); + static_cast( + m_attribute_mask & ParameterProperties::HYPER) > 0); } EGradientAvailability get_gradient() const { return static_cast( - (m_attribute_mask & GRADIENT) > 0); + static_cast( + m_attribute_mask & ParameterProperties::GRADIENT) > 0); } bool get_model() const { - return static_cast(m_attribute_mask & MODEL); + return static_cast( + m_attribute_mask & ParameterProperties::MODEL); } private: std::string m_description; EModelSelectionAvailability m_model_selection; EGradientAvailability m_gradient; - int32_t m_attribute_mask; + ParameterProperties m_attribute_mask; }; class AnyParameter diff --git a/src/shogun/base/SGObject.h b/src/shogun/base/SGObject.h index 19b606f5cd4..7aefd5b82f8 100644 --- a/src/shogun/base/SGObject.h +++ b/src/shogun/base/SGObject.h @@ -675,11 +675,7 @@ class CSGObject template void watch_param( const std::string& name, T* value, - AnyParameterProperties properties = AnyParameterProperties( - "Unknown parameter", - AnyParameterProperties::HYPER | - AnyParameterProperties::GRADIENT | - AnyParameterProperties::MODEL)) + AnyParameterProperties properties = AnyParameterProperties()) { BaseTag tag(name); create_parameter(tag, AnyParameter(make_any_ref(value), properties)); @@ -735,9 +731,9 @@ class CSGObject BaseTag tag(name); AnyParameterProperties properties( "Dynamic parameter", - !AnyParameterProperties::HYPER | - !AnyParameterProperties::GRADIENT | - !AnyParameterProperties::MODEL); + ParameterProperties::HYPER | + ParameterProperties::GRADIENT | + ParameterProperties::MODEL); std::function bind_method = std::bind(method, dynamic_cast(this)); create_parameter(tag, AnyParameter(make_any(bind_method), properties));