simple_tensor.h#

Defines

ONNX_LIGHT_DECLARE_TENSOR_ELEMENT_TYPE(CPP_TYPE, ENUM_VALUE)#
namespace onnx_light

Alias that makes onnx-light headers compatible with code that references ONNX_LIGHT_NAMESPACE (the macro used in the standard onnx package).

Set to ONNX_LIGHT_NAMESPACE so both names resolve to the same namespace.

Symbol-visibility attribute for the public onnx-light C++ API.

Maps the upstream compatibility macro to onnx-light’s explicit proto ABI annotation. This keeps declarations from vendored ONNX headers visible when lib_onnx_proto uses hidden visibility by default.

Namespace alias so that ONNX C++ code (and consumers such as onnxruntime) that refers to the literal onnx namespace — rather than the ONNX_NAMESPACE macro — resolves to the onnx-light namespace. The standard onnx package lives in namespace onnx; onnx-light uses onnx_light (via ONNX_LIGHT_NAMESPACE), so this alias keeps onnx-light a true drop-in. It is only introduced when the onnx-light namespace differs from onnx.

namespace core
namespace runtime

Typedefs

using DataType = TensorProto::DataType#

DataType — alias for TensorProto::DataType.

Provides a short, namespace-local name for the upstream ONNX TensorProto::DataType enumeration so backend test code can write DataType::INT64 instead of fully qualifying every reference.

using RawByteBuffer = std::vector<uint8_t, DefaultInitAllocator<uint8_t>>#

Byte storage that skips zero-initialisation on resize/allocation.

Functions

inline bool operator==(const std::vector<int64_t> &v, const Shape &s) noexcept#

Symmetric comparison: std::vector<int64_t> == Shape.

inline bool operator!=(const std::vector<int64_t> &v, const Shape &s) noexcept#

Symmetric comparison: std::vector<int64_t> != Shape.

ONNX_LIGHT_DECLARE_TENSOR_ELEMENT_TYPE(float, DataType::FLOAT)#
ONNX_LIGHT_DECLARE_TENSOR_ELEMENT_TYPE(double, DataType::DOUBLE)#
ONNX_LIGHT_DECLARE_TENSOR_ELEMENT_TYPE(int16_t, DataType::INT16)#
ONNX_LIGHT_DECLARE_TENSOR_ELEMENT_TYPE(int32_t, DataType::INT32)#
ONNX_LIGHT_DECLARE_TENSOR_ELEMENT_TYPE(int64_t, DataType::INT64)#
ONNX_LIGHT_DECLARE_TENSOR_ELEMENT_TYPE(int8_t, DataType::INT8)#
ONNX_LIGHT_DECLARE_TENSOR_ELEMENT_TYPE(uint8_t, DataType::UINT8)#
ONNX_LIGHT_DECLARE_TENSOR_ELEMENT_TYPE(uint16_t, DataType::UINT16)#
ONNX_LIGHT_DECLARE_TENSOR_ELEMENT_TYPE(uint32_t, DataType::UINT32)#
ONNX_LIGHT_DECLARE_TENSOR_ELEMENT_TYPE(uint64_t, DataType::UINT64)#
Tensor MakeOutputTensor(int32_t data_type, const Shape &shape, size_t n_bytes, RawBufferAllocator *allocator)#

Creates an empty output tensor of n_bytes bytes with the given data_type and shape.

When allocator is non-null the byte buffer is acquired from it via :cpp:func:RawBufferAllocator::Allocate and the returned tensor is allocator-backed (has_allocation() returns true). When allocator is null the tensor uses an inline :cpp:class:RawBuffer of n_bytes. In both cases the buffer contents are left uninitialised: the caller is expected to fully overwrite the result, so no time is spent zero-filling the memory.

Parameters:
  • data_type – ONNX element type (a TensorProto::DataType integer).

  • shape – Output shape.

  • n_bytes – Total byte size of the output buffer (element_count × element_size).

  • allocator – Optional allocator; may be nullptr.

size_t ElementSize(int32_t dtype)#

Returns the size in bytes of one element of dtype (a DataType integer). Throws std::invalid_argument for unsupported types. Sub-byte packed dtypes (INT4/UINT4/INT2/UINT2) are not supported by this helper because they do not have a whole-byte per-element size; use PackedByteSize instead.

size_t PackedByteSize(int32_t dtype, int64_t element_count)#

Returns the storage size in bytes for element_count elements of dtype. Whole-byte dtypes return element_count * ElementSize(dtype); sub-byte packed dtypes pack 2 (INT4/UINT4) or 4 (INT2/UINT2) elements per byte and element_count is rounded up to fill the trailing byte. Throws std::invalid_argument for unsupported types.

void FillValueInfo(const Tensor &tensor, ValueInfoProto &vi)#

Fills vi with the type/shape information described by tensor. vi.name is set to tensor.name.

Tensor TensorFromProto(const TensorProto &tp, RawBufferAllocator *allocator = nullptr)#

Converts a TensorProto to a :cpp:class:Tensor.

Supports all numeric data types stored either in the typed repeated fields (float_data, int32_data, int64_data, double_data, uint64_data) or in the raw little-endian raw_data field. STRING tensors are read from string_data.

The resulting Tensor::name is set from tp.name(); the shape is taken from tp.dims().

For the typed-field path the byte buffer is acquired from allocator when it is non-null (the returned tensor is then allocator-backed); when allocator is null an inline :cpp:class:RawBuffer is used. The raw_data path always returns a borrowed (zero-copy) view and ignores allocator.

Parameters:
  • tp – The source TensorProto.

  • allocator – Optional allocator for the typed-field byte buffer; may be nullptr.

Throws:

std::invalid_argument – for unsupported data_type values.

Returns:

A Tensor whose data matches the content of tp.

class AllocationHandle#
#include <simple_tensor.h>

Owns one allocator-backed raw buffer and returns it exactly once.

The handle is move-only. Moving it transfers ownership without moving or copying the payload. Destruction and :cpp:func:Reset return the buffer to its allocator; an empty or moved-from handle is a no-op.

A handle may instead own an :cpp:class:IOLease (see the lease-adopting constructor). Such a handle keeps its owning :cpp:class:IOArena alive on its own, so it may outlive the :cpp:class:RuntimeContext that produced it — making it suitable for ownership by a cross-boundary consumer such as a NumPy capsule. Its accessors describe the leased allocation exactly like a plain allocator-backed handle, but :cpp:func:Reset returns the buffer through the lease rather than the allocator interface.

Public Functions

AllocationHandle() noexcept#
AllocationHandle(RawBufferAllocator *owner, RawBuffer *buffer)#
AllocationHandle(RawBufferAllocator *owner, IOLease lease)#

Adopts an :cpp:class:IOLease so the handle keeps its arena alive.

Parameters:
  • owner – The :cpp:class:IOArena that produced lease (reported by :cpp:func:owner).

  • lease – A lease pinning the exported allocation. Its buffer, logical size, and retained capacity are captured by the handle.

~AllocationHandle()#
AllocationHandle(const AllocationHandle&) = delete#
AllocationHandle &operator=(const AllocationHandle&) = delete#
AllocationHandle(AllocationHandle &&other) noexcept#
AllocationHandle &operator=(AllocationHandle &&other) noexcept#
inline explicit operator bool() const noexcept#

Returns whether this handle owns an allocation.

inline RawBuffer *buffer() const noexcept#

Returns the owned buffer, or nullptr for an empty handle.

inline RawBufferAllocator *owner() const noexcept#

Returns the allocator that owns the buffer, or nullptr when empty.

inline size_t logical_size() const noexcept#

Returns the logical byte size captured when the handle was created.

inline size_t retained_capacity() const noexcept#

Returns the retained byte capacity captured when the handle was created.

inline bool holds_lease() const noexcept#

Returns whether this handle keeps its arena alive through an :cpp:class:IOLease (as opposed to a plain allocator reference).

RawBuffer *Release() noexcept#

Relinquishes ownership of an allocator-backed buffer without returning it to the allocator, and makes this handle empty.

Returns the previously owned buffer for a plain allocator-backed handle so the caller can take over its lifetime (for example to re-export it through an :cpp:class:IOArena lease). A lease-backed handle owns no transferable raw buffer, so its lease is released to the arena and nullptr is returned.

void Reset() noexcept#

Returns the allocation to its owner and makes this handle empty.

