CDT++ 1.0.0-rc3
Causal Dynamical Triangulations in C++
Loading...
Searching...
No Matches
Move_run.hpp
Go to the documentation of this file.
1/*******************************************************************************
2 Causal Dynamical Triangulations in C++ using CGAL
3
4 Copyright © 2026 Adam Getchell
5 ******************************************************************************/
6
9
10#ifndef CDT_PLUSPLUS_MOVE_RUN_HPP
11#define CDT_PLUSPLUS_MOVE_RUN_HPP
12
13#include <fmt/format.h>
14
15#include <expected>
16#include <functional>
17#include <stdexcept>
18#include <string_view>
19#include <utility>
20
21#include "Move_tracker.hpp"
22#include "Random.hpp"
23
24namespace cdt
25{
32
36 class MoveRunCadence
37 {
38 struct Parsed
39 {};
40
41 Int_precision m_passes{1};
42 Int_precision m_checkpoint{1};
43
45 Parsed /*proof*/) noexcept
46 : m_passes{passes}, m_checkpoint{checkpoint}
47 {}
48
49 public:
51 MoveRunCadence() = default;
52
61 [[nodiscard]] static auto parse(Int_precision const passes,
62 Int_precision const checkpoint) noexcept
63 -> std::expected<MoveRunCadence, MoveRunCadenceError>
64 {
65 if (passes <= 0)
66 {
67 return std::unexpected{MoveRunCadenceError::NONPOSITIVE_PASSES};
68 }
69 if (checkpoint <= 0)
70 {
71 return std::unexpected{MoveRunCadenceError::NONPOSITIVE_CHECKPOINT};
72 }
73 return MoveRunCadence{passes, checkpoint, Parsed{}};
74 }
75
77 [[nodiscard]] constexpr auto passes() const noexcept { return m_passes; }
78
80 [[nodiscard]] constexpr auto checkpoint() const noexcept
81 { return m_checkpoint; }
82 };
83
84 namespace detail
85 {
88 [[nodiscard]] inline auto parse_move_run_cadence(
89 Int_precision const passes, Int_precision const checkpoint,
90 std::string_view const strategy_name) -> MoveRunCadence
91 {
92 auto cadence = MoveRunCadence::parse(passes, checkpoint);
93 if (cadence) { return *cadence; }
94
95 switch (cadence.error())
96 {
98 throw std::invalid_argument{
99 fmt::format("{} passes must be positive", strategy_name)};
101 throw std::invalid_argument{fmt::format(
102 "{} checkpoint interval must be positive", strategy_name)};
103 }
104 throw std::logic_error{"Unknown move-run cadence error"};
105 }
106
108 template <typename ManifoldType>
109 requires(ManifoldType::dimension == 3)
110 struct MoveCommandResults
111 {
112 using Counter = move_tracker::MoveTracker;
113
114 Counter attempted;
115 Counter succeeded;
116 Counter failed;
117 };
118
120 template <typename ManifoldType>
121 [[nodiscard]] auto accumulate_command_results(
122 MoveCommandResults<ManifoldType> totals,
123 MoveCommandResults<ManifoldType> const& delta)
124 -> MoveCommandResults<ManifoldType>
125 {
126 totals.attempted += delta.attempted;
127 totals.succeeded += delta.succeeded;
128 totals.failed += delta.failed;
129 return totals;
130 }
131
133 template <typename ManifoldType, typename Command>
134 [[nodiscard]] auto consume_command_results(Command& command)
135 -> MoveCommandResults<ManifoldType>
136 {
137 MoveCommandResults<ManifoldType> result{.attempted = command.attempted(),
138 .succeeded = command.succeeded(),
139 .failed = command.failed()};
140 command.reset_counters();
141 return result;
142 }
143
145 template <typename ManifoldType, typename StrategyState>
146 struct MovePassResult
147 {
148 ManifoldType manifold;
149 MoveCommandResults<ManifoldType> command_results;
150 StrategyState strategy_state;
151 };
152
154 template <typename ManifoldType, typename StrategyState>
155 struct MoveRunResult
156 {
157 ManifoldType manifold;
158 MoveCommandResults<ManifoldType> command_results;
159 StrategyState strategy_state;
160 Int_precision checkpoint_events{};
161 };
162
164 struct MoveRunIdentity
165 {
166 std::string_view algorithm;
167 cdt::RandomSeed seed;
168 cdt::RandomStream stream;
169 };
170
176 template <typename ManifoldType, typename StrategyState,
177 typename ExecutePass, typename Report, typename Checkpoint>
178 [[nodiscard]] auto execute_move_run(ManifoldType initial,
179 StrategyState initial_strategy_state,
180 MoveRunCadence const cadence,
181 MoveRunIdentity const identity,
182 bool const writes_files,
183 ExecutePass execute_pass, Report report,
184 Checkpoint checkpoint)
185 -> MoveRunResult<ManifoldType, StrategyState>
186 {
187 auto current = std::move(initial);
188 auto command_totals = MoveCommandResults<ManifoldType>{};
189 auto strategy_state = std::move(initial_strategy_state);
190 auto checkpoint_events = Int_precision{};
191
192 fmt::print("Starting {} algorithm in {}+1 dimensions ...\n",
193 identity.algorithm, ManifoldType::dimension - 1);
194 fmt::print("Effective random seed: {} (stream {}).\n", identity.seed,
195 identity.stream);
196 fmt::print("Making random moves ...\n");
197
198 for (auto pass_index = Int_precision{}; pass_index < cadence.passes();
199 ++pass_index)
200 {
201 auto const pass_number = pass_index + 1;
202 fmt::print("=== Pass {} ===\n", pass_number);
203 auto const attempts = current.N3();
204 auto pass = std::invoke(execute_pass, std::move(current),
205 std::move(strategy_state), attempts);
206 current = std::move(pass.manifold);
207 command_totals = accumulate_command_results(std::move(command_totals),
208 pass.command_results);
209 strategy_state = std::move(pass.strategy_state);
210
211 if (pass_number % cadence.checkpoint() == 0)
212 {
213 ++checkpoint_events;
214 std::invoke(report, std::as_const(current),
215 std::as_const(command_totals),
216 std::as_const(strategy_state));
217 if (writes_files)
218 {
219 fmt::print("Writing checkpoint for pass {}.\n", pass_number);
220 std::invoke(checkpoint, std::as_const(current),
221 std::as_const(command_totals),
222 std::as_const(strategy_state), pass_number);
223 }
224 }
225 }
226
227 fmt::print("=== Run results ===\n");
228 std::invoke(report, std::as_const(current), std::as_const(command_totals),
229 std::as_const(strategy_state));
230 return {.manifold = std::move(current),
231 .command_results = std::move(command_totals),
232 .strategy_state = std::move(strategy_state),
233 .checkpoint_events = checkpoint_events};
234 }
235 } // namespace detail
236} // namespace cdt
237
238#endif // CDT_PLUSPLUS_MOVE_RUN_HPP
auto execute_move_run(ManifoldType initial, StrategyState initial_strategy_state, MoveRunCadence const cadence, MoveRunIdentity const identity, bool const writes_files, ExecutePass execute_pass, Report report, Checkpoint checkpoint) -> MoveRunResult< ManifoldType, StrategyState >
Execute shared pass, accounting, checkpoint, and report cadence.
Definition Move_run.hpp:178
auto consume_command_results(Command &command) -> MoveCommandResults< ManifoldType >
Consume cumulative MoveCommand counters exactly once.
Definition Move_run.hpp:134
auto accumulate_command_results(MoveCommandResults< ManifoldType > totals, MoveCommandResults< ManifoldType > const &delta) -> MoveCommandResults< ManifoldType >
Add one pass delta to accumulated command results.
Definition Move_run.hpp:121
auto parse_move_run_cadence(Int_precision const passes, Int_precision const checkpoint, std::string_view const strategy_name) -> MoveRunCadence
Convert a raw constructor boundary or throw its established error.
Definition Move_run.hpp:88
Track ergodic moves.
Run-owned random-number generation and reproducible stream splitting.
Positive pass count and checkpoint interval for a move run.
Definition Move_run.hpp:37
constexpr auto passes() const noexcept
Definition Move_run.hpp:77
MoveRunCadence()=default
Construct the valid single-pass default cadence.
static auto parse(Int_precision const passes, Int_precision const checkpoint) noexcept -> std::expected< MoveRunCadence, MoveRunCadenceError >
Parse raw counts into a cadence that proves positivity.
Definition Move_run.hpp:61
constexpr auto checkpoint() const noexcept
Definition Move_run.hpp:80
The data and methods to track ergodic moves.
clang-15 does not support std::format
std::int32_t Int_precision
Definition Settings.hpp:30
MoveRunCadenceError
Reasons raw move-run cadence cannot become a domain value.
Definition Move_run.hpp:28
@ NONPOSITIVE_CHECKPOINT
The checkpoint interval is not positive.
Definition Move_run.hpp:30
@ NONPOSITIVE_PASSES
The requested pass count is not positive.
Definition Move_run.hpp:29