The types an inference backend shares, so calling code names a backend once rather than at every call site. `API.Onnx` runs a model in-process; `API.Inference` sends it to a server. They answer the same question and neither is right for every deployment: ONNX needs a model file and a runtime for the architecture, a server is the only GPU path today, and a model that will not convert to ONNX reaches Objeck no other way (docs/INFERENCE_ENGINES_PLAN.md). This bundle exists because both previously defined their own `Tensor`. That was deliberate and temporary -- the generic ONNX run shipped before a shared library existed -- and two near-identical classes drift. They are one class now. Compile with -lib models.
Tensor
A named, shaped block of numbers: one input to or output from a model. Elements are flat and row-major; the shape says how to read them. A 1x3x224x224 image is 150,528 numbers with shape [1,3,224,224], and nesting it would cost a Vector per row for nothing. Floats and integers are held SEPARATELY rather than one being converted to the other. Both are needed in practice -- pixels and embeddings are FP32, token ids for a language model are INT64 -- and a conversion at construction would impose the narrower type's limits on a backend that does not have them. An HTTP server receives an integer tensor as JSON integers with no range limit at all; only the native crossing needs floats, so that is where the conversion and its check live.
Example
pixels := Float->New[1 * 3 * 224 * 224];
input := Tensor->New("data", [1, 3, 224, 224], pixels);
ids := [101, 2003, 1037];
tokens := Tensor->New("input_ids", [1, 3], ids);Operations
AsFloats #
The elements as floats, converting an integer tensor if needed. REFUSES rather than rounds. A Float holds every integer up to 2^53 (9,007,199,254,740,992) exactly, which covers every token id, class index and mask there is, but a value past that cannot survive the conversion and nothing downstream could tell that it had not. Only a backend that must have floats should call this -- the native ONNX crossing does; an HTTP server does not, and sends integers as integers.
method : public : AsFloats() ~ Float[]Return
| Type | Description |
|---|---|
| Float | elements as floats, or Nil when a value will not convert |
GetDatatype #
The element type. On a result this is what the backend produced; on an input it is advisory, because a backend that declares its own input types uses those instead.
method : public : GetDatatype() ~ StringReturn
| Type | Description |
|---|---|
| String | element type name |
GetFloats #
The float elements, or Nil for an integer tensor. Use AsFloats to get floats whichever way the tensor was built.
method : public : GetFloats() ~ Float[]Return
| Type | Description |
|---|---|
| Float | elements, or Nil |
GetInts #
The integer elements, or Nil for a float tensor.
method : public : GetInts() ~ Int[]Return
| Type | Description |
|---|---|
| Int | elements, or Nil |
GetName #
The name the model knows this tensor by.
method : public : GetName() ~ StringReturn
| Type | Description |
|---|---|
| String | name |
GetShape #
Dimensions, outermost first.
method : public : GetShape() ~ Int[]Return
| Type | Description |
|---|---|
| Int | shape |
GetShapeProduct #
The product of the dimensions, which GetCount must equal.
method : public : GetShapeProduct() ~ IntReturn
| Type | Description |
|---|---|
| Int | expected element count, or 0 for an unset shape |
IsConsistent #
Whether the element count matches the shape. An EMPTY tensor is consistent: [1,32,0,96] with no elements is how every small language model passes its key/value cache on the first forward pass, and a "count must be positive" check gets that wrong first.
method : public : IsConsistent() ~ BoolReturn
| Type | Description |
|---|---|
| Bool | true when the tensor is internally consistent |
IsFloat #
Whether this tensor holds floats rather than integers.
method : public : IsFloat() ~ BoolReturn
| Type | Description |
|---|---|
| Bool | true for a float tensor |
New # constructor
A float tensor, datatype FP32.
New(name:String, shape:Int[], data:Float[])Parameters
| Name | Type | Description |
|---|---|---|
| name | String | the input or output name the model uses |
| shape | Int | dimensions, e.g. [1,3,224,224] |
| data | Float | elements, flat and row-major |
New # constructor
An integer tensor, datatype INT64 -- token ids, class indexes, a mask. Stored as integers, exactly as given. Nothing is lost here; see AsFloats for where a conversion becomes necessary and what it costs.
New(name:String, shape:Int[], data:Int[])Parameters
| Name | Type | Description |
|---|---|---|
| name | String | the input or output name the model uses |
| shape | Int | dimensions |
| data | Int | elements, flat and row-major |
New # constructor
A tensor whose element type is named explicitly, for the types the two constructors above do not cover -- FP16, INT32, UINT8, BOOL. The data is still carried as floats; the datatype says how to read it.
New(name:String, datatype:String, shape:Int[], data:Float[])Parameters
| Name | Type | Description |
|---|---|---|
| name | String | the input or output name the model uses |
| datatype | String | an element type, e.g. "FP16", "INT32", "BOOL" |
| shape | Int | dimensions |
| data | Float | elements |