Private Members

RawBufferAllocator *owner_ = nullptr#
RawBuffer *buffer_ = nullptr#
size_t logical_size_ = 0#
size_t retained_capacity_ = 0#
std::unique_ptr<IOLease> lease_#

Non-null when the handle owns its allocation through a reference-counted lease that keeps the :cpp:class:IOArena alive. Held by pointer so the header only needs a forward declaration of :cpp:class:IOLease.

template<typename T, typename Allocator = std::allocator<T>>
class DefaultInitAllocator : public std::allocator<T>#
#include <simple_tensor.h>

DefaultInitAllocator — allocator that default-initialises elements.

A drop-in std::allocator replacement whose only difference is that a value-initialisation request with no arguments (as issued by std::vector::resize(n) or std::vector(n)) performs default initialisation instead. For a trivially constructible element type such as uint8_t this leaves the newly created bytes uninitialised rather than zero-filling them, which avoids a needless memset when the buffer will be fully overwritten (for example a kernel result). All other construction (with explicit arguments) behaves exactly like std::allocator.

Public Functions

DefaultInitAllocator() noexcept = default#
template<typename U, typename A>
inline explicit DefaultInitAllocator(const DefaultInitAllocator<U, A> &other) noexcept#
template<typename U>
inline void construct(U *ptr) noexcept(std::is_nothrow_default_constructible_v<U>)#

Default-initialises (leaves uninitialised for scalars) instead of value-initialising.

template<typename U, typename ...Args>
inline void construct(U *ptr, Args&&... args)#

Forwards all other constructions to the wrapped allocator unchanged.

Private Types

using traits = std::allocator_traits<Allocator>#
template<typename U>
struct rebind#
#include <simple_tensor.h>

Public Types

using other = DefaultInitAllocator<U, typename traits::template rebind_alloc<U>>#
struct RawBuffer#
#include <simple_tensor.h>

RawBuffer — an owned byte buffer equivalent to std::vector<uint8_t>.

Wraps a std::vector<uint8_t> (backed by :cpp:class:DefaultInitAllocator) under a dedicated type name to make the ownership semantics of raw element bytes explicit in the Tensor struct and to provide a natural extension point should the storage strategy change in the future. Because the backing allocator default-initialises, :cpp:func:resize and the size constructor leave the fresh bytes uninitialised rather than zero-filling them.

The full std::vector<uint8_t> interface subset needed by the codebase is exposed: size, empty, data, begin/end, indexed access, assign, and resize. Implicit conversions to and from std::vector<uint8_t> are provided for backward compatibility.

Public Functions

RawBuffer() = default#
inline explicit RawBuffer(size_t n)#

Constructs a buffer of n bytes whose contents are left uninitialised.

inline RawBuffer(const std::vector<uint8_t> &v)#
inline RawBuffer(std::vector<uint8_t> &&v)#
inline RawBuffer(RawByteBuffer &&v) noexcept#
RawBuffer(const RawBuffer&) = default#
RawBuffer(RawBuffer&&) noexcept = default#
RawBuffer &operator=(const RawBuffer&) = default#
RawBuffer &operator=(RawBuffer&&) noexcept = default#
inline RawBuffer &operator=(const std::vector<uint8_t> &v)#
inline RawBuffer &operator=(std::vector<uint8_t> &&v)#
inline operator std::vector<uint8_t>() const#

Implicitly converts to std::vector<uint8_t> for backward compatibility.

inline bool operator==(const RawBuffer &other) const noexcept#
inline bool operator!=(const RawBuffer &other) const noexcept#
inline bool operator==(const std::vector<uint8_t> &v) const noexcept#
inline bool operator!=(const std::vector<uint8_t> &v) const noexcept#
inline size_t size() const noexcept#
inline size_t capacity() const noexcept#
inline bool empty() const noexcept#
inline uint8_t *data() noexcept#
inline const uint8_t *data() const noexcept#
inline uint8_t &operator[](size_t i) noexcept#
inline const uint8_t &operator[](size_t i) const noexcept#
inline auto begin() noexcept#
inline auto end() noexcept#
inline auto begin() const noexcept#
inline auto end() const noexcept#
inline RawByteBuffer release() noexcept#

Moves the underlying byte storage out of the buffer, leaving it empty.

