-
Notifications
You must be signed in to change notification settings - Fork 100
Add minimum iteration stopping criterion wrapper #1951
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: simpler_stop_interface
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,76 @@ | ||
| // SPDX-FileCopyrightText: 2017 - 2025 The Ginkgo authors | ||
| // | ||
| // SPDX-License-Identifier: BSD-3-Clause | ||
|
|
||
| #ifndef GKO_CORE_STOP_ITERATION_HPP_ | ||
| #define GKO_CORE_STOP_ITERATION_HPP_ | ||
|
|
||
| #include <ginkgo/core/base/abstract_factory.hpp> | ||
| #include <ginkgo/core/stop/combined.hpp> | ||
| #include <ginkgo/core/stop/criterion.hpp> | ||
| #include <ginkgo/core/stop/iteration.hpp> | ||
|
|
||
| namespace gko { | ||
| namespace stop { | ||
|
|
||
|
|
||
| class MinIterationWrapper | ||
| : public EnablePolymorphicObject<MinIterationWrapper, Criterion> { | ||
| friend class EnablePolymorphicObject<MinIterationWrapper, Criterion>; | ||
|
|
||
| public: | ||
| GKO_CREATE_FACTORY_PARAMETERS(parameters, Factory) | ||
| { | ||
| /** | ||
| * Minimum number of iterations, after which we check the inner | ||
| * criterion | ||
| */ | ||
| size_type min_iters{0}; | ||
|
|
||
| parameters_type& with_min_iters(size_type value) | ||
| { | ||
| this->min_iters = value; | ||
| return *this; | ||
| } | ||
|
|
||
| std::shared_ptr<const CriterionFactory> GKO_DEFERRED_FACTORY_PARAMETER( | ||
| inner_criterion); | ||
| }; | ||
| GKO_ENABLE_CRITERION_FACTORY(MinIterationWrapper, parameters, Factory); | ||
| GKO_ENABLE_BUILD_METHOD(Factory); | ||
|
|
||
| protected: | ||
| bool check_impl(uint8 stopping_id, bool set_finalized, | ||
| array<stopping_status>* stop_status, bool* one_changed, | ||
| const Updater& updater) override | ||
| { | ||
| if (updater.num_iterations_ < this->get_parameters().min_iters) { | ||
| return false; | ||
| } | ||
| return inner_criterion_->check(stopping_id, set_finalized, stop_status, | ||
| one_changed, updater); | ||
| } | ||
|
|
||
| explicit MinIterationWrapper(std::shared_ptr<const gko::Executor> exec) | ||
| : EnablePolymorphicObject<MinIterationWrapper, Criterion>( | ||
| std::move(exec)) | ||
| {} | ||
|
|
||
| explicit MinIterationWrapper(const Factory* factory, | ||
| const CriterionArgs& args) | ||
| : EnablePolymorphicObject<MinIterationWrapper, Criterion>( | ||
| factory->get_executor()), | ||
| parameters_{factory->get_parameters()}, | ||
| inner_criterion_{ | ||
| factory->get_parameters().inner_criterion->generate(args)} | ||
| {} | ||
|
|
||
| std::shared_ptr<Criterion> inner_criterion_; | ||
| }; | ||
|
|
||
|
|
||
| } // namespace stop | ||
| } // namespace gko | ||
|
|
||
|
|
||
| #endif // GKO_CORE_STOP_ITERATION_HPP_ |
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -6,10 +6,10 @@ | |||||||||||
| #define GKO_PUBLIC_CORE_STOP_ITERATION_HPP_ | ||||||||||||
|
|
||||||||||||
|
|
||||||||||||
| #include <ginkgo/core/base/abstract_factory.hpp> | ||||||||||||
| #include <ginkgo/core/stop/combined.hpp> | ||||||||||||
| #include <ginkgo/core/stop/criterion.hpp> | ||||||||||||
|
|
||||||||||||
| #include "ginkgo/core/base/abstract_factory.hpp" | ||||||||||||
|
|
||||||||||||
|
|
||||||||||||
| namespace gko { | ||||||||||||
| namespace stop { | ||||||||||||
|
|
@@ -83,6 +83,51 @@ class Iteration : public EnablePolymorphicObject<Iteration, Criterion> { | |||||||||||
| deferred_factory_parameter<Iteration::Factory> max_iters(size_type count); | ||||||||||||
|
|
||||||||||||
|
|
||||||||||||
| /** | ||||||||||||
| * Creates the precursor to an MinimumIteration stopping criterion factory, to | ||||||||||||
| * be used in conjunction with `.with_criteria(...)` function calls when | ||||||||||||
| * building a solver factory. This stopping criterion wraps another stopping | ||||||||||||
| * criterion inside, which only starts getting checked after the first `count` | ||||||||||||
| * iterations finished. | ||||||||||||
| * | ||||||||||||
| * Full usage example: Stop when the relative residual | ||||||||||||
| * norm is below $10^{-10}$, but with at least 100 iterations. | ||||||||||||
| * ```cpp | ||||||||||||
| * auto factory = gko::solver::Cg<double>::build() | ||||||||||||
| * .with_criteria(gko::stop::min_iters(100, | ||||||||||||
| * gko::stop::relative_residual_norm(1e-10))) | ||||||||||||
| * .on(exec); | ||||||||||||
| * ``` | ||||||||||||
| * | ||||||||||||
| * @param count the number of iterations after which to start checking the | ||||||||||||
| * inner criterion | ||||||||||||
| * @param criterion the inner criterion, which will not be checked until | ||||||||||||
| * `count` iterations finished, afterwards the min_iters | ||||||||||||
| * stopping criterion behaves like the inner criterion. | ||||||||||||
| * @return a deferred_factory_parameter that can be passed to the | ||||||||||||
|
Comment on lines
+106
to
+107
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
nit |
||||||||||||
| * `with_criteria` function when building a solver. | ||||||||||||
| */ | ||||||||||||
| deferred_factory_parameter<CriterionFactory> min_iters( | ||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Some documentation would be needed here, so that users know how to use this wrapper.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any idea how this can be realized in the file config? From the user side this: criteria:
max_iters: 100
relative_residual_norm: 1e-6
min_iters: 10should be pretty clear, i.e. the first two only activate once
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks good from the first sight. but feel weird trying explaining it in consistent way
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||||||||||||
| size_type count, deferred_factory_parameter<CriterionFactory> criterion); | ||||||||||||
|
|
||||||||||||
|
|
||||||||||||
| /** | ||||||||||||
| * @copydoc min_iters(size_type, deferred_factory_parameter<CriterionFactory>) | ||||||||||||
| * This version supports supplying multiple stopping criteria independently, all | ||||||||||||
| * of which will only be checked after the minimum iteration count has been | ||||||||||||
| * exceeded. | ||||||||||||
| */ | ||||||||||||
| template <typename... Args> | ||||||||||||
| std::enable_if_t<sizeof...(Args) >= 2, | ||||||||||||
| deferred_factory_parameter<CriterionFactory>> | ||||||||||||
| min_iters(size_type count, Args&&... criteria) | ||||||||||||
| { | ||||||||||||
| std::vector<deferred_factory_parameter<CriterionFactory>> criterion_vec{ | ||||||||||||
| std::forward<Args>(criteria)...}; | ||||||||||||
| return min_iters(count, Combined::build().with_criteria(criterion_vec)); | ||||||||||||
| }; | ||||||||||||
|
|
||||||||||||
|
|
||||||||||||
| } // namespace stop | ||||||||||||
| } // namespace gko | ||||||||||||
|
|
||||||||||||
|
|
||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit