diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 14ae6ce6592..df8f748b4d3 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -62,6 +62,7 @@ target_sources(${ginkgo_core} log/tau.cpp log/vtune.cpp log/record.cpp + log/solver_progress.cpp log/stream.cpp matrix/batch_csr.cpp matrix/batch_dense.cpp diff --git a/core/log/solver_progress.cpp b/core/log/solver_progress.cpp new file mode 100644 index 00000000000..effa0279bba --- /dev/null +++ b/core/log/solver_progress.cpp @@ -0,0 +1,314 @@ +// SPDX-FileCopyrightText: 2017 - 2024 The Ginkgo authors +// +// SPDX-License-Identifier: BSD-3-Clause + +#include "ginkgo/core/log/solver_progress.hpp" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "core/base/dispatch_helper.hpp" + + +namespace gko { +namespace log { +namespace { + + +bool is_dense(const LinOp* value) +{ + using conv_to_double = ConvertibleTo>; + using conv_to_complex = ConvertibleTo>>; + return dynamic_cast(value) || + dynamic_cast(value); +} + + +class SolverProgressPrint : public SolverProgress { + friend class SolverProgress; + +public: + /* Internal solver events */ + void on_linop_apply_started(const LinOp* solver, const LinOp* in, + const LinOp* out) const override + { + printed_header_ = false; + } + + void on_iteration_complete( + const LinOp* solver, const LinOp* right_hand_side, + const LinOp* solution, const size_type& num_iterations, + const LinOp* residual, const LinOp* residual_norm, + const LinOp* implicit_sq_residual_norm, + const array* status, bool stopped) const override + { + using solver_base = solver::detail::SolverBaseLinOp; + auto dynamic_type = name_demangling::get_dynamic_type(*solver); + auto& stream = *output_; + auto base = gko::as(solver); + if (!printed_header_) { + stream << dynamic_type << "::apply(" << right_hand_side << ',' + << solution << ") of dimensions " << solver->get_size() + << " and " << right_hand_side->get_size()[1] << " rhs\n"; + const auto scalars = base->get_workspace_scalars(); + const auto names = base->get_workspace_op_names(); + stream << std::setw(column_width_) << "Iteration"; + for (auto scalar : scalars) { + if (separator_) { + stream << separator_; + } + stream << std::setw(column_width_) << names[scalar]; + } + if (residual_norm) { + if (separator_) { + stream << separator_; + } + stream << std::setw(column_width_) << "residual_norm"; + } + if (implicit_sq_residual_norm) { + if (separator_) { + stream << separator_; + } + stream << std::setw(column_width_) + << "implicit_sq_residual_norm"; + } + stream << '\n'; + printed_header_ = true; + } + stream << std::setprecision(precision_); + const auto scalars = base->get_workspace_scalars(); + stream << std::setw(column_width_) << num_iterations; + for (auto scalar : scalars) { + print_scalar(base->get_workspace_op(scalar), stream); + } + if (residual_norm) { + print_scalar(residual_norm, stream); + } + if (implicit_sq_residual_norm) { + print_scalar(implicit_sq_residual_norm, stream); + } + stream << '\n'; + } + + GKO_DEPRECATED( + "Please use the version with the additional stopping " + "information.") + void on_iteration_complete(const LinOp* solver, + const size_type& num_iterations, + const LinOp* residual, const LinOp* solution, + const LinOp* residual_norm) const override + { + on_iteration_complete(solver, nullptr, solution, num_iterations, + residual, residual_norm, nullptr, nullptr, false); + } + + GKO_DEPRECATED( + "Please use the version with the additional stopping " + "information.") + void on_iteration_complete( + const LinOp* solver, const size_type& num_iterations, + const LinOp* residual, const LinOp* solution, + const LinOp* residual_norm, + const LinOp* implicit_sq_residual_norm) const override + { + on_iteration_complete(solver, nullptr, solution, num_iterations, + residual, residual_norm, + implicit_sq_residual_norm, nullptr, false); + } + +private: + void print_scalar(const LinOp* value, std::ostream& stream) const + { + if (separator_) { + stream << separator_; + } + stream << std::setw(column_width_); + if (!value->get_size()) { + stream << ""; + } else if (value->get_size()[0] != 1) { + stream << ""; + } else if (is_dense(value)) { + auto host_exec = value->get_executor()->get_master(); + run>, + ConvertibleTo>>>( + value, [&](auto vector) { + using vector_type = + typename detail::pointee::result_type; + auto host_vec = vector_type::create(host_exec); + vector->convert_to(host_vec); + stream << host_vec->at(0, 0); + }); + + } else { + stream << ""; + } + } + + SolverProgressPrint(std::ostream& output, int precision, int column_width, + char separator) + : output_{&output}, + precision_{precision}, + column_width_{column_width}, + separator_{separator}, + printed_header_(false) + {} + + std::ostream* output_; + int precision_; + int column_width_; + char separator_; + mutable bool printed_header_; +}; + + +class SolverProgressStore : public SolverProgress { + friend class SolverProgress; + +public: + /* Internal solver events */ + void on_linop_apply_started(const LinOp* solver, const LinOp* in, + const LinOp* out) const override + { + using solver_base = solver::detail::SolverBaseLinOp; + auto dynamic_type = name_demangling::get_dynamic_type(*solver); + auto base = gko::as(solver); + store_vector(base->get_system_matrix().get(), "system_matrix"); + store_vector(in, "rhs"); + store_vector(out, "initial_guess"); + } + + void on_iteration_complete( + const LinOp* solver, const LinOp* right_hand_side, + const LinOp* solution, const size_type& num_iterations, + const LinOp* residual, const LinOp* residual_norm, + const LinOp* implicit_sq_residual_norm, + const array* status, bool stopped) const override + { + using solver_base = solver::detail::SolverBaseLinOp; + auto base = gko::as(solver); + const auto num_vectors = base->get_num_workspace_ops(); + const auto names = base->get_workspace_op_names(); + for (int i = 0; i < num_vectors; i++) { + store_vector(base->get_workspace_op(i), num_iterations, + base->get_workspace_op_names()[i]); + } + store_vector(solution, num_iterations, "solution"); + store_vector(residual, num_iterations, "residual"); + store_vector(residual_norm, num_iterations, "residual_norm"); + store_vector(implicit_sq_residual_norm, num_iterations, + "implicit_sq_residual_norm"); + } + + GKO_DEPRECATED( + "Please use the version with the additional stopping " + "information.") + void on_iteration_complete(const LinOp* solver, + const size_type& num_iterations, + const LinOp* residual, const LinOp* solution, + const LinOp* residual_norm) const override + { + on_iteration_complete(solver, nullptr, solution, num_iterations, + residual, residual_norm, nullptr, nullptr, false); + } + + GKO_DEPRECATED( + "Please use the version with the additional stopping " + "information.") + void on_iteration_complete( + const LinOp* solver, const size_type& num_iterations, + const LinOp* residual, const LinOp* solution, + const LinOp* residual_norm, + const LinOp* implicit_sq_residual_norm) const override + { + on_iteration_complete(solver, nullptr, solution, num_iterations, + residual, residual_norm, + implicit_sq_residual_norm, nullptr, false); + } + +private: + void store_vector(const LinOp* value, const std::string& name) const + { + const auto filename = + output_file_prefix_ + "_" + name + (binary_ ? ".bin" : ".mtx"); + if (!value) { + return; + } + // putting Dense first here causes gko::write to use dense output + run, gko::matrix::Dense, + gko::matrix::Dense>, + gko::matrix::Dense>, + // fallback for other matrix types + gko::WritableToMatrixData, + gko::WritableToMatrixData, + gko::WritableToMatrixData, int32>, + gko::WritableToMatrixData, int32>, + gko::WritableToMatrixData, + gko::WritableToMatrixData, + gko::WritableToMatrixData, int64>, + gko::WritableToMatrixData, int64>>( + value, [&](auto vector) { + std::ofstream output{ + filename, binary_ ? (std::ios::out | std::ios::binary) + : std::ios::out}; + if (binary_) { + gko::write_binary(output, vector); + } else { + gko::write(output, vector); + } + }); + } + + void store_vector(const LinOp* value, size_type iteration, + const std::string& name) const + { + store_vector(value, std::to_string(iteration) + "_" + name); + } + + SolverProgressStore(std::string output_file_prefix, bool binary) + : output_file_prefix_{std::move(output_file_prefix)}, binary_{binary} + {} + + std::string output_file_prefix_; + bool binary_; +}; + + +} // namespace + + +std::shared_ptr SolverProgress::create_scalar_table_writer( + std::ostream& output, int precision, int column_width) +{ + return std::shared_ptr{ + new SolverProgressPrint{output, precision, column_width, '\0'}}; +} + + +std::shared_ptr SolverProgress::create_scalar_csv_writer( + std::ostream& output, int precision, char separator) +{ + return std::shared_ptr{ + new SolverProgressPrint{output, precision, 0, separator}}; +} + + +std::shared_ptr SolverProgress::create_vector_storage( + std::string output_file_prefix, bool binary) +{ + return std::shared_ptr{ + new SolverProgressStore{output_file_prefix, binary}}; +} + + +} // namespace log +} // namespace gko diff --git a/core/solver/bicg.cpp b/core/solver/bicg.cpp index c379cb8df08..0b39b3664cc 100644 --- a/core/solver/bicg.cpp +++ b/core/solver/bicg.cpp @@ -124,7 +124,6 @@ void Bicg::apply_dense_impl(const matrix::Dense* dense_b, GKO_SOLVER_VECTOR(p2, dense_b); GKO_SOLVER_VECTOR(q2, dense_b); - GKO_SOLVER_SCALAR(alpha, dense_b); GKO_SOLVER_SCALAR(beta, dense_b); GKO_SOLVER_SCALAR(prev_rho, dense_b); GKO_SOLVER_SCALAR(rho, dense_b); @@ -255,7 +254,7 @@ int workspace_traits>::num_arrays(const Solver&) template int workspace_traits>::num_vectors(const Solver&) { - return 14; + return 13; } @@ -264,8 +263,8 @@ std::vector workspace_traits>::op_names( const Solver&) { return { - "r", "z", "p", "q", "r2", "z2", "p2", - "q2", "alpha", "beta", "prev_rho", "rho", "one", "minus_one", + "r", "z", "p", "q", "r2", "z2", "p2", + "q2", "beta", "prev_rho", "rho", "one", "minus_one", }; } @@ -281,7 +280,7 @@ std::vector workspace_traits>::array_names( template std::vector workspace_traits>::scalars(const Solver&) { - return {alpha, beta, prev_rho, rho}; + return {beta, prev_rho, rho}; } diff --git a/core/solver/cg.cpp b/core/solver/cg.cpp index 20487b4cd0d..c512dc4313b 100644 --- a/core/solver/cg.cpp +++ b/core/solver/cg.cpp @@ -102,7 +102,6 @@ void Cg::apply_dense_impl(const VectorType* dense_b, GKO_SOLVER_VECTOR(p, dense_b); GKO_SOLVER_VECTOR(q, dense_b); - GKO_SOLVER_SCALAR(alpha, dense_b); GKO_SOLVER_SCALAR(beta, dense_b); GKO_SOLVER_SCALAR(prev_rho, dense_b); GKO_SOLVER_SCALAR(rho, dense_b); @@ -206,7 +205,7 @@ int workspace_traits>::num_arrays(const Solver&) template int workspace_traits>::num_vectors(const Solver&) { - return 10; + return 9; } @@ -215,8 +214,7 @@ std::vector workspace_traits>::op_names( const Solver&) { return { - "r", "z", "p", "q", "alpha", - "beta", "prev_rho", "rho", "one", "minus_one", + "r", "z", "p", "q", "beta", "prev_rho", "rho", "one", "minus_one", }; } @@ -232,7 +230,7 @@ std::vector workspace_traits>::array_names( template std::vector workspace_traits>::scalars(const Solver&) { - return {alpha, beta, prev_rho, rho}; + return {beta, prev_rho, rho}; } diff --git a/core/solver/fcg.cpp b/core/solver/fcg.cpp index c4f79854c0a..6c65f63ccae 100644 --- a/core/solver/fcg.cpp +++ b/core/solver/fcg.cpp @@ -102,7 +102,6 @@ void Fcg::apply_dense_impl(const VectorType* dense_b, GKO_SOLVER_VECTOR(q, dense_b); GKO_SOLVER_VECTOR(t, dense_b); - GKO_SOLVER_SCALAR(alpha, dense_b); GKO_SOLVER_SCALAR(beta, dense_b); GKO_SOLVER_SCALAR(prev_rho, dense_b); GKO_SOLVER_SCALAR(rho, dense_b); @@ -209,7 +208,7 @@ int workspace_traits>::num_arrays(const Solver&) template int workspace_traits>::num_vectors(const Solver&) { - return 12; + return 11; } @@ -218,8 +217,8 @@ std::vector workspace_traits>::op_names( const Solver&) { return { - "r", "z", "p", "q", "t", "alpha", - "beta", "prev_rho", "rho", "rho_t", "one", "minus_one", + "r", "z", "p", "q", "t", "beta", + "prev_rho", "rho", "rho_t", "one", "minus_one", }; } @@ -235,7 +234,7 @@ std::vector workspace_traits>::array_names( template std::vector workspace_traits>::scalars(const Solver&) { - return {alpha, beta, prev_rho, rho, rho_t}; + return {beta, prev_rho, rho, rho_t}; } diff --git a/core/test/log/CMakeLists.txt b/core/test/log/CMakeLists.txt index 8efd7fafc46..6e8c89ef671 100644 --- a/core/test/log/CMakeLists.txt +++ b/core/test/log/CMakeLists.txt @@ -6,4 +6,5 @@ endif() ginkgo_create_test(performance_hint) ginkgo_create_test(profiler_hook) ginkgo_create_test(record) +ginkgo_create_test(solver_progress) ginkgo_create_test(stream) diff --git a/core/test/log/solver_progress.cpp b/core/test/log/solver_progress.cpp new file mode 100644 index 00000000000..f2433779864 --- /dev/null +++ b/core/test/log/solver_progress.cpp @@ -0,0 +1,184 @@ +// SPDX-FileCopyrightText: 2017 - 2024 The Ginkgo authors +// +// SPDX-License-Identifier: BSD-3-Clause + +#include + +#include + +#include +#include +#include +#include + +#include "core/test/utils.hpp" +#include "core/test/utils/assertions.hpp" + + +template +class SolverProgress : public ::testing::Test { +public: + using Dense = gko::matrix::Dense; + using Cg = gko::solver::Cg; + + SolverProgress() : ref{gko::ReferenceExecutor::create()} + { + mtx = gko::initialize({T{1.0}}, ref); + in = gko::initialize({T{2.0}}, ref); + out = gko::initialize({T{4.0}}, ref); + zero = gko::initialize({T{0.0}}, ref); + solver = + Cg::build() + .with_criteria(gko::stop::Iteration::build().with_max_iters(1u)) + .on(ref) + ->generate(mtx); + } + + template + void assert_file_equals(const std::string& filename, Mtx* ref_mtx) + { + SCOPED_TRACE(filename); + auto cleanup = [filename] { + std::remove((filename + ".mtx").c_str()); + std::remove((filename + ".bin").c_str()); + }; + std::ifstream stream_mtx{filename + ".mtx"}; + std::ifstream stream_bin{filename + ".bin", std::ios::binary}; + // check that the files exist + ASSERT_TRUE(stream_mtx.good()); + ASSERT_TRUE(stream_bin.good()); + if (!ref_mtx) { + cleanup(); + return; + } + // check that the files have the correct contents + auto mtx = gko::read(stream_mtx, ref); + auto mtx_bin = gko::read_binary(stream_bin, ref); + cleanup(); + GKO_ASSERT_MTX_NEAR(mtx, ref_mtx, 0.0); + GKO_ASSERT_MTX_NEAR(mtx_bin, ref_mtx, 0.0); + } + + std::shared_ptr ref; + std::shared_ptr mtx; + std::shared_ptr in; + std::unique_ptr out; + std::unique_ptr zero; + std::unique_ptr solver; +}; + +TYPED_TEST_SUITE(SolverProgress, gko::test::ValueTypes, TypenameNameGenerator); + + +TYPED_TEST(SolverProgress, TableWorks) +{ + using T = TypeParam; + std::stringstream ref_ss; + int default_column_width = 12; + auto dynamic_type = gko::name_demangling::get_dynamic_type(*this->solver); + ref_ss << dynamic_type << "::apply(" << this->in.get() << ',' + << this->out.get() << ") of dimensions " << this->solver->get_size() + << " and " << this->in->get_size()[1] << " rhs\n"; + ref_ss << std::setw(default_column_width) << "Iteration" + << std::setw(default_column_width) << "beta" + << std::setw(default_column_width) << "prev_rho" + << std::setw(default_column_width) << "rho" + << std::setw(default_column_width) << "implicit_sq_residual_norm" + << '\n'; + ref_ss << std::setw(default_column_width) << 0 + << std::setw(default_column_width) << T{0.0} + << std::setw(default_column_width) << T{1.0} + << std::setw(default_column_width) << T{4.0} + << std::setw(default_column_width) << T{4.0} << '\n' + << std::setw(default_column_width) << 1 + << std::setw(default_column_width) << T{4.0} + << std::setw(default_column_width) << T{0.0} + << std::setw(default_column_width) << T{4.0} + << std::setw(default_column_width) << T{0.0} << '\n'; + std::stringstream ss; + this->solver->add_logger( + gko::log::SolverProgress::create_scalar_table_writer(ss)); + + this->solver->apply(this->in, this->out); + + // the first value of beta is uninitialized, so we need to remove it + std::regex first_beta("\n 0 *[()0-9.e,+-]*"); + auto clean_str = std::regex_replace(ss.str(), first_beta, "\n 0"); + auto clean_ref = + std::regex_replace(ref_ss.str(), first_beta, "\n 0"); + ASSERT_EQ(clean_str, clean_ref); +} + + +TYPED_TEST(SolverProgress, CsvWorks) +{ + using T = TypeParam; + std::stringstream ref_ss; + auto dynamic_type = gko::name_demangling::get_dynamic_type(*this->solver); + ref_ss << dynamic_type << "::apply(" << this->in.get() << ',' + << this->out.get() << ") of dimensions " << this->solver->get_size() + << " and " << this->in->get_size()[1] << " rhs\n"; + ref_ss << "Iteration;beta;prev_rho;rho;implicit_sq_residual_norm" << '\n'; + ref_ss << 0 << ';' << T{0.0} << ';' << T{1.0} << ';' << T{4.0} << ';' + << T{4.0} << '\n' + << 1 << ';' << T{4.0} << ';' << T{0.0} << ';' << T{4.0} << ';' + << T{0.0} << '\n'; + std::stringstream ss; + this->solver->add_logger( + gko::log::SolverProgress::create_scalar_csv_writer(ss, 6, ';')); + + this->solver->apply(this->in, this->out); + + // the first value of beta is uninitialized, so we need to remove it + std::regex first_beta("\n0;[^;]*"); + auto clean_str = std::regex_replace(ss.str(), first_beta, "\n0;"); + auto clean_ref = std::regex_replace(ref_ss.str(), first_beta, "\n0;"); + ASSERT_EQ(clean_str, clean_ref); +} + + +TYPED_TEST(SolverProgress, StorageWorks) +{ + using T = TypeParam; + using Dense = typename TestFixture::Dense; + auto orig_out = this->out->clone(); + auto init_residual = gko::initialize({T{-2.0}}, this->ref); + std::vector> files{ + {"solver_progress_test_0_beta", nullptr}, + {"solver_progress_test_0_implicit_sq_residual_norm", orig_out.get()}, + {"solver_progress_test_0_minus_one", nullptr}, + {"solver_progress_test_0_one", nullptr}, + {"solver_progress_test_0_p", nullptr}, + {"solver_progress_test_0_prev_rho", nullptr}, + {"solver_progress_test_0_q", nullptr}, + {"solver_progress_test_0_r", nullptr}, + {"solver_progress_test_0_residual", init_residual.get()}, + {"solver_progress_test_0_rho", nullptr}, + {"solver_progress_test_0_solution", orig_out.get()}, + {"solver_progress_test_0_z", nullptr}, + {"solver_progress_test_1_beta", orig_out.get()}, + {"solver_progress_test_1_implicit_sq_residual_norm", this->zero.get()}, + {"solver_progress_test_1_minus_one", nullptr}, + {"solver_progress_test_1_one", nullptr}, + {"solver_progress_test_1_p", nullptr}, + {"solver_progress_test_1_prev_rho", nullptr}, + {"solver_progress_test_1_q", nullptr}, + {"solver_progress_test_1_r", nullptr}, + {"solver_progress_test_1_residual", this->zero.get()}, + {"solver_progress_test_1_rho", nullptr}, + {"solver_progress_test_1_solution", this->in.get()}, + {"solver_progress_test_1_z", nullptr}, + {"solver_progress_test_initial_guess", orig_out.get()}, + {"solver_progress_test_rhs", this->in.get()}, + {"solver_progress_test_system_matrix", this->mtx.get()}}; + this->solver->add_logger(gko::log::SolverProgress::create_vector_storage( + "solver_progress_test", false)); + this->solver->add_logger(gko::log::SolverProgress::create_vector_storage( + "solver_progress_test", true)); + + this->solver->apply(this->in, this->out); + + for (auto pair : files) { + this->assert_file_equals(pair.first, pair.second); + } +} diff --git a/include/ginkgo/core/log/solver_progress.hpp b/include/ginkgo/core/log/solver_progress.hpp new file mode 100644 index 00000000000..71e08fc96c9 --- /dev/null +++ b/include/ginkgo/core/log/solver_progress.hpp @@ -0,0 +1,77 @@ +// SPDX-FileCopyrightText: 2017 - 2024 The Ginkgo authors +// +// SPDX-License-Identifier: BSD-3-Clause + +#ifndef GKO_PUBLIC_CORE_LOG_SOLVER_PROGRESS_HPP_ +#define GKO_PUBLIC_CORE_LOG_SOLVER_PROGRESS_HPP_ + + +#include +#include + +#include + + +namespace gko { +namespace log { + + +/** + * This Logger outputs the value of all scalar values (and potentially vectors) + * stored internally by the solver after each iteration. It needs to be attached + * to the solver being inspected. + */ +class SolverProgress : public Logger { +public: + /** + * Creates a logger printing the value for all scalar values in the solver + * after each iteration in an ASCII table. + * If the solver is applied to multiple right-hand sides, only the first + * right-hand side gets printed. + * + * @param output the stream to write the output to. + * @param precision the number of digits of precision to print + * @param column_width the number of characters an output column is wide + */ + static std::shared_ptr create_scalar_table_writer( + std::ostream& output, int precision = 6, int column_width = 12); + + + /** + * Creates a logger printing the value for all scalar values in the solver + * after each iteration in a CSV table. + * If the solver is applied to multiple right-hand sides, only the first + * right-hand side gets printed. + * + * @param output the stream to write the output to. + * @param precision the number of digits of precision to print + * @param separator the character separating columns from each other + */ + static std::shared_ptr create_scalar_csv_writer( + std::ostream& output, int precision = 6, char separator = ','); + + + /** + * Creates a logger storing all vectors and scalar values in the solver + * after each iteration on disk. + * This logger can handle multiple right-hand sides, in contrast to + * create_scalar_table_writer or create_scalar_csv_writer. + * + * @param output the path and file name prefix used to generate the output + * file names. + * @param precision the number of digits of precision to print when + * outputting matrices in text format + * @param binary if true, write data in Ginkgo's own binary format + * (lossless), if false write data in the MatrixMarket format + * (potentially lossy) + */ + static std::shared_ptr create_vector_storage( + std::string output_file_prefix = "solver_", bool binary = false); +}; + + +} // namespace log +} // namespace gko + + +#endif // GKO_PUBLIC_CORE_LOG_SOLVER_PROGRESS_HPP_ diff --git a/include/ginkgo/core/solver/bicg.hpp b/include/ginkgo/core/solver/bicg.hpp index 9f1ef54cc34..2a43c1ca3f8 100644 --- a/include/ginkgo/core/solver/bicg.hpp +++ b/include/ginkgo/core/solver/bicg.hpp @@ -155,18 +155,16 @@ struct workspace_traits> { constexpr static int p2 = 6; // "transposed" q vector constexpr static int q2 = 7; - // alpha scalar - constexpr static int alpha = 8; // beta scalar - constexpr static int beta = 9; + constexpr static int beta = 8; // previous rho scalar - constexpr static int prev_rho = 10; + constexpr static int prev_rho = 9; // current rho scalar - constexpr static int rho = 11; + constexpr static int rho = 10; // constant 1.0 scalar - constexpr static int one = 12; + constexpr static int one = 11; // constant -1.0 scalar - constexpr static int minus_one = 13; + constexpr static int minus_one = 12; // stopping status array constexpr static int stop = 0; diff --git a/include/ginkgo/core/solver/cg.hpp b/include/ginkgo/core/solver/cg.hpp index 9d850ecbe6d..984d5d1f104 100644 --- a/include/ginkgo/core/solver/cg.hpp +++ b/include/ginkgo/core/solver/cg.hpp @@ -141,18 +141,16 @@ struct workspace_traits> { constexpr static int p = 2; // q vector constexpr static int q = 3; - // alpha scalar - constexpr static int alpha = 4; // beta scalar - constexpr static int beta = 5; + constexpr static int beta = 4; // previous rho scalar - constexpr static int prev_rho = 6; + constexpr static int prev_rho = 5; // current rho scalar - constexpr static int rho = 7; + constexpr static int rho = 6; // constant 1.0 scalar - constexpr static int one = 8; + constexpr static int one = 7; // constant -1.0 scalar - constexpr static int minus_one = 9; + constexpr static int minus_one = 8; // stopping status array constexpr static int stop = 0; diff --git a/include/ginkgo/core/solver/fcg.hpp b/include/ginkgo/core/solver/fcg.hpp index 4577dd1b1d4..dfaf252b557 100644 --- a/include/ginkgo/core/solver/fcg.hpp +++ b/include/ginkgo/core/solver/fcg.hpp @@ -148,20 +148,18 @@ struct workspace_traits> { constexpr static int q = 3; // t vector constexpr static int t = 4; - // alpha scalar - constexpr static int alpha = 5; // beta scalar - constexpr static int beta = 6; + constexpr static int beta = 5; // previous rho scalar - constexpr static int prev_rho = 7; + constexpr static int prev_rho = 6; // current rho scalar - constexpr static int rho = 8; + constexpr static int rho = 7; // current rho_t scalar - constexpr static int rho_t = 9; + constexpr static int rho_t = 8; // constant 1.0 scalar - constexpr static int one = 10; + constexpr static int one = 9; // constant -1.0 scalar - constexpr static int minus_one = 11; + constexpr static int minus_one = 10; // stopping status array constexpr static int stop = 0; diff --git a/include/ginkgo/ginkgo.hpp b/include/ginkgo/ginkgo.hpp index 503b0143e09..0fab93dcefe 100644 --- a/include/ginkgo/ginkgo.hpp +++ b/include/ginkgo/ginkgo.hpp @@ -87,6 +87,7 @@ #include #include #include +#include #include #include