From 6d675049bafcb87aafcf1e51abe79d163858e196 Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Wed, 31 Jul 2024 21:47:49 +0200 Subject: [PATCH 01/37] Add classes IQuantization, IQuantizationFactory and IQuantizationConfig. --- .../mlrl/boosting/statistics/quantization.hpp | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization.hpp diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization.hpp new file mode 100644 index 0000000000..5064585722 --- /dev/null +++ b/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization.hpp @@ -0,0 +1,53 @@ +/* + * @author Michael Rapp (michael.rapp.ml@gmail.com) + */ +#pragma once + +#include + +namespace boosting { + + /** + * Defines an interface for all classes that implement a method for quantizing statistics about the quality of + * predictions for training examples. + */ + class IQuantization { + public: + + virtual ~IQuantization() {} + }; + + /** + * Defines an interface for all factories that allows to create instances of the type `IQuantization`. + */ + class IQuantizationFactory { + public: + + virtual ~IQuantizationFactory() {} + + /** + * Creates and returns a new object of type `IQuantization`. + * + * @return An unique pointer to an object of type `IQuantization` that has been created + */ + virtual std::unique_ptr create() const = 0; + }; + + /** + * Defines an interface for all classes that allow to configure a method for quantizing statistics about the quality + * of predictions for training examples. + */ + class IQuantizationConfig { + public: + + virtual ~IQuantizationConfig() {} + + /** + * Creates and returns a new object of type `IQuantizationFactory` according to the specified configuration. + * + * @return An unique pointer to an object of type `IQuantizationFactory` that has been created + */ + virtual std::unique_ptr createQuantizationFactory() const = 0; + }; + +} From 8a460759dc4db84cbf79e986a13b8d06fecdc88e Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Wed, 31 Jul 2024 21:48:01 +0200 Subject: [PATCH 02/37] Add class NoQuantizationConfig. --- .../boosting/statistics/quantization_no.hpp | 22 ++++++++++++++++ cpp/subprojects/boosting/meson.build | 1 + .../boosting/statistics/quantization_no.cpp | 25 +++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization_no.hpp create mode 100644 cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_no.cpp diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization_no.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization_no.hpp new file mode 100644 index 0000000000..b0ba1f1643 --- /dev/null +++ b/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization_no.hpp @@ -0,0 +1,22 @@ +/* + * @author Michael Rapp (michael.rapp.ml@gmail.com) + */ +#pragma once + +#include "mlrl/boosting/statistics/quantization.hpp" + +#include + +namespace boosting { + + /** + * Defines an interface for all classes that allow to configure a method for quantizing statistics that does not + * actually perform any quantization. + */ + class NoQuantizationConfig final : public IQuantizationConfig { + public: + + std::unique_ptr createQuantizationFactory() const override; + }; + +} diff --git a/cpp/subprojects/boosting/meson.build b/cpp/subprojects/boosting/meson.build index 2fffd1816f..80cb230ced 100644 --- a/cpp/subprojects/boosting/meson.build +++ b/cpp/subprojects/boosting/meson.build @@ -62,6 +62,7 @@ source_files = [ 'src/mlrl/boosting/rule_evaluation/rule_evaluation_non_decomposable_partial_fixed_binned.cpp', 'src/mlrl/boosting/rule_model_assemblage/default_rule_auto.cpp', 'src/mlrl/boosting/sampling/partition_sampling_auto.cpp', + 'src/mlrl/boosting/statistics/quantization_no.cpp', 'src/mlrl/boosting/statistics/statistic_format_auto.cpp', 'src/mlrl/boosting/statistics/statistic_format_dense.cpp', 'src/mlrl/boosting/statistics/statistic_format_sparse.cpp', diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_no.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_no.cpp new file mode 100644 index 0000000000..d3ad99335a --- /dev/null +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_no.cpp @@ -0,0 +1,25 @@ +#include "mlrl/boosting/statistics/quantization_no.hpp" + +namespace boosting { + + /** + * An implementation of the type `IQuantization` that does not actually perform any quantization. + */ + class NoQuantization final : public IQuantization {}; + + /** + * Allows to to create instances of the type `IQuantization` that do not actually perform any quantization. + */ + class NoQuantizationFactory final : public IQuantizationFactory { + public: + + std::unique_ptr create() const override { + return std::make_unique(); + } + }; + + std::unique_ptr NoQuantizationConfig::createQuantizationFactory() const { + return std::make_unique(); + } + +} From 061ed218c18d8054d18e34f01fcd03663fd74060 Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Wed, 31 Jul 2024 21:59:08 +0200 Subject: [PATCH 03/37] Add function "getQuantizationConfig" to class IBoostedRuleLearnerConfig. --- .../boosting/include/mlrl/boosting/learner.hpp | 11 +++++++++++ .../boosting/include/mlrl/boosting/learner_common.hpp | 9 +++++++++ 2 files changed, 20 insertions(+) diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/learner.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/learner.hpp index b99a9860ee..5df422eb95 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/learner.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/learner.hpp @@ -20,6 +20,8 @@ #include "mlrl/boosting/rule_evaluation/regularization_no.hpp" #include "mlrl/boosting/rule_model_assemblage/default_rule_auto.hpp" #include "mlrl/boosting/sampling/partition_sampling_auto.hpp" +#include "mlrl/boosting/statistics/quantization.hpp" +#include "mlrl/boosting/statistics/quantization_no.hpp" #include "mlrl/boosting/statistics/statistic_format.hpp" #include "mlrl/boosting/statistics/statistic_format_auto.hpp" #include "mlrl/boosting/statistics/statistic_format_dense.hpp" @@ -77,6 +79,15 @@ namespace boosting { */ virtual SharedProperty getRegressionStatisticsConfig() = 0; + /** + * Returns a `Property` that allows to access the `IQuantizationConfig` that stores the configuration of the + * method for quantizing statistics about the quality of predictions for the training examples. + * + * @return A `Property` that allows to access the `IQuantizationConfig` that stores the configuration of the + * method for quantizing statistics about the quality of predictions for the training examples + */ + virtual Property getQuantizationConfig() = 0; + /** * Returns a `Property` that allows to access the `IRegularizationConfig` that stores the configuration of * the L1 regularization term. diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/learner_common.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/learner_common.hpp index 6e87b58f2f..c17f0071a8 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/learner_common.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/learner_common.hpp @@ -91,6 +91,11 @@ namespace boosting { */ std::shared_ptr regressionStatisticsConfigPtr_; + /** + * An unique pointer that stores the configuration of the method for quantizing statistics. + */ + std::unique_ptr quantizationConfigPtr_; + /** * A shared pointer that stores the configuration of the loss function that should be used in classification * problems. @@ -143,6 +148,10 @@ namespace boosting { return util::sharedProperty(regressionStatisticsConfigPtr_); } + Property getQuantizationConfig() override final { + return util::property(quantizationConfigPtr_); + } + Property getL1RegularizationConfig() override final { return util::property(l1RegularizationConfigPtr_); } From 348ab8646ee8a27fef9a384d8500b50c74fe091e Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Wed, 31 Jul 2024 21:59:17 +0200 Subject: [PATCH 04/37] Add class INoQuantizationMixin. --- .../include/mlrl/boosting/learner.hpp | 21 +++++++++++++++++++ .../boosting/mlrl/boosting/cython/learner.pxd | 7 +++++++ .../boosting/mlrl/boosting/cython/learner.pyx | 15 +++++++++++++ .../mlrl/boosting/cython/learner_boomer.pxd | 6 ++++-- .../mlrl/boosting/cython/learner_boomer.pyx | 10 ++++++++- 5 files changed, 56 insertions(+), 3 deletions(-) diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/learner.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/learner.hpp index 5df422eb95..58dc29e515 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/learner.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/learner.hpp @@ -306,6 +306,25 @@ namespace boosting { } }; + /** + * Defines an interface for all classes that allow to configure a rule learner to not quantize statistics about the + * quality of predictions for the training examples. + */ + class MLRLBOOSTING_API INoQuantizationMixin : public virtual IBoostedRuleLearnerConfig { + public: + + virtual ~INoQuantizationMixin() override {} + + /** + * Configures the rule learner to not quantize statistics about the quality of predictions for the training + * examples. + */ + virtual void useNoQuantization() { + Property property = this->getQuantizationConfig(); + property.set(std::make_unique()); + } + }; + /** * Defines an interface for all classes that allow to configure a rule learner to not use L1 regularization. */ @@ -610,6 +629,7 @@ namespace boosting { virtual public IDefaultRuleMixin, virtual public INoL1RegularizationMixin, virtual public INoL2RegularizationMixin, + virtual public INoQuantizationMixin, virtual public INoLabelBinningMixin { public: @@ -622,6 +642,7 @@ namespace boosting { IRuleLearnerMixin::useDefaults(); this->useNoL1Regularization(); this->useNoL2Regularization(); + this->useNoQuantization(); this->useNoLabelBinning(); } }; diff --git a/python/subprojects/boosting/mlrl/boosting/cython/learner.pxd b/python/subprojects/boosting/mlrl/boosting/cython/learner.pxd index 5a4139c164..d90a08d8e7 100644 --- a/python/subprojects/boosting/mlrl/boosting/cython/learner.pxd +++ b/python/subprojects/boosting/mlrl/boosting/cython/learner.pxd @@ -41,6 +41,13 @@ cdef extern from "mlrl/boosting/learner.hpp" namespace "boosting" nogil: IConstantShrinkageConfig& useConstantShrinkagePostProcessor() + cdef cppclass INoQuantizationMixin: + + # Functions: + + void useNoQuantization() + + cdef cppclass INoL1RegularizationMixin: # Functions: diff --git a/python/subprojects/boosting/mlrl/boosting/cython/learner.pyx b/python/subprojects/boosting/mlrl/boosting/cython/learner.pyx index d5a4da062d..063e203c35 100644 --- a/python/subprojects/boosting/mlrl/boosting/cython/learner.pyx +++ b/python/subprojects/boosting/mlrl/boosting/cython/learner.pyx @@ -126,6 +126,21 @@ class L2RegularizationMixin(ABC): pass +class NoQuantizationMixin(ABC): + """ + Allows to configure a rule learner to not quantize statistics about the quality of predictions for the training + examples. + """ + + @abstractmethod + def use_no_quantization(self): + """ + Configures the rule learner to not quantize statistics about the quality of predictions for the training + examples. + """ + pass + + class CompleteHeadMixin(ABC): """ Allows to configure a rule learner to induce rules with complete heads that predict for all available outputs. diff --git a/python/subprojects/boosting/mlrl/boosting/cython/learner_boomer.pxd b/python/subprojects/boosting/mlrl/boosting/cython/learner_boomer.pxd index 9c9c192b2c..4e5da8187f 100644 --- a/python/subprojects/boosting/mlrl/boosting/cython/learner_boomer.pxd +++ b/python/subprojects/boosting/mlrl/boosting/cython/learner_boomer.pxd @@ -22,8 +22,8 @@ from mlrl.boosting.cython.learner cimport DdotFunction, DspmvFunction, DsysvFunc IAutomaticHeadMixin, IAutomaticParallelRuleRefinementMixin, IAutomaticParallelStatisticUpdateMixin, \ ICompleteHeadMixin, IConstantShrinkageMixin, IDecomposableSquaredErrorLossMixin, IDynamicPartialHeadMixin, \ IFixedPartialHeadMixin, IL1RegularizationMixin, IL2RegularizationMixin, INoL1RegularizationMixin, \ - INoL2RegularizationMixin, INonDecomposableSquaredErrorLossMixin, IOutputWiseScorePredictorMixin, \ - ISingleOutputHeadMixin + INoL2RegularizationMixin, INonDecomposableSquaredErrorLossMixin, INoQuantizationMixin, \ + IOutputWiseScorePredictorMixin, ISingleOutputHeadMixin from mlrl.boosting.cython.learner_classification cimport IAutomaticBinaryPredictorMixin, IAutomaticDefaultRuleMixin, \ IAutomaticLabelBinningMixin, IAutomaticPartitionSamplingMixin, IAutomaticProbabilityPredictorMixin, \ IAutomaticStatisticsMixin, IDecomposableLogisticLossMixin, IDecomposableSquaredHingeLossMixin, \ @@ -47,6 +47,7 @@ cdef extern from "mlrl/boosting/learner_boomer_classifier.hpp" namespace "boosti IL1RegularizationMixin, INoL2RegularizationMixin, IL2RegularizationMixin, + INoQuantizationMixin, INoDefaultRuleMixin, IDefaultRuleMixin, IAutomaticDefaultRuleMixin, @@ -144,6 +145,7 @@ cdef extern from "mlrl/boosting/learner_boomer_regressor.hpp" namespace "boostin IL1RegularizationMixin, INoL2RegularizationMixin, IL2RegularizationMixin, + INoQuantizationMixin, INoDefaultRuleMixin, IDefaultRuleMixin, IAutomaticDefaultRuleMixin, diff --git a/python/subprojects/boosting/mlrl/boosting/cython/learner_boomer.pyx b/python/subprojects/boosting/mlrl/boosting/cython/learner_boomer.pyx index 34a701d946..63beb1b87a 100644 --- a/python/subprojects/boosting/mlrl/boosting/cython/learner_boomer.pyx +++ b/python/subprojects/boosting/mlrl/boosting/cython/learner_boomer.pyx @@ -61,7 +61,7 @@ from mlrl.boosting.cython.learner import AutomaticFeatureBinningMixin, Automatic AutomaticParallelRuleRefinementMixin, AutomaticParallelStatisticUpdateMixin, CompleteHeadMixin, \ ConstantShrinkageMixin, DecomposableSquaredErrorLossMixin, DynamicPartialHeadMixin, FixedPartialHeadMixin, \ L1RegularizationMixin, L2RegularizationMixin, NoL1RegularizationMixin, NoL2RegularizationMixin, \ - NonDecomposableSquaredErrorLossMixin, OutputWiseScorePredictorMixin, SingleOutputHeadMixin + NonDecomposableSquaredErrorLossMixin, NoQuantizationMixin, OutputWiseScorePredictorMixin, SingleOutputHeadMixin from mlrl.boosting.cython.learner_classification import AutomaticBinaryPredictorMixin, AutomaticDefaultRuleMixin, \ AutomaticLabelBinningMixin, AutomaticPartitionSamplingMixin, AutomaticProbabilityPredictorMixin, \ AutomaticStatisticsMixin, DecomposableLogisticLossMixin, DecomposableSquaredHingeLossMixin, DenseStatisticsMixin, \ @@ -83,6 +83,7 @@ cdef class BoomerClassifierConfig(RuleLearnerConfig, L1RegularizationMixin, NoL2RegularizationMixin, L2RegularizationMixin, + NoQuantizationMixin, NoDefaultRuleMixin, DefaultRuleMixin, AutomaticDefaultRuleMixin, @@ -462,6 +463,9 @@ cdef class BoomerClassifierConfig(RuleLearnerConfig, config.config_ptr = config_ptr return config + def use_no_quantization(self): + self.config_ptr.get().useNoQuantization() + def use_non_decomposable_logistic_loss(self): self.config_ptr.get().useNonDecomposableLogisticLoss() @@ -586,6 +590,7 @@ cdef class BoomerRegressorConfig(RuleLearnerConfig, L1RegularizationMixin, NoL2RegularizationMixin, L2RegularizationMixin, + NoQuantizationMixin, NoDefaultRuleMixin, DefaultRuleMixin, AutomaticDefaultRuleMixin, @@ -886,6 +891,9 @@ cdef class BoomerRegressorConfig(RuleLearnerConfig, config.config_ptr = config_ptr return config + def use_no_quantization(self): + self.config_ptr.get().useNoQuantization() + def use_non_decomposable_squared_error_loss(self): self.config_ptr.get().useNonDecomposableSquaredErrorLoss() From 0d1cd7ae40fe7d907af82b36e5466676619f6d8e Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Wed, 31 Jul 2024 22:10:03 +0200 Subject: [PATCH 05/37] Add class StochasticQuantizationConfig. --- .../statistics/quantization_stochastic.hpp | 60 +++++++++++++++++++ cpp/subprojects/boosting/meson.build | 1 + .../statistics/quantization_stochastic.cpp | 48 +++++++++++++++ python/subprojects/boosting/meson.build | 1 + .../mlrl/boosting/cython/quantization.pxd | 19 ++++++ .../mlrl/boosting/cython/quantization.pyx | 30 ++++++++++ 6 files changed, 159 insertions(+) create mode 100644 cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization_stochastic.hpp create mode 100644 cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp create mode 100644 python/subprojects/boosting/mlrl/boosting/cython/quantization.pxd create mode 100644 python/subprojects/boosting/mlrl/boosting/cython/quantization.pyx diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization_stochastic.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization_stochastic.hpp new file mode 100644 index 0000000000..4d7e05a8a6 --- /dev/null +++ b/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization_stochastic.hpp @@ -0,0 +1,60 @@ +/* + * @author Michael Rapp (michael.rapp.ml@gmail.com) + */ +#pragma once + +#include "mlrl/boosting/statistics/quantization.hpp" +#include "mlrl/common/data/types.hpp" // TODO Remove later + +#include + +namespace boosting { + + /** + * Defines an interface for all classes that allow to configure a method for quantizing statistics that uses a + * stochastic rounding strategy. + */ + class IStochasticQuantizationConfig { + public: + + virtual ~IStochasticQuantizationConfig() {} + + /** + * Returns the number of bits that are used for quantized statistics. + * + * @return The number of bits that are used + */ + virtual uint32 getNumBits() const = 0; + + /** + * Sets the number of bits to be used for quantized statistics. + * + * @param numBits The number of bits to be used. Must be greater than 0 + * @return A reference to an object of type `IStochasticQuantizationConfig` that allows further + * configuration of the quantization method + */ + virtual IStochasticQuantizationConfig& setNumBits(uint32 numBits) = 0; + }; + + /** + * Defines an interface for all classes that allow to configure a method for quantizing statistics that uses a + * stochastic rounding strategy. + */ + class StochasticQuantizationConfig final : public IQuantizationConfig, + public IStochasticQuantizationConfig { + private: + + uint32 numBits_; + + public: + + StochasticQuantizationConfig(); + + uint32 getNumBits() const override; + + IStochasticQuantizationConfig& setNumBits(uint32 numBits) override; + + std::unique_ptr createQuantizationFactory() const override; + }; + +} diff --git a/cpp/subprojects/boosting/meson.build b/cpp/subprojects/boosting/meson.build index 80cb230ced..6752a9eccf 100644 --- a/cpp/subprojects/boosting/meson.build +++ b/cpp/subprojects/boosting/meson.build @@ -63,6 +63,7 @@ source_files = [ 'src/mlrl/boosting/rule_model_assemblage/default_rule_auto.cpp', 'src/mlrl/boosting/sampling/partition_sampling_auto.cpp', 'src/mlrl/boosting/statistics/quantization_no.cpp', + 'src/mlrl/boosting/statistics/quantization_stochastic.cpp', 'src/mlrl/boosting/statistics/statistic_format_auto.cpp', 'src/mlrl/boosting/statistics/statistic_format_dense.cpp', 'src/mlrl/boosting/statistics/statistic_format_sparse.cpp', diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp new file mode 100644 index 0000000000..ce7446320f --- /dev/null +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp @@ -0,0 +1,48 @@ +#include "mlrl/boosting/statistics/quantization_stochastic.hpp" + +#include "mlrl/common/util/validation.hpp" + +namespace boosting { + + /** + * An implementation of the type `IQuantization` that uses a stochastic rounding strategy. + */ + class StochasticQuantization final : public IQuantization {}; + + /** + * Allows to to create instances of the type `IQuantization` that uses a stochastic rounding strategy. + */ + class StochasticQuantizationFactory final : public IQuantizationFactory { + private: + + uint32 numBits_; + + public: + + /** + * @param numBits The number of bits to be used for quantized statistics + */ + StochasticQuantizationFactory(uint32 numBits) : numBits_(numBits) {} + + std::unique_ptr create() const override { + return std::make_unique(); + } + }; + + StochasticQuantizationConfig::StochasticQuantizationConfig() : numBits_(4) {} + + uint32 StochasticQuantizationConfig::getNumBits() const { + return numBits_; + } + + IStochasticQuantizationConfig& StochasticQuantizationConfig::setNumBits(uint32 numBits) { + util::assertGreater("numBits", numBits, 0); + numBits_ = numBits; + return *this; + } + + std::unique_ptr StochasticQuantizationConfig::createQuantizationFactory() const { + return std::make_unique(numBits_); + } + +} diff --git a/python/subprojects/boosting/meson.build b/python/subprojects/boosting/meson.build index 02bfec7ab9..f76cb4d24c 100644 --- a/python/subprojects/boosting/meson.build +++ b/python/subprojects/boosting/meson.build @@ -12,6 +12,7 @@ cython_module_names = [ 'post_processor', 'prediction', 'probability_calibration', + 'quantization', 'regularization' ] diff --git a/python/subprojects/boosting/mlrl/boosting/cython/quantization.pxd b/python/subprojects/boosting/mlrl/boosting/cython/quantization.pxd new file mode 100644 index 0000000000..d4cbc8dbc0 --- /dev/null +++ b/python/subprojects/boosting/mlrl/boosting/cython/quantization.pxd @@ -0,0 +1,19 @@ +from mlrl.common.cython._types cimport uint32 + + +cdef extern from "mlrl/boosting/statistics/quantization_stochastic.hpp" namespace "boosting" nogil: + + cdef cppclass IStochasticQuantizationConfig: + + # Functions: + + uint32 getNumBits() const + + IStochasticQuantizationConfig& setNumBits(uint32 numBits) except + + + +cdef class StochasticQuantizationConfig: + + # Attributes: + + cdef IStochasticQuantizationConfig* config_ptr diff --git a/python/subprojects/boosting/mlrl/boosting/cython/quantization.pyx b/python/subprojects/boosting/mlrl/boosting/cython/quantization.pyx new file mode 100644 index 0000000000..f4437e064f --- /dev/null +++ b/python/subprojects/boosting/mlrl/boosting/cython/quantization.pyx @@ -0,0 +1,30 @@ +""" +@author: Michael Rapp (michael.rapp.ml@gmail.com) +""" +from mlrl.common.cython.validation import assert_greater + + +cdef class StochasticQuantizationConfig: + """ + Allows to configure a method for quantizing statistics that uses a stochastic rounding strategy. + """ + + def get_num_bits(self) -> int: + """ + Returns the number of bits that are used used for quantized statistics. + + :return: The number of bits that are used + """ + return self.config_ptr.getNumBits() + + def set_num_bits(self, num_bits: int) -> StochasticQuantizationConfig: + """ + Sets the number of bits to be used for quantized statistics. + + :param num_bits: The number of bits to be used. Must be greater than 0 + :return: An `StochasticQuantizationConfig` that allows further configuration of the quantization + method + """ + assert_greater('num_bits', num_bits, 0) + self.config_ptr.setNumBits(num_bits) + return self From 01f7829bccf846b7a0b1b5a21e89319bd6467bb4 Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Wed, 31 Jul 2024 22:23:29 +0200 Subject: [PATCH 06/37] Add class IStochasticQuantizationMixin. --- .../include/mlrl/boosting/learner.hpp | 26 +++++++++++++++++++ .../boosting/learner_boomer_classifier.hpp | 1 + .../boosting/learner_boomer_regressor.hpp | 1 + .../boosting/mlrl/boosting/cython/learner.pxd | 7 +++++ .../boosting/mlrl/boosting/cython/learner.pyx | 17 ++++++++++++ .../mlrl/boosting/cython/learner_boomer.pxd | 4 ++- .../mlrl/boosting/cython/learner_boomer.pyx | 18 ++++++++++++- 7 files changed, 72 insertions(+), 2 deletions(-) diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/learner.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/learner.hpp index 58dc29e515..23ec541e32 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/learner.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/learner.hpp @@ -22,6 +22,7 @@ #include "mlrl/boosting/sampling/partition_sampling_auto.hpp" #include "mlrl/boosting/statistics/quantization.hpp" #include "mlrl/boosting/statistics/quantization_no.hpp" +#include "mlrl/boosting/statistics/quantization_stochastic.hpp" #include "mlrl/boosting/statistics/statistic_format.hpp" #include "mlrl/boosting/statistics/statistic_format_auto.hpp" #include "mlrl/boosting/statistics/statistic_format_dense.hpp" @@ -325,6 +326,31 @@ namespace boosting { } }; + /** + * Defines an interface for all classes that allow to configure a rule learner to quantize statistics using a + * stochastic rounding strategy. + */ + class MLRLBOOSTING_API IStochasticQuantizationMixin : public virtual IBoostedRuleLearnerConfig { + public: + + virtual ~IStochasticQuantizationMixin() override {} + + /** + * Configures the rule learner to quantize statistics about the quality of predictions for the training + * examples using a stochastic rounding strategy. + * + * @return A reference to an object of type `IStochasticQuantizationConfig` that allows further + * configuration of the quantization method + */ + virtual IStochasticQuantizationConfig& useStochasticQuantization() { + Property property = this->getQuantizationConfig(); + std::unique_ptr ptr = std::make_unique(); + IStochasticQuantizationConfig& ref = *ptr; + property.set(std::move(ptr)); + return ref; + } + }; + /** * Defines an interface for all classes that allow to configure a rule learner to not use L1 regularization. */ diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/learner_boomer_classifier.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/learner_boomer_classifier.hpp index 06beb4343b..5fa6c68bd3 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/learner_boomer_classifier.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/learner_boomer_classifier.hpp @@ -36,6 +36,7 @@ namespace boosting { virtual public IDenseStatisticsMixin, virtual public ISparseStatisticsMixin, virtual public IAutomaticStatisticsMixin, + virtual public IStochasticQuantizationMixin, virtual public IDecomposableLogisticLossMixin, virtual public IDecomposableSquaredErrorLossMixin, virtual public IDecomposableSquaredHingeLossMixin, diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/learner_boomer_regressor.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/learner_boomer_regressor.hpp index 65701427f2..d764cac8dd 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/learner_boomer_regressor.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/learner_boomer_regressor.hpp @@ -37,6 +37,7 @@ namespace boosting { virtual public IDenseStatisticsMixin, virtual public ISparseStatisticsMixin, virtual public IAutomaticStatisticsMixin, + virtual public IStochasticQuantizationMixin, virtual public IDecomposableSquaredErrorLossMixin, virtual public INonDecomposableSquaredErrorLossMixin, virtual public IOutputWiseScorePredictorMixin, diff --git a/python/subprojects/boosting/mlrl/boosting/cython/learner.pxd b/python/subprojects/boosting/mlrl/boosting/cython/learner.pxd index d90a08d8e7..0169888d72 100644 --- a/python/subprojects/boosting/mlrl/boosting/cython/learner.pxd +++ b/python/subprojects/boosting/mlrl/boosting/cython/learner.pxd @@ -1,5 +1,6 @@ from mlrl.boosting.cython.head_type cimport IDynamicPartialHeadConfig, IFixedPartialHeadConfig from mlrl.boosting.cython.post_processor cimport IConstantShrinkageConfig +from mlrl.boosting.cython.quantization cimport IStochasticQuantizationConfig from mlrl.boosting.cython.regularization cimport IManualRegularizationConfig ctypedef double (*DdotFunction)(int* n, double* dx, int* incx, double* dy, int* incy) @@ -47,6 +48,12 @@ cdef extern from "mlrl/boosting/learner.hpp" namespace "boosting" nogil: void useNoQuantization() + cdef cppclass IStochasticQuantizationMixin: + + # Functions: + + IStochasticQuantizationConfig& useStochasticQuantization() + cdef cppclass INoL1RegularizationMixin: diff --git a/python/subprojects/boosting/mlrl/boosting/cython/learner.pyx b/python/subprojects/boosting/mlrl/boosting/cython/learner.pyx index 063e203c35..cb5ef5d1a0 100644 --- a/python/subprojects/boosting/mlrl/boosting/cython/learner.pyx +++ b/python/subprojects/boosting/mlrl/boosting/cython/learner.pyx @@ -5,6 +5,7 @@ from abc import ABC, abstractmethod from mlrl.boosting.cython.head_type import DynamicPartialHeadConfig, FixedPartialHeadConfig from mlrl.boosting.cython.post_processor import ConstantShrinkageConfig +from mlrl.boosting.cython.quantization import StochasticQuantizationConfig from mlrl.boosting.cython.regularization import ManualRegularizationConfig @@ -141,6 +142,22 @@ class NoQuantizationMixin(ABC): pass +class StochasticQuantizationMixin(ABC): + """ + Allows to configure a rule learner to quantize statistics using a stochastic rounding strategy. + """ + + @abstractmethod + def use_stochastic_quantization(self) -> StochasticQuanizationConfig: + """ + Configures the rule learner to quantize statistics about the quality of predictions for the training examples + using a stochastic rounding strategy. + + :return: A `StochasticQuantizationConfig` that allows further configuration of the quantization method + """ + pass + + class CompleteHeadMixin(ABC): """ Allows to configure a rule learner to induce rules with complete heads that predict for all available outputs. diff --git a/python/subprojects/boosting/mlrl/boosting/cython/learner_boomer.pxd b/python/subprojects/boosting/mlrl/boosting/cython/learner_boomer.pxd index 4e5da8187f..6c3ee59d77 100644 --- a/python/subprojects/boosting/mlrl/boosting/cython/learner_boomer.pxd +++ b/python/subprojects/boosting/mlrl/boosting/cython/learner_boomer.pxd @@ -23,7 +23,7 @@ from mlrl.boosting.cython.learner cimport DdotFunction, DspmvFunction, DsysvFunc ICompleteHeadMixin, IConstantShrinkageMixin, IDecomposableSquaredErrorLossMixin, IDynamicPartialHeadMixin, \ IFixedPartialHeadMixin, IL1RegularizationMixin, IL2RegularizationMixin, INoL1RegularizationMixin, \ INoL2RegularizationMixin, INonDecomposableSquaredErrorLossMixin, INoQuantizationMixin, \ - IOutputWiseScorePredictorMixin, ISingleOutputHeadMixin + IOutputWiseScorePredictorMixin, ISingleOutputHeadMixin, IStochasticQuantizationMixin from mlrl.boosting.cython.learner_classification cimport IAutomaticBinaryPredictorMixin, IAutomaticDefaultRuleMixin, \ IAutomaticLabelBinningMixin, IAutomaticPartitionSamplingMixin, IAutomaticProbabilityPredictorMixin, \ IAutomaticStatisticsMixin, IDecomposableLogisticLossMixin, IDecomposableSquaredHingeLossMixin, \ @@ -48,6 +48,7 @@ cdef extern from "mlrl/boosting/learner_boomer_classifier.hpp" namespace "boosti INoL2RegularizationMixin, IL2RegularizationMixin, INoQuantizationMixin, + IStochasticQuantizationMixin, INoDefaultRuleMixin, IDefaultRuleMixin, IAutomaticDefaultRuleMixin, @@ -146,6 +147,7 @@ cdef extern from "mlrl/boosting/learner_boomer_regressor.hpp" namespace "boostin INoL2RegularizationMixin, IL2RegularizationMixin, INoQuantizationMixin, + IStochasticQuantizationMixin, INoDefaultRuleMixin, IDefaultRuleMixin, IAutomaticDefaultRuleMixin, diff --git a/python/subprojects/boosting/mlrl/boosting/cython/learner_boomer.pyx b/python/subprojects/boosting/mlrl/boosting/cython/learner_boomer.pyx index 63beb1b87a..ecddc1f556 100644 --- a/python/subprojects/boosting/mlrl/boosting/cython/learner_boomer.pyx +++ b/python/subprojects/boosting/mlrl/boosting/cython/learner_boomer.pyx @@ -39,6 +39,7 @@ from mlrl.boosting.cython.prediction cimport ExampleWiseBinaryPredictorConfig, G from mlrl.boosting.cython.probability_calibration cimport IIsotonicJointProbabilityCalibratorConfig, \ IIsotonicMarginalProbabilityCalibratorConfig, IsotonicJointProbabilityCalibratorConfig, \ IsotonicMarginalProbabilityCalibratorConfig +from mlrl.boosting.cython.quantization cimport IStochasticQuantizationConfig, StochasticQuantizationConfig from mlrl.boosting.cython.regularization cimport IManualRegularizationConfig, ManualRegularizationConfig from mlrl.common.cython.learner import BeamSearchTopDownRuleInductionMixin, DefaultRuleMixin, \ @@ -61,7 +62,8 @@ from mlrl.boosting.cython.learner import AutomaticFeatureBinningMixin, Automatic AutomaticParallelRuleRefinementMixin, AutomaticParallelStatisticUpdateMixin, CompleteHeadMixin, \ ConstantShrinkageMixin, DecomposableSquaredErrorLossMixin, DynamicPartialHeadMixin, FixedPartialHeadMixin, \ L1RegularizationMixin, L2RegularizationMixin, NoL1RegularizationMixin, NoL2RegularizationMixin, \ - NonDecomposableSquaredErrorLossMixin, NoQuantizationMixin, OutputWiseScorePredictorMixin, SingleOutputHeadMixin + NonDecomposableSquaredErrorLossMixin, NoQuantizationMixin, OutputWiseScorePredictorMixin, SingleOutputHeadMixin, \ + StochasticQuantizationMixin from mlrl.boosting.cython.learner_classification import AutomaticBinaryPredictorMixin, AutomaticDefaultRuleMixin, \ AutomaticLabelBinningMixin, AutomaticPartitionSamplingMixin, AutomaticProbabilityPredictorMixin, \ AutomaticStatisticsMixin, DecomposableLogisticLossMixin, DecomposableSquaredHingeLossMixin, DenseStatisticsMixin, \ @@ -84,6 +86,7 @@ cdef class BoomerClassifierConfig(RuleLearnerConfig, NoL2RegularizationMixin, L2RegularizationMixin, NoQuantizationMixin, + StochasticQuantizationMixin, NoDefaultRuleMixin, DefaultRuleMixin, AutomaticDefaultRuleMixin, @@ -466,6 +469,12 @@ cdef class BoomerClassifierConfig(RuleLearnerConfig, def use_no_quantization(self): self.config_ptr.get().useNoQuantization() + def use_stochastic_quantization(self) -> StochasticQuantizationConfig: + cdef IStochasticQuantizationConfig* config_ptr = &self.config_ptr.get().useStochasticQuantization() + cdef StochasticQuantizationConfig config = StochasticQuantizationConfig.__new__(StochasticQuantizationConfig) + config.config_ptr = config_ptr + return config + def use_non_decomposable_logistic_loss(self): self.config_ptr.get().useNonDecomposableLogisticLoss() @@ -591,6 +600,7 @@ cdef class BoomerRegressorConfig(RuleLearnerConfig, NoL2RegularizationMixin, L2RegularizationMixin, NoQuantizationMixin, + StochasticQuantizationMixin, NoDefaultRuleMixin, DefaultRuleMixin, AutomaticDefaultRuleMixin, @@ -894,6 +904,12 @@ cdef class BoomerRegressorConfig(RuleLearnerConfig, def use_no_quantization(self): self.config_ptr.get().useNoQuantization() + def use_stochastic_quantization(self) -> StochasticQuantizationConfig: + cdef IStochasticQuantizationConfig* config_ptr = &self.config_ptr.get().useStochasticQuantization() + cdef StochasticQuantizationConfig config = StochasticQuantizationConfig.__new__(StochasticQuantizationConfig) + config.config_ptr = config_ptr + return config + def use_non_decomposable_squared_error_loss(self): self.config_ptr.get().useNonDecomposableSquaredErrorLoss() From 90e5e689911f3fd27b06aa37c845ac04b0bc848d Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Wed, 31 Jul 2024 23:29:31 +0200 Subject: [PATCH 07/37] Add parameter "quantization" to BoomerClassifier. --- doc/user_guide/boosting/parameters.md | 16 +++++++++++ .../mlrl/boosting/boosting_learners.py | 5 ++++ .../boosting/mlrl/boosting/config.py | 27 ++++++++++++++++++- 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/doc/user_guide/boosting/parameters.md b/doc/user_guide/boosting/parameters.md index c1ccbcc8b4..4e20f1cd31 100644 --- a/doc/user_guide/boosting/parameters.md +++ b/doc/user_guide/boosting/parameters.md @@ -598,6 +598,22 @@ The following parameters can be used to control various approximation and optimi A sparse format is used for the representation of gradients and Hessians, if supported by the loss function. ``` +### `quantization` + +> *Default value = `'none'`.* + +```{glossary} +`'none'` + No quantization is used. + +`'stochastic'` + Gradients and Hessians are quantized using a stochastic rounding strategy. The following options may be provided using the {ref}`bracket notation`: + + - `num_bits` *(Default value = `4`)* + + The number of bits to be used for quantized gradients and Hessians. The given value must be at least 1. +``` + ## Probability Calibration The following parameters enable to learn calibration models that should be included in a model and may result in more accurate probability estimates being predicted. diff --git a/python/subprojects/boosting/mlrl/boosting/boosting_learners.py b/python/subprojects/boosting/mlrl/boosting/boosting_learners.py index 93d799b170..95ce491018 100644 --- a/python/subprojects/boosting/mlrl/boosting/boosting_learners.py +++ b/python/subprojects/boosting/mlrl/boosting/boosting_learners.py @@ -48,6 +48,7 @@ def __init__(self, shrinkage: Optional[float] = 0.3, l1_regularization_weight: Optional[float] = None, l2_regularization_weight: Optional[float] = None, + quantization: Optional[str] = None, parallel_rule_refinement: Optional[str] = None, parallel_statistic_update: Optional[str] = None, parallel_prediction: Optional[str] = None): @@ -132,6 +133,9 @@ def __init__(self, used to shrink the weight of individual rules. Must be in (0, 1] :param l1_regularization_weight: The weight of the L1 regularization. Must be at least 0 :param l2_regularization_weight: The weight of the L2 regularization. Must be at least 0 + :param quantization: The method that should be used for quantizing gradients and + Hessians. Must be one 'stochastic' or 'none', if no quantization + should be used :param parallel_rule_refinement: Whether potential refinements of rules should be searched for in parallel or not. Must be 'true', 'false' or 'auto', if the most suitable strategy should be chosen automatically depending on the @@ -170,6 +174,7 @@ def __init__(self, self.shrinkage = shrinkage self.l1_regularization_weight = l1_regularization_weight self.l2_regularization_weight = l2_regularization_weight + self.quantization = quantization self.parallel_rule_refinement = parallel_rule_refinement self.parallel_statistic_update = parallel_statistic_update self.parallel_prediction = parallel_prediction diff --git a/python/subprojects/boosting/mlrl/boosting/config.py b/python/subprojects/boosting/mlrl/boosting/config.py index cc27461cd1..c261a86fcb 100644 --- a/python/subprojects/boosting/mlrl/boosting/config.py +++ b/python/subprojects/boosting/mlrl/boosting/config.py @@ -16,7 +16,7 @@ AutomaticParallelStatisticUpdateMixin, CompleteHeadMixin, ConstantShrinkageMixin, \ DecomposableSquaredErrorLossMixin, DynamicPartialHeadMixin, FixedPartialHeadMixin, L1RegularizationMixin, \ L2RegularizationMixin, NoL1RegularizationMixin, NoL2RegularizationMixin, NonDecomposableSquaredErrorLossMixin, \ - SingleOutputHeadMixin + NoQuantizationMixin, SingleOutputHeadMixin, StochasticQuantizationMixin from mlrl.boosting.cython.learner_classification import AutomaticBinaryPredictorMixin, AutomaticDefaultRuleMixin, \ AutomaticLabelBinningMixin, AutomaticPartitionSamplingMixin, AutomaticProbabilityPredictorMixin, \ AutomaticStatisticsMixin, DecomposableLogisticLossMixin, DecomposableSquaredHingeLossMixin, DenseStatisticsMixin, \ @@ -211,6 +211,30 @@ def _configure(self, config, value: str, _: Optional[Options]): config.use_automatic_statistics() +class QuantizationParameter(NominalParameter): + """ + A parameter that allows to configure the method to be used for quantizing gradients and Hessians. + """ + + QUANTIZATION_STOCHASTIC = 'stochastic' + + OPTION_NUM_BITS = 'num_bits' + + def __init__(self): + super().__init__(name='quantization', description='The method to be used for quantizing gradients and Hessians') + self.add_value(name=NONE, mixin=NoQuantizationMixin) + self.add_value(name=self.QUANTIZATION_STOCHASTIC, + mixin=StochasticQuantizationMixin, + options={self.OPTION_NUM_BITS}) + + def _configure(self, config, value: str, options: Optional[Options]): + if value == NONE: + config.use_no_quantization() + elif value == self.QUANTIZATION_STOCHASTIC: + conf = config.use_stochastic_quantization() + conf.set_num_bits(options.get_int(self.OPTION_NUM_BITS, conf.get_num_bits())) + + class LabelBinningParameter(NominalParameter): """ A parameter that allows to configure the strategy to be used for gradient-based label binning (GBLB). @@ -489,6 +513,7 @@ def _configure(self, config, value: str, options: Optional[Options]): L2RegularizationParameter(), DefaultRuleParameter(), StatisticFormatParameter(), + QuantizationParameter(), LabelBinningParameter(), ClassificationLossParameter(), HeadTypeParameter(), From 06404e0a21097e999525144eb45e81d2a1958940 Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Thu, 1 Aug 2024 00:26:29 +0200 Subject: [PATCH 08/37] Add member "quantizationPtr_" to class AbstractStatistics. --- .../include/mlrl/boosting/learner.hpp | 23 +++--- .../rule_evaluation/head_type_auto.hpp | 9 ++- .../rule_evaluation/head_type_complete.hpp | 9 ++- .../head_type_partial_dynamic.hpp | 8 ++- .../head_type_partial_fixed.hpp | 8 ++- .../rule_evaluation/head_type_single.hpp | 9 ++- ...statistics_provider_decomposable_dense.hpp | 13 ++++ ...tatistics_provider_decomposable_sparse.hpp | 7 ++ ...istics_provider_non_decomposable_dense.hpp | 25 +++++++ .../rule_evaluation/head_type_auto.cpp | 32 +++++---- .../rule_evaluation/head_type_complete.cpp | 40 +++++++---- .../head_type_partial_dynamic.cpp | 46 +++++++----- .../head_type_partial_fixed.cpp | 46 +++++++----- .../rule_evaluation/head_type_single.cpp | 47 ++++++++----- .../boosting/statistics/statistics_common.hpp | 13 +++- .../statistics_decomposable_common.hpp | 9 ++- .../statistics_decomposable_dense.hpp | 8 ++- .../statistics_non_decomposable_common.hpp | 9 ++- ...statistics_provider_decomposable_dense.cpp | 31 ++++---- ...tatistics_provider_decomposable_sparse.cpp | 27 ++++--- ...istics_provider_non_decomposable_dense.cpp | 70 +++++++++++-------- 21 files changed, 330 insertions(+), 159 deletions(-) diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/learner.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/learner.hpp index 23ec541e32..c731da9278 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/learner.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/learner.hpp @@ -475,8 +475,9 @@ namespace boosting { */ virtual void useCompleteHeads() { this->getHeadConfig().set(std::make_unique( - this->getLabelBinningConfig(), this->getParallelStatisticUpdateConfig(), - this->getL1RegularizationConfig(), this->getL2RegularizationConfig())); + this->getQuantizationConfig(), this->getLabelBinningConfig(), + this->getParallelStatisticUpdateConfig(), this->getL1RegularizationConfig(), + this->getL2RegularizationConfig())); } }; @@ -497,8 +498,9 @@ namespace boosting { * the rule heads */ virtual IFixedPartialHeadConfig& useFixedPartialHeads() { - auto ptr = std::make_unique(this->getLabelBinningConfig(), - this->getParallelStatisticUpdateConfig()); + auto ptr = + std::make_unique(this->getQuantizationConfig(), this->getLabelBinningConfig(), + this->getParallelStatisticUpdateConfig()); IFixedPartialHeadConfig& ref = *ptr; this->getHeadConfig().set(std::move(ptr)); return ref; @@ -523,7 +525,8 @@ namespace boosting { * the rule heads */ virtual IDynamicPartialHeadConfig& useDynamicPartialHeads() { - auto ptr = std::make_unique(this->getLabelBinningConfig(), + auto ptr = std::make_unique(this->getQuantizationConfig(), + this->getLabelBinningConfig(), this->getParallelStatisticUpdateConfig()); IDynamicPartialHeadConfig& ref = *ptr; this->getHeadConfig().set(std::move(ptr)); @@ -545,8 +548,9 @@ namespace boosting { */ virtual void useSingleOutputHeads() { this->getHeadConfig().set(std::make_unique( - this->getLabelBinningConfig(), this->getParallelStatisticUpdateConfig(), - this->getL1RegularizationConfig(), this->getL2RegularizationConfig())); + this->getQuantizationConfig(), this->getLabelBinningConfig(), + this->getParallelStatisticUpdateConfig(), this->getL1RegularizationConfig(), + this->getL2RegularizationConfig())); } }; @@ -564,8 +568,9 @@ namespace boosting { */ virtual void useAutomaticHeads() { this->getHeadConfig().set(std::make_unique( - this->getLossConfig(), this->getLabelBinningConfig(), this->getParallelStatisticUpdateConfig(), - this->getL1RegularizationConfig(), this->getL2RegularizationConfig())); + this->getQuantizationConfig(), this->getLossConfig(), this->getLabelBinningConfig(), + this->getParallelStatisticUpdateConfig(), this->getL1RegularizationConfig(), + this->getL2RegularizationConfig())); } }; diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/head_type_auto.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/head_type_auto.hpp index 615a2dfa73..ca9d95f8fd 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/head_type_auto.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/head_type_auto.hpp @@ -6,6 +6,7 @@ #include "mlrl/boosting/binning/label_binning.hpp" #include "mlrl/boosting/rule_evaluation/head_type.hpp" #include "mlrl/boosting/rule_evaluation/regularization.hpp" +#include "mlrl/boosting/statistics/quantization.hpp" #include "mlrl/common/multi_threading/multi_threading.hpp" #include "mlrl/common/util/properties.hpp" @@ -19,6 +20,8 @@ namespace boosting { class AutomaticHeadConfig final : public IHeadConfig { private: + const ReadableProperty quantizationConfig_; + const ReadableProperty lossConfig_; const ReadableProperty labelBinningConfig_; @@ -32,6 +35,9 @@ namespace boosting { public: /** + * @param quantizationConfig A `ReadableProperty` that allows to access the `IQuantizationConfig` that + * stores the configuration of the method for quantizing gradients and + * Hessians * @param lossConfig A `ReadableProperty` that allows to access the `ILossConfig` that stores * the configuration of the loss function * @param labelBinningConfig A `ReadableProperty` that allows to access the `ILabelBinningConfig` that @@ -44,7 +50,8 @@ namespace boosting { * @param l2RegularizationConfig A `ReadableProperty` that allows to access the `IRegularizationConfig` * that stores the configuration of the L2 regularization */ - AutomaticHeadConfig(ReadableProperty lossConfig, + AutomaticHeadConfig(ReadableProperty quantizationConfig, + ReadableProperty lossConfig, ReadableProperty labelBinningConfig, ReadableProperty multiThreadingConfig, ReadableProperty l1RegularizationConfig, diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/head_type_complete.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/head_type_complete.hpp index f4cf14b76e..cf9b69fc28 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/head_type_complete.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/head_type_complete.hpp @@ -6,6 +6,7 @@ #include "mlrl/boosting/binning/label_binning.hpp" #include "mlrl/boosting/rule_evaluation/head_type.hpp" #include "mlrl/boosting/rule_evaluation/regularization.hpp" +#include "mlrl/boosting/statistics/quantization.hpp" #include "mlrl/common/multi_threading/multi_threading.hpp" #include "mlrl/common/util/properties.hpp" @@ -19,6 +20,8 @@ namespace boosting { class CompleteHeadConfig final : public IHeadConfig { private: + const ReadableProperty quantizationConfig_; + const ReadableProperty labelBinningConfig_; const ReadableProperty multiThreadingConfig_; @@ -30,6 +33,9 @@ namespace boosting { public: /** + * @param quantizationConfig A `ReadableProperty` that allows to access the `IQuantizationConfig` that + * stores the configuration of the method for quantizing gradients and + * Hessians * @param labelBinningConfig A `ReadableProperty` that allows to access the `ILabelBinningConfig` that * stores the configuration of the method for assigning labels to bins * @param multiThreadingConfig A `ReadableProperty` that allows to access the `IMultiThreadingConfig` @@ -40,7 +46,8 @@ namespace boosting { * @param l2RegularizationConfig A `ReadableProperty` that allows to access the `IRegularizationConfig` * that stores the configuration of the L2 regularization */ - CompleteHeadConfig(ReadableProperty labelBinningConfig, + CompleteHeadConfig(ReadableProperty quantizationConfig, + ReadableProperty labelBinningConfig, ReadableProperty multiThreadingConfig, ReadableProperty l1RegularizationConfig, ReadableProperty l2RegularizationConfig); diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/head_type_partial_dynamic.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/head_type_partial_dynamic.hpp index 26f48ecdc6..6063ba898e 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/head_type_partial_dynamic.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/head_type_partial_dynamic.hpp @@ -6,6 +6,7 @@ #include "mlrl/boosting/binning/label_binning.hpp" #include "mlrl/boosting/rule_evaluation/head_type.hpp" #include "mlrl/boosting/rule_evaluation/regularization.hpp" +#include "mlrl/boosting/statistics/quantization.hpp" #include "mlrl/boosting/util/dll_exports.hpp" #include "mlrl/common/multi_threading/multi_threading.hpp" #include "mlrl/common/util/properties.hpp" @@ -77,6 +78,8 @@ namespace boosting { float32 exponent_; + const ReadableProperty quantizationConfig_; + const ReadableProperty labelBinningConfig_; const ReadableProperty multiThreadingConfig_; @@ -84,13 +87,16 @@ namespace boosting { public: /** + * @param quantizationConfig A `ReadableProperty` that allows to access the `IQuantizationConfig` that + * stores the configuration of the method for quantizing gradients and Hessians * @param labelBinningConfig A `ReadableProperty` that allows to access the `ILabelBinningConfig` that * stores the configuration of the method for assigning labels to bins * @param multiThreadingConfig A `ReadableProperty` that allows to access the `IMultiThreadingConfig` that * stores the configuration of the multi-threading behavior that should be used * for the parallel update of statistics */ - DynamicPartialHeadConfig(ReadableProperty labelBinningConfig, + DynamicPartialHeadConfig(ReadableProperty quantizationConfig, + ReadableProperty labelBinningConfig, ReadableProperty multiThreadingConfig); float32 getThreshold() const override; diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/head_type_partial_fixed.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/head_type_partial_fixed.hpp index c26af6dac1..a06f5b2894 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/head_type_partial_fixed.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/head_type_partial_fixed.hpp @@ -6,6 +6,7 @@ #include "mlrl/boosting/binning/label_binning.hpp" #include "mlrl/boosting/rule_evaluation/head_type.hpp" #include "mlrl/boosting/rule_evaluation/regularization.hpp" +#include "mlrl/boosting/statistics/quantization.hpp" #include "mlrl/boosting/util/dll_exports.hpp" #include "mlrl/common/multi_threading/multi_threading.hpp" #include "mlrl/common/util/properties.hpp" @@ -92,6 +93,8 @@ namespace boosting { uint32 maxOutputs_; + const ReadableProperty quantizationConfig_; + const ReadableProperty labelBinningConfig_; const ReadableProperty multiThreadingConfig_; @@ -99,13 +102,16 @@ namespace boosting { public: /** + * @param quantizationConfig A `ReadableProperty` that allows to access the `IQuantizationConfig` that + * stores the configuration of the method for quantizing gradients and Hessians * @param labelBinningConfig A `ReadableProperty` that allows to access the `ILabelBinningConfig` that * stores the configuration of the method for assigning labels to bins * @param multiThreadingConfig A `ReadableProperty` that allows to access the `IMultiThreadingConfig` that * stores the configuration of the multi-threading behavior that should be used * for the parallel update of statistics */ - FixedPartialHeadConfig(ReadableProperty labelBinningConfig, + FixedPartialHeadConfig(ReadableProperty quantizationConfig, + ReadableProperty labelBinningConfig, ReadableProperty multiThreadingConfig); float32 getOutputRatio() const override; diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/head_type_single.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/head_type_single.hpp index d35511fe2b..4584d2acfd 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/head_type_single.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/head_type_single.hpp @@ -6,6 +6,7 @@ #include "mlrl/boosting/binning/label_binning.hpp" #include "mlrl/boosting/rule_evaluation/head_type.hpp" #include "mlrl/boosting/rule_evaluation/regularization.hpp" +#include "mlrl/boosting/statistics/quantization.hpp" #include "mlrl/common/multi_threading/multi_threading.hpp" #include "mlrl/common/util/properties.hpp" @@ -19,6 +20,8 @@ namespace boosting { class SingleOutputHeadConfig final : public IHeadConfig { private: + const ReadableProperty quantizationConfig_; + const ReadableProperty labelBinningConfig_; const ReadableProperty multiThreadingConfig_; @@ -30,6 +33,9 @@ namespace boosting { public: /** + * @param quantizationConfig A `ReadableProperty` that allows to access the `IQuantizationConfig` that + * stores the configuration of the method for quantizing gradients and + * Hessians * @param labelBinningConfig A `ReadableProperty` that allows to access the `ILabelBinningConfig` that * stores the configuration of the method for assigning labels to bins * @param multiThreadingConfig A `ReadableProperty` that allows to access the `IMultiThreadingConfig` @@ -40,7 +46,8 @@ namespace boosting { * @param l2RegularizationConfig A `ReadableProperty` that allows to access the `IRegularizationConfig` * that stores the configuration of the L2 regularization */ - SingleOutputHeadConfig(ReadableProperty labelBinningConfig, + SingleOutputHeadConfig(ReadableProperty quantizationConfig, + ReadableProperty labelBinningConfig, ReadableProperty multiThreadingConfig, ReadableProperty l1RegularizationConfig, ReadableProperty l2RegularizationConfig); diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/statistics/statistics_provider_decomposable_dense.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/statistics/statistics_provider_decomposable_dense.hpp index 4218db5db7..81fd8f394f 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/statistics/statistics_provider_decomposable_dense.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/statistics/statistics_provider_decomposable_dense.hpp @@ -5,6 +5,7 @@ #pragma once #include "mlrl/boosting/losses/loss_decomposable.hpp" +#include "mlrl/boosting/statistics/quantization.hpp" #include "mlrl/boosting/statistics/statistics_decomposable.hpp" #include "mlrl/common/multi_threading/multi_threading.hpp" #include "mlrl/common/statistics/statistics_provider.hpp" @@ -22,6 +23,8 @@ namespace boosting { : public IClassificationStatisticsProviderFactory { private: + const std::unique_ptr quantizationFactoryPtr_; + const std::unique_ptr lossFactoryPtr_; const std::unique_ptr evaluationMeasureFactoryPtr_; @@ -37,6 +40,9 @@ namespace boosting { public: /** + * @param quantizationFactoryPtr An unique pointer to an object of type `IQuantizationFactory` + * that allows to create implementations of the method that should + * be used for quantizing gradients and Hessians * @param lossFactoryPtr An unique pointer to an object of type * `IDecomposableClassificationLossFactory` that allows to create * implementations of the loss function that should be used for @@ -62,6 +68,7 @@ namespace boosting { * parallel */ DenseDecomposableClassificationStatisticsProviderFactory( + std::unique_ptr quantizationFactoryPtr, std::unique_ptr lossFactoryPtr, std::unique_ptr evaluationMeasureFactoryPtr, std::unique_ptr defaultRuleEvaluationFactoryPtr, @@ -87,6 +94,8 @@ namespace boosting { class DenseDecomposableRegressionStatisticsProviderFactory final : public IRegressionStatisticsProviderFactory { private: + const std::unique_ptr quantizationFactoryPtr_; + const std::unique_ptr lossFactoryPtr_; const std::unique_ptr evaluationMeasureFactoryPtr_; @@ -102,6 +111,9 @@ namespace boosting { public: /** + * @param quantizationFactoryPtr An unique pointer to an object of type `IQuantizationFactory` + * that allows to create implementations of the method that should + * be used for quantizing gradients and Hessians * @param lossFactoryPtr An unique pointer to an object of type * `IDecomposableRegressionLossFactory` that allows to create * implementations of the loss function that should be used for @@ -127,6 +139,7 @@ namespace boosting { * parallel */ DenseDecomposableRegressionStatisticsProviderFactory( + std::unique_ptr quantizationFactoryPtr, std::unique_ptr lossFactoryPtr, std::unique_ptr evaluationMeasureFactoryPtr, std::unique_ptr defaultRuleEvaluationFactoryPtr, diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/statistics/statistics_provider_decomposable_sparse.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/statistics/statistics_provider_decomposable_sparse.hpp index 60f609fc10..ec2c62c164 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/statistics/statistics_provider_decomposable_sparse.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/statistics/statistics_provider_decomposable_sparse.hpp @@ -5,6 +5,7 @@ #include "mlrl/boosting/losses/loss_decomposable_sparse.hpp" #include "mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_sparse.hpp" +#include "mlrl/boosting/statistics/quantization.hpp" #include "mlrl/boosting/statistics/statistics_decomposable.hpp" #include "mlrl/common/multi_threading/multi_threading.hpp" #include "mlrl/common/statistics/statistics_provider.hpp" @@ -22,6 +23,8 @@ namespace boosting { : public IClassificationStatisticsProviderFactory { private: + const std::unique_ptr quantizationFactoryPtr_; + const std::unique_ptr lossFactoryPtr_; const std::unique_ptr evaluationMeasureFactoryPtr_; @@ -35,6 +38,9 @@ namespace boosting { public: /** + * @param quantizationFactoryPtr An unique pointer to an object of type `IQuantizationFactory` + * that allows to create implementations of the method that should + * be used for quantizing gradients and Hessians * @param lossFactoryPtr An unique pointer to an object of type * `ISparseDecomposableClassificationLossFactory` that allows to * create implementations of the loss function that should be used @@ -56,6 +62,7 @@ namespace boosting { * parallel */ SparseDecomposableClassificationStatisticsProviderFactory( + std::unique_ptr quantizationFactoryPtr, std::unique_ptr lossFactoryPtr, std::unique_ptr evaluationMeasureFactoryPtr, std::unique_ptr regularRuleEvaluationFactoryPtr, diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.hpp index 57e6da1d52..95de22e6ca 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.hpp @@ -5,6 +5,7 @@ #pragma once #include "mlrl/boosting/losses/loss_non_decomposable.hpp" +#include "mlrl/boosting/statistics/quantization.hpp" #include "mlrl/boosting/statistics/statistics_non_decomposable.hpp" #include "mlrl/common/multi_threading/multi_threading.hpp" #include "mlrl/common/statistics/statistics_provider.hpp" @@ -22,6 +23,8 @@ namespace boosting { : public IClassificationStatisticsProviderFactory { private: + const std::unique_ptr quantizationFactoryPtr_; + const std::unique_ptr lossFactoryPtr_; const std::unique_ptr evaluationMeasureFactoryPtr_; @@ -37,6 +40,9 @@ namespace boosting { public: /** + * @param quantizationFactoryPtr An unique pointer to an object of type `IQuantizationFactory` + * that allows to create implementations of the method that should + * be used for quantizing gradients and Hessians * @param lossFactoryPtr An unique pointer to an object of type * `INonDecomposableClassificationLossFactory` that allows to * create implementations of the loss function that should be used @@ -62,6 +68,7 @@ namespace boosting { * parallel */ DenseNonDecomposableClassificationStatisticsProviderFactory( + std::unique_ptr quantizationFactoryPtr, std::unique_ptr lossFactoryPtr, std::unique_ptr evaluationMeasureFactoryPtr, std::unique_ptr defaultRuleEvaluationFactoryPtr, @@ -87,6 +94,8 @@ namespace boosting { class DenseNonDecomposableRegressionStatisticsProviderFactory final : public IRegressionStatisticsProviderFactory { private: + const std::unique_ptr quantizationFactoryPtr_; + const std::unique_ptr lossFactoryPtr_; const std::unique_ptr evaluationMeasureFactoryPtr_; @@ -102,6 +111,9 @@ namespace boosting { public: /** + * @param quantizationFactoryPtr An unique pointer to an object of type `IQuantizationFactory` + * that allows to create implementations of the method that should + * be used for quantizing gradients and Hessians * @param lossFactoryPtr An unique pointer to an object of type * `INonDecomposableRegressionLossFactory` that allows to create * implementations of the loss function that should be used for @@ -127,6 +139,7 @@ namespace boosting { * parallel */ DenseNonDecomposableRegressionStatisticsProviderFactory( + std::unique_ptr quantizationFactoryPtr, std::unique_ptr lossFactoryPtr, std::unique_ptr evaluationMeasureFactoryPtr, std::unique_ptr defaultRuleEvaluationFactoryPtr, @@ -155,6 +168,8 @@ namespace boosting { : public IClassificationStatisticsProviderFactory { private: + const std::unique_ptr quantizationFactoryPtr_; + const std::unique_ptr lossFactoryPtr_; const std::unique_ptr evaluationMeasureFactoryPtr_; @@ -170,6 +185,9 @@ namespace boosting { public: /** + * @param quantizationFactoryPtr An unique pointer to an object of type `IQuantizationFactory` + * that allows to create implementations of the method that should + * be used for quantizing gradients and Hessians * @param lossFactoryPtr An unique pointer to an object of type * `INonDecomposableClassificationLossFactory` that allows to * create implementations of the loss function that should be used @@ -195,6 +213,7 @@ namespace boosting { * parallel */ DenseConvertibleNonDecomposableClassificationStatisticsProviderFactory( + std::unique_ptr quantizationFactoryPtr, std::unique_ptr lossFactoryPtr, std::unique_ptr evaluationMeasureFactoryPtr, std::unique_ptr defaultRuleEvaluationFactoryPtr, @@ -222,6 +241,8 @@ namespace boosting { : public IRegressionStatisticsProviderFactory { private: + const std::unique_ptr quantizationFactoryPtr_; + const std::unique_ptr lossFactoryPtr_; const std::unique_ptr evaluationMeasureFactoryPtr_; @@ -237,6 +258,9 @@ namespace boosting { public: /** + * @param quantizationFactoryPtr An unique pointer to an object of type `IQuantizationFactory` + * that allows to create implementations of the method that should + * be used for quantizing gradients and Hessians * @param lossFactoryPtr An unique pointer to an object of type * `INonDecomposableRegressionLossFactory` that allows to create * implementations of the loss function that should be used for @@ -262,6 +286,7 @@ namespace boosting { * parallel */ DenseConvertibleNonDecomposableRegressionStatisticsProviderFactory( + std::unique_ptr quantizationFactoryPtr, std::unique_ptr lossFactoryPtr, std::unique_ptr evaluationMeasureFactoryPtr, std::unique_ptr defaultRuleEvaluationFactoryPtr, diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/head_type_auto.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/head_type_auto.cpp index 2641c708ac..327e6632f4 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/head_type_auto.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/head_type_auto.cpp @@ -5,20 +5,22 @@ namespace boosting { - AutomaticHeadConfig::AutomaticHeadConfig(ReadableProperty lossConfig, + AutomaticHeadConfig::AutomaticHeadConfig(ReadableProperty quantizationConfig, + ReadableProperty lossConfig, ReadableProperty labelBinningConfig, ReadableProperty multiThreadingConfig, ReadableProperty l1RegularizationConfig, ReadableProperty l2RegularizationConfig) - : lossConfig_(lossConfig), labelBinningConfig_(labelBinningConfig), multiThreadingConfig_(multiThreadingConfig), - l1RegularizationConfig_(l1RegularizationConfig), l2RegularizationConfig_(l2RegularizationConfig) {} + : quantizationConfig_(quantizationConfig), lossConfig_(lossConfig), labelBinningConfig_(labelBinningConfig), + multiThreadingConfig_(multiThreadingConfig), l1RegularizationConfig_(l1RegularizationConfig), + l2RegularizationConfig_(l2RegularizationConfig) {} std::unique_ptr AutomaticHeadConfig::createClassificationStatisticsProviderFactory( const IFeatureMatrix& featureMatrix, const IRowWiseLabelMatrix& labelMatrix, const IDecomposableClassificationLossConfig& lossConfig) const { - CompleteHeadConfig headConfig(labelBinningConfig_, multiThreadingConfig_, l1RegularizationConfig_, - l2RegularizationConfig_); + CompleteHeadConfig headConfig(quantizationConfig_, labelBinningConfig_, multiThreadingConfig_, + l1RegularizationConfig_, l2RegularizationConfig_); return headConfig.createClassificationStatisticsProviderFactory(featureMatrix, labelMatrix, lossConfig); } @@ -27,12 +29,12 @@ namespace boosting { const IFeatureMatrix& featureMatrix, const IRowWiseLabelMatrix& labelMatrix, const ISparseDecomposableClassificationLossConfig& lossConfig) const { if (labelMatrix.getNumOutputs() > 1) { - SingleOutputHeadConfig headConfig(labelBinningConfig_, multiThreadingConfig_, l1RegularizationConfig_, - l2RegularizationConfig_); + SingleOutputHeadConfig headConfig(quantizationConfig_, labelBinningConfig_, multiThreadingConfig_, + l1RegularizationConfig_, l2RegularizationConfig_); return headConfig.createClassificationStatisticsProviderFactory(featureMatrix, labelMatrix, lossConfig); } else { - CompleteHeadConfig headConfig(labelBinningConfig_, multiThreadingConfig_, l1RegularizationConfig_, - l2RegularizationConfig_); + CompleteHeadConfig headConfig(quantizationConfig_, labelBinningConfig_, multiThreadingConfig_, + l1RegularizationConfig_, l2RegularizationConfig_); return headConfig.createClassificationStatisticsProviderFactory(featureMatrix, labelMatrix, lossConfig); } } @@ -41,8 +43,8 @@ namespace boosting { AutomaticHeadConfig::createClassificationStatisticsProviderFactory( const IFeatureMatrix& featureMatrix, const IRowWiseLabelMatrix& labelMatrix, const INonDecomposableClassificationLossConfig& lossConfig, const Blas& blas, const Lapack& lapack) const { - CompleteHeadConfig headConfig(labelBinningConfig_, multiThreadingConfig_, l1RegularizationConfig_, - l2RegularizationConfig_); + CompleteHeadConfig headConfig(quantizationConfig_, labelBinningConfig_, multiThreadingConfig_, + l1RegularizationConfig_, l2RegularizationConfig_); return headConfig.createClassificationStatisticsProviderFactory(featureMatrix, labelMatrix, lossConfig, blas, lapack); } @@ -51,8 +53,8 @@ namespace boosting { AutomaticHeadConfig::createRegressionStatisticsProviderFactory( const IFeatureMatrix& featureMatrix, const IRowWiseRegressionMatrix& regressionMatrix, const IDecomposableRegressionLossConfig& lossConfig) const { - CompleteHeadConfig headConfig(labelBinningConfig_, multiThreadingConfig_, l1RegularizationConfig_, - l2RegularizationConfig_); + CompleteHeadConfig headConfig(quantizationConfig_, labelBinningConfig_, multiThreadingConfig_, + l1RegularizationConfig_, l2RegularizationConfig_); return headConfig.createRegressionStatisticsProviderFactory(featureMatrix, regressionMatrix, lossConfig); } @@ -60,8 +62,8 @@ namespace boosting { AutomaticHeadConfig::createRegressionStatisticsProviderFactory( const IFeatureMatrix& featureMatrix, const IRowWiseRegressionMatrix& regressionMatrix, const INonDecomposableRegressionLossConfig& lossConfig, const Blas& blas, const Lapack& lapack) const { - CompleteHeadConfig headConfig(labelBinningConfig_, multiThreadingConfig_, l1RegularizationConfig_, - l2RegularizationConfig_); + CompleteHeadConfig headConfig(quantizationConfig_, labelBinningConfig_, multiThreadingConfig_, + l1RegularizationConfig_, l2RegularizationConfig_); return headConfig.createRegressionStatisticsProviderFactory(featureMatrix, regressionMatrix, lossConfig, blas, lapack); } diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/head_type_complete.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/head_type_complete.cpp index f302bfcb2f..7b58d57150 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/head_type_complete.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/head_type_complete.cpp @@ -6,12 +6,14 @@ namespace boosting { - CompleteHeadConfig::CompleteHeadConfig(ReadableProperty labelBinningConfig, + CompleteHeadConfig::CompleteHeadConfig(ReadableProperty quantizationConfig, + ReadableProperty labelBinningConfig, ReadableProperty multiThreadingConfig, ReadableProperty l1RegularizationConfig, ReadableProperty l2RegularizationConfig) - : labelBinningConfig_(labelBinningConfig), multiThreadingConfig_(multiThreadingConfig), - l1RegularizationConfig_(l1RegularizationConfig), l2RegularizationConfig_(l2RegularizationConfig) {} + : quantizationConfig_(quantizationConfig), labelBinningConfig_(labelBinningConfig), + multiThreadingConfig_(multiThreadingConfig), l1RegularizationConfig_(l1RegularizationConfig), + l2RegularizationConfig_(l2RegularizationConfig) {} std::unique_ptr CompleteHeadConfig::createClassificationStatisticsProviderFactory( @@ -21,6 +23,8 @@ namespace boosting { float64 l2RegularizationWeight = l2RegularizationConfig_.get().getWeight(); MultiThreadingSettings multiThreadingSettings = multiThreadingConfig_.get().getSettings(featureMatrix, labelMatrix.getNumOutputs()); + std::unique_ptr quantizationFactoryPtr = + quantizationConfig_.get().createQuantizationFactory(); std::unique_ptr lossFactoryPtr = lossConfig.createDecomposableClassificationLossFactory(); std::unique_ptr evaluationMeasureFactoryPtr = @@ -32,9 +36,9 @@ namespace boosting { std::unique_ptr pruningRuleEvaluationFactoryPtr = std::make_unique(l1RegularizationWeight, l2RegularizationWeight); return std::make_unique( - std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), std::move(defaultRuleEvaluationFactoryPtr), - std::move(regularRuleEvaluationFactoryPtr), std::move(pruningRuleEvaluationFactoryPtr), - multiThreadingSettings); + std::move(quantizationFactoryPtr), std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), + std::move(defaultRuleEvaluationFactoryPtr), std::move(regularRuleEvaluationFactoryPtr), + std::move(pruningRuleEvaluationFactoryPtr), multiThreadingSettings); } std::unique_ptr @@ -51,6 +55,8 @@ namespace boosting { const INonDecomposableClassificationLossConfig& lossConfig, const Blas& blas, const Lapack& lapack) const { MultiThreadingSettings multiThreadingSettings = multiThreadingConfig_.get().getSettings(featureMatrix, labelMatrix.getNumOutputs()); + std::unique_ptr quantizationFactoryPtr = + quantizationConfig_.get().createQuantizationFactory(); std::unique_ptr lossFactoryPtr = lossConfig.createNonDecomposableClassificationLossFactory(); std::unique_ptr evaluationMeasureFactoryPtr = @@ -62,9 +68,9 @@ namespace boosting { std::unique_ptr pruningRuleEvaluationFactoryPtr = labelBinningConfig_.get().createNonDecomposableCompleteRuleEvaluationFactory(blas, lapack); return std::make_unique( - std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), std::move(defaultRuleEvaluationFactoryPtr), - std::move(regularRuleEvaluationFactoryPtr), std::move(pruningRuleEvaluationFactoryPtr), - multiThreadingSettings); + std::move(quantizationFactoryPtr), std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), + std::move(defaultRuleEvaluationFactoryPtr), std::move(regularRuleEvaluationFactoryPtr), + std::move(pruningRuleEvaluationFactoryPtr), multiThreadingSettings); } std::unique_ptr CompleteHeadConfig::createRegressionStatisticsProviderFactory( @@ -74,6 +80,8 @@ namespace boosting { float64 l2RegularizationWeight = l2RegularizationConfig_.get().getWeight(); MultiThreadingSettings multiThreadingSettings = multiThreadingConfig_.get().getSettings(featureMatrix, regressionMatrix.getNumOutputs()); + std::unique_ptr quantizationFactoryPtr = + quantizationConfig_.get().createQuantizationFactory(); std::unique_ptr lossFactoryPtr = lossConfig.createDecomposableRegressionLossFactory(); std::unique_ptr evaluationMeasureFactoryPtr = @@ -85,9 +93,9 @@ namespace boosting { std::unique_ptr pruningRuleEvaluationFactoryPtr = std::make_unique(l1RegularizationWeight, l2RegularizationWeight); return std::make_unique( - std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), std::move(defaultRuleEvaluationFactoryPtr), - std::move(regularRuleEvaluationFactoryPtr), std::move(pruningRuleEvaluationFactoryPtr), - multiThreadingSettings); + std::move(quantizationFactoryPtr), std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), + std::move(defaultRuleEvaluationFactoryPtr), std::move(regularRuleEvaluationFactoryPtr), + std::move(pruningRuleEvaluationFactoryPtr), multiThreadingSettings); } std::unique_ptr CompleteHeadConfig::createRegressionStatisticsProviderFactory( @@ -95,6 +103,8 @@ namespace boosting { const INonDecomposableRegressionLossConfig& lossConfig, const Blas& blas, const Lapack& lapack) const { MultiThreadingSettings multiThreadingSettings = multiThreadingConfig_.get().getSettings(featureMatrix, regressionMatrix.getNumOutputs()); + std::unique_ptr quantizationFactoryPtr = + quantizationConfig_.get().createQuantizationFactory(); std::unique_ptr lossFactoryPtr = lossConfig.createNonDecomposableRegressionLossFactory(); std::unique_ptr evaluationMeasureFactoryPtr = @@ -106,9 +116,9 @@ namespace boosting { std::unique_ptr pruningRuleEvaluationFactoryPtr = labelBinningConfig_.get().createNonDecomposableCompleteRuleEvaluationFactory(blas, lapack); return std::make_unique( - std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), std::move(defaultRuleEvaluationFactoryPtr), - std::move(regularRuleEvaluationFactoryPtr), std::move(pruningRuleEvaluationFactoryPtr), - multiThreadingSettings); + std::move(quantizationFactoryPtr), std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), + std::move(defaultRuleEvaluationFactoryPtr), std::move(regularRuleEvaluationFactoryPtr), + std::move(pruningRuleEvaluationFactoryPtr), multiThreadingSettings); } bool CompleteHeadConfig::isPartial() const { diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/head_type_partial_dynamic.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/head_type_partial_dynamic.cpp index ad77009ca3..eb867d5e81 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/head_type_partial_dynamic.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/head_type_partial_dynamic.cpp @@ -7,10 +7,11 @@ namespace boosting { - DynamicPartialHeadConfig::DynamicPartialHeadConfig(ReadableProperty labelBinningConfig, + DynamicPartialHeadConfig::DynamicPartialHeadConfig(ReadableProperty quantizationConfig, + ReadableProperty labelBinningConfig, ReadableProperty multiThreadingConfig) - : threshold_(0.02f), exponent_(2.0f), labelBinningConfig_(labelBinningConfig), - multiThreadingConfig_(multiThreadingConfig) {} + : threshold_(0.02f), exponent_(2.0f), quantizationConfig_(quantizationConfig), + labelBinningConfig_(labelBinningConfig), multiThreadingConfig_(multiThreadingConfig) {} float32 DynamicPartialHeadConfig::getThreshold() const { return threshold_; @@ -39,6 +40,8 @@ namespace boosting { const IDecomposableClassificationLossConfig& lossConfig) const { MultiThreadingSettings multiThreadingSettings = multiThreadingConfig_.get().getSettings(featureMatrix, labelMatrix.getNumOutputs()); + std::unique_ptr quantizationFactoryPtr = + quantizationConfig_.get().createQuantizationFactory(); std::unique_ptr lossFactoryPtr = lossConfig.createDecomposableClassificationLossFactory(); std::unique_ptr evaluationMeasureFactoryPtr = @@ -50,9 +53,9 @@ namespace boosting { std::unique_ptr pruningRuleEvaluationFactoryPtr = labelBinningConfig_.get().createDecomposableDynamicPartialRuleEvaluationFactory(threshold_, exponent_); return std::make_unique( - std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), std::move(defaultRuleEvaluationFactoryPtr), - std::move(regularRuleEvaluationFactoryPtr), std::move(pruningRuleEvaluationFactoryPtr), - multiThreadingSettings); + std::move(quantizationFactoryPtr), std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), + std::move(defaultRuleEvaluationFactoryPtr), std::move(regularRuleEvaluationFactoryPtr), + std::move(pruningRuleEvaluationFactoryPtr), multiThreadingSettings); } std::unique_ptr @@ -61,6 +64,8 @@ namespace boosting { const ISparseDecomposableClassificationLossConfig& lossConfig) const { MultiThreadingSettings multiThreadingSettings = multiThreadingConfig_.get().getSettings(featureMatrix, labelMatrix.getNumOutputs()); + std::unique_ptr quantizationFactoryPtr = + quantizationConfig_.get().createQuantizationFactory(); std::unique_ptr lossFactoryPtr = lossConfig.createSparseDecomposableClassificationLossFactory(); std::unique_ptr evaluationMeasureFactoryPtr = @@ -70,8 +75,9 @@ namespace boosting { std::unique_ptr pruningRuleEvaluationFactoryPtr = labelBinningConfig_.get().createDecomposableDynamicPartialRuleEvaluationFactory(threshold_, exponent_); return std::make_unique( - std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), std::move(regularRuleEvaluationFactoryPtr), - std::move(pruningRuleEvaluationFactoryPtr), multiThreadingSettings); + std::move(quantizationFactoryPtr), std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), + std::move(regularRuleEvaluationFactoryPtr), std::move(pruningRuleEvaluationFactoryPtr), + multiThreadingSettings); } std::unique_ptr @@ -80,6 +86,8 @@ namespace boosting { const INonDecomposableClassificationLossConfig& lossConfig, const Blas& blas, const Lapack& lapack) const { MultiThreadingSettings multiThreadingSettings = multiThreadingConfig_.get().getSettings(featureMatrix, labelMatrix.getNumOutputs()); + std::unique_ptr quantizationFactoryPtr = + quantizationConfig_.get().createQuantizationFactory(); std::unique_ptr lossFactoryPtr = lossConfig.createNonDecomposableClassificationLossFactory(); std::unique_ptr evaluationMeasureFactoryPtr = @@ -93,9 +101,9 @@ namespace boosting { labelBinningConfig_.get().createNonDecomposableDynamicPartialRuleEvaluationFactory(threshold_, exponent_, blas, lapack); return std::make_unique( - std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), std::move(defaultRuleEvaluationFactoryPtr), - std::move(regularRuleEvaluationFactoryPtr), std::move(pruningRuleEvaluationFactoryPtr), - multiThreadingSettings); + std::move(quantizationFactoryPtr), std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), + std::move(defaultRuleEvaluationFactoryPtr), std::move(regularRuleEvaluationFactoryPtr), + std::move(pruningRuleEvaluationFactoryPtr), multiThreadingSettings); } std::unique_ptr @@ -104,6 +112,8 @@ namespace boosting { const IDecomposableRegressionLossConfig& lossConfig) const { MultiThreadingSettings multiThreadingSettings = multiThreadingConfig_.get().getSettings(featureMatrix, regressionMatrix.getNumOutputs()); + std::unique_ptr quantizationFactoryPtr = + quantizationConfig_.get().createQuantizationFactory(); std::unique_ptr lossFactoryPtr = lossConfig.createDecomposableRegressionLossFactory(); std::unique_ptr evaluationMeasureFactoryPtr = @@ -115,9 +125,9 @@ namespace boosting { std::unique_ptr pruningRuleEvaluationFactoryPtr = labelBinningConfig_.get().createDecomposableDynamicPartialRuleEvaluationFactory(threshold_, exponent_); return std::make_unique( - std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), std::move(defaultRuleEvaluationFactoryPtr), - std::move(regularRuleEvaluationFactoryPtr), std::move(pruningRuleEvaluationFactoryPtr), - multiThreadingSettings); + std::move(quantizationFactoryPtr), std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), + std::move(defaultRuleEvaluationFactoryPtr), std::move(regularRuleEvaluationFactoryPtr), + std::move(pruningRuleEvaluationFactoryPtr), multiThreadingSettings); } std::unique_ptr @@ -126,6 +136,8 @@ namespace boosting { const INonDecomposableRegressionLossConfig& lossConfig, const Blas& blas, const Lapack& lapack) const { MultiThreadingSettings multiThreadingSettings = multiThreadingConfig_.get().getSettings(featureMatrix, regressionMatrix.getNumOutputs()); + std::unique_ptr quantizationFactoryPtr = + quantizationConfig_.get().createQuantizationFactory(); std::unique_ptr lossFactoryPtr = lossConfig.createNonDecomposableRegressionLossFactory(); std::unique_ptr evaluationMeasureFactoryPtr = @@ -139,9 +151,9 @@ namespace boosting { labelBinningConfig_.get().createNonDecomposableDynamicPartialRuleEvaluationFactory(threshold_, exponent_, blas, lapack); return std::make_unique( - std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), std::move(defaultRuleEvaluationFactoryPtr), - std::move(regularRuleEvaluationFactoryPtr), std::move(pruningRuleEvaluationFactoryPtr), - multiThreadingSettings); + std::move(quantizationFactoryPtr), std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), + std::move(defaultRuleEvaluationFactoryPtr), std::move(regularRuleEvaluationFactoryPtr), + std::move(pruningRuleEvaluationFactoryPtr), multiThreadingSettings); } bool DynamicPartialHeadConfig::isPartial() const { diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/head_type_partial_fixed.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/head_type_partial_fixed.cpp index ca5f16ed0e..f4ad0a5fb5 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/head_type_partial_fixed.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/head_type_partial_fixed.cpp @@ -23,10 +23,11 @@ namespace boosting { } } - FixedPartialHeadConfig::FixedPartialHeadConfig(ReadableProperty labelBinningConfig, + FixedPartialHeadConfig::FixedPartialHeadConfig(ReadableProperty quantizationConfig, + ReadableProperty labelBinningConfig, ReadableProperty multiThreadingConfig) - : outputRatio_(0.0f), minOutputs_(2), maxOutputs_(0), labelBinningConfig_(labelBinningConfig), - multiThreadingConfig_(multiThreadingConfig) {} + : outputRatio_(0.0f), minOutputs_(2), maxOutputs_(0), quantizationConfig_(quantizationConfig), + labelBinningConfig_(labelBinningConfig), multiThreadingConfig_(multiThreadingConfig) {} float32 FixedPartialHeadConfig::getOutputRatio() const { return outputRatio_; @@ -69,6 +70,8 @@ namespace boosting { MultiThreadingSettings multiThreadingSettings = multiThreadingConfig_.get().getSettings(featureMatrix, labelMatrix.getNumOutputs()); float32 outputRatio = calculateOutputRatio(outputRatio_, labelMatrix); + std::unique_ptr quantizationFactoryPtr = + quantizationConfig_.get().createQuantizationFactory(); std::unique_ptr lossFactoryPtr = lossConfig.createDecomposableClassificationLossFactory(); std::unique_ptr evaluationMeasureFactoryPtr = @@ -82,9 +85,9 @@ namespace boosting { labelBinningConfig_.get().createDecomposableFixedPartialRuleEvaluationFactory(outputRatio, minOutputs_, maxOutputs_); return std::make_unique( - std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), std::move(defaultRuleEvaluationFactoryPtr), - std::move(regularRuleEvaluationFactoryPtr), std::move(pruningRuleEvaluationFactoryPtr), - multiThreadingSettings); + std::move(quantizationFactoryPtr), std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), + std::move(defaultRuleEvaluationFactoryPtr), std::move(regularRuleEvaluationFactoryPtr), + std::move(pruningRuleEvaluationFactoryPtr), multiThreadingSettings); } std::unique_ptr @@ -94,6 +97,8 @@ namespace boosting { MultiThreadingSettings multiThreadingSettings = multiThreadingConfig_.get().getSettings(featureMatrix, labelMatrix.getNumOutputs()); float32 outputRatio = calculateOutputRatio(outputRatio_, labelMatrix); + std::unique_ptr quantizationFactoryPtr = + quantizationConfig_.get().createQuantizationFactory(); std::unique_ptr lossFactoryPtr = lossConfig.createSparseDecomposableClassificationLossFactory(); std::unique_ptr evaluationMeasureFactoryPtr = @@ -105,8 +110,9 @@ namespace boosting { labelBinningConfig_.get().createDecomposableFixedPartialRuleEvaluationFactory(outputRatio, minOutputs_, maxOutputs_); return std::make_unique( - std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), std::move(regularRuleEvaluationFactoryPtr), - std::move(pruningRuleEvaluationFactoryPtr), multiThreadingSettings); + std::move(quantizationFactoryPtr), std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), + std::move(regularRuleEvaluationFactoryPtr), std::move(pruningRuleEvaluationFactoryPtr), + multiThreadingSettings); } std::unique_ptr @@ -116,6 +122,8 @@ namespace boosting { MultiThreadingSettings multiThreadingSettings = multiThreadingConfig_.get().getSettings(featureMatrix, labelMatrix.getNumOutputs()); float32 outputRatio = calculateOutputRatio(outputRatio_, labelMatrix); + std::unique_ptr quantizationFactoryPtr = + quantizationConfig_.get().createQuantizationFactory(); std::unique_ptr lossFactoryPtr = lossConfig.createNonDecomposableClassificationLossFactory(); std::unique_ptr evaluationMeasureFactoryPtr = @@ -129,9 +137,9 @@ namespace boosting { labelBinningConfig_.get().createNonDecomposableFixedPartialRuleEvaluationFactory(outputRatio, minOutputs_, maxOutputs_, blas, lapack); return std::make_unique( - std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), std::move(defaultRuleEvaluationFactoryPtr), - std::move(regularRuleEvaluationFactoryPtr), std::move(pruningRuleEvaluationFactoryPtr), - multiThreadingSettings); + std::move(quantizationFactoryPtr), std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), + std::move(defaultRuleEvaluationFactoryPtr), std::move(regularRuleEvaluationFactoryPtr), + std::move(pruningRuleEvaluationFactoryPtr), multiThreadingSettings); } std::unique_ptr @@ -141,6 +149,8 @@ namespace boosting { MultiThreadingSettings multiThreadingSettings = multiThreadingConfig_.get().getSettings(featureMatrix, regressionMatrix.getNumOutputs()); float32 outputRatio = calculateOutputRatio(outputRatio_, regressionMatrix); + std::unique_ptr quantizationFactoryPtr = + quantizationConfig_.get().createQuantizationFactory(); std::unique_ptr lossFactoryPtr = lossConfig.createDecomposableRegressionLossFactory(); std::unique_ptr evaluationMeasureFactoryPtr = @@ -154,9 +164,9 @@ namespace boosting { labelBinningConfig_.get().createDecomposableFixedPartialRuleEvaluationFactory(outputRatio, minOutputs_, maxOutputs_); return std::make_unique( - std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), std::move(defaultRuleEvaluationFactoryPtr), - std::move(regularRuleEvaluationFactoryPtr), std::move(pruningRuleEvaluationFactoryPtr), - multiThreadingSettings); + std::move(quantizationFactoryPtr), std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), + std::move(defaultRuleEvaluationFactoryPtr), std::move(regularRuleEvaluationFactoryPtr), + std::move(pruningRuleEvaluationFactoryPtr), multiThreadingSettings); } std::unique_ptr @@ -166,6 +176,8 @@ namespace boosting { MultiThreadingSettings multiThreadingSettings = multiThreadingConfig_.get().getSettings(featureMatrix, regressionMatrix.getNumOutputs()); float32 outputRatio = calculateOutputRatio(outputRatio_, regressionMatrix); + std::unique_ptr quantizationFactoryPtr = + quantizationConfig_.get().createQuantizationFactory(); std::unique_ptr lossFactoryPtr = lossConfig.createNonDecomposableRegressionLossFactory(); std::unique_ptr evaluationMeasureFactoryPtr = @@ -179,9 +191,9 @@ namespace boosting { labelBinningConfig_.get().createNonDecomposableFixedPartialRuleEvaluationFactory(outputRatio, minOutputs_, maxOutputs_, blas, lapack); return std::make_unique( - std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), std::move(defaultRuleEvaluationFactoryPtr), - std::move(regularRuleEvaluationFactoryPtr), std::move(pruningRuleEvaluationFactoryPtr), - multiThreadingSettings); + std::move(quantizationFactoryPtr), std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), + std::move(defaultRuleEvaluationFactoryPtr), std::move(regularRuleEvaluationFactoryPtr), + std::move(pruningRuleEvaluationFactoryPtr), multiThreadingSettings); } bool FixedPartialHeadConfig::isPartial() const { diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/head_type_single.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/head_type_single.cpp index f3327de56e..3d7ac91273 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/head_type_single.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/head_type_single.cpp @@ -7,12 +7,14 @@ namespace boosting { - SingleOutputHeadConfig::SingleOutputHeadConfig(ReadableProperty labelBinningConfig, + SingleOutputHeadConfig::SingleOutputHeadConfig(ReadableProperty quantizationConfig, + ReadableProperty labelBinningConfig, ReadableProperty multiThreadingConfig, ReadableProperty l1RegularizationConfig, ReadableProperty l2RegularizationConfig) - : labelBinningConfig_(labelBinningConfig), multiThreadingConfig_(multiThreadingConfig), - l1RegularizationConfig_(l1RegularizationConfig), l2RegularizationConfig_(l2RegularizationConfig) {} + : quantizationConfig_(quantizationConfig), labelBinningConfig_(labelBinningConfig), + multiThreadingConfig_(multiThreadingConfig), l1RegularizationConfig_(l1RegularizationConfig), + l2RegularizationConfig_(l2RegularizationConfig) {} std::unique_ptr SingleOutputHeadConfig::createClassificationStatisticsProviderFactory( @@ -22,6 +24,8 @@ namespace boosting { float64 l2RegularizationWeight = l2RegularizationConfig_.get().getWeight(); MultiThreadingSettings multiThreadingSettings = multiThreadingConfig_.get().getSettings(featureMatrix, labelMatrix.getNumOutputs()); + std::unique_ptr quantizationFactoryPtr = + quantizationConfig_.get().createQuantizationFactory(); std::unique_ptr lossFactoryPtr = lossConfig.createDecomposableClassificationLossFactory(); std::unique_ptr evaluationMeasureFactoryPtr = @@ -35,9 +39,9 @@ namespace boosting { std::make_unique(l1RegularizationWeight, l2RegularizationWeight); return std::make_unique( - std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), std::move(defaultRuleEvaluationFactoryPtr), - std::move(regularRuleEvaluationFactoryPtr), std::move(pruningRuleEvaluationFactoryPtr), - multiThreadingSettings); + std::move(quantizationFactoryPtr), std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), + std::move(defaultRuleEvaluationFactoryPtr), std::move(regularRuleEvaluationFactoryPtr), + std::move(pruningRuleEvaluationFactoryPtr), multiThreadingSettings); } std::unique_ptr @@ -48,6 +52,8 @@ namespace boosting { float64 l2RegularizationWeight = l2RegularizationConfig_.get().getWeight(); MultiThreadingSettings multiThreadingSettings = multiThreadingConfig_.get().getSettings(featureMatrix, labelMatrix.getNumOutputs()); + std::unique_ptr quantizationFactoryPtr = + quantizationConfig_.get().createQuantizationFactory(); std::unique_ptr lossFactoryPtr = lossConfig.createSparseDecomposableClassificationLossFactory(); std::unique_ptr evaluationMeasureFactoryPtr = @@ -59,8 +65,9 @@ namespace boosting { std::make_unique(l1RegularizationWeight, l2RegularizationWeight); return std::make_unique( - std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), std::move(regularRuleEvaluationFactoryPtr), - std::move(pruningRuleEvaluationFactoryPtr), multiThreadingSettings); + std::move(quantizationFactoryPtr), std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), + std::move(regularRuleEvaluationFactoryPtr), std::move(pruningRuleEvaluationFactoryPtr), + multiThreadingSettings); } std::unique_ptr @@ -71,6 +78,8 @@ namespace boosting { float64 l2RegularizationWeight = l2RegularizationConfig_.get().getWeight(); MultiThreadingSettings multiThreadingSettings = multiThreadingConfig_.get().getSettings(featureMatrix, labelMatrix.getNumOutputs()); + std::unique_ptr quantizationFactoryPtr = + quantizationConfig_.get().createQuantizationFactory(); std::unique_ptr lossFactoryPtr = lossConfig.createNonDecomposableClassificationLossFactory(); std::unique_ptr evaluationMeasureFactoryPtr = @@ -84,9 +93,9 @@ namespace boosting { std::make_unique(l1RegularizationWeight, l2RegularizationWeight); return std::make_unique( - std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), std::move(defaultRuleEvaluationFactoryPtr), - std::move(regularRuleEvaluationFactoryPtr), std::move(pruningRuleEvaluationFactoryPtr), - multiThreadingSettings); + std::move(quantizationFactoryPtr), std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), + std::move(defaultRuleEvaluationFactoryPtr), std::move(regularRuleEvaluationFactoryPtr), + std::move(pruningRuleEvaluationFactoryPtr), multiThreadingSettings); } std::unique_ptr @@ -97,6 +106,8 @@ namespace boosting { float64 l2RegularizationWeight = l2RegularizationConfig_.get().getWeight(); MultiThreadingSettings multiThreadingSettings = multiThreadingConfig_.get().getSettings(featureMatrix, regressionMatrix.getNumOutputs()); + std::unique_ptr quantizationFactoryPtr = + quantizationConfig_.get().createQuantizationFactory(); std::unique_ptr lossFactoryPtr = lossConfig.createDecomposableRegressionLossFactory(); std::unique_ptr evaluationMeasureFactoryPtr = @@ -110,9 +121,9 @@ namespace boosting { std::make_unique(l1RegularizationWeight, l2RegularizationWeight); return std::make_unique( - std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), std::move(defaultRuleEvaluationFactoryPtr), - std::move(regularRuleEvaluationFactoryPtr), std::move(pruningRuleEvaluationFactoryPtr), - multiThreadingSettings); + std::move(quantizationFactoryPtr), std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), + std::move(defaultRuleEvaluationFactoryPtr), std::move(regularRuleEvaluationFactoryPtr), + std::move(pruningRuleEvaluationFactoryPtr), multiThreadingSettings); } std::unique_ptr @@ -123,6 +134,8 @@ namespace boosting { float64 l2RegularizationWeight = l2RegularizationConfig_.get().getWeight(); MultiThreadingSettings multiThreadingSettings = multiThreadingConfig_.get().getSettings(featureMatrix, regressionMatrix.getNumOutputs()); + std::unique_ptr quantizationFactoryPtr = + quantizationConfig_.get().createQuantizationFactory(); std::unique_ptr lossFactoryPtr = lossConfig.createNonDecomposableRegressionLossFactory(); std::unique_ptr evaluationMeasureFactoryPtr = @@ -136,9 +149,9 @@ namespace boosting { std::make_unique(l1RegularizationWeight, l2RegularizationWeight); return std::make_unique( - std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), std::move(defaultRuleEvaluationFactoryPtr), - std::move(regularRuleEvaluationFactoryPtr), std::move(pruningRuleEvaluationFactoryPtr), - multiThreadingSettings); + std::move(quantizationFactoryPtr), std::move(lossFactoryPtr), std::move(evaluationMeasureFactoryPtr), + std::move(defaultRuleEvaluationFactoryPtr), std::move(regularRuleEvaluationFactoryPtr), + std::move(pruningRuleEvaluationFactoryPtr), multiThreadingSettings); } bool SingleOutputHeadConfig::isPartial() const { diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp index 4b3f9c049d..b6a2b7eb9d 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp @@ -3,6 +3,7 @@ */ #pragma once +#include "mlrl/boosting/statistics/quantization.hpp" #include "mlrl/boosting/statistics/statistics.hpp" #include @@ -526,6 +527,11 @@ namespace boosting { protected: + /** + * An unique pointer to the method that should be used for quantizing gradients and Hessians. + */ + std::unique_ptr quantizationPtr_; + /** * An unique pointer to the loss function that should be used for calculating gradients and Hessians. */ @@ -573,6 +579,8 @@ namespace boosting { public: /** + * @param quantizationPtr An unique pointer to an object of type `IQuantization` that implements the + * method that should be used for quantizing gradients and Hessians * @param lossPtr An unique pointer to an object of template type `LossFunction` that * implements the loss function that should be used for calculating gradients * and Hessians @@ -589,12 +597,13 @@ namespace boosting { * @param scoreMatrixPtr An unique pointer to an object of template type `ScoreMatrix` that stores * the currently predicted scores */ - AbstractStatistics(std::unique_ptr lossPtr, + AbstractStatistics(std::unique_ptr quantizationPtr, std::unique_ptr lossPtr, std::unique_ptr evaluationMeasurePtr, const RuleEvaluationFactory& ruleEvaluationFactory, const OutputMatrix& outputMatrix, std::unique_ptr statisticMatrixPtr, std::unique_ptr scoreMatrixPtr) - : lossPtr_(std::move(lossPtr)), evaluationMeasurePtr_(std::move(evaluationMeasurePtr)), + : quantizationPtr_(std::move(quantizationPtr)), lossPtr_(std::move(lossPtr)), + evaluationMeasurePtr_(std::move(evaluationMeasurePtr)), ruleEvaluationFactory_(&ruleEvaluationFactory), outputMatrix_(outputMatrix), statisticMatrixPtr_(std::move(statisticMatrixPtr)), scoreMatrixPtr_(std::move(scoreMatrixPtr)) {} diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_decomposable_common.hpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_decomposable_common.hpp index 9816501de8..ae6d4320ee 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_decomposable_common.hpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_decomposable_common.hpp @@ -61,6 +61,8 @@ namespace boosting { public: /** + * @param quantizationPtr An unique pointer to an object of type `IQuantization` that implements the + * method that should be used for quantizing gradients and Hessians * @param lossPtr An unique pointer to an object of template type `LossFunction` that * implements the loss function that should be used for calculating gradients * and Hessians @@ -77,7 +79,8 @@ namespace boosting { * @param scoreMatrixPtr An unique pointer to an object of template type `ScoreMatrix` that stores * the currently predicted scores */ - AbstractDecomposableStatistics(std::unique_ptr lossPtr, + AbstractDecomposableStatistics(std::unique_ptr quantizationPtr, + std::unique_ptr lossPtr, std::unique_ptr evaluationMeasurePtr, const RuleEvaluationFactory& ruleEvaluationFactory, const OutputMatrix& outputMatrix, @@ -85,8 +88,8 @@ namespace boosting { std::unique_ptr scoreMatrixPtr) : AbstractStatistics( - std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, outputMatrix, - std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)) {} + std::move(quantizationPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), + ruleEvaluationFactory, outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)) {} /** * @see `IDecomposableStatistics::setRuleEvaluationFactory` diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_decomposable_dense.hpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_decomposable_dense.hpp index e3125d669d..e9bd697907 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_decomposable_dense.hpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_decomposable_dense.hpp @@ -62,6 +62,8 @@ namespace boosting { public: /** + * @param quantizationPtr An unique pointer to an object of type `IQuantization` that implements the + * method that should be used for quantizing gradients and Hessians * @param lossPtr An unique pointer to an object of template type `Loss` that implements the * loss function that should be used for calculating gradients and Hessians * @param evaluationMeasurePtr An unique pointer to an object of template type `EvaluationMeasure` that @@ -77,7 +79,7 @@ namespace boosting { * @param scoreMatrixPtr An unique pointer to an object of type `NumericCContiguousMatrix` that * stores the currently predicted scores */ - DenseDecomposableStatistics(std::unique_ptr lossPtr, + DenseDecomposableStatistics(std::unique_ptr quantizationPtr, std::unique_ptr lossPtr, std::unique_ptr evaluationMeasurePtr, const IDecomposableRuleEvaluationFactory& ruleEvaluationFactory, const OutputMatrix& outputMatrix, @@ -86,8 +88,8 @@ namespace boosting { : AbstractDecomposableStatistics, Loss, EvaluationMeasure, IDecomposableRuleEvaluationFactory>( - std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, outputMatrix, - std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)) {} + std::move(quantizationPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), + ruleEvaluationFactory, outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)) {} /** * @see `IBoostingStatistics::visitScoreMatrix` diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_non_decomposable_common.hpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_non_decomposable_common.hpp index 8f7af8c6b4..4ab5024171 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_non_decomposable_common.hpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_non_decomposable_common.hpp @@ -68,6 +68,8 @@ namespace boosting { public: /** + * @param quantizationPtr An unique pointer to an object of type `IQuantization` that implements the + * method that should be used for quantizing gradients and Hessians * @param lossPtr An unique pointer to an object of template type `LossFunction` that * implements the loss function that should be used for calculating gradients * and Hessians @@ -85,7 +87,8 @@ namespace boosting { * @param scoreMatrixPtr An unique pointer to an object of template type `ScoreMatrix` that stores * the currently predicted scores */ - AbstractNonDecomposableStatistics(std::unique_ptr lossPtr, + AbstractNonDecomposableStatistics(std::unique_ptr quantizationPtr, + std::unique_ptr lossPtr, std::unique_ptr evaluationMeasurePtr, const NonDecomposableRuleEvaluationFactory& ruleEvaluationFactory, const OutputMatrix& outputMatrix, @@ -93,8 +96,8 @@ namespace boosting { std::unique_ptr scoreMatrixPtr) : AbstractStatistics( - std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, outputMatrix, - std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)) {} + std::move(quantizationPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), + ruleEvaluationFactory, outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)) {} /** * @see `INonDecomposableStatistics::setRuleEvaluationFactory` diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp index 05a67b565f..f18332b85d 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp @@ -9,10 +9,11 @@ namespace boosting { template static inline std::unique_ptr> createStatistics( std::unique_ptr lossPtr, std::unique_ptr evaluationMeasurePtr, - const IDecomposableRuleEvaluationFactory& ruleEvaluationFactory, MultiThreadingSettings multiThreadingSettings, - const OutputMatrix& outputMatrix) { + const IQuantizationFactory& quantizationFactory, const IDecomposableRuleEvaluationFactory& ruleEvaluationFactory, + MultiThreadingSettings multiThreadingSettings, const OutputMatrix& outputMatrix) { uint32 numExamples = outputMatrix.numRows; uint32 numOutputs = outputMatrix.numCols; + std::unique_ptr quantizationPtr = quantizationFactory.create(); std::unique_ptr statisticMatrixPtr = std::make_unique(numExamples, numOutputs); std::unique_ptr> scoreMatrixPtr = @@ -33,18 +34,19 @@ namespace boosting { } return std::make_unique>( - std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, outputMatrix, - std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)); + std::move(quantizationPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, + outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)); } DenseDecomposableClassificationStatisticsProviderFactory::DenseDecomposableClassificationStatisticsProviderFactory( + std::unique_ptr quantizationFactoryPtr, std::unique_ptr lossFactoryPtr, std::unique_ptr evaluationMeasureFactoryPtr, std::unique_ptr defaultRuleEvaluationFactoryPtr, std::unique_ptr regularRuleEvaluationFactoryPtr, std::unique_ptr pruningRuleEvaluationFactoryPtr, MultiThreadingSettings multiThreadingSettings) - : lossFactoryPtr_(std::move(lossFactoryPtr)), + : quantizationFactoryPtr_(std::move(quantizationFactoryPtr)), lossFactoryPtr_(std::move(lossFactoryPtr)), evaluationMeasureFactoryPtr_(std::move(evaluationMeasureFactoryPtr)), defaultRuleEvaluationFactoryPtr_(std::move(defaultRuleEvaluationFactoryPtr)), regularRuleEvaluationFactoryPtr_(std::move(regularRuleEvaluationFactoryPtr)), @@ -58,8 +60,8 @@ namespace boosting { std::unique_ptr evaluationMeasurePtr = evaluationMeasureFactoryPtr_->createClassificationEvaluationMeasure(); std::unique_ptr> statisticsPtr = - createStatistics(std::move(lossPtr), std::move(evaluationMeasurePtr), *defaultRuleEvaluationFactoryPtr_, - multiThreadingSettings_, labelMatrix); + createStatistics(std::move(lossPtr), std::move(evaluationMeasurePtr), *quantizationFactoryPtr_, + *defaultRuleEvaluationFactoryPtr_, multiThreadingSettings_, labelMatrix); return std::make_unique>( *regularRuleEvaluationFactoryPtr_, *pruningRuleEvaluationFactoryPtr_, std::move(statisticsPtr)); } @@ -71,20 +73,21 @@ namespace boosting { std::unique_ptr evaluationMeasurePtr = evaluationMeasureFactoryPtr_->createClassificationEvaluationMeasure(); std::unique_ptr> statisticsPtr = - createStatistics(std::move(lossPtr), std::move(evaluationMeasurePtr), *defaultRuleEvaluationFactoryPtr_, - multiThreadingSettings_, labelMatrix); + createStatistics(std::move(lossPtr), std::move(evaluationMeasurePtr), *quantizationFactoryPtr_, + *defaultRuleEvaluationFactoryPtr_, multiThreadingSettings_, labelMatrix); return std::make_unique>( *regularRuleEvaluationFactoryPtr_, *pruningRuleEvaluationFactoryPtr_, std::move(statisticsPtr)); } DenseDecomposableRegressionStatisticsProviderFactory::DenseDecomposableRegressionStatisticsProviderFactory( + std::unique_ptr quantizationFactoryPtr, std::unique_ptr lossFactoryPtr, std::unique_ptr evaluationMeasureFactoryPtr, std::unique_ptr defaultRuleEvaluationFactoryPtr, std::unique_ptr regularRuleEvaluationFactoryPtr, std::unique_ptr pruningRuleEvaluationFactoryPtr, MultiThreadingSettings multiThreadingSettings) - : lossFactoryPtr_(std::move(lossFactoryPtr)), + : quantizationFactoryPtr_(std::move(quantizationFactoryPtr)), lossFactoryPtr_(std::move(lossFactoryPtr)), evaluationMeasureFactoryPtr_(std::move(evaluationMeasureFactoryPtr)), defaultRuleEvaluationFactoryPtr_(std::move(defaultRuleEvaluationFactoryPtr)), regularRuleEvaluationFactoryPtr_(std::move(regularRuleEvaluationFactoryPtr)), @@ -97,8 +100,8 @@ namespace boosting { std::unique_ptr evaluationMeasurePtr = evaluationMeasureFactoryPtr_->createRegressionEvaluationMeasure(); std::unique_ptr> statisticsPtr = - createStatistics(std::move(lossPtr), std::move(evaluationMeasurePtr), *defaultRuleEvaluationFactoryPtr_, - multiThreadingSettings_, regressionMatrix); + createStatistics(std::move(lossPtr), std::move(evaluationMeasurePtr), *quantizationFactoryPtr_, + *defaultRuleEvaluationFactoryPtr_, multiThreadingSettings_, regressionMatrix); return std::make_unique>( *regularRuleEvaluationFactoryPtr_, *pruningRuleEvaluationFactoryPtr_, std::move(statisticsPtr)); } @@ -109,8 +112,8 @@ namespace boosting { std::unique_ptr evaluationMeasurePtr = evaluationMeasureFactoryPtr_->createRegressionEvaluationMeasure(); std::unique_ptr> statisticsPtr = - createStatistics(std::move(lossPtr), std::move(evaluationMeasurePtr), *defaultRuleEvaluationFactoryPtr_, - multiThreadingSettings_, regressionMatrix); + createStatistics(std::move(lossPtr), std::move(evaluationMeasurePtr), *quantizationFactoryPtr_, + *defaultRuleEvaluationFactoryPtr_, multiThreadingSettings_, regressionMatrix); return std::make_unique>( *regularRuleEvaluationFactoryPtr_, *pruningRuleEvaluationFactoryPtr_, std::move(statisticsPtr)); } diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_sparse.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_sparse.cpp index 0a535690c2..aab3c1f484 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_sparse.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_sparse.cpp @@ -38,6 +38,8 @@ namespace boosting { public: /** + * @param quantizationPtr An unique pointer to an object of type `IQuantization` that implements the + * method that should be used for calculating gradients and Hessians * @param lossPtr An unique pointer to an object of template type `LossFunction` that * implements the loss function that should be used for calculating gradients * and Hessians @@ -54,7 +56,8 @@ namespace boosting { * @param scoreMatrixPtr An unique pointer to an object of type `NumericSparseSetMatrix` that stores * the currently predicted scores */ - SparseDecomposableStatistics(std::unique_ptr lossPtr, + SparseDecomposableStatistics(std::unique_ptr quantizationPtr, + std::unique_ptr lossPtr, std::unique_ptr evaluationMeasurePtr, const ISparseDecomposableRuleEvaluationFactory& ruleEvaluationFactory, const OutputMatrix& outputMatrix, @@ -64,8 +67,8 @@ namespace boosting { SparseDecomposableStatisticMatrix, NumericSparseSetMatrix, ISparseDecomposableClassificationLoss, ISparseEvaluationMeasure, ISparseDecomposableRuleEvaluationFactory>( - std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, outputMatrix, - std::move(statisticViewPtr), std::move(scoreMatrixPtr)) {} + std::move(quantizationPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), + ruleEvaluationFactory, outputMatrix, std::move(statisticViewPtr), std::move(scoreMatrixPtr)) {} /** * @see `IBoostingStatistics::visitScoreMatrix` @@ -78,12 +81,13 @@ namespace boosting { template static inline std::unique_ptr> createStatistics( - const ISparseDecomposableClassificationLossFactory& lossFactory, + const IQuantizationFactory& quantizationFactory, const ISparseDecomposableClassificationLossFactory& lossFactory, const ISparseEvaluationMeasureFactory& evaluationMeasureFactory, const ISparseDecomposableRuleEvaluationFactory& ruleEvaluationFactory, MultiThreadingSettings multiThreadingSettings, const OutputMatrix& outputMatrix) { uint32 numExamples = outputMatrix.numRows; uint32 numOutputs = outputMatrix.numCols; + std::unique_ptr quantizationPtr = quantizationFactory.create(); std::unique_ptr lossPtr = lossFactory.createSparseDecomposableClassificationLoss(); std::unique_ptr evaluationMeasurePtr = @@ -108,18 +112,19 @@ namespace boosting { } return std::make_unique>( - std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, outputMatrix, - std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)); + std::move(quantizationPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, + outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)); } SparseDecomposableClassificationStatisticsProviderFactory:: SparseDecomposableClassificationStatisticsProviderFactory( + std::unique_ptr quantizationFactoryPtr, std::unique_ptr lossFactoryPtr, std::unique_ptr evaluationMeasureFactoryPtr, std::unique_ptr regularRuleEvaluationFactoryPtr, std::unique_ptr pruningRuleEvaluationFactoryPtr, MultiThreadingSettings multiThreadingSettings) - : lossFactoryPtr_(std::move(lossFactoryPtr)), + : quantizationFactoryPtr_(std::move(quantizationFactoryPtr)), lossFactoryPtr_(std::move(lossFactoryPtr)), evaluationMeasureFactoryPtr_(std::move(evaluationMeasureFactoryPtr)), regularRuleEvaluationFactoryPtr_(std::move(regularRuleEvaluationFactoryPtr)), pruningRuleEvaluationFactoryPtr_(std::move(pruningRuleEvaluationFactoryPtr)), @@ -128,8 +133,8 @@ namespace boosting { std::unique_ptr SparseDecomposableClassificationStatisticsProviderFactory::create( const CContiguousView& labelMatrix) const { std::unique_ptr> statisticsPtr = - createStatistics(*lossFactoryPtr_, *evaluationMeasureFactoryPtr_, *regularRuleEvaluationFactoryPtr_, - multiThreadingSettings_, labelMatrix); + createStatistics(*quantizationFactoryPtr_, *lossFactoryPtr_, *evaluationMeasureFactoryPtr_, + *regularRuleEvaluationFactoryPtr_, multiThreadingSettings_, labelMatrix); return std::make_unique>( *regularRuleEvaluationFactoryPtr_, *pruningRuleEvaluationFactoryPtr_, std::move(statisticsPtr)); } @@ -137,8 +142,8 @@ namespace boosting { std::unique_ptr SparseDecomposableClassificationStatisticsProviderFactory::create( const BinaryCsrView& labelMatrix) const { std::unique_ptr> statisticsPtr = - createStatistics(*lossFactoryPtr_, *evaluationMeasureFactoryPtr_, *regularRuleEvaluationFactoryPtr_, - multiThreadingSettings_, labelMatrix); + createStatistics(*quantizationFactoryPtr_, *lossFactoryPtr_, *evaluationMeasureFactoryPtr_, + *regularRuleEvaluationFactoryPtr_, multiThreadingSettings_, labelMatrix); return std::make_unique>( *regularRuleEvaluationFactoryPtr_, *pruningRuleEvaluationFactoryPtr_, std::move(statisticsPtr)); } diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp index 11980bf279..6871d6a391 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp @@ -66,6 +66,8 @@ namespace boosting { public: /** + * @param quantizationPtr An unique pointer to an object of type `IQuantization` that implements the + * method for quantizing gradients and Hessians * @param lossPtr An unique pointer to an object of template type `Loss` that implements the * loss function to be used for calculating gradients and Hessians * @param evaluationMeasurePtr An unique pointer to an object of template type `EvaluationMeasure` that @@ -81,7 +83,8 @@ namespace boosting { * @param scoreMatrixPtr An unique pointer to an object of type `NumericCContiguousMatrix` that * stores the currently predicted scores */ - DenseNonDecomposableStatistics(std::unique_ptr lossPtr, + DenseNonDecomposableStatistics(std::unique_ptr quantizationPtr, + std::unique_ptr lossPtr, std::unique_ptr evaluationMeasurePtr, const INonDecomposableRuleEvaluationFactory& ruleEvaluationFactory, const OutputMatrix& outputMatrix, @@ -90,9 +93,9 @@ namespace boosting { : AbstractNonDecomposableStatistics< OutputMatrix, DenseNonDecomposableStatisticVector, DenseNonDecomposableStatisticMatrix, NumericCContiguousMatrix, Loss, EvaluationMeasure, INonDecomposableRuleEvaluationFactory, - IDecomposableRuleEvaluationFactory>(std::move(lossPtr), std::move(evaluationMeasurePtr), - ruleEvaluationFactory, outputMatrix, - std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)) {} + IDecomposableRuleEvaluationFactory>( + std::move(quantizationPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), + ruleEvaluationFactory, outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)) {} /** * @see `IBoostingStatistics::visitScoreMatrix` @@ -138,8 +141,9 @@ namespace boosting { } return std::make_unique>( - std::move(this->lossPtr_), std::move(this->evaluationMeasurePtr_), ruleEvaluationFactory, - this->outputMatrix_, std::move(decomposableStatisticMatrixPtr), std::move(this->scoreMatrixPtr_)); + std::move(this->quantizationPtr_), std::move(this->lossPtr_), std::move(this->evaluationMeasurePtr_), + ruleEvaluationFactory, this->outputMatrix_, std::move(decomposableStatisticMatrixPtr), + std::move(this->scoreMatrixPtr_)); } }; @@ -147,10 +151,12 @@ namespace boosting { static inline std::unique_ptr< INonDecomposableStatistics> createStatistics(std::unique_ptr lossPtr, std::unique_ptr evaluationMeasurePtr, + const IQuantizationFactory& quantizationFactory, const INonDecomposableRuleEvaluationFactory& ruleEvaluationFactory, MultiThreadingSettings multiThreadingSettings, const OutputMatrix& outputMatrix) { uint32 numExamples = outputMatrix.numRows; uint32 numOutputs = outputMatrix.numCols; + std::unique_ptr quantizationPtr = quantizationFactory.create(); std::unique_ptr statisticMatrixPtr = std::make_unique(numExamples, numOutputs); std::unique_ptr> scoreMatrixPtr = @@ -170,19 +176,20 @@ namespace boosting { } return std::make_unique>( - std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, outputMatrix, - std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)); + std::move(quantizationPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, + outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)); } DenseNonDecomposableClassificationStatisticsProviderFactory:: DenseNonDecomposableClassificationStatisticsProviderFactory( + std::unique_ptr quantizationFactoryPtr, std::unique_ptr lossFactoryPtr, std::unique_ptr evaluationMeasureFactoryPtr, std::unique_ptr defaultRuleEvaluationFactoryPtr, std::unique_ptr regularRuleEvaluationFactoryPtr, std::unique_ptr pruningRuleEvaluationFactoryPtr, MultiThreadingSettings multiThreadingSettings) - : lossFactoryPtr_(std::move(lossFactoryPtr)), + : quantizationFactoryPtr_(std::move(quantizationFactoryPtr)), lossFactoryPtr_(std::move(lossFactoryPtr)), evaluationMeasureFactoryPtr_(std::move(evaluationMeasureFactoryPtr)), defaultRuleEvaluationFactoryPtr_(std::move(defaultRuleEvaluationFactoryPtr)), regularRuleEvaluationFactoryPtr_(std::move(regularRuleEvaluationFactoryPtr)), @@ -197,8 +204,9 @@ namespace boosting { evaluationMeasureFactoryPtr_->createClassificationEvaluationMeasure(); std::unique_ptr< INonDecomposableStatistics> - statisticsPtr = createStatistics(std::move(lossPtr), std::move(evaluationMeasurePtr), - *defaultRuleEvaluationFactoryPtr_, multiThreadingSettings_, labelMatrix); + statisticsPtr = + createStatistics(std::move(lossPtr), std::move(evaluationMeasurePtr), *quantizationFactoryPtr_, + *defaultRuleEvaluationFactoryPtr_, multiThreadingSettings_, labelMatrix); return std::make_unique< NonDecomposableStatisticsProvider>( *regularRuleEvaluationFactoryPtr_, *pruningRuleEvaluationFactoryPtr_, std::move(statisticsPtr)); @@ -212,21 +220,23 @@ namespace boosting { evaluationMeasureFactoryPtr_->createClassificationEvaluationMeasure(); std::unique_ptr< INonDecomposableStatistics> - statisticsPtr = createStatistics(std::move(lossPtr), std::move(evaluationMeasurePtr), - *defaultRuleEvaluationFactoryPtr_, multiThreadingSettings_, labelMatrix); + statisticsPtr = + createStatistics(std::move(lossPtr), std::move(evaluationMeasurePtr), *quantizationFactoryPtr_, + *defaultRuleEvaluationFactoryPtr_, multiThreadingSettings_, labelMatrix); return std::make_unique< NonDecomposableStatisticsProvider>( *regularRuleEvaluationFactoryPtr_, *pruningRuleEvaluationFactoryPtr_, std::move(statisticsPtr)); } DenseNonDecomposableRegressionStatisticsProviderFactory::DenseNonDecomposableRegressionStatisticsProviderFactory( + std::unique_ptr quantizationFactoryPtr, std::unique_ptr lossFactoryPtr, std::unique_ptr evaluationMeasureFactoryPtr, std::unique_ptr defaultRuleEvaluationFactoryPtr, std::unique_ptr regularRuleEvaluationFactoryPtr, std::unique_ptr pruningRuleEvaluationFactoryPtr, MultiThreadingSettings multiThreadingSettings) - : lossFactoryPtr_(std::move(lossFactoryPtr)), + : quantizationFactoryPtr_(std::move(quantizationFactoryPtr)), lossFactoryPtr_(std::move(lossFactoryPtr)), evaluationMeasureFactoryPtr_(std::move(evaluationMeasureFactoryPtr)), defaultRuleEvaluationFactoryPtr_(std::move(defaultRuleEvaluationFactoryPtr)), regularRuleEvaluationFactoryPtr_(std::move(regularRuleEvaluationFactoryPtr)), @@ -242,8 +252,8 @@ namespace boosting { std::unique_ptr< INonDecomposableStatistics> statisticsPtr = - createStatistics(std::move(lossPtr), std::move(evaluationMeasurePtr), *defaultRuleEvaluationFactoryPtr_, - multiThreadingSettings_, regressionMatrix); + createStatistics(std::move(lossPtr), std::move(evaluationMeasurePtr), *quantizationFactoryPtr_, + *defaultRuleEvaluationFactoryPtr_, multiThreadingSettings_, regressionMatrix); return std::make_unique< NonDecomposableStatisticsProvider>( *regularRuleEvaluationFactoryPtr_, *pruningRuleEvaluationFactoryPtr_, std::move(statisticsPtr)); @@ -258,8 +268,8 @@ namespace boosting { std::unique_ptr< INonDecomposableStatistics> statisticsPtr = - createStatistics(std::move(lossPtr), std::move(evaluationMeasurePtr), *defaultRuleEvaluationFactoryPtr_, - multiThreadingSettings_, regressionMatrix); + createStatistics(std::move(lossPtr), std::move(evaluationMeasurePtr), *quantizationFactoryPtr_, + *defaultRuleEvaluationFactoryPtr_, multiThreadingSettings_, regressionMatrix); return std::make_unique< NonDecomposableStatisticsProvider>( *regularRuleEvaluationFactoryPtr_, *pruningRuleEvaluationFactoryPtr_, std::move(statisticsPtr)); @@ -267,13 +277,14 @@ namespace boosting { DenseConvertibleNonDecomposableClassificationStatisticsProviderFactory:: DenseConvertibleNonDecomposableClassificationStatisticsProviderFactory( + std::unique_ptr quantizationFactoryPtr, std::unique_ptr lossFactoryPtr, std::unique_ptr evaluationMeasureFactoryPtr, std::unique_ptr defaultRuleEvaluationFactoryPtr, std::unique_ptr regularRuleEvaluationFactoryPtr, std::unique_ptr pruningRuleEvaluationFactoryPtr, MultiThreadingSettings multiThreadingSettings) - : lossFactoryPtr_(std::move(lossFactoryPtr)), + : quantizationFactoryPtr_(std::move(quantizationFactoryPtr)), lossFactoryPtr_(std::move(lossFactoryPtr)), evaluationMeasureFactoryPtr_(std::move(evaluationMeasureFactoryPtr)), defaultRuleEvaluationFactoryPtr_(std::move(defaultRuleEvaluationFactoryPtr)), regularRuleEvaluationFactoryPtr_(std::move(regularRuleEvaluationFactoryPtr)), @@ -288,8 +299,9 @@ namespace boosting { evaluationMeasureFactoryPtr_->createClassificationEvaluationMeasure(); std::unique_ptr< INonDecomposableStatistics> - statisticsPtr = createStatistics(std::move(lossPtr), std::move(evaluationMeasurePtr), - *defaultRuleEvaluationFactoryPtr_, multiThreadingSettings_, labelMatrix); + statisticsPtr = + createStatistics(std::move(lossPtr), std::move(evaluationMeasurePtr), *quantizationFactoryPtr_, + *defaultRuleEvaluationFactoryPtr_, multiThreadingSettings_, labelMatrix); return std::make_unique>( *regularRuleEvaluationFactoryPtr_, *pruningRuleEvaluationFactoryPtr_, std::move(statisticsPtr), @@ -304,8 +316,9 @@ namespace boosting { evaluationMeasureFactoryPtr_->createClassificationEvaluationMeasure(); std::unique_ptr< INonDecomposableStatistics> - statisticsPtr = createStatistics(std::move(lossPtr), std::move(evaluationMeasurePtr), - *defaultRuleEvaluationFactoryPtr_, multiThreadingSettings_, labelMatrix); + statisticsPtr = + createStatistics(std::move(lossPtr), std::move(evaluationMeasurePtr), *quantizationFactoryPtr_, + *defaultRuleEvaluationFactoryPtr_, multiThreadingSettings_, labelMatrix); return std::make_unique>( *regularRuleEvaluationFactoryPtr_, *pruningRuleEvaluationFactoryPtr_, std::move(statisticsPtr), @@ -314,13 +327,14 @@ namespace boosting { DenseConvertibleNonDecomposableRegressionStatisticsProviderFactory:: DenseConvertibleNonDecomposableRegressionStatisticsProviderFactory( + std::unique_ptr quantizationFactoryPtr, std::unique_ptr lossFactoryPtr, std::unique_ptr evaluationMeasureFactoryPtr, std::unique_ptr defaultRuleEvaluationFactoryPtr, std::unique_ptr regularRuleEvaluationFactoryPtr, std::unique_ptr pruningRuleEvaluationFactoryPtr, MultiThreadingSettings multiThreadingSettings) - : lossFactoryPtr_(std::move(lossFactoryPtr)), + : quantizationFactoryPtr_(std::move(quantizationFactoryPtr)), lossFactoryPtr_(std::move(lossFactoryPtr)), evaluationMeasureFactoryPtr_(std::move(evaluationMeasureFactoryPtr)), defaultRuleEvaluationFactoryPtr_(std::move(defaultRuleEvaluationFactoryPtr)), regularRuleEvaluationFactoryPtr_(std::move(regularRuleEvaluationFactoryPtr)), @@ -336,8 +350,8 @@ namespace boosting { std::unique_ptr< INonDecomposableStatistics> statisticsPtr = - createStatistics(std::move(lossPtr), std::move(evaluationMeasurePtr), *defaultRuleEvaluationFactoryPtr_, - multiThreadingSettings_, regressionMatrix); + createStatistics(std::move(lossPtr), std::move(evaluationMeasurePtr), *quantizationFactoryPtr_, + *defaultRuleEvaluationFactoryPtr_, multiThreadingSettings_, regressionMatrix); return std::make_unique>( *regularRuleEvaluationFactoryPtr_, *pruningRuleEvaluationFactoryPtr_, std::move(statisticsPtr), @@ -353,8 +367,8 @@ namespace boosting { std::unique_ptr< INonDecomposableStatistics> statisticsPtr = - createStatistics(std::move(lossPtr), std::move(evaluationMeasurePtr), *defaultRuleEvaluationFactoryPtr_, - multiThreadingSettings_, regressionMatrix); + createStatistics(std::move(lossPtr), std::move(evaluationMeasurePtr), *quantizationFactoryPtr_, + *defaultRuleEvaluationFactoryPtr_, multiThreadingSettings_, regressionMatrix); return std::make_unique>( *regularRuleEvaluationFactoryPtr_, *pruningRuleEvaluationFactoryPtr_, std::move(statisticsPtr), From 87daa7a5eba412deff1ef47efb1cf904aabee206 Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Sun, 11 Aug 2024 16:14:39 +0200 Subject: [PATCH 09/37] Edit comments. --- .../src/mlrl/boosting/statistics/statistics_common.hpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp index b6a2b7eb9d..199f189600 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp @@ -567,12 +567,20 @@ namespace boosting { /** * Must be implemented by subclasses in order to update the statistics for all available outputs at a * specific index. + * + * @param statisticIndex The index of the statistics that should be updated + * @param prediction A reference to an object of type `CompletePrediction` that stores the + * predictions according to which the statistics should be updated */ virtual void updateStatistics(uint32 statisticIndex, const CompletePrediction& prediction) = 0; /** * Must be implemented by subclasses in order to update the statistics for a subset of the available outputs * at a specific index. + * + * @param statisticIndex The index of the statistics that should be updated + * @param prediction A reference to an object of type `PartialPrediction` that stores the predictions + * according to which the statistics should be updated */ virtual void updateStatistics(uint32 statisticIndex, const PartialPrediction& prediction) = 0; From b99a0714dd2b41a23489852b88ddef4b8439d1fc Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Sun, 11 Aug 2024 18:32:56 +0200 Subject: [PATCH 10/37] Add function "commit" to class IStatisticsUpdate. --- .../src/mlrl/boosting/statistics/statistics_common.hpp | 4 ++++ .../common/include/mlrl/common/statistics/statistics.hpp | 5 +++++ .../src/mlrl/common/rule_induction/rule_induction_common.hpp | 1 + .../mlrl/common/rule_refinement/feature_space_tabular.cpp | 4 ++++ .../seco/src/mlrl/seco/statistics/statistics_common.hpp | 2 ++ 5 files changed, 16 insertions(+) diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp index 199f189600..f75bce23b9 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp @@ -523,6 +523,10 @@ namespace boosting { revertPredictionInternally(statisticIndex, prediction_, *statistics_.scoreMatrixPtr_); statistics_.updateStatistics(statisticIndex, prediction_); } + + void commit() override { + // TODO Implement + } }; protected: diff --git a/cpp/subprojects/common/include/mlrl/common/statistics/statistics.hpp b/cpp/subprojects/common/include/mlrl/common/statistics/statistics.hpp index 2a6ea33b49..cb8d18bf88 100644 --- a/cpp/subprojects/common/include/mlrl/common/statistics/statistics.hpp +++ b/cpp/subprojects/common/include/mlrl/common/statistics/statistics.hpp @@ -39,6 +39,11 @@ class IStatisticsUpdate { * @param statisticIndex The index of the statistic that should be updated */ virtual void revertPrediction(uint32 statisticIndex) = 0; + + /** + * Commits the update. + */ + virtual void commit() = 0; }; /** diff --git a/cpp/subprojects/common/src/mlrl/common/rule_induction/rule_induction_common.hpp b/cpp/subprojects/common/src/mlrl/common/rule_induction/rule_induction_common.hpp index 0be83e5748..4de065a007 100644 --- a/cpp/subprojects/common/src/mlrl/common/rule_induction/rule_induction_common.hpp +++ b/cpp/subprojects/common/src/mlrl/common/rule_induction/rule_induction_common.hpp @@ -97,6 +97,7 @@ class AbstractRuleInduction : public IRuleInduction { statisticsUpdatePtr->applyPrediction(i); } + statisticsUpdatePtr->commit(); modelBuilder.setDefaultRule(defaultPredictionPtr); } diff --git a/cpp/subprojects/common/src/mlrl/common/rule_refinement/feature_space_tabular.cpp b/cpp/subprojects/common/src/mlrl/common/rule_refinement/feature_space_tabular.cpp index 9b74db1e7f..32156fd4b2 100644 --- a/cpp/subprojects/common/src/mlrl/common/rule_refinement/feature_space_tabular.cpp +++ b/cpp/subprojects/common/src/mlrl/common/rule_refinement/feature_space_tabular.cpp @@ -287,6 +287,8 @@ class TabularFeatureSpace final : public IFeatureSpace { statisticsUpdateRawPtr->applyPrediction(i); } } + + statisticsUpdatePtr->commit(); } void revertPrediction(const IPrediction& prediction) override { @@ -307,6 +309,8 @@ class TabularFeatureSpace final : public IFeatureSpace { statisticsUpdateRawPtr->revertPrediction(i); } } + + statisticsUpdatePtr->commit(); } }; diff --git a/cpp/subprojects/seco/src/mlrl/seco/statistics/statistics_common.hpp b/cpp/subprojects/seco/src/mlrl/seco/statistics/statistics_common.hpp index be77d58ee8..93e3882c03 100644 --- a/cpp/subprojects/seco/src/mlrl/seco/statistics/statistics_common.hpp +++ b/cpp/subprojects/seco/src/mlrl/seco/statistics/statistics_common.hpp @@ -617,6 +617,8 @@ namespace seco { statistics_.majorityLabelVectorPtr_->cbegin(), statistics_.majorityLabelVectorPtr_->cend()); } + + void commit() override {} }; const LabelMatrix& labelMatrix_; From cbdb212a82276f5db1241827e64a42e7adb5fa1e Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Sun, 11 Aug 2024 18:41:33 +0200 Subject: [PATCH 11/37] Remove inline functions. --- .../boosting/statistics/statistics_common.hpp | 22 +++++-------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp index f75bce23b9..bece10c58d 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp @@ -457,20 +457,6 @@ namespace boosting { } }; - template - static inline void applyPredictionInternally(uint32 statisticIndex, const Prediction& prediction, - ScoreMatrix& scoreMatrix) { - scoreMatrix.addToRowFromSubset(statisticIndex, prediction.values_cbegin(), prediction.values_cend(), - prediction.indices_cbegin(), prediction.indices_cend()); - } - - template - static inline void revertPredictionInternally(uint32 statisticIndex, const Prediction& prediction, - ScoreMatrix& scoreMatrix) { - scoreMatrix.removeFromRowFromSubset(statisticIndex, prediction.values_cbegin(), prediction.values_cend(), - prediction.indices_cbegin(), prediction.indices_cend()); - } - /** * An abstract base class for all statistics that provide access to gradients and Hessians that are calculated * according to a loss function. @@ -515,12 +501,16 @@ namespace boosting { : statistics_(statistics), prediction_(prediction) {} void applyPrediction(uint32 statisticIndex) override { - applyPredictionInternally(statisticIndex, prediction_, *statistics_.scoreMatrixPtr_); + statistics_.scoreMatrixPtr_->addToRowFromSubset( + statisticIndex, prediction_.values_cbegin(), prediction_.values_cend(), + prediction_.indices_cbegin(), prediction_.indices_cend()); statistics_.updateStatistics(statisticIndex, prediction_); } void revertPrediction(uint32 statisticIndex) override { - revertPredictionInternally(statisticIndex, prediction_, *statistics_.scoreMatrixPtr_); + statistics_.scoreMatrixPtr_->removeFromRowFromSubset( + statisticIndex, prediction_.values_cbegin(), prediction_.values_cend(), + prediction_.indices_cbegin(), prediction_.indices_cend()); statistics_.updateStatistics(statisticIndex, prediction_); } From e00bd5e7c6a4f90c49c3c735f3153f2430d8c23b Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Sun, 11 Aug 2024 19:25:15 +0200 Subject: [PATCH 12/37] Add function "getIndexVector" to classes CompletePrediction and PartialPrediction. --- .../mlrl/common/rule_refinement/prediction_complete.hpp | 8 ++++++++ .../mlrl/common/rule_refinement/prediction_partial.hpp | 8 ++++++++ .../mlrl/common/rule_refinement/prediction_complete.cpp | 4 ++++ .../mlrl/common/rule_refinement/prediction_partial.cpp | 4 ++++ 4 files changed, 24 insertions(+) diff --git a/cpp/subprojects/common/include/mlrl/common/rule_refinement/prediction_complete.hpp b/cpp/subprojects/common/include/mlrl/common/rule_refinement/prediction_complete.hpp index 96c7d5992d..472ad22f90 100644 --- a/cpp/subprojects/common/include/mlrl/common/rule_refinement/prediction_complete.hpp +++ b/cpp/subprojects/common/include/mlrl/common/rule_refinement/prediction_complete.hpp @@ -82,6 +82,14 @@ class CompletePrediction final : public VectorDecorator */ index_const_iterator indices_cend() const; + /** + * Returns a reference to the `CompleteIndexVector` that stores the indices for which the rule predicts. + * + * @return A reference to an object of type `CompleteIndexVector` that stores the indices for which the rule + * predicts + */ + const CompleteIndexVector& getIndexVector() const; + uint32 getNumElements() const override; void sort() override; diff --git a/cpp/subprojects/common/include/mlrl/common/rule_refinement/prediction_partial.hpp b/cpp/subprojects/common/include/mlrl/common/rule_refinement/prediction_partial.hpp index 85745009aa..944dc90e6d 100644 --- a/cpp/subprojects/common/include/mlrl/common/rule_refinement/prediction_partial.hpp +++ b/cpp/subprojects/common/include/mlrl/common/rule_refinement/prediction_partial.hpp @@ -105,6 +105,14 @@ class PartialPrediction final : public ResizableVectorDecorator>::getNumElements(); } diff --git a/cpp/subprojects/common/src/mlrl/common/rule_refinement/prediction_partial.cpp b/cpp/subprojects/common/src/mlrl/common/rule_refinement/prediction_partial.cpp index b31fb476fb..12c54471d7 100644 --- a/cpp/subprojects/common/src/mlrl/common/rule_refinement/prediction_partial.cpp +++ b/cpp/subprojects/common/src/mlrl/common/rule_refinement/prediction_partial.cpp @@ -42,6 +42,10 @@ PartialPrediction::index_const_iterator PartialPrediction::indices_cend() const return indexVector_.cend(); } +const PartialIndexVector& PartialPrediction::getIndexVector() const { + return indexVector_; +} + uint32 PartialPrediction::getNumElements() const { return ResizableVectorDecorator>>::getNumElements(); } From 44b781876ba3224b64618eca3890f47a00e6189b Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Sun, 11 Aug 2024 18:46:41 +0200 Subject: [PATCH 13/37] Add function "quantize" to class IQuantization. --- .../mlrl/boosting/statistics/quantization.hpp | 19 +++++++++++++++++++ .../statistics/quantization_stochastic.hpp | 1 - .../boosting/statistics/quantization_no.cpp | 8 +++++++- .../statistics/quantization_stochastic.cpp | 12 +++++++++++- .../boosting/statistics/statistics_common.hpp | 2 +- 5 files changed, 38 insertions(+), 4 deletions(-) diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization.hpp index 5064585722..d99a78ac8b 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization.hpp @@ -3,6 +3,9 @@ */ #pragma once +#include "mlrl/common/indices/index_vector_complete.hpp" +#include "mlrl/common/indices/index_vector_partial.hpp" + #include namespace boosting { @@ -15,6 +18,22 @@ namespace boosting { public: virtual ~IQuantization() {} + + /** + * Quantifies all statistics that corresonds to the available outputs. + * + * @param outputIndices A reference to an object of type `ICompleteIndexVector` that stores the indices of + * the output for which the statistics should be quantized + */ + virtual void quantize(const CompleteIndexVector& outputIndices) = 0; + + /** + * Quantifies all statistics that correspond to a certain subset of the outputs. + * + * @param outputIndices A reference to an object of type `IPartialIndexVector` that stores the indices of + * the output for which the statistics should be quantized + */ + virtual void quantize(const PartialIndexVector& outputIndices) = 0; }; /** diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization_stochastic.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization_stochastic.hpp index 4d7e05a8a6..7ff50a5745 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization_stochastic.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization_stochastic.hpp @@ -4,7 +4,6 @@ #pragma once #include "mlrl/boosting/statistics/quantization.hpp" -#include "mlrl/common/data/types.hpp" // TODO Remove later #include diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_no.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_no.cpp index d3ad99335a..ca3798cc4b 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_no.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_no.cpp @@ -5,7 +5,13 @@ namespace boosting { /** * An implementation of the type `IQuantization` that does not actually perform any quantization. */ - class NoQuantization final : public IQuantization {}; + class NoQuantization final : public IQuantization { + public: + + void quantize(const CompleteIndexVector& outputIndices) override {} + + void quantize(const PartialIndexVector& outputIndices) override {} + }; /** * Allows to to create instances of the type `IQuantization` that do not actually perform any quantization. diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp index ce7446320f..22cc416b93 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp @@ -7,7 +7,17 @@ namespace boosting { /** * An implementation of the type `IQuantization` that uses a stochastic rounding strategy. */ - class StochasticQuantization final : public IQuantization {}; + class StochasticQuantization final : public IQuantization { + public: + + void quantize(const CompleteIndexVector& outputIndices) override { + // TODO Implement + } + + void quantize(const PartialIndexVector& outputIndices) override { + // TODO Implement + } + }; /** * Allows to to create instances of the type `IQuantization` that uses a stochastic rounding strategy. diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp index bece10c58d..91559f164e 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp @@ -515,7 +515,7 @@ namespace boosting { } void commit() override { - // TODO Implement + statistics_.quantizationPtr_->quantize(prediction_.getIndexVector()); } }; From f543e93c9fa9005cc9640226d88424ddc7ef658e Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Sun, 11 Aug 2024 23:02:37 +0200 Subject: [PATCH 14/37] Add "create" functions that accept different types of statistic matrices as arguments to class IQuantizationFactory. --- .../mlrl/boosting/statistics/quantization.hpp | 31 +++++++++++++++++-- .../boosting/statistics/quantization_no.cpp | 12 ++++++- .../statistics/quantization_stochastic.cpp | 12 ++++++- ...statistics_provider_decomposable_dense.cpp | 2 +- ...tatistics_provider_decomposable_sparse.cpp | 2 +- ...istics_provider_non_decomposable_dense.cpp | 2 +- 6 files changed, 54 insertions(+), 7 deletions(-) diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization.hpp index d99a78ac8b..a495072c06 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization.hpp @@ -3,6 +3,10 @@ */ #pragma once +#include "mlrl/boosting/data/view_statistic_non_decomposable_dense.hpp" +#include "mlrl/common/data/tuple.hpp" +#include "mlrl/common/data/view_matrix_c_contiguous.hpp" +#include "mlrl/common/data/view_matrix_sparse_set.hpp" #include "mlrl/common/indices/index_vector_complete.hpp" #include "mlrl/common/indices/index_vector_partial.hpp" @@ -47,9 +51,32 @@ namespace boosting { /** * Creates and returns a new object of type `IQuantization`. * - * @return An unique pointer to an object of type `IQuantization` that has been created + * @param statisticMatrix A reference to an object of type `CContiguousView` that stores the statistics to + * be quantized + * @return An unique pointer to an object of type `IQuantization` that has been created */ - virtual std::unique_ptr create() const = 0; + virtual std::unique_ptr create( + const CContiguousView>& statisticMatrix) const = 0; + + /** + * Creates and returns a new object of type `IQuantization`. + * + * @param statisticMatrix A reference to an object of type `SparseSetView` that stores the statistics to + * be quantized + * @return An unique pointer to an object of type `IQuantization` that has been created + */ + virtual std::unique_ptr create( + const SparseSetView>& statisticMatrix) const = 0; + + /** + * Creates and returns a new object of type `IQuantization`. + * + * @param statisticMatrix A reference to an object of type `DenseNonDecomposableStatisticView` that stores + * the statistics to be quantized + * @return An unique pointer to an object of type `IQuantization` that has been created + */ + virtual std::unique_ptr create( + const DenseNonDecomposableStatisticView& statisticMatrix) const = 0; }; /** diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_no.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_no.cpp index ca3798cc4b..b2ff246a14 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_no.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_no.cpp @@ -19,7 +19,17 @@ namespace boosting { class NoQuantizationFactory final : public IQuantizationFactory { public: - std::unique_ptr create() const override { + std::unique_ptr create( + const CContiguousView>& statisticMatrix) const override { + return std::make_unique(); + } + + std::unique_ptr create(const SparseSetView>& statisticMatrix) const override { + return std::make_unique(); + } + + std::unique_ptr create( + const DenseNonDecomposableStatisticView& statisticMatrix) const override { return std::make_unique(); } }; diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp index 22cc416b93..2dd1719f78 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp @@ -34,7 +34,17 @@ namespace boosting { */ StochasticQuantizationFactory(uint32 numBits) : numBits_(numBits) {} - std::unique_ptr create() const override { + std::unique_ptr create( + const CContiguousView>& statisticMatrix) const override { + return std::make_unique(); + } + + std::unique_ptr create(const SparseSetView>& statisticMatrix) const override { + return std::make_unique(); + } + + std::unique_ptr create( + const DenseNonDecomposableStatisticView& statisticMatrix) const override { return std::make_unique(); } }; diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp index f18332b85d..f78ae7a036 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp @@ -13,9 +13,9 @@ namespace boosting { MultiThreadingSettings multiThreadingSettings, const OutputMatrix& outputMatrix) { uint32 numExamples = outputMatrix.numRows; uint32 numOutputs = outputMatrix.numCols; - std::unique_ptr quantizationPtr = quantizationFactory.create(); std::unique_ptr statisticMatrixPtr = std::make_unique(numExamples, numOutputs); + std::unique_ptr quantizationPtr = quantizationFactory.create(statisticMatrixPtr->getView()); std::unique_ptr> scoreMatrixPtr = std::make_unique>(numExamples, numOutputs, true); const Loss* lossRawPtr = lossPtr.get(); diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_sparse.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_sparse.cpp index aab3c1f484..afd6e3922b 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_sparse.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_sparse.cpp @@ -87,13 +87,13 @@ namespace boosting { MultiThreadingSettings multiThreadingSettings, const OutputMatrix& outputMatrix) { uint32 numExamples = outputMatrix.numRows; uint32 numOutputs = outputMatrix.numCols; - std::unique_ptr quantizationPtr = quantizationFactory.create(); std::unique_ptr lossPtr = lossFactory.createSparseDecomposableClassificationLoss(); std::unique_ptr evaluationMeasurePtr = evaluationMeasureFactory.createSparseEvaluationMeasure(); std::unique_ptr statisticMatrixPtr = std::make_unique(numExamples, numOutputs); + std::unique_ptr quantizationPtr = quantizationFactory.create(statisticMatrixPtr->getView()); std::unique_ptr> scoreMatrixPtr = std::make_unique>(numExamples, numOutputs); const ISparseDecomposableClassificationLoss* lossRawPtr = lossPtr.get(); diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp index 6871d6a391..f59205cc8f 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp @@ -156,9 +156,9 @@ namespace boosting { MultiThreadingSettings multiThreadingSettings, const OutputMatrix& outputMatrix) { uint32 numExamples = outputMatrix.numRows; uint32 numOutputs = outputMatrix.numCols; - std::unique_ptr quantizationPtr = quantizationFactory.create(); std::unique_ptr statisticMatrixPtr = std::make_unique(numExamples, numOutputs); + std::unique_ptr quantizationPtr = quantizationFactory.create(statisticMatrixPtr->getView()); std::unique_ptr> scoreMatrixPtr = std::make_unique>(numExamples, numOutputs, true); const Loss* lossRawPtr = lossPtr.get(); From 2976254b7a6be3d257ee0f8d180953dece597b07 Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Sun, 11 Aug 2024 23:43:45 +0200 Subject: [PATCH 15/37] Add class IQuantizationMatrix. --- .../mlrl/boosting/statistics/quantization.hpp | 78 ++++++++++++++++ .../boosting/statistics/quantization_no.cpp | 93 +++++++++++++++++-- .../statistics/quantization_stochastic.cpp | 54 +++++++++-- 3 files changed, 206 insertions(+), 19 deletions(-) diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization.hpp index a495072c06..1153fc3591 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization.hpp @@ -10,10 +10,49 @@ #include "mlrl/common/indices/index_vector_complete.hpp" #include "mlrl/common/indices/index_vector_partial.hpp" +#include #include namespace boosting { + /** + * Defines an interfaces for all matrices for storing quantized statistics that are backed by a view. + */ + template + class IQuantizationMatrix { + public: + + virtual ~IQuantizationMatrix() {} + + /** + * Quantifies all statistics that corresonds to the available outputs. + * + * @param outputIndices A reference to an object of type `ICompleteIndexVector` that stores the indices of + * the output for which the statistics should be quantized + */ + virtual void quantize(const CompleteIndexVector& outputIndices) = 0; + + /** + * Quantifies all statistics that correspond to a certain subset of the outputs. + * + * @param outputIndices A reference to an object of type `IPartialIndexVector` that stores the indices of + * the output for which the statistics should be quantized + */ + virtual void quantize(const PartialIndexVector& outputIndices) = 0; + + /** + * The type of the view, the matrix is backed by. + */ + typedef View view_type; + + /** + * Returns the view, the matrix is backed by. + * + * @return A reference to an object of type `view_type` + */ + virtual const view_type& getView() const = 0; + }; + /** * Defines an interface for all classes that implement a method for quantizing statistics about the quality of * predictions for training examples. @@ -23,12 +62,50 @@ namespace boosting { virtual ~IQuantization() {} + /** + * A visitor function for handling quantization matrices that are backed by a view of the type + * `CContiguousView>`. + */ + typedef std::function>>>&)> + DenseDecomposableMatrixVisitor; + + /** + * A visitor function for handling quantization matrices that are backed by a view of the type + * `SparseSetView>`. + */ + typedef std::function>>>&)> + SparseDecomposableMatrixVisitor; + + /** + * A visitor function for handling quantization matrices that are backed by a view of the type + * `DenseNonDecomposableStatisticView`. + */ + typedef std::function>&)> + DenseNonDecomposableMatrixVisitor; + + /** + * Invokes one of the given visitor functions, depending on which one is able to handle the type of the + * matrix that is used for storing quantized scores. + * + * @param denseDecomposableMatrixVisitor The visitor function for handling quantization matrices that are + * backed by a view of the type `CContiguousView>` + * @param sparseDecomposableMatrixVisitor The visitor function for handling quantization matrices that are + * backed by a view of the type `SparseSetView>` + * @param denseNonDecomposableMatrixVisitor The visitor function for handling quantization matrices that are + * backed by a view of the type `DenseNonDecomposableStatisticView` + */ + virtual void visitQuantizationMatrix( + DenseDecomposableMatrixVisitor denseDecomposableMatrixVisitor, + SparseDecomposableMatrixVisitor sparseDecomposableMatrixVisitor, + DenseNonDecomposableMatrixVisitor denseNonDecomposableMatrixVisitor) = 0; + /** * Quantifies all statistics that corresonds to the available outputs. * * @param outputIndices A reference to an object of type `ICompleteIndexVector` that stores the indices of * the output for which the statistics should be quantized */ + // TODO Remove virtual void quantize(const CompleteIndexVector& outputIndices) = 0; /** @@ -37,6 +114,7 @@ namespace boosting { * @param outputIndices A reference to an object of type `IPartialIndexVector` that stores the indices of * the output for which the statistics should be quantized */ + // TODO Remove virtual void quantize(const PartialIndexVector& outputIndices) = 0; }; diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_no.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_no.cpp index b2ff246a14..486140f400 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_no.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_no.cpp @@ -2,35 +2,108 @@ namespace boosting { - /** - * An implementation of the type `IQuantization` that does not actually perform any quantization. - */ - class NoQuantization final : public IQuantization { + template + class NoQuantizationMatrix final : public IQuantizationMatrix { + private: + + const View& view_; + public: + NoQuantizationMatrix(const View& view) : view_(view) {} + void quantize(const CompleteIndexVector& outputIndices) override {} void quantize(const PartialIndexVector& outputIndices) override {} + + const typename IQuantizationMatrix::view_type& getView() const override { + return view_; + } + }; + + class NoDenseDecomposableQuantization final : public IQuantization { + private: + + std::unique_ptr>>> quantizationMatrixPtr_; + + public: + + NoDenseDecomposableQuantization(const CContiguousView>& view) + : quantizationMatrixPtr_( + std::make_unique>>>(view)) {} + + void quantize(const CompleteIndexVector& outputIndices) override {} + + void quantize(const PartialIndexVector& outputIndices) override {} + + void visitQuantizationMatrix( + IQuantization::DenseDecomposableMatrixVisitor denseDecomposableMatrixVisitor, + IQuantization::SparseDecomposableMatrixVisitor sparseDecomposableMatrixVisitor, + IQuantization::DenseNonDecomposableMatrixVisitor denseNonDecomposableMatrixVisitor) override { + denseDecomposableMatrixVisitor(quantizationMatrixPtr_); + } + }; + + class NoSparseDecomposableQuantization final : public IQuantization { + private: + + std::unique_ptr>>> quantizationMatrixPtr_; + + public: + + NoSparseDecomposableQuantization(const SparseSetView>& view) + : quantizationMatrixPtr_(std::make_unique>>>(view)) {} + + void quantize(const CompleteIndexVector& outputIndices) override {} + + void quantize(const PartialIndexVector& outputIndices) override {} + + void visitQuantizationMatrix( + IQuantization::DenseDecomposableMatrixVisitor denseDecomposableMatrixVisitor, + IQuantization::SparseDecomposableMatrixVisitor sparseDecomposableMatrixVisitor, + IQuantization::DenseNonDecomposableMatrixVisitor denseNonDecomposableMatrixVisitor) override { + sparseDecomposableMatrixVisitor(quantizationMatrixPtr_); + } + }; + + class NoDenseNonDecomposableQuantization final : public IQuantization { + private: + + std::unique_ptr> quantizationMatrixPtr_; + + public: + + NoDenseNonDecomposableQuantization(const DenseNonDecomposableStatisticView& view) + : quantizationMatrixPtr_( + std::make_unique>(view)) {} + + void quantize(const CompleteIndexVector& outputIndices) override {} + + void quantize(const PartialIndexVector& outputIndices) override {} + + void visitQuantizationMatrix( + IQuantization::DenseDecomposableMatrixVisitor denseDecomposableMatrixVisitor, + IQuantization::SparseDecomposableMatrixVisitor sparseDecomposableMatrixVisitor, + IQuantization::DenseNonDecomposableMatrixVisitor denseNonDecomposableMatrixVisitor) override { + denseNonDecomposableMatrixVisitor(quantizationMatrixPtr_); + } }; - /** - * Allows to to create instances of the type `IQuantization` that do not actually perform any quantization. - */ class NoQuantizationFactory final : public IQuantizationFactory { public: std::unique_ptr create( const CContiguousView>& statisticMatrix) const override { - return std::make_unique(); + return std::make_unique(statisticMatrix); } std::unique_ptr create(const SparseSetView>& statisticMatrix) const override { - return std::make_unique(); + return std::make_unique(statisticMatrix); } std::unique_ptr create( const DenseNonDecomposableStatisticView& statisticMatrix) const override { - return std::make_unique(); + return std::make_unique(statisticMatrix); } }; diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp index 2dd1719f78..9added3749 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp @@ -4,12 +4,44 @@ namespace boosting { - /** - * An implementation of the type `IQuantization` that uses a stochastic rounding strategy. - */ + template + class StochasticQuantizationMatrix final : public IQuantizationMatrix>> { + private: + + const View& view_; + + // TODO Use correct type + MatrixDecorator>> matrix_; + + public: + + StochasticQuantizationMatrix(const View& view) + : view_(view), matrix_(AllocatedCContiguousView>(view.numRows, view.numCols)) {} + + void quantize(const CompleteIndexVector& outputIndices) override { + // TODO Implement + } + + void quantize(const PartialIndexVector& outputIndices) override { + // TODO Implement + } + + const typename IQuantizationMatrix>>::view_type& getView() const override { + return matrix_.getView(); + } + }; + + template class StochasticQuantization final : public IQuantization { + private: + + std::unique_ptr>>> quantizationMatrixPtr_; + public: + StochasticQuantization(const View& view) + : quantizationMatrixPtr_(std::make_unique>(view)) {} + void quantize(const CompleteIndexVector& outputIndices) override { // TODO Implement } @@ -17,11 +49,15 @@ namespace boosting { void quantize(const PartialIndexVector& outputIndices) override { // TODO Implement } + + void visitQuantizationMatrix( + IQuantization::DenseDecomposableMatrixVisitor denseDecomposableMatrixVisitor, + IQuantization::SparseDecomposableMatrixVisitor sparseDecomposableMatrixVisitor, + IQuantization::DenseNonDecomposableMatrixVisitor denseNonDecomposableMatrixVisitor) override { + denseDecomposableMatrixVisitor(quantizationMatrixPtr_); + } }; - /** - * Allows to to create instances of the type `IQuantization` that uses a stochastic rounding strategy. - */ class StochasticQuantizationFactory final : public IQuantizationFactory { private: @@ -36,16 +72,16 @@ namespace boosting { std::unique_ptr create( const CContiguousView>& statisticMatrix) const override { - return std::make_unique(); + return std::make_unique>>>(statisticMatrix); } std::unique_ptr create(const SparseSetView>& statisticMatrix) const override { - return std::make_unique(); + return std::make_unique>>>(statisticMatrix); } std::unique_ptr create( const DenseNonDecomposableStatisticView& statisticMatrix) const override { - return std::make_unique(); + return std::make_unique>(statisticMatrix); } }; From dd83d2baab9bf3f2205ffb5b21f43a6a72fcd637 Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Tue, 13 Aug 2024 01:03:04 +0200 Subject: [PATCH 16/37] Use function "visitQuantizationMatrix". --- ...statistics_provider_decomposable_dense.cpp | 21 ++++++++++++++--- ...tatistics_provider_decomposable_sparse.cpp | 21 ++++++++++++++--- ...istics_provider_non_decomposable_dense.cpp | 23 ++++++++++++++++--- 3 files changed, 56 insertions(+), 9 deletions(-) diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp index f78ae7a036..7ae37226a4 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp @@ -33,9 +33,24 @@ namespace boosting { IndexIterator(outputMatrixPtr->numCols), *statisticMatrixRawPtr); } - return std::make_unique>( - std::move(quantizationPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, - outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)); + std::unique_ptr> statisticsPtr; + auto denseDecomposableMatrixVisitor = + [&](std::unique_ptr>>>& ptr) { + statisticsPtr = std::make_unique>( + std::move(quantizationPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, + outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)); + }; + auto sparseDecomposableMatrixVisitor = + [&](std::unique_ptr>>>& quantizationMatrixPtr) { + throw std::runtime_error("not implemented"); + }; + auto denseNonDecomposableMatrixVisitor = + [&](std::unique_ptr>& quantizationMatrixPtr) { + throw std::runtime_error("not implemented"); + }; + quantizationPtr->visitQuantizationMatrix(denseDecomposableMatrixVisitor, sparseDecomposableMatrixVisitor, + denseNonDecomposableMatrixVisitor); + return statisticsPtr; } DenseDecomposableClassificationStatisticsProviderFactory::DenseDecomposableClassificationStatisticsProviderFactory( diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_sparse.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_sparse.cpp index afd6e3922b..6d1d5d5f1e 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_sparse.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_sparse.cpp @@ -111,9 +111,24 @@ namespace boosting { IndexIterator(outputMatrixPtr->numCols), *statisticMatrixRawPtr); } - return std::make_unique>( - std::move(quantizationPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, - outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)); + std::unique_ptr> statisticsPtr; + auto denseDecomposableMatrixVisitor = + [&](std::unique_ptr>>>& quantizationMatrixPtr) { + throw std::runtime_error("not implemented"); + }; + auto sparseDecomposableMatrixVisitor = + [&](std::unique_ptr>>>& ptr) { + statisticsPtr = std::make_unique>( + std::move(quantizationPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, + outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)); + }; + auto denseNonDecomposableMatrixVisitor = + [&](std::unique_ptr>& quantizationMatrixPtr) { + throw std::runtime_error("not implemented"); + }; + quantizationPtr->visitQuantizationMatrix(denseDecomposableMatrixVisitor, sparseDecomposableMatrixVisitor, + denseNonDecomposableMatrixVisitor); + return statisticsPtr; } SparseDecomposableClassificationStatisticsProviderFactory:: diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp index f59205cc8f..afbb22e834 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp @@ -175,9 +175,26 @@ namespace boosting { *statisticMatrixRawPtr); } - return std::make_unique>( - std::move(quantizationPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, - outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)); + std::unique_ptr< + INonDecomposableStatistics> + statisticsPtr; + auto denseDecomposableMatrixVisitor = + [&](std::unique_ptr>>>& quantizationMatrixPtr) { + throw std::runtime_error("not implemented"); + }; + auto sparseDecomposableMatrixVisitor = + [&](std::unique_ptr>>>& quantizationMatrixPtr) { + throw std::runtime_error("not implemented"); + }; + auto denseNonDecomposableMatrixVisitor = + [&](std::unique_ptr>& ptr) { + statisticsPtr = std::make_unique>( + std::move(quantizationPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, + outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)); + }; + quantizationPtr->visitQuantizationMatrix(denseDecomposableMatrixVisitor, sparseDecomposableMatrixVisitor, + denseNonDecomposableMatrixVisitor); + return statisticsPtr; } DenseNonDecomposableClassificationStatisticsProviderFactory:: From 2867c50016e1cd32f6986d78b48fa9ee02407fae Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Tue, 13 Aug 2024 01:17:10 +0200 Subject: [PATCH 17/37] Add template argument "QuantizationMatrix" to class AbstractStatistics. --- .../boosting/statistics/statistics_common.hpp | 5 +++-- .../statistics_decomposable_common.hpp | 13 +++++++------ .../statistics_decomposable_dense.hpp | 7 ++++--- .../statistics_non_decomposable_common.hpp | 16 +++++++++------- .../statistics_provider_decomposable_dense.cpp | 3 ++- .../statistics_provider_decomposable_sparse.cpp | 13 ++++++++----- ...atistics_provider_non_decomposable_dense.cpp | 17 ++++++++++------- 7 files changed, 43 insertions(+), 31 deletions(-) diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp index 91559f164e..55d3a27b1c 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp @@ -463,6 +463,7 @@ namespace boosting { * * @tparam OutputMatrix The type of the matrix that provides access to the ground truth of the training * examples + * @tparam QuantizationMatrix The type of the matrix that provides access to quantized gradients and Hessians * @tparam StatisticVector The type of the vectors that are used to store gradients and Hessians * @tparam StatisticMatrix The type of the matrix that provides access to the gradients and Hessians * @tparam ScoreMatrix The type of the matrices that are used to store predicted scores @@ -473,8 +474,8 @@ namespace boosting { * used for calculating the predictions of rules, as well as corresponding quality * scores */ - template + template class AbstractStatistics : virtual public IBoostingStatistics { private: diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_decomposable_common.hpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_decomposable_common.hpp index ae6d4320ee..ed1ede7b17 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_decomposable_common.hpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_decomposable_common.hpp @@ -28,6 +28,7 @@ namespace boosting { * * @tparam OutputMatrix The type of the matrix that provides access to the ground truth of the training * examples + * @tparam QuantizationMatrix The type of the matrix that provides access to quantized gradients and Hessians * @tparam StatisticVector The type of the vectors that are used to store gradients and Hessians * @tparam StatisticMatrix The type of the matrix that provides access to the gradients and Hessians * @tparam ScoreMatrix The type of the matrices that are used to store predicted scores @@ -38,11 +39,11 @@ namespace boosting { * used for calculating the predictions of rules, as well as corresponding quality * scores */ - template + template class AbstractDecomposableStatistics - : public AbstractStatistics, + : public AbstractStatistics, virtual public IDecomposableStatistics { protected: @@ -86,8 +87,8 @@ namespace boosting { const OutputMatrix& outputMatrix, std::unique_ptr statisticMatrixPtr, std::unique_ptr scoreMatrixPtr) - : AbstractStatistics( + : AbstractStatistics( std::move(quantizationPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)) {} diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_decomposable_dense.hpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_decomposable_dense.hpp index e9bd697907..9980a0424d 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_decomposable_dense.hpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_decomposable_dense.hpp @@ -52,11 +52,12 @@ namespace boosting { * @tparam Loss The type of the loss function * @tparam OutputMatrix The type of the matrix that provides access to the ground truth of the training * examples + * @tparam QuantizationMatrix The type of the matrix that provides access to quantized gradients and Hessians * @tparam EvaluationMeasure The type of the evaluation that should be used to access the quality of predictions */ - template + template class DenseDecomposableStatistics final - : public AbstractDecomposableStatistics, Loss, EvaluationMeasure, IDecomposableRuleEvaluationFactory> { public: @@ -85,7 +86,7 @@ namespace boosting { const OutputMatrix& outputMatrix, std::unique_ptr statisticMatrixPtr, std::unique_ptr> scoreMatrixPtr) - : AbstractDecomposableStatistics, Loss, EvaluationMeasure, IDecomposableRuleEvaluationFactory>( std::move(quantizationPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_non_decomposable_common.hpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_non_decomposable_common.hpp index 4ab5024171..f1d00085bb 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_non_decomposable_common.hpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_non_decomposable_common.hpp @@ -26,6 +26,8 @@ namespace boosting { * * @tparam OutputMatrix The type of the matrix that provides access to the ground truth of * the training examples + * @tparam QuantizationMatrix The type of the matrix that provides access to quantized gradients + * and Hessians * @tparam StatisticVector The type of the vectors that are used to store gradients and * Hessians * @tparam StatisticMatrix The type of the matrix that stores the gradients and Hessians @@ -43,12 +45,12 @@ namespace boosting { * their overall quality, based on gradients and Hessians that have * been calculated according to a decomposable loss function */ - template + template class AbstractNonDecomposableStatistics - : public AbstractStatistics, + : public AbstractStatistics, virtual public INonDecomposableStatistics { protected: @@ -94,8 +96,8 @@ namespace boosting { const OutputMatrix& outputMatrix, std::unique_ptr statisticMatrixPtr, std::unique_ptr scoreMatrixPtr) - : AbstractStatistics( + : AbstractStatistics( std::move(quantizationPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)) {} diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp index 7ae37226a4..74a77ced57 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp @@ -36,7 +36,8 @@ namespace boosting { std::unique_ptr> statisticsPtr; auto denseDecomposableMatrixVisitor = [&](std::unique_ptr>>>& ptr) { - statisticsPtr = std::make_unique>( + statisticsPtr = std::make_unique>>, EvaluationMeasure>>( std::move(quantizationPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)); }; diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_sparse.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_sparse.cpp index 6d1d5d5f1e..fbcdcabbb3 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_sparse.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_sparse.cpp @@ -27,11 +27,13 @@ namespace boosting { * Provides access to gradients and Hessians that have been calculated according to a decomposable loss function * and are stored using sparse data structures. * - * @tparam OutputMatrix The type of the matrix that provides access to the ground truth of the training examples + * @tparam OutputMatrix The type of the matrix that provides access to the ground truth of the training + * examples + * @tparam QuantizationMatrix The type of the matrix that provides access to quantized gradients and Hessians */ - template + template class SparseDecomposableStatistics final - : public AbstractDecomposableStatistics, ISparseDecomposableClassificationLoss, ISparseEvaluationMeasure, ISparseDecomposableRuleEvaluationFactory> { @@ -63,7 +65,7 @@ namespace boosting { const OutputMatrix& outputMatrix, std::unique_ptr statisticViewPtr, std::unique_ptr> scoreMatrixPtr) - : AbstractDecomposableStatistics, ISparseDecomposableClassificationLoss, ISparseEvaluationMeasure, ISparseDecomposableRuleEvaluationFactory>( @@ -118,7 +120,8 @@ namespace boosting { }; auto sparseDecomposableMatrixVisitor = [&](std::unique_ptr>>>& ptr) { - statisticsPtr = std::make_unique>( + statisticsPtr = std::make_unique< + SparseDecomposableStatistics>>>>( std::move(quantizationPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)); }; diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp index afbb22e834..a66f4adfa1 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp @@ -54,13 +54,14 @@ namespace boosting { * @tparam Loss The type of the non-decomposable loss function * @tparam OutputMatrix The type of the matrix that provides access to the ground truth of the training * examples + * @tparam QuantizationMatrix The type of the matrix that provides access to quantized gradients and Hessians * @tparam EvaluationMeasure The type of the evaluation measure that should be used to access the quality of * predictions */ - template + template class DenseNonDecomposableStatistics final : public AbstractNonDecomposableStatistics< - OutputMatrix, DenseNonDecomposableStatisticVector, DenseNonDecomposableStatisticMatrix, + OutputMatrix, QuantizationMatrix, DenseNonDecomposableStatisticVector, DenseNonDecomposableStatisticMatrix, NumericCContiguousMatrix, Loss, EvaluationMeasure, INonDecomposableRuleEvaluationFactory, IDecomposableRuleEvaluationFactory> { public: @@ -91,9 +92,9 @@ namespace boosting { std::unique_ptr statisticMatrixPtr, std::unique_ptr> scoreMatrixPtr) : AbstractNonDecomposableStatistics< - OutputMatrix, DenseNonDecomposableStatisticVector, DenseNonDecomposableStatisticMatrix, - NumericCContiguousMatrix, Loss, EvaluationMeasure, INonDecomposableRuleEvaluationFactory, - IDecomposableRuleEvaluationFactory>( + OutputMatrix, QuantizationMatrix, DenseNonDecomposableStatisticVector, + DenseNonDecomposableStatisticMatrix, NumericCContiguousMatrix, Loss, EvaluationMeasure, + INonDecomposableRuleEvaluationFactory, IDecomposableRuleEvaluationFactory>( std::move(quantizationPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)) {} @@ -140,7 +141,8 @@ namespace boosting { } } - return std::make_unique>( + return std::make_unique< + DenseDecomposableStatistics>( std::move(this->quantizationPtr_), std::move(this->lossPtr_), std::move(this->evaluationMeasurePtr_), ruleEvaluationFactory, this->outputMatrix_, std::move(decomposableStatisticMatrixPtr), std::move(this->scoreMatrixPtr_)); @@ -188,7 +190,8 @@ namespace boosting { }; auto denseNonDecomposableMatrixVisitor = [&](std::unique_ptr>& ptr) { - statisticsPtr = std::make_unique>( + statisticsPtr = std::make_unique, EvaluationMeasure>>( std::move(quantizationPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)); }; From 30c62397ef73860eccc63107bc6317c1f026fe90 Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Tue, 13 Aug 2024 01:28:25 +0200 Subject: [PATCH 18/37] Pass argument of type IQuantizationMatrix to constructor of the class AbstractStatistics. --- .../boosting/statistics/statistics_common.hpp | 15 +++++++------- .../statistics_decomposable_common.hpp | 8 ++++---- .../statistics_decomposable_dense.hpp | 9 +++++---- .../statistics_non_decomposable_common.hpp | 8 ++++---- ...statistics_provider_decomposable_dense.cpp | 6 +++--- ...tatistics_provider_decomposable_sparse.cpp | 14 ++++++------- ...istics_provider_non_decomposable_dense.cpp | 20 +++++++++---------- 7 files changed, 41 insertions(+), 39 deletions(-) diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp index 55d3a27b1c..f69aff0995 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp @@ -516,16 +516,16 @@ namespace boosting { } void commit() override { - statistics_.quantizationPtr_->quantize(prediction_.getIndexVector()); + statistics_.quantizationMatrixPtr_->quantize(prediction_.getIndexVector()); } }; protected: /** - * An unique pointer to the method that should be used for quantizing gradients and Hessians. + * An unique pointer to the matrix that provides access to quantized gradients and Hessians. */ - std::unique_ptr quantizationPtr_; + std::unique_ptr quantizationMatrixPtr_; /** * An unique pointer to the loss function that should be used for calculating gradients and Hessians. @@ -582,8 +582,8 @@ namespace boosting { public: /** - * @param quantizationPtr An unique pointer to an object of type `IQuantization` that implements the - * method that should be used for quantizing gradients and Hessians + * @param quantizationMatrixPtr An unique pointer to an object of template type `QuantizationMatrix` that + * provides access to quantized gradients and Hessians * @param lossPtr An unique pointer to an object of template type `LossFunction` that * implements the loss function that should be used for calculating gradients * and Hessians @@ -600,12 +600,13 @@ namespace boosting { * @param scoreMatrixPtr An unique pointer to an object of template type `ScoreMatrix` that stores * the currently predicted scores */ - AbstractStatistics(std::unique_ptr quantizationPtr, std::unique_ptr lossPtr, + AbstractStatistics(std::unique_ptr quantizationMatrixPtr, + std::unique_ptr lossPtr, std::unique_ptr evaluationMeasurePtr, const RuleEvaluationFactory& ruleEvaluationFactory, const OutputMatrix& outputMatrix, std::unique_ptr statisticMatrixPtr, std::unique_ptr scoreMatrixPtr) - : quantizationPtr_(std::move(quantizationPtr)), lossPtr_(std::move(lossPtr)), + : quantizationMatrixPtr_(std::move(quantizationMatrixPtr)), lossPtr_(std::move(lossPtr)), evaluationMeasurePtr_(std::move(evaluationMeasurePtr)), ruleEvaluationFactory_(&ruleEvaluationFactory), outputMatrix_(outputMatrix), statisticMatrixPtr_(std::move(statisticMatrixPtr)), scoreMatrixPtr_(std::move(scoreMatrixPtr)) {} diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_decomposable_common.hpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_decomposable_common.hpp index ed1ede7b17..a544127ad0 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_decomposable_common.hpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_decomposable_common.hpp @@ -62,8 +62,8 @@ namespace boosting { public: /** - * @param quantizationPtr An unique pointer to an object of type `IQuantization` that implements the - * method that should be used for quantizing gradients and Hessians + * @param quantizationMatrixPtr An unique pointer to an object of template type `QuantizationMatrix` that + * provides access to quantized gradients and Hessians * @param lossPtr An unique pointer to an object of template type `LossFunction` that * implements the loss function that should be used for calculating gradients * and Hessians @@ -80,7 +80,7 @@ namespace boosting { * @param scoreMatrixPtr An unique pointer to an object of template type `ScoreMatrix` that stores * the currently predicted scores */ - AbstractDecomposableStatistics(std::unique_ptr quantizationPtr, + AbstractDecomposableStatistics(std::unique_ptr quantizationMatrixPtr, std::unique_ptr lossPtr, std::unique_ptr evaluationMeasurePtr, const RuleEvaluationFactory& ruleEvaluationFactory, @@ -89,7 +89,7 @@ namespace boosting { std::unique_ptr scoreMatrixPtr) : AbstractStatistics( - std::move(quantizationPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), + std::move(quantizationMatrixPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)) {} /** diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_decomposable_dense.hpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_decomposable_dense.hpp index 9980a0424d..e772407733 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_decomposable_dense.hpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_decomposable_dense.hpp @@ -63,8 +63,8 @@ namespace boosting { public: /** - * @param quantizationPtr An unique pointer to an object of type `IQuantization` that implements the - * method that should be used for quantizing gradients and Hessians + * @param quantizationMatrixPtr An unique pointer to an object of template type `QuantizationMatrix` that + * provides access to quantized gradients and Hessians * @param lossPtr An unique pointer to an object of template type `Loss` that implements the * loss function that should be used for calculating gradients and Hessians * @param evaluationMeasurePtr An unique pointer to an object of template type `EvaluationMeasure` that @@ -80,7 +80,8 @@ namespace boosting { * @param scoreMatrixPtr An unique pointer to an object of type `NumericCContiguousMatrix` that * stores the currently predicted scores */ - DenseDecomposableStatistics(std::unique_ptr quantizationPtr, std::unique_ptr lossPtr, + DenseDecomposableStatistics(std::unique_ptr quantizationMatrixPtr, + std::unique_ptr lossPtr, std::unique_ptr evaluationMeasurePtr, const IDecomposableRuleEvaluationFactory& ruleEvaluationFactory, const OutputMatrix& outputMatrix, @@ -89,7 +90,7 @@ namespace boosting { : AbstractDecomposableStatistics, Loss, EvaluationMeasure, IDecomposableRuleEvaluationFactory>( - std::move(quantizationPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), + std::move(quantizationMatrixPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)) {} /** diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_non_decomposable_common.hpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_non_decomposable_common.hpp index f1d00085bb..4b60ed524d 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_non_decomposable_common.hpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_non_decomposable_common.hpp @@ -70,8 +70,8 @@ namespace boosting { public: /** - * @param quantizationPtr An unique pointer to an object of type `IQuantization` that implements the - * method that should be used for quantizing gradients and Hessians + * @param quantizationMatrixPtr An unique pointer to an object of template type `QuantizationMatrix` that + * provides access to quantized gradients and Hessians * @param lossPtr An unique pointer to an object of template type `LossFunction` that * implements the loss function that should be used for calculating gradients * and Hessians @@ -89,7 +89,7 @@ namespace boosting { * @param scoreMatrixPtr An unique pointer to an object of template type `ScoreMatrix` that stores * the currently predicted scores */ - AbstractNonDecomposableStatistics(std::unique_ptr quantizationPtr, + AbstractNonDecomposableStatistics(std::unique_ptr quantizationMatrixPtr, std::unique_ptr lossPtr, std::unique_ptr evaluationMeasurePtr, const NonDecomposableRuleEvaluationFactory& ruleEvaluationFactory, @@ -98,7 +98,7 @@ namespace boosting { std::unique_ptr scoreMatrixPtr) : AbstractStatistics( - std::move(quantizationPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), + std::move(quantizationMatrixPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)) {} /** diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp index 74a77ced57..09e594db65 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp @@ -35,11 +35,11 @@ namespace boosting { std::unique_ptr> statisticsPtr; auto denseDecomposableMatrixVisitor = - [&](std::unique_ptr>>>& ptr) { + [&](std::unique_ptr>>>& quantizationMatrixPtr) { statisticsPtr = std::make_unique>>, EvaluationMeasure>>( - std::move(quantizationPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, - outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)); + std::move(quantizationMatrixPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), + ruleEvaluationFactory, outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)); }; auto sparseDecomposableMatrixVisitor = [&](std::unique_ptr>>>& quantizationMatrixPtr) { diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_sparse.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_sparse.cpp index fbcdcabbb3..e04579fdb1 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_sparse.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_sparse.cpp @@ -40,8 +40,8 @@ namespace boosting { public: /** - * @param quantizationPtr An unique pointer to an object of type `IQuantization` that implements the - * method that should be used for calculating gradients and Hessians + * @param quantizationMatrixPtr An unique pointer to an object of template type `QuantizationMatrix` that + * provides access to quantized gradients and Hessians * @param lossPtr An unique pointer to an object of template type `LossFunction` that * implements the loss function that should be used for calculating gradients * and Hessians @@ -58,7 +58,7 @@ namespace boosting { * @param scoreMatrixPtr An unique pointer to an object of type `NumericSparseSetMatrix` that stores * the currently predicted scores */ - SparseDecomposableStatistics(std::unique_ptr quantizationPtr, + SparseDecomposableStatistics(std::unique_ptr quantizationMatrixPtr, std::unique_ptr lossPtr, std::unique_ptr evaluationMeasurePtr, const ISparseDecomposableRuleEvaluationFactory& ruleEvaluationFactory, @@ -69,7 +69,7 @@ namespace boosting { SparseDecomposableStatisticMatrix, NumericSparseSetMatrix, ISparseDecomposableClassificationLoss, ISparseEvaluationMeasure, ISparseDecomposableRuleEvaluationFactory>( - std::move(quantizationPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), + std::move(quantizationMatrixPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, outputMatrix, std::move(statisticViewPtr), std::move(scoreMatrixPtr)) {} /** @@ -119,11 +119,11 @@ namespace boosting { throw std::runtime_error("not implemented"); }; auto sparseDecomposableMatrixVisitor = - [&](std::unique_ptr>>>& ptr) { + [&](std::unique_ptr>>>& quantizationMatrixPtr) { statisticsPtr = std::make_unique< SparseDecomposableStatistics>>>>( - std::move(quantizationPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, - outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)); + std::move(quantizationMatrixPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), + ruleEvaluationFactory, outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)); }; auto denseNonDecomposableMatrixVisitor = [&](std::unique_ptr>& quantizationMatrixPtr) { diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp index a66f4adfa1..a8a1009942 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp @@ -67,8 +67,8 @@ namespace boosting { public: /** - * @param quantizationPtr An unique pointer to an object of type `IQuantization` that implements the - * method for quantizing gradients and Hessians + * @param quantizationMatrixPtr An unique pointer to an object of template type `QuantizationMatrix` that + * provides access to quantized gradients and Hessians * @param lossPtr An unique pointer to an object of template type `Loss` that implements the * loss function to be used for calculating gradients and Hessians * @param evaluationMeasurePtr An unique pointer to an object of template type `EvaluationMeasure` that @@ -84,7 +84,7 @@ namespace boosting { * @param scoreMatrixPtr An unique pointer to an object of type `NumericCContiguousMatrix` that * stores the currently predicted scores */ - DenseNonDecomposableStatistics(std::unique_ptr quantizationPtr, + DenseNonDecomposableStatistics(std::unique_ptr quantizationMatrixPtr, std::unique_ptr lossPtr, std::unique_ptr evaluationMeasurePtr, const INonDecomposableRuleEvaluationFactory& ruleEvaluationFactory, @@ -95,7 +95,7 @@ namespace boosting { OutputMatrix, QuantizationMatrix, DenseNonDecomposableStatisticVector, DenseNonDecomposableStatisticMatrix, NumericCContiguousMatrix, Loss, EvaluationMeasure, INonDecomposableRuleEvaluationFactory, IDecomposableRuleEvaluationFactory>( - std::move(quantizationPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), + std::move(quantizationMatrixPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)) {} /** @@ -143,9 +143,9 @@ namespace boosting { return std::make_unique< DenseDecomposableStatistics>( - std::move(this->quantizationPtr_), std::move(this->lossPtr_), std::move(this->evaluationMeasurePtr_), - ruleEvaluationFactory, this->outputMatrix_, std::move(decomposableStatisticMatrixPtr), - std::move(this->scoreMatrixPtr_)); + std::move(this->quantizationMatrixPtr_), std::move(this->lossPtr_), + std::move(this->evaluationMeasurePtr_), ruleEvaluationFactory, this->outputMatrix_, + std::move(decomposableStatisticMatrixPtr), std::move(this->scoreMatrixPtr_)); } }; @@ -189,11 +189,11 @@ namespace boosting { throw std::runtime_error("not implemented"); }; auto denseNonDecomposableMatrixVisitor = - [&](std::unique_ptr>& ptr) { + [&](std::unique_ptr>& quantizationMatrixPtr) { statisticsPtr = std::make_unique, EvaluationMeasure>>( - std::move(quantizationPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, - outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)); + std::move(quantizationMatrixPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), + ruleEvaluationFactory, outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)); }; quantizationPtr->visitQuantizationMatrix(denseDecomposableMatrixVisitor, sparseDecomposableMatrixVisitor, denseNonDecomposableMatrixVisitor); From d09e5a493d0d70c64b7b851643fd9df3a11592a3 Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Wed, 14 Aug 2024 22:56:20 +0200 Subject: [PATCH 19/37] Let IQuantizationMatrix inherit from IQuantizationFactory. --- .../mlrl/boosting/statistics/quantization.hpp | 78 +++++++++--------- .../boosting/statistics/quantization_no.cpp | 81 ++++++++++++------- .../statistics/quantization_stochastic.cpp | 63 ++++++++++----- ...istics_provider_non_decomposable_dense.cpp | 27 +++++-- 4 files changed, 156 insertions(+), 93 deletions(-) diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization.hpp index 1153fc3591..f4fb743a00 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization.hpp @@ -15,43 +15,9 @@ namespace boosting { - /** - * Defines an interfaces for all matrices for storing quantized statistics that are backed by a view. - */ - template - class IQuantizationMatrix { - public: - - virtual ~IQuantizationMatrix() {} - - /** - * Quantifies all statistics that corresonds to the available outputs. - * - * @param outputIndices A reference to an object of type `ICompleteIndexVector` that stores the indices of - * the output for which the statistics should be quantized - */ - virtual void quantize(const CompleteIndexVector& outputIndices) = 0; - - /** - * Quantifies all statistics that correspond to a certain subset of the outputs. - * - * @param outputIndices A reference to an object of type `IPartialIndexVector` that stores the indices of - * the output for which the statistics should be quantized - */ - virtual void quantize(const PartialIndexVector& outputIndices) = 0; - - /** - * The type of the view, the matrix is backed by. - */ - typedef View view_type; - - /** - * Returns the view, the matrix is backed by. - * - * @return A reference to an object of type `view_type` - */ - virtual const view_type& getView() const = 0; - }; + // Forward declarations + template + class IQuantizationMatrix; /** * Defines an interface for all classes that implement a method for quantizing statistics about the quality of @@ -157,6 +123,44 @@ namespace boosting { const DenseNonDecomposableStatisticView& statisticMatrix) const = 0; }; + /** + * Defines an interfaces for all matrices for storing quantized statistics that are backed by a view. + */ + template + class IQuantizationMatrix : public IQuantizationFactory { + public: + + virtual ~IQuantizationMatrix() override {} + + /** + * Quantifies all statistics that corresonds to the available outputs. + * + * @param outputIndices A reference to an object of type `ICompleteIndexVector` that stores the indices of + * the output for which the statistics should be quantized + */ + virtual void quantize(const CompleteIndexVector& outputIndices) = 0; + + /** + * Quantifies all statistics that correspond to a certain subset of the outputs. + * + * @param outputIndices A reference to an object of type `IPartialIndexVector` that stores the indices of + * the output for which the statistics should be quantized + */ + virtual void quantize(const PartialIndexVector& outputIndices) = 0; + + /** + * The type of the view, the matrix is backed by. + */ + typedef View view_type; + + /** + * Returns the view, the matrix is backed by. + * + * @return A reference to an object of type `view_type` + */ + virtual const view_type& getView() const = 0; + }; + /** * Defines an interface for all classes that allow to configure a method for quantizing statistics about the quality * of predictions for training examples. diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_no.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_no.cpp index 486140f400..71df467221 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_no.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_no.cpp @@ -2,25 +2,6 @@ namespace boosting { - template - class NoQuantizationMatrix final : public IQuantizationMatrix { - private: - - const View& view_; - - public: - - NoQuantizationMatrix(const View& view) : view_(view) {} - - void quantize(const CompleteIndexVector& outputIndices) override {} - - void quantize(const PartialIndexVector& outputIndices) override {} - - const typename IQuantizationMatrix::view_type& getView() const override { - return view_; - } - }; - class NoDenseDecomposableQuantization final : public IQuantization { private: @@ -28,9 +9,9 @@ namespace boosting { public: - NoDenseDecomposableQuantization(const CContiguousView>& view) - : quantizationMatrixPtr_( - std::make_unique>>>(view)) {} + NoDenseDecomposableQuantization( + std::unique_ptr>>> quantizationMatrixPtr) + : quantizationMatrixPtr_(std::move(quantizationMatrixPtr)) {} void quantize(const CompleteIndexVector& outputIndices) override {} @@ -51,8 +32,9 @@ namespace boosting { public: - NoSparseDecomposableQuantization(const SparseSetView>& view) - : quantizationMatrixPtr_(std::make_unique>>>(view)) {} + NoSparseDecomposableQuantization( + std::unique_ptr>>> quantizationMatrixPtr) + : quantizationMatrixPtr_(std::move(quantizationMatrixPtr)) {} void quantize(const CompleteIndexVector& outputIndices) override {} @@ -73,9 +55,9 @@ namespace boosting { public: - NoDenseNonDecomposableQuantization(const DenseNonDecomposableStatisticView& view) - : quantizationMatrixPtr_( - std::make_unique>(view)) {} + NoDenseNonDecomposableQuantization( + std::unique_ptr> quantizationMatrixPtr) + : quantizationMatrixPtr_(std::move(quantizationMatrixPtr)) {} void quantize(const CompleteIndexVector& outputIndices) override {} @@ -89,21 +71,60 @@ namespace boosting { } }; + template + class NoQuantizationMatrix final : public IQuantizationMatrix { + private: + + const View& view_; + + public: + + NoQuantizationMatrix(const View& view) : view_(view) {} + + void quantize(const CompleteIndexVector& outputIndices) override {} + + void quantize(const PartialIndexVector& outputIndices) override {} + + const typename IQuantizationMatrix::view_type& getView() const override { + return view_; + } + + std::unique_ptr create( + const CContiguousView>& statisticMatrix) const override { + return std::make_unique( + std::make_unique>>>(statisticMatrix)); + } + + std::unique_ptr create(const SparseSetView>& statisticMatrix) const override { + return std::make_unique( + std::make_unique>>>(statisticMatrix)); + } + + std::unique_ptr create( + const DenseNonDecomposableStatisticView& statisticMatrix) const override { + return std::make_unique( + std::make_unique>(statisticMatrix)); + } + }; + class NoQuantizationFactory final : public IQuantizationFactory { public: std::unique_ptr create( const CContiguousView>& statisticMatrix) const override { - return std::make_unique(statisticMatrix); + return std::make_unique( + std::make_unique>>>(statisticMatrix)); } std::unique_ptr create(const SparseSetView>& statisticMatrix) const override { - return std::make_unique(statisticMatrix); + return std::make_unique( + std::make_unique>>>(statisticMatrix)); } std::unique_ptr create( const DenseNonDecomposableStatisticView& statisticMatrix) const override { - return std::make_unique(statisticMatrix); + return std::make_unique( + std::make_unique>(statisticMatrix)); } }; diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp index 9added3749..eb2ffa1a2e 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp @@ -5,18 +5,16 @@ namespace boosting { template - class StochasticQuantizationMatrix final : public IQuantizationMatrix>> { + class StochasticQuantization final : public IQuantization { private: - const View& view_; - - // TODO Use correct type - MatrixDecorator>> matrix_; + std::unique_ptr>>> quantizationMatrixPtr_; public: - StochasticQuantizationMatrix(const View& view) - : view_(view), matrix_(AllocatedCContiguousView>(view.numRows, view.numCols)) {} + StochasticQuantization( + std::unique_ptr>>> quantizationMatrixPtr) + : quantizationMatrixPtr_(std::move(quantizationMatrixPtr)) {} void quantize(const CompleteIndexVector& outputIndices) override { // TODO Implement @@ -26,21 +24,27 @@ namespace boosting { // TODO Implement } - const typename IQuantizationMatrix>>::view_type& getView() const override { - return matrix_.getView(); + void visitQuantizationMatrix( + IQuantization::DenseDecomposableMatrixVisitor denseDecomposableMatrixVisitor, + IQuantization::SparseDecomposableMatrixVisitor sparseDecomposableMatrixVisitor, + IQuantization::DenseNonDecomposableMatrixVisitor denseNonDecomposableMatrixVisitor) override { + denseDecomposableMatrixVisitor(quantizationMatrixPtr_); } }; template - class StochasticQuantization final : public IQuantization { + class StochasticQuantizationMatrix final : public IQuantizationMatrix>> { private: - std::unique_ptr>>> quantizationMatrixPtr_; + const View& view_; + + // TODO Use correct type + MatrixDecorator>> matrix_; public: - StochasticQuantization(const View& view) - : quantizationMatrixPtr_(std::make_unique>(view)) {} + StochasticQuantizationMatrix(const View& view) + : view_(view), matrix_(AllocatedCContiguousView>(view.numRows, view.numCols)) {} void quantize(const CompleteIndexVector& outputIndices) override { // TODO Implement @@ -50,11 +54,25 @@ namespace boosting { // TODO Implement } - void visitQuantizationMatrix( - IQuantization::DenseDecomposableMatrixVisitor denseDecomposableMatrixVisitor, - IQuantization::SparseDecomposableMatrixVisitor sparseDecomposableMatrixVisitor, - IQuantization::DenseNonDecomposableMatrixVisitor denseNonDecomposableMatrixVisitor) override { - denseDecomposableMatrixVisitor(quantizationMatrixPtr_); + const typename IQuantizationMatrix>>::view_type& getView() const override { + return matrix_.getView(); + } + + std::unique_ptr create( + const CContiguousView>& statisticMatrix) const override { + return std::make_unique>>>( + std::make_unique>>>(statisticMatrix)); + } + + std::unique_ptr create(const SparseSetView>& statisticMatrix) const override { + return std::make_unique>>>( + std::make_unique>>>(statisticMatrix)); + } + + std::unique_ptr create( + const DenseNonDecomposableStatisticView& statisticMatrix) const override { + return std::make_unique>( + std::make_unique>(statisticMatrix)); } }; @@ -72,16 +90,19 @@ namespace boosting { std::unique_ptr create( const CContiguousView>& statisticMatrix) const override { - return std::make_unique>>>(statisticMatrix); + return std::make_unique>>>( + std::make_unique>>>(statisticMatrix)); } std::unique_ptr create(const SparseSetView>& statisticMatrix) const override { - return std::make_unique>>>(statisticMatrix); + return std::make_unique>>>( + std::make_unique>>>(statisticMatrix)); } std::unique_ptr create( const DenseNonDecomposableStatisticView& statisticMatrix) const override { - return std::make_unique>(statisticMatrix); + return std::make_unique>( + std::make_unique>(statisticMatrix)); } }; diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp index a8a1009942..4e6b6dda7a 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp @@ -141,11 +141,28 @@ namespace boosting { } } - return std::make_unique< - DenseDecomposableStatistics>( - std::move(this->quantizationMatrixPtr_), std::move(this->lossPtr_), - std::move(this->evaluationMeasurePtr_), ruleEvaluationFactory, this->outputMatrix_, - std::move(decomposableStatisticMatrixPtr), std::move(this->scoreMatrixPtr_)); + std::unique_ptr quantizationPtr = + this->quantizationMatrixPtr_->create(*decomposableStatisticMatrixRawPtr); + std::unique_ptr> statisticsPtr; + auto denseDecomposableMatrixVisitor = + [&](std::unique_ptr>>>& quantizationMatrixPtr) { + statisticsPtr = std::make_unique>>, EvaluationMeasure>>( + std::move(quantizationMatrixPtr), std::move(this->lossPtr_), + std::move(this->evaluationMeasurePtr_), ruleEvaluationFactory, this->outputMatrix_, + std::move(decomposableStatisticMatrixPtr), std::move(this->scoreMatrixPtr_)); + }; + auto sparseDecomposableMatrixVisitor = + [&](std::unique_ptr>>>& quantizationMatrixPtr) { + throw std::runtime_error("not implemented"); + }; + auto denseNonDecomposableMatrixVisitor = + [&](std::unique_ptr>& quantizationMatrixPtr) { + throw std::runtime_error("not implemented"); + }; + quantizationPtr->visitQuantizationMatrix( + denseDecomposableMatrixVisitor, sparseDecomposableMatrixVisitor, denseNonDecomposableMatrixVisitor); + return statisticsPtr; } }; From 594bc1a4f633465e2a32c64a971cf734e09aca48 Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Wed, 14 Aug 2024 23:05:23 +0200 Subject: [PATCH 20/37] Pass quantization matrix when creating objects of type IStatisticsSubset or IWeightedStatistics. --- .../boosting/statistics/statistics_common.hpp | 60 +++++++++---------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp index f69aff0995..323f34995b 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp @@ -652,9 +652,9 @@ namespace boosting { std::unique_ptr createSubset(const CompleteIndexVector& outputIndices, const EqualWeightVector& weights) const override final { return std::make_unique< - StatisticsSubset>( - statisticMatrixPtr_->getView(), *ruleEvaluationFactory_, weights, outputIndices); + quantizationMatrixPtr_->getView(), *ruleEvaluationFactory_, weights, outputIndices); } /** @@ -662,9 +662,9 @@ namespace boosting { */ std::unique_ptr createSubset(const PartialIndexVector& outputIndices, const EqualWeightVector& weights) const override final { - return std::make_unique>( - statisticMatrixPtr_->getView(), *ruleEvaluationFactory_, weights, outputIndices); + quantizationMatrixPtr_->getView(), *ruleEvaluationFactory_, weights, outputIndices); } /** @@ -672,9 +672,9 @@ namespace boosting { */ std::unique_ptr createSubset(const CompleteIndexVector& outputIndices, const BitWeightVector& weights) const override final { - return std::make_unique>( - statisticMatrixPtr_->getView(), *ruleEvaluationFactory_, weights, outputIndices); + quantizationMatrixPtr_->getView(), *ruleEvaluationFactory_, weights, outputIndices); } /** @@ -682,9 +682,9 @@ namespace boosting { */ std::unique_ptr createSubset(const PartialIndexVector& outputIndices, const BitWeightVector& weights) const override final { - return std::make_unique>( - statisticMatrixPtr_->getView(), *ruleEvaluationFactory_, weights, outputIndices); + quantizationMatrixPtr_->getView(), *ruleEvaluationFactory_, weights, outputIndices); } /** @@ -693,9 +693,9 @@ namespace boosting { std::unique_ptr createSubset( const CompleteIndexVector& outputIndices, const DenseWeightVector& weights) const override final { return std::make_unique< - StatisticsSubset, CompleteIndexVector>>( - statisticMatrixPtr_->getView(), *ruleEvaluationFactory_, weights, outputIndices); + quantizationMatrixPtr_->getView(), *ruleEvaluationFactory_, weights, outputIndices); } /** @@ -704,9 +704,9 @@ namespace boosting { std::unique_ptr createSubset( const PartialIndexVector& outputIndices, const DenseWeightVector& weights) const override final { return std::make_unique< - StatisticsSubset, PartialIndexVector>>( - statisticMatrixPtr_->getView(), *ruleEvaluationFactory_, weights, outputIndices); + quantizationMatrixPtr_->getView(), *ruleEvaluationFactory_, weights, outputIndices); } /** @@ -716,9 +716,9 @@ namespace boosting { const CompleteIndexVector& outputIndices, const OutOfSampleWeightVector& weights) const override final { return std::make_unique< - StatisticsSubset, CompleteIndexVector>>( - statisticMatrixPtr_->getView(), *ruleEvaluationFactory_, weights, outputIndices); + quantizationMatrixPtr_->getView(), *ruleEvaluationFactory_, weights, outputIndices); } /** @@ -728,9 +728,9 @@ namespace boosting { const PartialIndexVector& outputIndices, const OutOfSampleWeightVector& weights) const override final { return std::make_unique< - StatisticsSubset, PartialIndexVector>>( - statisticMatrixPtr_->getView(), *ruleEvaluationFactory_, weights, outputIndices); + quantizationMatrixPtr_->getView(), *ruleEvaluationFactory_, weights, outputIndices); } /** @@ -740,9 +740,9 @@ namespace boosting { const CompleteIndexVector& outputIndices, const OutOfSampleWeightVector& weights) const override final { return std::make_unique< - StatisticsSubset, CompleteIndexVector>>( - statisticMatrixPtr_->getView(), *ruleEvaluationFactory_, weights, outputIndices); + quantizationMatrixPtr_->getView(), *ruleEvaluationFactory_, weights, outputIndices); } /** @@ -752,9 +752,9 @@ namespace boosting { const PartialIndexVector& outputIndices, const OutOfSampleWeightVector& weights) const override final { return std::make_unique< - StatisticsSubset, PartialIndexVector>>( - statisticMatrixPtr_->getView(), *ruleEvaluationFactory_, weights, outputIndices); + quantizationMatrixPtr_->getView(), *ruleEvaluationFactory_, weights, outputIndices); } /** @@ -764,9 +764,9 @@ namespace boosting { const CompleteIndexVector& outputIndices, const OutOfSampleWeightVector>& weights) const override final { return std::make_unique< - StatisticsSubset>, CompleteIndexVector>>( - statisticMatrixPtr_->getView(), *ruleEvaluationFactory_, weights, outputIndices); + quantizationMatrixPtr_->getView(), *ruleEvaluationFactory_, weights, outputIndices); } /** @@ -776,9 +776,9 @@ namespace boosting { const PartialIndexVector& outputIndices, const OutOfSampleWeightVector>& weights) const override final { return std::make_unique< - StatisticsSubset>, PartialIndexVector>>( - statisticMatrixPtr_->getView(), *ruleEvaluationFactory_, weights, outputIndices); + quantizationMatrixPtr_->getView(), *ruleEvaluationFactory_, weights, outputIndices); } /** @@ -786,9 +786,9 @@ namespace boosting { */ std::unique_ptr createWeightedStatistics( const EqualWeightVector& weights) const override final { - return std::make_unique>( - statisticMatrixPtr_->getView(), *ruleEvaluationFactory_, weights); + quantizationMatrixPtr_->getView(), *ruleEvaluationFactory_, weights); } /** @@ -796,9 +796,9 @@ namespace boosting { */ std::unique_ptr createWeightedStatistics( const BitWeightVector& weights) const override final { - return std::make_unique>( - statisticMatrixPtr_->getView(), *ruleEvaluationFactory_, weights); + quantizationMatrixPtr_->getView(), *ruleEvaluationFactory_, weights); } /** @@ -806,9 +806,9 @@ namespace boosting { */ std::unique_ptr createWeightedStatistics( const DenseWeightVector& weights) const override final { - return std::make_unique>>( - statisticMatrixPtr_->getView(), *ruleEvaluationFactory_, weights); + quantizationMatrixPtr_->getView(), *ruleEvaluationFactory_, weights); } }; From b26a018a95fd1a7268cffbe4221e2f818aa51cde Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Thu, 15 Aug 2024 00:45:17 +0200 Subject: [PATCH 21/37] Use std::optional for the arguments of visitor functions. --- .../mlrl/boosting/statistics/quantization.hpp | 22 +++--- .../mlrl/boosting/statistics/statistics.hpp | 9 +-- .../boosting/statistics/quantization_no.cpp | 33 +++++---- .../statistics/quantization_stochastic.cpp | 11 +-- .../statistics_decomposable_dense.hpp | 9 ++- ...statistics_provider_decomposable_dense.cpp | 11 +-- ...tatistics_provider_decomposable_sparse.cpp | 20 ++---- ...istics_provider_non_decomposable_dense.cpp | 31 +++------ .../common/include/mlrl/common/model/body.hpp | 9 ++- .../mlrl/common/model/body_conjunctive.hpp | 3 +- .../include/mlrl/common/model/body_empty.hpp | 3 +- .../common/include/mlrl/common/model/head.hpp | 8 ++- .../mlrl/common/model/head_complete.hpp | 3 +- .../mlrl/common/model/head_partial.hpp | 3 +- .../include/mlrl/common/model/rule_list.hpp | 68 +++++++++++-------- .../mlrl/common/model/body_conjunctive.cpp | 7 +- .../src/mlrl/common/model/body_empty.cpp | 7 +- .../src/mlrl/common/model/head_complete.cpp | 7 +- .../src/mlrl/common/model/head_partial.cpp | 7 +- .../src/mlrl/common/model/rule_list.cpp | 22 +++--- 20 files changed, 157 insertions(+), 136 deletions(-) diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization.hpp index f4fb743a00..d3ab1fdd2b 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization.hpp @@ -12,6 +12,7 @@ #include #include +#include namespace boosting { @@ -53,17 +54,20 @@ namespace boosting { * Invokes one of the given visitor functions, depending on which one is able to handle the type of the * matrix that is used for storing quantized scores. * - * @param denseDecomposableMatrixVisitor The visitor function for handling quantization matrices that are - * backed by a view of the type `CContiguousView>` - * @param sparseDecomposableMatrixVisitor The visitor function for handling quantization matrices that are - * backed by a view of the type `SparseSetView>` - * @param denseNonDecomposableMatrixVisitor The visitor function for handling quantization matrices that are - * backed by a view of the type `DenseNonDecomposableStatisticView` + * @param denseDecomposableMatrixVisitor An optional visitor function for handling quantization matrices + * that are backed by a view of the type + * `CContiguousView>` + * @param sparseDecomposableMatrixVisitor An optional visitor function for handling quantization matrices + * that are backed by a view of the type + * `SparseSetView>` + * @param denseNonDecomposableMatrixVisitor An optional visitor function for handling quantization matrices + * that are backed by a view of the type + * `DenseNonDecomposableStatisticView` */ virtual void visitQuantizationMatrix( - DenseDecomposableMatrixVisitor denseDecomposableMatrixVisitor, - SparseDecomposableMatrixVisitor sparseDecomposableMatrixVisitor, - DenseNonDecomposableMatrixVisitor denseNonDecomposableMatrixVisitor) = 0; + std::optional denseDecomposableMatrixVisitor, + std::optional sparseDecomposableMatrixVisitor, + std::optional denseNonDecomposableMatrixVisitor) = 0; /** * Quantifies all statistics that corresonds to the available outputs. diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/statistics/statistics.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/statistics/statistics.hpp index ce07fcf841..464321435e 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/statistics/statistics.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/statistics/statistics.hpp @@ -8,6 +8,7 @@ #include "mlrl/common/statistics/statistics.hpp" #include +#include namespace boosting { @@ -34,11 +35,11 @@ namespace boosting { * Invokes one of the given visitor functions, depending on which one is able to handle the type of matrix * that is used to store the currently predicted scores. * - * @param denseVisitor The visitor function for handling objects of the type `CContiguousView` - * @param sparseVisitor The visitor function for handling objects of the type `SparseSetView` + * @param denseVisitor An optional visitor function for handling objects of the type `CContiguousView` + * @param sparseVisitor An optional visitor function for handling objects of the type `SparseSetView` */ - virtual void visitScoreMatrix(DenseScoreMatrixVisitor denseVisitor, - SparseScoreMatrixVisitor sparseVisitor) const = 0; + virtual void visitScoreMatrix(std::optional denseVisitor, + std::optional sparseVisitor) const = 0; }; } diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_no.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_no.cpp index 71df467221..caa947701c 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_no.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_no.cpp @@ -18,10 +18,13 @@ namespace boosting { void quantize(const PartialIndexVector& outputIndices) override {} void visitQuantizationMatrix( - IQuantization::DenseDecomposableMatrixVisitor denseDecomposableMatrixVisitor, - IQuantization::SparseDecomposableMatrixVisitor sparseDecomposableMatrixVisitor, - IQuantization::DenseNonDecomposableMatrixVisitor denseNonDecomposableMatrixVisitor) override { - denseDecomposableMatrixVisitor(quantizationMatrixPtr_); + std::optional denseDecomposableMatrixVisitor, + std::optional sparseDecomposableMatrixVisitor, + std::optional denseNonDecomposableMatrixVisitor) + override { + if (denseDecomposableMatrixVisitor) { + (*denseDecomposableMatrixVisitor)(quantizationMatrixPtr_); + } } }; @@ -41,10 +44,13 @@ namespace boosting { void quantize(const PartialIndexVector& outputIndices) override {} void visitQuantizationMatrix( - IQuantization::DenseDecomposableMatrixVisitor denseDecomposableMatrixVisitor, - IQuantization::SparseDecomposableMatrixVisitor sparseDecomposableMatrixVisitor, - IQuantization::DenseNonDecomposableMatrixVisitor denseNonDecomposableMatrixVisitor) override { - sparseDecomposableMatrixVisitor(quantizationMatrixPtr_); + std::optional denseDecomposableMatrixVisitor, + std::optional sparseDecomposableMatrixVisitor, + std::optional denseNonDecomposableMatrixVisitor) + override { + if (sparseDecomposableMatrixVisitor) { + (*sparseDecomposableMatrixVisitor)(quantizationMatrixPtr_); + } } }; @@ -64,10 +70,13 @@ namespace boosting { void quantize(const PartialIndexVector& outputIndices) override {} void visitQuantizationMatrix( - IQuantization::DenseDecomposableMatrixVisitor denseDecomposableMatrixVisitor, - IQuantization::SparseDecomposableMatrixVisitor sparseDecomposableMatrixVisitor, - IQuantization::DenseNonDecomposableMatrixVisitor denseNonDecomposableMatrixVisitor) override { - denseNonDecomposableMatrixVisitor(quantizationMatrixPtr_); + std::optional denseDecomposableMatrixVisitor, + std::optional sparseDecomposableMatrixVisitor, + std::optional denseNonDecomposableMatrixVisitor) + override { + if (denseNonDecomposableMatrixVisitor) { + (*denseNonDecomposableMatrixVisitor)(quantizationMatrixPtr_); + } } }; diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp index eb2ffa1a2e..7ab6399c2c 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp @@ -25,10 +25,13 @@ namespace boosting { } void visitQuantizationMatrix( - IQuantization::DenseDecomposableMatrixVisitor denseDecomposableMatrixVisitor, - IQuantization::SparseDecomposableMatrixVisitor sparseDecomposableMatrixVisitor, - IQuantization::DenseNonDecomposableMatrixVisitor denseNonDecomposableMatrixVisitor) override { - denseDecomposableMatrixVisitor(quantizationMatrixPtr_); + std::optional denseDecomposableMatrixVisitor, + std::optional sparseDecomposableMatrixVisitor, + std::optional denseNonDecomposableMatrixVisitor) + override { + if (denseDecomposableMatrixVisitor) { + (*denseDecomposableMatrixVisitor)(quantizationMatrixPtr_); + } } }; diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_decomposable_dense.hpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_decomposable_dense.hpp index e772407733..b164d6eee1 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_decomposable_dense.hpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_decomposable_dense.hpp @@ -96,9 +96,12 @@ namespace boosting { /** * @see `IBoostingStatistics::visitScoreMatrix` */ - void visitScoreMatrix(IBoostingStatistics::DenseScoreMatrixVisitor denseVisitor, - IBoostingStatistics::SparseScoreMatrixVisitor sparseVisitor) const override { - denseVisitor(this->scoreMatrixPtr_->getView()); + void visitScoreMatrix( + std::optional denseVisitor, + std::optional sparseVisitor) const override { + if (denseVisitor) { + (*denseVisitor)(this->scoreMatrixPtr_->getView()); + } } }; diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp index 09e594db65..047d455f1a 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp @@ -41,16 +41,7 @@ namespace boosting { std::move(quantizationMatrixPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)); }; - auto sparseDecomposableMatrixVisitor = - [&](std::unique_ptr>>>& quantizationMatrixPtr) { - throw std::runtime_error("not implemented"); - }; - auto denseNonDecomposableMatrixVisitor = - [&](std::unique_ptr>& quantizationMatrixPtr) { - throw std::runtime_error("not implemented"); - }; - quantizationPtr->visitQuantizationMatrix(denseDecomposableMatrixVisitor, sparseDecomposableMatrixVisitor, - denseNonDecomposableMatrixVisitor); + quantizationPtr->visitQuantizationMatrix(denseDecomposableMatrixVisitor, {}, {}); return statisticsPtr; } diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_sparse.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_sparse.cpp index e04579fdb1..273e08c7a3 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_sparse.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_sparse.cpp @@ -75,9 +75,12 @@ namespace boosting { /** * @see `IBoostingStatistics::visitScoreMatrix` */ - void visitScoreMatrix(IBoostingStatistics::DenseScoreMatrixVisitor denseVisitor, - IBoostingStatistics::SparseScoreMatrixVisitor sparseVisitor) const override { - sparseVisitor(this->scoreMatrixPtr_->getView()); + void visitScoreMatrix( + std::optional denseVisitor, + std::optional sparseVisitor) const override { + if (sparseVisitor) { + (*sparseVisitor)(this->scoreMatrixPtr_->getView()); + } } }; @@ -114,10 +117,6 @@ namespace boosting { } std::unique_ptr> statisticsPtr; - auto denseDecomposableMatrixVisitor = - [&](std::unique_ptr>>>& quantizationMatrixPtr) { - throw std::runtime_error("not implemented"); - }; auto sparseDecomposableMatrixVisitor = [&](std::unique_ptr>>>& quantizationMatrixPtr) { statisticsPtr = std::make_unique< @@ -125,12 +124,7 @@ namespace boosting { std::move(quantizationMatrixPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)); }; - auto denseNonDecomposableMatrixVisitor = - [&](std::unique_ptr>& quantizationMatrixPtr) { - throw std::runtime_error("not implemented"); - }; - quantizationPtr->visitQuantizationMatrix(denseDecomposableMatrixVisitor, sparseDecomposableMatrixVisitor, - denseNonDecomposableMatrixVisitor); + quantizationPtr->visitQuantizationMatrix({}, sparseDecomposableMatrixVisitor, {}); return statisticsPtr; } diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp index 4e6b6dda7a..1ad2e3eecf 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp @@ -101,9 +101,12 @@ namespace boosting { /** * @see `IBoostingStatistics::visitScoreMatrix` */ - void visitScoreMatrix(IBoostingStatistics::DenseScoreMatrixVisitor denseVisitor, - IBoostingStatistics::SparseScoreMatrixVisitor sparseVisitor) const override { - denseVisitor(this->scoreMatrixPtr_->getView()); + void visitScoreMatrix( + std::optional denseVisitor, + std::optional sparseVisitor) const override { + if (denseVisitor) { + (*denseVisitor)(this->scoreMatrixPtr_->getView()); + } } /** @@ -152,16 +155,7 @@ namespace boosting { std::move(this->evaluationMeasurePtr_), ruleEvaluationFactory, this->outputMatrix_, std::move(decomposableStatisticMatrixPtr), std::move(this->scoreMatrixPtr_)); }; - auto sparseDecomposableMatrixVisitor = - [&](std::unique_ptr>>>& quantizationMatrixPtr) { - throw std::runtime_error("not implemented"); - }; - auto denseNonDecomposableMatrixVisitor = - [&](std::unique_ptr>& quantizationMatrixPtr) { - throw std::runtime_error("not implemented"); - }; - quantizationPtr->visitQuantizationMatrix( - denseDecomposableMatrixVisitor, sparseDecomposableMatrixVisitor, denseNonDecomposableMatrixVisitor); + quantizationPtr->visitQuantizationMatrix(denseDecomposableMatrixVisitor, {}, {}); return statisticsPtr; } }; @@ -197,14 +191,6 @@ namespace boosting { std::unique_ptr< INonDecomposableStatistics> statisticsPtr; - auto denseDecomposableMatrixVisitor = - [&](std::unique_ptr>>>& quantizationMatrixPtr) { - throw std::runtime_error("not implemented"); - }; - auto sparseDecomposableMatrixVisitor = - [&](std::unique_ptr>>>& quantizationMatrixPtr) { - throw std::runtime_error("not implemented"); - }; auto denseNonDecomposableMatrixVisitor = [&](std::unique_ptr>& quantizationMatrixPtr) { statisticsPtr = std::make_uniquevisitQuantizationMatrix(denseDecomposableMatrixVisitor, sparseDecomposableMatrixVisitor, - denseNonDecomposableMatrixVisitor); + quantizationPtr->visitQuantizationMatrix({}, {}, denseNonDecomposableMatrixVisitor); return statisticsPtr; } diff --git a/cpp/subprojects/common/include/mlrl/common/model/body.hpp b/cpp/subprojects/common/include/mlrl/common/model/body.hpp index e9d4c426b7..f59adba22e 100644 --- a/cpp/subprojects/common/include/mlrl/common/model/body.hpp +++ b/cpp/subprojects/common/include/mlrl/common/model/body.hpp @@ -6,6 +6,7 @@ #include "mlrl/common/data/view.hpp" #include +#include // Forward declarations class EmptyBody; @@ -74,8 +75,10 @@ class MLRLCOMMON_API IBody : public IConditional { * Invokes one of the given visitor functions, depending on which one is able to handle this particular type of * body. * - * @param emptyBodyVisitor The visitor function for handling objects of the type `EmptyBody` - * @param conjunctiveBodyVisitor The visitor function for handling objects of the type `ConjunctiveBody` + * @param emptyBodyVisitor An optional visitor function for handling objects of the type `EmptyBody` + * @param conjunctiveBodyVisitor An optional visitor function for handling objects of the type + * `ConjunctiveBody` */ - virtual void visit(EmptyBodyVisitor emptyBodyVisitor, ConjunctiveBodyVisitor conjunctiveBodyVisitor) const = 0; + virtual void visit(std::optional emptyBodyVisitor, + std::optional conjunctiveBodyVisitor) const = 0; }; diff --git a/cpp/subprojects/common/include/mlrl/common/model/body_conjunctive.hpp b/cpp/subprojects/common/include/mlrl/common/model/body_conjunctive.hpp index 6cf22f6847..df78dca5e3 100644 --- a/cpp/subprojects/common/include/mlrl/common/model/body_conjunctive.hpp +++ b/cpp/subprojects/common/include/mlrl/common/model/body_conjunctive.hpp @@ -668,5 +668,6 @@ class MLRLCOMMON_API ConjunctiveBody final : public IBody { float32 sparseValue, View::iterator tmpArray1, View::iterator tmpArray2, uint32 n) const override; - void visit(EmptyBodyVisitor emptyBodyVisitor, ConjunctiveBodyVisitor conjunctiveBodyVisitor) const override; + void visit(std::optional emptyBodyVisitor, + std::optional conjunctiveBodyVisitor) const override; }; diff --git a/cpp/subprojects/common/include/mlrl/common/model/body_empty.hpp b/cpp/subprojects/common/include/mlrl/common/model/body_empty.hpp index f9ada75b75..686c50f04b 100644 --- a/cpp/subprojects/common/include/mlrl/common/model/body_empty.hpp +++ b/cpp/subprojects/common/include/mlrl/common/model/body_empty.hpp @@ -18,5 +18,6 @@ class MLRLCOMMON_API EmptyBody final : public IBody { float32 sparseValue, View::iterator tmpArray1, View::iterator tmpArray2, uint32 n) const override; - void visit(EmptyBodyVisitor emptyBodyVisitor, ConjunctiveBodyVisitor conjunctiveBodyVisitor) const override; + void visit(std::optional emptyBodyVisitor, + std::optional conjunctiveBodyVisitor) const override; }; diff --git a/cpp/subprojects/common/include/mlrl/common/model/head.hpp b/cpp/subprojects/common/include/mlrl/common/model/head.hpp index 31ca14fa64..3a06cd7cfe 100644 --- a/cpp/subprojects/common/include/mlrl/common/model/head.hpp +++ b/cpp/subprojects/common/include/mlrl/common/model/head.hpp @@ -4,6 +4,7 @@ #pragma once #include +#include // Forward declarations class CompleteHead; @@ -31,8 +32,9 @@ class MLRLCOMMON_API IHead { * Invokes one of the given visitor functions, depending on which one is able to handle this particular type of * head. * - * @param completeHeadVisitor The visitor function for handling objects of the type `CompleteHead` - * @param partialHeadVisitor The visitor function for handling objects of the type `PartialHead` + * @param completeHeadVisitor An optional visitor function for handling objects of the type `CompleteHead` + * @param partialHeadVisitor An optional visitor function for handling objects of the type `PartialHead` */ - virtual void visit(CompleteHeadVisitor completeHeadVisitor, PartialHeadVisitor partialHeadVisitor) const = 0; + virtual void visit(std::optional completeHeadVisitor, + std::optional partialHeadVisitor) const = 0; }; diff --git a/cpp/subprojects/common/include/mlrl/common/model/head_complete.hpp b/cpp/subprojects/common/include/mlrl/common/model/head_complete.hpp index be5e69f18d..d06799209d 100644 --- a/cpp/subprojects/common/include/mlrl/common/model/head_complete.hpp +++ b/cpp/subprojects/common/include/mlrl/common/model/head_complete.hpp @@ -56,5 +56,6 @@ class MLRLCOMMON_API CompleteHead final : public VectorDecorator completeHeadVisitor, + std::optional partialHeadVisitor) const override; }; diff --git a/cpp/subprojects/common/include/mlrl/common/model/head_partial.hpp b/cpp/subprojects/common/include/mlrl/common/model/head_partial.hpp index 81f635ca83..0fe106cab9 100644 --- a/cpp/subprojects/common/include/mlrl/common/model/head_partial.hpp +++ b/cpp/subprojects/common/include/mlrl/common/model/head_partial.hpp @@ -19,5 +19,6 @@ class MLRLCOMMON_API PartialHead final */ PartialHead(uint32 numElements); - void visit(CompleteHeadVisitor completeHeadVisitor, PartialHeadVisitor partialHeadVisitor) const override; + void visit(std::optional completeHeadVisitor, + std::optional partialHeadVisitor) const override; }; diff --git a/cpp/subprojects/common/include/mlrl/common/model/rule_list.hpp b/cpp/subprojects/common/include/mlrl/common/model/rule_list.hpp index 74f9cecd79..209a1a0986 100644 --- a/cpp/subprojects/common/include/mlrl/common/model/rule_list.hpp +++ b/cpp/subprojects/common/include/mlrl/common/model/rule_list.hpp @@ -52,29 +52,31 @@ class MLRLCOMMON_API IRuleList : public IRuleModel { * Invokes some of the given visitor functions, depending on which ones are able to handle the bodies and heads * of all rules that are contained in this model, including the default rule, if available. * - * @param emptyBodyVisitor The visitor function for handling objects of the type `EmptyBody` - * @param conjunctiveBodyVisitor The visitor function for handling objects of the type `ConjunctiveBody` - * @param completeHeadVisitor The visitor function for handling objects of the type `CompleteHead` - * @param partialHeadVisitor The visitor function for handling objects of the type `PartialHead` + * @param emptyBodyVisitor An optional visitor function for handling objects of the type `EmptyBody` + * @param conjunctiveBodyVisitor An optional visitor function for handling objects of the type + * `ConjunctiveBody` + * @param completeHeadVisitor An optional visitor function for handling objects of the type `CompleteHead` + * @param partialHeadVisitor An optional visitor function for handling objects of the type `PartialHead` */ - virtual void visit(IBody::EmptyBodyVisitor emptyBodyVisitor, - IBody::ConjunctiveBodyVisitor conjunctiveBodyVisitor, - IHead::CompleteHeadVisitor completeHeadVisitor, - IHead::PartialHeadVisitor partialHeadVisitor) const = 0; + virtual void visit(std::optional emptyBodyVisitor, + std::optional conjunctiveBodyVisitor, + std::optional completeHeadVisitor, + std::optional partialHeadVisitor) const = 0; /** * Invokes some of the given visitor functions, depending on which ones are able to handle the bodies and heads * of all used rules that are contained in this model, including the default rule, if available. * - * @param emptyBodyVisitor The visitor function for handling objects of the type `EmptyBody` - * @param conjunctiveBodyVisitor The visitor function for handling objects of the type `ConjunctiveBody` - * @param completeHeadVisitor The visitor function for handling objects of the type `CompleteHead` - * @param partialHeadVisitor The visitor function for handling objects of the type `PartialHead` + * @param emptyBodyVisitor An optional visitor function for handling objects of the type `EmptyBody` + * @param conjunctiveBodyVisitor An optional visitor function for handling objects of the type + * `ConjunctiveBody` + * @param completeHeadVisitor An optional visitor function for handling objects of the type `CompleteHead` + * @param partialHeadVisitor An optional visitor function for handling objects of the type `PartialHead` */ - virtual void visitUsed(IBody::EmptyBodyVisitor emptyBodyVisitor, - IBody::ConjunctiveBodyVisitor conjunctiveBodyVisitor, - IHead::CompleteHeadVisitor completeHeadVisitor, - IHead::PartialHeadVisitor partialHeadVisitor) const = 0; + virtual void visitUsed(std::optional emptyBodyVisitor, + std::optional conjunctiveBodyVisitor, + std::optional completeHeadVisitor, + std::optional partialHeadVisitor) const = 0; }; /** @@ -120,15 +122,19 @@ class RuleList final : public IRuleList { * Invokes some of the given visitor functions, depending on which ones are able to handle the rule's * particular type of body and head. * - * @param emptyBodyVisitor The visitor function for handling objects of type `EmptyBody` - * @param conjunctiveBodyVisitor The visitor function for handling objects of type `ConjunctiveBody` - * @param completeHeadVisitor The visitor function for handling objects of type `CompleteHead` - * @param partialHeadVisitor The visitor function for handling objects of type `PartialHead` + * @param emptyBodyVisitor An optional visitor function for handling objects of type + * `EmptyBody` + * @param conjunctiveBodyVisitor An optional visitor function for handling objects of type + * `ConjunctiveBody` + * @param completeHeadVisitor An optional visitor function for handling objects of type + * `CompleteHead` + * @param partialHeadVisitor An optional visitor function for handling objects of type + * `PartialHead` */ - void visit(IBody::EmptyBodyVisitor emptyBodyVisitor, - IBody::ConjunctiveBodyVisitor conjunctiveBodyVisitor, - IHead::CompleteHeadVisitor completeHeadVisitor, - IHead::PartialHeadVisitor partialHeadVisitor) const; + void visit(std::optional emptyBodyVisitor, + std::optional conjunctiveBodyVisitor, + std::optional completeHeadVisitor, + std::optional partialHeadVisitor) const; }; private: @@ -317,13 +323,15 @@ class RuleList final : public IRuleList { bool isDefaultRuleTakingPrecedence() const override; - void visit(IBody::EmptyBodyVisitor emptyBodyVisitor, IBody::ConjunctiveBodyVisitor conjunctiveBodyVisitor, - IHead::CompleteHeadVisitor completeHeadVisitor, - IHead::PartialHeadVisitor partialHeadVisitor) const override; + void visit(std::optional emptyBodyVisitor, + std::optional conjunctiveBodyVisitor, + std::optional completeHeadVisitor, + std::optional partialHeadVisitor) const override; - void visitUsed(IBody::EmptyBodyVisitor emptyBodyVisitor, IBody::ConjunctiveBodyVisitor conjunctiveBodyVisitor, - IHead::CompleteHeadVisitor completeHeadVisitor, - IHead::PartialHeadVisitor partialHeadVisitor) const override; + void visitUsed(std::optional emptyBodyVisitor, + std::optional conjunctiveBodyVisitor, + std::optional completeHeadVisitor, + std::optional partialHeadVisitor) const override; std::unique_ptr createBinaryPredictor( const IBinaryPredictorFactory& factory, const CContiguousView& featureMatrix, diff --git a/cpp/subprojects/common/src/mlrl/common/model/body_conjunctive.cpp b/cpp/subprojects/common/src/mlrl/common/model/body_conjunctive.cpp index 441136a4e7..e055c8fefb 100644 --- a/cpp/subprojects/common/src/mlrl/common/model/body_conjunctive.cpp +++ b/cpp/subprojects/common/src/mlrl/common/model/body_conjunctive.cpp @@ -304,6 +304,9 @@ bool ConjunctiveBody::covers(View::const_iterator indicesBegin, View emptyBodyVisitor, + std::optional conjunctiveBodyVisitor) const { + if (conjunctiveBodyVisitor) { + (*conjunctiveBodyVisitor)(*this); + } } diff --git a/cpp/subprojects/common/src/mlrl/common/model/body_empty.cpp b/cpp/subprojects/common/src/mlrl/common/model/body_empty.cpp index b6a4ab842f..bdfe820e2a 100644 --- a/cpp/subprojects/common/src/mlrl/common/model/body_empty.cpp +++ b/cpp/subprojects/common/src/mlrl/common/model/body_empty.cpp @@ -10,6 +10,9 @@ bool EmptyBody::covers(View::const_iterator indicesBegin, View:: return true; } -void EmptyBody::visit(EmptyBodyVisitor emptyBodyVisitor, ConjunctiveBodyVisitor conjunctiveBodyVisitor) const { - emptyBodyVisitor(*this); +void EmptyBody::visit(std::optional emptyBodyVisitor, + std::optional conjunctiveBodyVisitor) const { + if (emptyBodyVisitor) { + (*emptyBodyVisitor)(*this); + } } diff --git a/cpp/subprojects/common/src/mlrl/common/model/head_complete.cpp b/cpp/subprojects/common/src/mlrl/common/model/head_complete.cpp index e52eb8ee5c..de2f21f846 100644 --- a/cpp/subprojects/common/src/mlrl/common/model/head_complete.cpp +++ b/cpp/subprojects/common/src/mlrl/common/model/head_complete.cpp @@ -19,6 +19,9 @@ CompleteHead::value_const_iterator CompleteHead::values_cend() const { return this->view.cend(); } -void CompleteHead::visit(CompleteHeadVisitor completeHeadVisitor, PartialHeadVisitor partialHeadVisitor) const { - completeHeadVisitor(*this); +void CompleteHead::visit(std::optional completeHeadVisitor, + std::optional partialHeadVisitor) const { + if (completeHeadVisitor) { + (*completeHeadVisitor)(*this); + } } diff --git a/cpp/subprojects/common/src/mlrl/common/model/head_partial.cpp b/cpp/subprojects/common/src/mlrl/common/model/head_partial.cpp index 5b1e83fa84..8eba41781e 100644 --- a/cpp/subprojects/common/src/mlrl/common/model/head_partial.cpp +++ b/cpp/subprojects/common/src/mlrl/common/model/head_partial.cpp @@ -5,6 +5,9 @@ PartialHead::PartialHead(uint32 numElements) CompositeVector, AllocatedVector>(AllocatedVector(numElements), AllocatedVector(numElements))) {} -void PartialHead::visit(CompleteHeadVisitor completeHeadVisitor, PartialHeadVisitor partialHeadVisitor) const { - partialHeadVisitor(*this); +void PartialHead::visit(std::optional completeHeadVisitor, + std::optional partialHeadVisitor) const { + if (partialHeadVisitor) { + (*partialHeadVisitor)(*this); + } } diff --git a/cpp/subprojects/common/src/mlrl/common/model/rule_list.cpp b/cpp/subprojects/common/src/mlrl/common/model/rule_list.cpp index 9fd9426da2..0f9cb3a36e 100644 --- a/cpp/subprojects/common/src/mlrl/common/model/rule_list.cpp +++ b/cpp/subprojects/common/src/mlrl/common/model/rule_list.cpp @@ -17,10 +17,10 @@ const IHead& RuleList::Rule::getHead() const { return *headPtr_; } -void RuleList::Rule::visit(IBody::EmptyBodyVisitor emptyBodyVisitor, - IBody::ConjunctiveBodyVisitor conjunctiveBodyVisitor, - IHead::CompleteHeadVisitor completeHeadVisitor, - IHead::PartialHeadVisitor partialHeadVisitor) const { +void RuleList::Rule::visit(std::optional emptyBodyVisitor, + std::optional conjunctiveBodyVisitor, + std::optional completeHeadVisitor, + std::optional partialHeadVisitor) const { bodyPtr_->visit(emptyBodyVisitor, conjunctiveBodyVisitor); headPtr_->visit(completeHeadVisitor, partialHeadVisitor); } @@ -131,18 +131,20 @@ bool RuleList::isDefaultRuleTakingPrecedence() const { return defaultRuleTakesPrecedence_; } -void RuleList::visit(IBody::EmptyBodyVisitor emptyBodyVisitor, IBody::ConjunctiveBodyVisitor conjunctiveBodyVisitor, - IHead::CompleteHeadVisitor completeHeadVisitor, - IHead::PartialHeadVisitor partialHeadVisitor) const { +void RuleList::visit(std::optional emptyBodyVisitor, + std::optional conjunctiveBodyVisitor, + std::optional completeHeadVisitor, + std::optional partialHeadVisitor) const { for (auto it = this->cbegin(); it != this->cend(); it++) { const Rule& rule = *it; rule.visit(emptyBodyVisitor, conjunctiveBodyVisitor, completeHeadVisitor, partialHeadVisitor); } } -void RuleList::visitUsed(IBody::EmptyBodyVisitor emptyBodyVisitor, IBody::ConjunctiveBodyVisitor conjunctiveBodyVisitor, - IHead::CompleteHeadVisitor completeHeadVisitor, - IHead::PartialHeadVisitor partialHeadVisitor) const { +void RuleList::visitUsed(std::optional emptyBodyVisitor, + std::optional conjunctiveBodyVisitor, + std::optional completeHeadVisitor, + std::optional partialHeadVisitor) const { for (auto it = this->used_cbegin(); it != this->used_cend(); it++) { const Rule& rule = *it; rule.visit(emptyBodyVisitor, conjunctiveBodyVisitor, completeHeadVisitor, partialHeadVisitor); From dad91584f3e16288a1dad3859b33ae3603cd4a35 Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Thu, 15 Aug 2024 18:40:35 +0200 Subject: [PATCH 22/37] Rename class BitVector to BinaryBitVector. --- .../{vector_bit.hpp => vector_bit_binary.hpp} | 4 ++-- .../mlrl/common/sampling/weight_vector_bit.hpp | 7 ++++--- cpp/subprojects/common/meson.build | 4 ++-- .../{vector_bit.cpp => vector_bit_binary.cpp} | 10 +++++----- .../mlrl/common/input/feature_info_mixed.cpp | 10 +++++----- .../stratified_sampling_output_wise.cpp | 2 +- .../{vector_bit.cpp => vector_bit_binary.cpp} | 18 +++++++++--------- .../predictor_binary_output_wise.cpp | 12 ++++++------ 8 files changed, 34 insertions(+), 33 deletions(-) rename cpp/subprojects/common/include/mlrl/common/data/{vector_bit.hpp => vector_bit_binary.hpp} (87%) rename cpp/subprojects/common/src/mlrl/common/data/{vector_bit.cpp => vector_bit_binary.cpp} (75%) rename cpp/subprojects/common/test/mlrl/common/data/{vector_bit.cpp => vector_bit_binary.cpp} (62%) diff --git a/cpp/subprojects/common/include/mlrl/common/data/vector_bit.hpp b/cpp/subprojects/common/include/mlrl/common/data/vector_bit_binary.hpp similarity index 87% rename from cpp/subprojects/common/include/mlrl/common/data/vector_bit.hpp rename to cpp/subprojects/common/include/mlrl/common/data/vector_bit_binary.hpp index 91742b6b98..70d9b2d396 100644 --- a/cpp/subprojects/common/include/mlrl/common/data/vector_bit.hpp +++ b/cpp/subprojects/common/include/mlrl/common/data/vector_bit_binary.hpp @@ -8,7 +8,7 @@ /** * An one-dimension vector that stores binary data in a space-efficient way. */ -class BitVector final : public ClearableViewDecorator>> { +class BinaryBitVector final : public ClearableViewDecorator>> { private: const uint32 numElements_; @@ -19,7 +19,7 @@ class BitVector final : public ClearableViewDecorator /** - * An one-dimensional vector that provides random access to a fixed number of binary weights stored in a `BitVector`. + * An one-dimensional vector that provides random access to a fixed number of binary weights stored in a + * `BinaryBitVector`. */ class BitWeightVector final : public IWeightVector { private: - BitVector vector_; + BinaryBitVector vector_; uint32 numNonZeroWeights_; diff --git a/cpp/subprojects/common/meson.build b/cpp/subprojects/common/meson.build index 1503ce9b1a..d0e10d4466 100644 --- a/cpp/subprojects/common/meson.build +++ b/cpp/subprojects/common/meson.build @@ -2,7 +2,7 @@ project('common', 'cpp') # Source files source_files = [ - 'src/mlrl/common/data/vector_bit.cpp', + 'src/mlrl/common/data/vector_bit_binary.cpp', 'src/mlrl/common/iterator/iterator_index.cpp', 'src/mlrl/common/indices/index_vector_complete.cpp', 'src/mlrl/common/indices/index_vector_partial.cpp', @@ -102,7 +102,7 @@ source_files = [ # Test files test_files = [ 'test/mlrl/common/data/array.cpp', - 'test/mlrl/common/data/vector_bit.cpp', + 'test/mlrl/common/data/vector_bit_binary.cpp', 'test/mlrl/common/data/vector_dense.cpp', 'test/mlrl/common/input/feature_binning_equal_frequency.cpp', 'test/mlrl/common/input/feature_binning_equal_width.cpp', diff --git a/cpp/subprojects/common/src/mlrl/common/data/vector_bit.cpp b/cpp/subprojects/common/src/mlrl/common/data/vector_bit_binary.cpp similarity index 75% rename from cpp/subprojects/common/src/mlrl/common/data/vector_bit.cpp rename to cpp/subprojects/common/src/mlrl/common/data/vector_bit_binary.cpp index 4b5e50515c..efb8633543 100644 --- a/cpp/subprojects/common/src/mlrl/common/data/vector_bit.cpp +++ b/cpp/subprojects/common/src/mlrl/common/data/vector_bit_binary.cpp @@ -1,4 +1,4 @@ -#include "mlrl/common/data/vector_bit.hpp" +#include "mlrl/common/data/vector_bit_binary.hpp" #include @@ -16,16 +16,16 @@ static inline constexpr uint32 mask(uint32 pos) { return 1U << (pos % UINT32_SIZE); } -BitVector::BitVector(uint32 numElements, bool init) +BinaryBitVector::BinaryBitVector(uint32 numElements, bool init) : ClearableViewDecorator>>( AllocatedVector(size(numElements), init)), numElements_(numElements) {} -bool BitVector::operator[](uint32 pos) const { +bool BinaryBitVector::operator[](uint32 pos) const { return this->view.array[index(pos)] & mask(pos); } -void BitVector::set(uint32 pos, bool value) { +void BinaryBitVector::set(uint32 pos, bool value) { if (value) { this->view.array[index(pos)] |= mask(pos); } else { @@ -33,6 +33,6 @@ void BitVector::set(uint32 pos, bool value) { } } -uint32 BitVector::getNumElements() const { +uint32 BinaryBitVector::getNumElements() const { return numElements_; } diff --git a/cpp/subprojects/common/src/mlrl/common/input/feature_info_mixed.cpp b/cpp/subprojects/common/src/mlrl/common/input/feature_info_mixed.cpp index d8246326ac..3b87834ca0 100644 --- a/cpp/subprojects/common/src/mlrl/common/input/feature_info_mixed.cpp +++ b/cpp/subprojects/common/src/mlrl/common/input/feature_info_mixed.cpp @@ -1,20 +1,20 @@ #include "mlrl/common/input/feature_info_mixed.hpp" -#include "mlrl/common/data/vector_bit.hpp" +#include "mlrl/common/data/vector_bit_binary.hpp" #include "mlrl/common/input/feature_type_nominal.hpp" #include "mlrl/common/input/feature_type_numerical.hpp" #include "mlrl/common/input/feature_type_ordinal.hpp" /** - * An implementation of the type `IMixedFeatureInfo` that uses `BitVector`s to store whether individual features are - * ordinal, nominal or numerical. + * An implementation of the type `IMixedFeatureInfo` that uses `BinaryBitVector`s to store whether individual features + * are ordinal, nominal or numerical. */ class BitFeatureInfo final : public IMixedFeatureInfo { private: - BitVector ordinalBitVector_; + BinaryBitVector ordinalBitVector_; - BitVector nominalBitVector_; + BinaryBitVector nominalBitVector_; public: diff --git a/cpp/subprojects/common/src/mlrl/common/sampling/stratified_sampling_output_wise.cpp b/cpp/subprojects/common/src/mlrl/common/sampling/stratified_sampling_output_wise.cpp index 446b272f94..522cc76403 100644 --- a/cpp/subprojects/common/src/mlrl/common/sampling/stratified_sampling_output_wise.cpp +++ b/cpp/subprojects/common/src/mlrl/common/sampling/stratified_sampling_output_wise.cpp @@ -262,7 +262,7 @@ class StratificationMatrix final : public AllocatedBinaryCscView { // Create a boolean array that stores whether individual examples remain to be processed (1) or not (0)... uint32 numTotalExamples = columnWiseLabelMatrix.numRows; - BitVector mask(numTotalExamples, true); + BinaryBitVector mask(numTotalExamples, true); for (uint32 i = 0; i < Matrix::numRows; i++) { uint32 exampleIndex = indicesBegin[i]; diff --git a/cpp/subprojects/common/test/mlrl/common/data/vector_bit.cpp b/cpp/subprojects/common/test/mlrl/common/data/vector_bit_binary.cpp similarity index 62% rename from cpp/subprojects/common/test/mlrl/common/data/vector_bit.cpp rename to cpp/subprojects/common/test/mlrl/common/data/vector_bit_binary.cpp index b1402d7828..aee0707a48 100644 --- a/cpp/subprojects/common/test/mlrl/common/data/vector_bit.cpp +++ b/cpp/subprojects/common/test/mlrl/common/data/vector_bit_binary.cpp @@ -1,25 +1,25 @@ -#include "mlrl/common/data/vector_bit.hpp" +#include "mlrl/common/data/vector_bit_binary.hpp" #include -TEST(BitVectorTest, getNumElements) { +TEST(BinaryBitVectorTest, getNumElements) { uint32 numElements = 270; - BitVector vector(numElements); + BinaryBitVector vector(numElements); EXPECT_EQ(vector.getNumElements(), numElements); } -TEST(BitVectorTest, defaultInitialization) { +TEST(BinaryBitVectorTest, defaultInitialization) { uint32 numElements = 270; - BitVector vector(numElements, true); + BinaryBitVector vector(numElements, true); for (uint32 i = 0; i < numElements; i++) { EXPECT_FALSE(vector[i]); } } -TEST(BitVectorTest, set) { +TEST(BinaryBitVectorTest, set) { uint32 numElements = 270; - BitVector vector(numElements, false); + BinaryBitVector vector(numElements, false); for (uint32 i = 0; i < numElements; i++) { vector.set(i, false); @@ -27,9 +27,9 @@ TEST(BitVectorTest, set) { } } -TEST(BitVectorTest, clear) { +TEST(BinaryBitVectorTest, clear) { uint32 numElements = 270; - BitVector vector(numElements); + BinaryBitVector vector(numElements); for (uint32 i = 0; i < numElements; i++) { vector.set(i, true); diff --git a/cpp/subprojects/seco/src/mlrl/seco/prediction/predictor_binary_output_wise.cpp b/cpp/subprojects/seco/src/mlrl/seco/prediction/predictor_binary_output_wise.cpp index 8dbb49bf61..943bdecdd4 100644 --- a/cpp/subprojects/seco/src/mlrl/seco/prediction/predictor_binary_output_wise.cpp +++ b/cpp/subprojects/seco/src/mlrl/seco/prediction/predictor_binary_output_wise.cpp @@ -1,7 +1,7 @@ #include "mlrl/seco/prediction/predictor_binary_output_wise.hpp" #include "mlrl/common/data/array.hpp" -#include "mlrl/common/data/vector_bit.hpp" +#include "mlrl/common/data/vector_bit_binary.hpp" #include "mlrl/common/iterator/iterator_forward_non_zero_index.hpp" #include "mlrl/common/iterator/iterator_index.hpp" #include "mlrl/common/model/head_complete.hpp" @@ -10,7 +10,7 @@ namespace seco { - static inline void applyHead(const CompleteHead& head, View::iterator iterator, BitVector& mask) { + static inline void applyHead(const CompleteHead& head, View::iterator iterator, BinaryBitVector& mask) { CompleteHead::value_const_iterator valueIterator = head.values_cbegin(); uint32 numElements = head.getNumElements(); @@ -23,7 +23,7 @@ namespace seco { } } - static inline void applyHead(const PartialHead& head, View::iterator iterator, BitVector& mask) { + static inline void applyHead(const PartialHead& head, View::iterator iterator, BinaryBitVector& mask) { PartialHead::value_const_iterator valueIterator = head.values_cbegin(); PartialHead::index_const_iterator indexIterator = head.indices_cbegin(); uint32 numElements = head.getNumElements(); @@ -39,7 +39,7 @@ namespace seco { } } - static inline void applyHead(const IHead& head, View::iterator scoreIterator, BitVector& mask) { + static inline void applyHead(const IHead& head, View::iterator scoreIterator, BinaryBitVector& mask) { auto completeHeadVisitor = [&](const CompleteHead& head) { applyHead(head, scoreIterator, mask); }; @@ -54,7 +54,7 @@ namespace seco { RuleList::const_iterator rulesEnd, CContiguousView& predictionMatrix, uint32 exampleIndex, uint32 predictionIndex) { - BitVector mask(predictionMatrix.numCols, true); + BinaryBitVector mask(predictionMatrix.numCols, true); for (; rulesBegin != rulesEnd; rulesBegin++) { const RuleList::Rule& rule = *rulesBegin; @@ -72,7 +72,7 @@ namespace seco { RuleList::const_iterator rulesEnd, CContiguousView& predictionMatrix, uint32 exampleIndex, uint32 predictionIndex) { - BitVector mask(predictionMatrix.numCols, true); + BinaryBitVector mask(predictionMatrix.numCols, true); uint32 numFeatures = featureMatrix.numCols; Array tmpArray1(numFeatures); Array tmpArray2(numFeatures, true); From 53b1651774572ec319cd26822dfd36f1001b99c5 Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Thu, 15 Aug 2024 19:15:57 +0200 Subject: [PATCH 23/37] Add classes BitView, BitVector, BitVectorAllocator and BinaryBitVectorDecorator. --- .../mlrl/common/data/vector_bit_binary.hpp | 38 ++----- .../include/mlrl/common/data/view_bit.hpp | 50 +++++++++ .../mlrl/common/data/view_vector_bit.hpp | 102 ++++++++++++++++++ .../common/data/view_vector_bit_binary.hpp | 52 +++++++++ .../mlrl/common/util/bit_functions.hpp | 61 +++++++++++ cpp/subprojects/common/meson.build | 1 - .../mlrl/common/data/vector_bit_binary.cpp | 38 ------- 7 files changed, 272 insertions(+), 70 deletions(-) create mode 100644 cpp/subprojects/common/include/mlrl/common/data/view_bit.hpp create mode 100644 cpp/subprojects/common/include/mlrl/common/data/view_vector_bit.hpp create mode 100644 cpp/subprojects/common/include/mlrl/common/data/view_vector_bit_binary.hpp create mode 100644 cpp/subprojects/common/include/mlrl/common/util/bit_functions.hpp delete mode 100644 cpp/subprojects/common/src/mlrl/common/data/vector_bit_binary.cpp diff --git a/cpp/subprojects/common/include/mlrl/common/data/vector_bit_binary.hpp b/cpp/subprojects/common/include/mlrl/common/data/vector_bit_binary.hpp index 70d9b2d396..3b3278b608 100644 --- a/cpp/subprojects/common/include/mlrl/common/data/vector_bit_binary.hpp +++ b/cpp/subprojects/common/include/mlrl/common/data/vector_bit_binary.hpp @@ -3,44 +3,20 @@ */ #pragma once -#include "mlrl/common/data/view_vector.hpp" +#include "mlrl/common/data/view_vector_bit_binary.hpp" /** - * An one-dimension vector that stores binary data in a space-efficient way. + * An one-dimensional vector that stores binary data in a space-efficient way. */ -class BinaryBitVector final : public ClearableViewDecorator>> { - private: - - const uint32 numElements_; - +class BinaryBitVector final + : public ClearableViewDecorator>> { public: /** * @param numElements The number of elements in the vector * @param init True, if all elements in the vector should be value-initialized, false otherwise */ - BinaryBitVector(uint32 numElements, bool init = false); - - /** - * Returns the value of the element at a specific position. - * - * @param pos The position of the element - * @return The value of the specified element - */ - bool operator[](uint32 pos) const; - - /** - * Sets a value to the element at a specific position. - * - * @param pos The position of the element - * @param value The value to be set - */ - void set(uint32 pos, bool value); - - /** - * Returns the number of elements in the vector. - * - * @return The number of elements in the vector - */ - uint32 getNumElements() const; + BinaryBitVector(uint32 numElements, bool init = false) + : ClearableViewDecorator>>( + AllocatedBitVector(numElements, 1, init)) {} }; diff --git a/cpp/subprojects/common/include/mlrl/common/data/view_bit.hpp b/cpp/subprojects/common/include/mlrl/common/data/view_bit.hpp new file mode 100644 index 0000000000..a527f01d44 --- /dev/null +++ b/cpp/subprojects/common/include/mlrl/common/data/view_bit.hpp @@ -0,0 +1,50 @@ +/* + * @author Michael Rapp (michael.rapp.ml@gmail.com) + */ +#pragma once + +#include "mlrl/common/data/view.hpp" + +#include + +/** + * A view that provides random access to integer values, each with a specific number of bits, stored in a pre-allocated + * array of a specific size. + */ +class BitView : public BaseView { + public: + + /** + * The number of bits per element in the view. + */ + uint32 numBitsPerElement; + + /** + * @param array A pointer to an array of type `uint32` that stores the values, the view should provide + * access to + * @param dimensions The number of elements in each dimension of the view + */ + BitView(uint32* array, std::initializer_list dimensions) + : BaseView(array), numBitsPerElement(dimensions.begin()[1]) {} + + /** + * @param array A pointer to an array of type `uint32` that stores the values, the view should + * provide access to + * @param numElements The number of elements in the view + * @param numBitsPerElement The number of bits per element in the view + */ + BitView(uint32* array, uint32 numElements, uint32 numBitsPerElement) + : BaseView(array), numBitsPerElement(numBitsPerElement) {} + + /** + * @param other A const reference to an object of type `BitView` that should be copied + */ + BitView(const BitView& other) : BaseView(other), numBitsPerElement(other.numBitsPerElement) {} + + /** + * @param other A reference to an object of type `BitView` that should be moved + */ + BitView(BitView&& other) : BaseView(std::move(other)), numBitsPerElement(other.numBitsPerElement) {} + + virtual ~BitView() override {} +}; diff --git a/cpp/subprojects/common/include/mlrl/common/data/view_vector_bit.hpp b/cpp/subprojects/common/include/mlrl/common/data/view_vector_bit.hpp new file mode 100644 index 0000000000..545960fab0 --- /dev/null +++ b/cpp/subprojects/common/include/mlrl/common/data/view_vector_bit.hpp @@ -0,0 +1,102 @@ +/* + * @author Michael Rapp (michael.rapp.ml@gmail.com) + */ +#pragma once + +#include "mlrl/common/data/view_bit.hpp" +#include "mlrl/common/data/view_vector.hpp" +#include "mlrl/common/util/bit_functions.hpp" + +#include + +/** + * A one-dimensional vector that provides random access to integer values, each with a specific number of bits, stored + * in a pre-allocated array of a specific size. + */ +class BitVector : public BitView { + public: + + /** + * The number of elements in the bit vector. + */ + uint32 numElements; + + /** + * @param array A pointer to an array of type `uint32` that stores the values, the bit vector should + * provide access to + * @param dimensions The number of elements in each dimension of the bit vector + */ + BitVector(uint32* array, std::initializer_list dimensions) + : BitView(array, dimensions), numElements(dimensions.begin()[0]) {} + + /** + * @param array A pointer to an array of type `uint32` that stores the values, the bit vector should + * provide access to + * @param numElements The number of elements in the bit vector + * @param numBitsPerElement The number of bits per element in the bit vector + */ + BitVector(uint32* array, uint32 numElements, uint32 numBitsPerElement) + : BitView(array, numElements, numBitsPerElement), numElements(numElements) {} + + /** + * @param other A const reference to an object of type `BitVector` that should be copied + */ + BitVector(const BitVector& other) : BitView(other), numElements(other.numElements) {} + + /** + * @param other A reference to an object of type `BitVector` that should be moved + */ + BitVector(BitVector&& other) : BitView(std::move(other)), numElements(other.numElements) {} + + virtual ~BitVector() override {} + + /** + * Sets all values stored in the bit vector to zero. + */ + void clear() { + util::setViewToZeros(BaseView::array, util::bitArraySize(numElements * BitView::numBitsPerElement)); + } +}; + +/** + * Allocates the memory, a bit vector provides access to. + * + * @tparam BitVector The type of the bit vector + */ +template +class BitVectorAllocator : public BitVector { + public: + + /** + * @param numElements The number of elements in the bit vector + * @param numBitsPerElement The number of bits per element in the bit vector + * @param init True, if all elements in the bit vector should be value-initialized, false otherwise + */ + explicit BitVectorAllocator(uint32 numElements, uint32 numBitsPerElement, bool init = false) + : BitVector(util::allocateMemory( + util::bitArraySize(numElements * numBitsPerElement), init), + {numElements, numBitsPerElement}) {} + + /** + * @param other A reference to an object of type `BitVectorAllocator` that should be copied + */ + BitVectorAllocator(const BitVectorAllocator& other) : BitVector(other) { + throw std::runtime_error("Objects of type BitVectorAllocator cannot be copied"); + } + + /** + * @param other A reference to an object of type `BitVectorAllocator` that should be moved + */ + BitVectorAllocator(BitVectorAllocator&& other) : BitVector(std::move(other)) { + other.release(); + } + + virtual ~BitVectorAllocator() override { + util::freeMemory(BitVector::array); + } +}; + +/** + * Allocates the memory, a `BitVector` provides access to. + */ +typedef BitVectorAllocator AllocatedBitVector; diff --git a/cpp/subprojects/common/include/mlrl/common/data/view_vector_bit_binary.hpp b/cpp/subprojects/common/include/mlrl/common/data/view_vector_bit_binary.hpp new file mode 100644 index 0000000000..5210facf57 --- /dev/null +++ b/cpp/subprojects/common/include/mlrl/common/data/view_vector_bit_binary.hpp @@ -0,0 +1,52 @@ +/* + * @author Michael Rapp (michael.rapp.ml@gmail.com) + */ +#pragma once + +#include "mlrl/common/data/view_vector_bit.hpp" + +#include + +/** + * Provides random read and write access to binary values stored in a bit vector. + * + * @tparam BitVector The type of view, the bit vector is backed by + */ +template +class BinaryBitVectorDecorator : public BitVector { + public: + + /** + * @param view The view, the bit vector should be backed by + */ + explicit BinaryBitVectorDecorator(typename BitVector::view_type&& view) : BitVector(std::move(view)) {} + + virtual ~BinaryBitVectorDecorator() override {} + + /** + * Returns the value of the element at a specific position. + * + * @param pos The position of the element + * @return The value of the specified element + */ + bool operator[](uint32 pos) const { + return this->view.array[util::bitArrayOffset(pos)] + & util::bitArrayMask(pos); + } + + /** + * Sets a value to the element at a specific position. + * + * @param pos The position of the element + * @param value The value to be set + */ + void set(uint32 pos, bool value) { + if (value) { + this->view.array[util::bitArrayOffset(pos)] |= + util::bitArrayMask(pos); + } else { + this->view.array[util::bitArrayOffset(pos)] &= + ~util::bitArrayMask(pos); + } + } +}; diff --git a/cpp/subprojects/common/include/mlrl/common/util/bit_functions.hpp b/cpp/subprojects/common/include/mlrl/common/util/bit_functions.hpp new file mode 100644 index 0000000000..0ffa687fcb --- /dev/null +++ b/cpp/subprojects/common/include/mlrl/common/util/bit_functions.hpp @@ -0,0 +1,61 @@ +/* + * @author Michael Rapp (michael.rapp.ml@gmail.com) + */ +#pragma once + +#include "mlrl/common/data/types.hpp" + +#include + +namespace util { + + /** + * Returns the number of bits used by a certain type. + * + * @tparam T The type + * @return The number of bits + */ + template + static inline constexpr std::size_t bits() { + return CHAR_BIT * sizeof(T); + } + + /** + * Returns the number of elements needed by an array of a specific type for storing a given number of bits. + * + * @tparam T The type of the array + * @param numBits The number of bits to be stored + * @return The number of elements needed + */ + template + static inline constexpr std::size_t bitArraySize(uint32 numBits) { + return (numBits + bits() - 1) / bits(); + } + + /** + * Returns the index of the element in an array of a specific type that stores the bit at a specific position, + * starting from the beginning of the array. + * + * @tparam T The type of the array + * @param arrayIndex The index of the bit + * @return The index of the element that stores the bit + */ + template + static inline constexpr uint32 bitArrayOffset(uint32 arrayIndex) { + return arrayIndex / bits(); + } + + /** + * Returns a bit mask that can be compared via bit-wise operators to a single element in an array of a specific + * type. The mask consists exclusively of zeros, except for a single bit at a specific index that is set to one. + * + * @tparam T The type of the array + * @param bitIndex The index of the bit to be set to one + * @return A value of template type `T` that stores the bit mask + */ + template + static inline constexpr T bitArrayMask(uint32 bitIndex) { + return 1U << (bitIndex % bits()); + } + +} diff --git a/cpp/subprojects/common/meson.build b/cpp/subprojects/common/meson.build index d0e10d4466..cff6d20a9f 100644 --- a/cpp/subprojects/common/meson.build +++ b/cpp/subprojects/common/meson.build @@ -2,7 +2,6 @@ project('common', 'cpp') # Source files source_files = [ - 'src/mlrl/common/data/vector_bit_binary.cpp', 'src/mlrl/common/iterator/iterator_index.cpp', 'src/mlrl/common/indices/index_vector_complete.cpp', 'src/mlrl/common/indices/index_vector_partial.cpp', diff --git a/cpp/subprojects/common/src/mlrl/common/data/vector_bit_binary.cpp b/cpp/subprojects/common/src/mlrl/common/data/vector_bit_binary.cpp deleted file mode 100644 index efb8633543..0000000000 --- a/cpp/subprojects/common/src/mlrl/common/data/vector_bit_binary.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "mlrl/common/data/vector_bit_binary.hpp" - -#include - -static inline constexpr uint32 UINT32_SIZE = static_cast(CHAR_BIT * sizeof(uint32)); - -static inline constexpr uint32 size(uint32 numElements) { - return numElements / UINT32_SIZE + (numElements % UINT32_SIZE != 0); -} - -static inline constexpr uint32 index(uint32 pos) { - return pos / UINT32_SIZE; -} - -static inline constexpr uint32 mask(uint32 pos) { - return 1U << (pos % UINT32_SIZE); -} - -BinaryBitVector::BinaryBitVector(uint32 numElements, bool init) - : ClearableViewDecorator>>( - AllocatedVector(size(numElements), init)), - numElements_(numElements) {} - -bool BinaryBitVector::operator[](uint32 pos) const { - return this->view.array[index(pos)] & mask(pos); -} - -void BinaryBitVector::set(uint32 pos, bool value) { - if (value) { - this->view.array[index(pos)] |= mask(pos); - } else { - this->view.array[index(pos)] &= ~mask(pos); - } -} - -uint32 BinaryBitVector::getNumElements() const { - return numElements_; -} From fa7e1d971b4a4986465439bd743c9c32607f63eb Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Sun, 18 Aug 2024 01:07:48 +0200 Subject: [PATCH 24/37] Add classes BitMatrix and BitMatrixAllocator. --- .../mlrl/common/data/view_matrix_bit.hpp | 86 +++++++++++++++++++ .../mlrl/common/data/view_vector_bit.hpp | 2 +- 2 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 cpp/subprojects/common/include/mlrl/common/data/view_matrix_bit.hpp diff --git a/cpp/subprojects/common/include/mlrl/common/data/view_matrix_bit.hpp b/cpp/subprojects/common/include/mlrl/common/data/view_matrix_bit.hpp new file mode 100644 index 0000000000..98944af521 --- /dev/null +++ b/cpp/subprojects/common/include/mlrl/common/data/view_matrix_bit.hpp @@ -0,0 +1,86 @@ +/* + * @author Michael Rapp (michael.rapp.ml@gmail.com) + */ +#pragma once + +#include "mlrl/common/data/view_bit.hpp" +#include "mlrl/common/data/view_matrix.hpp" +#include "mlrl/common/util/bit_functions.hpp" + +#include + +/** + * A two-dimensional view that provides random access to integer values, each with a specific number of bits, stored in + * a dense matrix of a specific size. + */ +class BitMatrix : public BitView, + public Matrix { + public: + + /** + * @param array A pointer to an array of type `uint32` that stores the values, the view should + * provide access to + * @param numRows The number of rows in the view + * @param numCols The number of columns in the view + * @param numBitsPerElement The number of bits per element in the view + */ + BitMatrix(uint32* array, uint32 numRows, uint32 numCols, uint32 numBitsPerElement) + : BitView(array, numRows * numCols, numBitsPerElement), Matrix(numRows, numCols) {} + + /** + * @param other A const reference to an object of type `BitMatrix` that should be copied + */ + BitMatrix(const BitMatrix& other) : BitView(other), Matrix(other) {} + + /** + * @param other A reference to an object of type `BitMatrix` that should be moved + */ + BitMatrix(BitMatrix&& other) : BitView(std::move(other)), Matrix(std::move(other)) {} + + virtual ~BitMatrix() override {} +}; + +/** + * Allocates the memory, a `BitMatrix` provides access to. + * + * @tparam BitMatrix The type of the bit matrix + */ +template +class BitMatrixAllocator : public BitMatrix { + public: + + /** + * @param numRows The number of rows in the bit matrix + * @param numCols The number of columns in the bit matrix + * @param numBitsPerElement The number of bits per element in the bit matrix + * @param init True, if all elements in the bit matrix should be value-initialized, false otherwise + */ + explicit BitMatrixAllocator(uint32 numRows, uint32 numCols, uint32 numBitsPerElement, bool init = false) + : BitMatrix( + util::allocateMemory( + util::bitArraySize(numCols * numBitsPerElement) * numRows, init), + numRows, numCols, numBitsPerElement) {} + + /** + * @param other A reference to an object of type `BitMatrixAllocator` that should be copied + */ + BitMatrixAllocator(const BitMatrixAllocator& other) : BitMatrix(other) { + throw std::runtime_error("Objects of type BitMatrixAllocator cannot be copied"); + } + + /** + * @param other A reference to an object of type `BitMatrixAllocator` that should be moved + */ + BitMatrixAllocator(BitMatrixAllocator&& other) : BitMatrix(std::move(other)) { + other.release(); + } + + virtual ~BitMatrixAllocator() override { + util::freeMemory(BitMatrix::array); + } +}; + +/** + * Allocates the memory, a `BitMatrix` provides access to. + */ +typedef BitMatrixAllocator AllocatedBitMatrix; diff --git a/cpp/subprojects/common/include/mlrl/common/data/view_vector_bit.hpp b/cpp/subprojects/common/include/mlrl/common/data/view_vector_bit.hpp index 545960fab0..7e6582a77c 100644 --- a/cpp/subprojects/common/include/mlrl/common/data/view_vector_bit.hpp +++ b/cpp/subprojects/common/include/mlrl/common/data/view_vector_bit.hpp @@ -59,7 +59,7 @@ class BitVector : public BitView { }; /** - * Allocates the memory, a bit vector provides access to. + * Allocates the memory, a `BitVector` provides access to. * * @tparam BitVector The type of the bit vector */ From 8a6f801f691ddcaf6a7a818723aacb14d249bafb Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Sun, 18 Aug 2024 01:35:51 +0200 Subject: [PATCH 25/37] Add class IntegerBitMatrix. --- .../statistics/quantization_stochastic.cpp | 39 ++++++++++--------- .../mlrl/common/data/matrix_bit_integer.hpp | 22 +++++++++++ 2 files changed, 43 insertions(+), 18 deletions(-) create mode 100644 cpp/subprojects/common/include/mlrl/common/data/matrix_bit_integer.hpp diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp index 7ab6399c2c..7aee87fe9d 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp @@ -1,5 +1,6 @@ #include "mlrl/boosting/statistics/quantization_stochastic.hpp" +#include "mlrl/common/data/matrix_bit_integer.hpp" #include "mlrl/common/util/validation.hpp" namespace boosting { @@ -8,12 +9,11 @@ namespace boosting { class StochasticQuantization final : public IQuantization { private: - std::unique_ptr>>> quantizationMatrixPtr_; + std::unique_ptr> quantizationMatrixPtr_; public: - StochasticQuantization( - std::unique_ptr>>> quantizationMatrixPtr) + StochasticQuantization(std::unique_ptr> quantizationMatrixPtr) : quantizationMatrixPtr_(std::move(quantizationMatrixPtr)) {} void quantize(const CompleteIndexVector& outputIndices) override { @@ -29,25 +29,22 @@ namespace boosting { std::optional sparseDecomposableMatrixVisitor, std::optional denseNonDecomposableMatrixVisitor) override { - if (denseDecomposableMatrixVisitor) { - (*denseDecomposableMatrixVisitor)(quantizationMatrixPtr_); - } + // TODO Implement } }; template - class StochasticQuantizationMatrix final : public IQuantizationMatrix>> { + class StochasticQuantizationMatrix final : public IQuantizationMatrix { private: const View& view_; - // TODO Use correct type - MatrixDecorator>> matrix_; + IntegerBitMatrix matrix_; public: - StochasticQuantizationMatrix(const View& view) - : view_(view), matrix_(AllocatedCContiguousView>(view.numRows, view.numCols)) {} + StochasticQuantizationMatrix(const View& view, uint32 numBits) + : view_(view), matrix_(view.numRows, view.numCols, numBits, true) {} void quantize(const CompleteIndexVector& outputIndices) override { // TODO Implement @@ -57,25 +54,28 @@ namespace boosting { // TODO Implement } - const typename IQuantizationMatrix>>::view_type& getView() const override { + const typename IQuantizationMatrix::view_type& getView() const override { return matrix_.getView(); } std::unique_ptr create( const CContiguousView>& statisticMatrix) const override { return std::make_unique>>>( - std::make_unique>>>(statisticMatrix)); + std::make_unique>>>( + statisticMatrix, matrix_.getView().numBitsPerElement)); } std::unique_ptr create(const SparseSetView>& statisticMatrix) const override { return std::make_unique>>>( - std::make_unique>>>(statisticMatrix)); + std::make_unique>>>( + statisticMatrix, matrix_.getView().numBitsPerElement)); } std::unique_ptr create( const DenseNonDecomposableStatisticView& statisticMatrix) const override { return std::make_unique>( - std::make_unique>(statisticMatrix)); + std::make_unique>( + statisticMatrix, matrix_.getView().numBitsPerElement)); } }; @@ -94,18 +94,21 @@ namespace boosting { std::unique_ptr create( const CContiguousView>& statisticMatrix) const override { return std::make_unique>>>( - std::make_unique>>>(statisticMatrix)); + std::make_unique>>>(statisticMatrix, + numBits_)); } std::unique_ptr create(const SparseSetView>& statisticMatrix) const override { return std::make_unique>>>( - std::make_unique>>>(statisticMatrix)); + std::make_unique>>>(statisticMatrix, + numBits_)); } std::unique_ptr create( const DenseNonDecomposableStatisticView& statisticMatrix) const override { return std::make_unique>( - std::make_unique>(statisticMatrix)); + std::make_unique>(statisticMatrix, + numBits_)); } }; diff --git a/cpp/subprojects/common/include/mlrl/common/data/matrix_bit_integer.hpp b/cpp/subprojects/common/include/mlrl/common/data/matrix_bit_integer.hpp new file mode 100644 index 0000000000..5da5071a87 --- /dev/null +++ b/cpp/subprojects/common/include/mlrl/common/data/matrix_bit_integer.hpp @@ -0,0 +1,22 @@ +/* + * @author Michael Rapp (michael.rapp.ml@gmail.com) + */ +#pragma once + +#include "mlrl/common/data/view_matrix_bit.hpp" + +/** + * A two-dimensional matrix that stores integer values, each with a specific number of bits. + */ +class IntegerBitMatrix final : public MatrixDecorator { + public: + + /** + * @param numRows The number of rows in the matrix + * @param numCols The number of columns in the matrix + * @param numBitsPerElement The number of bits per element in the matrix + * @param init True, if all elements in the matrix should be value-initialized, false otherwise + */ + IntegerBitMatrix(uint32 numRows, uint32 numCols, uint32 numBitsPerElements, bool init = false) + : MatrixDecorator(AllocatedBitMatrix(numRows, numCols, numBitsPerElements, init)) {} +}; From 7fd8e9195846a142baf140511c4d942bf1fbb6e7 Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Sun, 18 Aug 2024 02:17:58 +0200 Subject: [PATCH 26/37] Add functions "operator[]" and "set" to class BitVector. --- .../mlrl/common/data/vector_bit_binary.hpp | 8 +- .../mlrl/common/data/view_matrix_bit.hpp | 2 +- .../mlrl/common/data/view_vector_bit.hpp | 101 +++++++++++++++++- .../common/data/view_vector_bit_binary.hpp | 52 --------- .../mlrl/common/util/bit_functions.hpp | 46 +++----- cpp/subprojects/common/meson.build | 1 + .../test/mlrl/common/data/view_vector_bit.cpp | 78 ++++++++++++++ 7 files changed, 198 insertions(+), 90 deletions(-) delete mode 100644 cpp/subprojects/common/include/mlrl/common/data/view_vector_bit_binary.hpp create mode 100644 cpp/subprojects/common/test/mlrl/common/data/view_vector_bit.cpp diff --git a/cpp/subprojects/common/include/mlrl/common/data/vector_bit_binary.hpp b/cpp/subprojects/common/include/mlrl/common/data/vector_bit_binary.hpp index 3b3278b608..d27aab2681 100644 --- a/cpp/subprojects/common/include/mlrl/common/data/vector_bit_binary.hpp +++ b/cpp/subprojects/common/include/mlrl/common/data/vector_bit_binary.hpp @@ -3,13 +3,13 @@ */ #pragma once -#include "mlrl/common/data/view_vector_bit_binary.hpp" +#include "mlrl/common/data/view_vector_bit.hpp" /** * An one-dimensional vector that stores binary data in a space-efficient way. */ class BinaryBitVector final - : public ClearableViewDecorator>> { + : public ClearableViewDecorator>>> { public: /** @@ -17,6 +17,6 @@ class BinaryBitVector final * @param init True, if all elements in the vector should be value-initialized, false otherwise */ BinaryBitVector(uint32 numElements, bool init = false) - : ClearableViewDecorator>>( - AllocatedBitVector(numElements, 1, init)) {} + : ClearableViewDecorator>>>( + AllocatedBitVector(numElements, 1, init)) {} }; diff --git a/cpp/subprojects/common/include/mlrl/common/data/view_matrix_bit.hpp b/cpp/subprojects/common/include/mlrl/common/data/view_matrix_bit.hpp index 98944af521..0d6384b5da 100644 --- a/cpp/subprojects/common/include/mlrl/common/data/view_matrix_bit.hpp +++ b/cpp/subprojects/common/include/mlrl/common/data/view_matrix_bit.hpp @@ -58,7 +58,7 @@ class BitMatrixAllocator : public BitMatrix { explicit BitMatrixAllocator(uint32 numRows, uint32 numCols, uint32 numBitsPerElement, bool init = false) : BitMatrix( util::allocateMemory( - util::bitArraySize(numCols * numBitsPerElement) * numRows, init), + util::getBitArraySize(numCols, numBitsPerElement) * numRows, init), numRows, numCols, numBitsPerElement) {} /** diff --git a/cpp/subprojects/common/include/mlrl/common/data/view_vector_bit.hpp b/cpp/subprojects/common/include/mlrl/common/data/view_vector_bit.hpp index 7e6582a77c..f778fd4002 100644 --- a/cpp/subprojects/common/include/mlrl/common/data/view_vector_bit.hpp +++ b/cpp/subprojects/common/include/mlrl/common/data/view_vector_bit.hpp @@ -12,8 +12,29 @@ /** * A one-dimensional vector that provides random access to integer values, each with a specific number of bits, stored * in a pre-allocated array of a specific size. + * + * @param T The type of the integer values, the view provides access to */ +template class BitVector : public BitView { + private: + + static inline constexpr uint32 NUM_BITS = util::bits(); + + inline constexpr uint32 getOffset(uint32 pos) const { + return pos / (NUM_BITS / BitView::numBitsPerElement); + } + + inline constexpr uint32 getNumShifts(uint32 pos) const { + uint32 numIntegersPerElement = NUM_BITS / numBitsPerElement; + return NUM_BITS - ((pos % numIntegersPerElement) * numBitsPerElement) - numBitsPerElement; + } + + inline constexpr uint32 getBitMask(uint32 numShifts) const { + uint32 ones = util::getNumBitCombinations(numBitsPerElement) - 1; + return ones << numShifts; + } + public: /** @@ -50,11 +71,45 @@ class BitVector : public BitView { virtual ~BitVector() override {} + /** + * The type of the integer values, the view provides access to + */ + typedef T type; + /** * Sets all values stored in the bit vector to zero. */ void clear() { - util::setViewToZeros(BaseView::array, util::bitArraySize(numElements * BitView::numBitsPerElement)); + util::setViewToZeros(BaseView::array, + util::getBitArraySize(numElements, BitView::numBitsPerElement)); + } + + /** + * Returns the value of the element at a specific position. + * + * @param pos The position of the element + * @return The value of the specified element + */ + type operator[](uint32 pos) const { + uint32 offset = this->getOffset(pos); + uint32 numShifts = this->getNumShifts(pos); + uint32 bitMask = this->getBitMask(numShifts); + uint32 value = BaseView::array[offset]; + return static_cast((value & bitMask) >> numShifts); + } + + /** + * Sets a value to the element at a specific position. + * + * @param pos The position of the element + * @param value The value to be set + */ + void set(uint32 pos, type value) { + uint32 offset = this->getOffset(pos); + uint32 numShifts = this->getNumShifts(pos); + uint32 bitMask = this->getBitMask(numShifts); + BaseView::array[offset] &= ~bitMask; + BaseView::array[offset] |= value << numShifts; } }; @@ -74,7 +129,7 @@ class BitVectorAllocator : public BitVector { */ explicit BitVectorAllocator(uint32 numElements, uint32 numBitsPerElement, bool init = false) : BitVector(util::allocateMemory( - util::bitArraySize(numElements * numBitsPerElement), init), + util::getBitArraySize(numElements, numBitsPerElement), init), {numElements, numBitsPerElement}) {} /** @@ -98,5 +153,45 @@ class BitVectorAllocator : public BitVector { /** * Allocates the memory, a `BitVector` provides access to. + * + * @tparam T The type of the integer values, the view provides access to + */ +template +using AllocatedBitVector = BitVectorAllocator>; + +/** + * Provides random read and write access to integer values stored in a bit vector. + * + * @tparam BitVector The type of view, the bit vector is backed by */ -typedef BitVectorAllocator AllocatedBitVector; +template +class BitVectorDecorator : public BitVector { + public: + + /** + * @param view The view, the bit vector should be backed by + */ + explicit BitVectorDecorator(typename BitVector::view_type&& view) : BitVector(std::move(view)) {} + + virtual ~BitVectorDecorator() override {} + + /** + * Returns the value of the element at a specific position. + * + * @param pos The position of the element + * @return The value of the specified element + */ + typename BitVector::view_type::type operator[](uint32 pos) const { + return this->view[pos]; + } + + /** + * Sets a value to the element at a specific position. + * + * @param pos The position of the element + * @param value The value to be set + */ + void set(uint32 pos, typename BitVector::view_type::type value) { + this->view.set(pos, value); + } +}; diff --git a/cpp/subprojects/common/include/mlrl/common/data/view_vector_bit_binary.hpp b/cpp/subprojects/common/include/mlrl/common/data/view_vector_bit_binary.hpp deleted file mode 100644 index 5210facf57..0000000000 --- a/cpp/subprojects/common/include/mlrl/common/data/view_vector_bit_binary.hpp +++ /dev/null @@ -1,52 +0,0 @@ -/* - * @author Michael Rapp (michael.rapp.ml@gmail.com) - */ -#pragma once - -#include "mlrl/common/data/view_vector_bit.hpp" - -#include - -/** - * Provides random read and write access to binary values stored in a bit vector. - * - * @tparam BitVector The type of view, the bit vector is backed by - */ -template -class BinaryBitVectorDecorator : public BitVector { - public: - - /** - * @param view The view, the bit vector should be backed by - */ - explicit BinaryBitVectorDecorator(typename BitVector::view_type&& view) : BitVector(std::move(view)) {} - - virtual ~BinaryBitVectorDecorator() override {} - - /** - * Returns the value of the element at a specific position. - * - * @param pos The position of the element - * @return The value of the specified element - */ - bool operator[](uint32 pos) const { - return this->view.array[util::bitArrayOffset(pos)] - & util::bitArrayMask(pos); - } - - /** - * Sets a value to the element at a specific position. - * - * @param pos The position of the element - * @param value The value to be set - */ - void set(uint32 pos, bool value) { - if (value) { - this->view.array[util::bitArrayOffset(pos)] |= - util::bitArrayMask(pos); - } else { - this->view.array[util::bitArrayOffset(pos)] &= - ~util::bitArrayMask(pos); - } - } -}; diff --git a/cpp/subprojects/common/include/mlrl/common/util/bit_functions.hpp b/cpp/subprojects/common/include/mlrl/common/util/bit_functions.hpp index 0ffa687fcb..f3a8de6811 100644 --- a/cpp/subprojects/common/include/mlrl/common/util/bit_functions.hpp +++ b/cpp/subprojects/common/include/mlrl/common/util/bit_functions.hpp @@ -16,46 +16,32 @@ namespace util { * @return The number of bits */ template - static inline constexpr std::size_t bits() { - return CHAR_BIT * sizeof(T); + static inline constexpr uint32 bits() { + return static_cast(CHAR_BIT * sizeof(T)); } /** - * Returns the number of elements needed by an array of a specific type for storing a given number of bits. + * Returns the number of elements needed by an array of a specific type for storing a given number of integers, each + * with a specific number of bits. * - * @tparam T The type of the array - * @param numBits The number of bits to be stored - * @return The number of elements needed + * @tparam T The type of the array + * @param numIntegers The number of integers to be stored + * @param numBitsPerInteger The number of bits per integer + * @return The number of elements needed */ template - static inline constexpr std::size_t bitArraySize(uint32 numBits) { - return (numBits + bits() - 1) / bits(); + static inline constexpr uint32 getBitArraySize(uint32 numIntegers, uint32 numBitsPerInteger) { + uint32 numIntegersPerElement = bits() / numBitsPerInteger; + return numIntegers / numIntegersPerElement + (numIntegers % numIntegersPerElement != 0); } /** - * Returns the index of the element in an array of a specific type that stores the bit at a specific position, - * starting from the beginning of the array. + * Returns the number of values representable by a given number of bits. * - * @tparam T The type of the array - * @param arrayIndex The index of the bit - * @return The index of the element that stores the bit + * @param numBits The number of bits + * @return The number of representable values */ - template - static inline constexpr uint32 bitArrayOffset(uint32 arrayIndex) { - return arrayIndex / bits(); - } - - /** - * Returns a bit mask that can be compared via bit-wise operators to a single element in an array of a specific - * type. The mask consists exclusively of zeros, except for a single bit at a specific index that is set to one. - * - * @tparam T The type of the array - * @param bitIndex The index of the bit to be set to one - * @return A value of template type `T` that stores the bit mask - */ - template - static inline constexpr T bitArrayMask(uint32 bitIndex) { - return 1U << (bitIndex % bits()); + static inline uint32 getNumBitCombinations(uint32 numBits) { + return static_cast(std::pow(2, numBits)); } - } diff --git a/cpp/subprojects/common/meson.build b/cpp/subprojects/common/meson.build index cff6d20a9f..fc5a9d99f6 100644 --- a/cpp/subprojects/common/meson.build +++ b/cpp/subprojects/common/meson.build @@ -103,6 +103,7 @@ test_files = [ 'test/mlrl/common/data/array.cpp', 'test/mlrl/common/data/vector_bit_binary.cpp', 'test/mlrl/common/data/vector_dense.cpp', + 'test/mlrl/common/data/view_vector_bit.cpp', 'test/mlrl/common/input/feature_binning_equal_frequency.cpp', 'test/mlrl/common/input/feature_binning_equal_width.cpp', 'test/mlrl/common/input/feature_type_nominal.cpp', diff --git a/cpp/subprojects/common/test/mlrl/common/data/view_vector_bit.cpp b/cpp/subprojects/common/test/mlrl/common/data/view_vector_bit.cpp new file mode 100644 index 0000000000..1929efd620 --- /dev/null +++ b/cpp/subprojects/common/test/mlrl/common/data/view_vector_bit.cpp @@ -0,0 +1,78 @@ +#include "mlrl/common/data/view_vector_bit.hpp" + +#include + +TEST(BitVectorTest, constructor) { + uint32 numElements = 256; + uint32 numBitsPerElement = 4; + AllocatedBitVector vector(numElements, numBitsPerElement); + EXPECT_EQ(vector.numElements, numElements); + EXPECT_EQ(vector.numBitsPerElement, numBitsPerElement); +} + +TEST(BitVectorTest, defaultInitialization) { + uint32 numElements = 256; + AllocatedBitVector vector(numElements, 4, true); + + for (uint32 i = 0; i < numElements; i++) { + EXPECT_EQ(vector[i], (uint32) 0); + } +} + +TEST(BitVectorTest, set1) { + uint32 numElements = 256; + uint32 numBitsPerElement = 4; + uint32 numValuesPerElement = util::getNumBitCombinations(numBitsPerElement); + AllocatedBitVector vector(numElements, numBitsPerElement, false); + uint32 i = 0; + + while (i < numElements) { + for (uint32 j = 0; i < numElements && j < numValuesPerElement; j++) { + vector.set(i, j); + i++; + } + } + + i = 0; + + while (i < numElements) { + for (uint32 j = 0; i < numElements && j < numValuesPerElement; j++) { + EXPECT_EQ(vector[i], (uint32) j); + i++; + } + } +} + +TEST(BitVectorTest, set2) { + uint32 numElements = 256; + uint32 numBitsPerElement = 3; + uint32 numValuesPerElement = util::getNumBitCombinations(numBitsPerElement); + AllocatedBitVector vector(numElements, numBitsPerElement, false); + uint32 i = 0; + + while (i < numElements) { + for (uint32 j = 0; i < numElements && j < numValuesPerElement; j++) { + vector.set(i, j); + i++; + } + } + + i = 0; + + while (i < numElements) { + for (uint32 j = 0; i < numElements && j < numValuesPerElement; j++) { + EXPECT_EQ(vector[i], (uint32) j); + i++; + } + } +} + +TEST(BitVectorTest, clear) { + uint32 numElements = 256; + AllocatedBitVector vector(numElements, 4, false); + vector.clear(); + + for (uint32 i = 0; i < numElements; i++) { + EXPECT_EQ(vector[i], (uint32) 0); + } +} From a6e849fb32118b5b141d695a34a094c16413ed96 Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Mon, 19 Aug 2024 01:01:14 +0200 Subject: [PATCH 27/37] Add function "operator[]" to class BitMatrix. --- .../statistics/quantization_stochastic.cpp | 8 +-- .../mlrl/common/data/matrix_bit_integer.hpp | 5 +- .../mlrl/common/data/view_matrix_bit.hpp | 49 +++++++++++++++++-- 3 files changed, 53 insertions(+), 9 deletions(-) diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp index 7aee87fe9d..ad12a2d35b 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp @@ -9,11 +9,11 @@ namespace boosting { class StochasticQuantization final : public IQuantization { private: - std::unique_ptr> quantizationMatrixPtr_; + std::unique_ptr>> quantizationMatrixPtr_; public: - StochasticQuantization(std::unique_ptr> quantizationMatrixPtr) + StochasticQuantization(std::unique_ptr>> quantizationMatrixPtr) : quantizationMatrixPtr_(std::move(quantizationMatrixPtr)) {} void quantize(const CompleteIndexVector& outputIndices) override { @@ -34,7 +34,7 @@ namespace boosting { }; template - class StochasticQuantizationMatrix final : public IQuantizationMatrix { + class StochasticQuantizationMatrix final : public IQuantizationMatrix> { private: const View& view_; @@ -54,7 +54,7 @@ namespace boosting { // TODO Implement } - const typename IQuantizationMatrix::view_type& getView() const override { + const typename IQuantizationMatrix>::view_type& getView() const override { return matrix_.getView(); } diff --git a/cpp/subprojects/common/include/mlrl/common/data/matrix_bit_integer.hpp b/cpp/subprojects/common/include/mlrl/common/data/matrix_bit_integer.hpp index 5da5071a87..2b540bf341 100644 --- a/cpp/subprojects/common/include/mlrl/common/data/matrix_bit_integer.hpp +++ b/cpp/subprojects/common/include/mlrl/common/data/matrix_bit_integer.hpp @@ -8,7 +8,7 @@ /** * A two-dimensional matrix that stores integer values, each with a specific number of bits. */ -class IntegerBitMatrix final : public MatrixDecorator { +class IntegerBitMatrix final : public MatrixDecorator> { public: /** @@ -18,5 +18,6 @@ class IntegerBitMatrix final : public MatrixDecorator { * @param init True, if all elements in the matrix should be value-initialized, false otherwise */ IntegerBitMatrix(uint32 numRows, uint32 numCols, uint32 numBitsPerElements, bool init = false) - : MatrixDecorator(AllocatedBitMatrix(numRows, numCols, numBitsPerElements, init)) {} + : MatrixDecorator>( + AllocatedBitMatrix(numRows, numCols, numBitsPerElements, init)) {} }; diff --git a/cpp/subprojects/common/include/mlrl/common/data/view_matrix_bit.hpp b/cpp/subprojects/common/include/mlrl/common/data/view_matrix_bit.hpp index 0d6384b5da..9cf4f135b9 100644 --- a/cpp/subprojects/common/include/mlrl/common/data/view_matrix_bit.hpp +++ b/cpp/subprojects/common/include/mlrl/common/data/view_matrix_bit.hpp @@ -3,8 +3,8 @@ */ #pragma once -#include "mlrl/common/data/view_bit.hpp" #include "mlrl/common/data/view_matrix.hpp" +#include "mlrl/common/data/view_vector_bit.hpp" #include "mlrl/common/util/bit_functions.hpp" #include @@ -12,9 +12,16 @@ /** * A two-dimensional view that provides random access to integer values, each with a specific number of bits, stored in * a dense matrix of a specific size. + * + * @tparam T The type of the integer values, the view provides access to */ +template class BitMatrix : public BitView, public Matrix { + private: + + uint32 numElementsPerRow; + public: /** @@ -25,7 +32,8 @@ class BitMatrix : public BitView, * @param numBitsPerElement The number of bits per element in the view */ BitMatrix(uint32* array, uint32 numRows, uint32 numCols, uint32 numBitsPerElement) - : BitView(array, numRows * numCols, numBitsPerElement), Matrix(numRows, numCols) {} + : BitView(array, numRows * numCols, numBitsPerElement), Matrix(numRows, numCols), + numElementsPerRow(util::getBitArraySize(numCols, numBitsPerElement)) {} /** * @param other A const reference to an object of type `BitMatrix` that should be copied @@ -38,6 +46,38 @@ class BitMatrix : public BitView, BitMatrix(BitMatrix&& other) : BitView(std::move(other)), Matrix(std::move(other)) {} virtual ~BitMatrix() override {} + + /** + * Provides read-only access to an individual row in the view. + */ + typedef const BitVector const_row; + + /** + * Provides access to an individual row in the view and allows to modify it. + */ + typedef BitVector row; + + /** + * Creates and returns a view that provides read-only access to a specific row in the view. + * + * @param row The index of the row + * @return A `const_row` + */ + const_row operator[](uint32 row) const { + return BitVector(&BaseView::array[numElementsPerRow * row], numElementsPerRow, + BitView::numBitsPerElement); + } + + /** + * Creates and returns a view that provides access to a specific row in the view and allows to modify it. + * + * @param row The index of the row + * @return A `row` + */ + row operator[](uint32 row) { + return BitVector(&BaseView::array[numElementsPerRow * row], numElementsPerRow, + BitView::numBitsPerElement); + } }; /** @@ -82,5 +122,8 @@ class BitMatrixAllocator : public BitMatrix { /** * Allocates the memory, a `BitMatrix` provides access to. + * + * @tparam T The type of the integer values, the view provides access to */ -typedef BitMatrixAllocator AllocatedBitMatrix; +template +using AllocatedBitMatrix = BitMatrixAllocator>; From 7e97408a4f5df5e11a2774c89d0bc46e60ee7115 Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Mon, 19 Aug 2024 01:17:07 +0200 Subject: [PATCH 28/37] Remove obsolete functions. --- .../mlrl/boosting/statistics/quantization.hpp | 18 ------------------ .../boosting/statistics/quantization_no.cpp | 12 ------------ .../statistics/quantization_stochastic.cpp | 8 -------- 3 files changed, 38 deletions(-) diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization.hpp index d3ab1fdd2b..41323a3c28 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization.hpp @@ -68,24 +68,6 @@ namespace boosting { std::optional denseDecomposableMatrixVisitor, std::optional sparseDecomposableMatrixVisitor, std::optional denseNonDecomposableMatrixVisitor) = 0; - - /** - * Quantifies all statistics that corresonds to the available outputs. - * - * @param outputIndices A reference to an object of type `ICompleteIndexVector` that stores the indices of - * the output for which the statistics should be quantized - */ - // TODO Remove - virtual void quantize(const CompleteIndexVector& outputIndices) = 0; - - /** - * Quantifies all statistics that correspond to a certain subset of the outputs. - * - * @param outputIndices A reference to an object of type `IPartialIndexVector` that stores the indices of - * the output for which the statistics should be quantized - */ - // TODO Remove - virtual void quantize(const PartialIndexVector& outputIndices) = 0; }; /** diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_no.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_no.cpp index caa947701c..f7bf7eb4cf 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_no.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_no.cpp @@ -13,10 +13,6 @@ namespace boosting { std::unique_ptr>>> quantizationMatrixPtr) : quantizationMatrixPtr_(std::move(quantizationMatrixPtr)) {} - void quantize(const CompleteIndexVector& outputIndices) override {} - - void quantize(const PartialIndexVector& outputIndices) override {} - void visitQuantizationMatrix( std::optional denseDecomposableMatrixVisitor, std::optional sparseDecomposableMatrixVisitor, @@ -39,10 +35,6 @@ namespace boosting { std::unique_ptr>>> quantizationMatrixPtr) : quantizationMatrixPtr_(std::move(quantizationMatrixPtr)) {} - void quantize(const CompleteIndexVector& outputIndices) override {} - - void quantize(const PartialIndexVector& outputIndices) override {} - void visitQuantizationMatrix( std::optional denseDecomposableMatrixVisitor, std::optional sparseDecomposableMatrixVisitor, @@ -65,10 +57,6 @@ namespace boosting { std::unique_ptr> quantizationMatrixPtr) : quantizationMatrixPtr_(std::move(quantizationMatrixPtr)) {} - void quantize(const CompleteIndexVector& outputIndices) override {} - - void quantize(const PartialIndexVector& outputIndices) override {} - void visitQuantizationMatrix( std::optional denseDecomposableMatrixVisitor, std::optional sparseDecomposableMatrixVisitor, diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp index ad12a2d35b..975a551dca 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp @@ -16,14 +16,6 @@ namespace boosting { StochasticQuantization(std::unique_ptr>> quantizationMatrixPtr) : quantizationMatrixPtr_(std::move(quantizationMatrixPtr)) {} - void quantize(const CompleteIndexVector& outputIndices) override { - // TODO Implement - } - - void quantize(const PartialIndexVector& outputIndices) override { - // TODO Implement - } - void visitQuantizationMatrix( std::optional denseDecomposableMatrixVisitor, std::optional sparseDecomposableMatrixVisitor, From cb7d5d8788f13d04d8aa9734bdbc8a3e67ead457 Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Mon, 19 Aug 2024 01:30:14 +0200 Subject: [PATCH 29/37] Replace class IntegerBitMatrix with new class BitDecomposableStatisticView. --- .../data/view_statistic_decomposable_bit.hpp | 34 +++++++++++++++++++ cpp/subprojects/boosting/meson.build | 1 + .../data/view_statistic_decomposable_bit.cpp | 15 ++++++++ .../statistics/quantization_stochastic.cpp | 23 +++++++------ .../mlrl/common/data/matrix_bit_integer.hpp | 23 ------------- 5 files changed, 62 insertions(+), 34 deletions(-) create mode 100644 cpp/subprojects/boosting/include/mlrl/boosting/data/view_statistic_decomposable_bit.hpp create mode 100644 cpp/subprojects/boosting/src/mlrl/boosting/data/view_statistic_decomposable_bit.cpp delete mode 100644 cpp/subprojects/common/include/mlrl/common/data/matrix_bit_integer.hpp diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/data/view_statistic_decomposable_bit.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/data/view_statistic_decomposable_bit.hpp new file mode 100644 index 0000000000..1dfac07e16 --- /dev/null +++ b/cpp/subprojects/boosting/include/mlrl/boosting/data/view_statistic_decomposable_bit.hpp @@ -0,0 +1,34 @@ +/* + * @author Michael Rapp (michael.rapp.ml@gmail.com) + */ +#pragma once + +#include "mlrl/common/data/view_matrix_bit.hpp" +#include "mlrl/common/data/view_matrix_composite.hpp" + +namespace boosting { + + /** + * Implements row-wise read and write access to the gradients and Hessians that have been calculated using a + * decomposable loss function and are stored in pre-allocated bit matrices. + */ + class BitDecomposableStatisticView + : public CompositeMatrix, AllocatedBitMatrix> { + public: + + /** + * @param numRows The number of rows in the view + * @param numCols The number of columns in the view + * @param numBits The number of bits per statistic in the view + */ + BitDecomposableStatisticView(uint32 numRows, uint32 numCols, uint32 numBits); + + /** + * @param other A reference to an object of type `BitDecomposableStatisticView` that should be copied + */ + BitDecomposableStatisticView(BitDecomposableStatisticView&& other); + + virtual ~BitDecomposableStatisticView() override {} + }; + +} diff --git a/cpp/subprojects/boosting/meson.build b/cpp/subprojects/boosting/meson.build index 6752a9eccf..4b878820e7 100644 --- a/cpp/subprojects/boosting/meson.build +++ b/cpp/subprojects/boosting/meson.build @@ -10,6 +10,7 @@ source_files = [ 'src/mlrl/boosting/data/vector_statistic_decomposable_dense.cpp', 'src/mlrl/boosting/data/vector_statistic_decomposable_sparse.cpp', 'src/mlrl/boosting/data/vector_statistic_non_decomposable_dense.cpp', + 'src/mlrl/boosting/data/view_statistic_decomposable_bit.cpp', 'src/mlrl/boosting/data/view_statistic_non_decomposable_dense.cpp', 'src/mlrl/boosting/input/feature_binning_auto.cpp', 'src/mlrl/boosting/losses/loss_decomposable_logistic.cpp', diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/data/view_statistic_decomposable_bit.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/data/view_statistic_decomposable_bit.cpp new file mode 100644 index 0000000000..008606bc62 --- /dev/null +++ b/cpp/subprojects/boosting/src/mlrl/boosting/data/view_statistic_decomposable_bit.cpp @@ -0,0 +1,15 @@ +#include "mlrl/boosting/data/view_statistic_decomposable_bit.hpp" + +#include "mlrl/boosting/util/math.hpp" + +namespace boosting { + + BitDecomposableStatisticView::BitDecomposableStatisticView(uint32 numRows, uint32 numCols, uint32 numBits) + : CompositeMatrix, AllocatedBitMatrix>( + AllocatedBitMatrix(numRows, numCols, numBits), + AllocatedBitMatrix(numRows, util::triangularNumber(numCols), numBits), numRows, numCols) {} + + BitDecomposableStatisticView::BitDecomposableStatisticView(BitDecomposableStatisticView&& other) + : CompositeMatrix, AllocatedBitMatrix>(std::move(other)) {} + +} diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp index 975a551dca..fcd1d5a4d8 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp @@ -1,6 +1,6 @@ #include "mlrl/boosting/statistics/quantization_stochastic.hpp" -#include "mlrl/common/data/matrix_bit_integer.hpp" +#include "mlrl/boosting/data/view_statistic_decomposable_bit.hpp" #include "mlrl/common/util/validation.hpp" namespace boosting { @@ -9,11 +9,12 @@ namespace boosting { class StochasticQuantization final : public IQuantization { private: - std::unique_ptr>> quantizationMatrixPtr_; + std::unique_ptr> quantizationMatrixPtr_; public: - StochasticQuantization(std::unique_ptr>> quantizationMatrixPtr) + StochasticQuantization( + std::unique_ptr> quantizationMatrixPtr) : quantizationMatrixPtr_(std::move(quantizationMatrixPtr)) {} void visitQuantizationMatrix( @@ -26,17 +27,17 @@ namespace boosting { }; template - class StochasticQuantizationMatrix final : public IQuantizationMatrix> { + class StochasticQuantizationMatrix final : public IQuantizationMatrix { private: const View& view_; - IntegerBitMatrix matrix_; + BitDecomposableStatisticView quantizedView_; public: StochasticQuantizationMatrix(const View& view, uint32 numBits) - : view_(view), matrix_(view.numRows, view.numCols, numBits, true) {} + : view_(view), quantizedView_(view.numRows, view.numCols, numBits) {} void quantize(const CompleteIndexVector& outputIndices) override { // TODO Implement @@ -46,28 +47,28 @@ namespace boosting { // TODO Implement } - const typename IQuantizationMatrix>::view_type& getView() const override { - return matrix_.getView(); + const typename IQuantizationMatrix::view_type& getView() const override { + return quantizedView_; } std::unique_ptr create( const CContiguousView>& statisticMatrix) const override { return std::make_unique>>>( std::make_unique>>>( - statisticMatrix, matrix_.getView().numBitsPerElement)); + statisticMatrix, quantizedView_.firstView.numBitsPerElement)); } std::unique_ptr create(const SparseSetView>& statisticMatrix) const override { return std::make_unique>>>( std::make_unique>>>( - statisticMatrix, matrix_.getView().numBitsPerElement)); + statisticMatrix, quantizedView_.firstView.numBitsPerElement)); } std::unique_ptr create( const DenseNonDecomposableStatisticView& statisticMatrix) const override { return std::make_unique>( std::make_unique>( - statisticMatrix, matrix_.getView().numBitsPerElement)); + statisticMatrix, quantizedView_.firstView.numBitsPerElement)); } }; diff --git a/cpp/subprojects/common/include/mlrl/common/data/matrix_bit_integer.hpp b/cpp/subprojects/common/include/mlrl/common/data/matrix_bit_integer.hpp deleted file mode 100644 index 2b540bf341..0000000000 --- a/cpp/subprojects/common/include/mlrl/common/data/matrix_bit_integer.hpp +++ /dev/null @@ -1,23 +0,0 @@ -/* - * @author Michael Rapp (michael.rapp.ml@gmail.com) - */ -#pragma once - -#include "mlrl/common/data/view_matrix_bit.hpp" - -/** - * A two-dimensional matrix that stores integer values, each with a specific number of bits. - */ -class IntegerBitMatrix final : public MatrixDecorator> { - public: - - /** - * @param numRows The number of rows in the matrix - * @param numCols The number of columns in the matrix - * @param numBitsPerElement The number of bits per element in the matrix - * @param init True, if all elements in the matrix should be value-initialized, false otherwise - */ - IntegerBitMatrix(uint32 numRows, uint32 numCols, uint32 numBitsPerElements, bool init = false) - : MatrixDecorator>( - AllocatedBitMatrix(numRows, numCols, numBitsPerElements, init)) {} -}; From a1c2c5cca0bbacc540b6a9021f462beb6a3b5711 Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Mon, 19 Aug 2024 01:54:56 +0200 Subject: [PATCH 30/37] Add missing DLL exports. --- .../mlrl/boosting/data/view_statistic_decomposable_bit.hpp | 3 ++- .../common/include/mlrl/common/data/view_bit.hpp | 2 +- .../common/include/mlrl/common/data/view_matrix_bit.hpp | 6 +++--- .../common/include/mlrl/common/data/view_vector_bit.hpp | 4 ++-- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/data/view_statistic_decomposable_bit.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/data/view_statistic_decomposable_bit.hpp index 1dfac07e16..40828733b5 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/data/view_statistic_decomposable_bit.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/data/view_statistic_decomposable_bit.hpp @@ -3,6 +3,7 @@ */ #pragma once +#include "mlrl/boosting/util/dll_exports.hpp" #include "mlrl/common/data/view_matrix_bit.hpp" #include "mlrl/common/data/view_matrix_composite.hpp" @@ -12,7 +13,7 @@ namespace boosting { * Implements row-wise read and write access to the gradients and Hessians that have been calculated using a * decomposable loss function and are stored in pre-allocated bit matrices. */ - class BitDecomposableStatisticView + class MLRLBOOSTING_API BitDecomposableStatisticView : public CompositeMatrix, AllocatedBitMatrix> { public: diff --git a/cpp/subprojects/common/include/mlrl/common/data/view_bit.hpp b/cpp/subprojects/common/include/mlrl/common/data/view_bit.hpp index a527f01d44..994e031b02 100644 --- a/cpp/subprojects/common/include/mlrl/common/data/view_bit.hpp +++ b/cpp/subprojects/common/include/mlrl/common/data/view_bit.hpp @@ -11,7 +11,7 @@ * A view that provides random access to integer values, each with a specific number of bits, stored in a pre-allocated * array of a specific size. */ -class BitView : public BaseView { +class MLRLCOMMON_API BitView : public BaseView { public: /** diff --git a/cpp/subprojects/common/include/mlrl/common/data/view_matrix_bit.hpp b/cpp/subprojects/common/include/mlrl/common/data/view_matrix_bit.hpp index 9cf4f135b9..96b7063e77 100644 --- a/cpp/subprojects/common/include/mlrl/common/data/view_matrix_bit.hpp +++ b/cpp/subprojects/common/include/mlrl/common/data/view_matrix_bit.hpp @@ -16,8 +16,8 @@ * @tparam T The type of the integer values, the view provides access to */ template -class BitMatrix : public BitView, - public Matrix { +class MLRLCOMMON_API BitMatrix : public BitView, + public Matrix { private: uint32 numElementsPerRow; @@ -86,7 +86,7 @@ class BitMatrix : public BitView, * @tparam BitMatrix The type of the bit matrix */ template -class BitMatrixAllocator : public BitMatrix { +class MLRLCOMMON_API BitMatrixAllocator : public BitMatrix { public: /** diff --git a/cpp/subprojects/common/include/mlrl/common/data/view_vector_bit.hpp b/cpp/subprojects/common/include/mlrl/common/data/view_vector_bit.hpp index f778fd4002..8a0e170903 100644 --- a/cpp/subprojects/common/include/mlrl/common/data/view_vector_bit.hpp +++ b/cpp/subprojects/common/include/mlrl/common/data/view_vector_bit.hpp @@ -16,7 +16,7 @@ * @param T The type of the integer values, the view provides access to */ template -class BitVector : public BitView { +class MLRLCOMMON_API BitVector : public BitView { private: static inline constexpr uint32 NUM_BITS = util::bits(); @@ -119,7 +119,7 @@ class BitVector : public BitView { * @tparam BitVector The type of the bit vector */ template -class BitVectorAllocator : public BitVector { +class MLRLCOMMON_API BitVectorAllocator : public BitVector { public: /** From 457e7db8b065f09af36ff20990d7671055f76802 Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Mon, 19 Aug 2024 15:28:58 +0200 Subject: [PATCH 31/37] Add visitor for handling views of type BitDecomposableMatrixVisitor to class IQuantization. --- .../mlrl/boosting/statistics/quantization.hpp | 12 ++++++++++++ .../src/mlrl/boosting/statistics/quantization_no.cpp | 3 +++ .../boosting/statistics/quantization_stochastic.cpp | 5 ++++- .../statistics_provider_decomposable_dense.cpp | 7 ++++++- .../statistics_provider_decomposable_sparse.cpp | 2 +- .../statistics_provider_non_decomposable_dense.cpp | 10 ++++++++-- 6 files changed, 34 insertions(+), 5 deletions(-) diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization.hpp index 41323a3c28..a74154b824 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization.hpp @@ -3,6 +3,7 @@ */ #pragma once +#include "mlrl/boosting/data/view_statistic_decomposable_bit.hpp" #include "mlrl/boosting/data/view_statistic_non_decomposable_dense.hpp" #include "mlrl/common/data/tuple.hpp" #include "mlrl/common/data/view_matrix_c_contiguous.hpp" @@ -43,6 +44,13 @@ namespace boosting { typedef std::function>>>&)> SparseDecomposableMatrixVisitor; + /** + * A visitor function for handling quantization matrices that are backed by a view of the type + * `BitDecomposableStatisticView`. + */ + typedef std::function>&)> + BitDecomposableMatrixVisitor; + /** * A visitor function for handling quantization matrices that are backed by a view of the type * `DenseNonDecomposableStatisticView`. @@ -57,6 +65,9 @@ namespace boosting { * @param denseDecomposableMatrixVisitor An optional visitor function for handling quantization matrices * that are backed by a view of the type * `CContiguousView>` + * @param bitDecomposableMatrixVisitor An optional visitor function for handling quantization matrices + * that are backed by a view of the type + * `BitDecomposableStatisticView` * @param sparseDecomposableMatrixVisitor An optional visitor function for handling quantization matrices * that are backed by a view of the type * `SparseSetView>` @@ -66,6 +77,7 @@ namespace boosting { */ virtual void visitQuantizationMatrix( std::optional denseDecomposableMatrixVisitor, + std::optional bitDecomposableMatrixVisitor, std::optional sparseDecomposableMatrixVisitor, std::optional denseNonDecomposableMatrixVisitor) = 0; }; diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_no.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_no.cpp index f7bf7eb4cf..61958c6e24 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_no.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_no.cpp @@ -15,6 +15,7 @@ namespace boosting { void visitQuantizationMatrix( std::optional denseDecomposableMatrixVisitor, + std::optional bitDecomposableMatrixVisitor, std::optional sparseDecomposableMatrixVisitor, std::optional denseNonDecomposableMatrixVisitor) override { @@ -37,6 +38,7 @@ namespace boosting { void visitQuantizationMatrix( std::optional denseDecomposableMatrixVisitor, + std::optional bitDecomposableMatrixVisitor, std::optional sparseDecomposableMatrixVisitor, std::optional denseNonDecomposableMatrixVisitor) override { @@ -59,6 +61,7 @@ namespace boosting { void visitQuantizationMatrix( std::optional denseDecomposableMatrixVisitor, + std::optional bitDecomposableMatrixVisitor, std::optional sparseDecomposableMatrixVisitor, std::optional denseNonDecomposableMatrixVisitor) override { diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp index fcd1d5a4d8..7c07994485 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp @@ -19,10 +19,13 @@ namespace boosting { void visitQuantizationMatrix( std::optional denseDecomposableMatrixVisitor, + std::optional bitDecomposableMatrixVisitor, std::optional sparseDecomposableMatrixVisitor, std::optional denseNonDecomposableMatrixVisitor) override { - // TODO Implement + if (bitDecomposableMatrixVisitor) { + (*bitDecomposableMatrixVisitor)(quantizationMatrixPtr_); + } } }; diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp index 047d455f1a..01703c4843 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp @@ -41,7 +41,12 @@ namespace boosting { std::move(quantizationMatrixPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)); }; - quantizationPtr->visitQuantizationMatrix(denseDecomposableMatrixVisitor, {}, {}); + auto bitDecomposableMatrixVisitor = + [&](std::unique_ptr>& quantizationMatrixPtr) { + // TODO Implement + throw std::runtime_error("not implemented"); + }; + quantizationPtr->visitQuantizationMatrix(denseDecomposableMatrixVisitor, bitDecomposableMatrixVisitor, {}, {}); return statisticsPtr; } diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_sparse.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_sparse.cpp index 273e08c7a3..491e8ba44f 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_sparse.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_sparse.cpp @@ -124,7 +124,7 @@ namespace boosting { std::move(quantizationMatrixPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)); }; - quantizationPtr->visitQuantizationMatrix({}, sparseDecomposableMatrixVisitor, {}); + quantizationPtr->visitQuantizationMatrix({}, {}, sparseDecomposableMatrixVisitor, {}); return statisticsPtr; } diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp index 1ad2e3eecf..14acfac5d0 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp @@ -155,7 +155,13 @@ namespace boosting { std::move(this->evaluationMeasurePtr_), ruleEvaluationFactory, this->outputMatrix_, std::move(decomposableStatisticMatrixPtr), std::move(this->scoreMatrixPtr_)); }; - quantizationPtr->visitQuantizationMatrix(denseDecomposableMatrixVisitor, {}, {}); + auto bitDecomposableMatrixVisitor = + [&](std::unique_ptr>& quantizationMatrixPtr) { + // TODO Implement + throw std::runtime_error("not implemented"); + }; + quantizationPtr->visitQuantizationMatrix(denseDecomposableMatrixVisitor, bitDecomposableMatrixVisitor, + {}, {}); return statisticsPtr; } }; @@ -198,7 +204,7 @@ namespace boosting { std::move(quantizationMatrixPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)); }; - quantizationPtr->visitQuantizationMatrix({}, {}, denseNonDecomposableMatrixVisitor); + quantizationPtr->visitQuantizationMatrix({}, {}, {}, denseNonDecomposableMatrixVisitor); return statisticsPtr; } From 1171d48c0dd6a7d8eb91350d2bb9daf2127201fd Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Mon, 19 Aug 2024 16:14:43 +0200 Subject: [PATCH 32/37] Add class BitDecomposableStatisticVector. --- .../vector_statistic_decomposable_bit.hpp | 183 ++++++++++++++++++ cpp/subprojects/boosting/meson.build | 1 + .../vector_statistic_decomposable_bit.cpp | 141 ++++++++++++++ .../mlrl/common/data/view_vector_bit.hpp | 64 +++++- 4 files changed, 385 insertions(+), 4 deletions(-) create mode 100644 cpp/subprojects/boosting/include/mlrl/boosting/data/vector_statistic_decomposable_bit.hpp create mode 100644 cpp/subprojects/boosting/src/mlrl/boosting/data/vector_statistic_decomposable_bit.cpp diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/data/vector_statistic_decomposable_bit.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/data/vector_statistic_decomposable_bit.hpp new file mode 100644 index 0000000000..f9d90b75b2 --- /dev/null +++ b/cpp/subprojects/boosting/include/mlrl/boosting/data/vector_statistic_decomposable_bit.hpp @@ -0,0 +1,183 @@ +/* + * @author Michael Rapp (michael.rapp.ml@gmail.com) + */ +#pragma once + +#include "mlrl/boosting/data/view_statistic_decomposable_bit.hpp" +#include "mlrl/common/data/view_composite.hpp" +#include "mlrl/common/indices/index_vector_complete.hpp" +#include "mlrl/common/indices/index_vector_partial.hpp" + +namespace boosting { + + /** + * An one-dimensional vector that stores aggregated gradients and Hessians that have been calculated using a + * decomposable loss function in a bit vector. For each element in the vector a single gradient and Hessian is + * stored. + */ + class BitDecomposableStatisticVector final + : public CompositeView, AllocatedBitVector> { + public: + + /** + * @param numElements The number of gradients and Hessians in the vector + * @param numBitsPerElement The number of bits per element in the bit vector + * @param init True, if all gradients and Hessians in the vector should be initialized with + * zero, false otherwise + */ + BitDecomposableStatisticVector(uint32 numElements, uint32 numBitsPerElement, bool init = false); + + /** + * @param other A reference to an object of type `BitDecomposableStatisticVector` to be copied + */ + BitDecomposableStatisticVector(const BitDecomposableStatisticVector& other); + + /** + * Returns the number of gradients and Hessians in the vector. + * + * @return The number of gradients and Hessians + */ + uint32 getNumElements() const; + + /** + * Returns the number of bits per gradient or Hessian in the vector. + * + * @return The number of bits per gradient or Hessian + */ + uint32 getNumBitsPerElement() const; + + /** + * Adds all gradients and Hessians in another vector to this vector. + * + * @param vector A reference to an object of type `BitDecomposableStatisticVector` that stores the gradients + * and Hessians to be added to this vector + */ + void add(const BitDecomposableStatisticVector& vector); + + /** + * Adds all gradients and Hessians in a single row of a `BitDecomposableStatisticView` to this vector. + * + * @param view A reference to an object of type `BitDecomposableStatisticView` that stores the gradients + * and Hessians to be added to this vector + * @param row The index of the row to be added to this vector + */ + void add(const BitDecomposableStatisticView& view, uint32 row); + + /** + * Adds all gradients and Hessians in a single row of a `CContiguousView` to this vector. The gradients and + * Hessians to be added are multiplied by a specific weight. + * + * @param view A reference to an object of type `CContiguousView` that stores the gradients and + * Hessians to be added to this vector + * @param row The index of the row to be added to this vector + * @param weight The weight, the gradients and Hessians should be multiplied by + */ + void add(const BitDecomposableStatisticView& view, uint32 row, float64 weight); + + /** + * Removes all gradients and Hessians in a single row of a `CContiguousView` from this vector. + * + * @param view A reference to an object of type `CContiguousView` that stores the gradients and Hessians to + * be removed from this vector + * @param row The index of the row to be removed from this vector + */ + void remove(const BitDecomposableStatisticView& view, uint32 row); + + /** + * Removes all gradients and Hessians in a single row of a `CContiguousView` from this vector. The gradients + * and Hessians to be removed are multiplied by a specific weight. + * + * @param view A reference to an object of type `CContiguousView` that stores the gradients and + * Hessians to be removed from this vector + * @param row The index of the row to be removed from this vector + * @param weight The weight, the gradients and Hessians should be multiplied by + */ + void remove(const BitDecomposableStatisticView& view, uint32 row, float64 weight); + + /** + * Adds certain gradients and Hessians in a single row of a `CContiguousView`, whose positions are given as + * a `CompleteIndexVector`, to this vector. + * + * @param view A reference to an object of type `CContiguousView` that stores the gradients and + * Hessians to be added to this vector + * @param row The index of the row to be added to this vector + * @param indices A reference to a `CompleteIndexVector' that provides access to the indices + */ + void addToSubset(const BitDecomposableStatisticView& view, uint32 row, const CompleteIndexVector& indices); + + /** + * Adds certain gradients and Hessians in single row of a `CContiguousView`, whose positions are given as a + * `PartialIndexVector`, to this vector. + * + * @param view A reference to an object of type `CContiguousView` that stores the gradients and + * Hessians to be added to this vector + * @param row The index of the row to be added to this vector + * @param indices A reference to a `PartialIndexVector' that provides access to the indices + */ + void addToSubset(const BitDecomposableStatisticView& view, uint32 row, const PartialIndexVector& indices); + + /** + * Adds certain gradients and Hessians in a single row of a `CContiguousView`, whose positions are given as + * a `CompleteIndexVector`, to this vector. The gradients and Hessians to be added are multiplied by a + * specific weight. + * + * @param view A reference to an object of type `CContiguousView` that stores the gradients and + * Hessians to be added to this vector + * @param row The index of the row to be added to this vector + * @param indices A reference to a `CompleteIndexVector' that provides access to the indices + * @param weight The weight, the gradients and Hessians should be multiplied by + */ + void addToSubset(const BitDecomposableStatisticView& view, uint32 row, const CompleteIndexVector& indices, + float64 weight); + + /** + * Adds certain gradients and Hessians in single row of a `CContiguousView`, whose positions are given as a + * `PartialIndexVector`, to this vector. The gradients and Hessians to be added are multiplied by a specific + * weight. + * + * @param view A reference to an object of type `CContiguousView` that stores the gradients and + * Hessians to be added to this vector + * @param row The index of the row to be added to this vector + * @param indices A reference to a `PartialIndexVector' that provides access to the indices + * @param weight The weight, the gradients and Hessians should be multiplied by + */ + void addToSubset(const BitDecomposableStatisticView& view, uint32 row, const PartialIndexVector& indices, + float64 weight); + + /** + * Sets the gradients and Hessians in this vector to the difference `first - second` between the gradients + * and Hessians in two other vectors, considering only the gradients and Hessians in the first vector that + * correspond to the positions provided by a `CompleteIndexVector`. + * + * @param first A reference to an object of type `BitDecomposableStatisticVector` that stores the + * gradients and Hessians in the first vector + * @param firstIndices A reference to an object of type `CompleteIndexVector` that provides access to the + * indices + * @param second A reference to an object of type `BitDecomposableStatisticVector` that stores the + * gradients and Hessians in the second vector + */ + void difference(const BitDecomposableStatisticVector& first, const CompleteIndexVector& firstIndices, + const BitDecomposableStatisticVector& second); + + /** + * Sets the gradients and Hessians in this vector to the difference `first - second` between the gradients + * and Hessians in two other vectors, considering only the gradients and Hessians in the first vector that + * correspond to the positions provided by a `PartialIndexVector`. + * + * @param first A reference to an object of type `BitDecomposableStatisticVector` that stores the + * gradients and Hessians in the first vector + * @param firstIndices A reference to an object of type `PartialIndexVector` that provides access to the + * indices + * @param second A reference to an object of type `BitDecomposableStatisticVector` that stores the + * gradients and Hessians in the second vector + */ + void difference(const BitDecomposableStatisticVector& first, const PartialIndexVector& firstIndices, + const BitDecomposableStatisticVector& second); + + /** + * Sets all gradients and Hessians stored in the vector to zero. + */ + void clear(); + }; + +} diff --git a/cpp/subprojects/boosting/meson.build b/cpp/subprojects/boosting/meson.build index 4b878820e7..d43affcb36 100644 --- a/cpp/subprojects/boosting/meson.build +++ b/cpp/subprojects/boosting/meson.build @@ -7,6 +7,7 @@ source_files = [ 'src/mlrl/boosting/binning/label_binning_no.cpp', 'src/mlrl/boosting/data/matrix_c_contiguous_numeric.cpp', 'src/mlrl/boosting/data/matrix_sparse_set_numeric.cpp', + 'src/mlrl/boosting/data/vector_statistic_decomposable_bit.cpp', 'src/mlrl/boosting/data/vector_statistic_decomposable_dense.cpp', 'src/mlrl/boosting/data/vector_statistic_decomposable_sparse.cpp', 'src/mlrl/boosting/data/vector_statistic_non_decomposable_dense.cpp', diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/data/vector_statistic_decomposable_bit.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/data/vector_statistic_decomposable_bit.cpp new file mode 100644 index 0000000000..257563694f --- /dev/null +++ b/cpp/subprojects/boosting/src/mlrl/boosting/data/vector_statistic_decomposable_bit.cpp @@ -0,0 +1,141 @@ +#include "mlrl/boosting/data/vector_statistic_decomposable_bit.hpp" + +namespace boosting { + + static inline void copyInternally(const BitVector& firstView, BitVector& secondView) { + typename BitVector::const_iterator begin = firstView.cbegin(); + uint32 arraySize = firstView.cend() - begin; + util::copyView(begin, secondView.begin(), arraySize); + } + + static inline void addInternally(BitVector& firstView, const BitVector& secondView) { + typename BitVector::iterator begin = firstView.begin(); + uint32 arraySize = firstView.end() - begin; + util::addToView(begin, secondView.cbegin(), arraySize); + } + + static inline void addInternally(BitVector& firstView, const BitVector& secondView, + const PartialIndexVector& indices) { + uint32 numIndices = indices.getNumElements(); + + for (uint32 i = 0; i < numIndices; i++) { + uint32 index = indices[i]; + uint32 value = secondView[index]; + firstView.set(i, value); + } + } + + static inline void removeInternally(BitVector& firstView, const BitVector& secondView) { + typename BitVector::iterator begin = firstView.begin(); + uint32 arraySize = firstView.end() - begin; + util::removeFromView(begin, secondView.cbegin(), arraySize); + } + + static inline void differenceInternally(BitVector& firstView, const BitVector& secondView, + const BitVector& thirdView) { + typename BitVector::iterator begin = firstView.begin(); + uint32 arraySize = firstView.end() - begin; + util::setViewToDifference(begin, secondView.cbegin(), thirdView.cbegin(), arraySize); + } + + static inline void differenceInternally(BitVector& firstView, const BitVector& secondView, + const PartialIndexVector& indices, const BitVector& thirdView) { + uint32 numIndices = indices.getNumElements(); + + for (uint32 i = 0; i < numIndices; i++) { + uint32 index = indices[i]; + uint32 firstValue = secondView[index]; + uint32 secondValue = thirdView[i]; + firstView.set(i, firstValue - secondValue); + } + } + + BitDecomposableStatisticVector::BitDecomposableStatisticVector(uint32 numElements, uint32 numBitsPerElement, + bool init) + : CompositeView, AllocatedBitVector>( + AllocatedBitVector(numElements, numBitsPerElement, init), + AllocatedBitVector(numElements, numBitsPerElement, init)) {} + + BitDecomposableStatisticVector::BitDecomposableStatisticVector(const BitDecomposableStatisticVector& other) + : BitDecomposableStatisticVector(other.getNumElements(), other.getNumBitsPerElement()) { + copyInternally(other.firstView, this->firstView); + copyInternally(other.secondView, this->secondView); + } + + uint32 BitDecomposableStatisticVector::getNumElements() const { + return this->firstView.numElements; + } + + uint32 BitDecomposableStatisticVector::getNumBitsPerElement() const { + return this->firstView.numBitsPerElement; + } + + void BitDecomposableStatisticVector::add(const BitDecomposableStatisticVector& vector) { + addInternally(this->firstView, vector.firstView); + addInternally(this->secondView, vector.secondView); + } + + void BitDecomposableStatisticVector::add(const BitDecomposableStatisticView& view, uint32 row) { + addInternally(this->firstView, view.firstView[row]); + addInternally(this->secondView, view.secondView[row]); + } + + void BitDecomposableStatisticVector::add(const BitDecomposableStatisticView& view, uint32 row, float64 weight) { + // TODO Implement + throw std::runtime_error("not implemented"); + } + + void BitDecomposableStatisticVector::remove(const BitDecomposableStatisticView& view, uint32 row) { + removeInternally(this->firstView, view.firstView[row]); + removeInternally(this->secondView, view.secondView[row]); + } + + void BitDecomposableStatisticVector::remove(const BitDecomposableStatisticView& view, uint32 row, float64 weight) { + // TODO Implement + throw std::runtime_error("not implemented"); + } + + void BitDecomposableStatisticVector::addToSubset(const BitDecomposableStatisticView& view, uint32 row, + const CompleteIndexVector& indices) { + addInternally(this->firstView, view.firstView[row]); + addInternally(this->secondView, view.secondView[row]); + } + + void BitDecomposableStatisticVector::addToSubset(const BitDecomposableStatisticView& view, uint32 row, + const PartialIndexVector& indices) { + addInternally(this->firstView, view.firstView[row], indices); + addInternally(this->secondView, view.secondView[row], indices); + } + + void BitDecomposableStatisticVector::addToSubset(const BitDecomposableStatisticView& view, uint32 row, + const CompleteIndexVector& indices, float64 weight) { + // TODO Implement + throw std::runtime_error("not implemented"); + } + + void BitDecomposableStatisticVector::addToSubset(const BitDecomposableStatisticView& view, uint32 row, + const PartialIndexVector& indices, float64 weight) { + // TODO Implement + throw std::runtime_error("not implemented"); + } + + void BitDecomposableStatisticVector::difference(const BitDecomposableStatisticVector& first, + const CompleteIndexVector& firstIndices, + const BitDecomposableStatisticVector& second) { + differenceInternally(this->firstView, first.firstView, second.firstView); + differenceInternally(this->secondView, first.secondView, second.secondView); + } + + void BitDecomposableStatisticVector::difference(const BitDecomposableStatisticVector& first, + const PartialIndexVector& firstIndices, + const BitDecomposableStatisticVector& second) { + differenceInternally(this->firstView, first.firstView, firstIndices, second.firstView); + differenceInternally(this->secondView, first.secondView, firstIndices, second.secondView); + } + + void BitDecomposableStatisticVector::clear() { + this->firstView.clear(); + this->secondView.clear(); + } + +} diff --git a/cpp/subprojects/common/include/mlrl/common/data/view_vector_bit.hpp b/cpp/subprojects/common/include/mlrl/common/data/view_vector_bit.hpp index 8a0e170903..f5d2bf034e 100644 --- a/cpp/subprojects/common/include/mlrl/common/data/view_vector_bit.hpp +++ b/cpp/subprojects/common/include/mlrl/common/data/view_vector_bit.hpp @@ -77,11 +77,49 @@ class MLRLCOMMON_API BitVector : public BitView { typedef T type; /** - * Sets all values stored in the bit vector to zero. + * An iterator that provides read-only access to the view's underlying array. */ - void clear() { - util::setViewToZeros(BaseView::array, - util::getBitArraySize(numElements, BitView::numBitsPerElement)); + typedef const typename BaseView::value_type* const_iterator; + + /** + * An iterator that provides access to the view's underlying array and allows to modify it. + */ + typedef typename BaseView::value_type* iterator; + + /** + * Returns a `const_iterator` to the beginning of the view's underlying array. + * + * @return A `const_iterator` to the beginning + */ + const_iterator cbegin() const { + return BaseView::array; + } + + /** + * Returns a `const_iterator` to the end of the view's underlying array. + * + * @return A `const_iterator` to the end + */ + const_iterator cend() const { + return &BaseView::array[util::getBitArraySize(numElements, BitView::numBitsPerElement)]; + } + + /** + * Returns an `iterator` to the beginning of the view's underlying array. + * + * @return An `iterator` to the beginning + */ + iterator begin() { + return BaseView::array; + } + + /** + * Returns an `iterator` to the end of the view's underlying array. + * + * @return An `iterator` to the end + */ + iterator end() { + return &BaseView::array[util::getBitArraySize(numElements, BitView::numBitsPerElement)]; } /** @@ -111,6 +149,15 @@ class MLRLCOMMON_API BitVector : public BitView { BaseView::array[offset] &= ~bitMask; BaseView::array[offset] |= value << numShifts; } + + /** + * Sets all values stored in the bit vector to zero. + */ + void clear() { + iterator begin = this->begin(); + uint32 arraySize = util::getBitArraySize(numElements, BitView::numBitsPerElement); + util::setViewToZeros(begin, arraySize); + } }; /** @@ -175,6 +222,15 @@ class BitVectorDecorator : public BitVector { virtual ~BitVectorDecorator() override {} + /** + * Returns the number of bits per element in the bit vector. + * + * @return The number of bits per element + */ + uint32 getNumBitsPerElement() const { + return this->view.numBitsPerElement; + } + /** * Returns the value of the element at a specific position. * From 6d300f3aca6987f2fbf11f89670eaab7a43b4adc Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Mon, 19 Aug 2024 18:24:30 +0200 Subject: [PATCH 33/37] Add create functions that accept arguments of type BitDecomposableStatisticVector to the class IDecomposableRuleEvaluationFactory. --- .../rule_evaluation_decomposable.hpp | 31 +++++++++++++++++++ .../rule_evaluation_decomposable_complete.hpp | 8 +++++ ...valuation_decomposable_complete_binned.hpp | 8 +++++ ...valuation_decomposable_partial_dynamic.hpp | 8 +++++ ...on_decomposable_partial_dynamic_binned.hpp | 8 +++++ ..._evaluation_decomposable_partial_fixed.hpp | 8 +++++ ...tion_decomposable_partial_fixed_binned.hpp | 8 +++++ .../rule_evaluation_decomposable_single.hpp | 8 +++++ .../rule_evaluation_decomposable_complete.cpp | 12 +++++++ ...valuation_decomposable_complete_binned.cpp | 14 +++++++++ ...valuation_decomposable_partial_dynamic.cpp | 14 +++++++++ ...on_decomposable_partial_dynamic_binned.cpp | 14 +++++++++ ..._evaluation_decomposable_partial_fixed.cpp | 14 +++++++++ ...tion_decomposable_partial_fixed_binned.cpp | 14 +++++++++ .../rule_evaluation_decomposable_single.cpp | 14 +++++++++ 15 files changed, 183 insertions(+) diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable.hpp index a419a37f44..f6d49b8ea4 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable.hpp @@ -3,6 +3,7 @@ */ #pragma once +#include "mlrl/boosting/data/vector_statistic_decomposable_bit.hpp" #include "mlrl/boosting/data/vector_statistic_decomposable_dense.hpp" #include "mlrl/boosting/rule_evaluation/rule_evaluation.hpp" #include "mlrl/common/indices/index_vector_complete.hpp" @@ -52,6 +53,36 @@ namespace boosting { */ virtual std::unique_ptr> create( const DenseDecomposableStatisticVector& statisticVector, const PartialIndexVector& indexVector) const = 0; + + /** + * Creates a new instance of the class `IRuleEvaluation` that allows to calculate the predictions of rules + * that predict for all available outputs, based on the gradients and Hessians that are stored by a + * `BitDecomposableStatisticVector`. + * + * @param statisticVector A reference to an object of type `BitDecomposableStatisticVector`. This vector + * is only used to identify the function that is able to deal with this particular + * type of vector via function overloading + * @param indexVector A reference to an object of the type `CompleteIndexVector` that provides access + * to the indices of the outputs for which the rules may predict + * @return An unique pointer to an object of type `IRuleEvaluation` that has been created + */ + virtual std::unique_ptr> create( + const BitDecomposableStatisticVector& statisticVector, const CompleteIndexVector& indexVector) const = 0; + + /** + * Creates a new instance of the class `IRuleEvaluation` that allows to calculate the predictions of rules + * that predict for a subset of the available outputs, based on the gradients and Hessians that are stored + * by a `BitDecomposableStatisticVector`. + * + * @param statisticVector A reference to an object of type `BitDecomposableStatisticVector`. This vector + * is only used to identify the function that is able to deal with this particular + * type of vector via function overloading + * @param indexVector A reference to an object of the type `PartialIndexVector` that provides access + * to the indices of the outputs for which the rules may predict + * @return An unique pointer to an object of type `IRuleEvaluation` that has been created + */ + virtual std::unique_ptr> create( + const BitDecomposableStatisticVector& statisticVector, const PartialIndexVector& indexVector) const = 0; }; } diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_complete.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_complete.hpp index ce978d785b..2f77b0f73a 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_complete.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_complete.hpp @@ -37,6 +37,14 @@ namespace boosting { std::unique_ptr> create( const DenseDecomposableStatisticVector& statisticVector, const PartialIndexVector& indexVector) const override; + + std::unique_ptr> create( + const BitDecomposableStatisticVector& statisticVector, + const CompleteIndexVector& indexVector) const override; + + std::unique_ptr> create( + const BitDecomposableStatisticVector& statisticVector, + const PartialIndexVector& indexVector) const override; }; } diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_complete_binned.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_complete_binned.hpp index 3070877d6d..c80b0ce88e 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_complete_binned.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_complete_binned.hpp @@ -44,6 +44,14 @@ namespace boosting { std::unique_ptr> create( const DenseDecomposableStatisticVector& statisticVector, const PartialIndexVector& indexVector) const override; + + std::unique_ptr> create( + const BitDecomposableStatisticVector& statisticVector, + const CompleteIndexVector& indexVector) const override; + + std::unique_ptr> create( + const BitDecomposableStatisticVector& statisticVector, + const PartialIndexVector& indexVector) const override; }; } diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_partial_dynamic.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_partial_dynamic.hpp index 0349b71afe..b167404dc9 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_partial_dynamic.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_partial_dynamic.hpp @@ -55,6 +55,14 @@ namespace boosting { const DenseDecomposableStatisticVector& statisticVector, const PartialIndexVector& indexVector) const override; + std::unique_ptr> create( + const BitDecomposableStatisticVector& statisticVector, + const CompleteIndexVector& indexVector) const override; + + std::unique_ptr> create( + const BitDecomposableStatisticVector& statisticVector, + const PartialIndexVector& indexVector) const override; + std::unique_ptr> create( const SparseDecomposableStatisticVector& statisticVector, const CompleteIndexVector& indexVector) const override; diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_partial_dynamic_binned.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_partial_dynamic_binned.hpp index d9e2b7986e..eabe812ffa 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_partial_dynamic_binned.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_partial_dynamic_binned.hpp @@ -62,6 +62,14 @@ namespace boosting { const DenseDecomposableStatisticVector& statisticVector, const PartialIndexVector& indexVector) const override; + std::unique_ptr> create( + const BitDecomposableStatisticVector& statisticVector, + const CompleteIndexVector& indexVector) const override; + + std::unique_ptr> create( + const BitDecomposableStatisticVector& statisticVector, + const PartialIndexVector& indexVector) const override; + std::unique_ptr> create( const SparseDecomposableStatisticVector& statisticVector, const CompleteIndexVector& indexVector) const override; diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_partial_fixed.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_partial_fixed.hpp index b18cb78db4..67df86d949 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_partial_fixed.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_partial_fixed.hpp @@ -55,6 +55,14 @@ namespace boosting { const DenseDecomposableStatisticVector& statisticVector, const PartialIndexVector& indexVector) const override; + std::unique_ptr> create( + const BitDecomposableStatisticVector& statisticVector, + const CompleteIndexVector& indexVector) const override; + + std::unique_ptr> create( + const BitDecomposableStatisticVector& statisticVector, + const PartialIndexVector& indexVector) const override; + std::unique_ptr> create( const SparseDecomposableStatisticVector& statisticVector, const CompleteIndexVector& indexVector) const override; diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_partial_fixed_binned.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_partial_fixed_binned.hpp index c378b69883..2a78325e09 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_partial_fixed_binned.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_partial_fixed_binned.hpp @@ -61,6 +61,14 @@ namespace boosting { const DenseDecomposableStatisticVector& statisticVector, const PartialIndexVector& indexVector) const override; + std::unique_ptr> create( + const BitDecomposableStatisticVector& statisticVector, + const CompleteIndexVector& indexVector) const override; + + std::unique_ptr> create( + const BitDecomposableStatisticVector& statisticVector, + const PartialIndexVector& indexVector) const override; + std::unique_ptr> create( const SparseDecomposableStatisticVector& statisticVector, const CompleteIndexVector& indexVector) const override; diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_single.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_single.hpp index 8b8ea2466d..4b7bd42dc8 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_single.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_single.hpp @@ -39,6 +39,14 @@ namespace boosting { const DenseDecomposableStatisticVector& statisticVector, const PartialIndexVector& indexVector) const override; + std::unique_ptr> create( + const BitDecomposableStatisticVector& statisticVector, + const CompleteIndexVector& indexVector) const override; + + std::unique_ptr> create( + const BitDecomposableStatisticVector& statisticVector, + const PartialIndexVector& indexVector) const override; + std::unique_ptr> create( const SparseDecomposableStatisticVector& statisticVector, const CompleteIndexVector& indexVector) const override; diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_complete.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_complete.cpp index 17635cda40..54a1c6286f 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_complete.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_complete.cpp @@ -24,4 +24,16 @@ namespace boosting { indexVector, l1RegularizationWeight_, l2RegularizationWeight_); } + std::unique_ptr> DecomposableCompleteRuleEvaluationFactory::create( + const BitDecomposableStatisticVector& statisticVector, const CompleteIndexVector& indexVector) const { + // TODO Implement + return nullptr; + } + + std::unique_ptr> DecomposableCompleteRuleEvaluationFactory::create( + const BitDecomposableStatisticVector& statisticVector, const PartialIndexVector& indexVector) const { + // TODO Implement + return nullptr; + } + } diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_complete_binned.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_complete_binned.cpp index b1baacec5e..0737a1480f 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_complete_binned.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_complete_binned.cpp @@ -28,4 +28,18 @@ namespace boosting { indexVector, l1RegularizationWeight_, l2RegularizationWeight_, std::move(labelBinningPtr)); } + std::unique_ptr> + DecomposableCompleteBinnedRuleEvaluationFactory::create(const BitDecomposableStatisticVector& statisticVector, + const CompleteIndexVector& indexVector) const { + // TODO Implement + return nullptr; + } + + std::unique_ptr> + DecomposableCompleteBinnedRuleEvaluationFactory::create(const BitDecomposableStatisticVector& statisticVector, + const PartialIndexVector& indexVector) const { + // TODO Implement + return nullptr; + } + } diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_partial_dynamic.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_partial_dynamic.cpp index 967d3e9385..c2cf903c4f 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_partial_dynamic.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_partial_dynamic.cpp @@ -107,6 +107,20 @@ namespace boosting { indexVector, l1RegularizationWeight_, l2RegularizationWeight_); } + std::unique_ptr> + DecomposableDynamicPartialRuleEvaluationFactory::create(const BitDecomposableStatisticVector& statisticVector, + const CompleteIndexVector& indexVector) const { + // TODO Implement + return nullptr; + } + + std::unique_ptr> + DecomposableDynamicPartialRuleEvaluationFactory::create(const BitDecomposableStatisticVector& statisticVector, + const PartialIndexVector& indexVector) const { + // TODO Implement + return nullptr; + } + std::unique_ptr> DecomposableDynamicPartialRuleEvaluationFactory::create(const SparseDecomposableStatisticVector& statisticVector, const CompleteIndexVector& indexVector) const { diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_partial_dynamic_binned.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_partial_dynamic_binned.cpp index 98c149e026..cc1655361d 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_partial_dynamic_binned.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_partial_dynamic_binned.cpp @@ -115,6 +115,20 @@ namespace boosting { indexVector, l1RegularizationWeight_, l2RegularizationWeight_, std::move(labelBinningPtr)); } + std::unique_ptr> + DecomposableDynamicPartialBinnedRuleEvaluationFactory::create( + const BitDecomposableStatisticVector& statisticVector, const CompleteIndexVector& indexVector) const { + // TODO Implement + return nullptr; + } + + std::unique_ptr> + DecomposableDynamicPartialBinnedRuleEvaluationFactory::create( + const BitDecomposableStatisticVector& statisticVector, const PartialIndexVector& indexVector) const { + // TODO Implement + return nullptr; + } + std::unique_ptr> DecomposableDynamicPartialBinnedRuleEvaluationFactory::create( const SparseDecomposableStatisticVector& statisticVector, const CompleteIndexVector& indexVector) const { diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_partial_fixed.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_partial_fixed.cpp index 35e5004354..f74fb030f1 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_partial_fixed.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_partial_fixed.cpp @@ -99,6 +99,20 @@ namespace boosting { indexVector, l1RegularizationWeight_, l2RegularizationWeight_); } + std::unique_ptr> + DecomposableFixedPartialRuleEvaluationFactory::create(const BitDecomposableStatisticVector& statisticVector, + const CompleteIndexVector& indexVector) const { + // TODO Implement + return nullptr; + } + + std::unique_ptr> + DecomposableFixedPartialRuleEvaluationFactory::create(const BitDecomposableStatisticVector& statisticVector, + const PartialIndexVector& indexVector) const { + // TODO Implement + return nullptr; + } + std::unique_ptr> DecomposableFixedPartialRuleEvaluationFactory::create(const SparseDecomposableStatisticVector& statisticVector, const CompleteIndexVector& indexVector) const { diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_partial_fixed_binned.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_partial_fixed_binned.cpp index 875953f9a3..ce56d0e935 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_partial_fixed_binned.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_partial_fixed_binned.cpp @@ -99,6 +99,20 @@ namespace boosting { indexVector, l1RegularizationWeight_, l2RegularizationWeight_, std::move(labelBinningPtr)); } + std::unique_ptr> + DecomposableFixedPartialBinnedRuleEvaluationFactory::create(const BitDecomposableStatisticVector& statisticVector, + const CompleteIndexVector& indexVector) const { + // TODO Implement + return nullptr; + } + + std::unique_ptr> + DecomposableFixedPartialBinnedRuleEvaluationFactory::create(const BitDecomposableStatisticVector& statisticVector, + const PartialIndexVector& indexVector) const { + // TODO Implement + return nullptr; + } + std::unique_ptr> DecomposableFixedPartialBinnedRuleEvaluationFactory::create( const SparseDecomposableStatisticVector& statisticVector, const CompleteIndexVector& indexVector) const { diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_single.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_single.cpp index 4c4327f954..335556c1be 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_single.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/rule_evaluation/rule_evaluation_decomposable_single.cpp @@ -91,6 +91,20 @@ namespace boosting { indexVector, l1RegularizationWeight_, l2RegularizationWeight_); } + std::unique_ptr> + DecomposableSingleOutputRuleEvaluationFactory::create(const BitDecomposableStatisticVector& statisticVector, + const CompleteIndexVector& indexVector) const { + // TODO Implement + return nullptr; + } + + std::unique_ptr> + DecomposableSingleOutputRuleEvaluationFactory::create(const BitDecomposableStatisticVector& statisticVector, + const PartialIndexVector& indexVector) const { + // TODO Implement + return nullptr; + } + std::unique_ptr> DecomposableSingleOutputRuleEvaluationFactory::create(const SparseDecomposableStatisticVector& statisticVector, const CompleteIndexVector& indexVector) const { From 9d7d0482ffd2b6b244716788a1ac361a1185f50e Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Mon, 19 Aug 2024 18:25:26 +0200 Subject: [PATCH 34/37] Add template argument StatisticVector to class DenseDecomposableStatistics. --- .../boosting/statistics/statistics_decomposable_dense.hpp | 8 +++++--- .../statistics/statistics_provider_decomposable_dense.cpp | 5 +++-- .../statistics_provider_non_decomposable_dense.cpp | 3 ++- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_decomposable_dense.hpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_decomposable_dense.hpp index b164d6eee1..0a178822f0 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_decomposable_dense.hpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_decomposable_dense.hpp @@ -53,11 +53,13 @@ namespace boosting { * @tparam OutputMatrix The type of the matrix that provides access to the ground truth of the training * examples * @tparam QuantizationMatrix The type of the matrix that provides access to quantized gradients and Hessians + * @tparam StatisticVector The type of the vectors that are used to store gradients and Hessians * @tparam EvaluationMeasure The type of the evaluation that should be used to access the quality of predictions */ - template + template class DenseDecomposableStatistics final - : public AbstractDecomposableStatistics, Loss, EvaluationMeasure, IDecomposableRuleEvaluationFactory> { public: @@ -87,7 +89,7 @@ namespace boosting { const OutputMatrix& outputMatrix, std::unique_ptr statisticMatrixPtr, std::unique_ptr> scoreMatrixPtr) - : AbstractDecomposableStatistics, Loss, EvaluationMeasure, IDecomposableRuleEvaluationFactory>( std::move(quantizationMatrixPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp index 01703c4843..b6b67f6924 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp @@ -36,8 +36,9 @@ namespace boosting { std::unique_ptr> statisticsPtr; auto denseDecomposableMatrixVisitor = [&](std::unique_ptr>>>& quantizationMatrixPtr) { - statisticsPtr = std::make_unique>>, EvaluationMeasure>>( + statisticsPtr = std::make_unique< + DenseDecomposableStatistics>>, + DenseDecomposableStatisticVector, EvaluationMeasure>>( std::move(quantizationMatrixPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), ruleEvaluationFactory, outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)); }; diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp index 14acfac5d0..fae99bb6cd 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp @@ -150,7 +150,8 @@ namespace boosting { auto denseDecomposableMatrixVisitor = [&](std::unique_ptr>>>& quantizationMatrixPtr) { statisticsPtr = std::make_unique>>, EvaluationMeasure>>( + Loss, OutputMatrix, IQuantizationMatrix>>, + DenseDecomposableStatisticVector, EvaluationMeasure>>( std::move(quantizationMatrixPtr), std::move(this->lossPtr_), std::move(this->evaluationMeasurePtr_), ruleEvaluationFactory, this->outputMatrix_, std::move(decomposableStatisticMatrixPtr), std::move(this->scoreMatrixPtr_)); From 707008861c4888fdc071cb1396c51c417b2e1ce1 Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Mon, 19 Aug 2024 23:20:00 +0200 Subject: [PATCH 35/37] Add constructor argument "view" to vectors for storing statistics. --- .../data/vector_statistic_decomposable_bit.hpp | 11 ++++++----- .../data/vector_statistic_decomposable_dense.hpp | 4 +++- .../data/vector_statistic_decomposable_sparse.hpp | 4 +++- .../data/vector_statistic_non_decomposable_dense.hpp | 10 ++++++---- .../data/vector_statistic_decomposable_bit.cpp | 12 +++++++----- .../data/vector_statistic_decomposable_dense.cpp | 6 ++++-- .../data/vector_statistic_decomposable_sparse.cpp | 6 ++++-- .../data/vector_statistic_non_decomposable_dense.cpp | 7 +++++-- .../mlrl/boosting/statistics/statistics_common.hpp | 9 +++++---- 9 files changed, 43 insertions(+), 26 deletions(-) diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/data/vector_statistic_decomposable_bit.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/data/vector_statistic_decomposable_bit.hpp index f9d90b75b2..a94f735b1a 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/data/vector_statistic_decomposable_bit.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/data/vector_statistic_decomposable_bit.hpp @@ -20,12 +20,13 @@ namespace boosting { public: /** - * @param numElements The number of gradients and Hessians in the vector - * @param numBitsPerElement The number of bits per element in the bit vector - * @param init True, if all gradients and Hessians in the vector should be initialized with - * zero, false otherwise + * @param view A reference to an object of type `BitDecomposableStatisticView` + * @param numElements The number of gradients and Hessians in the vector + * @param init True, if all gradients and Hessians in the vector should be initialized with zero, + * false otherwise */ - BitDecomposableStatisticVector(uint32 numElements, uint32 numBitsPerElement, bool init = false); + BitDecomposableStatisticVector(const BitDecomposableStatisticView& view, uint32 numElements, + bool init = false); /** * @param other A reference to an object of type `BitDecomposableStatisticVector` to be copied diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/data/vector_statistic_decomposable_dense.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/data/vector_statistic_decomposable_dense.hpp index 6897b33c45..d6eaf3e180 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/data/vector_statistic_decomposable_dense.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/data/vector_statistic_decomposable_dense.hpp @@ -21,11 +21,13 @@ namespace boosting { public: /** + * @param view A reference to an object of type `CContiguousView` * @param numElements The number of gradients and Hessians in the vector * @param init True, if all gradients and Hessians in the vector should be initialized with zero, * false otherwise */ - DenseDecomposableStatisticVector(uint32 numElements, bool init = false); + DenseDecomposableStatisticVector(const CContiguousView>& view, uint32 numElements, + bool init = false); /** * @param other A reference to an object of type `DenseDecomposableStatisticVector` to be copied diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/data/vector_statistic_decomposable_sparse.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/data/vector_statistic_decomposable_sparse.hpp index 85cc705bde..069285b04c 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/data/vector_statistic_decomposable_sparse.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/data/vector_statistic_decomposable_sparse.hpp @@ -138,11 +138,13 @@ namespace boosting { public: /** + * @param view A reference to an object of type `SparseSetView` * @param numElements The number of gradients and Hessians in the vector * @param init True, if all gradients and Hessians in the vector should be initialized with zero, * false otherwise */ - SparseDecomposableStatisticVector(uint32 numElements, bool init = false); + SparseDecomposableStatisticVector(const SparseSetView>& view, uint32 numElements, + bool init = false); /** * @param other A reference to an object of type `SparseDecomposableStatisticVector` to be copied diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/data/vector_statistic_non_decomposable_dense.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/data/vector_statistic_non_decomposable_dense.hpp index 4cc4132f01..324234157a 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/data/vector_statistic_non_decomposable_dense.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/data/vector_statistic_non_decomposable_dense.hpp @@ -23,11 +23,13 @@ namespace boosting { public: /** - * @param numGradients The number of gradients in the vector - * @param init True, if all gradients and Hessians in the vector should be initialized with zero, - * false otherwise + * @param view A reference to an object of type `DenseNonDecomposableStatisticView` + * @param numGradients The number of gradients in the vector + * @param init True, if all gradients and Hessians in the vector should be initialized with zero, + * false otherwise */ - DenseNonDecomposableStatisticVector(uint32 numGradients, bool init = false); + DenseNonDecomposableStatisticVector(const DenseNonDecomposableStatisticView& view, uint32 numGradients, + bool init = false); /** * @param other A reference to an object of type `DenseNonDecomposableStatisticVector` to be copied diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/data/vector_statistic_decomposable_bit.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/data/vector_statistic_decomposable_bit.cpp index 257563694f..fc5c0dbcc5 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/data/vector_statistic_decomposable_bit.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/data/vector_statistic_decomposable_bit.cpp @@ -50,14 +50,16 @@ namespace boosting { } } - BitDecomposableStatisticVector::BitDecomposableStatisticVector(uint32 numElements, uint32 numBitsPerElement, - bool init) + BitDecomposableStatisticVector::BitDecomposableStatisticVector(const BitDecomposableStatisticView& view, + uint32 numElements, bool init) : CompositeView, AllocatedBitVector>( - AllocatedBitVector(numElements, numBitsPerElement, init), - AllocatedBitVector(numElements, numBitsPerElement, init)) {} + AllocatedBitVector(numElements, view.firstView.numBitsPerElement, init), + AllocatedBitVector(numElements, view.secondView.numBitsPerElement, init)) {} BitDecomposableStatisticVector::BitDecomposableStatisticVector(const BitDecomposableStatisticVector& other) - : BitDecomposableStatisticVector(other.getNumElements(), other.getNumBitsPerElement()) { + : CompositeView, AllocatedBitVector>( + AllocatedBitVector(other.firstView.numElements, other.firstView.numBitsPerElement), + AllocatedBitVector(other.secondView.numElements, other.secondView.numBitsPerElement)) { copyInternally(other.firstView, this->firstView); copyInternally(other.secondView, this->secondView); } diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/data/vector_statistic_decomposable_dense.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/data/vector_statistic_decomposable_dense.cpp index 0e6523558a..f0aab8efd7 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/data/vector_statistic_decomposable_dense.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/data/vector_statistic_decomposable_dense.cpp @@ -2,12 +2,14 @@ namespace boosting { - DenseDecomposableStatisticVector::DenseDecomposableStatisticVector(uint32 numElements, bool init) + DenseDecomposableStatisticVector::DenseDecomposableStatisticVector(const CContiguousView>& view, + uint32 numElements, bool init) : ClearableViewDecorator>>>( AllocatedVector>(numElements, init)) {} DenseDecomposableStatisticVector::DenseDecomposableStatisticVector(const DenseDecomposableStatisticVector& other) - : DenseDecomposableStatisticVector(other.getNumElements()) { + : ClearableViewDecorator>>>( + AllocatedVector>(other.getNumElements())) { util::copyView(other.cbegin(), this->begin(), this->getNumElements()); } diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/data/vector_statistic_decomposable_sparse.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/data/vector_statistic_decomposable_sparse.cpp index 87786ce2c3..23faccd452 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/data/vector_statistic_decomposable_sparse.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/data/vector_statistic_decomposable_sparse.cpp @@ -118,13 +118,15 @@ namespace boosting { return iterator_ - rhs.iterator_; } - SparseDecomposableStatisticVector::SparseDecomposableStatisticVector(uint32 numElements, bool init) + SparseDecomposableStatisticVector::SparseDecomposableStatisticVector(const SparseSetView>& view, + uint32 numElements, bool init) : ClearableViewDecorator>>>( AllocatedVector>(numElements, init)), sumOfWeights_(0) {} SparseDecomposableStatisticVector::SparseDecomposableStatisticVector(const SparseDecomposableStatisticVector& other) - : SparseDecomposableStatisticVector(other.getNumElements()) { + : ClearableViewDecorator>>>( + AllocatedVector>(other.getNumElements())) { util::copyView(other.view.cbegin(), this->view.begin(), this->getNumElements()); sumOfWeights_ = other.sumOfWeights_; } diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/data/vector_statistic_non_decomposable_dense.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/data/vector_statistic_non_decomposable_dense.cpp index f3c9ce6f4d..d7a3de0a55 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/data/vector_statistic_non_decomposable_dense.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/data/vector_statistic_non_decomposable_dense.cpp @@ -4,7 +4,8 @@ namespace boosting { - DenseNonDecomposableStatisticVector::DenseNonDecomposableStatisticVector(uint32 numGradients, bool init) + DenseNonDecomposableStatisticVector::DenseNonDecomposableStatisticVector( + const DenseNonDecomposableStatisticView& view, uint32 numGradients, bool init) : ClearableViewDecorator, AllocatedVector>>>( CompositeVector, AllocatedVector>( AllocatedVector(numGradients, init), @@ -12,7 +13,9 @@ namespace boosting { DenseNonDecomposableStatisticVector::DenseNonDecomposableStatisticVector( const DenseNonDecomposableStatisticVector& other) - : DenseNonDecomposableStatisticVector(other.getNumGradients()) { + : ClearableViewDecorator, AllocatedVector>>>( + CompositeVector, AllocatedVector>( + AllocatedVector(other.getNumGradients()), AllocatedVector(other.getNumHessians()))) { util::copyView(other.gradients_cbegin(), this->gradients_begin(), this->getNumGradients()); util::copyView(other.hessians_cbegin(), this->hessians_begin(), this->getNumHessians()); } diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp index 323f34995b..f0bb3db6a6 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_common.hpp @@ -98,8 +98,8 @@ namespace boosting { */ StatisticsSubset(const StatisticView& statisticView, const RuleEvaluationFactory& ruleEvaluationFactory, const WeightVector& weights, const IndexVector& outputIndices) - : sumVector_(outputIndices.getNumElements(), true), statisticView_(statisticView), weights_(weights), - outputIndices_(outputIndices), + : sumVector_(statisticView, outputIndices.getNumElements(), true), statisticView_(statisticView), + weights_(weights), outputIndices_(outputIndices), ruleEvaluationPtr_(ruleEvaluationFactory.create(sumVector_, outputIndices)) {} /** @@ -182,7 +182,8 @@ namespace boosting { : StatisticsSubset(statistics.statisticView_, statistics.ruleEvaluationFactory_, statistics.weights_, outputIndices), - tmpVector_(outputIndices.getNumElements()), totalSumVector_(&totalSumVector) {} + tmpVector_(statistics.statisticView_, outputIndices.getNumElements()), + totalSumVector_(&totalSumVector) {} /** * @see `IResettableStatisticsSubset::resetSubset` @@ -392,7 +393,7 @@ namespace boosting { const WeightVector& weights) : AbstractWeightedStatistics( statisticView, ruleEvaluationFactory, weights), - totalSumVectorPtr_(std::make_unique(statisticView.numCols, true)) { + totalSumVectorPtr_(std::make_unique(statisticView, statisticView.numCols, true)) { uint32 numStatistics = weights.getNumElements(); for (uint32 i = 0; i < numStatistics; i++) { From de5aae4a5f0d07af1b959b422c09ef376da5e9ec Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Mon, 19 Aug 2024 23:20:51 +0200 Subject: [PATCH 36/37] Implement visitors for creating statistics backed by a `BitDecomposableStatisticView`. --- .../statistics/statistics_provider_decomposable_dense.cpp | 7 +++++-- .../statistics_provider_non_decomposable_dense.cpp | 8 ++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp index b6b67f6924..b0db2287ba 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_decomposable_dense.cpp @@ -44,8 +44,11 @@ namespace boosting { }; auto bitDecomposableMatrixVisitor = [&](std::unique_ptr>& quantizationMatrixPtr) { - // TODO Implement - throw std::runtime_error("not implemented"); + statisticsPtr = std::make_unique< + DenseDecomposableStatistics, + BitDecomposableStatisticVector, EvaluationMeasure>>( + std::move(quantizationMatrixPtr), std::move(lossPtr), std::move(evaluationMeasurePtr), + ruleEvaluationFactory, outputMatrix, std::move(statisticMatrixPtr), std::move(scoreMatrixPtr)); }; quantizationPtr->visitQuantizationMatrix(denseDecomposableMatrixVisitor, bitDecomposableMatrixVisitor, {}, {}); return statisticsPtr; diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp index fae99bb6cd..50f8a75348 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/statistics_provider_non_decomposable_dense.cpp @@ -158,8 +158,12 @@ namespace boosting { }; auto bitDecomposableMatrixVisitor = [&](std::unique_ptr>& quantizationMatrixPtr) { - // TODO Implement - throw std::runtime_error("not implemented"); + statisticsPtr = std::make_unique< + DenseDecomposableStatistics, + BitDecomposableStatisticVector, EvaluationMeasure>>( + std::move(quantizationMatrixPtr), std::move(this->lossPtr_), + std::move(this->evaluationMeasurePtr_), ruleEvaluationFactory, this->outputMatrix_, + std::move(decomposableStatisticMatrixPtr), std::move(this->scoreMatrixPtr_)); }; quantizationPtr->visitQuantizationMatrix(denseDecomposableMatrixVisitor, bitDecomposableMatrixVisitor, {}, {}); From d00c5b6aa3f972a498ebe888f025a762c1b06096 Mon Sep 17 00:00:00 2001 From: Michael Rapp Date: Fri, 23 Aug 2024 11:33:19 +0200 Subject: [PATCH 37/37] Add shared pointer of type RNG as a member of the class StochasticQuantizationMatrix. --- .../include/mlrl/boosting/learner.hpp | 8 ++-- .../statistics/quantization_stochastic.hpp | 10 ++++- .../statistics/quantization_stochastic.cpp | 37 ++++++++++--------- 3 files changed, 32 insertions(+), 23 deletions(-) diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/learner.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/learner.hpp index c731da9278..ec232e7b4e 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/learner.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/learner.hpp @@ -321,8 +321,7 @@ namespace boosting { * examples. */ virtual void useNoQuantization() { - Property property = this->getQuantizationConfig(); - property.set(std::make_unique()); + this->getQuantizationConfig().set(std::make_unique()); } }; @@ -343,10 +342,9 @@ namespace boosting { * configuration of the quantization method */ virtual IStochasticQuantizationConfig& useStochasticQuantization() { - Property property = this->getQuantizationConfig(); - std::unique_ptr ptr = std::make_unique(); + auto ptr = std::make_unique(this->getRNGConfig()); IStochasticQuantizationConfig& ref = *ptr; - property.set(std::move(ptr)); + this->getQuantizationConfig().set(std::move(ptr)); return ref; } }; diff --git a/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization_stochastic.hpp b/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization_stochastic.hpp index 7ff50a5745..b6478dfe52 100644 --- a/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization_stochastic.hpp +++ b/cpp/subprojects/boosting/include/mlrl/boosting/statistics/quantization_stochastic.hpp @@ -4,6 +4,8 @@ #pragma once #include "mlrl/boosting/statistics/quantization.hpp" +#include "mlrl/common/random/rng.hpp" +#include "mlrl/common/util/properties.hpp" #include @@ -43,11 +45,17 @@ namespace boosting { public IStochasticQuantizationConfig { private: + const ReadableProperty rngConfig_; + uint32 numBits_; public: - StochasticQuantizationConfig(); + /** + * @param rngConfig A `ReadableProperty` that provides acccess the `RNGConfig` that stores the configuration + * of random number generators + */ + StochasticQuantizationConfig(ReadableProperty rngConfig); uint32 getNumBits() const override; diff --git a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp index 7c07994485..ac90bc4aaa 100644 --- a/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp +++ b/cpp/subprojects/boosting/src/mlrl/boosting/statistics/quantization_stochastic.cpp @@ -33,14 +33,16 @@ namespace boosting { class StochasticQuantizationMatrix final : public IQuantizationMatrix { private: + std::shared_ptr rngPtr_; + const View& view_; BitDecomposableStatisticView quantizedView_; public: - StochasticQuantizationMatrix(const View& view, uint32 numBits) - : view_(view), quantizedView_(view.numRows, view.numCols, numBits) {} + StochasticQuantizationMatrix(std::shared_ptr rngPtr, const View& view, uint32 numBits) + : rngPtr_(std::move(rngPtr)), view_(view), quantizedView_(view.numRows, view.numCols, numBits) {} void quantize(const CompleteIndexVector& outputIndices) override { // TODO Implement @@ -58,57 +60,58 @@ namespace boosting { const CContiguousView>& statisticMatrix) const override { return std::make_unique>>>( std::make_unique>>>( - statisticMatrix, quantizedView_.firstView.numBitsPerElement)); + rngPtr_, statisticMatrix, quantizedView_.firstView.numBitsPerElement)); } std::unique_ptr create(const SparseSetView>& statisticMatrix) const override { return std::make_unique>>>( std::make_unique>>>( - statisticMatrix, quantizedView_.firstView.numBitsPerElement)); + rngPtr_, statisticMatrix, quantizedView_.firstView.numBitsPerElement)); } std::unique_ptr create( const DenseNonDecomposableStatisticView& statisticMatrix) const override { return std::make_unique>( std::make_unique>( - statisticMatrix, quantizedView_.firstView.numBitsPerElement)); + rngPtr_, statisticMatrix, quantizedView_.firstView.numBitsPerElement)); } }; class StochasticQuantizationFactory final : public IQuantizationFactory { private: + const std::unique_ptr rngFactoryPtr_; + uint32 numBits_; public: - /** - * @param numBits The number of bits to be used for quantized statistics - */ - StochasticQuantizationFactory(uint32 numBits) : numBits_(numBits) {} + StochasticQuantizationFactory(std::unique_ptr rngFactoryPtr, uint32 numBits) + : rngFactoryPtr_(std::move(rngFactoryPtr)), numBits_(numBits) {} std::unique_ptr create( const CContiguousView>& statisticMatrix) const override { return std::make_unique>>>( - std::make_unique>>>(statisticMatrix, - numBits_)); + std::make_unique>>>( + rngFactoryPtr_->create(), statisticMatrix, numBits_)); } std::unique_ptr create(const SparseSetView>& statisticMatrix) const override { return std::make_unique>>>( - std::make_unique>>>(statisticMatrix, - numBits_)); + std::make_unique>>>( + rngFactoryPtr_->create(), statisticMatrix, numBits_)); } std::unique_ptr create( const DenseNonDecomposableStatisticView& statisticMatrix) const override { return std::make_unique>( - std::make_unique>(statisticMatrix, - numBits_)); + std::make_unique>( + rngFactoryPtr_->create(), statisticMatrix, numBits_)); } }; - StochasticQuantizationConfig::StochasticQuantizationConfig() : numBits_(4) {} + StochasticQuantizationConfig::StochasticQuantizationConfig(ReadableProperty rngConfig) + : rngConfig_(rngConfig), numBits_(4) {} uint32 StochasticQuantizationConfig::getNumBits() const { return numBits_; @@ -121,7 +124,7 @@ namespace boosting { } std::unique_ptr StochasticQuantizationConfig::createQuantizationFactory() const { - return std::make_unique(numBits_); + return std::make_unique(rngConfig_.get().createRNGFactory(), numBits_); } }