Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
gpu_wavenet.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cstddef>
4#include <cstdint>
5#include <limits>
6#include <memory>
7#include <optional>
8#include <span>
9#include <string>
10
11namespace pulp::gpu_audio {
12
13namespace detail {
14struct GpuWaveNetSessionAccess;
15struct GpuWaveNetSessionTestAccess;
16struct GpuWaveNetSessionPoolAccess;
17} // namespace detail
18
19// Model-neutral shape accepted by the first provider-owned WaveNet adapter.
20// The execution object remains private to the provider; consumers pass only
21// immutable metadata and the flat weight count through this boundary.
23 std::uint32_t input_size = 0;
24 std::uint32_t condition_size = 0;
25 std::uint32_t channels = 0;
26 std::uint32_t kernel = 0;
27 std::uint32_t head_size = 0;
28 // Retained for source compatibility with the first one-layer descriptor.
29 // Multi-layer arrays leave this zero and provide dilations below.
30 std::uint32_t dilation = 0;
31 bool gated = false;
32 bool head_bias = false;
33 bool tanh_activation = false;
34 std::span<const std::uint32_t> dilations;
35};
36
37// Semantic alias for callers describing a full WaveNet layer array. The
38// original public name remains valid and retains its aggregate field order.
40
42 std::uint32_t block_size = 0;
43 std::uint32_t sample_rate = 0;
44 std::uint32_t stream_instances = 0;
45 float head_scale = 1.0f;
46 std::span<const GpuWaveNetLayerDescriptor> layers;
47 std::size_t weight_count = 0;
48};
49
58
61
62 constexpr bool accepted() const noexcept {
64 }
65};
66
84
85enum class GpuWaveNetBlockStatus : std::uint8_t {
88};
89
101
107
122 public:
134
136 std::unique_ptr<GpuWaveNetSession> session;
138
139 explicit operator bool() const noexcept {
140 return session != nullptr && error == GpuWaveNetSessionError::None;
141 }
142 };
143
144 static CreateResult create(const Config& config) noexcept;
146
149
150 bool prepared() const noexcept;
151 std::uint32_t block_size() const noexcept;
156 bool completion_policy_supported() const noexcept;
157
160 bool submit_block(std::span<const float> input, std::uint64_t sequence,
161 std::uint64_t deadline_ns = 0) noexcept;
162
165 std::size_t service(std::uint64_t now_ns) noexcept;
166
169 std::size_t service_until(std::uint64_t deadline_ns) noexcept;
170
173 std::optional<GpuWaveNetBlockResult> receive(std::span<float> output) noexcept;
174
177 bool release() noexcept;
178
184 bool release_bounded(std::uint64_t budget_ns) noexcept;
185
189 bool device_lost() const noexcept;
190
193 std::uint64_t outstanding_blocks() const noexcept;
194
195 private:
199 // Drains a quiescent session within `budget_ns` (zero: the provider's
200 // default) and opens a fresh slot generation on the same provider and
201 // program, for GpuAudioProviderPool. False leaves it to release().
202 // Resident causal history is not cleared.
203 bool recycle(std::uint64_t budget_ns) noexcept;
204 // Provider kind and revision this session runs on, and the ones a new
205 // session would request, for GpuAudioProviderPool keys. Host only.
206 std::string provider_key() const;
207 static std::string requested_provider_key();
208 struct Impl;
209 explicit GpuWaveNetSession(std::unique_ptr<Impl> impl) noexcept;
210 std::unique_ptr<Impl> impl_;
211};
212
213// The first public adapter is deliberately narrow. Unsupported NAM models
214// must remain on the continuously prepared CPU fallback rather than silently
215// entering a provider path with the wrong state layout.
216constexpr GpuWaveNetValidation
218 if (descriptor.block_size == 0 || descriptor.sample_rate == 0 ||
219 descriptor.stream_instances != 1 || descriptor.layers.empty() ||
220 descriptor.weight_count == 0)
221 return {GpuWaveNetError::InvalidShape};
222 std::uint64_t required = 1u; // trailing serialized head scale
223 for (std::size_t index = 0; index < descriptor.layers.size(); ++index) {
224 const auto& array = descriptor.layers[index];
225 const auto expected_input = index == 0 ? 1u : descriptor.layers[index - 1].channels;
226 if (array.input_size != expected_input || array.condition_size != 1 ||
227 array.channels == 0 || array.channels > 64 || array.kernel == 0 ||
228 array.head_size == 0 || !array.tanh_activation ||
229 (array.dilation == 0 && array.dilations.empty()) ||
230 (array.dilation != 0 && !array.dilations.empty()))
232 if (index > 0 && descriptor.layers[index - 1].head_size != array.channels)
234
235 const auto z = array.gated ? 2ull * array.channels : array.channels;
236 required += static_cast<std::uint64_t>(array.channels) * array.input_size;
237 const auto dilation_count = array.dilations.empty() ? 1u : array.dilations.size();
238 for (std::size_t dilation_index = 0; dilation_index < dilation_count; ++dilation_index) {
239 const auto dilation =
240 array.dilations.empty() ? array.dilation : array.dilations[dilation_index];
241 if (dilation == 0)
243 const auto reach = static_cast<std::uint64_t>(array.kernel - 1u) * dilation;
244 if (reach > std::numeric_limits<std::uint32_t>::max() - descriptor.block_size)
246 required += z * array.channels * array.kernel + z + z * array.condition_size +
247 static_cast<std::uint64_t>(array.channels) * array.channels +
248 array.channels;
249 if (required > std::numeric_limits<std::uint32_t>::max())
251 }
252 required += static_cast<std::uint64_t>(array.head_size) * array.channels;
253 if (array.head_bias)
254 required += array.head_size;
255 if (required >= std::numeric_limits<std::uint32_t>::max())
257 }
258 if (descriptor.layers.back().head_size != 1)
259 return {GpuWaveNetError::UnsupportedTopology};
260 if (required != descriptor.weight_count)
261 return {GpuWaveNetError::WeightBlobMismatch};
262 return {};
263}
264
265} // namespace pulp::gpu_audio
friend struct detail::GpuWaveNetSessionPoolAccess
Definition gpu_wavenet.hpp:198
std::uint32_t block_size() const noexcept
friend struct detail::GpuWaveNetSessionAccess
Definition gpu_wavenet.hpp:196
GpuWaveNetSession(const GpuWaveNetSession &)=delete
bool release_bounded(std::uint64_t budget_ns) noexcept
release() that bounds the provider's physical drain to budget_ns.
static CreateResult create(const Config &config) noexcept
std::size_t service_until(std::uint64_t deadline_ns) noexcept
Services completions until the supplied steady-clock deadline.
bool completion_policy_supported() const noexcept
True when the provider accepted the requested policy without fallback.
friend struct detail::GpuWaveNetSessionTestAccess
Definition gpu_wavenet.hpp:197
GpuWaveNetCompletionPolicy completion_policy() const noexcept
Returns the requested policy.
std::size_t service(std::uint64_t now_ns) noexcept
Services already-submitted provider work without waiting for a future completion.
std::optional< GpuWaveNetBlockResult > receive(std::span< float > output) noexcept
Copies one completed block into output and releases its shared slot.
bool submit_block(std::span< const float > input, std::uint64_t sequence, std::uint64_t deadline_ns=0) noexcept
Copies one mono block into a persistent shared slot and submits it to the authenticated provider.
std::uint64_t outstanding_blocks() const noexcept
Blocks accepted by submit_block() whose result receive() has not yet returned, whether delivered or f...
bool device_lost() const noexcept
True once the provider has observed loss of its device.
GpuWaveNetSession & operator=(const GpuWaveNetSession &)=delete
bool release() noexcept
Host/quiescent-only release.
bool prepared() const noexcept
Definition gpu_audio_node.hpp:78
Definition flow_pans.hpp:19
GpuWaveNetLayerDescriptor GpuWaveNetLayerArrayDescriptor
Definition gpu_wavenet.hpp:39
@ GpuDelivered
Definition gpu_audio_program.hpp:29
GpuWaveNetBlockStatus
Definition gpu_wavenet.hpp:85
@ ProviderFailed
Definition gpu_wavenet.hpp:87
constexpr GpuWaveNetValidation validate_gpu_wavenet_descriptor(const GpuWaveNetDescriptor &descriptor) noexcept
Definition gpu_wavenet.hpp:217
@ None
Definition gpu_audio_capability.hpp:75
GpuWaveNetError
Definition gpu_wavenet.hpp:50
@ WeightBlobMismatch
Definition gpu_wavenet.hpp:55
@ None
Definition gpu_wavenet.hpp:51
@ UnsupportedTopology
Definition gpu_wavenet.hpp:53
@ ResourceOverflow
Definition gpu_wavenet.hpp:56
@ UnsupportedActivation
Definition gpu_wavenet.hpp:54
GpuWaveNetSessionError
Errors returned while constructing or operating a one-stream shared WaveNet session.
Definition gpu_wavenet.hpp:70
@ NoSlot
Definition gpu_wavenet.hpp:79
@ SubmissionRejected
Definition gpu_wavenet.hpp:80
@ ProgramUnavailable
Definition gpu_wavenet.hpp:75
@ ProviderUnavailable
Definition gpu_wavenet.hpp:74
@ ReleaseFailed
Definition gpu_wavenet.hpp:82
@ NotPrepared
Definition gpu_wavenet.hpp:77
@ InvalidDescriptor
Definition gpu_wavenet.hpp:72
@ None
Definition gpu_wavenet.hpp:71
@ InvalidWeights
Definition gpu_wavenet.hpp:73
@ PreparationFailed
Definition gpu_wavenet.hpp:76
@ InvalidBlock
Definition gpu_wavenet.hpp:78
@ OutputTooSmall
Definition gpu_wavenet.hpp:81
GpuWaveNetCompletionPolicy
How the serialized, non-realtime dispatcher services provider completions.
Definition gpu_wavenet.hpp:91
@ ProcessEvents
Let the provider deliver finished work through its event pump on each service step.
Definition gpu_wavenet.hpp:94
@ InvalidShape
Definition gpu_audio_program.hpp:54
@ TimedWaitAny
Definition gpu_audio_status.hpp:64
@ WaitAny
Definition gpu_audio_status.hpp:63
@ ProcessEvents
Definition gpu_audio_status.hpp:62
Definition host_transport_projector.hpp:8
STL namespace.
Definition gpu_wavenet.hpp:102
bool late
Definition gpu_wavenet.hpp:105
GpuWaveNetBlockStatus status
Definition gpu_wavenet.hpp:104
std::uint64_t sequence
Definition gpu_wavenet.hpp:103
Definition gpu_wavenet.hpp:41
std::uint32_t sample_rate
Definition gpu_wavenet.hpp:43
std::uint32_t stream_instances
Definition gpu_wavenet.hpp:44
std::span< const GpuWaveNetLayerDescriptor > layers
Definition gpu_wavenet.hpp:46
std::uint32_t block_size
Definition gpu_wavenet.hpp:42
float head_scale
Definition gpu_wavenet.hpp:45
std::size_t weight_count
Definition gpu_wavenet.hpp:47
Definition gpu_wavenet.hpp:22
std::uint32_t channels
Definition gpu_wavenet.hpp:25
bool gated
Definition gpu_wavenet.hpp:31
std::uint32_t input_size
Definition gpu_wavenet.hpp:23
std::uint32_t condition_size
Definition gpu_wavenet.hpp:24
std::uint32_t kernel
Definition gpu_wavenet.hpp:26
bool head_bias
Definition gpu_wavenet.hpp:32
bool tanh_activation
Definition gpu_wavenet.hpp:33
std::span< const std::uint32_t > dilations
Definition gpu_wavenet.hpp:34
std::uint32_t head_size
Definition gpu_wavenet.hpp:27
std::uint32_t dilation
Definition gpu_wavenet.hpp:30
Definition gpu_wavenet.hpp:123
GpuWaveNetCompletionPolicy completion_policy
Selects how the non-realtime service thread waits for completions.
Definition gpu_wavenet.hpp:129
std::uint64_t completion_wait_ns
TimedWaitAny wait budget in nanoseconds.
Definition gpu_wavenet.hpp:132
std::span< const float > weights
Definition gpu_wavenet.hpp:125
GpuWaveNetDescriptor descriptor
Definition gpu_wavenet.hpp:124
std::uint32_t slots
Definition gpu_wavenet.hpp:126
GpuWaveNetSessionError error
Definition gpu_wavenet.hpp:137
std::unique_ptr< GpuWaveNetSession > session
Definition gpu_wavenet.hpp:136
Definition gpu_wavenet.hpp:59
constexpr bool accepted() const noexcept
Definition gpu_wavenet.hpp:62
GpuWaveNetError error
Definition gpu_wavenet.hpp:60