Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
tpl_ca_async_engine.H
Go to the documentation of this file.
1/*
2 Aleph_w
3
4 Data structures & Algorithms
5 version 2.0.0b
6 https://github.com/lrleon/Aleph-w
7
8 This file is part of Aleph-w library
9
10 Copyright (c) 2002-2026 Leandro Rabindranath Leon
11
12 Permission is hereby granted, free of charge, to any person obtaining a copy
13 of this software and associated documentation files (the "Software"), to deal
14 in the Software without restriction, including without limitation the rights
15 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 copies of the Software, and to permit persons to whom the Software is
17 furnished to do so, subject to the following conditions:
18
19 The above copyright notice and this permission notice shall be included in all
20 copies or substantial portions of the Software.
21
22 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28 SOFTWARE.
29*/
30
69#ifndef TPL_CA_ASYNC_ENGINE_H
70#define TPL_CA_ASYNC_ENGINE_H
71
72#include <cstddef>
73#include <functional>
74#include <type_traits>
75#include <utility>
76
77#include <ah-errors.H>
78
79#include <ca-traits.H>
80#include <tpl_ca_concepts.H>
81#include <tpl_ca_neighborhood.H>
83
84namespace Aleph {
85namespace CA {
86
87namespace ca_async_engine_detail {
88
93template <typename Scheme, typename Engine, typename Rule>
95 = requires(const Scheme &s, Engine &e, Rule &r, ca_index_t o) { s.apply_with_origin(e, r, o); };
96
97} // namespace ca_async_engine_detail
98
109template <std::size_t Rank>
111{
112public:
114 static constexpr std::size_t rank_v = Rank;
116 static constexpr std::size_t size_v = 0;
118 static constexpr std::size_t radius_v = 0;
121
125 [[nodiscard]] static constexpr std::size_t radius() noexcept
126 {
127 return 0;
128 }
129
133 [[nodiscard]] static constexpr std::size_t size() noexcept
134 {
135 return 0;
136 }
137
141 template <typename F>
142 static constexpr void for_each_offset(const coord_type &, F &&) noexcept
143 {}
144};
145
161template <typename Lattice, typename Rule, typename Neighborhood, typename Update_Scheme = Synchronous_Update<RowMajor>>
163{
164 static_assert(LatticeLike<Lattice>, "Async_Engine requires a LatticeLike lattice");
165 static_assert(NeighborhoodLike<Neighborhood>,
166 "Async_Engine requires a NeighborhoodLike neighborhood (use Null_Neighborhood for "
167 "block rules)");
168 static_assert(Neighborhood::rank_v == Lattice::rank, "Neighborhood rank must match lattice rank");
169
170public:
172 using rule_type = Rule;
175
179
181 static constexpr std::size_t rank = Lattice::rank;
182
184 using hook_type = std::function<void(std::size_t, const Lattice &)>;
185
186private:
188 Lattice nxt_; // empty for in-place schemes
189 Rule rule_;
194 std::size_t step_count_ = 0;
195
196public:
210 : cur_(std::move(initial)), rule_(std::move(r)), nh_(std::move(n)), scheme_(std::move(s))
211 {
212 if constexpr (Update_Scheme::requires_double_buffer)
214 }
215
223 requires std::default_initializable<Neighborhood>
224 : Async_Engine(std::move(initial), std::move(r), Neighborhood{}, std::move(s))
225 {}
226
229 {
230 return cur_;
231 }
232
235 {
236 return step_count_;
237 }
238
241 {
242 return cur_.extents();
243 }
244
247 {
248 return nh_;
249 }
250
253 {
254 return cur_;
255 }
256
259 {
260 return cur_;
261 }
262
265 {
266 return cur_;
267 }
268
275 void set_step_count(const std::size_t s) noexcept
276 {
277 step_count_ = s;
278 }
279
283 {
284 return nxt_;
285 }
286
289 {
290 return rule_;
291 }
292
294 [[nodiscard]] const Rule &rule() const noexcept
295 {
296 return rule_;
297 }
298
301 {
302 return scheme_;
303 }
304
307 {
308 return step_count_;
309 }
310
313 {
314 cur_.swap(nxt_);
315 }
316
321 template <typename F>
322 void on_pre_step(F &&f)
323 {
324 pre_hook_ = std::forward<F>(f);
325 }
326
331 template <typename F>
332 void on_post_step(F &&f)
333 {
334 post_hook_ = std::forward<F>(f);
335 }
336
346 void step()
347 {
348 if constexpr (HasRefreshHalo<Lattice>)
349 cur_.refresh_halo();
350
351 if (pre_hook_)
353
354 scheme_.apply(*this, rule_);
355 ++step_count_;
356
357 if (post_hook_)
359 }
360
375 requires ca_async_engine_detail::HasApplyWithOrigin<Update_Scheme, Async_Engine, Rule>
376 {
377 ah_out_of_range_error_if(step_count_ == 0) << "Async_Engine::step_back: no step to reverse";
378
379 --step_count_;
380 if constexpr (HasRefreshHalo<Lattice>)
381 cur_.refresh_halo();
382
383 if (pre_hook_)
385
386 scheme_.apply_with_origin(*this, rule_, Update_Scheme::origin_for_step(step_count_));
387
388 if (post_hook_)
390 }
391
396 void run(const std::size_t steps)
397 {
398 for (std::size_t i = 0; i < steps; ++i)
399 step();
400 }
401
406 void run_back(const std::size_t steps)
408 {
409 for (std::size_t i = 0; i < steps; ++i)
410 step_back();
411 }
412};
413
414} // namespace CA
415} // namespace Aleph
416
417#endif // TPL_CA_ASYNC_ENGINE_H
Exception handling system with formatted messages for Aleph-w.
#define ah_out_of_range_error_if(C)
Throws std::out_of_range if condition holds.
Definition ah-errors.H:584
size_t steps
Definition ca-c-api.h:126
Common typedefs and tag types for the Cellular Automata module.
Update-scheme aware engine.
const Lattice & frame() const noexcept
Lattice & current_buffer() noexcept
void step_back()
Reverse the most recent step (Margolus only).
std::size_t step_count() const noexcept
void swap_buffers() noexcept(noexcept(cur_.swap(nxt_)))
O(1) swap of the two buffers (called by double-buffer schemes).
const Neighborhood & neighborhood() const noexcept
const Update_Scheme & scheme() const noexcept
typename Lattice::extents_type extents_type
void on_post_step(F &&f)
Register a hook fired after every step().
Lattice & next_buffer() noexcept
void step()
Run one engine step using the configured update scheme.
void set_step_count(const std::size_t s) noexcept
Override the completed-step counter.
void on_pre_step(F &&f)
Register a hook fired before every step().
Async_Engine(Lattice initial, Rule r, Update_Scheme s={})
Build an engine with a default-constructed neighborhood.
void run_back(const std::size_t steps)
Reverse several steps (Margolus only).
typename Lattice::coord_type coord_type
std::size_t steps_run() const noexcept
std::function< void(std::size_t, const Lattice &)> hook_type
Hook signature: (step_index, frame).
const Lattice & current_buffer() const noexcept
typename Lattice::state_type state_type
void run(const std::size_t steps)
Run several steps.
Async_Engine(Lattice initial, Rule r, Neighborhood n, Update_Scheme s={})
Build an engine.
Lattice & write_lattice() noexcept
Alias for current_buffer(). Used by checkpoint restore.
const extents_type & extents() const noexcept
static constexpr std::size_t rank
Lattice dimension.
const Rule & rule() const noexcept
Lattice that adds boundary-aware access on top of a storage.
typename Storage::state_type state_type
typename Storage::extents_type extents_type
const extents_type & extents() const noexcept
void swap(Lattice &other) noexcept(noexcept(store_.swap(other.store_)))
O(1) swap.
typename Storage::coord_type coord_type
static constexpr std::size_t rank
Placeholder neighbourhood for engines that drive block rules.
static constexpr std::size_t size_v
Empty neighbourhood: zero offsets.
static constexpr std::size_t radius() noexcept
Always returns 0 (no offsets).
static constexpr void for_each_offset(const coord_type &, F &&) noexcept
No-op: the neighbourhood is empty.
static constexpr std::size_t rank_v
Lattice dimension.
static constexpr std::size_t radius_v
Compile-time radius (zero, since the neighbourhood is empty).
static constexpr std::size_t size() noexcept
Always returns 0 (no offsets).
Coord_Vec< Rank > coord_type
Coordinate type accepted by for_each_offset.
Detect whether a lattice exposes a refresh_halo() method (the hallmark of a Ghost_Lattice or any othe...
Storage + topology that carries the cell values.
Connectivity pattern around a coordinate.
Detect whether the scheme exposes apply_with_origin(engine, rule, origin) (Margolus).
size_t blossom_maximum_cardinality_matching(const GT &g, DynDlist< typename GT::Arc * > &matching, SA sa=SA())
Alias of compute_maximum_cardinality_general_matching().
Definition Blossom.H:466
std::ptrdiff_t ca_index_t
Signed coordinate component used by lattices and neighborhoods.
Definition ca-traits.H:60
std::array< ca_index_t, N > Coord_Vec
Default coordinate vector.
Definition ca-traits.H:69
void swap(Bit_Cell_Storage< N > &a, Bit_Cell_Storage< N > &b) noexcept
Free-function swap so the storage plays nicely with std::swap.
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
STL namespace.
gsl_rng * r
C++20 concepts for the Cellular Automata module.
Neighborhoods catalogue for Aleph::CA.
Phase 13 update-scheme strategies for Aleph::CA.