MayaFlux 0.5.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
NDData.cpp
Go to the documentation of this file.
1#include "NDData.hpp"
2
4
6
7namespace MayaFlux::Kakshya {
8
10{
11 switch (fmt) {
13 return 1;
15 return 2;
19 return 4;
22 return 8;
24 return 12;
27 return 16;
29 return 24;
31 return 32;
32 default:
33 return 0;
34 }
35}
36
37DataDimension::DataDimension(std::string n, uint64_t s, uint64_t st, Role r)
38 : name(std::move(n))
39 , size(s)
40 , stride(st)
41 , role(r)
42{
43}
44
45DataDimension DataDimension::time(uint64_t samples, std::string name)
46{
47 return { std::move(name), samples, 1, Role::TIME };
48}
49
50DataDimension DataDimension::channel(uint64_t count, uint64_t stride)
51{
52 return { "channel", count, stride, Role::CHANNEL };
53}
54
55DataDimension DataDimension::depth(uint64_t count, uint64_t stride)
56{
57 return { "depth", count, stride, Role::DEPTH };
58}
59
60DataDimension DataDimension::frequency(uint64_t bins, std::string name)
61{
62 return { std::move(name), bins, 1, Role::FREQUENCY };
63}
64
65DataDimension DataDimension::spatial(uint64_t size, char axis, uint64_t stride, std::string name)
66{
67 Role r = [axis]() {
68 switch (axis) {
69 case 'x':
70 return Role::SPATIAL_X;
71 case 'y':
72 return Role::SPATIAL_Y;
73 case 'z':
74 default:
75 return Role::SPATIAL_Z;
76 }
77 }();
78
79 if (name == "") {
80 name = std::string("spatial_") + axis;
81 }
82 return { name, size, stride, r };
83}
84
86{
87 return spatial(width, 'x');
88}
89
91{
92 return spatial(height, 'y', width * sizeof(float));
93}
94
96{
97 return spatial(depth, 'z', width * height * sizeof(float));
98}
99
101{
102 return { "mip_levels", levels, 1, Role::MIP_LEVEL };
103}
104
106 std::string name,
107 uint64_t element_count,
108 uint8_t components_per_element,
109 Role role)
110{
111 DataDimension dim { std::move(name), element_count, 1, role };
112 dim.grouping = ComponentGroup { components_per_element, 0 };
113 return dim;
114}
115
117 std::optional<double> invalid)
118{
119 if (max <= min) {
121 "DataDimension::with_range on '{}': max ({}) must exceed min ({}); range not applied",
122 name, max, min);
123 return *this;
124 }
125
126 value_range = ValueRange { .min = min, .max = max, .invalid = invalid };
127 return *this;
128}
129
130std::string_view modality_to_string(DataModality modality)
131{
132 return Reflect::enum_to_string(modality);
133}
134
136{
137 return grouped("positions", count, 3, Role::POSITION);
138}
139
141{
142 return grouped("normals", count, 3, Role::NORMAL);
143}
144
146{
147 return grouped("uvs", count, 2, Role::UV);
148}
149
151{
152 return grouped("colors", count, has_alpha ? 4 : 3, Role::COLOR);
153}
154
155std::vector<DataDimension> DataDimension::create_dimensions(
156 DataModality modality,
157 const std::vector<uint64_t>& shape,
158 MemoryLayout layout)
159{
160 std::vector<DataDimension> dims;
161 auto strides = calculate_strides(shape, layout);
162
163 switch (modality) {
165 if (shape.size() != 1) {
166 error<std::invalid_argument>(
169 std::source_location::current(),
170 "AUDIO_1D requires 1D shape");
171 }
172 dims.push_back(DataDimension::time(shape[0]));
173 break;
174
176 if (shape.size() != 2) {
177 error<std::invalid_argument>(
180 std::source_location::current(),
181 "AUDIO_MULTICHANNEL requires 2D shape [samples, channels]");
182 }
183 dims.push_back(DataDimension::time(shape[0]));
184 dims.push_back(DataDimension::channel(shape[1], strides[1]));
185 break;
186
188 if (shape.size() != 2) {
189 error<std::invalid_argument>(
192 std::source_location::current(),
193 "IMAGE_2D requires 2D shape [height, width]");
194 }
195 dims.push_back(DataDimension::spatial(shape[0], 'y', strides[0]));
196 dims.push_back(DataDimension::spatial(shape[1], 'x', strides[1]));
197 break;
198
200 if (shape.size() != 3) {
201 error<std::invalid_argument>(
204 std::source_location::current(),
205 "IMAGE_COLOR requires 3D shape [height, width, channels]");
206 }
207 dims.push_back(DataDimension::spatial(shape[0], 'y', strides[0]));
208 dims.push_back(DataDimension::spatial(shape[1], 'x', strides[1]));
209 dims.push_back(DataDimension::channel(shape[2], strides[2]));
210 break;
211
213 if (shape.size() != 4) {
214 error<std::invalid_argument>(
217 std::source_location::current(),
218 "IMAGE_COLOR_ARRAY requires 4D shape [frames, height, width, channels]");
219 }
220 dims.push_back(DataDimension::time(shape[0], "index"));
221 dims.push_back(DataDimension::spatial(shape[1], 'y', strides[1]));
222 dims.push_back(DataDimension::spatial(shape[2], 'x', strides[2]));
223 dims.push_back(DataDimension::channel(shape[3], strides[3]));
224 break;
225
227 if (shape.size() != 3) {
228 error<std::invalid_argument>(
231 std::source_location::current(),
232 "DEPTH_MAP requires 3D shape [height, width, components]");
233 }
234 dims.push_back(DataDimension::spatial(shape[0], 'y', strides[0]));
235 dims.push_back(DataDimension::spatial(shape[1], 'x', strides[1]));
236 dims.push_back(DataDimension::depth(shape[2], strides[2]));
237 break;
238
240 if (shape.size() != 2) {
241 error<std::invalid_argument>(
244 std::source_location::current(),
245 "SPECTRAL_2D requires 2D shape [time_windows, frequency_bins]");
246 }
247 dims.push_back(DataDimension::time(shape[0], "time_windows"));
248 dims.push_back(DataDimension::frequency(shape[1]));
249 dims[1].stride = strides[1];
250 break;
251
253 if (shape.size() != 3) {
254 error<std::invalid_argument>(
257 std::source_location::current(),
258 "VOLUMETRIC_3D requires 3D shape [x, y, z]");
259 }
260 dims.push_back(DataDimension::spatial(shape[0], 'x', strides[0]));
261 dims.push_back(DataDimension::spatial(shape[1], 'y', strides[1]));
262 dims.push_back(DataDimension::spatial(shape[2], 'z', strides[2]));
263 break;
264
266 if (shape.size() != 3) {
267 error<std::invalid_argument>(
270 std::source_location::current(),
271 "VIDEO_GRAYSCALE requires 3D shape [frames, height, width]");
272 }
273 dims.push_back(DataDimension::time(shape[0], "frames"));
274 dims.push_back(DataDimension::spatial(shape[1], 'y', strides[1]));
275 dims.push_back(DataDimension::spatial(shape[2], 'x', strides[2]));
276 break;
277
279 if (shape.size() != 4) {
280 error<std::invalid_argument>(
283 std::source_location::current(),
284 "VIDEO_COLOR requires 4D shape [frames, height, width, channels]");
285 }
286 dims.push_back(DataDimension::time(shape[0], "frames"));
287 dims.push_back(DataDimension::spatial(shape[1], 'y', strides[1]));
288 dims.push_back(DataDimension::spatial(shape[2], 'x', strides[2]));
289 dims.push_back(DataDimension::channel(shape[3], strides[3]));
290 break;
291
293 if (shape.size() != 4) {
294 error<std::invalid_argument>(
297 std::source_location::current(),
298 "VIDEO_DEPTH requires 4D shape [frames, height, width, components]");
299 }
300 dims.push_back(DataDimension::time(shape[0], "frames"));
301 dims.push_back(DataDimension::spatial(shape[1], 'y', strides[1]));
302 dims.push_back(DataDimension::spatial(shape[2], 'x', strides[2]));
303 dims.push_back(DataDimension::depth(shape[3], strides[3]));
304 break;
305
306 default:
307 error<std::invalid_argument>(
310 std::source_location::current(),
311 "Unsupported modality for dimension creation: {}", modality_to_string(modality));
312 }
313
314 return dims;
315}
316
318 const std::vector<uint64_t>& shape,
319 MemoryLayout layout)
320{
321 if (shape.empty())
322 return {};
323
324 std::vector<uint64_t> strides(shape.size());
325
326 if (layout == MemoryLayout::ROW_MAJOR) {
327 auto reversed_shape = shape | std::views::reverse;
328 std::exclusive_scan(
329 reversed_shape.begin(),
330 reversed_shape.end(),
331 strides.rbegin(),
332 uint64_t(1),
333 std::multiplies<uint64_t> {});
334 } else {
335 std::exclusive_scan(
336 shape.begin(),
337 shape.end(),
338 strides.begin(),
339 uint64_t(1),
340 std::multiplies<uint64_t> {});
341 }
342
343 return strides;
344}
345
346}
#define MF_ERROR(comp, ctx,...)
std::string name
Definition VKDevice.cpp:143
size_t count
uint32_t width
uint32_t height
uint32_t depth
@ Runtime
General runtime operations (default fallback)
@ Kakshya
Containers[Signalsource, Stream, File], Regions, DataProcessors.
size_t gpu_data_format_bytes(GpuDataFormat fmt) noexcept
Byte size of one element of a GpuDataFormat.
Definition NDData.cpp:9
DataModality
Data modality types for cross-modal analysis.
Definition NDData.hpp:164
@ DEPTH_MAP
[height, width, components] - range/disparity image
@ AUDIO_MULTICHANNEL
Multi-channel audio.
@ SPECTRAL_2D
2D spectral data (time + frequency)
@ VIDEO_DEPTH
[frames, height, width, components] - streaming range data
@ IMAGE_COLOR_ARRAY
4D (idx + 2D + color)
@ VOLUMETRIC_3D
3D volumetric data
@ VIDEO_GRAYSCALE
3D video (time + 2D grayscale)
@ VIDEO_COLOR
4D video (time + 2D + color)
@ IMAGE_COLOR
2D RGB/RGBA image
@ IMAGE_2D
2D image (grayscale or single channel)
MemoryLayout
Memory layout for multi-dimensional data.
Definition NDData.hpp:65
@ ROW_MAJOR
C/C++ style (last dimension varies fastest)
GpuDataFormat
GPU data formats with explicit precision levels.
Definition NDData.hpp:25
std::string_view modality_to_string(DataModality modality)
Convert DataModality enum to string representation.
Definition NDData.cpp:130
constexpr std::string_view enum_to_string(EnumType value) noexcept
Universal enum to string converter using magic_enum (original case)
Grouping information for sub-dimensions.
Definition NDData.hpp:261
Numeric interpretation of the values along this dimension.
Definition NDData.hpp:289
std::optional< ValueRange > value_range
Definition NDData.hpp:295
static DataDimension spatial_2d(uint64_t width, uint64_t height)
Convenience constructor for a 2D spatial dimension.
Definition NDData.cpp:90
Role
Semantic role of the dimension.
Definition NDData.hpp:236
@ FREQUENCY
Spectral/frequency axis.
@ TIME
Temporal progression (samples, frames, steps)
@ POSITION
Vertex positions (3D space)
@ DEPTH
Distance from the observation point (depth, disparity, range)
@ CHANNEL
Parallel streams (audio channels, color channels)
@ SPATIAL_X
Spatial X axis (images, tensors)
uint64_t stride
Memory stride (elements between consecutive indices)
Definition NDData.hpp:299
std::string name
Human-readable identifier for the dimension.
Definition NDData.hpp:297
static DataDimension vertex_positions(uint64_t count)
Create dimension for vertex positions (vec3)
Definition NDData.cpp:135
DataDimension & with_range(double min, double max, std::optional< double > invalid=std::nullopt)
Attach a value range.
Definition NDData.cpp:116
uint64_t size
Number of elements in this dimension.
Definition NDData.hpp:298
static DataDimension vertex_colors(uint64_t count, bool has_alpha=false)
Create dimension for colors (vec3 or vec4)
Definition NDData.cpp:150
Role role
Semantic hint for common operations.
Definition NDData.hpp:300
static DataDimension spatial(uint64_t size, char axis, uint64_t stride=1, std::string name="spatial")
Convenience constructor for a spatial dimension.
Definition NDData.cpp:65
static DataDimension grouped(std::string name, uint64_t element_count, uint8_t components_per_element, Role role=Role::CUSTOM)
Create dimension with component grouping.
Definition NDData.cpp:105
static DataDimension vertex_normals(uint64_t count)
Create dimension for vertex normals (vec3)
Definition NDData.cpp:140
static DataDimension frequency(uint64_t bins, std::string name="frequency")
Convenience constructor for a frequency dimension.
Definition NDData.cpp:60
static DataDimension spatial_1d(uint64_t width)
Convenience constructor for an array dimension.
Definition NDData.cpp:85
static DataDimension time(uint64_t samples, std::string name="time")
Convenience constructor for a temporal (time) dimension.
Definition NDData.cpp:45
static std::vector< uint64_t > calculate_strides(const std::vector< uint64_t > &shape, MemoryLayout layout)
Calculate memory strides based on shape and layout.
Definition NDData.cpp:317
static DataDimension depth(uint64_t count=1, uint64_t stride=1)
Convenience constructor for a depth dimension.
Definition NDData.cpp:55
static std::vector< DataDimension > create_dimensions(DataModality modality, const std::vector< uint64_t > &shape, MemoryLayout layout=MemoryLayout::ROW_MAJOR)
Create dimension descriptors for a data modality.
Definition NDData.cpp:155
static DataDimension mipmap_levels(uint64_t levels)
Create dimension for mipmap levels.
Definition NDData.cpp:100
static DataDimension texture_coords(uint64_t count)
Create dimension for texture coordinates (vec2)
Definition NDData.cpp:145
static DataDimension spatial_3d(uint64_t width, uint64_t height, uint64_t depth)
Convenience constructor for a 3D spatial dimension.
Definition NDData.cpp:95
std::optional< ComponentGroup > grouping
Definition NDData.hpp:277
static DataDimension channel(uint64_t count, uint64_t stride=1)
Convenience constructor for a channel dimension.
Definition NDData.cpp:50
Minimal dimension descriptor focusing on structure only.
Definition NDData.hpp:229