Returns the owned :cpp:type:RawByteBuffer by move so callers can take ownership of the bytes (for example to hand them to NumPy through a DLPack-style capsule) without copying. After the call the buffer is empty (size() == 0).

inline void assign(size_t count, uint8_t value)#

Fills the buffer with count copies of value, resizing as needed.

template<typename InputIt>
inline void assign(InputIt first, InputIt last)#

Replaces the buffer contents with the bytes from [first, last).

inline void resize(size_t count)#

Resizes the buffer to count bytes. Newly added bytes are left uninitialised (the backing allocator default-initialises), so callers must fully overwrite the buffer before reading it.

Private Members

RawByteBuffer storage_#
struct Shape#
#include <simple_tensor.h>

Shape — a fixed-capacity tensor shape storing up to 16 dimensions.

Stores dimension values in an inline int64_t[kMaxRank] array so no heap allocation is required for ordinary shapes. The number of valid dimensions is tracked by size_. An empty shape (size_ == 0) represents a scalar.

Implicit conversions to and from std::vector<int64_t> are provided for backward compatibility with existing call sites that use std::vector<int64_t> for shape parameters.

Public Functions

inline Shape() noexcept#

Constructs an empty shape (scalar).

inline Shape(std::initializer_list<int64_t> il)#

Constructs from a brace-enclosed initializer list, e.g. Shape{2, 3}. Throws std::invalid_argument when the list exceeds kMaxRank.

inline Shape(const std::vector<int64_t> &v)#

Constructs from a std::vector<int64_t> (copies all dimensions). Throws std::invalid_argument when the vector size exceeds kMaxRank.

inline Shape(std::vector<int64_t> &&v)#

Constructs from a moved std::vector<int64_t> (copies all dimensions). Throws std::invalid_argument when the vector size exceeds kMaxRank.

Shape(const Shape&) noexcept = default#
Shape(Shape&&) noexcept = default#
Shape &operator=(const Shape&) noexcept = default#
Shape &operator=(Shape&&) noexcept = default#
inline Shape &operator=(std::initializer_list<int64_t> il)#

Assigns from a brace-enclosed initializer list. Throws std::invalid_argument when the list exceeds kMaxRank.

inline Shape &operator=(const std::vector<int64_t> &v)#

Assigns from a std::vector<int64_t>. Throws std::invalid_argument when the vector size exceeds kMaxRank.

inline Shape &operator=(std::vector<int64_t> &&v)#

Assigns from a moved std::vector<int64_t>. Throws std::invalid_argument when the vector size exceeds kMaxRank.

inline operator std::vector<int64_t>() const#

Implicitly converts to std::vector<int64_t> for backward compatibility.

inline size_t size() const noexcept#

Returns the number of valid dimensions.

inline bool empty() const noexcept#

Returns true when there are no dimensions (scalar shape).

inline int64_t product() const noexcept#

Computes and returns the product of all dimensions; 1 for an empty (scalar) shape.

inline int64_t product(size_t begin, size_t end, const std::string &where) const#

Computes the product of dimensions in [begin, end).

Validates the requested range and checks for negative dimensions and INT64 overflow while multiplying.

Parameters: begin: Start index of the dimension range (inclusive). end: End index of the dimension range (exclusive). where: Caller-provided context describing the multiplication site. Returns: The product of the selected dimensions, or 1 for an empty range.

inline int64_t *begin() noexcept#
inline const int64_t *begin() const noexcept#
inline int64_t *end() noexcept#
inline const int64_t *end() const noexcept#
inline const int64_t *data() const noexcept#

Returns a pointer to the underlying dimension array.

inline int64_t &operator[](size_t i) noexcept#

Element access without bounds checking (matches std::vector semantics). Behaviour is undefined when i >= size().

inline const int64_t &operator[](size_t i) const noexcept#

Element access without bounds checking (matches std::vector semantics). Behaviour is undefined when i >= size().

inline void push_back(int64_t v)#

Appends a dimension. Throws std::invalid_argument when already at kMaxRank.

inline void reserve(size_t) noexcept#

No-op: storage is always inline; provided for interface parity with std::vector.

inline void assign(size_t count, int64_t value)#

