Skip to main content

henad_core/
metadata.rs

1//! Model metadata the engine derives from a model's declarations.
2
3use crate::authoring::model::gpu_agent_model::{BufferSpec, PassSpec};
4use crate::topology::NeighborhoodKind;
5
6/// Model backend.
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub enum Backend {
9    /// The model steps on the CPU.
10    Cpu,
11    /// The model steps on the GPU.
12    Gpu,
13}
14
15impl Backend {
16    /// Returns the label the UI shows, `CPU` or `GPU`.
17    pub fn label(self) -> &'static str {
18        match self {
19            Self::Cpu => "CPU",
20            Self::Gpu => "GPU",
21        }
22    }
23}
24
25/// One lane of a CPU agent model's struct-of-arrays storage.
26///
27/// `agent_lanes!` generates one `LaneSpec` per lane.
28#[derive(Debug, Clone, Copy)]
29pub struct LaneSpec {
30    /// Name of the lane. For a double buffered lane, this is the name of the current side.
31    pub name: &'static str,
32    /// Element type as written in the declaration.
33    pub ty: &'static str,
34    /// Whether the lane is declared `dual`, with a second side the kernel writes.
35    pub double_buffered: bool,
36}
37
38/// Storage layout of a model, by backend and topology.
39#[derive(Debug, Clone)]
40pub enum Structure {
41    /// A CPU grid model.
42    Grid {
43        /// Neighbourhood a cell's rule reads.
44        neighborhood: NeighborhoodKind,
45    },
46    /// A CPU agent model.
47    Agents {
48        /// Agents per chunk in a step pass.
49        chunk: usize,
50        /// Agent lanes, in declaration order.
51        lanes: &'static [LaneSpec],
52        /// [`crate::authoring::model::agent_model::NeighborIndex::KIND`].
53        index: &'static str,
54        /// [`crate::authoring::model::field::FieldLayer::KIND`].
55        field: &'static str,
56    },
57    /// A CPU network model.
58    Network {
59        /// Number of nodes per chunk in the node pass.
60        chunk: usize,
61        /// Node lanes, in declaration order.
62        lanes: &'static [LaneSpec],
63        /// Edge colours, indexed by each edge's colour byte.
64        edge_palette: &'static [[u8; 4]],
65    },
66    /// A GPU grid model.
67    GpuGrid {
68        /// Ping-ponged buffer labels.
69        buffers: &'static [&'static str],
70        /// Side of the square workgroup that every shader declares.
71        workgroup: u32,
72    },
73    /// A GPU agent model.
74    GpuAgents {
75        /// Storage buffers, in declaration order.
76        buffers: &'static [BufferSpec],
77        /// Passes of one step, in the order they run.
78        passes: &'static [PassSpec],
79        /// Whether the engine rebuilds a neighbour index before every step.
80        index: bool,
81        /// Whether the model declares a display pass.
82        display: bool,
83        /// Number of persistent `u32` counters.
84        counters: usize,
85    },
86}
87
88/// Model metadata that the UI displays.
89#[derive(Debug, Clone)]
90pub struct ModelMetadata {
91    /// Backend the model steps on.
92    pub backend: Backend,
93    /// Colours that the display layer or the agent population draws from. `None` for a GPU agent
94    /// model, whose shaders write RGBA directly and declare no palette.
95    pub palette: Option<&'static [[u8; 4]]>,
96    /// Storage layout of the model.
97    pub structure: Structure,
98    /// Whether two builds on one seed step through identical states. `true` for every CPU model.
99    pub replays_exactly: bool,
100}