MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
DataIO.hpp
Go to the documentation of this file.
1#pragma once
2
7
8namespace MayaFlux::Yantra {
9
10/**
11 * @struct Datum
12 * @brief Input/Output container for computation pipeline data flow with structure preservation.
13 * @tparam T Data type that satisfies ComputeData concept
14 *
15 * Encapsulates data with associated structure information and metadata for pipeline operations.
16 * The structure (dimensions and modality) is automatically inferred at construction time,
17 * ensuring that all data flowing through operations carries its dimensional context.
18 *
19 * Key Features:
20 * - Automatic structure inference from data type and content
21 * - Dimension and modality preservation through pipeline operations
22 * - Flexible metadata storage for operation-specific information
23 * - Move semantics for efficiency with large data
24 */
25template <ComputeData T = std::vector<Kakshya::DataVariant>>
26struct Datum {
27 T data; ///< The actual computation data
28 std::vector<Kakshya::DataDimension> dimensions; ///< Data dimensional structure
29 Kakshya::DataModality modality {}; ///< Data modality (audio, image, spectral, etc.)
30 std::unordered_map<std::string, std::any> metadata; ///< Associated metadata
32
33 std::optional<std::shared_ptr<Kakshya::SignalSourceContainer>> container; ///< Optional reference to container, required for regions
34
35 /** @brief Construct an empty datum when its data type has a valid default. */
36 Datum() requires std::default_initializable<T> = default;
37
38 /**
39 * @brief Construct from data by copy with automatic structure inference
40 * @param d Data to copy into the container
41 *
42 * Automatically infers dimensions and modality from the data type and content.
43 * For containers, uses their existing dimensional information.
44 * For other types, creates appropriate dimensional structures.
45 */
46 Datum(const T& d)
47 : data(d)
48 {
49 auto [dims, mod] = infer_structure(d);
50 dimensions = std::move(dims);
51 modality = mod;
52 }
53
54 /**
55 * @brief Construct from data by copy with container reference and automatic structure inference
56 * @param d Data to copy into the container
57 * @param cont Shared pointer to the associated RegionLike Data
58 *
59 * This constructor is useful when the data is part of a larger container
60 * and we want to maintain a reference to that container for context.
61 */
62 Datum(const T& d, const std::shared_ptr<Kakshya::SignalSourceContainer>& cont)
63 : data(d)
64 , container(cont)
65 {
66 auto [dims, mod] = infer_structure(d);
67 dimensions = std::move(dims);
68 modality = mod;
69 }
70
71 /**
72 * @brief Construct from data by move with automatic structure inference
73 * @param d Data to move into the container
74 *
75 * Automatically infers dimensions and modality before moving the data.
76 * More efficient for large data structures.
77 */
78 Datum(T&& d)
79 : data(std::move(d))
80 {
81 // Note: We infer from data after it's moved, which should be fine
82 // since inference typically only needs type info and basic properties
83 auto [dims, mod] = infer_structure(data);
84 dimensions = std::move(dims);
85 modality = mod;
86 }
87
88 /**
89 * @brief Construct from data by move with automatic structure inference
90 * @param d Data to move into the container
91 * @param cont Shared pointer to the associated RegionLike Data
92 *
93 * Automatically infers dimensions and modality before moving the data.
94 * More efficient for large data structures.
95 */
96 Datum(T&& d, const std::shared_ptr<Kakshya::SignalSourceContainer>& cont)
97 : data(std::move(d))
98 , container(cont)
99 {
100 auto [dims, mod] = infer_structure(data);
101 dimensions = std::move(dims);
102 modality = mod;
103 }
104
105 /**
106 * @brief Construct with move and explicit structure information
107 * @param d Data to move
108 * @param dims Explicit dimensional structure
109 * @param mod Explicit data modality
110 */
111 Datum(T&& d, std::vector<Kakshya::DataDimension> dims, Kakshya::DataModality mod)
112 : data(std::move(d))
113 , dimensions(std::move(dims))
114 , modality(mod)
115 {
116 }
117
118 /**
119 * @brief Construct with move and explicit structure information
120 * @param d Data to move
121 * @param container Shared pointer to the associated RegionLike Data
122 * @param dims Explicit dimensional structure
123 * @param mod Explicit data modality
124 */
125 Datum(T&& d, const std::shared_ptr<Kakshya::SignalSourceContainer> container, std::vector<Kakshya::DataDimension> dims, Kakshya::DataModality mod)
126 : data(std::move(d))
128 , dimensions(std::move(dims))
129 , modality(mod)
130 {
131 }
132
133 /**
134 * @brief Access underlying data (const)
135 * @return Const reference to the data
136 */
137 const T& operator*() const { return data; }
138
139 /**
140 * @brief Access underlying data (mutable)
141 * @return Mutable reference to the data
142 */
143 T& operator*() { return data; }
144
145 /**
146 * @brief Set or update the associated container reference
147 * @param cont Shared pointer to the new container
148 */
149 void set_container(const std::shared_ptr<Kakshya::SignalSourceContainer>& cont)
150 {
151 container = cont;
152 }
153
154 /**
155 * @brief Check if a container reference is associated
156 * @return True if a container is set
157 */
158 [[nodiscard]] bool has_container() const
159 {
160 return container.has_value();
161 }
162
163 /**
164 * @brief Check if processing is needed (for container types)
165 * @return True if processing is required before data extraction
166 */
167 [[nodiscard]] bool needs_processig() const
168 {
169 if constexpr (std::is_same_v<T, std::shared_ptr<Kakshya::SignalSourceContainer>>) {
171 }
172 return false;
173 }
174
175 /**
176 * @brief Set whether processing is needed (for container types)
177 * @param val True if processing should be done before data extraction
178 */
180 {
181 if constexpr (std::is_same_v<T, std::shared_ptr<Kakshya::SignalSourceContainer>>) {
183 } else {
185 }
186 }
187
188 /**
189 * @brief Check if data has specific modality
190 * @param target_modality Modality to check for
191 * @return True if data matches the target modality
192 */
193 [[nodiscard]] bool has_modality(Kakshya::DataModality target_modality) const
194 {
195 return modality == target_modality;
196 }
197
198 /**
199 * @brief Get total number of elements across all dimensions
200 * @return Product of all dimension sizes
201 */
202 [[nodiscard]] uint64_t get_total_elements() const
203 {
204 uint64_t total = 1;
205 for (const auto& dim : dimensions) {
206 total *= dim.size;
207 }
208 return total;
209 }
210
211 /**
212 * @brief Find dimension by semantic role
213 * @param role Dimension role to search for
214 * @return Index of dimension with that role, or -1 if not found
215 */
217 {
219 }
220
221 /**
222 * @brief Check if data is suitable for a specific type of processing
223 * @param required_modality Required data modality
224 * @param min_dimensions Minimum number of dimensions required
225 * @return True if data meets the requirements
226 */
227 [[nodiscard]] bool is_suitable_for_processing(Kakshya::DataModality required_modality,
228 size_t min_dimensions = 1) const
229 {
230 if constexpr (RequiresContainer<T>) {
231 if (!container.has_value()) {
232 return false;
233 }
234 }
235 return (modality == required_modality || required_modality == Kakshya::DataModality::UNKNOWN) && dimensions.size() >= min_dimensions;
236 }
237
238 /**
239 * @brief Update structure information (use carefully!)
240 * @param new_dims New dimensional structure
241 * @param new_modality New data modality
242 *
243 * This allows operations to update structure info when they transform
244 * the data in ways that change its dimensional characteristics.
245 */
246 void update_structure(std::vector<Kakshya::DataDimension> new_dims,
247 Kakshya::DataModality new_modality)
248 {
249 dimensions = std::move(new_dims);
250 modality = new_modality;
251 }
252
253 /**
254 * @brief Add or update metadata entry
255 * @param key Metadata key
256 * @param value Metadata value
257 */
258 template <typename ValueType>
259 void set_metadata(const std::string& key, ValueType&& value)
260 {
261 metadata[key] = std::forward<ValueType>(value);
262 }
263
264 /**
265 * @brief Get metadata entry with type safety
266 * @tparam ValueType Expected value type
267 * @param key Metadata key
268 * @return Optional value if found and correct type
269 */
270 template <typename ValueType>
271 std::optional<ValueType> get_metadata(const std::string& key) const
272 {
273 auto it = metadata.find(key);
274 if (it == metadata.end()) {
275 return std::nullopt;
276 }
277
278 return safe_any_cast<ValueType>(it->second);
279 }
280};
281
282/**
283 * @class OpUnit
284 * @brief Abstract base class for operation units in recursive processing graphs.
285 * @tparam T Data type that satisfies ComputeData concept
286 *
287 * Represents a single computational node that can process data and maintain
288 * dependencies on other operation units. Forms the building blocks of
289 * computation pipelines with automatic dependency resolution.
290 */
291template <ComputeData T = std::vector<Kakshya::DataVariant>>
292class OpUnit {
293public:
294 virtual ~OpUnit() = default;
295
296 /**
297 * @brief Execute the operation on input data
298 * @param input Input data container with metadata
299 * @return Processed output data container
300 */
301 virtual Datum<T> execute(const Datum<T>& input) = 0;
302
303 /**
304 * @brief Get the name/identifier of this operation
305 * @return String name of the operation
306 */
307 [[nodiscard]] virtual std::string get_name() const = 0;
308
309 /**
310 * @brief Add a dependency operation unit
311 * @param dep Shared pointer to the dependency operation
312 *
313 * Dependencies are executed before this operation in the pipeline.
314 */
315 void add_dependency(std::shared_ptr<OpUnit<T>> dep)
316 {
317 dependencies.push_back(std::move(dep));
318 }
319
320 /**
321 * @brief Get all dependency operations
322 * @return Const reference to the dependencies vector
323 */
324 const auto& get_dependencies() const { return dependencies; }
325
326protected:
327 std::vector<std::shared_ptr<OpUnit<T>>> dependencies; ///< Operation dependencies
328};
329
330/// Helper to detect if a type is an Datum
331template <typename>
332struct is_IO : std::false_type { };
333/// Specialization for Datum types
334template <typename T>
335struct is_IO<Datum<T>> : std::true_type { };
336
337/**
338 * @brief Convert a vector of raw values into a vector of Datum wrappers
339 * @tparam T ComputeData type
340 * @param inputs Raw input vector to wrap
341 * @return Vector of Datum containers with inferred structure
342 */
343template <ComputeData T>
344std::vector<Datum<T>> as_io_batch(const std::vector<T>& inputs)
345{
346 std::vector<Datum<T>> wrapped;
347 wrapped.reserve(inputs.size());
348 for (const auto& i : inputs)
349 wrapped.emplace_back(i);
350 return wrapped;
351}
352
353/**
354 * @brief Convert a vector of raw values into a vector of Datum wrappers via move
355 * @tparam T ComputeData type
356 * @param inputs Raw input vector to consume
357 * @return Vector of Datum containers with inferred structure
358 */
359template <ComputeData T>
360std::vector<Datum<T>> as_io_batch(std::vector<T>&& inputs)
361{
362 std::vector<Datum<T>> wrapped;
363 wrapped.reserve(inputs.size());
364 for (auto& i : inputs)
365 wrapped.emplace_back(std::move(i));
366 return wrapped;
367}
368
369/**
370 * @concept OperationReadyData
371 * @brief Concept to constrain types suitable for operation units
372 *
373 * Ensures that types used in operation units are either:
374 * - MultiVariant (universal data variant)
375 * - CompositeData (schema-bearing records or their owning container)
376 * - RegionLike (regions or region groups)
377 * - EigenMatrixLike (Eigen matrices/vectors)
378 * - Datum (input/output containers with structure)
379 */
380template <typename T>
382
383using DataIO = Datum<std::vector<Kakshya::DataVariant>>; ///< IO for universal data variant
385using CompositeIO = Datum<Kakshya::CompositeArray>; ///< IO for owning Composite records
387using RegionIO = Datum<Kakshya::Region>; ///< IO for single regions
388using RegionGroupIO = Datum<Kakshya::RegionGroup>; ///< IO for region groups
389using SegmentIO = Datum<std::vector<Kakshya::RegionSegment>>; ///< IO for region segments
390
391}
Core::GlobalInputConfig input
Definition Config.cpp:42
uint32_t total
glm::vec3 value
virtual Datum< T > execute(const Datum< T > &input)=0
Execute the operation on input data.
virtual std::string get_name() const =0
Get the name/identifier of this operation.
virtual ~OpUnit()=default
const auto & get_dependencies() const
Get all dependency operations.
Definition DataIO.hpp:324
void add_dependency(std::shared_ptr< OpUnit< T > > dep)
Add a dependency operation unit.
Definition DataIO.hpp:315
std::vector< std::shared_ptr< OpUnit< T > > > dependencies
Operation dependencies.
Definition DataIO.hpp:327
Abstract base class for operation units in recursive processing graphs.
Definition DataIO.hpp:292
Composite data that retains its field layout and presence information.
Definition DataSpec.hpp:49
Any Eigen matrix type, regardless of scalar type.
Definition DataSpec.hpp:121
Types that yield multiple data channels on extraction.
Definition DataSpec.hpp:103
Concept to constrain types suitable for operation units.
Definition DataIO.hpp:381
Types that represent spatial or temporal markers requiring a container to resolve data.
Definition DataSpec.hpp:96
Types that need an associated SignalSourceContainer to extract data.
Definition DataSpec.hpp:110
DataModality
Data modality types for cross-modal analysis.
Definition NDData.hpp:132
@ UNKNOWN
Unknown or undefined modality.
int find_dimension_by_role(const std::vector< DataDimension > &dimensions, DataDimension::Role role)
Find the index of a dimension by its semantic role.
std::vector< Datum< T > > as_io_batch(const std::vector< T > &inputs)
Convert a vector of raw values into a vector of Datum wrappers.
Definition DataIO.hpp:344
static std::pair< std::vector< Kakshya::DataDimension >, Kakshya::DataModality > infer_structure(const T &data, const std::shared_ptr< Kakshya::SignalSourceContainer > &container=nullptr)
Infer dimensions and modality from any ComputeData type.
Role
Semantic role of the dimension.
Definition NDData.hpp:204
T & operator*()
Access underlying data (mutable)
Definition DataIO.hpp:143
bool has_modality(Kakshya::DataModality target_modality) const
Check if data has specific modality.
Definition DataIO.hpp:193
Datum()=default
Construct an empty datum when its data type has a valid default.
Datum(T &&d, const std::shared_ptr< Kakshya::SignalSourceContainer > &cont)
Construct from data by move with automatic structure inference.
Definition DataIO.hpp:96
T data
The actual computation data.
Definition DataIO.hpp:27
int find_dimension_by_role(Kakshya::DataDimension::Role role) const
Find dimension by semantic role.
Definition DataIO.hpp:216
Datum(T &&d)
Construct from data by move with automatic structure inference.
Definition DataIO.hpp:78
void set_metadata(const std::string &key, ValueType &&value)
Add or update metadata entry.
Definition DataIO.hpp:259
void set_container_processing(bool val)
Set whether processing is needed (for container types)
Definition DataIO.hpp:179
bool has_container() const
Check if a container reference is associated.
Definition DataIO.hpp:158
bool is_suitable_for_processing(Kakshya::DataModality required_modality, size_t min_dimensions=1) const
Check if data is suitable for a specific type of processing.
Definition DataIO.hpp:227
std::vector< Kakshya::DataDimension > dimensions
Data dimensional structure.
Definition DataIO.hpp:28
std::optional< ValueType > get_metadata(const std::string &key) const
Get metadata entry with type safety.
Definition DataIO.hpp:271
Datum(T &&d, const std::shared_ptr< Kakshya::SignalSourceContainer > container, std::vector< Kakshya::DataDimension > dims, Kakshya::DataModality mod)
Construct with move and explicit structure information.
Definition DataIO.hpp:125
bool needs_processig() const
Check if processing is needed (for container types)
Definition DataIO.hpp:167
std::optional< std::shared_ptr< Kakshya::SignalSourceContainer > > container
Optional reference to container, required for regions.
Definition DataIO.hpp:33
Kakshya::DataModality modality
Data modality (audio, image, spectral, etc.)
Definition DataIO.hpp:29
uint64_t get_total_elements() const
Get total number of elements across all dimensions.
Definition DataIO.hpp:202
void set_container(const std::shared_ptr< Kakshya::SignalSourceContainer > &cont)
Set or update the associated container reference.
Definition DataIO.hpp:149
const T & operator*() const
Access underlying data (const)
Definition DataIO.hpp:137
Datum(T &&d, std::vector< Kakshya::DataDimension > dims, Kakshya::DataModality mod)
Construct with move and explicit structure information.
Definition DataIO.hpp:111
std::unordered_map< std::string, std::any > metadata
Associated metadata.
Definition DataIO.hpp:30
void update_structure(std::vector< Kakshya::DataDimension > new_dims, Kakshya::DataModality new_modality)
Update structure information (use carefully!)
Definition DataIO.hpp:246
Datum(const T &d, const std::shared_ptr< Kakshya::SignalSourceContainer > &cont)
Construct from data by copy with container reference and automatic structure inference.
Definition DataIO.hpp:62
Input/Output container for computation pipeline data flow with structure preservation.
Definition DataIO.hpp:26
Helper to detect if a type is an Datum.
Definition DataIO.hpp:332