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...

structDetectionSpec

Detection-decoder metadata — tags tensors that carry packed detection output. 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
107
115enum class PlaneRole {
116 Unknown = 0,
117 Y,
118 U,
119 V,
120 UV,
121};
122
125enum class MapMode {
126 Read = 0,
127 Write,
128 ReadWrite,
130};
131
139struct ImageSpec {
141 enum class PixelFormat {
142 RGB = 0,
143 BGR,
144 GRAY8,
145 NV12,
146 I420,
147 UNKNOWN,
148 };
149
151 std::string color_space;
152};
153
156
158struct AudioSpec {
159 int sample_rate = 0;
160 int channels = 0;
162 true;
163};
164
166struct TokensSpec {
167 int vocab_size = 0;
168};
169
177struct TextSpec {
178 std::string encoding = "utf-8";
179};
180
190 enum class Codec {
191 H264 = 0,
192 H265,
193 RTP_H264,
194 RTP_H265,
195 JPEG,
196 UNKNOWN,
197 };
198
200};
201
212 enum class ByteFormat {
213 Raw = 0,
214 };
215
216 ByteFormat format = ByteFormat::Raw;
217 std::string description;
218};
219
223
232struct QuantSpec {
233 float scale = 1.0f;
234 int32_t zero_point = 0;
235 int axis = -1;
236 std::vector<float> scales;
237 std::vector<int32_t> zero_points;
238};
239
249struct TessSpec {
250 std::vector<int64_t> slice_shape;
251 std::string format;
252
254 void set_slice_shape(std::vector<int64_t> shape) {
255 slice_shape = std::move(shape);
256 }
257};
258
276 std::string format;
277};
278
294 int resized_width = 0;
296 int scaled_width = 0;
297 int scaled_height = 0;
298 int pad_left = 0;
299 int pad_right = 0;
300 int pad_top = 0;
301 int pad_bottom = 0;
302
303 std::string resize_mode;
304 std::string color_in;
305 std::string color_out;
307 std::vector<int> axis_perm;
308
309 bool normalize = false;
310 bool quantize = false;
311 bool tessellate = false;
312
313 double affine_m00 = 1.0;
314 double affine_m01 = 0.0;
315 double affine_m02 = 0.0;
316 double affine_m10 = 0.0;
317 double affine_m11 = 1.0;
318 double affine_m12 = 0.0;
319 double affine_scale_x = 1.0;
320 double affine_scale_y = 1.0;
321 double affine_offset_x = 0.0;
322 double affine_offset_y = 0.0;
323
325 bool has_axis_perm() const noexcept {
326 return !axis_perm.empty();
327 }
328};
329
348struct Semantic {
349 std::optional<ImageSpec> image;
350 std::optional<AudioSpec> audio;
351 std::optional<TokensSpec> tokens;
352 std::optional<TextSpec> text;
353 std::optional<ByteStreamSpec> byte_stream;
354 std::optional<TessSpec> tess;
355 std::optional<EncodedSpec> encoded;
356 std::optional<QuantSpec> quant;
357 std::optional<DetectionSpec> detection;
358 std::optional<PreprocessRuntimeMeta>
360};
361
377struct Mapping {
378 void* data =
379 nullptr;
380 std::size_t size_bytes = 0;
381 std::function<void()>
383 std::shared_ptr<void>
385
387 Mapping() = default;
389 Mapping(const Mapping&) = delete;
391 Mapping& operator=(const Mapping&) = delete;
393 Mapping(Mapping&& other) noexcept {
394 *this = std::move(other);
395 }
397 Mapping& operator=(Mapping&& other) noexcept {
398 if (this != &other) {
399 if (unmap)
400 unmap();
401 data = other.data;
402 size_bytes = other.size_bytes;
403 unmap = std::move(other.unmap);
404 keepalive = std::move(other.keepalive);
405 other.data = nullptr;
406 other.size_bytes = 0;
407 other.unmap = nullptr;
408 other.keepalive.reset();
409 }
410 return *this;
411 }
414 if (unmap)
415 unmap();
416 }
417};
418
419#if defined(SIMA_WITH_OPENCV)
422struct CvMatView {
423 Mapping mapping;
424 cv::Mat mat;
425};
426#endif
427
429struct Segment {
430 std::string name;
431 std::size_t size_bytes = 0;
432};
433
452 std::size_t size_bytes = 0;
453 std::shared_ptr<void>
455 void* data =
456 nullptr;
457 std::function<Mapping(MapMode)>
459 std::uint64_t sima_mem_target_flags =
460 0;
461 std::uint64_t sima_mem_flags = 0;
462 std::vector<Segment> sima_segments;
464
472 Mapping map(MapMode mode) const {
473 Mapping mapping;
474 if (map_fn) {
475 mapping = map_fn(mode);
476 } else {
477 mapping.data = data;
478 mapping.size_bytes = size_bytes;
479 }
480 if (!mapping.keepalive) {
481 mapping.keepalive = holder;
482 }
483 return mapping;
484 }
485};
486
489
491std::shared_ptr<TensorBuffer> make_cpu_owned_storage(std::size_t size_bytes);
499std::shared_ptr<TensorBuffer> make_cpu_external_storage(void* data, std::size_t size_bytes,
500 std::shared_ptr<void> holder = {},
501 bool read_only = true);
502
511struct Plane {
513 std::vector<int64_t> shape;
514 std::vector<int64_t> strides_bytes;
515 int64_t byte_offset = 0;
516};
517
519struct Nv12View {
520 int width = 0;
521 int height = 0;
522 const uint8_t* y = nullptr;
523 int64_t y_stride = 0;
524 const uint8_t* uv = nullptr;
525 int64_t uv_stride = 0;
526};
527
529struct Nv12Mapped {
532};
533
535struct I420View {
536 int width = 0;
537 int height = 0;
538 const uint8_t* y = nullptr;
539 int64_t y_stride = 0;
540 const uint8_t* u = nullptr;
541 int64_t u_stride = 0;
542 const uint8_t* v = nullptr;
543 int64_t v_stride = 0;
544};
545
547struct I420Mapped {
550};
551
563 std::string stage_key;
564 int logical_index = -1;
566 int route_slot = -1;
567 int physical_index = -1;
568 int memory_index = -1;
570 std::string name;
571 std::string backend_name;
572 std::string segment_name;
573};
574
606struct Tensor {
607 std::shared_ptr<TensorBuffer>
613 std::vector<int64_t> shape;
614 std::vector<int64_t> strides_bytes;
616 int64_t byte_offset =
617 0;
618 std::vector<TensorAxisSemantic> axis_semantics;
621 std::vector<Plane>
623 bool read_only = true;
625
627 bool is_dense() const {
628 return planes.empty();
629 }
631 bool is_composite() const {
632 return !planes.empty();
633 }
634
636 bool has_axis_semantics() const noexcept {
637 return !axis_semantics.empty();
638 }
639
641 bool axis_semantics_match_shape() const noexcept {
642 return axis_semantics.empty() || axis_semantics.size() == shape.size();
643 }
644
646 bool is_contiguous() const {
647 if (shape.empty())
648 return true;
649 if (strides_bytes.empty())
650 return true;
651 std::size_t elem = dtype_bytes(dtype);
652 if (elem == 0)
653 return false;
654 std::int64_t expected = static_cast<std::int64_t>(elem);
655 for (int i = static_cast<int>(shape.size()) - 1; i >= 0; --i) {
656 if (strides_bytes[static_cast<size_t>(i)] != expected)
657 return false;
658 expected *= shape[static_cast<size_t>(i)];
659 }
660 return true;
661 }
662
664 const Plane* try_plane(PlaneRole role) const noexcept {
665 for (const auto& plane : planes) {
666 if (plane.role == role)
667 return &plane;
668 }
669 return nullptr;
670 }
671
673 bool has_plane(PlaneRole role) const noexcept {
674 return try_plane(role) != nullptr;
675 }
676
678 const Plane& plane(PlaneRole role) const {
679 const Plane* found = try_plane(role);
680 if (!found)
681 throw std::runtime_error("Tensor::plane: plane not found");
682 return *found;
683 }
684
686 Mapping map(MapMode mode) const;
687
689 Mapping map_read() const {
690 return map(MapMode::Read);
691 }
694 return map(MapMode::Write);
695 }
700 return view(MapMode::Read);
701 }
702
704 template <typename T> T* data_ptr() {
705 if (read_only) {
706 throw std::runtime_error("Tensor::data_ptr: tensor is read-only");
707 }
708 return const_cast<T*>(const_data_ptr<T>());
709 }
710
712 template <typename T> const T* data_ptr() const {
713 return const_data_ptr<T>();
714 }
715
719 Tensor clone() const;
721 Tensor to(Device target) const;
723 Tensor cpu() const;
725 Tensor cvu() const;
727 Tensor mla(bool force = false) const;
732 bool validate(std::string* err) const;
733
735 std::optional<Nv12Mapped> map_nv12_read() const;
737 std::size_t nv12_required_bytes() const;
739 bool copy_nv12_contiguous_to(uint8_t* dst, std::size_t dst_size) const;
741 std::vector<uint8_t> copy_nv12_contiguous() const;
742
744 std::optional<I420Mapped> map_i420_read() const;
746 std::size_t i420_required_bytes() const;
748 bool copy_i420_contiguous_to(uint8_t* dst, std::size_t dst_size) const;
750 std::vector<uint8_t> copy_i420_contiguous() const;
751
753 std::size_t dense_bytes_tight() const;
755 bool copy_dense_bytes_tight_to(uint8_t* dst, std::size_t dst_size) const;
757 std::vector<uint8_t> copy_dense_bytes_tight() const;
758
760 bool copy_payload_bytes_to(uint8_t* dst, std::size_t dst_size) const;
762 std::vector<uint8_t> copy_payload_bytes() const;
763
765 int width() const;
767 int height() const;
769 int channels() const;
771 std::optional<ImageSpec::PixelFormat> image_format() const;
773 bool is_nv12() const;
775 bool is_i420() const;
776
778 std::string debug_string() const;
779
781 static Tensor from_text(std::string_view text);
783 std::string to_text() const;
784
785#if defined(SIMA_WITH_OPENCV)
790 [[deprecated("Use Tensor::from_cv_mat(mat, fmt, TensorMemory::EV74/CPU/MLA); "
791 "Tensor::from_cv_mat(mat, fmt) defaults to EV74 placement.")]] static Tensor
792 from_cv_mat(const cv::Mat& mat, ImageSpec::PixelFormat fmt, bool read_only);
794 static Tensor from_cv_mat_view(const cv::Mat& mat,
796 bool read_only = true);
798 static Tensor from_cv_mat(const cv::Mat& mat,
802 static Tensor from_cv_mat(const cv::Mat& mat, TensorMemory memory);
804 std::optional<CvMatView> map_cv_mat_view(ImageSpec::PixelFormat desired) const;
806 cv::Mat to_cv_mat_copy(ImageSpec::PixelFormat desired) const;
807#endif
808
809private:
810 template <typename T> const T* const_data_ptr() const {
812 throw std::runtime_error("Tensor::data_ptr: tensor is not on CPU");
813 }
814 if (!is_dense()) {
815 throw std::runtime_error("Tensor::data_ptr: tensor is composite");
816 }
817 if (!is_contiguous()) {
818 throw std::runtime_error("Tensor::data_ptr: call cpu().contiguous() first");
819 }
820 if (!storage || !storage->data) {
821 throw std::runtime_error("Tensor::data_ptr: tensor storage is not mappable");
822 }
823 return reinterpret_cast<const T*>(static_cast<const uint8_t*>(storage->data) + byte_offset);
824 }
825
826 static std::size_t dtype_bytes(simaai::neat::TensorDType dtype) {
827 switch (dtype) {
830 return 1;
834 return 2;
837 return 4;
839 return 8;
840 }
841 return 0;
842 }
843
844public:
845 static Tensor from_vector(const std::vector<float>& data, std::vector<int64_t> shape,
847 static Tensor from_vector(const std::vector<uint8_t>& data, std::vector<int64_t> shape,
849 static Tensor from_vector(const std::vector<int8_t>& data, std::vector<int64_t> shape,
851 static Tensor from_vector(const std::vector<uint16_t>& data, std::vector<int64_t> shape,
853 static Tensor from_vector(const std::vector<int16_t>& data, std::vector<int64_t> shape,
855 static Tensor from_vector(const std::vector<int32_t>& data, std::vector<int64_t> shape,
857};
858
859} // namespace simaai::neat

Generated via doxygen2docusaurus 2.0.0 by Doxygen 1.9.8.