Skip to content

Commit a7dcc2a

Browse files
committed
add chebyshev test and fix the number of generated
1 parent 6a66ee5 commit a7dcc2a

4 files changed

Lines changed: 205 additions & 3 deletions

File tree

core/solver/chebyshev.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ void Chebyshev<ValueType>::apply_dense_impl(const VectorType* dense_b,
195195
GKO_SOLVER_VECTOR(inner_solution, dense_b);
196196
GKO_SOLVER_VECTOR(update_solution, dense_b);
197197

198+
auto old_num_max_generation = num_max_generation_;
198199
// Use the scalar first
199200
// get the iteration information from stopping criterion.
200201
if (auto combined =
@@ -213,6 +214,10 @@ void Chebyshev<ValueType>::apply_dense_impl(const VectorType* dense_b,
213214
num_max_generation_ = std::max(num_max_generation_,
214215
iter_stop->get_parameters().max_iters);
215216
}
217+
// Regenerate the vector if we realloc the memory.
218+
if (old_num_max_generation != num_max_generation_) {
219+
num_generated_scalar_ = 0;
220+
}
216221
auto alpha = this->template create_workspace_scalar<ValueType>(
217222
GKO_SOLVER_TRAITS::alpha, num_max_generation_ + 1);
218223
auto beta = this->template create_workspace_scalar<ValueType>(

test/solver/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ ginkgo_create_common_test(bicgstab_kernels)
33
ginkgo_create_common_test(cb_gmres_kernels)
44
ginkgo_create_common_test(cg_kernels)
55
ginkgo_create_common_test(cgs_kernels)
6+
ginkgo_create_common_test(chebyshev_kernels)
67
ginkgo_create_common_test(direct DISABLE_EXECUTORS dpcpp)
78
ginkgo_create_common_test(fcg_kernels)
89
ginkgo_create_common_test(gcr_kernels)

test/solver/chebyshev_kernels.cpp

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
/*******************************<GINKGO LICENSE>******************************
2+
Copyright (c) 2017-2023, the Ginkgo authors
3+
All rights reserved.
4+
5+
Redistribution and use in source and binary forms, with or without
6+
modification, are permitted provided that the following conditions
7+
are met:
8+
9+
1. Redistributions of source code must retain the above copyright
10+
notice, this list of conditions and the following disclaimer.
11+
12+
2. Redistributions in binary form must reproduce the above copyright
13+
notice, this list of conditions and the following disclaimer in the
14+
documentation and/or other materials provided with the distribution.
15+
16+
3. Neither the name of the copyright holder nor the names of its
17+
contributors may be used to endorse or promote products derived from
18+
this software without specific prior written permission.
19+
20+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21+
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22+
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23+
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24+
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31+
******************************<GINKGO LICENSE>*******************************/
32+
33+
#include <random>
34+
35+
36+
#include <gtest/gtest.h>
37+
38+
39+
#include <ginkgo/core/base/exception.hpp>
40+
#include <ginkgo/core/base/executor.hpp>
41+
#include <ginkgo/core/matrix/dense.hpp>
42+
#include <ginkgo/core/solver/chebyshev.hpp>
43+
#include <ginkgo/core/solver/gmres.hpp>
44+
#include <ginkgo/core/stop/combined.hpp>
45+
#include <ginkgo/core/stop/iteration.hpp>
46+
47+
48+
#include "core/test/utils.hpp"
49+
#include "test/utils/executor.hpp"
50+
51+
52+
class Chebyshev : public CommonTestFixture {
53+
protected:
54+
using Mtx = gko::matrix::Dense<value_type>;
55+
56+
Chebyshev() : rand_engine(30) {}
57+
58+
std::unique_ptr<Mtx> gen_mtx(gko::size_type num_rows,
59+
gko::size_type num_cols, gko::size_type stride)
60+
{
61+
auto tmp_mtx = gko::test::generate_random_matrix<Mtx>(
62+
num_rows, num_cols,
63+
std::uniform_int_distribution<>(num_cols, num_cols),
64+
std::normal_distribution<value_type>(-1.0, 1.0), rand_engine, ref);
65+
auto result = Mtx::create(ref, gko::dim<2>{num_rows, num_cols}, stride);
66+
result->copy_from(tmp_mtx);
67+
return result;
68+
}
69+
70+
std::default_random_engine rand_engine;
71+
};
72+
73+
74+
TEST_F(Chebyshev, ApplyIsEquivalentToRef)
75+
{
76+
auto mtx = gen_mtx(50, 50, 52);
77+
auto x = gen_mtx(50, 3, 8);
78+
auto b = gen_mtx(50, 3, 5);
79+
auto d_mtx = clone(exec, mtx);
80+
auto d_x = clone(exec, x);
81+
auto d_b = clone(exec, b);
82+
// Forget about accuracy - Chebyshev is not going to converge for a random
83+
// matrix, just check that a couple of iterations gives the same result on
84+
// both executors
85+
auto chebyshev_factory =
86+
gko::solver::Chebyshev<value_type>::build()
87+
.with_criteria(
88+
gko::stop::Iteration::build().with_max_iters(2u).on(ref))
89+
.on(ref);
90+
auto d_chebyshev_factory =
91+
gko::solver::Chebyshev<value_type>::build()
92+
.with_criteria(
93+
gko::stop::Iteration::build().with_max_iters(2u).on(exec))
94+
.on(exec);
95+
auto solver = chebyshev_factory->generate(std::move(mtx));
96+
auto d_solver = d_chebyshev_factory->generate(std::move(d_mtx));
97+
98+
solver->apply(b, x);
99+
d_solver->apply(d_b, d_x);
100+
101+
GKO_ASSERT_MTX_NEAR(d_x, x, r<value_type>::value);
102+
}
103+
104+
105+
TEST_F(Chebyshev, ApplyWithIterativeInnerSolverIsEquivalentToRef)
106+
{
107+
auto mtx = gen_mtx(50, 50, 54);
108+
auto x = gen_mtx(50, 3, 6);
109+
auto b = gen_mtx(50, 3, 10);
110+
auto d_mtx = clone(exec, mtx);
111+
auto d_x = clone(exec, x);
112+
auto d_b = clone(exec, b);
113+
114+
auto chebyshev_factory =
115+
gko::solver::Chebyshev<value_type>::build()
116+
.with_preconditioner(
117+
gko::solver::Gmres<value_type>::build()
118+
.with_criteria(
119+
gko::stop::Iteration::build().with_max_iters(1u).on(
120+
ref))
121+
.on(ref))
122+
.with_criteria(
123+
gko::stop::Iteration::build().with_max_iters(2u).on(ref))
124+
.on(ref);
125+
auto d_chebyshev_factory =
126+
gko::solver::Chebyshev<value_type>::build()
127+
.with_preconditioner(
128+
gko::solver::Gmres<value_type>::build()
129+
.with_criteria(
130+
gko::stop::Iteration::build().with_max_iters(1u).on(
131+
exec))
132+
.on(exec))
133+
.with_criteria(
134+
gko::stop::Iteration::build().with_max_iters(2u).on(exec))
135+
.on(exec);
136+
auto solver = chebyshev_factory->generate(std::move(mtx));
137+
auto d_solver = d_chebyshev_factory->generate(std::move(d_mtx));
138+
139+
solver->apply(b, x);
140+
d_solver->apply(d_b, d_x);
141+
142+
// Note: r<value_type>::value * 300 instead of r<value_type>::value, as
143+
// the difference in the inner gmres iteration gets amplified by the
144+
// difference in IR.
145+
GKO_ASSERT_MTX_NEAR(d_x, x, r<value_type>::value * 300);
146+
}
147+
148+
149+
TEST_F(Chebyshev, ApplyWithGivenInitialGuessModeIsEquivalentToRef)
150+
{
151+
using initial_guess_mode = gko::solver::initial_guess_mode;
152+
auto mtx = gko::share(gen_mtx(50, 50, 52));
153+
auto b = gen_mtx(50, 3, 7);
154+
auto d_mtx = gko::share(clone(exec, mtx));
155+
auto d_b = clone(exec, b);
156+
for (auto guess : {initial_guess_mode::provided, initial_guess_mode::rhs,
157+
initial_guess_mode::zero}) {
158+
auto x = gen_mtx(50, 3, 4);
159+
auto d_x = clone(exec, x);
160+
auto chebyshev_factory =
161+
gko::solver::Chebyshev<value_type>::build()
162+
.with_criteria(
163+
gko::stop::Iteration::build().with_max_iters(2u).on(ref))
164+
.with_default_initial_guess(guess)
165+
.on(ref);
166+
auto d_chebyshev_factory =
167+
gko::solver::Chebyshev<value_type>::build()
168+
.with_criteria(
169+
gko::stop::Iteration::build().with_max_iters(2u).on(exec))
170+
.with_default_initial_guess(guess)
171+
.on(exec);
172+
auto solver = chebyshev_factory->generate(mtx);
173+
auto d_solver = d_chebyshev_factory->generate(d_mtx);
174+
175+
solver->apply(b, x);
176+
d_solver->apply(d_b, d_x);
177+
178+
GKO_ASSERT_MTX_NEAR(d_x, x, r<value_type>::value);
179+
}
180+
}

test/solver/solver.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5050
#include <ginkgo/core/solver/cb_gmres.hpp>
5151
#include <ginkgo/core/solver/cg.hpp>
5252
#include <ginkgo/core/solver/cgs.hpp>
53+
#include <ginkgo/core/solver/chebyshev.hpp>
5354
#include <ginkgo/core/solver/fcg.hpp>
5455
#include <ginkgo/core/solver/gcr.hpp>
5556
#include <ginkgo/core/solver/gmres.hpp>
@@ -212,6 +213,21 @@ struct Ir : SimpleSolverTest<gko::solver::Ir<solver_value_type>> {
212213
};
213214

214215

216+
struct Chebyshev : SimpleSolverTest<gko::solver::Chebyshev<solver_value_type>> {
217+
static double tolerance() { return 1e7 * r<value_type>::value; }
218+
219+
static typename solver_type::parameters_type build_preconditioned(
220+
std::shared_ptr<const gko::Executor> exec,
221+
gko::size_type iteration_count, bool check_residual = true)
222+
{
223+
return SimpleSolverTest<gko::solver::Chebyshev<solver_value_type>>::
224+
build(exec, iteration_count, check_residual)
225+
.with_preconditioner(
226+
precond_type::build().with_max_block_size(1u).on(exec));
227+
}
228+
};
229+
230+
215231
template <unsigned dimension>
216232
struct CbGmres : SimpleSolverTest<gko::solver::CbGmres<solver_value_type>> {
217233
static constexpr bool will_not_allocate() { return false; }
@@ -927,9 +943,9 @@ using SolverTypes =
927943
::testing::Types<Cg, Cgs, Fcg, Bicg, Bicgstab,
928944
/* "IDR uses different initialization approaches even when
929945
deterministic", Idr<1>, Idr<4>,*/
930-
Ir, CbGmres<2>, CbGmres<10>, Gmres<2>, Gmres<10>,
931-
FGmres<2>, FGmres<10>, Gcr<2>, Gcr<10>, LowerTrs, UpperTrs,
932-
LowerTrsUnitdiag, UpperTrsUnitdiag
946+
Ir, Chebyshev, CbGmres<2>, CbGmres<10>, Gmres<2>,
947+
Gmres<10>, FGmres<2>, FGmres<10>, Gcr<2>, Gcr<10>,
948+
LowerTrs, UpperTrs, LowerTrsUnitdiag, UpperTrsUnitdiag
933949
#ifdef GKO_COMPILING_CUDA
934950
,
935951
LowerTrsSyncfree, UpperTrsSyncfree,

0 commit comments

Comments
 (0)