Aleph-w 3.0
A C++ Library for Data Structures and Algorithms
Loading...
Searching...
No Matches
ca_parallel_gol_example.cc
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
46#include <cstdio>
47#include <cstdlib>
48
49#include <ca-engine-utils.H>
50#include <tpl_ca_engine.H>
51#include <tpl_ca_lattice.H>
52#include <tpl_ca_neighborhood.H>
54#include <tpl_ca_rule.H>
55#include <tpl_ca_storage.H>
56
57using namespace Aleph;
58using namespace Aleph::CA;
59
61
62namespace {
63
65{
66 // Coordinates of every alive cell in Gosper's classic 36-cell gun,
67 // relative to the top-left of the bounding box.
68 static constexpr int gun[][2] = {
69 {0, 24}, {1, 22}, {1, 24}, {2, 12}, {2, 13}, {2, 20}, {2, 21}, {2, 34},
70 {2, 35}, {3, 11}, {3, 15}, {3, 20}, {3, 21}, {3, 34}, {3, 35}, {4, 0},
71 {4, 1}, {4, 10}, {4, 16}, {4, 20}, {4, 21}, {5, 0}, {5, 1}, {5, 10},
72 {5, 14}, {5, 16}, {5, 17}, {5, 22}, {5, 24}, {6, 10}, {6, 16}, {6, 24},
73 {7, 11}, {7, 15}, {8, 12}, {8, 13},
74 };
75 for (const auto &p : gun)
76 lat.set({row0 + p[0], col0 + p[1]}, 1);
77}
78
79void print_frame(const Lat_t &lat, std::size_t step, bool sparse_only = false)
80{
81 std::size_t alive = 0;
82 for (std::size_t i = 0; i < lat.size(0); ++i)
83 for (std::size_t j = 0; j < lat.size(1); ++j)
84 if (lat.at({static_cast<ca_index_t>(i), static_cast<ca_index_t>(j)}) != 0)
85 ++alive;
86
87 std::printf("\nStep %4zu alive=%zu\n", step, alive);
88 if (sparse_only)
89 return;
90
91 for (std::size_t i = 0; i < lat.size(0); ++i)
92 {
93 for (std::size_t j = 0; j < lat.size(1); ++j)
94 std::putchar(
95 lat.at({static_cast<ca_index_t>(i), static_cast<ca_index_t>(j)}) != 0
96 ? '#'
97 : '.');
98 std::putchar('\n');
99 }
100}
101
102bool frames_equal(const Lat_t &a, const Lat_t &b)
103{
104 if (a.extents() != b.extents())
105 return false;
106 for (std::size_t i = 0; i < a.size(0); ++i)
107 for (std::size_t j = 0; j < a.size(1); ++j)
108 if (a.at({static_cast<ca_index_t>(i), static_cast<ca_index_t>(j)})
109 != b.at({static_cast<ca_index_t>(i), static_cast<ca_index_t>(j)}))
110 return false;
111 return true;
112}
113
114} // namespace
115
116int main()
117{
118 constexpr std::size_t rows = 60;
119 constexpr std::size_t cols = 80;
120 constexpr std::size_t steps = 240;
121
122 Lat_t seed({rows, cols}, 0);
123 stamp_glider_gun(seed, /*row0=*/2, /*col0=*/2);
124
125 std::printf("Aleph::CA Phase-5 example: parallel Game of Life with Gosper's gun\n");
126 std::printf("Grid %zux%zu, toroidal, %zu steps, hardware_concurrency=%u\n",
127 rows,
128 cols,
129 steps,
130 static_cast<unsigned>(std::thread::hardware_concurrency()));
131
132 // Parallel engine: use the global default pool, four partitions.
135 cfg.min_parallel_cells = 0;
138
139 // Snapshot every 30 steps for visual inspection. We print the very
140 // first frame, then a dense view every quarter of the run, and
141 // sparse summaries for the rest so the terminal is not overwhelmed.
142 print_frame(par.frame(), 0);
143 for (std::size_t s = 30; s <= steps; s += 30)
144 {
145 par.run(30);
146 const bool dense = (s == steps) or (s == steps / 2);
147 print_frame(par.frame(), s, /*sparse_only=*/not dense);
148 }
149
150 // Cross-check the parallel run against a sequential baseline.
153 seq.run(steps);
154
155 if (not frames_equal(par.frame(), seq.frame()))
156 {
157 std::printf("\n*** parallel and sequential frames diverged ***\n");
158 return EXIT_FAILURE;
159 }
160 std::printf("\nParallel run matched the sequential reference frame "
161 "(%zu cells / step).\n",
162 static_cast<std::size_t>(rows) * cols);
163 return EXIT_SUCCESS;
164}
size_t steps
Definition ca-c-api.h:126
size_t * rows
Definition ca-c-api.h:112
size_t cols
Definition ca-c-api.h:105
Convenience builders for the Phase 3 synchronous engine.
Lattice that adds boundary-aware access on top of a storage.
const extents_type & extents() const noexcept
ca_size_t size() const noexcept
state_type at(const coord_type &c) const
Strict access: throws if c is out of range.
Moore (Chebyshev) neighborhood of radius R in N dimensions.
Parallel synchronous double-buffered engine.
Synchronous double-buffered engine.
void run(const std::size_t steps)
Run several synchronous steps.
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
constexpr Game_Of_Life_Rule make_game_of_life_rule() noexcept
Build the canonical Game of Life rule.
std::ptrdiff_t ca_index_t
Signed coordinate component used by lattices and neighborhoods.
Definition ca-traits.H:60
bool frames_equal(const Lattice &a, const Lattice &b)
Definition ca-metrics.H:323
Main namespace for Aleph-w library functions.
Definition ah-arena.H:89
Configuration for Parallel_Synchronous_Engine.
std::size_t num_partitions
Number of partitions per step.
The lattice wraps around on every axis.
Definition ca-traits.H:124
ValueArg< size_t > seed
Definition testHash.C:53
Synchronous double-buffered engine for cellular automata.
Cellular automata lattice with pluggable boundary policies.
Neighborhoods catalogue for Aleph::CA.
Parallel synchronous engine for cellular automata (Phase 5).
Rule mechanisms for Aleph::CA.
Dense, contiguous storage for cellular automata cells (1D/2D/3D).