Skip to main content

TensorCore.h File

The Tensor type — a labeled box of numbers, plus all its supporting types. More...

Included Headers

#include "pipeline/TensorTypes.h" #include <cstddef> #include <cstdint> #include <functional> #include <memory> #include <optional> #include <string> #include <stdexcept> #include <string_view> #include <utility> #include <vector>

Namespaces Index

namespacesimaai
namespaceneat

Classes Index

structDevice

Device descriptor: type + numeric ID (for multi-device boards). More...

structImageSpec

Image-tensor metadata: pixel format and (optional) color space. More...

structAudioSpec

Audio-tensor metadata: sample rate, channel count, interleaving. More...

structTokensSpec

Token-tensor metadata for NLP-style tensors. More...

structTextSpec

UTF-8 text tensor metadata. More...

structEncodedSpec

Encoded-stream tensor metadata: which codec the bytes represent. More...

structByteStreamSpec

Opaque byte-stream tensor metadata. More...

structQuantSpec

Quantization metadata for INT8/INT16 tensors. More...

structTessSpec

Tessellation metadata — tile geometry for the MLA's tile-block layout. More...

structPreprocessRuntimeMeta

Per-buffer preprocessing context — the inverse-transform breadcrumb trail. More...

structSemantic

Discriminated union of "what this tensor represents". More...

structMapping

Scoped read/write window into a TensorBuffer. More...

structSegment

One named memory segment within a multi-segment tensor buffer (e.g., separate Y / UV planes). More...

structTensorBuffer

Storage handle for a tensor — opaque container for one of four backing memory kinds. More...

structPlane

One plane of a composite (multi-plane) tensor. More...

structNv12View

Non-owning view into NV12 pixel data: Y plane + interleaved UV plane. More...

structNv12Mapped

Bundles an NV12 view with the Mapping that keeps its underlying buffer alive. More...

structI420View

Non-owning view into I420 pixel data: separate Y, U, V planes. More...

structI420Mapped

Bundles an I420 view with the Mapping that keeps its underlying buffer alive. More...

structTensorRouteMeta

Routing metadata that travels with a tensor through multi-output pipelines. More...

structTensor

Universal tensor type — a labeled box of numbers that flows between Nodes. More...

Description

The Tensor type — a labeled box of numbers, plus all its supporting types.

This is the framework's universal data carrier. A Tensor knows what numbers it holds (dtype, shape, strides_bytes), where they live (device, storage of one of four StorageKinds), and what they represent (Semantic — image, audio, tessellated tile, encoded video, quantization payload, or preprocessing residue). The Tensor's storage is typically zero-copy across processors via the unified IOMMU; this file defines the TensorBuffer abstraction that hides the per-storage-kind details.

Headline types in this file:

  • Tensor — the user-facing struct.
  • TensorBuffer (alias Storage) — the storage handle with map_fn for read/write.
  • Mapping — a scoped read/write window into a buffer (RAII-unmap on destruction).
  • Plane — per-plane info for composite formats (NV12 = Y + UV, I420 = Y + U + V).
  • Semantic — discriminated union of "what this tensor means" (image, audio, tess, etc.).
  • TensorRouteMeta — routing metadata used by multi-output models.
  • Device / DeviceType — where the tensor lives (CPU/CVU/MLA/APU).
See Also

"Tensors: hiding the memory mess" (§0.10 of the design deep dive)

See Also

TensorTypes.h for dtype/layout/axis-semantic enums

See Also

TensorSpec.h for TensorConstraint (the matching contract)

File Listing

The file content with the documentation metadata removed is:

1
26#pragma once
27
29
30#include <cstddef>
31#include <cstdint>
32#include <functional>
33#include <memory>
34#include <optional>
35#include <string>
36#include <stdexcept>
37#include <string_view>
38#include <utility>
39#include <vector>
40
41#if defined(SIMA_WITH_OPENCV)
42#include <opencv2/core.hpp>
43#endif
44
45namespace simaai::neat {
46
57enum class DeviceType {
58 CPU = 0,
62 UNKNOWN,
63};
64
66struct Device {
68 int id = 0;
69};
70
81enum class StorageKind {
82 CpuOwned = 0,
87};
88
97enum class TensorMemory {
98 EV74 = 0,
99 CPU,
100 MLA,
101 A65,
102 Auto,
103};
104
112enum class PlaneRole {
113 Unknown = 0,
114 Y,
115 U,
116 V,
117 UV,
118};
119
122enum class MapMode {
123 Read = 0,
124 Write,
125 ReadWrite,
127};
128
136struct ImageSpec {
138 enum class PixelFormat {
139 RGB = 0,
140 BGR,
141 GRAY8,
142 NV12,
143 I420,
144 UNKNOWN,
145 };
146
148 std::string color_space;
149};
150
152struct AudioSpec {
153 int sample_rate = 0;
154 int channels = 0;
156 true;
157};
158
160struct TokensSpec {
161 int vocab_size = 0;
162};
163
171struct TextSpec {
172 std::string encoding = "utf-8";
173};
174
184 enum class Codec {
185 H264 = 0,
186 H265,
187 RTP_H264,
188 RTP_H265,
189 JPEG,
190 UNKNOWN,
191 };
192
194};
195
206 enum class ByteFormat {
207 Raw = 0,
208 };
209
210 ByteFormat format = ByteFormat::Raw;
211 std::string description;
212};
213
217
226struct QuantSpec {
227 float scale = 1.0f;
228 int32_t zero_point = 0;
229 int axis = -1;
230 std::vector<float> scales;
231 std::vector<int32_t> zero_points;
232};
233
243struct TessSpec {
244 std::vector<int64_t> slice_shape;
245 std::string format;
246
248 void set_slice_shape(std::vector<int64_t> shape) {
249 slice_shape = std::move(shape);
250 }
251};
252
268 int resized_width = 0;
270 int scaled_width = 0;
271 int scaled_height = 0;
272 int pad_left = 0;
273 int pad_right = 0;
274 int pad_top = 0;
275 int pad_bottom = 0;
276
277 std::string resize_mode;
278 std::string color_in;
279 std::string color_out;
281 std::vector<int> axis_perm;
282
283 bool normalize = false;
284 bool quantize = false;
285 bool tessellate = false;
286
287 double affine_m00 = 1.0;
288 double affine_m01 = 0.0;
289 double affine_m02 = 0.0;
290 double affine_m10 = 0.0;
291 double affine_m11 = 1.0;
292 double affine_m12 = 0.0;
293 double affine_scale_x = 1.0;
294 double affine_scale_y = 1.0;
295 double affine_offset_x = 0.0;
296 double affine_offset_y = 0.0;
297
299 bool has_axis_perm() const noexcept {
300 return !axis_perm.empty();
301 }
302};
303
322struct Semantic {
323 std::optional<ImageSpec> image;
324 std::optional<AudioSpec> audio;
325 std::optional<TokensSpec> tokens;
326 std::optional<TextSpec> text;
327 std::optional<ByteStreamSpec> byte_stream;
328 std::optional<TessSpec> tess;
329 std::optional<EncodedSpec> encoded;
330 std::optional<QuantSpec> quant;
331 std::optional<PreprocessRuntimeMeta>
333};
334
350struct Mapping {
351 void* data =
352 nullptr;
353 std::size_t size_bytes = 0;
354 std::function<void()>
356 std::shared_ptr<void>
358
360 Mapping() = default;
362 Mapping(const Mapping&) = delete;
364 Mapping& operator=(const Mapping&) = delete;
366 Mapping(Mapping&& other) noexcept {
367 *this = std::move(other);
368 }
370 Mapping& operator=(Mapping&& other) noexcept {
371 if (this != &other) {
372 if (unmap)
373 unmap();
374 data = other.data;
375 size_bytes = other.size_bytes;
376 unmap = std::move(other.unmap);
377 keepalive = std::move(other.keepalive);
378 other.data = nullptr;
379 other.size_bytes = 0;
380 other.unmap = nullptr;
381 other.keepalive.reset();
382 }
383 return *this;
384 }
387 if (unmap)
388 unmap();
389 }
390};
391
392#if defined(SIMA_WITH_OPENCV)
395struct CvMatView {
396 Mapping mapping;
397 cv::Mat mat;
398};
399#endif
400
402struct Segment {
403 std::string name;
404 std::size_t size_bytes = 0;
405};
406
425 std::size_t size_bytes = 0;
426 std::shared_ptr<void>
428 void* data =
429 nullptr;
430 std::function<Mapping(MapMode)>
432 std::uint64_t sima_mem_target_flags =
433 0;
434 std::uint64_t sima_mem_flags = 0;
435 std::vector<Segment> sima_segments;
437
445 Mapping map(MapMode mode) const {
446 Mapping mapping;
447 if (map_fn) {
448 mapping = map_fn(mode);
449 } else {
450 mapping.data = data;
451 mapping.size_bytes = size_bytes;
452 }
453 if (!mapping.keepalive) {
454 mapping.keepalive = holder;
455 }
456 return mapping;
457 }
458};
459
462
464std::shared_ptr<TensorBuffer> make_cpu_owned_storage(std::size_t size_bytes);
472std::shared_ptr<TensorBuffer> make_cpu_external_storage(void* data, std::size_t size_bytes,
473 std::shared_ptr<void> holder = {},
474 bool read_only = true);
475
484struct Plane {
486 std::vector<int64_t> shape;
487 std::vector<int64_t> strides_bytes;
488 int64_t byte_offset = 0;
489};
490
492struct Nv12View {
493 int width = 0;
494 int height = 0;
495 const uint8_t* y = nullptr;
496 int64_t y_stride = 0;
497 const uint8_t* uv = nullptr;
498 int64_t uv_stride = 0;
499};
500
502struct Nv12Mapped {
505};
506
508struct I420View {
509 int width = 0;
510 int height = 0;
511 const uint8_t* y = nullptr;
512 int64_t y_stride = 0;
513 const uint8_t* u = nullptr;
514 int64_t u_stride = 0;
515 const uint8_t* v = nullptr;
516 int64_t v_stride = 0;
517};
518
520struct I420Mapped {
523};
524
536 std::string stage_key;
537 int logical_index = -1;
539 int route_slot = -1;
540 int physical_index = -1;
541 int memory_index = -1;
543 std::string name;
544 std::string backend_name;
545 std::string segment_name;
546};
547
579struct Tensor {
580 std::shared_ptr<TensorBuffer>
586 std::vector<int64_t> shape;
587 std::vector<int64_t> strides_bytes;
589 int64_t byte_offset =
590 0;
591 std::vector<TensorAxisSemantic> axis_semantics;
594 std::vector<Plane>
596 bool read_only = true;
598
600 bool is_dense() const {
601 return planes.empty();
602 }
604 bool is_composite() const {
605 return !planes.empty();
606 }
607
609 bool has_axis_semantics() const noexcept {
610 return !axis_semantics.empty();
611 }
612
614 bool axis_semantics_match_shape() const noexcept {
615 return axis_semantics.empty() || axis_semantics.size() == shape.size();
616 }
617
619 bool is_contiguous() const {
620 if (shape.empty())
621 return true;
622 if (strides_bytes.empty())
623 return true;
624 std::size_t elem = dtype_bytes(dtype);
625 if (elem == 0)
626 return false;
627 std::int64_t expected = static_cast<std::int64_t>(elem);
628 for (int i = static_cast<int>(shape.size()) - 1; i >= 0; --i) {
629 if (strides_bytes[static_cast<size_t>(i)] != expected)
630 return false;
631 expected *= shape[static_cast<size_t>(i)];
632 }
633 return true;
634 }
635
637 const Plane* try_plane(PlaneRole role) const noexcept {
638 for (const auto& plane : planes) {
639 if (plane.role == role)
640 return &plane;
641 }
642 return nullptr;
643 }
644
646 bool has_plane(PlaneRole role) const noexcept {
647 return try_plane(role) != nullptr;
648 }
649
651 const Plane& plane(PlaneRole role) const {
652 const Plane* found = try_plane(role);
653 if (!found)
654 throw std::runtime_error("Tensor::plane: plane not found");
655 return *found;
656 }
657
659 Mapping map(MapMode mode) const;
660
662 Mapping map_read() const {
663 return map(MapMode::Read);
664 }
667 return map(MapMode::Write);
668 }
673 return view(MapMode::Read);
674 }
675
677 template <typename T> T* data_ptr() {
678 if (read_only) {
679 throw std::runtime_error("Tensor::data_ptr: tensor is read-only");
680 }
681 return const_cast<T*>(const_data_ptr<T>());
682 }
683
685 template <typename T> const T* data_ptr() const {
686 return const_data_ptr<T>();
687 }
688
692 Tensor clone() const;
694 Tensor to(Device target) const;
696 Tensor cpu() const;
698 Tensor cvu() const;
700 Tensor mla(bool force = false) const;
705 bool validate(std::string* err) const;
706
708 std::optional<Nv12Mapped> map_nv12_read() const;
710 std::size_t nv12_required_bytes() const;
712 bool copy_nv12_contiguous_to(uint8_t* dst, std::size_t dst_size) const;
714 std::vector<uint8_t> copy_nv12_contiguous() const;
715
717 std::optional<I420Mapped> map_i420_read() const;
719 std::size_t i420_required_bytes() const;
721 bool copy_i420_contiguous_to(uint8_t* dst, std::size_t dst_size) const;
723 std::vector<uint8_t> copy_i420_contiguous() const;
724
726 std::size_t dense_bytes_tight() const;
728 bool copy_dense_bytes_tight_to(uint8_t* dst, std::size_t dst_size) const;
730 std::vector<uint8_t> copy_dense_bytes_tight() const;
731
733 bool copy_payload_bytes_to(uint8_t* dst, std::size_t dst_size) const;
735 std::vector<uint8_t> copy_payload_bytes() const;
736
738 int width() const;
740 int height() const;
742 int channels() const;
744 std::optional<ImageSpec::PixelFormat> image_format() const;
746 bool is_nv12() const;
748 bool is_i420() const;
749
751 std::string debug_string() const;
752
754 static Tensor from_text(std::string_view text);
756 std::string to_text() const;
757
758#if defined(SIMA_WITH_OPENCV)
763 [[deprecated("Use Tensor::from_cv_mat(mat, fmt, TensorMemory::EV74/CPU/MLA); "
764 "Tensor::from_cv_mat(mat, fmt) defaults to EV74 placement.")]] static Tensor
765 from_cv_mat(const cv::Mat& mat, ImageSpec::PixelFormat fmt, bool read_only);
767 static Tensor from_cv_mat_view(const cv::Mat& mat,
769 bool read_only = true);
771 static Tensor from_cv_mat(const cv::Mat& mat,
775 static Tensor from_cv_mat(const cv::Mat& mat, TensorMemory memory);
777 std::optional<CvMatView> map_cv_mat_view(ImageSpec::PixelFormat desired) const;
779 cv::Mat to_cv_mat_copy(ImageSpec::PixelFormat desired) const;
780#endif
781
782private:
783 template <typename T> const T* const_data_ptr() const {
785 throw std::runtime_error("Tensor::data_ptr: tensor is not on CPU");
786 }
787 if (!is_dense()) {
788 throw std::runtime_error("Tensor::data_ptr: tensor is composite");
789 }
790 if (!is_contiguous()) {
791 throw std::runtime_error("Tensor::data_ptr: call cpu().contiguous() first");
792 }
793 if (!storage || !storage->data) {
794 throw std::runtime_error("Tensor::data_ptr: tensor storage is not mappable");
795 }
796 return reinterpret_cast<const T*>(static_cast<const uint8_t*>(storage->data) + byte_offset);
797 }
798
799 static std::size_t dtype_bytes(simaai::neat::TensorDType dtype) {
800 switch (dtype) {
803 return 1;
807 return 2;
810 return 4;
812 return 8;
813 }
814 return 0;
815 }
816
817public:
818 static Tensor from_vector(const std::vector<float>& data, std::vector<int64_t> shape,
820 static Tensor from_vector(const std::vector<uint8_t>& data, std::vector<int64_t> shape,
822 static Tensor from_vector(const std::vector<int8_t>& data, std::vector<int64_t> shape,
824 static Tensor from_vector(const std::vector<uint16_t>& data, std::vector<int64_t> shape,
826 static Tensor from_vector(const std::vector<int16_t>& data, std::vector<int64_t> shape,
828 static Tensor from_vector(const std::vector<int32_t>& data, std::vector<int64_t> shape,
830};
831
832} // namespace simaai::neat

Generated via doxygen2docusaurus 2.0.0 by Doxygen 1.9.8.