Replaces the contents with count copies of value. Throws std::invalid_argument when count exceeds kMaxRank.

template<typename InputIt, typename = std::enable_if_t<!std::is_integral<InputIt>::value>>
inline void assign(InputIt first, InputIt last)#

Replaces the contents with the elements in the range [first, last). Throws std::invalid_argument when the range size exceeds kMaxRank.

inline int64_t &back()#

Returns a reference to the last dimension. Throws std::invalid_argument when the shape is empty.

inline const int64_t &back() const#
inline int64_t *insert(int64_t *pos, int64_t value)#

Inserts value before the element pointed to by pos. Throws std::invalid_argument when already at kMaxRank. Returns an iterator to the inserted element.

template<typename InputIt>
inline int64_t *insert(int64_t *pos, InputIt first, InputIt last)#

Inserts elements from [first, last) before the element pointed to by pos. Throws std::invalid_argument when the resulting rank would exceed kMaxRank. Returns an iterator to the first inserted element.

inline bool operator==(const Shape &other) const noexcept#
inline bool operator==(const std::vector<int64_t> &v) const noexcept#
inline bool operator!=(const Shape &other) const noexcept#
inline bool operator!=(const std::vector<int64_t> &v) const noexcept#

Public Static Attributes

static constexpr size_t kMaxRank = 16#

Maximum supported tensor rank.

Private Members

int64_t dims_[kMaxRank]#
size_t size_#
struct Tensor#
#include <simple_tensor.h>

Tensor — minimal runtime tensor used by backend test cases.

This struct is intentionally distinct from TensorProto: it carries no protobuf wire dependency, owns its bytes in row-major little-endian layout, and is meant to be consumed directly by a runtime exercising a single backend test node case.

Public Functions

Tensor() = default#
inline Tensor(std::string n, int32_t dt, Shape s, std::vector<uint8_t> d)#
~Tensor() = default#
Tensor(const Tensor &other)#

Deep-copies other. When other is allocator-backed (has_allocation()), a fresh buffer is acquired from the same allocator and the bytes are duplicated, so the copy never aliases other’s allocation — the two tensors can be freed independently without a double free. Borrowed (non-owning) views are copied by reference, as before.

Tensor &operator=(const Tensor &other)#
Tensor(Tensor &&other) noexcept#

Transfers ownership of any allocator-backed allocation from other to *this and resets other to a non-owning empty state, so other can be safely destroyed or overwritten afterwards (e.g. left behind in a map after std::move(it->second)) without triggering a double free.

Tensor &operator=(Tensor &&other) noexcept#
inline const uint8_t *bytes() const noexcept#

Returns a pointer to the raw element bytes. Works for both owned (data) and borrowed (non-owning view) tensors.

inline uint8_t *mutable_bytes() noexcept#

Returns a mutable pointer to the raw element bytes. Works for owned tensors and allocator-backed tensors. For borrowed tensors the underlying storage may be read-only; callers must not write through the returned pointer when the tensor was created via :cpp:func:Borrow with an immutable backing buffer.

inline size_t size_bytes() const noexcept#

Returns the total number of raw element bytes. Works for both owned and borrowed tensors.

inline void SetAllocation(RawBufferAllocator *allocator_owner, RawBuffer *allocation)#

Marks the tensor storage as allocator-backed. Callers must release/clear any existing allocation first.

inline bool has_allocation() const noexcept#
inline bool is_borrowed() const noexcept#

Returns whether the tensor is a non-owning (borrowed) view over external memory (created via :cpp:func:Borrow / :cpp:func:BorrowStrings, e.g. a zero-copy view into a TensorProto’s raw_data). Borrowed tensors do not own their bytes: the backing storage must outlive the tensor.

inline const std::shared_ptr<void> &borrowed_owner() const noexcept#

Returns the token retaining borrowed byte storage, or an empty token when the caller is responsible for its lifetime.

Tensor BorrowView() const#

Creates an immutable-storage view whose metadata is independent while its payload aliases this tensor. This tensor must outlive the returned view.

Tensor ToOwned() const#

Returns an owned deep copy of this tensor that references no external memory: the bytes (or, for STRING tensors, the strings) are copied into inline storage the returned tensor owns. Use this to detach a borrowed view (see :cpp:func:is_borrowed) from its backing buffer — for example a graph output that borrows into a TensorProto’s raw_data — so it stays valid once that buffer is released. Allocator-backed and already-owned tensors are copied inline as well.

