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
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
274 int resized_width = 0;
276 int scaled_width = 0;
277 int scaled_height = 0;
278 int pad_left = 0;
279 int pad_right = 0;
280 int pad_top = 0;
281 int pad_bottom = 0;
282
283 std::string resize_mode;
284 std::string color_in;
285 std::string color_out;
287 std::vector<int> axis_perm;
288
289 bool normalize = false;
290 bool quantize = false;
291 bool tessellate = false;
292
293 double affine_m00 = 1.0;
294 double affine_m01 = 0.0;
295 double affine_m02 = 0.0;
296 double affine_m10 = 0.0;
297 double affine_m11 = 1.0;
298 double affine_m12 = 0.0;
299 double affine_scale_x = 1.0;
300 double affine_scale_y = 1.0;
301 double affine_offset_x = 0.0;
302 double affine_offset_y = 0.0;
303
305 bool has_axis_perm() const noexcept {
306 return !axis_perm.empty();
307 }
308};
309
328struct Semantic {
329 std::optional<ImageSpec> image;
330 std::optional<AudioSpec> audio;
331 std::optional<TokensSpec> tokens;
332 std::optional<TextSpec> text;
333 std::optional<ByteStreamSpec> byte_stream;
334 std::optional<TessSpec> tess;
335 std::optional<EncodedSpec> encoded;
336 std::optional<QuantSpec> quant;
337 std::optional<PreprocessRuntimeMeta>
339};
340
356struct Mapping {
357 void* data =
358 nullptr;
359 std::size_t size_bytes = 0;
360 std::function<void()>
362 std::shared_ptr<void>
364
366 Mapping() = default;
368 Mapping(const Mapping&) = delete;
370 Mapping& operator=(const Mapping&) = delete;
372 Mapping(Mapping&& other) noexcept {
373 *this = std::move(other);
374 }
376 Mapping& operator=(Mapping&& other) noexcept {
377 if (this != &other) {
378 if (unmap)
379 unmap();
380 data = other.data;
381 size_bytes = other.size_bytes;
382 unmap = std::move(other.unmap);
383 keepalive = std::move(other.keepalive);
384 other.data = nullptr;
385 other.size_bytes = 0;
386 other.unmap = nullptr;
387 other.keepalive.reset();
388 }
389 return *this;
390 }
393 if (unmap)
394 unmap();
395 }
396};
397
398#if defined(SIMA_WITH_OPENCV)
401struct CvMatView {
402 Mapping mapping;
403 cv::Mat mat;
404};
405#endif
406
408struct Segment {
409 std::string name;
410 std::size_t size_bytes = 0;
411};
412
431 std::size_t size_bytes = 0;
432 std::shared_ptr<void>
434 void* data =
435 nullptr;
436 std::function<Mapping(MapMode)>
438 std::uint64_t sima_mem_target_flags =
439 0;
440 std::uint64_t sima_mem_flags = 0;
441 std::vector<Segment> sima_segments;
443
451 Mapping map(MapMode mode) const {
452 Mapping mapping;
453 if (map_fn) {
454 mapping = map_fn(mode);
455 } else {
456 mapping.data = data;
457 mapping.size_bytes = size_bytes;
458 }
459 if (!mapping.keepalive) {
460 mapping.keepalive = holder;
461 }
462 return mapping;
463 }
464};
465
468
470std::shared_ptr<TensorBuffer> make_cpu_owned_storage(std::size_t size_bytes);
478std::shared_ptr<TensorBuffer> make_cpu_external_storage(void* data, std::size_t size_bytes,
479 std::shared_ptr<void> holder = {},
480 bool read_only = true);
481
490struct Plane {
492 std::vector<int64_t> shape;
493 std::vector<int64_t> strides_bytes;
494 int64_t byte_offset = 0;
495};
496
498struct Nv12View {
499 int width = 0;
500 int height = 0;
501 const uint8_t* y = nullptr;
502 int64_t y_stride = 0;
503 const uint8_t* uv = nullptr;
504 int64_t uv_stride = 0;
505};
506
508struct Nv12Mapped {
511};
512
514struct I420View {
515 int width = 0;
516 int height = 0;
517 const uint8_t* y = nullptr;
518 int64_t y_stride = 0;
519 const uint8_t* u = nullptr;
520 int64_t u_stride = 0;
521 const uint8_t* v = nullptr;
522 int64_t v_stride = 0;
523};
524
526struct I420Mapped {
529};
530
542 std::string stage_key;
543 int logical_index = -1;
545 int route_slot = -1;
546 int physical_index = -1;
547 int memory_index = -1;
549 std::string name;
550 std::string backend_name;
551 std::string segment_name;
552};
553
585struct Tensor {
586 std::shared_ptr<TensorBuffer>
592 std::vector<int64_t> shape;
593 std::vector<int64_t> strides_bytes;
595 int64_t byte_offset =
596 0;
597 std::vector<TensorAxisSemantic> axis_semantics;
600 std::vector<Plane>
602 bool read_only = true;
604
606 bool is_dense() const {
607 return planes.empty();
608 }
610 bool is_composite() const {
611 return !planes.empty();
612 }
613
615 bool has_axis_semantics() const noexcept {
616 return !axis_semantics.empty();
617 }
618
620 bool axis_semantics_match_shape() const noexcept {
621 return axis_semantics.empty() || axis_semantics.size() == shape.size();
622 }
623
625 bool is_contiguous() const {
626 if (shape.empty())
627 return true;
628 if (strides_bytes.empty())
629 return true;
630 std::size_t elem = dtype_bytes(dtype);
631 if (elem == 0)
632 return false;
633 std::int64_t expected = static_cast<std::int64_t>(elem);
634 for (int i = static_cast<int>(shape.size()) - 1; i >= 0; --i) {
635 if (strides_bytes[static_cast<size_t>(i)] != expected)
636 return false;
637 expected *= shape[static_cast<size_t>(i)];
638 }
639 return true;
640 }
641
643 const Plane* try_plane(PlaneRole role) const noexcept {
644 for (const auto& plane : planes) {
645 if (plane.role == role)
646 return &plane;
647 }
648 return nullptr;
649 }
650
652 bool has_plane(PlaneRole role) const noexcept {
653 return try_plane(role) != nullptr;
654 }
655
657 const Plane& plane(PlaneRole role) const {
658 const Plane* found = try_plane(role);
659 if (!found)
660 throw std::runtime_error("Tensor::plane: plane not found");
661 return *found;
662 }
663
665 Mapping map(MapMode mode) const;
666
668 Mapping map_read() const {
669 return map(MapMode::Read);
670 }
673 return map(MapMode::Write);
674 }
679 return view(MapMode::Read);
680 }
681
683 template <typename T> T* data_ptr() {
684 if (read_only) {
685 throw std::runtime_error("Tensor::data_ptr: tensor is read-only");
686 }
687 return const_cast<T*>(const_data_ptr<T>());
688 }
689
691 template <typename T> const T* data_ptr() const {
692 return const_data_ptr<T>();
693 }
694
698 Tensor clone() const;
700 Tensor to(Device target) const;
702 Tensor cpu() const;
704 Tensor cvu() const;
706 Tensor mla(bool force = false) const;
711 bool validate(std::string* err) const;
712
714 std::optional<Nv12Mapped> map_nv12_read() const;
716 std::size_t nv12_required_bytes() const;
718 bool copy_nv12_contiguous_to(uint8_t* dst, std::size_t dst_size) const;
720 std::vector<uint8_t> copy_nv12_contiguous() const;
721
723 std::optional<I420Mapped> map_i420_read() const;
725 std::size_t i420_required_bytes() const;
727 bool copy_i420_contiguous_to(uint8_t* dst, std::size_t dst_size) const;
729 std::vector<uint8_t> copy_i420_contiguous() const;
730
732 std::size_t dense_bytes_tight() const;
734 bool copy_dense_bytes_tight_to(uint8_t* dst, std::size_t dst_size) const;
736 std::vector<uint8_t> copy_dense_bytes_tight() const;
737
739 bool copy_payload_bytes_to(uint8_t* dst, std::size_t dst_size) const;
741 std::vector<uint8_t> copy_payload_bytes() const;
742
744 int width() const;
746 int height() const;
748 int channels() const;
750 std::optional<ImageSpec::PixelFormat> image_format() const;
752 bool is_nv12() const;
754 bool is_i420() const;
755
757 std::string debug_string() const;
758
760 static Tensor from_text(std::string_view text);
762 std::string to_text() const;
763
764#if defined(SIMA_WITH_OPENCV)
769 [[deprecated("Use Tensor::from_cv_mat(mat, fmt, TensorMemory::EV74/CPU/MLA); "
770 "Tensor::from_cv_mat(mat, fmt) defaults to EV74 placement.")]] static Tensor
771 from_cv_mat(const cv::Mat& mat, ImageSpec::PixelFormat fmt, bool read_only);
773 static Tensor from_cv_mat_view(const cv::Mat& mat,
775 bool read_only = true);
777 static Tensor from_cv_mat(const cv::Mat& mat,
781 static Tensor from_cv_mat(const cv::Mat& mat, TensorMemory memory);
783 std::optional<CvMatView> map_cv_mat_view(ImageSpec::PixelFormat desired) const;
785 cv::Mat to_cv_mat_copy(ImageSpec::PixelFormat desired) const;
786#endif
787
788private:
789 template <typename T> const T* const_data_ptr() const {
791 throw std::runtime_error("Tensor::data_ptr: tensor is not on CPU");
792 }
793 if (!is_dense()) {
794 throw std::runtime_error("Tensor::data_ptr: tensor is composite");
795 }
796 if (!is_contiguous()) {
797 throw std::runtime_error("Tensor::data_ptr: call cpu().contiguous() first");
798 }
799 if (!storage || !storage->data) {
800 throw std::runtime_error("Tensor::data_ptr: tensor storage is not mappable");
801 }
802 return reinterpret_cast<const T*>(static_cast<const uint8_t*>(storage->data) + byte_offset);
803 }
804
805 static std::size_t dtype_bytes(simaai::neat::TensorDType dtype) {
806 switch (dtype) {
809 return 1;
813 return 2;
816 return 4;
818 return 8;
819 }
820 return 0;
821 }
822
823public:
824 static Tensor from_vector(const std::vector<float>& data, std::vector<int64_t> shape,
826 static Tensor from_vector(const std::vector<uint8_t>& data, std::vector<int64_t> shape,
828 static Tensor from_vector(const std::vector<int8_t>& data, std::vector<int64_t> shape,
830 static Tensor from_vector(const std::vector<uint16_t>& data, std::vector<int64_t> shape,
832 static Tensor from_vector(const std::vector<int16_t>& data, std::vector<int64_t> shape,
834 static Tensor from_vector(const std::vector<int32_t>& data, std::vector<int64_t> shape,
836};
837
838} // namespace simaai::neat

Generated via doxygen2docusaurus 2.0.0 by Doxygen 1.9.8.