Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
sample_region_runtime.hpp
Go to the documentation of this file.
1#pragma once
2
5
6#include <atomic>
7#include <cstddef>
8#include <cstdint>
9#include <map>
10#include <memory>
11#include <span>
12#include <string>
13#include <vector>
14
15namespace pulp::host {
16
17// The identity of one persistent scalar-kernel state cell. Runtime edits may
18// retain a cell only when every field is identical; changing an exact kernel
19// version deliberately creates fresh state.
23 std::string type_id;
24 int version = 0;
25
26 friend bool operator==(const SampleRegionStateKey&, const SampleRegionStateKey&) = default;
27 friend bool operator<(const SampleRegionStateKey& lhs,
28 const SampleRegionStateKey& rhs) noexcept;
29};
30
32 public:
36
37 static std::shared_ptr<SampleRegionStateCell> create(SampleRegionStateKey key,
40 double sample_rate,
41 std::uint32_t max_block_size) noexcept;
42
43 const SampleRegionStateKey& key() const noexcept {
44 return key_;
45 }
46 const SampleKernelDescriptor& descriptor() const noexcept {
47 return descriptor_;
48 }
49 const PreparedSampleKernelConfig& config() const noexcept {
50 return config_;
51 }
52 void* data() noexcept {
53 return storage_;
54 }
55 const void* data() const noexcept {
56 return storage_;
57 }
58 std::size_t size() const noexcept {
59 return descriptor_.state_size;
60 }
61 std::size_t alignment() const noexcept {
62 return descriptor_.state_alignment;
63 }
64 void reset() noexcept;
65
66 private:
68 PreparedSampleKernelConfig config, void* storage) noexcept;
69
71 SampleKernelDescriptor descriptor_;
73 void* storage_ = nullptr;
74 bool constructed_ = false;
75};
76
77// One execution lineage is shared by every snapshot that adopts any cell from
78// that lineage. Admission spans the complete graph dispatch and worker join.
80 public:
81 class Admission final {
82 public:
83 Admission() = default;
84 Admission(const Admission&) = delete;
85 Admission& operator=(const Admission&) = delete;
86 Admission(Admission&& other) noexcept;
87 Admission& operator=(Admission&& other) noexcept;
89
90 explicit operator bool() const noexcept {
91 return domain_ != nullptr;
92 }
93
94 private:
96 explicit Admission(SampleRegionExecutionDomain* domain) noexcept : domain_(domain) {}
97 void release() noexcept;
98 SampleRegionExecutionDomain* domain_ = nullptr;
99 };
100
104
105 // Fails immediately on contention and rejects an older binding after a
106 // newer generation has been admitted. It never spins or blocks.
107 Admission try_admit(std::uint64_t binding_generation) noexcept;
108 std::uint64_t adopted_generation() const noexcept {
109 return adopted_generation_.load(std::memory_order_relaxed);
110 }
111
112 private:
113 friend class Admission;
114 void leave() noexcept {
115 busy_.clear(std::memory_order_release);
116 }
117 std::atomic_flag busy_ = ATOMIC_FLAG_INIT;
118 std::atomic<std::uint64_t> adopted_generation_{0};
119};
120
122 public:
123 using CellMap = std::map<SampleRegionStateKey, std::shared_ptr<SampleRegionStateCell>>;
124
127
128 static std::shared_ptr<SampleRegionStateBank>
129 create_fresh(std::span<const PreparedSampleRegionPlan> plans, double sample_rate,
130 std::uint32_t max_block_size, std::uint64_t binding_generation) noexcept;
131
132 // Builds a new immutable bank view. Exact-key cells and the execution
133 // domain are shared without dereferencing, copying, or resetting cell bytes.
134 static std::shared_ptr<SampleRegionStateBank>
135 adopt(std::span<const PreparedSampleRegionPlan> plans, const SampleRegionStateBank& live,
136 double sample_rate, std::uint32_t max_block_size,
137 std::uint64_t binding_generation) noexcept;
138
139 std::shared_ptr<SampleRegionStateCell> cell(const SampleRegionStateKey& key) const noexcept;
140 std::span<const std::shared_ptr<SampleRegionStateCell>> ordered_cells() const noexcept {
141 return ordered_cells_;
142 }
144 return *domain_;
145 }
146 std::uint64_t binding_generation() const noexcept {
147 return binding_generation_;
148 }
149 std::uint64_t state_bytes() const noexcept {
150 return state_bytes_;
151 }
152 bool was_retained(const SampleRegionStateKey& key) const noexcept;
153 void reset() noexcept;
154
155 private:
157 std::uint64_t binding_generation) noexcept;
158 static bool populate(SampleRegionStateBank& bank,
159 std::span<const PreparedSampleRegionPlan> plans,
160 const SampleRegionStateBank* live, double sample_rate,
161 std::uint32_t max_block_size) noexcept;
162
163 std::shared_ptr<SampleRegionExecutionDomain> domain_;
164 std::uint64_t binding_generation_ = 0;
165 std::uint64_t state_bytes_ = 0;
166 CellMap cells_;
167 std::map<SampleRegionStateKey, bool> retained_;
168 std::vector<std::shared_ptr<SampleRegionStateCell>> ordered_cells_;
169};
170
180
182 public:
185
186 static std::shared_ptr<PreparedSampleRegion>
187 create(PreparedSampleRegionPlan plan, std::shared_ptr<SampleRegionStateBank> bank,
188 const SampleRegionParameterBinding* parameters) noexcept;
189
190 SampleRegionId region_id() const noexcept {
191 return plan_.region_id;
192 }
193 const PreparedSampleRegionPlan& plan() const noexcept {
194 return plan_;
195 }
196 const SampleRegionRuntimeReceipt& receipt() const noexcept {
197 return receipt_;
198 }
199 const std::shared_ptr<SampleRegionStateBank>& bank() const noexcept {
200 return bank_;
201 }
202
203 // Block callback used by the one fused quotient binding. All storage is
204 // prepared up front; the call is allocation-free and lock-free.
206 int num_samples) noexcept;
207
208 private:
209 struct BoundarySlot {
210 std::uint32_t boundary_index = 0;
211 std::uint32_t slot = 0;
212 };
213 struct KernelRuntime {
214 const PreparedSampleKernelBinding* binding = nullptr;
215 std::shared_ptr<SampleRegionStateCell> cell_keepalive;
216 void* state = nullptr;
217 };
218
219 PreparedSampleRegion(PreparedSampleRegionPlan plan, std::shared_ptr<SampleRegionStateBank> bank,
220 const SampleRegionParameterBinding* parameters) noexcept;
221 bool finish_prepare() noexcept;
222
223 PreparedSampleRegionPlan plan_;
224 std::shared_ptr<SampleRegionStateBank> bank_;
225 const SampleRegionParameterBinding* parameters_ = nullptr;
226 std::vector<KernelRuntime> kernels_;
227 std::vector<float> scalar_slots_;
228 std::vector<float> promoted_values_;
229 std::vector<BoundarySlot> input_boundaries_;
230 std::vector<BoundarySlot> output_boundaries_;
231 SampleRegionRuntimeReceipt receipt_;
232};
233
234} // namespace pulp::host
Non-owning view over multi-channel audio sample data.
Definition buffer.hpp:30
PreparedSampleRegion(const PreparedSampleRegion &)=delete
const SampleRegionRuntimeReceipt & receipt() const noexcept
Definition sample_region_runtime.hpp:196
const std::shared_ptr< SampleRegionStateBank > & bank() const noexcept
Definition sample_region_runtime.hpp:199
SampleRegionId region_id() const noexcept
Definition sample_region_runtime.hpp:190
PreparedSampleRegion & operator=(const PreparedSampleRegion &)=delete
static std::shared_ptr< PreparedSampleRegion > create(PreparedSampleRegionPlan plan, std::shared_ptr< SampleRegionStateBank > bank, const SampleRegionParameterBinding *parameters) noexcept
const PreparedSampleRegionPlan & plan() const noexcept
Definition sample_region_runtime.hpp:193
void process(audio::BufferView< float > &output, const audio::BufferView< const float > &input, int num_samples) noexcept
Definition sample_region_runtime.hpp:81
friend class SampleRegionExecutionDomain
Definition sample_region_runtime.hpp:95
Admission & operator=(Admission &&other) noexcept
Admission & operator=(const Admission &)=delete
Definition sample_region_runtime.hpp:79
Admission try_admit(std::uint64_t binding_generation) noexcept
std::uint64_t adopted_generation() const noexcept
Definition sample_region_runtime.hpp:108
Definition sample_region_parameters.hpp:80
std::uint64_t binding_generation() const noexcept
Definition sample_region_runtime.hpp:146
bool was_retained(const SampleRegionStateKey &key) const noexcept
static std::shared_ptr< SampleRegionStateBank > adopt(std::span< const PreparedSampleRegionPlan > plans, const SampleRegionStateBank &live, double sample_rate, std::uint32_t max_block_size, std::uint64_t binding_generation) noexcept
SampleRegionStateBank & operator=(const SampleRegionStateBank &)=delete
SampleRegionStateBank(const SampleRegionStateBank &)=delete
std::span< const std::shared_ptr< SampleRegionStateCell > > ordered_cells() const noexcept
Definition sample_region_runtime.hpp:140
std::map< SampleRegionStateKey, std::shared_ptr< SampleRegionStateCell > > CellMap
Definition sample_region_runtime.hpp:123
std::uint64_t state_bytes() const noexcept
Definition sample_region_runtime.hpp:149
SampleRegionExecutionDomain & domain() const noexcept
Definition sample_region_runtime.hpp:143
std::shared_ptr< SampleRegionStateCell > cell(const SampleRegionStateKey &key) const noexcept
static std::shared_ptr< SampleRegionStateBank > create_fresh(std::span< const PreparedSampleRegionPlan > plans, double sample_rate, std::uint32_t max_block_size, std::uint64_t binding_generation) noexcept
Definition sample_region_runtime.hpp:31
const SampleRegionStateKey & key() const noexcept
Definition sample_region_runtime.hpp:43
SampleRegionStateCell(const SampleRegionStateCell &)=delete
static std::shared_ptr< SampleRegionStateCell > create(SampleRegionStateKey key, const SampleKernelDescriptor &descriptor, const PreparedSampleKernelConfig &config, double sample_rate, std::uint32_t max_block_size) noexcept
std::size_t alignment() const noexcept
Definition sample_region_runtime.hpp:61
const SampleKernelDescriptor & descriptor() const noexcept
Definition sample_region_runtime.hpp:46
std::size_t size() const noexcept
Definition sample_region_runtime.hpp:58
const void * data() const noexcept
Definition sample_region_runtime.hpp:55
SampleRegionStateCell & operator=(const SampleRegionStateCell &)=delete
const PreparedSampleKernelConfig & config() const noexcept
Definition sample_region_runtime.hpp:49
void * data() noexcept
Definition sample_region_runtime.hpp:52
std::uint32_t NodeId
Definition graph_types.hpp:7
Bounded event contracts shared by host ingress and graph-authored nodes.
Definition anticipation_eligibility.hpp:9
std::uint32_t SampleRegionId
Definition sample_region_proof.hpp:13
SequencerStateChannel is the audio-safe transport for a plugin's structured NON-parameter state: the ...
Definition audio_device_manager.hpp:48
STL namespace.
Definition sample_region_plan.hpp:10
Definition custom_node_type.hpp:346
Definition sample_region_plan.hpp:45
Definition custom_node_type.hpp:386
Definition sample_region_proof.hpp:88
Definition sample_region_runtime.hpp:171
std::uint32_t scalar_slots
Definition sample_region_runtime.hpp:176
std::uint64_t private_boundary_copy_bytes
Definition sample_region_runtime.hpp:175
SampleRegionId region_id
Definition sample_region_runtime.hpp:172
SampleRegionResourceStats resources
Definition sample_region_runtime.hpp:173
std::uint32_t retained_state_cells
Definition sample_region_runtime.hpp:177
std::uint64_t physical_executor_bytes
Definition sample_region_runtime.hpp:174
std::uint32_t fresh_state_cells
Definition sample_region_runtime.hpp:178
Definition sample_region_runtime.hpp:20
std::string type_id
Definition sample_region_runtime.hpp:23
friend bool operator==(const SampleRegionStateKey &, const SampleRegionStateKey &)=default
SampleRegionId region_id
Definition sample_region_runtime.hpp:21
friend bool operator<(const SampleRegionStateKey &lhs, const SampleRegionStateKey &rhs) noexcept
NodeId node
Definition sample_region_runtime.hpp:22
int version
Definition sample_region_runtime.hpp:24