inline RawBuffer *allocation() const#
inline RawBufferAllocator *allocation_owner() const#
inline AllocationHandle ReleaseAllocation() noexcept#

Transfers the allocator-backed storage out of this tensor in O(1).

inline void ResetAllocation() noexcept#

Returns allocator-backed storage immediately and leaves the tensor empty.

int64_t element_count() const#

Returns the product of all shape dimensions; 1 for an empty shape.

size_t element_size() const#

Returns the size in bytes of one element of data_type. Throws std::invalid_argument for unsupported types.

template<typename T>
const T *As() const#

Typed views over the underlying data buffer. They throw if the requested type does not match data_type.

The templated As<T>() accessor is the generic version. The non-template AsFloat/AsDouble/AsInt32/AsInt64 are thin wrappers kept for source compatibility.

template<typename T>
T *As()#
const float *AsFloat() const#
float *AsFloat()#
const double *AsDouble() const#
double *AsDouble()#
const int32_t *AsInt32() const#
int32_t *AsInt32()#
const int64_t *AsInt64() const#
int64_t *AsInt64()#
const int8_t *AsInt8() const#
int8_t *AsInt8()#
const uint8_t *AsUint8() const#
uint8_t *AsUint8()#
const int16_t *AsInt16() const#
int16_t *AsInt16()#
const uint16_t *AsUint16() const#
uint16_t *AsUint16()#
const uint32_t *AsUint32() const#
uint32_t *AsUint32()#
const uint64_t *AsUint64() const#
uint64_t *AsUint64()#
const uint8_t *AsBool() const#

Typed view over data for BOOL element type, stored one byte per element. The byte value is 0 for false and non-zero (canonically 1) for true.

uint8_t *AsBool()#
const std::vector<std::string> &AsStrings() const#

Typed view over the underlying string_data buffer. Throws std::invalid_argument if data_type is not DataType::STRING. Borrowed string tensors return a const reference to the external backing vector; requesting a non-const view of borrowed string storage throws std::invalid_argument.

std::vector<std::string> &AsStrings()#

Public Members

std::string name#

Optional name of the tensor (input/output name in the test model).

int32_t data_type = 0#

Element data type stored as a DataType integer value.

Shape shape#

Tensor shape; an empty shape denotes a scalar (element_count == 1).

RawBuffer data#

Raw element bytes in row-major little-endian layout (owned storage).

Empty when the tensor uses a borrowed (non-owning) view — use :cpp:func:bytes and :cpp:func:size_bytes to access element bytes regardless of storage mode. Also empty when data_type is DataType::STRING; in that case the element values are stored in string_data instead.

std::vector<std::string> string_data#

String element values in row-major layout. Populated only when data_type is DataType::STRING and the tensor owns its string storage; empty for all other element types and for borrowed string views.

Public Static Functions

static inline Tensor FromRawBytes(std::string name, int32_t data_type, Shape shape, RawByteBuffer bytes)#

Creates a tensor by adopting canonical raw-byte storage without copying.

static inline Tensor MakeString(std::string n, Shape s, std::vector<std::string> sd)#

Constructs a STRING tensor whose elements live in string_data. Distinct from the bytes-based constructor so brace-enclosed { ... } initializer lists at call sites are unambiguous.

static Tensor Borrow(std::string name, int32_t dtype, Shape shape, const uint8_t *ptr, size_t sz, std::shared_ptr<void> owner = {})#

Creates a non-owning (borrowed) Tensor that references an external byte buffer without copying.

The pointed-to buffer at ptr[0 .. sz-1] MUST outlive this Tensor. Both the const and non-const As<T>() overloads (and AsBool()) are available on borrowed tensors; the non-const overloads return a T * via const_cast. Callers must not write through that pointer if the underlying storage is immutable — doing so is undefined behaviour.

Parameters:
  • nameTensor name.

  • dtype – Element data type (a DataType integer value).

  • shapeTensor shape.

  • ptr – Pointer to the first byte of element data.

  • sz – Total byte count of the element buffer.

Returns:

A Tensor backed by the external buffer.

