8 : m_gpu_config(
std::move(config))
64 slot.resize(byte_size);
65 std::memcpy(slot.data(), data, byte_size);
69 std::shared_ptr<Core::VKImage>
image,
76 .image = std::move(
image),
104 const std::vector<std::vector<double>>&,
110 const std::vector<std::vector<double>>&
channels,
118 const size_t fallback_bytes = float_byte_size > 0
122 std::vector<GpuResourceManager::ImageBind> image_binds;
125 const size_t idx =
b.binding;
134 const auto et =
b.element_type;
143 std::vector<uint8_t> zeros(sz, 0);
150 switch (
b.element_type) {
163 if (img->get_current_layout() != vk::ImageLayout::eGeneral) {
165 vk::ImageLayout::eGeneral);
167 image_binds.push_back({ .index = idx, .image = img, .sampler =
nullptr, .spec =
b });
175 if (img->get_current_layout() != vk::ImageLayout::eShaderReadOnlyOptimal) {
177 vk::ImageLayout::eShaderReadOnlyOptimal);
179 image_binds.push_back({ .index = idx, .image = img, .sampler = sampler, .spec =
b });
185 const size_t raw_bytes =
channels[0].size()
191 reinterpret_cast<const uint8_t*
>(
channels[0].data()),
209 if (!image_binds.empty())
216 uint64_t sz_x = 0, sz_y = 0, sz_z = 0;
217 for (
const auto& dim : structure_info.
dimensions) {
236 static_cast<uint32_t
>((sz_x + ws[0] - 1) / ws[0]),
237 sz_y > 0 ?
static_cast<uint32_t
>((sz_y + ws[1] - 1) / ws[1]) : 1U,
238 sz_z > 0 ?
static_cast<uint32_t
>((sz_z + ws[2] - 1) / ws[2]) : 1U,
242 return {
static_cast<uint32_t
>((total_elements + ws[0] - 1) / ws[0]), 1U, 1U };
250 const std::vector<std::vector<double>>&
channels,
275 const std::vector<std::vector<double>>&
channels,
300 const std::vector<std::vector<double>>&
channels,
311 std::source_location::current(),
312 "GpuDispatchCore: dispatch_core_chained_indirect GPU initialisation failed");
322 const auto indirect_it = std::ranges::find_if(
m_bindings, [](
const auto&
b) {
327 std::source_location::current(),
328 "GpuDispatchCore: dispatch_core_chained_indirect requires a binding with usage_hint INDIRECT");
342 const std::vector<std::vector<double>>&
channels,
385 auto& keys = plan.
keys;
386 auto& groups_per_key = plan.
groups;
388 auto& hazards_per_key = plan.
hazards;
389 auto& indirect_per_key = plan.
indirect;
391 keys.reserve(stages.size());
392 groups_per_key.reserve(stages.size());
393 pc_per_key.reserve(stages.size());
394 hazards_per_key.reserve(stages.size());
395 indirect_per_key.reserve(stages.size());
397 for (
const auto& stage : stages) {
406 stage.stage_fn(*
this);
411 std::source_location::current(),
412 "GpuDispatchCore: dispatch_core_dependency failed to initialise key '{}'",
413 stage.config.shader_path);
423 hazards_per_key.push_back(stage.hazard_fn ? stage.hazard_fn(*
this) : std::vector<Portal::Graphics::HazardResource> {});
426 if (stage.indirect_groups) {
428 indirect.
offset = stage.indirect_groups->offset_bytes;
430 indirect_per_key.push_back(indirect);
453 if (
b.binding != idx)
462 const size_t byte_size = std::min(float_count *
sizeof(
float), allocated);
463 std::vector<float>
out(byte_size /
sizeof(
float));
471 if (
b.skip_auto_readback)
474 const size_t idx =
b.binding;
484 std::vector<uint8_t> raw(sz);
486 result.
aux[idx] = std::move(raw);
501 const std::vector<std::vector<double>>&
channels,
511 for (
size_t i = 0; i <
m_bindings.size(); ++i) {
515 all_inputs_staged =
false;
519 if (all_inputs_staged)
535 const std::vector<Kakshya::DataVariant>& variants,
543 size_t total_bytes = 0;
544 for (
const auto& v : variants) {
545 std::visit([&](
const auto& vec) {
546 total_bytes += vec.size() *
sizeof(
typename std::decay_t<
decltype(vec)>::value_type);
553 for (
const auto& v : variants) {
554 std::visit([&](
const auto& vec) {
555 using T =
typename std::decay_t<
decltype(vec)>::value_type;
556 const auto* bytes =
reinterpret_cast<const uint8_t*
>(vec.data());
560 bytes + vec.size() *
sizeof(T));
568 size_t first_inout = SIZE_MAX;
573 && first_inout == SIZE_MAX)
574 first_inout =
b.binding;
576 if (first_inout != SIZE_MAX)
581 std::source_location::current(),
582 "GpuDispatchCore: no output buffer declared");
587 size_t max_bytes = 0;
591 const size_t idx =
b.binding;
595 return max_bytes /
sizeof(float);
std::vector< float > * out
DependencyPlan prepare_dependency(const std::vector< DependencyStage > &stages)
void readback_aux(GpuChannelResult &result)
Read back all OUTPUT bindings that have explicit size overrides into the aux map of a GpuChannelResul...
void stage_image_at(size_t binding_index, std::shared_ptr< Core::VKImage > image, GpuBufferBinding::ElementType kind, vk::Sampler sampler=nullptr)
Register a VKImage at an explicit binding index.
std::vector< ImageBinding > m_image_bindings
size_t largest_binding_data_element_count() const
GpuResourceManager m_resources
virtual std::array< uint32_t, 3 > calculate_dispatch_size(size_t total_elements, const DataStructureInfo &structure_info) const
Calculate workgroup dispatch counts from structure dimensions.
bool is_gpu_ready() const
Query GPU readiness without attempting initialisation.
const GpuComputeConfig & gpu_config() const
std::vector< uint8_t > m_native_staging_bytes
Native-typed staging buffer.
GpuComputeConfig m_gpu_config
void download_binding(size_t index, void *dest, size_t byte_size)
Read back a specific binding into a caller-provided destination.
std::shared_ptr< Core::VKImage > get_output_image(size_t binding_index) const
Return the image registered at an IMAGE_STORAGE output binding.
GpuDispatchCore(GpuComputeConfig config)
std::string m_cached_dispatch_key
Portal::Graphics::FenceID dispatch_core_dependency_async(const std::vector< DependencyStage > &stages)
Non-blocking variant of dispatch_core_dependency.
const std::string & dispatch_key() const
The key used for this context's GpuResourceManager unit.
std::vector< uint8_t > m_push_constants
std::vector< std::vector< uint8_t > > m_binding_data
void flatten_native_variants_to_staging(const std::vector< Kakshya::DataVariant > &variants, const DataStructureInfo &structure_info)
Flatten native-typed DataVariant channels into m_native_staging_bytes without any conversion.
GpuChannelResult dispatch_core(const std::vector< std::vector< double > > &channels, const DataStructureInfo &structure_info)
Full single-pass dispatch.
void stage_passthrough(size_t binding_index, const void *data, size_t byte_size)
Stage raw bytes for a PASSTHROUGH binding before dispatch.
Portal::Graphics::FenceID dispatch_core_async(const std::vector< std::vector< double > > &channels, const DataStructureInfo &structure_info)
Non-blocking variant of dispatch_core.
std::vector< GpuBufferBinding > m_bindings
bool ensure_gpu_ready()
Ensure GPU resources are initialised.
std::vector< size_t > m_output_size_overrides
void dispatch_core_dependency(const std::vector< DependencyStage > &stages)
Multi-pipeline dependency dispatch.
GpuChannelResult dispatch_core_chained(const std::vector< std::vector< double > > &channels, const DataStructureInfo &structure_info, const ExecutionContext &ctx)
Multi-pass (chained) dispatch.
void bind_all_descriptors()
virtual void prepare_gpu_inputs(const std::vector< std::vector< double > > &channels, const DataStructureInfo &structure_info)
Marshal channel data into GPU input buffers.
std::vector< std::vector< uint8_t > > m_passthrough_bytes
void stage_native_bytes(size_t binding_index, const void *data, size_t byte_size)
Stage a flat native-typed byte buffer for FLOAT32 bindings, bypassing the double-to-float cast in fla...
size_t m_last_effective_element_count
virtual void on_before_gpu_dispatch(const std::vector< std::vector< double > > &channels, const DataStructureInfo &structure_info)
Called immediately before dispatch.
void set_output_size(size_t index, size_t byte_size)
Declare the byte capacity of an output binding independently of input data.
std::vector< float > m_staging_floats
void update_dispatch_key_cache()
std::vector< float > readback_primary(size_t float_count)
Read back the primary output buffer into a float vector.
GpuChannelResult dispatch_core_chained_indirect(const std::vector< std::vector< double > > &channels, const DataStructureInfo &structure_info, const ExecutionContext &ctx)
Multi-pass dispatch where a GPU-resident indirect buffer gates each pass's workgroup count instead of...
void flatten_channels_to_staging(const std::vector< std::vector< double > > &channels, const DataStructureInfo &structure_info)
Flatten planar double channels into m_staging_floats.
virtual std::vector< GpuBufferBinding > declare_buffer_bindings() const
Declare the storage buffers the shader expects.
size_t find_first_output_index() const
void set_push_constants(const void *data, size_t bytes)
Set push constant data from a raw byte pointer.
void dispatch_batched_indirect(const std::string &key, uint32_t indirect_set, size_t indirect_binding, const std::array< uint32_t, 3 > &groups, const std::vector< GpuBufferBinding > &bindings, size_t push_constant_size, const ExecutionContext &ctx)
void download(const std::string &key, size_t index, float *dest, size_t byte_size)
bool initialise(const std::string &key, const GpuComputeConfig &config, const std::vector< GpuBufferBinding > &bindings)
Create (or confirm existing) pipeline for the given key.
bool is_ready(const std::string &key) const
void bind_descriptors_batch(const std::string &key, const std::vector< GpuBufferBinding > &bindings)
Bind every non-image buffer binding in one Vulkan call.
void bind_images_batch(const std::string &key, const std::vector< ImageBind > &images)
Bind every image in one Vulkan call.
void dispatch_sequence(const std::vector< std::string > &keys, const std::vector< std::array< uint32_t, 3 > > &groups_per_key, const std::vector< std::vector< uint8_t > > &push_constants_per_key, const std::vector< std::vector< Portal::Graphics::HazardResource > > &hazards_per_key, const std::vector< Portal::Graphics::IndirectDispatch > &indirect_per_key={})
Record a dispatch for each requested key into one command buffer via ComputePress::record_sequence,...
void upload(const std::string &key, size_t index, const float *data, size_t byte_size)
void transition_image(const std::shared_ptr< Core::VKImage > &image, vk::ImageLayout old_layout, vk::ImageLayout new_layout)
Transition a VKImage layout via an immediate command submission.
void dispatch(const std::string &key, const std::array< uint32_t, 3 > &groups, const std::vector< GpuBufferBinding > &bindings, const uint8_t *push_constant_data, size_t push_constant_size)
Portal::Graphics::FenceID dispatch_async(const std::string &key, const std::array< uint32_t, 3 > &groups, const std::vector< GpuBufferBinding > &bindings, const uint8_t *push_constant_data, size_t push_constant_size)
Submit a compute dispatch without blocking.
Portal::Graphics::FenceID dispatch_sequence_async(const std::vector< std::string > &keys, const std::vector< std::array< uint32_t, 3 > > &groups_per_key, const std::vector< std::vector< uint8_t > > &push_constants_per_key, const std::vector< std::vector< Portal::Graphics::HazardResource > > &hazards_per_key, const std::vector< Portal::Graphics::IndirectDispatch > &indirect_per_key={})
Non-blocking counterpart of dispatch_sequence.
void dispatch_batched(const std::string &key, const std::array< uint32_t, 3 > &groups, const std::vector< GpuBufferBinding > &bindings, size_t push_constant_size, const ExecutionContext &ctx)
void ensure_buffer(const std::string &key, size_t index, size_t required_bytes, Portal::Graphics::BufferUsageHint usage_hint=Portal::Graphics::BufferUsageHint::COMPUTE_STORAGE)
void upload_raw(const std::string &key, size_t index, const uint8_t *data, size_t byte_size)
Portal::Graphics::GpuBufferHandle shared_buffer_handle(uint32_t set, size_t binding_index) const
Non-owning view of the shared buffer at (set, binding_index).
size_t buffer_allocated_bytes(const std::string &key, size_t index) const
@ BufferProcessing
Buffer processing (Buffers::BufferManager, processing chains)
@ Runtime
General runtime operations (default fallback)
@ Yantra
DSP algorithms, computational units, matrix operations, Grammar.
bool is_structured_modality(DataModality modality)
Check if a modality represents structured data (vectors, matrices).
@ INDIRECT
Indirect draw/dispatch buffer (device-local)
bool is_image(const fs::path &filepath)
uint64_t get_total_elements() const
@ SPATIAL_Y
Spatial Y axis.
@ SPATIAL_Z
Spatial Z axis.
@ SPATIAL_X
Spatial X axis (images, tensors)
ElementType
Element type the shader expects in this binding.
enum MayaFlux::Portal::Graphics::GpuBufferBinding::Direction INPUT
enum MayaFlux::Portal::Graphics::GpuBufferBinding::ElementType FLOAT32
size_t push_constant_size
std::array< uint32_t, 3 > workgroup_size
Plain-data description of the compute shader to dispatch.
Optional GPU-resident source of a stage's workgroup counts.
Kakshya::DataModality modality
std::vector< Kakshya::DataDimension > dimensions
Dimensions, modality, source type, and optional Composite field schema.
Context information controlling how a compute operation executes.
std::unordered_map< size_t, std::vector< uint8_t > > aux
std::vector< float > primary
Erased output of a GPU dispatch: reconstructed float data plus any raw auxiliary outputs keyed by bin...
std::vector< std::vector< uint8_t > > push_constants
std::vector< std::string > keys
std::vector< Portal::Graphics::IndirectDispatch > indirect
std::vector< std::vector< Portal::Graphics::HazardResource > > hazards
std::vector< std::array< uint32_t, 3 > > groups