static Tensor BorrowStrings(std::string name, Shape shape, const std::vector<std::string> &strings)#

Creates a non-owning (borrowed) STRING tensor that references an external string vector without copying.

The referenced string vector MUST outlive this Tensor.

template<typename T>
static Tensor From(const std::string &name, const Shape &shape, const std::vector<T> &values, RawBufferAllocator *allocator = nullptr)#

Typed factories that construct a tensor of the given shape and copy the provided values into data. They throw std::invalid_argument if any dimension in shape is negative or if values.size() does not match prod(shape).

The templated From<T> factory is the generic version. The non-template FromFloat/FromDouble/FromInt32/FromInt64 are thin wrappers kept for source compatibility.

When allocator is non-null the element bytes are acquired from it (via :cpp:func:MakeOutputTensor) and the returned tensor is allocator-backed; when null the tensor uses inline :cpp:class:RawBuffer storage. Kernels producing a result should pass the runtime context allocator so no output buffer is allocated outside it.

static Tensor FromFloat(const std::string &name, const Shape &shape, const std::vector<float> &values, RawBufferAllocator *allocator = nullptr)#
static Tensor FromDouble(const std::string &name, const Shape &shape, const std::vector<double> &values, RawBufferAllocator *allocator = nullptr)#
static Tensor FromInt32(const std::string &name, const Shape &shape, const std::vector<int32_t> &values, RawBufferAllocator *allocator = nullptr)#
static Tensor FromInt64(const std::string &name, const Shape &shape, const std::vector<int64_t> &values, RawBufferAllocator *allocator = nullptr)#
static Tensor FromInt8(const std::string &name, const Shape &shape, const std::vector<int8_t> &values, RawBufferAllocator *allocator = nullptr)#
static Tensor FromUint8(const std::string &name, const Shape &shape, const std::vector<uint8_t> &values, RawBufferAllocator *allocator = nullptr)#
static Tensor FromInt16(const std::string &name, const Shape &shape, const std::vector<int16_t> &values, RawBufferAllocator *allocator = nullptr)#
static Tensor FromUint16(const std::string &name, const Shape &shape, const std::vector<uint16_t> &values, RawBufferAllocator *allocator = nullptr)#
static Tensor FromUint32(const std::string &name, const Shape &shape, const std::vector<uint32_t> &values, RawBufferAllocator *allocator = nullptr)#
static Tensor FromUint64(const std::string &name, const Shape &shape, const std::vector<uint64_t> &values, RawBufferAllocator *allocator = nullptr)#
static Tensor FromBool(const std::string &name, const Shape &shape, const std::vector<uint8_t> &values, RawBufferAllocator *allocator = nullptr)#

Constructs a BOOL tensor; element values are stored as one byte each (0 == false, non-zero == true). Provided as a uint8_t vector so the usual std::vector<bool> packing pitfalls are avoided.

static Tensor FromStrings(const std::string &name, const Shape &shape, const std::vector<std::string> &values)#

Constructs a STRING tensor whose elements are the provided UTF-8 strings (stored in string_data). Throws std::invalid_argument if any dimension in shape is negative or if values.size() does not match prod(shape).

Private Members

AllocationHandle allocation_#

Move-only ownership of allocator-backed bytes.

const uint8_t *borrow_ptr_ = nullptr#

Non-null only for borrowed (non-owning) tensors created via :cpp:func:Borrow. When set, element bytes are read from borrow_ptr_[0 .. borrow_size_-1] rather than from data.

size_t borrow_size_ = 0#
const std::vector<std::string> *borrow_string_data_ = nullptr#
std::shared_ptr<void> borrow_owner_#
class Tensors : public std::vector<Tensor>#
#include <simple_tensor.h>

Tensors — the runtime value produced by kernels that emit more than one tensor (for example Split, Loop or the training optimizers).

It is an ordered, owning list of :cpp:struct:Tensor values. Derives from std::vector<Tensor> and inherits its constructors, behaving exactly like the underlying vector while giving kernel signatures a named type to express “a list of created tensors” instead of spelling out std::vector<Tensor> at every call site.

Public Functions

Tensors() = default#
inline Tensors(const std::vector<Tensor> &values)#
inline Tensors(std::vector<Tensor> &&values)#